Merge branches 'fork-409' and 'fork-419' into develop
This commit is contained in:
commit
3dc58e435f
13 changed files with 140 additions and 33 deletions
|
|
@ -41,6 +41,12 @@ share_type cut_fee(share_type a, uint16_t p)
|
||||||
|
|
||||||
bool account_object::is_authorized_asset(const asset_object& asset_obj, const database& d) const
|
bool account_object::is_authorized_asset(const asset_object& asset_obj, const database& d) const
|
||||||
{
|
{
|
||||||
|
if( d.head_block_time() > HARDFORK_416_TIME )
|
||||||
|
{
|
||||||
|
if( !(asset_obj.options.flags & white_list) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for( const auto id : blacklisting_accounts )
|
for( const auto id : blacklisting_accounts )
|
||||||
{
|
{
|
||||||
if( asset_obj.options.blacklist_authorities.find(id) != asset_obj.options.blacklist_authorities.end() )
|
if( asset_obj.options.blacklist_authorities.find(id) != asset_obj.options.blacklist_authorities.end() )
|
||||||
|
|
@ -68,7 +74,6 @@ void account_balance_object::adjust_balance(const asset& delta)
|
||||||
balance += delta.amount;
|
balance += delta.amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void account_statistics_object::process_fees(const account_object& a, database& d) const
|
void account_statistics_object::process_fees(const account_object& a, database& d) const
|
||||||
{
|
{
|
||||||
if( pending_fees > 0 || pending_vested_fees > 0 )
|
if( pending_fees > 0 || pending_vested_fees > 0 )
|
||||||
|
|
|
||||||
|
|
@ -45,20 +45,36 @@ void_result asset_create_evaluator::do_evaluate( const asset_create_operation& o
|
||||||
for( auto id : op.common_options.blacklist_authorities )
|
for( auto id : op.common_options.blacklist_authorities )
|
||||||
d.get_object(id);
|
d.get_object(id);
|
||||||
|
|
||||||
auto& asset_indx = db().get_index_type<asset_index>().indices().get<by_symbol>();
|
auto& asset_indx = d.get_index_type<asset_index>().indices().get<by_symbol>();
|
||||||
auto asset_symbol_itr = asset_indx.find( op.symbol );
|
auto asset_symbol_itr = asset_indx.find( op.symbol );
|
||||||
FC_ASSERT( asset_symbol_itr == asset_indx.end() );
|
FC_ASSERT( asset_symbol_itr == asset_indx.end() );
|
||||||
|
|
||||||
auto dotpos = op.symbol.find( '.' );
|
if( d.head_block_time() <= HARDFORK_409_TIME )
|
||||||
if( dotpos != std::string::npos ) {
|
{
|
||||||
auto prefix = op.symbol.substr( 0, dotpos );
|
auto dotpos = op.symbol.find( '.' );
|
||||||
auto asset_symbol_itr = asset_indx.find( op.symbol );
|
if( dotpos != std::string::npos )
|
||||||
FC_ASSERT( asset_symbol_itr != asset_indx.end(), "Asset ${s} may only be created by issuer of ${p}, but ${p} has not been registered",
|
{
|
||||||
("s",op.symbol)("p",prefix) );
|
auto prefix = op.symbol.substr( 0, dotpos );
|
||||||
FC_ASSERT( asset_symbol_itr->issuer == op.issuer, "Asset ${s} may only be created by issuer of ${p}, ${i}",
|
auto asset_symbol_itr = asset_indx.find( op.symbol );
|
||||||
("s",op.symbol)("p",prefix)("i", op.issuer(d).name) );
|
FC_ASSERT( asset_symbol_itr != asset_indx.end(), "Asset ${s} may only be created by issuer of ${p}, but ${p} has not been registered",
|
||||||
|
("s",op.symbol)("p",prefix) );
|
||||||
|
FC_ASSERT( asset_symbol_itr->issuer == op.issuer, "Asset ${s} may only be created by issuer of ${p}, ${i}",
|
||||||
|
("s",op.symbol)("p",prefix)("i", op.issuer(d).name) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto dotpos = op.symbol.rfind( '.' );
|
||||||
|
if( dotpos != std::string::npos )
|
||||||
|
{
|
||||||
|
auto prefix = op.symbol.substr( 0, dotpos );
|
||||||
|
auto asset_symbol_itr = asset_indx.find( prefix );
|
||||||
|
FC_ASSERT( asset_symbol_itr != asset_indx.end(), "Asset ${s} may only be created by issuer of ${p}, but ${p} has not been registered",
|
||||||
|
("s",op.symbol)("p",prefix) );
|
||||||
|
FC_ASSERT( asset_symbol_itr->issuer == op.issuer, "Asset ${s} may only be created by issuer of ${p}, ${i}",
|
||||||
|
("s",op.symbol)("p",prefix)("i", op.issuer(d).name) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
core_fee_paid -= core_fee_paid.value/2;
|
core_fee_paid -= core_fee_paid.value/2;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ void_result transfer_to_blind_evaluator::do_evaluate( const transfer_to_blind_op
|
||||||
const auto& atype = o.amount.asset_id(db());
|
const auto& atype = o.amount.asset_id(db());
|
||||||
FC_ASSERT( atype.allow_confidential() );
|
FC_ASSERT( atype.allow_confidential() );
|
||||||
FC_ASSERT( !atype.is_transfer_restricted() );
|
FC_ASSERT( !atype.is_transfer_restricted() );
|
||||||
FC_ASSERT( !atype.enforce_white_list() );
|
FC_ASSERT( !(atype.options.flags & white_list) );
|
||||||
|
|
||||||
for( const auto& out : o.outputs )
|
for( const auto& out : o.outputs )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include <graphene/chain/database.hpp>
|
#include <graphene/chain/database.hpp>
|
||||||
#include <graphene/chain/evaluator.hpp>
|
#include <graphene/chain/evaluator.hpp>
|
||||||
#include <graphene/chain/exceptions.hpp>
|
#include <graphene/chain/exceptions.hpp>
|
||||||
|
#include <graphene/chain/hardfork.hpp>
|
||||||
#include <graphene/chain/transaction_evaluation_state.hpp>
|
#include <graphene/chain/transaction_evaluation_state.hpp>
|
||||||
|
|
||||||
#include <graphene/chain/asset_object.hpp>
|
#include <graphene/chain/asset_object.hpp>
|
||||||
|
|
@ -46,17 +47,25 @@ database& generic_evaluator::db()const { return trx_state->db(); }
|
||||||
|
|
||||||
void generic_evaluator::prepare_fee(account_id_type account_id, asset fee)
|
void generic_evaluator::prepare_fee(account_id_type account_id, asset fee)
|
||||||
{
|
{
|
||||||
|
const database& d = db();
|
||||||
fee_from_account = fee;
|
fee_from_account = fee;
|
||||||
FC_ASSERT( fee.amount >= 0 );
|
FC_ASSERT( fee.amount >= 0 );
|
||||||
fee_paying_account = &account_id(db());
|
fee_paying_account = &account_id(d);
|
||||||
fee_paying_account_statistics = &fee_paying_account->statistics(db());
|
fee_paying_account_statistics = &fee_paying_account->statistics(d);
|
||||||
|
|
||||||
fee_asset = &fee.asset_id(db());
|
fee_asset = &fee.asset_id(d);
|
||||||
fee_asset_dyn_data = &fee_asset->dynamic_asset_data_id(db());
|
fee_asset_dyn_data = &fee_asset->dynamic_asset_data_id(d);
|
||||||
|
|
||||||
|
if( d.head_block_time() > HARDFORK_419_TIME )
|
||||||
|
{
|
||||||
|
FC_ASSERT( fee_paying_account->is_authorized_asset( *fee_asset, d ), "Account ${acct} '${name}' attempted to pay fee by using asset ${a} '${sym}', which is unauthorized due to whitelist / blacklist",
|
||||||
|
("acct", fee_paying_account->id)("name", fee_paying_account->name)("a", fee_asset->id)("sym", fee_asset->symbol) );
|
||||||
|
}
|
||||||
|
|
||||||
if( fee_from_account.asset_id == asset_id_type() )
|
if( fee_from_account.asset_id == asset_id_type() )
|
||||||
core_fee_paid = fee_from_account.amount;
|
core_fee_paid = fee_from_account.amount;
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
asset fee_from_pool = fee_from_account * fee_asset->options.core_exchange_rate;
|
asset fee_from_pool = fee_from_account * fee_asset->options.core_exchange_rate;
|
||||||
FC_ASSERT( fee_from_pool.asset_id == asset_id_type() );
|
FC_ASSERT( fee_from_pool.asset_id == asset_id_type() );
|
||||||
core_fee_paid = fee_from_pool.amount;
|
core_fee_paid = fee_from_pool.amount;
|
||||||
|
|
|
||||||
|
|
@ -82,8 +82,6 @@ namespace graphene { namespace chain {
|
||||||
/// @return true if symbol is a valid ticker symbol; false otherwise.
|
/// @return true if symbol is a valid ticker symbol; false otherwise.
|
||||||
static bool is_valid_symbol( const string& symbol );
|
static bool is_valid_symbol( const string& symbol );
|
||||||
|
|
||||||
/// @return true if accounts must be on a whitelist in order to hold this asset; false otherwise.
|
|
||||||
bool enforce_white_list()const { return options.flags & white_list; }
|
|
||||||
/// @return true if this is a market-issued asset; false otherwise.
|
/// @return true if this is a market-issued asset; false otherwise.
|
||||||
bool is_market_issued()const { return bitasset_data_id.valid(); }
|
bool is_market_issued()const { return bitasset_data_id.valid(); }
|
||||||
/// @return true if users may request force-settlement of this market-issued asset; false otherwise
|
/// @return true if users may request force-settlement of this market-issued asset; false otherwise
|
||||||
|
|
|
||||||
|
|
@ -22,4 +22,7 @@
|
||||||
|
|
||||||
#define HARDFORK_357_TIME (fc::time_point_sec( 1444416300 ))
|
#define HARDFORK_357_TIME (fc::time_point_sec( 1444416300 ))
|
||||||
#define HARDFORK_359_TIME (fc::time_point_sec( 1444416300 ))
|
#define HARDFORK_359_TIME (fc::time_point_sec( 1444416300 ))
|
||||||
|
#define HARDFORK_409_TIME (fc::time_point_sec( 1446652800 ))
|
||||||
#define HARDFORK_415_TIME (fc::time_point_sec( 1446652800 ))
|
#define HARDFORK_415_TIME (fc::time_point_sec( 1446652800 ))
|
||||||
|
#define HARDFORK_416_TIME (fc::time_point_sec( 1446652800 ))
|
||||||
|
#define HARDFORK_419_TIME (fc::time_point_sec( 1446652800 ))
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,11 @@ namespace graphene { namespace chain {
|
||||||
/// the core exchange rate.
|
/// the core exchange rate.
|
||||||
price core_exchange_rate;
|
price core_exchange_rate;
|
||||||
|
|
||||||
/// A set of accounts which maintain whitelists to consult for this asset. If enforce_white_list() returns
|
/// A set of accounts which maintain whitelists to consult for this asset. If whitelist_authorities
|
||||||
/// true, an account may only send, receive, trade, etc. in this asset if one of these accounts appears in
|
/// is non-empty, then only accounts in whitelist_authorities are allowed to hold, use, or transfer the asset.
|
||||||
/// its account_object::whitelisting_accounts field.
|
|
||||||
flat_set<account_id_type> whitelist_authorities;
|
flat_set<account_id_type> whitelist_authorities;
|
||||||
/// A set of accounts which maintain blacklists to consult for this asset. If enforce_white_list() returns
|
/// A set of accounts which maintain blacklists to consult for this asset. If flags & white_list is set,
|
||||||
/// true, an account may only send, receive, trade, etc. in this asset if none of these accounts appears in
|
/// an account may only send, receive, trade, etc. in this asset if none of these accounts appears in
|
||||||
/// its account_object::blacklisting_accounts field. If the account is blacklisted, it may not transact in
|
/// its account_object::blacklisting_accounts field. If the account is blacklisted, it may not transact in
|
||||||
/// this asset even if it is also whitelisted.
|
/// this asset even if it is also whitelisted.
|
||||||
flat_set<account_id_type> blacklist_authorities;
|
flat_set<account_id_type> blacklist_authorities;
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,16 @@ void_result limit_order_create_evaluator::do_evaluate(const limit_order_create_o
|
||||||
if( _sell_asset->options.blacklist_markets.size() )
|
if( _sell_asset->options.blacklist_markets.size() )
|
||||||
FC_ASSERT( _sell_asset->options.blacklist_markets.find(_receive_asset->id) == _sell_asset->options.blacklist_markets.end() );
|
FC_ASSERT( _sell_asset->options.blacklist_markets.find(_receive_asset->id) == _sell_asset->options.blacklist_markets.end() );
|
||||||
|
|
||||||
if( _sell_asset->enforce_white_list() ) FC_ASSERT( _seller->is_authorized_asset( *_sell_asset, d ) );
|
if( d.head_block_time() <= HARDFORK_416_TIME )
|
||||||
if( _receive_asset->enforce_white_list() ) FC_ASSERT( _seller->is_authorized_asset( *_receive_asset, d ) );
|
{
|
||||||
|
if( _sell_asset->options.flags & white_list ) FC_ASSERT( _seller->is_authorized_asset( *_sell_asset, d ) );
|
||||||
|
if( _receive_asset->options.flags & white_list ) FC_ASSERT( _seller->is_authorized_asset( *_receive_asset, d ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FC_ASSERT( _seller->is_authorized_asset( *_sell_asset, d ) );
|
||||||
|
FC_ASSERT( _seller->is_authorized_asset( *_receive_asset, d ) );
|
||||||
|
}
|
||||||
|
|
||||||
FC_ASSERT( d.get_balance( *_seller, *_sell_asset ) >= op.amount_to_sell, "insufficient balance",
|
FC_ASSERT( d.get_balance( *_seller, *_sell_asset ) >= op.amount_to_sell, "insufficient balance",
|
||||||
("balance",d.get_balance(*_seller,*_sell_asset))("amount_to_sell",op.amount_to_sell) );
|
("balance",d.get_balance(*_seller,*_sell_asset))("amount_to_sell",op.amount_to_sell) );
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include <graphene/chain/transfer_evaluator.hpp>
|
#include <graphene/chain/transfer_evaluator.hpp>
|
||||||
#include <graphene/chain/account_object.hpp>
|
#include <graphene/chain/account_object.hpp>
|
||||||
#include <graphene/chain/exceptions.hpp>
|
#include <graphene/chain/exceptions.hpp>
|
||||||
|
#include <graphene/chain/hardfork.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene { namespace chain {
|
||||||
void_result transfer_evaluator::do_evaluate( const transfer_operation& op )
|
void_result transfer_evaluator::do_evaluate( const transfer_operation& op )
|
||||||
|
|
@ -53,8 +54,12 @@ void_result transfer_evaluator::do_evaluate( const transfer_operation& op )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( fee_asset_type.options.flags & white_list )
|
if( d.head_block_time() <= HARDFORK_419_TIME )
|
||||||
FC_ASSERT( from_account.is_authorized_asset( asset_type, d ) );
|
{
|
||||||
|
if( fee_asset_type.options.flags & white_list )
|
||||||
|
FC_ASSERT( from_account.is_authorized_asset( asset_type, d ) );
|
||||||
|
}
|
||||||
|
// the above becomes no-op after hardfork because this check will then be performed in evaluator
|
||||||
|
|
||||||
if( asset_type.is_transfer_restricted() )
|
if( asset_type.is_transfer_restricted() )
|
||||||
{
|
{
|
||||||
|
|
@ -108,8 +113,12 @@ void_result override_transfer_evaluator::do_evaluate( const override_transfer_op
|
||||||
FC_ASSERT( from_account.is_authorized_asset( asset_type, d ) );
|
FC_ASSERT( from_account.is_authorized_asset( asset_type, d ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( fee_asset_type.options.flags & white_list )
|
if( d.head_block_time() <= HARDFORK_419_TIME )
|
||||||
FC_ASSERT( from_account.is_authorized_asset( asset_type, d ) );
|
{
|
||||||
|
if( fee_asset_type.options.flags & white_list )
|
||||||
|
FC_ASSERT( from_account.is_authorized_asset( asset_type, d ) );
|
||||||
|
}
|
||||||
|
// the above becomes no-op after hardfork because this check will then be performed in evaluator
|
||||||
|
|
||||||
FC_ASSERT( d.get_balance( from_account, asset_type ).amount >= op.amount.amount,
|
FC_ASSERT( d.get_balance( from_account, asset_type ).amount >= op.amount.amount,
|
||||||
"", ("total_transfer",op.amount)("balance",d.get_balance(from_account, asset_type).amount) );
|
"", ("total_transfer",op.amount)("balance",d.get_balance(from_account, asset_type).amount) );
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include <graphene/chain/account_object.hpp>
|
#include <graphene/chain/account_object.hpp>
|
||||||
#include <graphene/chain/database.hpp>
|
#include <graphene/chain/database.hpp>
|
||||||
#include <graphene/chain/exceptions.hpp>
|
#include <graphene/chain/exceptions.hpp>
|
||||||
|
#include <graphene/chain/hardfork.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
|
|
@ -65,7 +66,17 @@ void_result withdraw_permission_claim_evaluator::do_evaluate(const withdraw_perm
|
||||||
const asset_object& _asset = op.amount_to_withdraw.asset_id(d);
|
const asset_object& _asset = op.amount_to_withdraw.asset_id(d);
|
||||||
if( _asset.is_transfer_restricted() ) FC_ASSERT( _asset.issuer == permit.authorized_account || _asset.issuer == permit.withdraw_from_account );
|
if( _asset.is_transfer_restricted() ) FC_ASSERT( _asset.issuer == permit.authorized_account || _asset.issuer == permit.withdraw_from_account );
|
||||||
|
|
||||||
if( _asset.enforce_white_list() )
|
if( d.head_block_time() <= HARDFORK_416_TIME )
|
||||||
|
{
|
||||||
|
if( _asset.options.flags & white_list )
|
||||||
|
{
|
||||||
|
const account_object& from = op.withdraw_to_account(d);
|
||||||
|
const account_object& to = permit.authorized_account(d);
|
||||||
|
FC_ASSERT( to.is_authorized_asset( _asset, d ) );
|
||||||
|
FC_ASSERT( from.is_authorized_asset( _asset, d ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
const account_object& from = op.withdraw_to_account(d);
|
const account_object& from = op.withdraw_to_account(d);
|
||||||
const account_object& to = permit.authorized_account(d);
|
const account_object& to = permit.authorized_account(d);
|
||||||
|
|
|
||||||
|
|
@ -501,7 +501,9 @@ const asset_object& database_fixture::create_user_issued_asset( const string& na
|
||||||
creator.common_options.max_supply = GRAPHENE_MAX_SHARE_SUPPLY;
|
creator.common_options.max_supply = GRAPHENE_MAX_SHARE_SUPPLY;
|
||||||
creator.common_options.flags = flags;
|
creator.common_options.flags = flags;
|
||||||
creator.common_options.issuer_permissions = flags;
|
creator.common_options.issuer_permissions = flags;
|
||||||
|
trx.operations.clear();
|
||||||
trx.operations.push_back(std::move(creator));
|
trx.operations.push_back(std::move(creator));
|
||||||
|
set_expiration( db, trx );
|
||||||
trx.validate();
|
trx.validate();
|
||||||
processed_transaction ptx = db.push_transaction(trx, ~0);
|
processed_transaction ptx = db.push_transaction(trx, ~0);
|
||||||
trx.operations.clear();
|
trx.operations.clear();
|
||||||
|
|
|
||||||
|
|
@ -687,7 +687,7 @@ BOOST_AUTO_TEST_CASE( create_uia )
|
||||||
const asset_object& test_asset = test_asset_id(db);
|
const asset_object& test_asset = test_asset_id(db);
|
||||||
BOOST_CHECK(test_asset.symbol == "TEST");
|
BOOST_CHECK(test_asset.symbol == "TEST");
|
||||||
BOOST_CHECK(asset(1, test_asset_id) * test_asset.options.core_exchange_rate == asset(2));
|
BOOST_CHECK(asset(1, test_asset_id) * test_asset.options.core_exchange_rate == asset(2));
|
||||||
BOOST_CHECK(!test_asset.enforce_white_list());
|
BOOST_CHECK((test_asset.options.flags & white_list) == 0);
|
||||||
BOOST_CHECK(test_asset.options.max_supply == 100000000);
|
BOOST_CHECK(test_asset.options.max_supply == 100000000);
|
||||||
BOOST_CHECK(!test_asset.bitasset_data_id.valid());
|
BOOST_CHECK(!test_asset.bitasset_data_id.valid());
|
||||||
BOOST_CHECK(test_asset.options.market_fee_percent == GRAPHENE_MAX_MARKET_FEE_PERCENT/100);
|
BOOST_CHECK(test_asset.options.market_fee_percent == GRAPHENE_MAX_MARKET_FEE_PERCENT/100);
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE( create_advanced_uia )
|
||||||
const asset_object& test_asset = test_asset_id(db);
|
const asset_object& test_asset = test_asset_id(db);
|
||||||
BOOST_CHECK(test_asset.symbol == "ADVANCED");
|
BOOST_CHECK(test_asset.symbol == "ADVANCED");
|
||||||
BOOST_CHECK(asset(1, test_asset_id) * test_asset.options.core_exchange_rate == asset(2));
|
BOOST_CHECK(asset(1, test_asset_id) * test_asset.options.core_exchange_rate == asset(2));
|
||||||
BOOST_CHECK(test_asset.enforce_white_list());
|
BOOST_CHECK(test_asset.options.flags & white_list);
|
||||||
BOOST_CHECK(test_asset.options.max_supply == 100000000);
|
BOOST_CHECK(test_asset.options.max_supply == 100000000);
|
||||||
BOOST_CHECK(!test_asset.bitasset_data_id.valid());
|
BOOST_CHECK(!test_asset.bitasset_data_id.valid());
|
||||||
BOOST_CHECK(test_asset.options.market_fee_percent == GRAPHENE_MAX_MARKET_FEE_PERCENT/100);
|
BOOST_CHECK(test_asset.options.market_fee_percent == GRAPHENE_MAX_MARKET_FEE_PERCENT/100);
|
||||||
|
|
@ -414,5 +414,52 @@ BOOST_AUTO_TEST_CASE( transfer_restricted_test )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( asset_name_test )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ACTORS( (alice)(bob) );
|
||||||
|
|
||||||
|
auto has_asset = [&]( std::string symbol ) -> bool
|
||||||
|
{
|
||||||
|
const auto& assets_by_symbol = db.get_index_type<asset_index>().indices().get<by_symbol>();
|
||||||
|
return assets_by_symbol.find( symbol ) != assets_by_symbol.end();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Alice creates asset "ALPHA"
|
||||||
|
BOOST_CHECK( !has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") );
|
||||||
|
create_user_issued_asset( "ALPHA", alice_id(db), 0 );
|
||||||
|
BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") );
|
||||||
|
|
||||||
|
// Nobody can create another asset named ALPHA
|
||||||
|
GRAPHENE_REQUIRE_THROW( create_user_issued_asset( "ALPHA", bob_id(db), 0 ), fc::exception );
|
||||||
|
BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") );
|
||||||
|
GRAPHENE_REQUIRE_THROW( create_user_issued_asset( "ALPHA", alice_id(db), 0 ), fc::exception );
|
||||||
|
BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") );
|
||||||
|
|
||||||
|
// Bob can't create ALPHA.ONE
|
||||||
|
GRAPHENE_REQUIRE_THROW( create_user_issued_asset( "ALPHA.ONE", bob_id(db), 0 ), fc::exception );
|
||||||
|
BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") );
|
||||||
|
if( db.head_block_time() <= HARDFORK_409_TIME )
|
||||||
|
{
|
||||||
|
// Alice can't create ALPHA.ONE before hardfork
|
||||||
|
GRAPHENE_REQUIRE_THROW( create_user_issued_asset( "ALPHA.ONE", alice_id(db), 0 ), fc::exception );
|
||||||
|
BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") );
|
||||||
|
generate_blocks( HARDFORK_409_TIME );
|
||||||
|
generate_block();
|
||||||
|
// Bob can't create ALPHA.ONE after hardfork
|
||||||
|
GRAPHENE_REQUIRE_THROW( create_user_issued_asset( "ALPHA.ONE", bob_id(db), 0 ), fc::exception );
|
||||||
|
BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") );
|
||||||
|
}
|
||||||
|
// Alice can create it
|
||||||
|
create_user_issued_asset( "ALPHA.ONE", alice_id(db), 0 );
|
||||||
|
BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( has_asset("ALPHA.ONE") );
|
||||||
|
}
|
||||||
|
catch(fc::exception& e)
|
||||||
|
{
|
||||||
|
edump((e.to_detail_string()));
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue