diff --git a/contracts/CMakeLists.txt b/contracts/CMakeLists.txt index 69d438e1..7f02640f 100644 --- a/contracts/CMakeLists.txt +++ b/contracts/CMakeLists.txt @@ -7,17 +7,7 @@ find_package(eosio.cdt) set(ICON_BASE_URL "http://127.0.0.1/ricardian_assets/eosio.contracts/icons") -set(ACCOUNT_ICON_URI "account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f") -set(ADMIN_ICON_URI "admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e") -set(MULTISIG_ICON_URI "multisig.png#4fb41d3cf02d0dd2d35a29308e93c2d826ec770d6bb520db668f530764be7153") -set(RESOURCE_ICON_URI "resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19") -set(REX_ICON_URI "rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8") set(TOKEN_ICON_URI "token.png#207ff68b0406eaa56618b08bda81d6a0954543f36adc328ab3065f31a5c5d654") set(TRANSFER_ICON_URI "transfer.png#5dfad0df72772ee1ccc155e670c1d124f5c5122f1d5027565df38b418042d1dd") -set(VOTING_ICON_URI "voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84") -add_subdirectory(eosio.bios) -add_subdirectory(eosio.msig) -add_subdirectory(eosio.system) add_subdirectory(eosio.token) -add_subdirectory(eosio.wrap) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp deleted file mode 100644 index 89f7dbc9..00000000 --- a/tests/eosio.msig_tests.cpp +++ /dev/null @@ -1,1002 +0,0 @@ -#include -#include -#include -#include - -#include - -#include -#include "contracts.hpp" -#include "test_symbol.hpp" - -using namespace eosio::testing; -using namespace eosio; -using namespace eosio::chain; -using namespace eosio::testing; -using namespace fc; - -using mvo = fc::mutable_variant_object; - -class eosio_msig_tester : public tester { -public: - eosio_msig_tester() { - create_accounts( { N(eosio.msig), N(eosio.stake), N(eosio.ram), N(eosio.ramfee), N(alice), N(bob), N(carol) } ); - produce_block(); - - auto trace = base_tester::push_action(config::system_account_name, N(setpriv), - config::system_account_name, mutable_variant_object() - ("account", "eosio.msig") - ("is_priv", 1) - ); - - set_code( N(eosio.msig), contracts::msig_wasm() ); - set_abi( N(eosio.msig), contracts::msig_abi().data() ); - - produce_blocks(); - const auto& accnt = control->db().get( N(eosio.msig) ); - abi_def abi; - BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); - } - - transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, - asset net = core_sym::from_string("10.0000"), asset cpu = core_sym::from_string("10.0000") ) { - signed_transaction trx; - set_transaction_headers(trx); - - authority owner_auth; - if (multisig) { - // multisig between account's owner key and creators active permission - owner_auth = authority(2, {key_weight{get_public_key( a, "owner" ), 1}}, {permission_level_weight{{creator, config::active_name}, 1}}); - } else { - owner_auth = authority( get_public_key( a, "owner" ) ); - } - - trx.actions.emplace_back( vector{{creator,config::active_name}}, - newaccount{ - .creator = creator, - .name = a, - .owner = owner_auth, - .active = authority( get_public_key( a, "active" ) ) - }); - - trx.actions.emplace_back( get_action( N(eosio), N(buyram), vector{{creator,config::active_name}}, - mvo() - ("payer", creator) - ("receiver", a) - ("quant", ramfunds) ) - ); - - trx.actions.emplace_back( get_action( N(eosio), N(delegatebw), vector{{creator,config::active_name}}, - mvo() - ("from", creator) - ("receiver", a) - ("stake_net_quantity", net ) - ("stake_cpu_quantity", cpu ) - ("transfer", 0 ) - ) - ); - - set_transaction_headers(trx); - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - return push_transaction( trx ); - } - void create_currency( name contract, name manager, asset maxsupply ) { - auto act = mutable_variant_object() - ("issuer", manager ) - ("maximum_supply", maxsupply ); - - base_tester::push_action(contract, N(create), contract, act ); - } - void issue( name to, const asset& amount, name manager = config::system_account_name ) { - base_tester::push_action( N(eosio.token), N(issue), manager, mutable_variant_object() - ("to", to ) - ("quantity", amount ) - ("memo", "") - ); - } - void transfer( name from, name to, const string& amount, name manager = config::system_account_name ) { - base_tester::push_action( N(eosio.token), N(transfer), manager, mutable_variant_object() - ("from", from) - ("to", to ) - ("quantity", asset::from_string(amount) ) - ("memo", "") - ); - } - asset get_balance( const account_name& act ) { - //return get_currency_balance( config::system_account_name, symbol(CORE_SYMBOL), act ); - //temporary code. current get_currency_balancy uses table name N(accounts) from currency.h - //generic_currency table name is N(account). - const auto& db = control->db(); - const auto* tbl = db.find(boost::make_tuple(N(eosio.token), act, N(accounts))); - share_type result = 0; - - // the balance is implied to be 0 if either the table or row does not exist - if (tbl) { - const auto *obj = db.find(boost::make_tuple(tbl->id, symbol(CORE_SYM).to_symbol_code())); - if (obj) { - // balance is the first field in the serialization - fc::datastream ds(obj->value.data(), obj->value.size()); - fc::raw::unpack(ds, result); - } - } - return asset( result, symbol(CORE_SYM) ); - } - - transaction_trace_ptr push_action( const account_name& signer, const action_name& name, const variant_object& data, bool auth = true ) { - vector accounts; - if( auth ) - accounts.push_back( signer ); - auto trace = base_tester::push_action( N(eosio.msig), name, accounts, data ); - produce_block(); - BOOST_REQUIRE_EQUAL( true, chain_has_transaction(trace->id) ); - return trace; - - /* - string action_type_name = abi_ser.get_action_type(name); - - action act; - act.account = N(eosio.msig); - act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - //std::cout << "test:\n" << fc::to_hex(act.data.data(), act.data.size()) << " size = " << act.data.size() << std::endl; - - return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : 0 ); - */ - } - - transaction reqauth( account_name from, const vector& auths, const fc::microseconds& max_serialization_time ); - - abi_serializer abi_ser; -}; - -transaction eosio_msig_tester::reqauth( account_name from, const vector& auths, const fc::microseconds& max_serialization_time ) { - fc::variants v; - for ( auto& level : auths ) { - v.push_back(fc::mutable_variant_object() - ("actor", level.actor) - ("permission", level.permission) - ); - } - variant pretty_trx = fc::mutable_variant_object() - ("expiration", "2020-01-01T00:30") - ("ref_block_num", 2) - ("ref_block_prefix", 3) - ("max_net_usage_words", 0) - ("max_cpu_usage_ms", 0) - ("delay_sec", 0) - ("actions", fc::variants({ - fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("name", "reqauth") - ("authorization", v) - ("data", fc::mutable_variant_object() ("from", from) ) - }) - ); - transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(max_serialization_time)); - return trx; -} - -BOOST_AUTO_TEST_SUITE(eosio_msig_tests) - -BOOST_FIXTURE_TEST_CASE( propose_approve_execute, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - //fail to execute before approval - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - - //approve and execute - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( propose_approve_unapprove, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - push_action( N(alice), N(unapprove), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( propose_approve_by_two, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }) - ); - - //approve by alice - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - //fail because approval by bob is missing - - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - - //approve by bob and execute - push_action( N(bob), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(bob), config::active_name }) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( propose_with_wrong_requested_auth, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); - //try with not enough requested auth - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "third") - ("trx", trx) - ("requested", vector{ { N(alice), config::active_name } } ) - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( big_transaction, eosio_msig_tester ) try { - vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name } }; - auto wasm = contracts::util::exchange_wasm(); - - variant pretty_trx = fc::mutable_variant_object() - ("expiration", "2020-01-01T00:30") - ("ref_block_num", 2) - ("ref_block_prefix", 3) - ("max_net_usage_words", 0) - ("max_cpu_usage_ms", 0) - ("delay_sec", 0) - ("actions", fc::variants({ - fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("name", "setcode") - ("authorization", perm) - ("data", fc::mutable_variant_object() - ("account", "alice") - ("vmtype", 0) - ("vmversion", 0) - ("code", bytes( wasm.begin(), wasm.end() )) - ) - }) - ); - - transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", perm) - ); - - //approve by alice - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - //approve by bob and execute - push_action( N(bob), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(bob), config::active_name }) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); -} FC_LOG_AND_RETHROW() - - - -BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) try { - - // required to set up the link between (eosio active) and (eosio.prods active) - // - // eosio active - // | - // eosio.prods active (2/3 threshold) - // / | \ <--- implicitly updated in onblock action - // alice active bob active carol active - - set_authority( - config::system_account_name, - config::active_name, - authority( 1, - vector{{get_private_key(config::system_account_name, "active").get_public_key(), 1}}, - vector{{{N(eosio.prods), config::active_name}, 1}} - ), - config::owner_name, - {{config::system_account_name, config::active_name}}, - {get_private_key(config::system_account_name, "active")} - ); - - set_producers( {N(alice),N(bob),N(carol)} ); - produce_blocks(50); - - create_accounts( { N(eosio.token), N(eosio.rex) } ); - set_code( N(eosio.token), contracts::token_wasm() ); - set_abi( N(eosio.token), contracts::token_abi().data() ); - - create_currency( N(eosio.token), config::system_account_name, core_sym::from_string("10000000000.0000") ); - issue(config::system_account_name, core_sym::from_string("1000000000.0000")); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), - get_balance(config::system_account_name) + get_balance(N(eosio.ramfee)) + get_balance(N(eosio.stake)) + get_balance(N(eosio.ram)) ); - - set_code( config::system_account_name, contracts::system_wasm() ); - set_abi( config::system_account_name, contracts::system_abi().data() ); - base_tester::push_action( config::system_account_name, N(init), - config::system_account_name, mutable_variant_object() - ("version", 0) - ("core", CORE_SYM_STR) - ); - produce_blocks(); - create_account_with_resources( N(alice1111111), N(eosio), core_sym::from_string("1.0000"), false ); - create_account_with_resources( N(bob111111111), N(eosio), core_sym::from_string("0.4500"), false ); - create_account_with_resources( N(carol1111111), N(eosio), core_sym::from_string("1.0000"), false ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), - get_balance(config::system_account_name) + get_balance(N(eosio.ramfee)) + get_balance(N(eosio.stake)) + get_balance(N(eosio.ram)) ); - - vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name }, - {N(carol), config::active_name} }; - - vector action_perm = {{N(eosio), config::active_name}}; - - auto wasm = contracts::util::reject_all_wasm(); - - variant pretty_trx = fc::mutable_variant_object() - ("expiration", "2020-01-01T00:30") - ("ref_block_num", 2) - ("ref_block_prefix", 3) - ("max_net_usage_words", 0) - ("max_cpu_usage_ms", 0) - ("delay_sec", 0) - ("actions", fc::variants({ - fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("name", "setcode") - ("authorization", action_perm) - ("data", fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("vmtype", 0) - ("vmversion", 0) - ("code", bytes( wasm.begin(), wasm.end() )) - ) - }) - ); - - transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - - // propose action - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", perm) - ); - - //approve by alice - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - //approve by bob - push_action( N(bob), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(bob), config::active_name }) - ); - //approve by carol - push_action( N(carol), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(carol), config::active_name }) - ); - // execute by alice to replace the eosio system contract - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - - // can't create account because system contract was replaced by the reject_all contract - - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(alice1111112), N(eosio), core_sym::from_string("1.0000"), false ), - eosio_assert_message_exception, eosio_assert_message_is("rejecting all actions") - - ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester ) try { - - // set up the link between (eosio active) and (eosio.prods active) - set_authority( - config::system_account_name, - config::active_name, - authority( 1, - vector{{get_private_key(config::system_account_name, "active").get_public_key(), 1}}, - vector{{{N(eosio.prods), config::active_name}, 1}} - ), - config::owner_name, - {{config::system_account_name, config::active_name}}, - {get_private_key(config::system_account_name, "active")} - ); - - create_accounts( { N(apple) } ); - set_producers( {N(alice),N(bob),N(carol), N(apple)} ); - produce_blocks(50); - - create_accounts( { N(eosio.token), N(eosio.rex) } ); - set_code( N(eosio.token), contracts::token_wasm() ); - set_abi( N(eosio.token), contracts::token_abi().data() ); - - create_currency( N(eosio.token), config::system_account_name, core_sym::from_string("10000000000.0000") ); - issue(config::system_account_name, core_sym::from_string("1000000000.0000")); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance( config::system_account_name ) ); - - set_code( config::system_account_name, contracts::system_wasm() ); - set_abi( config::system_account_name, contracts::system_abi().data() ); - base_tester::push_action( config::system_account_name, N(init), - config::system_account_name, mutable_variant_object() - ("version", 0) - ("core", CORE_SYM_STR) - ); - produce_blocks(); - - create_account_with_resources( N(alice1111111), N(eosio), core_sym::from_string("1.0000"), false ); - create_account_with_resources( N(bob111111111), N(eosio), core_sym::from_string("0.4500"), false ); - create_account_with_resources( N(carol1111111), N(eosio), core_sym::from_string("1.0000"), false ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), - get_balance(config::system_account_name) + get_balance(N(eosio.ramfee)) + get_balance(N(eosio.stake)) + get_balance(N(eosio.ram)) ); - - vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name }, - {N(carol), config::active_name}, {N(apple), config::active_name}}; - - vector action_perm = {{N(eosio), config::active_name}}; - - auto wasm = contracts::util::reject_all_wasm(); - - variant pretty_trx = fc::mutable_variant_object() - ("expiration", "2020-01-01T00:30") - ("ref_block_num", 2) - ("ref_block_prefix", 3) - ("max_net_usage_words", 0) - ("max_cpu_usage_ms", 0) - ("delay_sec", 0) - ("actions", fc::variants({ - fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("name", "setcode") - ("authorization", action_perm) - ("data", fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("vmtype", 0) - ("vmversion", 0) - ("code", bytes( wasm.begin(), wasm.end() )) - ) - }) - ); - - transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - - // propose action - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", perm) - ); - - //approve by alice - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - //approve by bob - push_action( N(bob), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(bob), config::active_name }) - ); - - // not enough approvers - BOOST_REQUIRE_EXCEPTION( - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, eosio_assert_message_is("transaction authorization failed") - ); - - //approve by apple - push_action( N(apple), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(apple), config::active_name }) - ); - // execute by alice to replace the eosio system contract - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - // execute by another producer different from proposer - push_action( N(apple), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "apple") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - - // can't create account because system contract was replaced by the reject_all contract - - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(alice1111112), N(eosio), core_sym::from_string("1.0000"), false ), - eosio_assert_message_exception, eosio_assert_message_is("rejecting all actions") - - ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( propose_approve_invalidate, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - //fail to execute before approval - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - - //approve - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - //invalidate - push_action( N(alice), N(invalidate), mvo() - ("account", "alice") - ); - - //fail to execute after invalidation - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( propose_invalidate_approve, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - //fail to execute before approval - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - - //invalidate - push_action( N(alice), N(invalidate), mvo() - ("account", "alice") - ); - - //approve - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - //successfully execute - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(bob), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "bob") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( approve_execute_old, eosio_msig_tester ) try { - set_code( N(eosio.msig), contracts::util::msig_wasm_old() ); - set_abi( N(eosio.msig), contracts::util::msig_abi_old().data() ); - produce_blocks(); - - //propose with old version of eosio.msig - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - set_code( N(eosio.msig), contracts::msig_wasm() ); - set_abi( N(eosio.msig), contracts::msig_abi().data() ); - produce_blocks(); - - //approve and execute with new version - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( approve_unapprove_old, eosio_msig_tester ) try { - set_code( N(eosio.msig), contracts::util::msig_wasm_old() ); - set_abi( N(eosio.msig), contracts::util::msig_abi_old().data() ); - produce_blocks(); - - //propose with old version of eosio.msig - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - //approve with old version - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - set_code( N(eosio.msig), contracts::msig_wasm() ); - set_abi( N(eosio.msig), contracts::msig_abi().data() ); - produce_blocks(); - - //unapprove with old version - push_action( N(alice), N(unapprove), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( approve_by_two_old, eosio_msig_tester ) try { - set_code( N(eosio.msig), contracts::util::msig_wasm_old() ); - set_abi( N(eosio.msig), contracts::util::msig_abi_old().data() ); - produce_blocks(); - - auto trx = reqauth( N(alice), vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }) - ); - - //approve by alice - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - set_code( N(eosio.msig), contracts::msig_wasm() ); - set_abi( N(eosio.msig), contracts::msig_abi().data() ); - produce_blocks(); - - //fail because approval by bob is missing - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - - //approve and execute with new version - push_action( N(bob), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(bob), config::active_name }) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( approve_with_hash, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - auto trx_hash = fc::sha256::hash( trx ); - auto not_trx_hash = fc::sha256::hash( trx_hash ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - //fail to approve with incorrect hash - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ("proposal_hash", not_trx_hash) - ), - eosio::chain::crypto_api_exception, - fc_exception_message_is("hash mismatch") - ); - - //approve and execute - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ("proposal_hash", trx_hash) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( switch_proposal_and_fail_approve_with_hash, eosio_msig_tester ) try { - auto trx1 = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - auto trx1_hash = fc::sha256::hash( trx1 ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx1) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - auto trx2 = reqauth( N(alice), - { permission_level{N(alice), config::active_name}, - permission_level{N(alice), config::owner_name} }, - abi_serializer_max_time ); - - push_action( N(alice), N(cancel), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("canceler", "alice") - ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx2) - ("requested", vector{ { N(alice), config::active_name }, - { N(alice), config::owner_name } }) - ); - - //fail to approve with hash meant for old proposal - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ("proposal_hash", trx1_hash) - ), - eosio::chain::crypto_api_exception, - fc_exception_message_is("hash mismatch") - ); -} FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/eosio.powerup_tests.cpp b/tests/eosio.powerup_tests.cpp deleted file mode 100644 index 3c8f43e0..00000000 --- a/tests/eosio.powerup_tests.cpp +++ /dev/null @@ -1,858 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "eosio.system_tester.hpp" - -inline constexpr int64_t powerup_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 -inline constexpr int64_t stake_weight = 100'000'000'0000ll; // 10^12 - -struct powerup_config_resource { - fc::optional current_weight_ratio = {}; - fc::optional target_weight_ratio = {}; - fc::optional assumed_stake_weight = {}; - fc::optional target_timestamp = {}; - fc::optional exponent = {}; - fc::optional decay_secs = {}; - fc::optional min_price = {}; - fc::optional max_price = {}; -}; -FC_REFLECT(powerup_config_resource, // - (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight)(target_timestamp) // - (exponent)(decay_secs)(min_price)(max_price)) - -struct powerup_config { - powerup_config_resource net = {}; - powerup_config_resource cpu = {}; - fc::optional powerup_days = {}; - fc::optional min_powerup_fee = {}; -}; -FC_REFLECT(powerup_config, (net)(cpu)(powerup_days)(min_powerup_fee)) - -struct powerup_state_resource { - uint8_t version; - int64_t weight; - int64_t weight_ratio; - int64_t assumed_stake_weight; - int64_t initial_weight_ratio; - int64_t target_weight_ratio; - time_point_sec initial_timestamp; - time_point_sec target_timestamp; - double exponent; - uint32_t decay_secs; - asset min_price; - asset max_price; - int64_t utilization; - int64_t adjusted_utilization; - time_point_sec utilization_timestamp; -}; -FC_REFLECT(powerup_state_resource, // - (version)(weight)(weight_ratio)(assumed_stake_weight)(initial_weight_ratio)(target_weight_ratio) // - (initial_timestamp)(target_timestamp)(exponent)(decay_secs)(min_price)(max_price)(utilization) // - (adjusted_utilization)(utilization_timestamp)) - -struct powerup_state { - uint8_t version; - powerup_state_resource net; - powerup_state_resource cpu; - uint32_t powerup_days; - asset min_powerup_fee; -}; -FC_REFLECT(powerup_state, (version)(net)(cpu)(powerup_days)(min_powerup_fee)) - -using namespace eosio_system; - -struct powerup_tester : eosio_system_tester { - - powerup_tester() { create_accounts_with_resources({ N(eosio.reserv) }); } - - void start_rex() { - create_account_with_resources(N(rexholder111), config::system_account_name, core_sym::from_string("1.0000"), - false); - transfer(config::system_account_name, N(rexholder111), core_sym::from_string("1001.0000")); - BOOST_REQUIRE_EQUAL("", stake(N(rexholder111), N(rexholder111), core_sym::from_string("500.0000"), - core_sym::from_string("500.0000"))); - create_account_with_resources(N(proxyaccount), config::system_account_name, core_sym::from_string("1.0000"), - false, core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); - BOOST_REQUIRE_EQUAL("", - push_action(N(proxyaccount), N(regproxy), mvo()("proxy", "proxyaccount")("isproxy", true))); - BOOST_REQUIRE_EQUAL("", vote(N(rexholder111), {}, N(proxyaccount))); - BOOST_REQUIRE_EQUAL("", push_action(N(rexholder111), N(deposit), - mvo()("owner", "rexholder111")("amount", asset::from_string("1.0000 TST")))); - BOOST_REQUIRE_EQUAL("", push_action(N(rexholder111), N(buyrex), - mvo()("from", "rexholder111")("amount", asset::from_string("1.0000 TST")))); - } - - template - powerup_config make_config(F f) { - powerup_config config; - - config.net.current_weight_ratio = powerup_frac; - config.net.target_weight_ratio = powerup_frac / 100; - config.net.assumed_stake_weight = stake_weight; - config.net.target_timestamp = control->head_block_time() + fc::days(100); - config.net.exponent = 2; - config.net.decay_secs = fc::days(1).to_seconds(); - config.net.min_price = asset::from_string("0.0000 TST"); - config.net.max_price = asset::from_string("1000000.0000 TST"); - - config.cpu.current_weight_ratio = powerup_frac; - config.cpu.target_weight_ratio = powerup_frac / 100; - config.cpu.assumed_stake_weight = stake_weight; - config.cpu.target_timestamp = control->head_block_time() + fc::days(100); - config.cpu.exponent = 2; - config.cpu.decay_secs = fc::days(1).to_seconds(); - config.cpu.min_price = asset::from_string("0.0000 TST"); - config.cpu.max_price = asset::from_string("1000000.0000 TST"); - - config.powerup_days = 30; - config.min_powerup_fee = asset::from_string("1.0000 TST"); - - f(config); - return config; - } - - powerup_config make_config() { - return make_config([](auto&) {}); - } - - template - powerup_config make_default_config(F f) { - powerup_config config; - f(config); - return config; - } - - action_result configbw(const powerup_config& config) { - // Verbose solution needed to work around bug in abi_serializer that fails if optional values aren't explicitly - // specified with a null value. - - auto optional_to_variant = []( const auto& v ) -> fc::variant { - return (!v ? fc::variant() : fc::variant(*v)); - }; - - auto resource_conf_vo = [&optional_to_variant](const powerup_config_resource& c ) { - return mvo("current_weight_ratio", optional_to_variant(c.current_weight_ratio)) - ("target_weight_ratio", optional_to_variant(c.target_weight_ratio)) - ("assumed_stake_weight", optional_to_variant(c.assumed_stake_weight)) - ("target_timestamp", optional_to_variant(c.target_timestamp)) - ("exponent", optional_to_variant(c.exponent)) - ("decay_secs", optional_to_variant(c.decay_secs)) - ("min_price", optional_to_variant(c.min_price)) - ("max_price", optional_to_variant(c.max_price)) - ; - }; - - auto conf = mvo("net", resource_conf_vo(config.net)) - ("cpu", resource_conf_vo(config.cpu)) - ("powerup_days", optional_to_variant(config.powerup_days)) - ("min_powerup_fee", optional_to_variant(config.min_powerup_fee)) - ; - - //idump((fc::json::to_pretty_string(conf))); - return push_action(config::system_account_name, N(cfgpowerup), mvo()("args", std::move(conf))); - - // If abi_serializer worked correctly, the following is all that would be needed: - //return push_action(config::system_account_name, N(cfgpowerup), mvo()("args", config)); - } - - action_result powerupexec(name user, uint16_t max) { - return push_action(user, N(powerupexec), mvo()("user", user)("max", max)); - } - - action_result powerup(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, - const asset& max_payment) { - return push_action(payer, N(powerup), - mvo()("payer", payer)("receiver", receiver)("days", days)("net_frac", net_frac)( - "cpu_frac", cpu_frac)("max_payment", max_payment)); - } - - powerup_state get_state() { - vector data = get_row_by_account(config::system_account_name, {}, N(powup.state), N(powup.state)); - return fc::raw::unpack(data); - } - - struct account_info { - int64_t ram = 0; - int64_t net = 0; - int64_t cpu = 0; - asset liquid; - }; - - account_info get_account_info(account_name acc) { - account_info info; - control->get_resource_limits_manager().get_account_limits(acc, info.ram, info.net, info.cpu); - info.liquid = get_balance(acc); - return info; - }; - - void check_powerup(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, - const asset& expected_fee, int64_t expected_net, int64_t expected_cpu) { - auto before_payer = get_account_info(payer); - auto before_receiver = get_account_info(receiver); - auto before_reserve = get_account_info(N(eosio.reserv)); - auto before_state = get_state(); - BOOST_REQUIRE_EQUAL("", powerup(payer, receiver, days, net_frac, cpu_frac, expected_fee)); - auto after_payer = get_account_info(payer); - auto after_receiver = get_account_info(receiver); - auto after_reserve = get_account_info(N(eosio.reserv)); - auto after_state = get_state(); - - if (false) { - ilog("before_state.net.assumed_stake_weight: ${x}", ("x", before_state.net.assumed_stake_weight)); - ilog("before_state.net.weight_ratio: ${x}", - ("x", before_state.net.weight_ratio / double(powerup_frac))); - ilog("before_state.net.assumed_stake_weight: ${x}", ("x", before_state.net.assumed_stake_weight)); - ilog("before_state.net.weight: ${x}", ("x", before_state.net.weight)); - - ilog("before_receiver.net: ${x}", ("x", before_receiver.net)); - ilog("after_receiver.net: ${x}", ("x", after_receiver.net)); - ilog("after_receiver.net - before_receiver.net: ${x}", ("x", after_receiver.net - before_receiver.net)); - ilog("expected_net: ${x}", ("x", expected_net)); - ilog("before_payer.liquid - after_payer.liquid: ${x}", ("x", before_payer.liquid - after_payer.liquid)); - ilog("expected_fee: ${x}", ("x", expected_fee)); - - ilog("before_reserve.net: ${x}", ("x", before_reserve.net)); - ilog("after_reserve.net: ${x}", ("x", after_reserve.net)); - ilog("before_reserve.cpu: ${x}", ("x", before_reserve.cpu)); - ilog("after_reserve.cpu: ${x}", ("x", after_reserve.cpu)); - } - - if (payer != receiver) { - BOOST_REQUIRE_EQUAL(before_payer.ram, after_payer.ram); - BOOST_REQUIRE_EQUAL(before_payer.net, after_payer.net); - BOOST_REQUIRE_EQUAL(before_payer.cpu, after_payer.cpu); - BOOST_REQUIRE_EQUAL(before_receiver.liquid, after_receiver.liquid); - } - BOOST_REQUIRE_EQUAL(before_receiver.ram, after_receiver.ram); - BOOST_REQUIRE_EQUAL(after_receiver.net - before_receiver.net, expected_net); - BOOST_REQUIRE_EQUAL(after_receiver.cpu - before_receiver.cpu, expected_cpu); - BOOST_REQUIRE_EQUAL(before_payer.liquid - after_payer.liquid, expected_fee); - - BOOST_REQUIRE_EQUAL(before_reserve.net - after_reserve.net, expected_net); - BOOST_REQUIRE_EQUAL(before_reserve.cpu - after_reserve.cpu, expected_cpu); - BOOST_REQUIRE_EQUAL(after_state.net.utilization - before_state.net.utilization, expected_net); - BOOST_REQUIRE_EQUAL(after_state.cpu.utilization - before_state.cpu.utilization, expected_cpu); - } -}; - -template -bool near(A a, B b, D delta) { - if (abs(a - b) <= delta) - return true; - elog("near: ${a} ${b}", ("a", a)("b", b)); - return false; -} - -BOOST_AUTO_TEST_SUITE(eosio_system_powerup_tests) - -BOOST_FIXTURE_TEST_CASE(config_tests, powerup_tester) try { - BOOST_REQUIRE_EQUAL("missing authority of eosio", - push_action(N(alice1111111), N(cfgpowerup), mvo()("args", make_config()))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("powerup hasn't been initialized"), powerupexec(N(alice1111111), 10)); - - BOOST_REQUIRE_EQUAL(wasm_assert_msg("powerup_days must be > 0"), - configbw(make_config([&](auto& c) { c.powerup_days = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_powerup_fee doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.min_powerup_fee = asset::from_string("1000000.000 TST"); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_powerup_fee does not have a default value"), - configbw(make_config([&](auto& c) { c.min_powerup_fee = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_powerup_fee must be positive"), - configbw(make_config([&](auto& c) { c.min_powerup_fee = asset::from_string("0.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_powerup_fee must be positive"), - configbw(make_config([&](auto& c) { c.min_powerup_fee = asset::from_string("-1.0000 TST"); }))); - - // net assertions - BOOST_REQUIRE_EQUAL(wasm_assert_msg("current_weight_ratio is too large"), - configbw(make_config([](auto& c) { c.net.current_weight_ratio = powerup_frac + 1; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight/target_weight_ratio is too large"), - configbw(make_config([](auto& c) { - c.net.assumed_stake_weight = 100000; - c.net.target_weight_ratio = 10; - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("weight can't grow over time"), - configbw(make_config([](auto& c) { c.net.target_weight_ratio = powerup_frac + 1; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight does not have a default value"), - configbw(make_config([](auto& c) { c.net.assumed_stake_weight = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight must be at least 1; a much larger value is recommended"), - configbw(make_config([](auto& c) { c.net.assumed_stake_weight = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp does not have a default value"), - configbw(make_config([&](auto& c) { c.net.target_timestamp = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), - configbw(make_config([&](auto& c) { c.net.target_timestamp = control->head_block_time(); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), configbw(make_config([&](auto& c) { - c.net.target_timestamp = control->head_block_time() - fc::seconds(1); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("exponent must be >= 1"), - configbw(make_config([&](auto& c) { c.net.exponent = .999; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), - configbw(make_config([&](auto& c) { c.net.decay_secs = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price does not have a default value"), - configbw(make_config([&](auto& c) { c.net.max_price = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.net.max_price = asset::from_string("1000000.000 TST"); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price must be positive"), - configbw(make_config([&](auto& c) { c.net.max_price = asset::from_string("0.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price must be positive"), - configbw(make_config([&](auto& c) { c.net.max_price = asset::from_string("-1.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.net.min_price = asset::from_string("1000000.000 TST"); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price must be non-negative"), - configbw(make_config([&](auto& c) { c.net.min_price = asset::from_string("-1.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price cannot exceed max_price"), - configbw(make_config([&](auto& c) { - c.net.min_price = asset::from_string("3.0000 TST"); - c.net.max_price = asset::from_string("2.0000 TST"); - }))); - - // cpu assertions - BOOST_REQUIRE_EQUAL(wasm_assert_msg("current_weight_ratio is too large"), - configbw(make_config([](auto& c) { c.cpu.current_weight_ratio = powerup_frac + 1; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight/target_weight_ratio is too large"), - configbw(make_config([](auto& c) { - c.cpu.assumed_stake_weight = 100000; - c.cpu.target_weight_ratio = 10; - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("weight can't grow over time"), - configbw(make_config([](auto& c) { c.cpu.target_weight_ratio = powerup_frac + 1; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight does not have a default value"), - configbw(make_config([](auto& c) { c.cpu.assumed_stake_weight = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight must be at least 1; a much larger value is recommended"), - configbw(make_config([](auto& c) { c.cpu.assumed_stake_weight = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp does not have a default value"), - configbw(make_config([&](auto& c) { c.cpu.target_timestamp = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), - configbw(make_config([&](auto& c) { c.cpu.target_timestamp = control->head_block_time(); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), configbw(make_config([&](auto& c) { - c.cpu.target_timestamp = control->head_block_time() - fc::seconds(1); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("exponent must be >= 1"), - configbw(make_config([&](auto& c) { c.cpu.exponent = .999; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), - configbw(make_config([&](auto& c) { c.cpu.decay_secs = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price does not have a default value"), - configbw(make_config([&](auto& c) { c.cpu.max_price = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.cpu.max_price = asset::from_string("1000000.000 TST"); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price must be positive"), - configbw(make_config([&](auto& c) { c.cpu.max_price = asset::from_string("0.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price must be positive"), - configbw(make_config([&](auto& c) { c.cpu.max_price = asset::from_string("-1.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.cpu.min_price = asset::from_string("1000000.000 TST"); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price must be non-negative"), - configbw(make_config([&](auto& c) { c.cpu.min_price = asset::from_string("-1.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price cannot exceed max_price"), - configbw(make_config([&](auto& c) { - c.cpu.min_price = asset::from_string("3.0000 TST"); - c.cpu.max_price = asset::from_string("2.0000 TST"); - }))); -} // config_tests -FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(weight_tests, powerup_tester) try { - produce_block(); - - auto net_start = (powerup_frac * 11) / 100; - auto net_target = (powerup_frac * 1) / 100; - auto cpu_start = (powerup_frac * 11) / 1000; - auto cpu_target = (powerup_frac * 1) / 1000; - - BOOST_REQUIRE_EQUAL("", configbw(make_config([&](powerup_config& config) { - config.net.current_weight_ratio = net_start; - config.net.target_weight_ratio = net_target; - config.net.assumed_stake_weight = stake_weight; - config.net.target_timestamp = control->head_block_time() + fc::days(10); - - config.cpu.current_weight_ratio = cpu_start; - config.cpu.target_weight_ratio = cpu_target; - config.cpu.assumed_stake_weight = stake_weight; - config.cpu.target_timestamp = control->head_block_time() + fc::days(20); - }))); - - int64_t net; - int64_t cpu; - - auto check_weight = [&] { - auto state = get_state(); - BOOST_REQUIRE(near( // - state.net.weight_ratio, // - int64_t(state.net.assumed_stake_weight * eosio::chain::int128_t(powerup_frac) / - (state.net.weight + state.net.assumed_stake_weight)), - 10)); - }; - - for (int i = 0; i <= 6; ++i) { - if (i == 2) { - // Leaves config as-is, but may introduce slight rounding - produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", configbw({})); - } else if (i) { - produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", powerupexec(config::system_account_name, 10)); - } - net = net_start + i * (net_target - net_start) / 10; - cpu = cpu_start + i * (cpu_target - cpu_start) / 20; - BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); - BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); - check_weight(); - } - - // Extend transition time - { - int i = 7; - produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](powerup_config& config) { - config.net.target_timestamp = control->head_block_time() + fc::days(30); - config.cpu.target_timestamp = control->head_block_time() + fc::days(40); - }))); - net_start = net = net_start + i * (net_target - net_start) / 10; - cpu_start = cpu = cpu_start + i * (cpu_target - cpu_start) / 20; - BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); - BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); - check_weight(); - } - - for (int i = 0; i <= 5; ++i) { - if (i) { - produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", powerupexec(config::system_account_name, 10)); - } - net = net_start + i * (net_target - net_start) / 30; - cpu = cpu_start + i * (cpu_target - cpu_start) / 40; - BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); - BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); - check_weight(); - } - - // Change target, keep existing transition time - { - int i = 6; - produce_block(fc::days(1) - fc::milliseconds(500)); - auto new_net_target = net_target / 10; - auto new_cpu_target = cpu_target / 20; - BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](powerup_config& config) { - config.net.target_weight_ratio = new_net_target; - config.cpu.target_weight_ratio = new_cpu_target; - }))); - net_start = net = net_start + i * (net_target - net_start) / 30; - cpu_start = cpu = cpu_start + i * (cpu_target - cpu_start) / 40; - net_target = new_net_target; - cpu_target = new_cpu_target; - BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); - BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); - check_weight(); - } - - for (int i = 0; i <= 10; ++i) { - if (i) { - produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", powerupexec(config::system_account_name, 10)); - } - net = net_start + i * (net_target - net_start) / (30 - 6); - cpu = cpu_start + i * (cpu_target - cpu_start) / (40 - 6); - BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); - BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); - check_weight(); - } - - // Move transition time to immediate future - { - produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](powerup_config& config) { - config.net.target_timestamp = control->head_block_time() + fc::milliseconds(1000); - config.cpu.target_timestamp = control->head_block_time() + fc::milliseconds(1000); - }))); - produce_blocks(2); - } - - // Verify targets hold as time advances - for (int i = 0; i <= 10; ++i) { - BOOST_REQUIRE_EQUAL("", powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(get_state().net.weight_ratio, net_target, 1)); - BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu_target, 1)); - check_weight(); - produce_block(fc::days(1)); - } -} // weight_tests -FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_CASE(rent_tests) try { - { - powerup_tester t; - t.produce_block(); - - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("powerup hasn't been initialized"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 4, powerup_frac / 8, - asset::from_string("1.000 TST"))); - - BOOST_REQUIRE_EQUAL("", t.configbw(t.make_config([&](auto& config) { - config.net.current_weight_ratio = powerup_frac; - config.net.target_weight_ratio = powerup_frac; - config.net.assumed_stake_weight = stake_weight; - config.net.exponent = 1; - config.net.min_price = asset::from_string("1000000.0000 TST"); - config.net.max_price = asset::from_string("1000000.0000 TST"); - - config.cpu.current_weight_ratio = powerup_frac; - config.cpu.target_weight_ratio = powerup_frac; - config.cpu.assumed_stake_weight = stake_weight; - config.cpu.exponent = 1; - config.cpu.min_price = asset::from_string("1000000.0000 TST"); - config.cpu.max_price = asset::from_string("1000000.0000 TST"); - - config.powerup_days = 30; - config.min_powerup_fee = asset::from_string("1.0000 TST"); - }))); - - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("max_payment doesn't match core symbol"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, powerup_frac, asset::from_string("1.000 TST"))); - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("market doesn't have resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, 0, powerup_frac, asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("market doesn't have resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, 0, asset::from_string("1.0000 TST"))); - - BOOST_REQUIRE_EQUAL("", t.configbw(t.make_default_config([&](auto& config) { - // weight = stake_weight - config.net.current_weight_ratio = powerup_frac/2; - config.net.target_weight_ratio = powerup_frac/2; - - // weight = stake_weight - config.cpu.current_weight_ratio = powerup_frac/2; - config.cpu.target_weight_ratio = powerup_frac/2; - }))); - - auto net_weight = stake_weight; - auto cpu_weight = stake_weight; - - t.start_rex(); - t.create_account_with_resources(N(aaaaaaaaaaaa), config::system_account_name, core_sym::from_string("1.0000"), - false, core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); - - // 10%, 20% - // (.1) * 1000000.0000 = 100000.0000 - // (.2) * 1000000.0000 = 200000.0000 - // total = 300000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("300000.0000")); - t.check_powerup(N(aaaaaaaaaaaa), N(aaaaaaaaaaaa), 30, powerup_frac * .1, powerup_frac * .2, - asset::from_string("300000.0000 TST"), net_weight * .1, cpu_weight * .2); - - // Start decay - t.produce_block(fc::days(30) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, .1 * net_weight, 0)); - BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, .2 * cpu_weight, 0)); - - // 2 days of decay from (10%, 20%) to (1.35%, 2.71%) - t.produce_block(fc::days(2) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, int64_t(.1 * net_weight * exp(-2)), - int64_t(.1 * net_weight * exp(-2)) / 1000)); - BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(.2 * cpu_weight * exp(-2)), - int64_t(.2 * cpu_weight * exp(-2)) / 1000)); - - // 2%, 2% - // (0.0135 + 0.02 - 0.0135) * 1000000.0000 = 20000.0000 - // (.02) * 1000000.0000 = 20000.0000 - // total = 40000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("40000.0001")); - t.check_powerup(N(aaaaaaaaaaaa), N(aaaaaaaaaaaa), 30, powerup_frac * .02, powerup_frac * .02, - asset::from_string("40000.0001 TST"), net_weight * .02, cpu_weight * .02); - } - - auto init = [](auto& t, bool rex) { - t.produce_block(); - BOOST_REQUIRE_EQUAL("", t.configbw(t.make_config([&](auto& config) { - // weight = stake_weight * 3 - config.net.current_weight_ratio = powerup_frac / 4; - config.net.target_weight_ratio = powerup_frac / 4; - config.net.assumed_stake_weight = stake_weight; - config.net.exponent = 2; - config.net.max_price = asset::from_string("2000000.0000 TST"); - - // weight = stake_weight * 4 / 2 - config.cpu.current_weight_ratio = powerup_frac / 5; - config.cpu.target_weight_ratio = powerup_frac / 5; - config.cpu.assumed_stake_weight = stake_weight / 2; - config.cpu.exponent = 3; - config.cpu.max_price = asset::from_string("6000000.0000 TST"); - - config.powerup_days = 30; - config.min_powerup_fee = asset::from_string("1.0000 TST"); - }))); - - if (rex) - t.start_rex(); - - t.create_account_with_resources(N(aaaaaaaaaaaa), config::system_account_name, core_sym::from_string("1.0000"), - false, core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); - t.create_account_with_resources(N(bbbbbbbbbbbb), config::system_account_name, core_sym::from_string("1.0000"), - false, core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); - }; - auto net_weight = stake_weight * 3; - auto cpu_weight = stake_weight * 4 / 2; - - { - powerup_tester t; - init(t, false); - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("days doesn't match configuration"), // - t.powerup(N(bob111111111), N(alice1111111), 20, powerup_frac, powerup_frac, asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( // - t.wasm_assert_msg("net_frac can't be negative"), // - t.powerup(N(bob111111111), N(alice1111111), 30, -powerup_frac, powerup_frac, - asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( // - t.wasm_assert_msg("cpu_frac can't be negative"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, -powerup_frac, - asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( // - t.wasm_assert_msg("net can't be more than 100%"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac + 1, powerup_frac, - asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( // - t.wasm_assert_msg("cpu can't be more than 100%"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, powerup_frac + 1, - asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("max_payment is less than calculated fee: 3000000.0000 TST"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, powerup_frac, asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("can't channel fees to rex"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, powerup_frac, - asset::from_string("3000000.0000 TST"))); - } - - // net:100%, cpu:100% - { - powerup_tester t; - init(t, true); - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3000000.0000")); - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("calculated fee is below minimum; try powering up with more resources"), - t.powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, 10, 10, asset::from_string("3000000.0000 TST"))); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, - asset::from_string("3000000.0000 TST"), net_weight, cpu_weight); - - BOOST_REQUIRE_EQUAL( // - t.wasm_assert_msg("weight can't shrink below utilization"), - t.configbw(t.make_default_config([&](auto& config) { - config.net.current_weight_ratio = powerup_frac / 4 + 1; - config.net.target_weight_ratio = powerup_frac / 4 + 1; - config.cpu.current_weight_ratio = powerup_frac / 5; - config.cpu.target_weight_ratio = powerup_frac / 5; - }))); - BOOST_REQUIRE_EQUAL( // - t.wasm_assert_msg("weight can't shrink below utilization"), - t.configbw(t.make_default_config([&](auto& config) { - config.net.current_weight_ratio = powerup_frac / 4; - config.net.target_weight_ratio = powerup_frac / 4; - config.cpu.current_weight_ratio = powerup_frac / 5 + 1; - config.cpu.target_weight_ratio = powerup_frac / 5 + 1; - }))); - BOOST_REQUIRE_EQUAL( // - "", // - t.configbw(t.make_default_config([&](auto& config) { - config.net.current_weight_ratio = powerup_frac / 4; - config.net.target_weight_ratio = powerup_frac / 4; - config.cpu.current_weight_ratio = powerup_frac / 5; - config.cpu.target_weight_ratio = powerup_frac / 5; - }))); - } - - // net:30%, cpu:40%, then net:5%, cpu:10% - { - powerup_tester t; - init(t, true); - // (.3 ^ 2) * 2000000.0000 / 2 = 90000.0000 - // (.4 ^ 3) * 6000000.0000 / 3 = 128000.0000 - // total = 218000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("218000.0001")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .3, powerup_frac * .4, - asset::from_string("218000.0001 TST"), net_weight * .3, cpu_weight * .4); - - // (.35 ^ 2) * 2000000.0000 / 2 - 90000.0000 = 32500.0000 - // (.5 ^ 3) * 6000000.0000 / 3 - 128000.0000 = 122000.0000 - // total = 154500.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("154500.0000")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .05, powerup_frac * .10, - asset::from_string("154500.0000 TST"), net_weight * .05, cpu_weight * .10); - } - - // net:50%, cpu:50% (but with non-zero min_price and also an exponent of 2 to simplify the math) - { - powerup_tester t; - init(t, true); - BOOST_REQUIRE_EQUAL("", t.configbw(t.make_default_config([&](auto& config) { - config.cpu.exponent = 2; - config.net.min_price = asset::from_string("1200000.0000 TST"); - config.net.max_price = asset::from_string("2000000.0000 TST"); - - config.cpu.exponent = 2; - config.cpu.min_price = asset::from_string("4000000.0000 TST"); - config.cpu.max_price = asset::from_string("6000000.0000 TST"); - }))); - - // At 0% utilization for both NET and CPU, the cost (in TST) for renting an infinitesimal amount of resources (dr) is - // 1200000.0000 * dr for NET and 4000000.0000 * dr for CPU. - // At 50% utilization for both NET and CPU, the cost (in TST for renting an infinitesimal amount of resources (dr) is - // 1600000.0000 * dr for NET and 5000000.0000 * dr for CPU. - - // The fee for renting 50% of NET (starting from 0% utilization) is expected to be somewhere between - // 1200000.0000 * 0.5 (= 600000.0000) and 1600000.0000 * 0.5 (= 800000.0000). - // In fact, the cost ends up being 700000.0000. - - // The fee for renting 50% of CPU (starting from 0% utilization) is expected to be somewhere between - // 4000000.0000 * 0.5 (= 2000000.0000) and 5000000.0000 * 0.5 (= 2500000.0000). - // In fact, the cost ends up being 2250000.0000. - - - // 1200000.0000 * .5 + (800000.0000 / 2) * (.5 ^ 2) = 700000.0000 - // 4000000.0000 * .5 + (2000000.0000 / 2) * (.5 ^ 2) = 2250000.0000 - // total = 2950000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("2950000.0000")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .5, powerup_frac * .5, - asset::from_string("2950000.0000 TST"), net_weight * .5, cpu_weight * .5); - } - - { - // net:100%, cpu:100% - powerup_tester t; - init(t, true); - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3000000.0000")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, - asset::from_string("3000000.0000 TST"), net_weight, cpu_weight); - - // No more available for 30 days - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, - asset::from_string("1.0000 TST"))); - t.produce_block(fc::days(29)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, - asset::from_string("1.0000 TST"))); - t.produce_block(fc::days(1) - fc::milliseconds(1500)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, - asset::from_string("1.0000 TST"))); - t.produce_block(fc::milliseconds(500)); - - // immediate renewal: adjusted_utilization doesn't have time to fall - // - // (1.0 ^ 1) * 2000000.0000 = 2000000.0000 - // (1.0 ^ 2) * 6000000.0000 = 6000000.0000 - // total = 8000000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("8000000.0000")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, - asset::from_string("8000000.0000 TST"), 0, 0); - - // No more available for 30 days - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, - asset::from_string("1.0000 TST"))); - t.produce_block(fc::days(29)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, - asset::from_string("1.0000 TST"))); - t.produce_block(fc::days(1) - fc::milliseconds(1000)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, - asset::from_string("1.0000 TST"))); - - // Start decay - t.produce_block(fc::milliseconds(1000)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, net_weight, net_weight / 1000)); - BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, cpu_weight, cpu_weight / 1000)); - - // 1 day of decay - t.produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, int64_t(net_weight * exp(-1)), - int64_t(net_weight * exp(-1)) / 1000)); - BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(cpu_weight * exp(-1)), - int64_t(cpu_weight * exp(-1)) / 1000)); - - // 1 day of decay - t.produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, int64_t(net_weight * exp(-2)), - int64_t(net_weight * exp(-2)) / 1000)); - BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(cpu_weight * exp(-2)), - int64_t(cpu_weight * exp(-2)) / 1000)); - - // 100% after 2 days of decay - // - // [ ((e^-2) ^ 1)*(e^-2 - 0.0) + ((1.0) ^ 2)/2 - ((e^-2) ^ 2)/2 ] * 2000000.0000 = 1018315.6389 - // [ ((e^-2) ^ 2)*(e^-2 - 0.0) + ((1.0) ^ 3)/3 - ((e^-2) ^ 3)/3 ] * 6000000.0000 = 2009915.0087 - // total = 3028230.6476 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3028229.8795")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, - asset::from_string("3028229.8795 TST"), net_weight, cpu_weight); - } - - { - powerup_tester t; - init(t, true); - - // 10%, 20% - // (.1 ^ 2) * 2000000.0000 / 2 = 10000.0000 - // (.2 ^ 3) * 6000000.0000 / 3 = 16000.0000 - // total = 26000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("26000.0002")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .1, powerup_frac * .2, - asset::from_string("26000.0002 TST"), net_weight * .1, cpu_weight * .2); - - t.produce_block(fc::days(15) - fc::milliseconds(500)); - - // 20%, 20% - // (.3 ^ 2) * 2000000.0000 / 2 - 10000.0000 = 80000.0000 - // (.4 ^ 3) * 6000000.0000 / 3 - 16000.0000 = 112000.0000 - // total = 192000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("192000.0001")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .2, powerup_frac * .2, - asset::from_string("192000.0001 TST"), net_weight * .2, cpu_weight * .2); - - // Start decay - t.produce_block(fc::days(15) - fc::milliseconds(1000)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, .3 * net_weight, 0)); - BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, .4 * cpu_weight, 0)); - - // 1 day of decay from (30%, 40%) to (20%, 20%) - t.produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE( - near(t.get_state().net.adjusted_utilization, int64_t(.1 * net_weight * exp(-1) + .2 * net_weight), 0)); - BOOST_REQUIRE( - near(t.get_state().cpu.adjusted_utilization, int64_t(.2 * cpu_weight * exp(-1) + .2 * cpu_weight), 0)); - - // 2 days of decay from (30%, 40%) to (20%, 20%) - t.produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE( - near(t.get_state().net.adjusted_utilization, int64_t(.1 * net_weight * exp(-2) + .2 * net_weight), 0)); - BOOST_REQUIRE( - near(t.get_state().cpu.adjusted_utilization, int64_t(.2 * cpu_weight * exp(-2) + .2 * cpu_weight), 0)); - } - -} // rent_tests -FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp deleted file mode 100644 index 3d9c76eb..00000000 --- a/tests/eosio.system_tester.hpp +++ /dev/null @@ -1,1126 +0,0 @@ -#pragma once - -#include -#include -#include -#include "contracts.hpp" -#include "test_symbol.hpp" - -#include -#include - -using namespace eosio::chain; -using namespace eosio::testing; -using namespace fc; - -using mvo = fc::mutable_variant_object; - -#ifndef TESTER -#ifdef NON_VALIDATING_TEST -#define TESTER tester -#else -#define TESTER validating_tester -#endif -#endif - -namespace eosio_system { - - -class eosio_system_tester : public TESTER { -public: - - void basic_setup() { - produce_blocks( 2 ); - - create_accounts({ N(eosio.token), N(eosio.ram), N(eosio.ramfee), N(eosio.stake), - N(eosio.bpay), N(eosio.vpay), N(eosio.saving), N(eosio.names), N(eosio.rex) }); - - - produce_blocks( 100 ); - set_code( N(eosio.token), contracts::token_wasm()); - set_abi( N(eosio.token), contracts::token_abi().data() ); - { - const auto& accnt = control->db().get( N(eosio.token) ); - abi_def abi; - BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - token_abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); - } - } - - void create_core_token( symbol core_symbol = symbol{CORE_SYM} ) { - FC_ASSERT( core_symbol.decimals() == 4, "create_core_token assumes core token has 4 digits of precision" ); - create_currency( N(eosio.token), config::system_account_name, asset(100000000000000, core_symbol) ); - issue( asset(10000000000000, core_symbol) ); - BOOST_REQUIRE_EQUAL( asset(10000000000000, core_symbol), get_balance( "eosio", core_symbol ) ); - } - - void deploy_contract( bool call_init = true ) { - set_code( config::system_account_name, contracts::system_wasm() ); - set_abi( config::system_account_name, contracts::system_abi().data() ); - if( call_init ) { - base_tester::push_action(config::system_account_name, N(init), - config::system_account_name, mutable_variant_object() - ("version", 0) - ("core", CORE_SYM_STR) - ); - } - - { - const auto& accnt = control->db().get( config::system_account_name ); - abi_def abi; - BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); - } - } - - void remaining_setup() { - produce_blocks(); - - // Assumes previous setup steps were done with core token symbol set to CORE_SYM - create_account_with_resources( N(alice1111111), config::system_account_name, core_sym::from_string("1.0000"), false ); - create_account_with_resources( N(bob111111111), config::system_account_name, core_sym::from_string("0.4500"), false ); - create_account_with_resources( N(carol1111111), config::system_account_name, core_sym::from_string("1.0000"), false ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); - } - - enum class setup_level { - none, - minimal, - core_token, - deploy_contract, - full - }; - - eosio_system_tester( setup_level l = setup_level::full ) { - if( l == setup_level::none ) return; - - basic_setup(); - if( l == setup_level::minimal ) return; - - create_core_token(); - if( l == setup_level::core_token ) return; - - deploy_contract(); - if( l == setup_level::deploy_contract ) return; - - remaining_setup(); - } - - template - eosio_system_tester(Lambda setup) { - setup(*this); - - basic_setup(); - create_core_token(); - deploy_contract(); - remaining_setup(); - } - - - void create_accounts_with_resources( vector accounts, account_name creator = config::system_account_name ) { - for( auto a : accounts ) { - create_account_with_resources( a, creator ); - } - } - - transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, uint32_t ram_bytes = 8000 ) { - signed_transaction trx; - set_transaction_headers(trx); - - authority owner_auth; - owner_auth = authority( get_public_key( a, "owner" ) ); - - trx.actions.emplace_back( vector{{creator,config::active_name}}, - newaccount{ - .creator = creator, - .name = a, - .owner = owner_auth, - .active = authority( get_public_key( a, "active" ) ) - }); - - trx.actions.emplace_back( get_action( config::system_account_name, N(buyrambytes), vector{{creator,config::active_name}}, - mvo() - ("payer", creator) - ("receiver", a) - ("bytes", ram_bytes) ) - ); - trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{{creator,config::active_name}}, - mvo() - ("from", creator) - ("receiver", a) - ("stake_net_quantity", core_sym::from_string("10.0000") ) - ("stake_cpu_quantity", core_sym::from_string("10.0000") ) - ("transfer", 0 ) - ) - ); - - set_transaction_headers(trx); - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - return push_transaction( trx ); - } - - transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, - asset net = core_sym::from_string("10.0000"), asset cpu = core_sym::from_string("10.0000") ) { - signed_transaction trx; - set_transaction_headers(trx); - - authority owner_auth; - if (multisig) { - // multisig between account's owner key and creators active permission - owner_auth = authority(2, {key_weight{get_public_key( a, "owner" ), 1}}, {permission_level_weight{{creator, config::active_name}, 1}}); - } else { - owner_auth = authority( get_public_key( a, "owner" ) ); - } - - trx.actions.emplace_back( vector{{creator,config::active_name}}, - newaccount{ - .creator = creator, - .name = a, - .owner = owner_auth, - .active = authority( get_public_key( a, "active" ) ) - }); - - trx.actions.emplace_back( get_action( config::system_account_name, N(buyram), vector{{creator,config::active_name}}, - mvo() - ("payer", creator) - ("receiver", a) - ("quant", ramfunds) ) - ); - - trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{{creator,config::active_name}}, - mvo() - ("from", creator) - ("receiver", a) - ("stake_net_quantity", net ) - ("stake_cpu_quantity", cpu ) - ("transfer", 0 ) - ) - ); - - set_transaction_headers(trx); - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - return push_transaction( trx ); - } - - transaction_trace_ptr setup_producer_accounts( const std::vector& accounts, - asset ram = core_sym::from_string("1.0000"), - asset cpu = core_sym::from_string("80.0000"), - asset net = core_sym::from_string("80.0000") - ) - { - account_name creator(config::system_account_name); - signed_transaction trx; - set_transaction_headers(trx); - - for (const auto& a: accounts) { - authority owner_auth( get_public_key( a, "owner" ) ); - trx.actions.emplace_back( vector{{creator,config::active_name}}, - newaccount{ - .creator = creator, - .name = a, - .owner = owner_auth, - .active = authority( get_public_key( a, "active" ) ) - }); - - trx.actions.emplace_back( get_action( config::system_account_name, N(buyram), vector{ {creator, config::active_name} }, - mvo() - ("payer", creator) - ("receiver", a) - ("quant", ram) ) - ); - - trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{ {creator, config::active_name} }, - mvo() - ("from", creator) - ("receiver", a) - ("stake_net_quantity", net) - ("stake_cpu_quantity", cpu ) - ("transfer", 0 ) - ) - ); - } - - set_transaction_headers(trx); - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - return push_transaction( trx ); - } - - action_result buyram( const account_name& payer, account_name receiver, const asset& eosin ) { - return push_action( payer, N(buyram), mvo()( "payer",payer)("receiver",receiver)("quant",eosin) ); - } - action_result buyram( std::string_view payer, std::string_view receiver, const asset& eosin ) { - return buyram( account_name(payer), account_name(receiver), eosin ); - } - - action_result buyrambytes( const account_name& payer, account_name receiver, uint32_t numbytes ) { - return push_action( payer, N(buyrambytes), mvo()( "payer",payer)("receiver",receiver)("bytes",numbytes) ); - } - action_result buyrambytes( std::string_view payer, std::string_view receiver, uint32_t numbytes ) { - return buyrambytes( account_name(payer), account_name(receiver), numbytes ); - } - - action_result sellram( const account_name& account, uint64_t numbytes ) { - return push_action( account, N(sellram), mvo()( "account", account)("bytes",numbytes) ); - } - action_result sellram( std::string_view account, uint64_t numbytes ) { - return sellram( account_name(account), numbytes ); - } - - action_result push_action( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) { - string action_type_name = abi_ser.get_action_type(name); - - action act; - act.account = config::system_account_name; - act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - - return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); - } - - action_result stake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { - return push_action( name(from), N(delegatebw), mvo() - ("from", from) - ("receiver", to) - ("stake_net_quantity", net) - ("stake_cpu_quantity", cpu) - ("transfer", 0 ) - ); - } - action_result stake( std::string_view from, std::string_view to, const asset& net, const asset& cpu ) { - return stake( account_name(from), account_name(to), net, cpu ); - } - - action_result stake( const account_name& acnt, const asset& net, const asset& cpu ) { - return stake( acnt, acnt, net, cpu ); - } - action_result stake( std::string_view acnt, const asset& net, const asset& cpu ) { - return stake( account_name(acnt), net, cpu ); - } - - action_result stake_with_transfer( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { - return push_action( name(from), N(delegatebw), mvo() - ("from", from) - ("receiver", to) - ("stake_net_quantity", net) - ("stake_cpu_quantity", cpu) - ("transfer", true ) - ); - } - action_result stake_with_transfer( std::string_view from, std::string_view to, const asset& net, const asset& cpu ) { - return stake_with_transfer( account_name(from), account_name(to), net, cpu ); - } - - action_result stake_with_transfer( const account_name& acnt, const asset& net, const asset& cpu ) { - return stake_with_transfer( acnt, acnt, net, cpu ); - } - action_result stake_with_transfer( std::string_view acnt, const asset& net, const asset& cpu ) { - return stake_with_transfer( account_name(acnt), net, cpu ); - } - - action_result unstake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { - return push_action( name(from), N(undelegatebw), mvo() - ("from", from) - ("receiver", to) - ("unstake_net_quantity", net) - ("unstake_cpu_quantity", cpu) - ); - } - action_result unstake( std::string_view from, std::string_view to, const asset& net, const asset& cpu ) { - return unstake( account_name(from), account_name(to), net, cpu ); - } - - action_result unstake( const account_name& acnt, const asset& net, const asset& cpu ) { - return unstake( acnt, acnt, net, cpu ); - } - action_result unstake( std::string_view acnt, const asset& net, const asset& cpu ) { - return unstake( account_name(acnt), net, cpu ); - } - - int64_t bancor_convert( int64_t S, int64_t R, int64_t T ) { return double(R) * T / ( double(S) + T ); }; - - int64_t get_net_limit( account_name a ) { - int64_t ram_bytes = 0, net = 0, cpu = 0; - control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); - return net; - }; - - int64_t get_cpu_limit( account_name a ) { - int64_t ram_bytes = 0, net = 0, cpu = 0; - control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); - return cpu; - }; - - action_result deposit( const account_name& owner, const asset& amount ) { - return push_action( name(owner), N(deposit), mvo() - ("owner", owner) - ("amount", amount) - ); - } - - action_result withdraw( const account_name& owner, const asset& amount ) { - return push_action( name(owner), N(withdraw), mvo() - ("owner", owner) - ("amount", amount) - ); - } - - action_result buyrex( const account_name& from, const asset& amount ) { - return push_action( name(from), N(buyrex), mvo() - ("from", from) - ("amount", amount) - ); - } - - asset get_buyrex_result( const account_name& from, const asset& amount ) { - auto trace = base_tester::push_action( config::system_account_name, N(buyrex), from, mvo()("from", from)("amount", amount) ); - asset rex_received; - for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - if ( trace->action_traces[i].act.name == N(buyresult) ) { - fc::raw::unpack( trace->action_traces[i].act.data.data(), - trace->action_traces[i].act.data.size(), - rex_received ); - return rex_received; - } - } - return rex_received; - } - - action_result unstaketorex( const account_name& owner, const account_name& receiver, const asset& from_net, const asset& from_cpu ) { - return push_action( name(owner), N(unstaketorex), mvo() - ("owner", owner) - ("receiver", receiver) - ("from_net", from_net) - ("from_cpu", from_cpu) - ); - } - - asset get_unstaketorex_result( const account_name& owner, const account_name& receiver, const asset& from_net, const asset& from_cpu ) { - auto trace = base_tester::push_action( config::system_account_name, N(unstaketorex), owner, mvo() - ("owner", owner) - ("receiver", receiver) - ("from_net", from_net) - ("from_cpu", from_cpu) - ); - asset rex_received; - for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - if ( trace->action_traces[i].act.name == N(buyresult) ) { - fc::raw::unpack( trace->action_traces[i].act.data.data(), - trace->action_traces[i].act.data.size(), - rex_received ); - return rex_received; - } - } - return rex_received; - } - - action_result sellrex( const account_name& from, const asset& rex ) { - return push_action( name(from), N(sellrex), mvo() - ("from", from) - ("rex", rex) - ); - } - - asset get_sellrex_result( const account_name& from, const asset& rex ) { - auto trace = base_tester::push_action( config::system_account_name, N(sellrex), from, mvo()("from", from)("rex", rex) ); - asset proceeds; - for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - if ( trace->action_traces[i].act.name == N(sellresult) ) { - fc::raw::unpack( trace->action_traces[i].act.data.data(), - trace->action_traces[i].act.data.size(), - proceeds ); - return proceeds; - } - } - return proceeds; - } - - auto get_rexorder_result( const transaction_trace_ptr& trace ) { - std::vector> output; - for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - if ( trace->action_traces[i].act.name == N(orderresult) ) { - fc::datastream ds( trace->action_traces[i].act.data.data(), - trace->action_traces[i].act.data.size() ); - account_name owner; fc::raw::unpack( ds, owner ); - asset proceeds; fc::raw::unpack( ds, proceeds ); - output.emplace_back( owner, proceeds ); - } - } - return output; - } - - action_result cancelrexorder( const account_name& owner ) { - return push_action( name(owner), N(cnclrexorder), mvo()("owner", owner) ); - } - - action_result rentcpu( const account_name& from, const account_name& receiver, const asset& payment, const asset& fund = core_sym::from_string("0.0000") ) { - return push_action( name(from), N(rentcpu), mvo() - ("from", from) - ("receiver", receiver) - ("loan_payment", payment) - ("loan_fund", fund) - ); - } - - action_result rentnet( const account_name& from, const account_name& receiver, const asset& payment, const asset& fund = core_sym::from_string("0.0000") ) { - return push_action( name(from), N(rentnet), mvo() - ("from", from) - ("receiver", receiver) - ("loan_payment", payment) - ("loan_fund", fund) - ); - } - - asset _get_rentrex_result( const account_name& from, const account_name& receiver, const asset& payment, bool cpu ) { - const name act = cpu ? N(rentcpu) : N(rentnet); - auto trace = base_tester::push_action( config::system_account_name, act, from, mvo() - ("from", from) - ("receiver", receiver) - ("loan_payment", payment) - ("loan_fund", core_sym::from_string("0.0000") ) - ); - - asset rented_tokens = core_sym::from_string("0.0000"); - for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - if ( trace->action_traces[i].act.name == N(rentresult) ) { - fc::raw::unpack( trace->action_traces[i].act.data.data(), - trace->action_traces[i].act.data.size(), - rented_tokens ); - return rented_tokens; - } - } - return rented_tokens; - } - - asset get_rentcpu_result( const account_name& from, const account_name& receiver, const asset& payment ) { - return _get_rentrex_result( from, receiver, payment, true ); - } - - asset get_rentnet_result( const account_name& from, const account_name& receiver, const asset& payment ) { - return _get_rentrex_result( from, receiver, payment, false ); - } - - action_result fundcpuloan( const account_name& from, const uint64_t loan_num, const asset& payment ) { - return push_action( name(from), N(fundcpuloan), mvo() - ("from", from) - ("loan_num", loan_num) - ("payment", payment) - ); - } - - action_result fundnetloan( const account_name& from, const uint64_t loan_num, const asset& payment ) { - return push_action( name(from), N(fundnetloan), mvo() - ("from", from) - ("loan_num", loan_num) - ("payment", payment) - ); - } - - - action_result defundcpuloan( const account_name& from, const uint64_t loan_num, const asset& amount ) { - return push_action( name(from), N(defcpuloan), mvo() - ("from", from) - ("loan_num", loan_num) - ("amount", amount) - ); - } - - action_result defundnetloan( const account_name& from, const uint64_t loan_num, const asset& amount ) { - return push_action( name(from), N(defnetloan), mvo() - ("from", from) - ("loan_num", loan_num) - ("amount", amount) - ); - } - - action_result updaterex( const account_name& owner ) { - return push_action( name(owner), N(updaterex), mvo()("owner", owner) ); - } - - action_result rexexec( const account_name& user, uint16_t max ) { - return push_action( name(user), N(rexexec), mvo()("user", user)("max", max) ); - } - - action_result consolidate( const account_name& owner ) { - return push_action( name(owner), N(consolidate), mvo()("owner", owner) ); - } - - action_result mvtosavings( const account_name& owner, const asset& rex ) { - return push_action( name(owner), N(mvtosavings), mvo()("owner", owner)("rex", rex) ); - } - - action_result mvfrsavings( const account_name& owner, const asset& rex ) { - return push_action( name(owner), N(mvfrsavings), mvo()("owner", owner)("rex", rex) ); - } - - action_result closerex( const account_name& owner ) { - return push_action( name(owner), N(closerex), mvo()("owner", owner) ); - } - - fc::variant get_last_loan(bool cpu) { - vector data; - const auto& db = control->db(); - namespace chain = eosio::chain; - auto table = cpu ? N(cpuloan) : N(netloan); - const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, table ) ); - if ( !t_id ) { - return fc::variant(); - } - - const auto& idx = db.get_index(); - - auto itr = idx.upper_bound( boost::make_tuple( t_id->id, std::numeric_limits::max() )); - if ( itr == idx.begin() ) { - return fc::variant(); - } - --itr; - if ( itr->t_id != t_id->id ) { - return fc::variant(); - } - - data.resize( itr->value.size() ); - memcpy( data.data(), itr->value.data(), data.size() ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_loan", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_last_cpu_loan() { - return get_last_loan( true ); - } - - fc::variant get_last_net_loan() { - return get_last_loan( false ); - } - - fc::variant get_loan_info( const uint64_t& loan_num, bool cpu ) const { - name table_name = cpu ? N(cpuloan) : N(netloan); - vector data = get_row_by_account( config::system_account_name, config::system_account_name, table_name, account_name(loan_num) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_loan", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_cpu_loan( const uint64_t loan_num ) const { - return get_loan_info( loan_num, true ); - } - - fc::variant get_net_loan( const uint64_t loan_num ) const { - return get_loan_info( loan_num, false ); - } - - fc::variant get_dbw_obj( const account_name& from, const account_name& receiver ) const { - vector data = get_row_by_account( config::system_account_name, from, N(delband), receiver ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant("delegated_bandwidth", data, abi_serializer::create_yield_function(abi_serializer_max_time)); - } - - asset get_rex_balance( const account_name& act ) const { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); - return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer::create_yield_function(abi_serializer_max_time))["rex_balance"].as(); - } - - fc::variant get_rex_balance_obj( const account_name& act ) const { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant("rex_balance", data, abi_serializer::create_yield_function(abi_serializer_max_time)); - } - - asset get_rex_fund( const account_name& act ) const { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexfund), act ); - return data.empty() ? asset(0, symbol{CORE_SYM}) : abi_ser.binary_to_variant("rex_fund", data, abi_serializer::create_yield_function(abi_serializer_max_time))["balance"].as(); - } - - fc::variant get_rex_fund_obj( const account_name& act ) const { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexfund), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_fund", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - asset get_rex_vote_stake( const account_name& act ) const { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); - return data.empty() ? core_sym::from_string("0.0000") : abi_ser.binary_to_variant("rex_balance", data, abi_serializer::create_yield_function(abi_serializer_max_time))["vote_stake"].as(); - } - - fc::variant get_rex_order( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexqueue), act ); - return abi_ser.binary_to_variant( "rex_order", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_rex_order_obj( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexqueue), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_order", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_rex_pool() const { - vector data; - const auto& db = control->db(); - namespace chain = eosio::chain; - const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, N(rexpool) ) ); - if ( !t_id ) { - return fc::variant(); - } - - const auto& idx = db.get_index(); - - auto itr = idx.lower_bound( boost::make_tuple( t_id->id, 0 ) ); - if ( itr == idx.end() || itr->t_id != t_id->id || 0 != itr->primary_key ) { - return fc::variant(); - } - - data.resize( itr->value.size() ); - memcpy( data.data(), itr->value.data(), data.size() ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_pool", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_rex_return_pool() const { - vector data; - const auto& db = control->db(); - namespace chain = eosio::chain; - const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, N(rexretpool) ) ); - if ( !t_id ) { - return fc::variant(); - } - - const auto& idx = db.get_index(); - - auto itr = idx.lower_bound( boost::make_tuple( t_id->id, 0 ) ); - if ( itr == idx.end() || itr->t_id != t_id->id || 0 != itr->primary_key ) { - return fc::variant(); - } - - data.resize( itr->value.size() ); - memcpy( data.data(), itr->value.data(), data.size() ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_pool", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_rex_return_buckets() const { - vector data; - const auto& db = control->db(); - namespace chain = eosio::chain; - const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, N(retbuckets) ) ); - if ( !t_id ) { - return fc::variant(); - } - - const auto& idx = db.get_index(); - - auto itr = idx.lower_bound( boost::make_tuple( t_id->id, 0 ) ); - if ( itr == idx.end() || itr->t_id != t_id->id || 0 != itr->primary_key ) { - return fc::variant(); - } - - data.resize( itr->value.size() ); - memcpy( data.data(), itr->value.data(), data.size() ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_buckets", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - void setup_rex_accounts( const std::vector& accounts, - const asset& init_balance, - const asset& net = core_sym::from_string("80.0000"), - const asset& cpu = core_sym::from_string("80.0000"), - bool deposit_into_rex_fund = true ) { - const asset nstake = core_sym::from_string("10.0000"); - const asset cstake = core_sym::from_string("10.0000"); - create_account_with_resources( N(proxyaccount), config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - BOOST_REQUIRE_EQUAL( success(), push_action( N(proxyaccount), N(regproxy), mvo()("proxy", "proxyaccount")("isproxy", true) ) ); - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, init_balance + nstake + cstake, config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( a, a, nstake, cstake) ); - BOOST_REQUIRE_EQUAL( success(), vote( a, { }, N(proxyaccount) ) ); - BOOST_REQUIRE_EQUAL( init_balance, get_balance(a) ); - BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); - if (deposit_into_rex_fund) { - BOOST_REQUIRE_EQUAL( success(), deposit( a, init_balance ) ); - BOOST_REQUIRE_EQUAL( init_balance, get_rex_fund( a ) ); - BOOST_REQUIRE_EQUAL( 0, get_balance( a ).get_amount() ); - } - } - } - - action_result bidname( const account_name& bidder, const account_name& newname, const asset& bid ) { - return push_action( name(bidder), N(bidname), mvo() - ("bidder", bidder) - ("newname", newname) - ("bid", bid) - ); - } - action_result bidname( std::string_view bidder, std::string_view newname, const asset& bid ) { - return bidname( account_name(bidder), account_name(newname), bid ); - } - - static fc::variant_object producer_parameters_example( int n ) { - return mutable_variant_object() - ("max_block_net_usage", 10000000 + n ) - ("target_block_net_usage_pct", 10 + n ) - ("max_transaction_net_usage", 1000000 + n ) - ("base_per_transaction_net_usage", 100 + n) - ("net_usage_leeway", 500 + n ) - ("context_free_discount_net_usage_num", 1 + n ) - ("context_free_discount_net_usage_den", 100 + n ) - ("max_block_cpu_usage", 10000000 + n ) - ("target_block_cpu_usage_pct", 10 + n ) - ("max_transaction_cpu_usage", 1000000 + n ) - ("min_transaction_cpu_usage", 100 + n ) - ("max_transaction_lifetime", 3600 + n) - ("deferred_trx_expiration_window", 600 + n) - ("max_transaction_delay", 10*86400+n) - ("max_inline_action_size", 4096 + n) - ("max_inline_action_depth", 4 + n) - ("max_authority_depth", 6 + n) - ("max_ram_size", (n % 10 + 1) * 1024 * 1024) - ("ram_reserve_ratio", 100 + n); - } - - action_result regproducer( const account_name& acnt, int params_fixture = 1 ) { - action_result r = push_action( acnt, N(regproducer), mvo() - ("producer", acnt ) - ("producer_key", get_public_key( acnt, "active" ) ) - ("url", "" ) - ("location", 0 ) - ); - BOOST_REQUIRE_EQUAL( success(), r); - return r; - } - - action_result vote( const account_name& voter, const std::vector& producers, const account_name& proxy = name(0) ) { - return push_action(voter, N(voteproducer), mvo() - ("voter", voter) - ("proxy", proxy) - ("producers", producers)); - } - action_result vote( const account_name& voter, const std::vector& producers, std::string_view proxy ) { - return vote( voter, producers, account_name(proxy) ); - } - - uint32_t last_block_time() const { - return time_point_sec( control->head_block_time() ).sec_since_epoch(); - } - - asset get_balance( const account_name& act, symbol balance_symbol = symbol{CORE_SYM} ) { - vector data = get_row_by_account( N(eosio.token), act, N(accounts), account_name(balance_symbol.to_symbol_code().value) ); - return data.empty() ? asset(0, balance_symbol) : token_abi_ser.binary_to_variant("account", data, abi_serializer::create_yield_function(abi_serializer_max_time))["balance"].as(); - } - - asset get_balance( std::string_view act, symbol balance_symbol = symbol{CORE_SYM} ) { - return get_balance( account_name(act), balance_symbol ); - } - - fc::variant get_total_stake( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, act, N(userres), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - fc::variant get_total_stake( std::string_view act ) { - return get_total_stake( account_name(act) ); - } - - fc::variant get_voter_info( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(voters), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - fc::variant get_voter_info( std::string_view act ) { - return get_voter_info( account_name(act) ); - } - - fc::variant get_producer_info( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers), act ); - return abi_ser.binary_to_variant( "producer_info", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - fc::variant get_producer_info( std::string_view act ) { - return get_producer_info( account_name(act) ); - } - - fc::variant get_producer_info2( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers2), act ); - return abi_ser.binary_to_variant( "producer_info2", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - fc::variant get_producer_info2( std::string_view act ) { - return get_producer_info2( account_name(act) ); - } - - void create_currency( name contract, name manager, asset maxsupply ) { - auto act = mutable_variant_object() - ("issuer", manager ) - ("maximum_supply", maxsupply ); - - base_tester::push_action(contract, N(create), contract, act ); - } - - void issue( const asset& amount, const name& manager = config::system_account_name ) { - base_tester::push_action( N(eosio.token), N(issue), manager, mutable_variant_object() - ("to", manager ) - ("quantity", amount ) - ("memo", "") - ); - } - - void transfer( const name& from, const name& to, const asset& amount, const name& manager = config::system_account_name ) { - base_tester::push_action( N(eosio.token), N(transfer), manager, mutable_variant_object() - ("from", from) - ("to", to ) - ("quantity", amount) - ("memo", "") - ); - } - - void transfer( const name& from, std::string_view to, const asset& amount, const name& manager = config::system_account_name ) { - transfer( from, name(to), amount, manager ); - } - - void transfer( std::string_view from, std::string_view to, const asset& amount, std::string_view manager ) { - transfer( name(from), name(to), amount, name(manager) ); - } - - void transfer( std::string_view from, std::string_view to, const asset& amount ) { - transfer( name(from), name(to), amount ); - } - - void issue_and_transfer( const name& to, const asset& amount, const name& manager = config::system_account_name ) { - signed_transaction trx; - trx.actions.emplace_back( get_action( N(eosio.token), N(issue), - vector{{manager, config::active_name}}, - mutable_variant_object() - ("to", manager ) - ("quantity", amount ) - ("memo", "") - ) - ); - if ( to != manager ) { - trx.actions.emplace_back( get_action( N(eosio.token), N(transfer), - vector{{manager, config::active_name}}, - mutable_variant_object() - ("from", manager) - ("to", to ) - ("quantity", amount ) - ("memo", "") - ) - ); - } - set_transaction_headers( trx ); - trx.sign( get_private_key( manager, "active" ), control->get_chain_id() ); - push_transaction( trx ); - } - - void issue_and_transfer( std::string_view to, const asset& amount, std::string_view manager ) { - issue_and_transfer( name(to), amount, name(manager) ); - } - - void issue_and_transfer( std::string_view to, const asset& amount, const name& manager ) { - issue_and_transfer( name(to), amount, manager); - } - - void issue_and_transfer( std::string_view to, const asset& amount ) { - issue_and_transfer( name(to), amount ); - } - - double stake2votes( asset stake ) { - auto now = control->pending_block_time().time_since_epoch().count() / 1000000; - return stake.get_amount() * pow(2, int64_t((now - (config::block_timestamp_epoch / 1000)) / (86400 * 7))/ double(52) ); // 52 week periods (i.e. ~years) - } - - double stake2votes( const string& s ) { - return stake2votes( core_sym::from_string(s) ); - } - - fc::variant get_stats( const string& symbolname ) { - auto symb = eosio::chain::symbol::from_string(symbolname); - auto symbol_code = symb.to_symbol_code().value; - vector data = get_row_by_account( N(eosio.token), name(symbol_code), N(stat), account_name(symbol_code) ); - return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - asset get_token_supply() { - return get_stats("4," CORE_SYM_NAME)["supply"].as(); - } - - uint64_t microseconds_since_epoch_of_iso_string( const fc::variant& v ) { - return static_cast( time_point::from_iso_string( v.as_string() ).time_since_epoch().count() ); - } - - fc::variant get_global_state() { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global), N(global) ); - if (data.empty()) std::cout << "\nData is empty\n" << std::endl; - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_global_state2() { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global2), N(global2) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_global_state3() { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global3), N(global3) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state3", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_refund_request( name account ) { - vector data = get_row_by_account( config::system_account_name, account, N(refunds), account ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - abi_serializer initialize_multisig() { - abi_serializer msig_abi_ser; - { - create_account_with_resources( N(eosio.msig), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), buyram( N(eosio), N(eosio.msig), core_sym::from_string("5000.0000") ) ); - produce_block(); - - auto trace = base_tester::push_action(config::system_account_name, N(setpriv), - config::system_account_name, mutable_variant_object() - ("account", "eosio.msig") - ("is_priv", 1) - ); - - set_code( N(eosio.msig), contracts::msig_wasm() ); - set_abi( N(eosio.msig), contracts::msig_abi().data() ); - - produce_blocks(); - const auto& accnt = control->db().get( N(eosio.msig) ); - abi_def msig_abi; - BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, msig_abi), true); - msig_abi_ser.set_abi(msig_abi, abi_serializer::create_yield_function(abi_serializer_max_time)); - } - return msig_abi_ser; - } - - vector active_and_vote_producers() { - //stake more than 15% of total EOS supply to activate chain - transfer( N(eosio), N(alice1111111), core_sym::from_string("650000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( N(alice1111111), N(alice1111111), core_sym::from_string("300000000.0000"), core_sym::from_string("300000000.0000") ) ); - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - const std::string root("defproducer"); - for ( char c = 'a'; c < 'a'+21; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - setup_producer_accounts(producer_names); - for (const auto& p: producer_names) { - - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - } - } - produce_blocks( 250); - - auto trace_auth = TESTER::push_action(config::system_account_name, updateauth::get_name(), config::system_account_name, mvo() - ("account", name(config::system_account_name).to_string()) - ("permission", name(config::active_name).to_string()) - ("parent", name(config::owner_name).to_string()) - ("auth", authority(1, {key_weight{get_public_key( config::system_account_name, "active" ), 1}}, { - permission_level_weight{{config::system_account_name, config::eosio_code_name}, 1}, - permission_level_weight{{config::producers_account_name, config::active_name}, 1} - } - )) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace_auth->receipt->status); - - //vote for producers - { - transfer( config::system_account_name, N(alice1111111), core_sym::from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake( N(alice1111111), core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000") ) ); - BOOST_REQUIRE_EQUAL(success(), buyram( N(alice1111111), N(alice1111111), core_sym::from_string("30000000.0000") ) ); - BOOST_REQUIRE_EQUAL(success(), push_action(N(alice1111111), N(voteproducer), mvo() - ("voter", "alice1111111") - ("proxy", name(0).to_string()) - ("producers", vector(producer_names.begin(), producer_names.begin()+21)) - ) - ); - } - produce_blocks( 250 ); - - auto producer_keys = control->head_block_state()->active_schedule.producers; - BOOST_REQUIRE_EQUAL( 21, producer_keys.size() ); - BOOST_REQUIRE_EQUAL( name("defproducera"), producer_keys[0].producer_name ); - - return producer_names; - } - - void cross_15_percent_threshold() { - setup_producer_accounts({N(producer1111)}); - regproducer(N(producer1111)); - { - signed_transaction trx; - set_transaction_headers(trx); - - trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), - vector{{config::system_account_name, config::active_name}}, - mvo() - ("from", name{config::system_account_name}) - ("receiver", "producer1111") - ("stake_net_quantity", core_sym::from_string("150000000.0000") ) - ("stake_cpu_quantity", core_sym::from_string("0.0000") ) - ("transfer", 1 ) - ) - ); - trx.actions.emplace_back( get_action( config::system_account_name, N(voteproducer), - vector{{N(producer1111), config::active_name}}, - mvo() - ("voter", "producer1111") - ("proxy", name(0).to_string()) - ("producers", vector(1, N(producer1111))) - ) - ); - trx.actions.emplace_back( get_action( config::system_account_name, N(undelegatebw), - vector{{N(producer1111), config::active_name}}, - mvo() - ("from", "producer1111") - ("receiver", "producer1111") - ("unstake_net_quantity", core_sym::from_string("150000000.0000") ) - ("unstake_cpu_quantity", core_sym::from_string("0.0000") ) - ) - ); - - set_transaction_headers(trx); - trx.sign( get_private_key( config::system_account_name, "active" ), control->get_chain_id() ); - trx.sign( get_private_key( N(producer1111), "active" ), control->get_chain_id() ); - push_transaction( trx ); - produce_block(); - } - } - - action_result setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) { - return push_action( N(eosio), N(setinflation), mvo() - ("annual_rate", annual_rate) - ("inflation_pay_factor", inflation_pay_factor) - ("votepay_factor", votepay_factor) - ); - } - - abi_serializer abi_ser; - abi_serializer token_abi_ser; -}; - -inline fc::mutable_variant_object voter( account_name acct ) { - return mutable_variant_object() - ("owner", acct) - ("proxy", name(0).to_string()) - ("producers", variants() ) - ("staked", int64_t(0)) - //("last_vote_weight", double(0)) - ("proxied_vote_weight", double(0)) - ("is_proxy", 0) - ; -} -inline fc::mutable_variant_object voter( std::string_view acct ) { - return voter( account_name(acct) ); -} - -inline fc::mutable_variant_object voter( account_name acct, const asset& vote_stake ) { - return voter( acct )( "staked", vote_stake.get_amount() ); -} -inline fc::mutable_variant_object voter( std::string_view acct, const asset& vote_stake ) { - return voter( account_name(acct), vote_stake ); -} - -inline fc::mutable_variant_object voter( account_name acct, int64_t vote_stake ) { - return voter( acct )( "staked", vote_stake ); -} -inline fc::mutable_variant_object voter( std::string_view acct, int64_t vote_stake ) { - return voter( account_name(acct), vote_stake ); -} - -inline fc::mutable_variant_object proxy( account_name acct ) { - return voter( acct )( "is_proxy", 1 ); -} - -inline uint64_t M( const string& eos_str ) { - return core_sym::from_string( eos_str ).get_amount(); -} - -} diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp deleted file mode 100644 index dbbf46d4..00000000 --- a/tests/eosio.system_tests.cpp +++ /dev/null @@ -1,5712 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "eosio.system_tester.hpp" -struct _abi_hash { - name owner; - fc::sha256 hash; -}; -FC_REFLECT( _abi_hash, (owner)(hash) ); - -struct connector { - asset balance; - double weight = .5; -}; -FC_REFLECT( connector, (balance)(weight) ); - -using namespace eosio_system; - -BOOST_AUTO_TEST_SUITE(eosio_system_tests) - -bool within_error(int64_t a, int64_t b, int64_t err) { return std::abs(a - b) <= err; }; -bool within_one(int64_t a, int64_t b) { return within_error(a, b, 1); } - -BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - auto total = get_total_stake( "alice1111111" ); - auto init_bytes = total["ram_bytes"].as_uint64(); - - const asset initial_ram_balance = get_balance(N(eosio.ram)); - const asset initial_ramfee_balance = get_balance(N(eosio.ramfee)); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("200.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("800.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( initial_ram_balance + core_sym::from_string("199.0000"), get_balance(N(eosio.ram)) ); - BOOST_REQUIRE_EQUAL( initial_ramfee_balance + core_sym::from_string("1.0000"), get_balance(N(eosio.ramfee)) ); - - total = get_total_stake( "alice1111111" ); - auto bytes = total["ram_bytes"].as_uint64(); - auto bought_bytes = bytes - init_bytes; - wdump((init_bytes)(bought_bytes)(bytes) ); - - BOOST_REQUIRE_EQUAL( true, 0 < bought_bytes ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("998.0049"), get_balance( "alice1111111" ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( true, total["ram_bytes"].as_uint64() == init_bytes ); - - transfer( "eosio", "alice1111111", core_sym::from_string("100000000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100000998.0049"), get_balance( "alice1111111" ) ); - // alice buys ram for 10000000.0000, 0.5% = 50000.0000 go to ramfee - // after fee 9950000.0000 go to bought bytes - // when selling back bought bytes, pay 0.5% fee and get back 99.5% of 9950000.0000 = 9900250.0000 - // expected account after that is 90000998.0049 + 9900250.0000 = 99901248.0049 with a difference - // of order 0.0001 due to rounding errors - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("90000998.0049"), get_balance( "alice1111111" ) ); - - total = get_total_stake( "alice1111111" ); - bytes = total["ram_bytes"].as_uint64(); - bought_bytes = bytes - init_bytes; - wdump((init_bytes)(bought_bytes)(bytes) ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - total = get_total_stake( "alice1111111" ); - - bytes = total["ram_bytes"].as_uint64(); - bought_bytes = bytes - init_bytes; - wdump((init_bytes)(bought_bytes)(bytes) ); - - BOOST_REQUIRE_EQUAL( true, total["ram_bytes"].as_uint64() == init_bytes ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("99901248.0048"), get_balance( "alice1111111" ) ); - - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("30.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("99900688.0048"), get_balance( "alice1111111" ) ); - - auto newtotal = get_total_stake( "alice1111111" ); - - auto newbytes = newtotal["ram_bytes"].as_uint64(); - bought_bytes = newbytes - bytes; - wdump((newbytes)(bytes)(bought_bytes) ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("99901242.4187"), get_balance( "alice1111111" ) ); - - newtotal = get_total_stake( "alice1111111" ); - auto startbytes = newtotal["ram_bytes"].as_uint64(); - - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("300000.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("49301242.4187"), get_balance( "alice1111111" ) ); - - auto finaltotal = get_total_stake( "alice1111111" ); - auto endbytes = finaltotal["ram_bytes"].as_uint64(); - - bought_bytes = endbytes - startbytes; - wdump((startbytes)(endbytes)(bought_bytes) ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - - BOOST_REQUIRE_EQUAL( false, get_row_by_account( config::system_account_name, config::system_account_name, - N(rammarket), account_name(symbol{SY(4,RAMCORE)}.value()) ).empty() ); - - auto get_ram_market = [this]() -> fc::variant { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, - N(rammarket), account_name(symbol{SY(4,RAMCORE)}.value()) ); - BOOST_REQUIRE( !data.empty() ); - return abi_ser.binary_to_variant("exchange_state", data, abi_serializer::create_yield_function(abi_serializer_max_time)); - }; - - { - transfer( config::system_account_name, N(alice1111111), core_sym::from_string("10000000.0000"), config::system_account_name ); - uint64_t bytes0 = get_total_stake( "alice1111111" )["ram_bytes"].as_uint64(); - - auto market = get_ram_market(); - const asset r0 = market["base"].as().balance; - const asset e0 = market["quote"].as().balance; - BOOST_REQUIRE_EQUAL( asset::from_string("0 RAM").get_symbol(), r0.get_symbol() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000").get_symbol(), e0.get_symbol() ); - - const asset payment = core_sym::from_string("10000000.0000"); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", payment ) ); - uint64_t bytes1 = get_total_stake( "alice1111111" )["ram_bytes"].as_uint64(); - - const int64_t fee = (payment.get_amount() + 199) / 200; - const double net_payment = payment.get_amount() - fee; - const int64_t expected_delta = net_payment * r0.get_amount() / ( net_payment + e0.get_amount() ); - - BOOST_REQUIRE_EQUAL( expected_delta, bytes1 - bytes0 ); - } - - { - transfer( config::system_account_name, N(bob111111111), core_sym::from_string("100000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must reserve a positive amount"), - buyrambytes( "bob111111111", "bob111111111", 1 ) ); - - uint64_t bytes0 = get_total_stake( "bob111111111" )["ram_bytes"].as_uint64(); - BOOST_REQUIRE_EQUAL( success(), buyrambytes( "bob111111111", "bob111111111", 1024 ) ); - uint64_t bytes1 = get_total_stake( "bob111111111" )["ram_bytes"].as_uint64(); - BOOST_REQUIRE( within_one( 1024, bytes1 - bytes0 ) ); - - BOOST_REQUIRE_EQUAL( success(), buyrambytes( "bob111111111", "bob111111111", 1024 * 1024) ); - uint64_t bytes2 = get_total_stake( "bob111111111" )["ram_bytes"].as_uint64(); - BOOST_REQUIRE( within_one( 1024 * 1024, bytes2 - bytes1 ) ); - } - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_unstake, eosio_system_tester ) try { - cross_15_percent_threshold(); - - produce_blocks( 10 ); - produce_block( fc::hours(3*24) ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - auto total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - - const auto init_eosio_stake_balance = get_balance( N(eosio.stake) ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( init_eosio_stake_balance + core_sym::from_string("300.0000"), get_balance( N(eosio.stake) ) ); - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - - produce_block( fc::hours(3*24-1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( init_eosio_stake_balance + core_sym::from_string("300.0000"), get_balance( N(eosio.stake) ) ); - //after 3 days funds should be released - produce_block( fc::hours(1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( init_eosio_stake_balance, get_balance( N(eosio.stake) ) ); - - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - total = get_total_stake("bob111111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000").get_amount(), total["net_weight"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000").get_amount(), total["cpu_weight"].as().get_amount() ); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000")), get_voter_info( "alice1111111" ) ); - - auto bytes = total["ram_bytes"].as_uint64(); - BOOST_REQUIRE_EQUAL( true, 0 < bytes ); - - //unstake from bob111111111 - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - total = get_total_stake("bob111111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); - produce_block( fc::hours(3*24-1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - //after 3 days funds should be released - produce_block( fc::hours(1) ); - produce_blocks(1); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000") ), get_voter_info( "alice1111111" ) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - - //eosio stakes for alice with transfer flag - - transfer( "eosio", "bob111111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(bob111111111), N(alice1111111), core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - //check that alice has both bandwidth and voting power - auto total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000")), get_voter_info( "alice1111111" ) ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - - //alice stakes for herself - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - //now alice's stake should be equal to transfered from eosio + own stake - total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("410.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("600.0000")), get_voter_info( "alice1111111" ) ); - - //alice can unstake everything (including what was transfered) - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("400.0000"), core_sym::from_string("200.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - - produce_block( fc::hours(3*24-1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - //after 3 days funds should be released - - produce_block( fc::hours(1) ); - produce_blocks(1); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("1300.0000"), get_balance( "alice1111111" ) ); - - //stake should be equal to what was staked in constructor, voting power should be 0 - total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000")), get_voter_info( "alice1111111" ) ); - - // Now alice stakes to bob with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(alice1111111), N(bob111111111), core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_to_self_with_transfer, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot use transfer flag if delegating to self"), - stake_with_transfer( N(alice1111111), N(alice1111111), core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) - ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_while_pending_refund, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - - //eosio stakes for alice with transfer flag - transfer( "eosio", "bob111111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(bob111111111), N(alice1111111), core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - //check that alice has both bandwidth and voting power - auto total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000")), get_voter_info( "alice1111111" ) ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - - //alice stakes for herself - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - //now alice's stake should be equal to transfered from eosio + own stake - total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("410.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("600.0000")), get_voter_info( "alice1111111" ) ); - - //alice can unstake everything (including what was transfered) - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("400.0000"), core_sym::from_string("200.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - - produce_block( fc::hours(3*24-1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - //after 3 days funds should be released - - produce_block( fc::hours(1) ); - produce_blocks(1); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("1300.0000"), get_balance( "alice1111111" ) ); - - //stake should be equal to what was staked in constructor, voting power should be 0 - total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000")), get_voter_info( "alice1111111" ) ); - - // Now alice stakes to bob with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(alice1111111), N(bob111111111), core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( fail_without_auth, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("2000.0000"), core_sym::from_string("1000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("10.0000"), core_sym::from_string("10.0000") ) ); - - BOOST_REQUIRE_EQUAL( error("missing authority of alice1111111"), - push_action( N(alice1111111), N(delegatebw), mvo() - ("from", "alice1111111") - ("receiver", "bob111111111") - ("stake_net_quantity", core_sym::from_string("10.0000")) - ("stake_cpu_quantity", core_sym::from_string("10.0000")) - ("transfer", 0 ) - ,false - ) - ); - - BOOST_REQUIRE_EQUAL( error("missing authority of alice1111111"), - push_action(N(alice1111111), N(undelegatebw), mvo() - ("from", "alice1111111") - ("receiver", "bob111111111") - ("unstake_net_quantity", core_sym::from_string("200.0000")) - ("unstake_cpu_quantity", core_sym::from_string("100.0000")) - ("transfer", 0 ) - ,false - ) - ); - //REQUIRE_MATCHING_OBJECT( , get_voter_info( "alice1111111" ) ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( stake_negative, eosio_system_tester ) try { - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111", core_sym::from_string("-0.0001"), core_sym::from_string("0.0000") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("-0.0001") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111", core_sym::from_string("00.0000"), core_sym::from_string("00.0000") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("00.0000") ) - - ); - - BOOST_REQUIRE_EQUAL( true, get_voter_info( "alice1111111" ).is_null() ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( unstake_negative, eosio_system_tester ) try { - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0001"), core_sym::from_string("100.0001") ) ); - - auto total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0001"), total["net_weight"].as()); - auto vinfo = get_voter_info("alice1111111" ); - wdump((vinfo)); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0002") ), get_voter_info( "alice1111111" ) ); - - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), - unstake( "alice1111111", "bob111111111", core_sym::from_string("-1.0000"), core_sym::from_string("0.0000") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), - unstake( "alice1111111", "bob111111111", core_sym::from_string("0.0000"), core_sym::from_string("-1.0000") ) - ); - - //unstake all zeros - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), - unstake( "alice1111111", "bob111111111", core_sym::from_string("0.0000"), core_sym::from_string("0.0000") ) - - ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( unstake_more_than_at_stake, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - auto total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - - //trying to unstake more net bandwith than at stake - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), - unstake( "alice1111111", core_sym::from_string("200.0001"), core_sym::from_string("0.0000") ) - ); - - //trying to unstake more cpu bandwith than at stake - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), - unstake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("100.0001") ) - - ); - - //check that nothing has changed - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( delegate_to_another_user, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - - BOOST_REQUIRE_EQUAL( success(), stake ( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - auto total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - //all voting power goes to alice1111111 - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); - //but not to bob111111111 - BOOST_REQUIRE_EQUAL( true, get_voter_info( "bob111111111" ).is_null() ); - - //bob111111111 should not be able to unstake what was staked by alice1111111 - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), - unstake( "bob111111111", core_sym::from_string("0.0000"), core_sym::from_string("10.0000") ) - - ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), - unstake( "bob111111111", core_sym::from_string("10.0000"), core_sym::from_string("0.0000") ) - ); - - issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", "bob111111111", core_sym::from_string("20.0000"), core_sym::from_string("10.0000") ) ); - total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("120.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("970.0000"), get_balance( "carol1111111" ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_sym::from_string("30.0000") ), get_voter_info( "carol1111111" ) ); - - //alice1111111 should not be able to unstake money staked by carol1111111 - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), - unstake( "alice1111111", "bob111111111", core_sym::from_string("2001.0000"), core_sym::from_string("1.0000") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), - unstake( "alice1111111", "bob111111111", core_sym::from_string("1.0000"), core_sym::from_string("101.0000") ) - - ); - - total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("120.0000"), total["cpu_weight"].as()); - //balance should not change after unsuccessfull attempts to unstake - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - //voting power too - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_sym::from_string("30.0000") ), get_voter_info( "carol1111111" ) ); - BOOST_REQUIRE_EQUAL( true, get_voter_info( "bob111111111" ).is_null() ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( stake_unstake_separate, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); - - //everything at once - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("10.0000"), core_sym::from_string("20.0000") ) ); - auto total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("20.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), total["cpu_weight"].as()); - - //cpu - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("0.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("120.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), total["cpu_weight"].as()); - - //net - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("200.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("120.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["cpu_weight"].as()); - - //unstake cpu - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("0.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("20.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["cpu_weight"].as()); - - //unstake net - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("200.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("20.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), total["cpu_weight"].as()); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( adding_stake_partial_unstake, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); - - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("100.0000"), core_sym::from_string("50.0000") ) ); - - auto total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("310.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("160.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("450.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("550.0000"), get_balance( "alice1111111" ) ); - - //unstake a share - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_sym::from_string("150.0000"), core_sym::from_string("75.0000") ) ); - - total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("160.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("85.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("225.0000") ), get_voter_info( "alice1111111" ) ); - - //unstake more - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("25.0000") ) ); - total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("150.0000") ), get_voter_info( "alice1111111" ) ); - - //combined amount should be available only in 3 days - produce_block( fc::days(2) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("550.0000"), get_balance( "alice1111111" ) ); - produce_block( fc::days(1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("850.0000"), get_balance( "alice1111111" ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - auto total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); - - total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("400.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("600.0000"), get_balance( "alice1111111" ) ); - - //unstake a share - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("50.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("250.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("600.0000"), get_balance( "alice1111111" ) ); - auto refund = get_refund_request( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "50.0000"), refund["cpu_amount"].as() ); - //XXX auto request_time = refund["request_time"].as_int64(); - - //alice delegates to bob, should pull from liquid balance not refund - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("350.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); - refund = get_refund_request( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "50.0000"), refund["cpu_amount"].as() ); - - //stake less than pending refund, entire amount should be taken from refund - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("50.0000"), core_sym::from_string("25.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("160.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("85.0000"), total["cpu_weight"].as()); - refund = get_refund_request( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("50.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("25.0000"), refund["cpu_amount"].as() ); - //request time should stay the same - //BOOST_REQUIRE_EQUAL( request_time, refund["request_time"].as_int64() ); - //balance should stay the same - BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); - - //stake exactly pending refund amount - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("50.0000"), core_sym::from_string("25.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - //pending refund should be removed - refund = get_refund_request( N(alice1111111) ); - BOOST_TEST_REQUIRE( refund.is_null() ); - //balance should stay the same - BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); - - //create pending refund again - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); - refund = get_refund_request( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); - - //stake more than pending refund - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("300.0000"), core_sym::from_string("200.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("310.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("700.0000") ), get_voter_info( "alice1111111" ) ); - refund = get_refund_request( N(alice1111111) ); - BOOST_TEST_REQUIRE( refund.is_null() ); - //200 core tokens should be taken from alice's account - BOOST_REQUIRE_EQUAL( core_sym::from_string("300.0000"), get_balance( "alice1111111" ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_to_another_user_not_from_refund, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - auto total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - - //unstake - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - auto refund = get_refund_request( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); - //auto orig_request_time = refund["request_time"].as_int64(); - - //stake to another user - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - //stake should be taken from alices' balance, and refund request should stay the same - BOOST_REQUIRE_EQUAL( core_sym::from_string("400.0000"), get_balance( "alice1111111" ) ); - refund = get_refund_request( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); - //BOOST_REQUIRE_EQUAL( orig_request_time, refund["request_time"].as_int64() ); - -} FC_LOG_AND_RETHROW() - -// Tests for voting -BOOST_FIXTURE_TEST_CASE( producer_register_unregister, eosio_system_tester ) try { - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - - //fc::variant params = producer_parameters_example(1); - auto key = fc::crypto::public_key( std::string("EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV") ); - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", key ) - ("url", "http://block.one") - ("location", 1) - ) - ); - - auto info = get_producer_info( "alice1111111" ); - BOOST_REQUIRE_EQUAL( "alice1111111", info["owner"].as_string() ); - BOOST_REQUIRE_EQUAL( 0, info["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( "http://block.one", info["url"].as_string() ); - - //change parameters one by one to check for things like #3783 - //fc::variant params2 = producer_parameters_example(2); - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", key ) - ("url", "http://block.two") - ("location", 1) - ) - ); - info = get_producer_info( "alice1111111" ); - BOOST_REQUIRE_EQUAL( "alice1111111", info["owner"].as_string() ); - BOOST_REQUIRE_EQUAL( key, fc::crypto::public_key(info["producer_key"].as_string()) ); - BOOST_REQUIRE_EQUAL( "http://block.two", info["url"].as_string() ); - BOOST_REQUIRE_EQUAL( 1, info["location"].as_int64() ); - - auto key2 = fc::crypto::public_key( std::string("EOS5jnmSKrzdBHE9n8hw58y7yxFWBC8SNiG7m8S1crJH3KvAnf9o6") ); - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", key2 ) - ("url", "http://block.two") - ("location", 2) - ) - ); - info = get_producer_info( "alice1111111" ); - BOOST_REQUIRE_EQUAL( "alice1111111", info["owner"].as_string() ); - BOOST_REQUIRE_EQUAL( key2, fc::crypto::public_key(info["producer_key"].as_string()) ); - BOOST_REQUIRE_EQUAL( "http://block.two", info["url"].as_string() ); - BOOST_REQUIRE_EQUAL( 2, info["location"].as_int64() ); - - //unregister producer - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(unregprod), mvo() - ("producer", "alice1111111") - ) - ); - info = get_producer_info( "alice1111111" ); - //key should be empty - BOOST_REQUIRE_EQUAL( fc::crypto::public_key(), fc::crypto::public_key(info["producer_key"].as_string()) ); - //everything else should stay the same - BOOST_REQUIRE_EQUAL( "alice1111111", info["owner"].as_string() ); - BOOST_REQUIRE_EQUAL( 0, info["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( "http://block.two", info["url"].as_string() ); - - //unregister bob111111111 who is not a producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer not found" ), - push_action( N(bob111111111), N(unregprod), mvo() - ("producer", "bob111111111") - ) - ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( control->active_producers().version, 0u ); - - issue_and_transfer( N(alice1111111), core_sym::from_string("200000000.0000"), config::system_account_name ); - block_signing_authority_v0 alice_signing_authority; - alice_signing_authority.threshold = 1; - alice_signing_authority.keys.push_back( {.key = get_public_key( N(alice1111111), "bs1"), .weight = 1} ); - alice_signing_authority.keys.push_back( {.key = get_public_key( N(alice1111111), "bs2"), .weight = 1} ); - producer_authority alice_producer_authority = {.producer_name = N(alice1111111), .authority = alice_signing_authority}; - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer2), mvo() - ("producer", "alice1111111") - ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - BOOST_REQUIRE_EQUAL( success(), stake( N(alice1111111), core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(alice1111111) } ) ); - - block_signing_private_keys.emplace(get_public_key(N(alice1111111), "bs1"), get_private_key(N(alice1111111), "bs1")); - - auto alice_prod_info = get_producer_info( N(alice1111111) ); - wdump((alice_prod_info)); - BOOST_REQUIRE_EQUAL( alice_prod_info["is_active"], true ); - - produce_block(); - produce_block( fc::minutes(2) ); - produce_blocks(2); - BOOST_REQUIRE_EQUAL( control->active_producers().version, 1u ); - produce_block(); - BOOST_REQUIRE_EQUAL( control->pending_block_producer(), N(alice1111111) ); - produce_block(); - - alice_signing_authority.threshold = 0; - alice_producer_authority.authority = alice_signing_authority; - - // Ensure an authority with a threshold of 0 is rejected. - BOOST_REQUIRE_EQUAL( error("assertion failure with message: invalid producer authority"), - push_action( N(alice1111111), N(regproducer2), mvo() - ("producer", "alice1111111") - ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - - // Ensure an authority that is not satisfiable is rejected. - alice_signing_authority.threshold = 3; - alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( error("assertion failure with message: invalid producer authority"), - push_action( N(alice1111111), N(regproducer2), mvo() - ("producer", "alice1111111") - ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - - // Ensure an authority with duplicate keys is rejected. - alice_signing_authority.threshold = 1; - alice_signing_authority.keys[1] = alice_signing_authority.keys[0]; - alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( error("assertion failure with message: invalid producer authority"), - push_action( N(alice1111111), N(regproducer2), mvo() - ("producer", "alice1111111") - ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - - // However, an authority with an invalid key is okay. - alice_signing_authority.keys[1] = {}; - alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( success(), - push_action( N(alice1111111), N(regproducer2), mvo() - ("producer", "alice1111111") - ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - - produce_block(); - produce_block( fc::minutes(2) ); - produce_blocks(2); - BOOST_REQUIRE_EQUAL( control->active_producers().version, 2u ); - produce_block(); - BOOST_REQUIRE_EQUAL( control->pending_block_producer(), N(alice1111111) ); - produce_block(); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( producer_wtmsig_transition, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( control->active_producers().version, 0u ); - - set_code( config::system_account_name, contracts::util::system_wasm_v1_8() ); - set_abi( config::system_account_name, contracts::util::system_abi_v1_8().data() ); - - issue_and_transfer( N(alice1111111), core_sym::from_string("200000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url","") - ("location", 0) - ) - ); - BOOST_REQUIRE_EQUAL( success(), stake( N(alice1111111), core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(alice1111111) } ) ); - - //auto alice_prod_info1 = get_producer_info( N(alice1111111) ); - //wdump((alice_prod_info1)); - - produce_block(); - produce_block( fc::minutes(2) ); - produce_blocks(2); - BOOST_REQUIRE_EQUAL( control->active_producers().version, 1u ); - - const auto schedule_update1 = get_global_state()["last_producer_schedule_update"]; - - const auto& rlm = control->get_resource_limits_manager(); - - auto alice_initial_ram_usage = rlm.get_account_ram_usage(N(alice1111111)); - - set_code( config::system_account_name, contracts::system_wasm() ); - set_abi( config::system_account_name, contracts::system_abi().data() ); - produce_block(); - BOOST_REQUIRE_EQUAL( control->pending_block_producer(), N(alice1111111) ); - - auto alice_prod_info2 = get_producer_info( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( alice_prod_info2["is_active"], true ); - - produce_block( fc::minutes(2) ); - const auto schedule_update2 = get_global_state()["last_producer_schedule_update"]; - BOOST_REQUIRE( schedule_update1 < schedule_update2 ); // Ensure last_producer_schedule_update is increasing. - - // Producing the above block would trigger the bug in v1.9.0 that sets the default block_signing_authority - // in the producer object of the currently active producer alice1111111. - // However, starting in v1.9.1, the producer object does not have a default block_signing_authority added to the - // serialization of the producer object if it was not already present in the binary extension field - // producer_authority to begin with. This is verified below by ensuring the RAM usage of alice (who pays for the - // producer object) does not increase. - - auto alice_ram_usage = rlm.get_account_ram_usage(N(alice1111111)); - BOOST_CHECK_EQUAL( alice_initial_ram_usage, alice_ram_usage ); - - auto alice_prod_info3 = get_producer_info( N(alice1111111) ); - if( alice_prod_info3.get_object().contains("producer_authority") ) { - BOOST_CHECK_EQUAL( alice_prod_info3["producer_authority"][1]["threshold"], 0 ); - } - - produce_block( fc::minutes(2) ); - const auto schedule_update3 = get_global_state()["last_producer_schedule_update"]; - - // The bug in v1.9.0 would cause alice to have an invalid producer authority (the default block_signing_authority). - // The v1.9.0 system contract would have attempted to set a proposed producer schedule including this invalid - // authority which would be rejected by the EOSIO native system and cause the onblock transaction to continue to fail. - // This could be observed by noticing that last_producer_schedule_update was not being updated even though it should. - // However, starting in v1.9.1, update_elected_producers is smarter about the producer schedule it constructs to - // propose to the system. It will recognize the default constructed authority (which shouldn't be created by the - // v1.9.1 system contract but may still exist in the tables if it was constructed by the buggy v1.9.0 system contract) - // and instead resort to constructing the block signing authority from the single producer key in the table. - // So newer system contracts should see onblock continue to function, which is verified by the check below. - - BOOST_CHECK( schedule_update2 < schedule_update3 ); // Ensure last_producer_schedule_update is increasing. - - // But even if the buggy v1.9.0 system contract was running, it should always still be possible to recover - // by having the producer with the invalid authority simply call regproducer or regproducer2 to correct their - // block signing authority. - - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url","") - ("location", 0) - ) - ); - - produce_block(); - produce_block( fc::minutes(2) ); - - auto alice_prod_info4 = get_producer_info( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( alice_prod_info4["is_active"], true ); - const auto schedule_update4 = get_global_state()["last_producer_schedule_update"]; - BOOST_REQUIRE( schedule_update2 < schedule_update4 ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - fc::variant params = producer_parameters_example(1); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - auto prod = get_producer_info( "alice1111111" ); - BOOST_REQUIRE_EQUAL( "alice1111111", prod["owner"].as_string() ); - BOOST_REQUIRE_EQUAL( 0, prod["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( "http://block.one", prod["url"].as_string() ); - - issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); - issue_and_transfer( "carol1111111", core_sym::from_string("3000.0000"), config::system_account_name ); - - //bob111111111 makes stake - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("11.0000"), core_sym::from_string("0.1111") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1988.8889"), get_balance( "bob111111111" ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("11.1111") ), get_voter_info( "bob111111111" ) ); - - //bob111111111 votes for alice1111111 - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(alice1111111) } ) ); - - //check that producer parameters stay the same after voting - prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("11.1111")) == prod["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( "alice1111111", prod["owner"].as_string() ); - BOOST_REQUIRE_EQUAL( "http://block.one", prod["url"].as_string() ); - - //carol1111111 makes stake - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("22.0000"), core_sym::from_string("0.2222") ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_sym::from_string("22.2222") ), get_voter_info( "carol1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("2977.7778"), get_balance( "carol1111111" ) ); - //carol1111111 votes for alice1111111 - BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111) } ) ); - - //new stake votes be added to alice1111111's total_votes - prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("33.3333")) == prod["total_votes"].as_double() ); - - //bob111111111 increases his stake - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("33.0000"), core_sym::from_string("0.3333") ) ); - //alice1111111 stake with transfer to bob111111111 - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(alice1111111), N(bob111111111), core_sym::from_string("22.0000"), core_sym::from_string("0.2222") ) ); - //should increase alice1111111's total_votes - prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("88.8888")) == prod["total_votes"].as_double() ); - - //carol1111111 unstakes part of the stake - BOOST_REQUIRE_EQUAL( success(), unstake( "carol1111111", core_sym::from_string("2.0000"), core_sym::from_string("0.0002")/*"2.0000 EOS", "0.0002 EOS"*/ ) ); - - //should decrease alice1111111's total_votes - prod = get_producer_info( "alice1111111" ); - wdump((prod)); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("86.8886")) == prod["total_votes"].as_double() ); - - //bob111111111 revokes his vote - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector() ) ); - - //should decrease alice1111111's total_votes - prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("20.2220")) == prod["total_votes"].as_double() ); - //but eos should still be at stake - BOOST_REQUIRE_EQUAL( core_sym::from_string("1955.5556"), get_balance( "bob111111111" ) ); - - //carol1111111 unstakes rest of eos - BOOST_REQUIRE_EQUAL( success(), unstake( "carol1111111", core_sym::from_string("20.0000"), core_sym::from_string("0.2220") ) ); - //should decrease alice1111111's total_votes to zero - prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( 0.0 == prod["total_votes"].as_double() ); - - //carol1111111 should receive funds in 3 days - produce_block( fc::days(3) ); - produce_block(); - BOOST_REQUIRE_EQUAL( core_sym::from_string("3000.0000"), get_balance( "carol1111111" ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( unregistered_producer_voting, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("13.0000"), core_sym::from_string("0.5791") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); - - //bob111111111 should not be able to vote for alice1111111 who is not a producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer alice1111111 is not registered" ), - vote( N(bob111111111), { N(alice1111111) } ) ); - - //alice1111111 registers as a producer - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - fc::variant params = producer_parameters_example(1); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url", "") - ("location", 0) - ) - ); - //and then unregisters - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(unregprod), mvo() - ("producer", "alice1111111") - ) - ); - //key should be empty - auto prod = get_producer_info( "alice1111111" ); - BOOST_REQUIRE_EQUAL( fc::crypto::public_key(), fc::crypto::public_key(prod["producer_key"].as_string()) ); - - //bob111111111 should not be able to vote for alice1111111 who is an unregistered producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer alice1111111 is not currently registered" ), - vote( N(bob111111111), { N(alice1111111) } ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( more_than_30_producer_voting, eosio_system_tester ) try { - issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("13.0000"), core_sym::from_string("0.5791") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); - - //bob111111111 should not be able to vote for alice1111111 who is not a producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "attempt to vote for too many producers" ), - vote( N(bob111111111), vector(31, N(alice1111111)) ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( vote_same_producer_30_times, eosio_system_tester ) try { - issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("100.0000") ), get_voter_info( "bob111111111" ) ); - - //alice1111111 becomes a producer - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - fc::variant params = producer_parameters_example(1); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key(N(alice1111111), "active") ) - ("url", "") - ("location", 0) - ) - ); - - //bob111111111 should not be able to vote for alice1111111 who is not a producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer votes must be unique and sorted" ), - vote( N(bob111111111), vector(30, N(alice1111111)) ) ); - - auto prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( 0 == prod["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( producer_keep_votes, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - fc::variant params = producer_parameters_example(1); - vector key = fc::raw::pack( get_public_key( N(alice1111111), "active" ) ); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url", "") - ("location", 0) - ) - ); - - //bob111111111 makes stake - issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("13.0000"), core_sym::from_string("0.5791") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); - - //bob111111111 votes for alice1111111 - BOOST_REQUIRE_EQUAL( success(), vote(N(bob111111111), { N(alice1111111) } ) ); - - auto prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("13.5791")) == prod["total_votes"].as_double() ); - - //unregister producer - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(unregprod), mvo() - ("producer", "alice1111111") - ) - ); - prod = get_producer_info( "alice1111111" ); - //key should be empty - BOOST_REQUIRE_EQUAL( fc::crypto::public_key(), fc::crypto::public_key(prod["producer_key"].as_string()) ); - //check parameters just in case - //REQUIRE_MATCHING_OBJECT( params, prod["prefs"]); - //votes should stay the same - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("13.5791")), prod["total_votes"].as_double() ); - - //regtister the same producer again - params = producer_parameters_example(2); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url", "") - ("location", 0) - ) - ); - prod = get_producer_info( "alice1111111" ); - //votes should stay the same - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("13.5791")), prod["total_votes"].as_double() ); - - //change parameters - params = producer_parameters_example(3); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url","") - ("location", 0) - ) - ); - prod = get_producer_info( "alice1111111" ); - //votes should stay the same - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("13.5791")), prod["total_votes"].as_double() ); - //check parameters just in case - //REQUIRE_MATCHING_OBJECT( params, prod["prefs"]); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( vote_for_two_producers, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - //alice1111111 becomes a producer - fc::variant params = producer_parameters_example(1); - auto key = get_public_key( N(alice1111111), "active" ); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url","") - ("location", 0) - ) - ); - //bob111111111 becomes a producer - params = producer_parameters_example(2); - key = get_public_key( N(bob111111111), "active" ); - BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproducer), mvo() - ("producer", "bob111111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url","") - ("location", 0) - ) - ); - - //carol1111111 votes for alice1111111 and bob111111111 - issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("15.0005"), core_sym::from_string("5.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111), N(bob111111111) } ) ); - - auto alice_info = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("20.0005")) == alice_info["total_votes"].as_double() ); - auto bob_info = get_producer_info( "bob111111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("20.0005")) == bob_info["total_votes"].as_double() ); - - //carol1111111 votes for alice1111111 (but revokes vote for bob111111111) - BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111) } ) ); - - alice_info = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("20.0005")) == alice_info["total_votes"].as_double() ); - bob_info = get_producer_info( "bob111111111" ); - BOOST_TEST_REQUIRE( 0 == bob_info["total_votes"].as_double() ); - - //alice1111111 votes for herself and bob111111111 - issue_and_transfer( "alice1111111", core_sym::from_string("2.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("1.0000"), core_sym::from_string("1.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote(N(alice1111111), { N(alice1111111), N(bob111111111) } ) ); - - alice_info = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("22.0005")) == alice_info["total_votes"].as_double() ); - - bob_info = get_producer_info( "bob111111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("2.0000")) == bob_info["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tester ) try { - //register proxy by first action for this user ever - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", true ) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); - - //unregister proxy - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", false) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111" ), get_voter_info( "alice1111111" ) ); - - //stake and then register as a proxy - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("200.0002"), core_sym::from_string("100.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() - ("proxy", "bob111111111") - ("isproxy", true) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( N(bob111111111) )( "staked", 3000003 ), get_voter_info( "bob111111111" ) ); - //unrgister and check that stake is still in place - BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() - ("proxy", "bob111111111") - ("isproxy", false) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("300.0003") ), get_voter_info( "bob111111111" ) ); - - //register as a proxy and then stake - BOOST_REQUIRE_EQUAL( success(), push_action( N(carol1111111), N(regproxy), mvo() - ("proxy", "carol1111111") - ("isproxy", true) - ) - ); - issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("246.0002"), core_sym::from_string("531.0001") ) ); - //check that both proxy flag and stake a correct - REQUIRE_MATCHING_OBJECT( proxy( N(carol1111111) )( "staked", 7770003 ), get_voter_info( "carol1111111" ) ); - - //unregister - BOOST_REQUIRE_EQUAL( success(), push_action( N(carol1111111), N(regproxy), mvo() - ("proxy", "carol1111111") - ("isproxy", false) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_sym::from_string("777.0003") ), get_voter_info( "carol1111111" ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( proxy_stake_unstake_keeps_proxy_flag, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", true) - ) - ); - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); - - //stake - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("50.0000") ) ); - //check that account is still a proxy - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "staked", 1500000 ), get_voter_info( "alice1111111" ) ); - - //stake more - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0000"), core_sym::from_string("20.0000") ) ); - //check that account is still a proxy - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )("staked", 2000000 ), get_voter_info( "alice1111111" ) ); - - //unstake more - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("65.0000"), core_sym::from_string("35.0000") ) ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )("staked", 1000000 ), get_voter_info( "alice1111111" ) ); - - //unstake the rest - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("65.0000"), core_sym::from_string("35.0000") ) ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "staked", 0 ), get_voter_info( "alice1111111" ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - cross_15_percent_threshold(); - - create_accounts_with_resources( { N(defproducer1), N(defproducer2), N(defproducer3) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer1), 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer2), 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer3), 3) ); - - //register as a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", true) - ) - ); - - //accumulate proxied votes - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote(N(bob111111111), vector(), N(alice1111111) ) ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); - - //vote for producers - BOOST_REQUIRE_EQUAL( success(), vote(N(alice1111111), { N(defproducer1), N(defproducer2) } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //vote for another producers - BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1), N(defproducer3) } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //unregister proxy - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", false) - ) - ); - //REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //register proxy again - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", true) - ) - ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //stake increase by proxy itself affects producers - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0001"), core_sym::from_string("20.0001") ) ); - BOOST_REQUIRE_EQUAL( stake2votes(core_sym::from_string("200.0005")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( stake2votes(core_sym::from_string("200.0005")), get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //stake decrease by proxy itself affects producers - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("10.0001"), core_sym::from_string("10.0001") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("180.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("180.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - const double continuous_rate = std::log1p(double(0.05)); - const double usecs_per_year = 52 * 7 * 24 * 3600 * 1000000ll; - const double secs_per_year = 52 * 7 * 24 * 3600; - - - const asset large_asset = core_sym::from_string("80.0000"); - create_account_with_resources( N(defproducera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(defproducerb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(defproducerc), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - - create_account_with_resources( N(producvotera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(producvoterb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - - BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducera))); - produce_block(fc::hours(24)); - auto prod = get_producer_info( N(defproducera) ); - BOOST_REQUIRE_EQUAL("defproducera", prod["owner"].as_string()); - BOOST_REQUIRE_EQUAL(0, prod["total_votes"].as_double()); - - transfer( config::system_account_name, "producvotera", core_sym::from_string("400000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000"))); - BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), { N(defproducera) })); - // defproducera is the only active producer - // produce enough blocks so new schedule kicks in and defproducera produces some blocks - { - produce_blocks(50); - - const auto initial_global_state = get_global_state(); - const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); - const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); - const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); - const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); - - prod = get_producer_info("defproducera"); - const uint32_t unpaid_blocks = prod["unpaid_blocks"].as(); - BOOST_REQUIRE(1 < unpaid_blocks); - - BOOST_REQUIRE_EQUAL(initial_tot_unpaid_blocks, unpaid_blocks); - - const asset initial_supply = get_token_supply(); - const asset initial_balance = get_balance(N(defproducera)); - - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - - const auto global_state = get_global_state(); - const uint64_t claim_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); - const int64_t pervote_bucket = global_state["pervote_bucket"].as(); - const int64_t perblock_bucket = global_state["perblock_bucket"].as(); - const int64_t savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); - - prod = get_producer_info("defproducera"); - BOOST_REQUIRE_EQUAL(1, prod["unpaid_blocks"].as()); - BOOST_REQUIRE_EQUAL(1, tot_unpaid_blocks); - const asset supply = get_token_supply(); - const asset balance = get_balance(N(defproducera)); - - BOOST_REQUIRE_EQUAL(claim_time, microseconds_since_epoch_of_iso_string( prod["last_claim_time"] )); - - auto usecs_between_fills = claim_time - initial_claim_time; - int32_t secs_between_fills = usecs_between_fills/1000000; - - BOOST_REQUIRE_EQUAL(0, initial_savings); - BOOST_REQUIRE_EQUAL(0, initial_perblock_bucket); - BOOST_REQUIRE_EQUAL(0, initial_pervote_bucket); - - BOOST_REQUIRE_EQUAL(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * continuous_rate ) / secs_per_year ), - supply.get_amount() - initial_supply.get_amount()); - BOOST_REQUIRE(within_one(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * (4. * continuous_rate/ 5.) / secs_per_year ) ), - savings - initial_savings)); - BOOST_REQUIRE(within_one(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * (0.25 * continuous_rate/ 5.) / secs_per_year ) ), - balance.get_amount() - initial_balance.get_amount())); - - int64_t from_perblock_bucket = int64_t( initial_supply.get_amount() * double(secs_between_fills) * (0.25 * continuous_rate/ 5.) / secs_per_year ) ; - int64_t from_pervote_bucket = int64_t( initial_supply.get_amount() * double(secs_between_fills) * (0.75 * continuous_rate/ 5.) / secs_per_year ) ; - - - if (from_pervote_bucket >= 100 * 10000) { - BOOST_REQUIRE_EQUAL(from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount()); - BOOST_REQUIRE_EQUAL(0, pervote_bucket); - } else { - BOOST_REQUIRE_EQUAL(from_perblock_bucket, balance.get_amount() - initial_balance.get_amount()); - BOOST_REQUIRE_EQUAL(from_pervote_bucket, pervote_bucket); - } - } - - { - BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), - push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - } - - // defproducera waits for 23 hours and 55 minutes, can't claim rewards yet - { - produce_block(fc::seconds(23 * 3600 + 55 * 60)); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), - push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - } - - // wait 5 more minutes, defproducera can now claim rewards again - { - produce_block(fc::seconds(5 * 60)); - - const auto initial_global_state = get_global_state(); - const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); - const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); - const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); - const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); - const double initial_tot_vote_weight = initial_global_state["total_producer_vote_weight"].as(); - - prod = get_producer_info("defproducera"); - const uint32_t unpaid_blocks = prod["unpaid_blocks"].as(); - BOOST_REQUIRE(1 < unpaid_blocks); - BOOST_REQUIRE_EQUAL(initial_tot_unpaid_blocks, unpaid_blocks); - BOOST_REQUIRE(0 < prod["total_votes"].as()); - BOOST_TEST(initial_tot_vote_weight, prod["total_votes"].as()); - BOOST_REQUIRE(0 < microseconds_since_epoch_of_iso_string( prod["last_claim_time"] )); - - BOOST_REQUIRE_EQUAL(initial_tot_unpaid_blocks, unpaid_blocks); - - const asset initial_supply = get_token_supply(); - const asset initial_balance = get_balance(N(defproducera)); - - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - - const auto global_state = get_global_state(); - const uint64_t claim_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); - const int64_t pervote_bucket = global_state["pervote_bucket"].as(); - const int64_t perblock_bucket = global_state["perblock_bucket"].as(); - const int64_t savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); - - prod = get_producer_info("defproducera"); - BOOST_REQUIRE_EQUAL(1, prod["unpaid_blocks"].as()); - BOOST_REQUIRE_EQUAL(1, tot_unpaid_blocks); - const asset supply = get_token_supply(); - const asset balance = get_balance(N(defproducera)); - - BOOST_REQUIRE_EQUAL(claim_time, microseconds_since_epoch_of_iso_string( prod["last_claim_time"] )); - auto usecs_between_fills = claim_time - initial_claim_time; - - BOOST_REQUIRE_EQUAL( int64_t( initial_supply.get_amount() * double(usecs_between_fills) * continuous_rate / usecs_per_year ), - supply.get_amount() - initial_supply.get_amount() ); - BOOST_REQUIRE_EQUAL( (supply.get_amount() - initial_supply.get_amount()) - (supply.get_amount() - initial_supply.get_amount()) / 5, - savings - initial_savings ); - - int64_t to_producer = int64_t( initial_supply.get_amount() * double(usecs_between_fills) * continuous_rate / usecs_per_year ) / 5; - int64_t to_perblock_bucket = to_producer / 4; - int64_t to_pervote_bucket = to_producer - to_perblock_bucket; - - if (to_pervote_bucket + initial_pervote_bucket >= 100 * 10000) { - BOOST_REQUIRE_EQUAL(to_perblock_bucket + to_pervote_bucket + initial_pervote_bucket, balance.get_amount() - initial_balance.get_amount()); - BOOST_REQUIRE_EQUAL(0, pervote_bucket); - } else { - BOOST_REQUIRE_EQUAL(to_perblock_bucket, balance.get_amount() - initial_balance.get_amount()); - BOOST_REQUIRE_EQUAL(to_pervote_bucket + initial_pervote_bucket, pervote_bucket); - } - } - - // defproducerb tries to claim rewards but he's not on the list - { - BOOST_REQUIRE_EQUAL(wasm_assert_msg("unable to find key"), - push_action(N(defproducerb), N(claimrewards), mvo()("owner", "defproducerb"))); - } - - // test stability over a year - { - regproducer(N(defproducerb)); - regproducer(N(defproducerc)); - produce_block(fc::hours(24)); - const asset initial_supply = get_token_supply(); - const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); - for (uint32_t i = 0; i < 7 * 52; ++i) { - produce_block(fc::seconds(8 * 3600)); - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducerc), N(claimrewards), mvo()("owner", "defproducerc"))); - produce_block(fc::seconds(8 * 3600)); - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducerb), N(claimrewards), mvo()("owner", "defproducerb"))); - produce_block(fc::seconds(8 * 3600)); - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - } - const asset supply = get_token_supply(); - const int64_t savings = get_balance(N(eosio.saving)).get_amount(); - // Amount issued per year is very close to the 5% inflation target. Small difference (500 tokens out of 50'000'000 issued) - // is due to compounding every 8 hours in this test as opposed to theoretical continuous compounding - BOOST_REQUIRE(500 * 10000 > int64_t(double(initial_supply.get_amount()) * double(0.05)) - (supply.get_amount() - initial_supply.get_amount())); - BOOST_REQUIRE(500 * 10000 > int64_t(double(initial_supply.get_amount()) * double(0.04)) - (savings - initial_savings)); - } -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { - - { - BOOST_REQUIRE_EQUAL( success(), - setinflation(0, 10000, 10000) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("annual_rate can't be negative"), - setinflation(-1, 10000, 10000) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("inflation_pay_factor must not be less than 10000"), - setinflation(1, 9999, 10000) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("votepay_factor must not be less than 10000"), - setinflation(1, 10000, 9999) ); - } - - { - const asset large_asset = core_sym::from_string("80.0000"); - create_account_with_resources( N(defproducera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(defproducerb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(defproducerc), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - - create_account_with_resources( N(producvotera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(producvoterb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - - BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducera))); - BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducerb))); - BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducerc))); - - produce_block(fc::hours(24)); - - transfer( config::system_account_name, "producvotera", core_sym::from_string("400000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000"))); - BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), { N(defproducera),N(defproducerb),N(defproducerc) })); - - auto run_for_1year = [this](int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor) { - - double inflation = double(annual_rate)/double(10000); - - BOOST_REQUIRE_EQUAL(success(), setinflation( - annual_rate, - inflation_pay_factor, - votepay_factor - )); - - produce_block(fc::hours(24)); - const asset initial_supply = get_token_supply(); - const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); - for (uint32_t i = 0; i < 7 * 52; ++i) { - produce_block(fc::seconds(8 * 3600)); - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducerc), N(claimrewards), mvo()("owner", "defproducerc"))); - produce_block(fc::seconds(8 * 3600)); - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducerb), N(claimrewards), mvo()("owner", "defproducerb"))); - produce_block(fc::seconds(8 * 3600)); - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - } - const asset final_supply = get_token_supply(); - const int64_t final_savings = get_balance(N(eosio.saving)).get_amount(); - - double computed_new_tokens = double(final_supply.get_amount() - initial_supply.get_amount()); - double theoretical_new_tokens = double(initial_supply.get_amount())*inflation; - double diff_new_tokens = std::abs(theoretical_new_tokens-computed_new_tokens); - - if( annual_rate > 0 ) { - //Error should be less than 0.3% - BOOST_REQUIRE( diff_new_tokens/theoretical_new_tokens < double(0.003) ); - } else { - BOOST_REQUIRE_EQUAL( computed_new_tokens, 0 ); - BOOST_REQUIRE_EQUAL( theoretical_new_tokens, 0 ); - } - - double savings_inflation = inflation - inflation * 10000 / inflation_pay_factor; - - double computed_savings_tokens = double(final_savings-initial_savings); - double theoretical_savings_tokens = double(initial_supply.get_amount())*savings_inflation; - double diff_savings_tokens = std::abs(theoretical_savings_tokens-computed_savings_tokens); - - if( annual_rate > 0 ) { - //Error should be less than 0.3% - BOOST_REQUIRE( diff_savings_tokens/theoretical_savings_tokens < double(0.003) ); - } else { - BOOST_REQUIRE_EQUAL( computed_savings_tokens, 0 ); - BOOST_REQUIRE_EQUAL( theoretical_savings_tokens, 0 ); - } - }; - - // 1% inflation for 1 year. 50% savings / 50% bp reward. 10000 / 50000 = 0.2 => 20% blockpay, 80% votepay - run_for_1year(100, 20000, 50000); - - // 3% inflation for 1 year. 66.6% savings / 33.33% bp reward. 10000/13333 = 0.75 => 75% blockpay, 25% votepay - run_for_1year(300, 30000, 13333); - - // 0% inflation for 1 year - run_for_1year(0, 30000, 50000); - } - -} FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_CASE(extreme_inflation) try { - eosio_system_tester t(eosio_system_tester::setup_level::minimal); - symbol core_symbol{CORE_SYM}; - t.create_currency( N(eosio.token), config::system_account_name, asset((1ll << 62) - 1, core_symbol) ); - t.issue( asset(10000000000000, core_symbol) ); - t.deploy_contract(); - t.produce_block(); - t.create_account_with_resources(N(defproducera), config::system_account_name, core_sym::from_string("1.0000"), false); - BOOST_REQUIRE_EQUAL(t.success(), t.regproducer(N(defproducera))); - t.transfer( config::system_account_name, "defproducera", core_sym::from_string("200000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(t.success(), t.stake("defproducera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000"))); - BOOST_REQUIRE_EQUAL(t.success(), t.vote( N(defproducera), { N(defproducera) })); - t.produce_blocks(4); - t.produce_block(fc::hours(24)); - - BOOST_REQUIRE_EQUAL(t.success(), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - t.produce_block(); - asset current_supply; - { - vector data = t.get_row_by_account( N(eosio.token), name(core_symbol.to_symbol_code().value), N(stat), account_name(core_symbol.to_symbol_code().value) ); - current_supply = t.token_abi_ser.binary_to_variant("currency_stats", data, abi_serializer::create_yield_function(eosio_system_tester::abi_serializer_max_time))["supply"].template as(); - } - t.issue( asset((1ll << 62) - 1, core_symbol) - current_supply ); - BOOST_REQUIRE_EQUAL(t.success(), t.setinflation(std::numeric_limits::max(), 50000, 40000)); - t.produce_block(); - - t.produce_block(fc::hours(10*24)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("quantity exceeds available supply"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - - t.produce_block(fc::hours(11*24)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("magnitude of asset amount must be less than 2^62"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - - t.produce_block(fc::hours(24)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("overflow in calculating new tokens to be issued; inflation rate is too high"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - BOOST_REQUIRE_EQUAL(t.success(), t.setinflation(500, 50000, 40000)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("quantity exceeds available supply"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - const int64_t secs_per_year = 52 * 7 * 24 * 3600; - const double usecs_per_year = secs_per_year * 1000000; - const double cont_rate = std::log1p(double(0.05)); - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; - for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_sym::from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); - } - - // create accounts {defproducera, defproducerb, ..., defproducerz, abcproducera, ..., defproducern} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - { - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - } - { - const std::string root("abcproducer"); - for ( char c = 'a'; c <= 'n'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - } - setup_producer_accounts(producer_names); - for (const auto& p: producer_names) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - produce_blocks(1); - ilog( "------ get pro----------" ); - wdump((p)); - BOOST_TEST(0 == get_producer_info(p)["total_votes"].as()); - } - } - - produce_block( fc::hours(24) ); - - // producvotera votes for defproducera ... defproducerj - // producvoterb votes for defproducera ... defproduceru - // producvoterc votes for defproducera ... defproducerz - // producvoterd votes for abcproducera ... abcproducern - { - BOOST_REQUIRE_EQUAL(success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.begin()+10))); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21))); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterc), vector(producer_names.begin(), producer_names.begin()+26))); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterd), vector(producer_names.begin()+26, producer_names.end()))); - } - - { - auto proda = get_producer_info( N(defproducera) ); - auto prodj = get_producer_info( N(defproducerj) ); - auto prodk = get_producer_info( N(defproducerk) ); - auto produ = get_producer_info( N(defproduceru) ); - auto prodv = get_producer_info( N(defproducerv) ); - auto prodz = get_producer_info( N(defproducerz) ); - - BOOST_REQUIRE (0 == proda["unpaid_blocks"].as() && 0 == prodz["unpaid_blocks"].as()); - - // check vote ratios - BOOST_REQUIRE ( 0 < proda["total_votes"].as() && 0 < prodz["total_votes"].as() ); - BOOST_TEST( proda["total_votes"].as() == prodj["total_votes"].as() ); - BOOST_TEST( prodk["total_votes"].as() == produ["total_votes"].as() ); - BOOST_TEST( prodv["total_votes"].as() == prodz["total_votes"].as() ); - BOOST_TEST( 2 * proda["total_votes"].as() == 3 * produ["total_votes"].as() ); - BOOST_TEST( proda["total_votes"].as() == 3 * prodz["total_votes"].as() ); - } - - // give a chance for everyone to produce blocks - { - produce_blocks(23 * 12 + 20); - bool all_21_produced = true; - for (uint32_t i = 0; i < 21; ++i) { - if (0 == get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - all_21_produced = false; - } - } - bool rest_didnt_produce = true; - for (uint32_t i = 21; i < producer_names.size(); ++i) { - if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - rest_didnt_produce = false; - } - } - BOOST_REQUIRE(all_21_produced && rest_didnt_produce); - } - - std::vector vote_shares(producer_names.size()); - { - double total_votes = 0; - for (uint32_t i = 0; i < producer_names.size(); ++i) { - vote_shares[i] = get_producer_info(producer_names[i])["total_votes"].as(); - total_votes += vote_shares[i]; - } - BOOST_TEST(total_votes == get_global_state()["total_producer_vote_weight"].as()); - std::for_each(vote_shares.begin(), vote_shares.end(), [total_votes](double& x) { x /= total_votes; }); - - BOOST_TEST(double(1) == std::accumulate(vote_shares.begin(), vote_shares.end(), double(0))); - BOOST_TEST(double(3./71.) == vote_shares.front()); - BOOST_TEST(double(1./71.) == vote_shares.back()); - } - - { - const uint32_t prod_index = 2; - const auto prod_name = producer_names[prod_index]; - - const auto initial_global_state = get_global_state(); - const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); - const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); - const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); - const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); - const asset initial_supply = get_token_supply(); - const asset initial_bpay_balance = get_balance(N(eosio.bpay)); - const asset initial_vpay_balance = get_balance(N(eosio.vpay)); - const asset initial_balance = get_balance(prod_name); - const uint32_t initial_unpaid_blocks = get_producer_info(prod_name)["unpaid_blocks"].as(); - - BOOST_REQUIRE_EQUAL(success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - - const auto global_state = get_global_state(); - const uint64_t claim_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); - const int64_t pervote_bucket = global_state["pervote_bucket"].as(); - const int64_t perblock_bucket = global_state["perblock_bucket"].as(); - const int64_t savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); - const asset supply = get_token_supply(); - const asset bpay_balance = get_balance(N(eosio.bpay)); - const asset vpay_balance = get_balance(N(eosio.vpay)); - const asset balance = get_balance(prod_name); - const uint32_t unpaid_blocks = get_producer_info(prod_name)["unpaid_blocks"].as(); - - const uint64_t usecs_between_fills = claim_time - initial_claim_time; - const int32_t secs_between_fills = static_cast(usecs_between_fills / 1000000); - - const double expected_supply_growth = initial_supply.get_amount() * double(usecs_between_fills) * cont_rate / usecs_per_year; - BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth), supply.get_amount() - initial_supply.get_amount() ); - - BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth) - int64_t(expected_supply_growth)/5, savings - initial_savings ); - - const int64_t expected_perblock_bucket = initial_supply.get_amount() * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year; - const int64_t expected_pervote_bucket = initial_supply.get_amount() * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year; - - const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks ; - const int64_t from_pervote_bucket = vote_shares[prod_index] * expected_pervote_bucket; - - BOOST_REQUIRE( 1 >= abs(int32_t(initial_tot_unpaid_blocks - tot_unpaid_blocks) - int32_t(initial_unpaid_blocks - unpaid_blocks)) ); - - if (from_pervote_bucket >= 100 * 10000) { - BOOST_REQUIRE( within_one( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ) ); - BOOST_REQUIRE( within_one( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ) ); - } else { - BOOST_REQUIRE( within_one( from_perblock_bucket, balance.get_amount() - initial_balance.get_amount() ) ); - BOOST_REQUIRE( within_one( expected_pervote_bucket, pervote_bucket ) ); - BOOST_REQUIRE( within_one( expected_pervote_bucket, vpay_balance.get_amount() ) ); - BOOST_REQUIRE( within_one( perblock_bucket, bpay_balance.get_amount() ) ); - } - - produce_blocks(5); - - BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - } - - { - const uint32_t prod_index = 23; - const auto prod_name = producer_names[prod_index]; - BOOST_REQUIRE_EQUAL(success(), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - BOOST_REQUIRE_EQUAL(0, get_balance(prod_name).get_amount()); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - } - - // Wait for 23 hours. By now, pervote_bucket has grown enough - // that a producer's share is more than 100 tokens. - produce_block(fc::seconds(23 * 3600)); - - { - const uint32_t prod_index = 15; - const auto prod_name = producer_names[prod_index]; - - const auto initial_global_state = get_global_state(); - const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); - const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); - const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); - const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); - const asset initial_supply = get_token_supply(); - const asset initial_bpay_balance = get_balance(N(eosio.bpay)); - const asset initial_vpay_balance = get_balance(N(eosio.vpay)); - const asset initial_balance = get_balance(prod_name); - const uint32_t initial_unpaid_blocks = get_producer_info(prod_name)["unpaid_blocks"].as(); - - BOOST_REQUIRE_EQUAL(success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - - const auto global_state = get_global_state(); - const uint64_t claim_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); - const int64_t pervote_bucket = global_state["pervote_bucket"].as(); - const int64_t perblock_bucket = global_state["perblock_bucket"].as(); - const int64_t savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); - const asset supply = get_token_supply(); - const asset bpay_balance = get_balance(N(eosio.bpay)); - const asset vpay_balance = get_balance(N(eosio.vpay)); - const asset balance = get_balance(prod_name); - const uint32_t unpaid_blocks = get_producer_info(prod_name)["unpaid_blocks"].as(); - - const uint64_t usecs_between_fills = claim_time - initial_claim_time; - - const double expected_supply_growth = initial_supply.get_amount() * double(usecs_between_fills) * cont_rate / usecs_per_year; - BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth), supply.get_amount() - initial_supply.get_amount() ); - BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth) - int64_t(expected_supply_growth)/5, savings - initial_savings ); - - const int64_t expected_perblock_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year ) - + initial_perblock_bucket; - const int64_t expected_pervote_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year ) - + initial_pervote_bucket; - const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks ; - const int64_t from_pervote_bucket = int64_t( vote_shares[prod_index] * expected_pervote_bucket); - - BOOST_REQUIRE( 1 >= abs(int32_t(initial_tot_unpaid_blocks - tot_unpaid_blocks) - int32_t(initial_unpaid_blocks - unpaid_blocks)) ); - if (from_pervote_bucket >= 100 * 10000) { - BOOST_REQUIRE( within_one( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ) ); - BOOST_REQUIRE( within_one( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ) ); - BOOST_REQUIRE( within_one( expected_pervote_bucket - from_pervote_bucket, vpay_balance.get_amount() ) ); - BOOST_REQUIRE( within_one( expected_perblock_bucket - from_perblock_bucket, perblock_bucket ) ); - BOOST_REQUIRE( within_one( expected_perblock_bucket - from_perblock_bucket, bpay_balance.get_amount() ) ); - } else { - BOOST_REQUIRE( within_one( from_perblock_bucket, balance.get_amount() - initial_balance.get_amount() ) ); - BOOST_REQUIRE( within_one( expected_pervote_bucket, pervote_bucket ) ); - } - - produce_blocks(5); - - BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - } - - { - const uint32_t prod_index = 24; - const auto prod_name = producer_names[prod_index]; - BOOST_REQUIRE_EQUAL(success(), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - BOOST_REQUIRE(100 * 10000 <= get_balance(prod_name).get_amount()); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - } - - { - const uint32_t rmv_index = 5; - account_name prod_name = producer_names[rmv_index]; - - auto info = get_producer_info(prod_name); - BOOST_REQUIRE( info["is_active"].as() ); - BOOST_REQUIRE( fc::crypto::public_key() != fc::crypto::public_key(info["producer_key"].as_string()) ); - - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action(prod_name, N(rmvproducer), mvo()("producer", prod_name))); - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action(producer_names[rmv_index + 2], N(rmvproducer), mvo()("producer", prod_name) ) ); - BOOST_REQUIRE_EQUAL( success(), - push_action(config::system_account_name, N(rmvproducer), mvo()("producer", prod_name) ) ); - { - bool rest_didnt_produce = true; - for (uint32_t i = 21; i < producer_names.size(); ++i) { - if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - rest_didnt_produce = false; - } - } - BOOST_REQUIRE(rest_didnt_produce); - } - - produce_blocks(3 * 21 * 12); - info = get_producer_info(prod_name); - const uint32_t init_unpaid_blocks = info["unpaid_blocks"].as(); - BOOST_REQUIRE( !info["is_active"].as() ); - BOOST_REQUIRE( fc::crypto::public_key() == fc::crypto::public_key(info["producer_key"].as_string()) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("producer does not have an active key"), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); - produce_blocks(3 * 21 * 12); - BOOST_REQUIRE_EQUAL( init_unpaid_blocks, get_producer_info(prod_name)["unpaid_blocks"].as() ); - { - bool prod_was_replaced = false; - for (uint32_t i = 21; i < producer_names.size(); ++i) { - if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - prod_was_replaced = true; - } - } - BOOST_REQUIRE(prod_was_replaced); - } - } - - { - BOOST_REQUIRE_EQUAL( wasm_assert_msg("producer not found"), - push_action( config::system_account_name, N(rmvproducer), mvo()("producer", "nonexistingp") ) ); - } - - produce_block(fc::hours(24)); - - // switch to new producer pay metric - { - BOOST_REQUIRE_EQUAL( 0, get_global_state2()["revision"].as() ); - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action(producer_names[1], N(updtrevision), mvo()("revision", 1) ) ); - BOOST_REQUIRE_EQUAL( success(), - push_action(config::system_account_name, N(updtrevision), mvo()("revision", 1) ) ); - BOOST_REQUIRE_EQUAL( 1, get_global_state2()["revision"].as() ); - - const uint32_t prod_index = 2; - const auto prod_name = producer_names[prod_index]; - - const auto initial_prod_info = get_producer_info(prod_name); - const auto initial_prod_info2 = get_producer_info2(prod_name); - const auto initial_global_state = get_global_state(); - const double initial_tot_votepay_share = get_global_state2()["total_producer_votepay_share"].as_double(); - const double initial_tot_vpay_rate = get_global_state3()["total_vpay_share_change_rate"].as_double(); - const uint64_t initial_vpay_state_update = microseconds_since_epoch_of_iso_string( get_global_state3()["last_vpay_state_update"] ); - const uint64_t initial_bucket_fill_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); - const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); - const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); - const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); - const asset initial_supply = get_token_supply(); - const asset initial_balance = get_balance(prod_name); - const uint32_t initial_unpaid_blocks = initial_prod_info["unpaid_blocks"].as(); - const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_prod_info["last_claim_time"] ); - const uint64_t initial_prod_update_time = microseconds_since_epoch_of_iso_string( initial_prod_info2["last_votepay_share_update"] ); - - BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); - BOOST_REQUIRE_EQUAL( success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); - - const auto prod_info = get_producer_info(prod_name); - const auto prod_info2 = get_producer_info2(prod_name); - const auto global_state = get_global_state(); - const uint64_t vpay_state_update = microseconds_since_epoch_of_iso_string( get_global_state3()["last_vpay_state_update"] ); - const uint64_t bucket_fill_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); - const int64_t pervote_bucket = global_state["pervote_bucket"].as(); - const int64_t perblock_bucket = global_state["perblock_bucket"].as(); - const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); - const asset supply = get_token_supply(); - const asset balance = get_balance(prod_name); - const uint32_t unpaid_blocks = prod_info["unpaid_blocks"].as(); - const uint64_t claim_time = microseconds_since_epoch_of_iso_string( prod_info["last_claim_time"] ); - const uint64_t prod_update_time = microseconds_since_epoch_of_iso_string( prod_info2["last_votepay_share_update"] ); - - const uint64_t usecs_between_fills = bucket_fill_time - initial_bucket_fill_time; - const double secs_between_global_updates = (vpay_state_update - initial_vpay_state_update) / 1E6; - const double secs_between_prod_updates = (prod_update_time - initial_prod_update_time) / 1E6; - const double votepay_share = initial_prod_info2["votepay_share"].as_double() + secs_between_prod_updates * prod_info["total_votes"].as_double(); - const double tot_votepay_share = initial_tot_votepay_share + initial_tot_vpay_rate * secs_between_global_updates; - - const int64_t expected_perblock_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year ) - + initial_perblock_bucket; - const int64_t expected_pervote_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year ) - + initial_pervote_bucket; - const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks; - const int64_t from_pervote_bucket = int64_t( ( votepay_share * expected_pervote_bucket ) / tot_votepay_share ); - - const double expected_supply_growth = initial_supply.get_amount() * double(usecs_between_fills) * cont_rate / usecs_per_year; - BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth), supply.get_amount() - initial_supply.get_amount() ); - BOOST_REQUIRE_EQUAL( claim_time, vpay_state_update ); - BOOST_REQUIRE( 100 * 10000 < from_pervote_bucket ); - BOOST_CHECK_EQUAL( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ); - BOOST_CHECK_EQUAL( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); - - produce_block(fc::hours(2)); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("already claimed rewards within past day"), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; - for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_sym::from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); - } - - // create accounts {defproducera, defproducerb, ..., defproducerz, abcproducera, ..., defproducern} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - { - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - } - { - const std::string root("abcproducer"); - for ( char c = 'a'; c <= 'n'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - } - setup_producer_accounts(producer_names); - for (const auto& p: producer_names) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - produce_blocks(1); - ilog( "------ get pro----------" ); - wdump((p)); - BOOST_TEST_REQUIRE(0 == get_producer_info(p)["total_votes"].as_double()); - BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["votepay_share"].as_double()); - BOOST_REQUIRE(0 < microseconds_since_epoch_of_iso_string( get_producer_info2(p)["last_votepay_share_update"] )); - } - } - - produce_block( fc::hours(24) ); - - // producvotera votes for defproducera ... defproducerj - // producvoterb votes for defproducera ... defproduceru - // producvoterc votes for defproducera ... defproducerz - // producvoterd votes for abcproducera ... abcproducern - { - BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_REQUIRE_EQUAL( success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.begin()+10)) ); - produce_block( fc::hours(10) ); - BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); - const auto& init_info = get_producer_info(producer_names[0]); - const auto& init_info2 = get_producer_info2(producer_names[0]); - uint64_t init_update = microseconds_since_epoch_of_iso_string( init_info2["last_votepay_share_update"] ); - double init_votes = init_info["total_votes"].as_double(); - BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21)) ); - const auto& info = get_producer_info(producer_names[0]); - const auto& info2 = get_producer_info2(producer_names[0]); - BOOST_TEST_REQUIRE( ((microseconds_since_epoch_of_iso_string( info2["last_votepay_share_update"] ) - init_update)/double(1E6)) * init_votes == info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( info2["votepay_share"].as_double() * 10 == get_global_state2()["total_producer_votepay_share"].as_double() ); - - BOOST_TEST_REQUIRE( 0 == get_producer_info2(producer_names[11])["votepay_share"].as_double() ); - produce_block( fc::hours(13) ); - BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterc), vector(producer_names.begin(), producer_names.begin()+26)) ); - BOOST_REQUIRE( 0 < get_producer_info2(producer_names[11])["votepay_share"].as_double() ); - produce_block( fc::hours(1) ); - BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterd), vector(producer_names.begin()+26, producer_names.end())) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(producer_names[26])["votepay_share"].as_double() ); - } - - { - auto proda = get_producer_info( N(defproducera) ); - auto prodj = get_producer_info( N(defproducerj) ); - auto prodk = get_producer_info( N(defproducerk) ); - auto produ = get_producer_info( N(defproduceru) ); - auto prodv = get_producer_info( N(defproducerv) ); - auto prodz = get_producer_info( N(defproducerz) ); - - BOOST_REQUIRE (0 == proda["unpaid_blocks"].as() && 0 == prodz["unpaid_blocks"].as()); - - // check vote ratios - BOOST_REQUIRE ( 0 < proda["total_votes"].as_double() && 0 < prodz["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( proda["total_votes"].as_double() == prodj["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( prodk["total_votes"].as_double() == produ["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( prodv["total_votes"].as_double() == prodz["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( 2 * proda["total_votes"].as_double() == 3 * produ["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( proda["total_votes"].as_double() == 3 * prodz["total_votes"].as_double() ); - } - - std::vector vote_shares(producer_names.size()); - { - double total_votes = 0; - for (uint32_t i = 0; i < producer_names.size(); ++i) { - vote_shares[i] = get_producer_info(producer_names[i])["total_votes"].as_double(); - total_votes += vote_shares[i]; - } - BOOST_TEST_REQUIRE( total_votes == get_global_state()["total_producer_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( total_votes == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_REQUIRE_EQUAL( microseconds_since_epoch_of_iso_string( get_producer_info2(producer_names.back())["last_votepay_share_update"] ), - microseconds_since_epoch_of_iso_string( get_global_state3()["last_vpay_state_update"] ) ); - - std::for_each( vote_shares.begin(), vote_shares.end(), [total_votes](double& x) { x /= total_votes; } ); - BOOST_TEST_REQUIRE( double(1) == std::accumulate(vote_shares.begin(), vote_shares.end(), double(0)) ); - BOOST_TEST_REQUIRE( double(3./71.) == vote_shares.front() ); - BOOST_TEST_REQUIRE( double(1./71.) == vote_shares.back() ); - } - - std::vector votepay_shares(producer_names.size()); - { - const auto& gs3 = get_global_state3(); - double total_votepay_shares = 0; - double expected_total_votepay_shares = 0; - for (uint32_t i = 0; i < producer_names.size() ; ++i) { - const auto& info = get_producer_info(producer_names[i]); - const auto& info2 = get_producer_info2(producer_names[i]); - votepay_shares[i] = info2["votepay_share"].as_double(); - total_votepay_shares += votepay_shares[i]; - expected_total_votepay_shares += votepay_shares[i]; - expected_total_votepay_shares += info["total_votes"].as_double() - * double( ( microseconds_since_epoch_of_iso_string( gs3["last_vpay_state_update"] ) - - microseconds_since_epoch_of_iso_string( info2["last_votepay_share_update"] ) - ) / 1E6 ); - } - BOOST_TEST( expected_total_votepay_shares > total_votepay_shares ); - BOOST_TEST_REQUIRE( expected_total_votepay_shares == get_global_state2()["total_producer_votepay_share"].as_double() ); - } - - { - const uint32_t prod_index = 15; - const account_name prod_name = producer_names[prod_index]; - const auto& init_info = get_producer_info(prod_name); - const auto& init_info2 = get_producer_info2(prod_name); - BOOST_REQUIRE( 0 < init_info2["votepay_share"].as_double() ); - BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( init_info2["last_votepay_share_update"] ) ); - - BOOST_REQUIRE_EQUAL( success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name)) ); - - BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); - BOOST_REQUIRE_EQUAL( get_producer_info(prod_name)["last_claim_time"].as_string(), - get_producer_info2(prod_name)["last_votepay_share_update"].as_string() ); - BOOST_REQUIRE_EQUAL( get_producer_info(prod_name)["last_claim_time"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - const auto& gs3 = get_global_state3(); - double expected_total_votepay_shares = 0; - for (uint32_t i = 0; i < producer_names.size(); ++i) { - const auto& info = get_producer_info(producer_names[i]); - const auto& info2 = get_producer_info2(producer_names[i]); - expected_total_votepay_shares += info2["votepay_share"].as_double(); - expected_total_votepay_shares += info["total_votes"].as_double() - * double( ( microseconds_since_epoch_of_iso_string( gs3["last_vpay_state_update"] ) - - microseconds_since_epoch_of_iso_string( info2["last_votepay_share_update"] ) - ) / 1E6 ); - } - BOOST_TEST_REQUIRE( expected_total_votepay_shares == get_global_state2()["total_producer_votepay_share"].as_double() ); - } - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(votepay_share_invariant, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - cross_15_percent_threshold(); - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_sym::from_string("1000.0000"), config::system_account_name ); - } - const auto vota = accounts[0]; - const auto votb = accounts[1]; - const auto proda = accounts[2]; - const auto prodb = accounts[3]; - - BOOST_REQUIRE_EQUAL( success(), stake( vota, core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( votb, core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); - - BOOST_REQUIRE_EQUAL( success(), regproducer( proda ) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( prodb ) ); - - BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); - BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); - - produce_block( fc::hours(25) ); - - BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); - BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); - - produce_block( fc::hours(1) ); - - BOOST_REQUIRE_EQUAL( success(), push_action(proda, N(claimrewards), mvo()("owner", proda)) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(proda)["votepay_share"].as_double() ); - - produce_block( fc::hours(24) ); - - BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); - - produce_block( fc::hours(24) ); - - BOOST_REQUIRE_EQUAL( success(), push_action(prodb, N(claimrewards), mvo()("owner", prodb)) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(prodb)["votepay_share"].as_double() ); - - produce_block( fc::hours(10) ); - - BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); - - produce_block( fc::hours(16) ); - - BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); - produce_block( fc::hours(2) ); - BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); - - const auto& info = get_producer_info(prodb); - const auto& info2 = get_producer_info2(prodb); - const auto& gs2 = get_global_state2(); - const auto& gs3 = get_global_state3(); - - double expected_total_vpay_share = info2["votepay_share"].as_double() - + info["total_votes"].as_double() - * ( microseconds_since_epoch_of_iso_string( gs3["last_vpay_state_update"] ) - - microseconds_since_epoch_of_iso_string( info2["last_votepay_share_update"] ) ) / 1E6; - - BOOST_TEST_REQUIRE( expected_total_vpay_share == gs2["total_producer_votepay_share"].as_double() ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_test::tolerance(1e-5)) try { - - cross_15_percent_threshold(); - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_sym::from_string("1000.0000"), config::system_account_name ); - } - const auto alice = accounts[0]; - const auto bob = accounts[1]; - const auto carol = accounts[2]; - const auto emily = accounts[3]; - - // alice becomes a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( alice, N(regproxy), mvo()("proxy", alice)("isproxy", true) ) ); - REQUIRE_MATCHING_OBJECT( proxy( alice ), get_voter_info( alice ) ); - - // carol and emily become producers - BOOST_REQUIRE_EQUAL( success(), regproducer( carol, 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( emily, 1) ); - - // bob chooses alice as proxy - BOOST_REQUIRE_EQUAL( success(), stake( bob, core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( alice, core_sym::from_string("150.0000"), core_sym::from_string("150.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( bob, { }, alice ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_voter_info(alice)["proxied_vote_weight"].as_double() ); - - // alice (proxy) votes for carol - BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol } ) ); - double total_votes = get_producer_info(carol)["total_votes"].as_double(); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("450.0003")) == total_votes ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); - uint64_t last_update_time = microseconds_since_epoch_of_iso_string( get_producer_info2(carol)["last_votepay_share_update"] ); - - produce_block( fc::hours(15) ); - - // alice (proxy) votes again for carol - BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol } ) ); - auto cur_info2 = get_producer_info2(carol); - double expected_votepay_share = double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("450.0003")) == get_producer_info(carol)["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - last_update_time = microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ); - total_votes = get_producer_info(carol)["total_votes"].as_double(); - - produce_block( fc::hours(40) ); - - // bob unstakes - BOOST_REQUIRE_EQUAL( success(), unstake( bob, core_sym::from_string("10.0002"), core_sym::from_string("10.0001") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); - - cur_info2 = get_producer_info2(carol); - expected_votepay_share += double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; - BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - last_update_time = microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ); - total_votes = get_producer_info(carol)["total_votes"].as_double(); - - // carol claims rewards - BOOST_REQUIRE_EQUAL( success(), push_action(carol, N(claimrewards), mvo()("owner", carol)) ); - - produce_block( fc::hours(20) ); - - // bob votes for carol - BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); - cur_info2 = get_producer_info2(carol); - expected_votepay_share = double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; - BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - - produce_block( fc::hours(54) ); - - // bob votes for carol again - // carol hasn't claimed rewards in over 3 days - total_votes = get_producer_info(carol)["total_votes"].as_double(); - BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); - BOOST_REQUIRE_EQUAL( get_producer_info2(carol)["last_votepay_share_update"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - - produce_block( fc::hours(20) ); - - // bob votes for carol again - // carol still hasn't claimed rewards - BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); - BOOST_REQUIRE_EQUAL(get_producer_info2(carol)["last_votepay_share_update"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - - produce_block( fc::hours(24) ); - - // carol finally claims rewards - BOOST_REQUIRE_EQUAL( success(), push_action( carol, N(claimrewards), mvo()("owner", carol) ) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( total_votes == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - - produce_block( fc::hours(5) ); - - // alice votes for carol and emily - // emily hasn't claimed rewards in over 3 days - last_update_time = microseconds_since_epoch_of_iso_string( get_producer_info2(carol)["last_votepay_share_update"] ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); - cur_info2 = get_producer_info2(carol); - auto cur_info2_emily = get_producer_info2(emily); - - expected_votepay_share = double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; - BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == cur_info2_emily["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( get_producer_info(carol)["total_votes"].as_double() == - get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_REQUIRE_EQUAL( cur_info2["last_votepay_share_update"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - BOOST_REQUIRE_EQUAL( cur_info2_emily["last_votepay_share_update"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - - produce_block( fc::hours(10) ); - - // bob chooses alice as proxy - // emily still hasn't claimed rewards - last_update_time = microseconds_since_epoch_of_iso_string( get_producer_info2(carol)["last_votepay_share_update"] ); - BOOST_REQUIRE_EQUAL( success(), vote( bob, { }, alice ) ); - cur_info2 = get_producer_info2(carol); - cur_info2_emily = get_producer_info2(emily); - - expected_votepay_share += double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; - BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == cur_info2_emily["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( get_producer_info(carol)["total_votes"].as_double() == - get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_REQUIRE_EQUAL( cur_info2["last_votepay_share_update"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - BOOST_REQUIRE_EQUAL( cur_info2_emily["last_votepay_share_update"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(votepay_share_update_order, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - cross_15_percent_threshold(); - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_sym::from_string("1000.0000"), config::system_account_name ); - } - const auto alice = accounts[0]; - const auto bob = accounts[1]; - const auto carol = accounts[2]; - const auto emily = accounts[3]; - - BOOST_REQUIRE_EQUAL( success(), regproducer( carol ) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( emily ) ); - - produce_block( fc::hours(24) ); - - BOOST_REQUIRE_EQUAL( success(), stake( alice, core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( bob, core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); - - BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); - - - BOOST_REQUIRE_EQUAL( success(), push_action( carol, N(claimrewards), mvo()("owner", carol) ) ); - produce_block( fc::hours(1) ); - BOOST_REQUIRE_EQUAL( success(), push_action( emily, N(claimrewards), mvo()("owner", emily) ) ); - - produce_block( fc::hours(3 * 24 + 1) ); - - { - signed_transaction trx; - set_transaction_headers(trx); - - trx.actions.emplace_back( get_action( config::system_account_name, N(claimrewards), { {carol, config::active_name} }, - mvo()("owner", carol) ) ); - - std::vector prods = { carol, emily }; - trx.actions.emplace_back( get_action( config::system_account_name, N(voteproducer), { {alice, config::active_name} }, - mvo()("voter", alice)("proxy", name(0))("producers", prods) ) ); - - trx.actions.emplace_back( get_action( config::system_account_name, N(claimrewards), { {emily, config::active_name} }, - mvo()("owner", emily) ) ); - - trx.sign( get_private_key( carol, "active" ), control->get_chain_id() ); - trx.sign( get_private_key( alice, "active" ), control->get_chain_id() ); - trx.sign( get_private_key( emily, "active" ), control->get_chain_id() ); - - push_transaction( trx ); - } - - const auto& carol_info = get_producer_info(carol); - const auto& carol_info2 = get_producer_info2(carol); - const auto& emily_info = get_producer_info(emily); - const auto& emily_info2 = get_producer_info2(emily); - const auto& gs3 = get_global_state3(); - BOOST_REQUIRE_EQUAL( carol_info2["last_votepay_share_update"].as_string(), gs3["last_vpay_state_update"].as_string() ); - BOOST_REQUIRE_EQUAL( emily_info2["last_votepay_share_update"].as_string(), gs3["last_vpay_state_update"].as_string() ); - BOOST_TEST_REQUIRE( 0 == carol_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == emily_info2["votepay_share"].as_double() ); - BOOST_REQUIRE( 0 < carol_info["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( carol_info["total_votes"].as_double() == emily_info["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( gs3["total_vpay_share_change_rate"].as_double() == 2 * carol_info["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; - for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_sym::from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); - } - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - { - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'd'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - } - setup_producer_accounts(producer_names); - for (const auto& p: producer_names) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - BOOST_TEST_REQUIRE(0 == get_producer_info(p)["total_votes"].as_double()); - BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["votepay_share"].as_double()); - BOOST_REQUIRE(0 < microseconds_since_epoch_of_iso_string( get_producer_info2(p)["last_votepay_share_update"] )); - } - } - - BOOST_REQUIRE_EQUAL( success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.end())) ); - auto* tbl = control->db().find( - boost::make_tuple( config::system_account_name, - config::system_account_name, - N(producers2) ) ); - BOOST_REQUIRE( tbl ); - BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( get_producer_info2("defproducera")["last_votepay_share_update"] ) ); - - // const_cast hack for now - const_cast(control->db()).remove( *tbl ); - tbl = control->db().find( - boost::make_tuple( config::system_account_name, - config::system_account_name, - N(producers2) ) ); - BOOST_REQUIRE( !tbl ); - - BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.end())) ); - tbl = control->db().find( - boost::make_tuple( config::system_account_name, - config::system_account_name, - N(producers2) ) ); - BOOST_REQUIRE( !tbl ); - BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducera)) ); - BOOST_REQUIRE( microseconds_since_epoch_of_iso_string( get_producer_info(N(defproducera))["last_claim_time"] ) < microseconds_since_epoch_of_iso_string( get_producer_info2(N(defproducera))["last_votepay_share_update"] ) ); - - create_account_with_resources( N(defproducer1), config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducer1)) ); - BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( get_producer_info(N(defproducer1))["last_claim_time"] ) ); - BOOST_REQUIRE_EQUAL( get_producer_info(N(defproducer1))["last_claim_time"].as_string(), - get_producer_info2(N(defproducer1))["last_votepay_share_update"].as_string() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_AUTO_TEST_CASE(votepay_transition2, * boost::unit_test::tolerance(1e-10)) try { - eosio_system_tester t(eosio_system_tester::setup_level::minimal); - - std::string old_contract_core_symbol_name = "SYS"; // Set to core symbol used in contracts::util::system_wasm_old() - symbol old_contract_core_symbol{::eosio::chain::string_to_symbol_c( 4, old_contract_core_symbol_name.c_str() )}; - - auto old_core_from_string = [&]( const std::string& s ) { - return eosio::chain::asset::from_string(s + " " + old_contract_core_symbol_name); - }; - - t.create_core_token( old_contract_core_symbol ); - t.set_code( config::system_account_name, contracts::util::system_wasm_old() ); - t.set_abi( config::system_account_name, contracts::util::system_abi_old().data() ); - { - const auto& accnt = t.control->db().get( config::system_account_name ); - abi_def abi; - BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - t.abi_ser.set_abi(abi, abi_serializer::create_yield_function(eosio_system_tester::abi_serializer_max_time)); - } - const asset net = old_core_from_string("80.0000"); - const asset cpu = old_core_from_string("80.0000"); - const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; - for (const auto& v: voters) { - t.create_account_with_resources( v, config::system_account_name, old_core_from_string("1.0000"), false, net, cpu ); - t.transfer( config::system_account_name, v, old_core_from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(t.success(), t.stake(v, old_core_from_string("30000000.0000"), old_core_from_string("30000000.0000")) ); - } - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - { - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'd'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - } - t.setup_producer_accounts( producer_names, old_core_from_string("1.0000"), - old_core_from_string("80.0000"), old_core_from_string("80.0000") ); - for (const auto& p: producer_names) { - BOOST_REQUIRE_EQUAL( t.success(), t.regproducer(p) ); - BOOST_TEST_REQUIRE(0 == t.get_producer_info(p)["total_votes"].as_double()); - } - } - - BOOST_REQUIRE_EQUAL( t.success(), t.vote(N(producvotera), vector(producer_names.begin(), producer_names.end())) ); - t.produce_block( fc::hours(20) ); - BOOST_REQUIRE_EQUAL( t.success(), t.vote(N(producvoterb), vector(producer_names.begin(), producer_names.end())) ); - t.produce_block( fc::hours(30) ); - BOOST_REQUIRE_EQUAL( t.success(), t.vote(N(producvoterc), vector(producer_names.begin(), producer_names.end())) ); - BOOST_REQUIRE_EQUAL( t.success(), t.push_action(producer_names[0], N(claimrewards), mvo()("owner", producer_names[0])) ); - BOOST_REQUIRE_EQUAL( t.success(), t.push_action(producer_names[1], N(claimrewards), mvo()("owner", producer_names[1])) ); - auto* tbl = t.control->db().find( - boost::make_tuple( config::system_account_name, - config::system_account_name, - N(producers2) ) ); - BOOST_REQUIRE( !tbl ); - - t.produce_block( fc::hours(2*24) ); - - t.deploy_contract( false ); - - t.produce_blocks(2); - t.produce_block( fc::hours(24 + 1) ); - - BOOST_REQUIRE_EQUAL( t.success(), t.push_action(producer_names[0], N(claimrewards), mvo()("owner", producer_names[0])) ); - BOOST_TEST_REQUIRE( 0 == t.get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( t.get_producer_info(producer_names[0])["total_votes"].as_double() == t.get_global_state3()["total_vpay_share_change_rate"].as_double() ); - - t.produce_block( fc::hours(5) ); - - BOOST_REQUIRE_EQUAL( t.success(), t.regproducer(producer_names[1]) ); - BOOST_TEST_REQUIRE( t.get_producer_info(producer_names[0])["total_votes"].as_double() + t.get_producer_info(producer_names[1])["total_votes"].as_double() == - t.get_global_state3()["total_vpay_share_change_rate"].as_double() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) try { - //install multisig contract - abi_serializer msig_abi_ser = initialize_multisig(); - auto producer_names = active_and_vote_producers(); - - //helper function - auto push_action_msig = [&]( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) -> action_result { - string action_type_name = msig_abi_ser.get_action_type(name); - - action act; - act.account = N(eosio.msig); - act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - - return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); - }; - // test begins - vector prod_perms; - for ( auto& x : producer_names ) { - prod_perms.push_back( { name(x), config::active_name } ); - } - - transaction trx; - { - //prepare system contract with different hash (contract differs in one byte) - auto code = contracts::system_wasm(); - string msg = "producer votes must be unique and sorted"; - auto it = std::search( code.begin(), code.end(), msg.begin(), msg.end() ); - BOOST_REQUIRE( it != code.end() ); - msg[0] = 'P'; - std::copy( msg.begin(), msg.end(), it ); - - variant pretty_trx = fc::mutable_variant_object() - ("expiration", "2020-01-01T00:30") - ("ref_block_num", 2) - ("ref_block_prefix", 3) - ("net_usage_words", 0) - ("max_cpu_usage_ms", 0) - ("delay_sec", 0) - ("actions", fc::variants({ - fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("name", "setcode") - ("authorization", vector{ { config::system_account_name, config::active_name } }) - ("data", fc::mutable_variant_object() ("account", name(config::system_account_name)) - ("vmtype", 0) - ("vmversion", "0") - ("code", bytes( code.begin(), code.end() )) - ) - }) - ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - } - - BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() - ("proposer", "alice1111111") - ("proposal_name", "upgrade1") - ("trx", trx) - ("requested", prod_perms) - ) - ); - - // get 15 approvals - for ( size_t i = 0; i < 14; ++i ) { - BOOST_REQUIRE_EQUAL(success(), push_action_msig( name(producer_names[i]), N(approve), mvo() - ("proposer", "alice1111111") - ("proposal_name", "upgrade1") - ("level", permission_level{ name(producer_names[i]), config::active_name }) - ) - ); - } - - //should fail - BOOST_REQUIRE_EQUAL(wasm_assert_msg("transaction authorization failed"), - push_action_msig( N(alice1111111), N(exec), mvo() - ("proposer", "alice1111111") - ("proposal_name", "upgrade1") - ("executer", "alice1111111") - ) - ); - - // one more approval - BOOST_REQUIRE_EQUAL(success(), push_action_msig( name(producer_names[14]), N(approve), mvo() - ("proposer", "alice1111111") - ("proposal_name", "upgrade1") - ("level", permission_level{ name(producer_names[14]), config::active_name }) - ) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(exec), mvo() - ("proposer", "alice1111111") - ("proposal_name", "upgrade1") - ("executer", "alice1111111") - ) - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - - produce_blocks( 250 ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(producer_onblock_check, eosio_system_tester) try { - - const asset large_asset = core_sym::from_string("80.0000"); - create_account_with_resources( N(producvotera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(producvoterb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(producvoterc), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - producer_names.reserve('z' - 'a' + 1); - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - setup_producer_accounts(producer_names); - - for (auto a:producer_names) - regproducer(a); - - produce_block(fc::hours(24)); - - BOOST_REQUIRE_EQUAL(0, get_producer_info( producer_names.front() )["total_votes"].as()); - BOOST_REQUIRE_EQUAL(0, get_producer_info( producer_names.back() )["total_votes"].as()); - - - transfer(config::system_account_name, "producvotera", core_sym::from_string("200000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_sym::from_string("70000000.0000"), core_sym::from_string("70000000.0000") )); - BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), vector(producer_names.begin(), producer_names.begin()+10))); - BOOST_CHECK_EQUAL( wasm_assert_msg( "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ), - unstake( "producvotera", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); - - // give a chance for everyone to produce blocks - { - produce_blocks(21 * 12); - bool all_21_produced = true; - for (uint32_t i = 0; i < 21; ++i) { - if (0 == get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - all_21_produced= false; - } - } - bool rest_didnt_produce = true; - for (uint32_t i = 21; i < producer_names.size(); ++i) { - if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - rest_didnt_produce = false; - } - } - BOOST_REQUIRE_EQUAL(false, all_21_produced); - BOOST_REQUIRE_EQUAL(true, rest_didnt_produce); - } - - { - const char* claimrewards_activation_error_message = "cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)"; - BOOST_CHECK_EQUAL(0, get_global_state()["total_unpaid_blocks"].as()); - BOOST_REQUIRE_EQUAL(wasm_assert_msg( claimrewards_activation_error_message ), - push_action(producer_names.front(), N(claimrewards), mvo()("owner", producer_names.front()))); - BOOST_REQUIRE_EQUAL(0, get_balance(producer_names.front()).get_amount()); - BOOST_REQUIRE_EQUAL(wasm_assert_msg( claimrewards_activation_error_message ), - push_action(producer_names.back(), N(claimrewards), mvo()("owner", producer_names.back()))); - BOOST_REQUIRE_EQUAL(0, get_balance(producer_names.back()).get_amount()); - } - - // stake across 15% boundary - transfer(config::system_account_name, "producvoterb", core_sym::from_string("100000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvoterb", core_sym::from_string("4000000.0000"), core_sym::from_string("4000000.0000"))); - transfer(config::system_account_name, "producvoterc", core_sym::from_string("100000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvoterc", core_sym::from_string("2000000.0000"), core_sym::from_string("2000000.0000"))); - - BOOST_REQUIRE_EQUAL(success(), vote( N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21))); - BOOST_REQUIRE_EQUAL(success(), vote( N(producvoterc), vector(producer_names.begin(), producer_names.end()))); - - // give a chance for everyone to produce blocks - { - produce_blocks(21 * 12); - bool all_21_produced = true; - for (uint32_t i = 0; i < 21; ++i) { - if (0 == get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - all_21_produced= false; - } - } - bool rest_didnt_produce = true; - for (uint32_t i = 21; i < producer_names.size(); ++i) { - if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - rest_didnt_produce = false; - } - } - BOOST_REQUIRE_EQUAL(true, all_21_produced); - BOOST_REQUIRE_EQUAL(true, rest_didnt_produce); - BOOST_REQUIRE_EQUAL(success(), - push_action(producer_names.front(), N(claimrewards), mvo()("owner", producer_names.front()))); - BOOST_REQUIRE(0 < get_balance(producer_names.front()).get_amount()); - } - - BOOST_CHECK_EQUAL( success(), unstake( "producvotera", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system_tester, * boost::unit_test::tolerance(1e+6) ) try { - cross_15_percent_threshold(); - - create_accounts_with_resources( { N(donald111111), N(defproducer1), N(defproducer2), N(defproducer3) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer1), 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer2), 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer3), 3) ); - - //alice1111111 becomes a producer - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", true) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); - - //alice1111111 makes stake and votes - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0001"), core_sym::from_string("20.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1), N(defproducer2) } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0002")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0002")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - BOOST_REQUIRE_EQUAL( success(), push_action( N(donald111111), N(regproxy), mvo() - ("proxy", "donald111111") - ("isproxy", true) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( N(donald111111) ), get_voter_info( "donald111111" ) ); - - //bob111111111 chooses alice1111111 as a proxy - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector(), "alice1111111" ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("200.0005")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("200.0005")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //carol1111111 chooses alice1111111 as a proxy - issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("30.0001"), core_sym::from_string("20.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "alice1111111" ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("200.0005")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("250.0007")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("250.0007")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //proxied voter carol1111111 increases stake - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("50.0000"), core_sym::from_string("70.0000") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("320.0005")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("370.0007")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("370.0007")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //proxied voter bob111111111 decreases stake - BOOST_REQUIRE_EQUAL( success(), unstake( "bob111111111", core_sym::from_string("50.0001"), core_sym::from_string("50.0001") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("220.0003")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("270.0005")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("270.0005")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //proxied voter carol1111111 chooses another proxy - BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "donald111111" ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0001")), get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("170.0002")), get_voter_info( "donald111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("100.0003")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("100.0003")), get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //bob111111111 switches to direct voting and votes for one of the same producers, but not for another one - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer2) } ) ); - BOOST_TEST_REQUIRE( 0.0 == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0002")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("100.0003")), get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( 0.0 == get_producer_info( "defproducer3" )["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( vote_both_proxy_and_producers, eosio_system_tester ) try { - //alice1111111 becomes a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", true) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); - - //carol1111111 becomes a producer - BOOST_REQUIRE_EQUAL( success(), regproducer( N(carol1111111), 1) ); - - //bob111111111 chooses alice1111111 as a proxy - - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot vote for producers and proxy at same time"), - vote( N(bob111111111), { N(carol1111111) }, "alice1111111" ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( select_invalid_proxy, eosio_system_tester ) try { - //accumulate proxied votes - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - - //selecting account not registered as a proxy - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "invalid proxy specified" ), - vote( N(bob111111111), vector(), "alice1111111" ) ); - - //selecting not existing account as a proxy - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "invalid proxy specified" ), - vote( N(bob111111111), vector(), "notexist" ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( double_register_unregister_proxy_keeps_votes, eosio_system_tester ) try { - //alice1111111 becomes a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", 1) - ) - ); - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("5.0000"), core_sym::from_string("5.0000") ) ); - edump((get_voter_info("alice1111111"))); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); - - //bob111111111 stakes and selects alice1111111 as a proxy - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector(), "alice1111111" ) ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "proxied_vote_weight", stake2votes( core_sym::from_string("150.0003") ))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); - - //double regestering should fail without affecting total votes and stake - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "action has no effect" ), - push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", 1) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); - - //uregister - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", 0) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); - - //double unregistering should not affect proxied_votes and stake - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "action has no effect" ), - push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", 0) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( proxy_cannot_use_another_proxy, eosio_system_tester ) try { - //alice1111111 becomes a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", 1) - ) - ); - - //bob111111111 becomes a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() - ("proxy", "bob111111111") - ("isproxy", 1) - ) - ); - - //proxy should not be able to use a proxy - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "account registered as a proxy is not allowed to use a proxy" ), - vote( N(bob111111111), vector(), "alice1111111" ) ); - - //voter that uses a proxy should not be allowed to become a proxy - issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "account that uses a proxy is not allowed to become a proxy" ), - push_action( N(carol1111111), N(regproxy), mvo() - ("proxy", "carol1111111") - ("isproxy", 1) - ) - ); - - //proxy should not be able to use itself as a proxy - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "cannot proxy to self" ), - vote( N(bob111111111), vector(), "bob111111111" ) ); - -} FC_LOG_AND_RETHROW() - -fc::mutable_variant_object config_to_variant( const eosio::chain::chain_config& config ) { - return mutable_variant_object() - ( "max_block_net_usage", config.max_block_net_usage ) - ( "target_block_net_usage_pct", config.target_block_net_usage_pct ) - ( "max_transaction_net_usage", config.max_transaction_net_usage ) - ( "base_per_transaction_net_usage", config.base_per_transaction_net_usage ) - ( "context_free_discount_net_usage_num", config.context_free_discount_net_usage_num ) - ( "context_free_discount_net_usage_den", config.context_free_discount_net_usage_den ) - ( "max_block_cpu_usage", config.max_block_cpu_usage ) - ( "target_block_cpu_usage_pct", config.target_block_cpu_usage_pct ) - ( "max_transaction_cpu_usage", config.max_transaction_cpu_usage ) - ( "min_transaction_cpu_usage", config.min_transaction_cpu_usage ) - ( "max_transaction_lifetime", config.max_transaction_lifetime ) - ( "deferred_trx_expiration_window", config.deferred_trx_expiration_window ) - ( "max_transaction_delay", config.max_transaction_delay ) - ( "max_inline_action_size", config.max_inline_action_size ) - ( "max_inline_action_depth", config.max_inline_action_depth ) - ( "max_authority_depth", config.max_authority_depth ); -} - -BOOST_FIXTURE_TEST_CASE( elect_producers /*_and_parameters*/, eosio_system_tester ) try { - create_accounts_with_resources( { N(defproducer1), N(defproducer2), N(defproducer3) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer1), 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer2), 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer3), 3) ); - - //stake more than 15% of total EOS supply to activate chain - transfer( "eosio", "alice1111111", core_sym::from_string("600000000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("300000000.0000"), core_sym::from_string("300000000.0000") ) ); - //vote for producers - BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1) } ) ); - produce_blocks(250); - auto producer_keys = control->head_block_state()->active_schedule.producers; - BOOST_REQUIRE_EQUAL( 1, producer_keys.size() ); - BOOST_REQUIRE_EQUAL( name("defproducer1"), producer_keys[0].producer_name ); - - //auto config = config_to_variant( control->get_global_properties().configuration ); - //auto prod1_config = testing::filter_fields( config, producer_parameters_example( 1 ) ); - //REQUIRE_EQUAL_OBJECTS(prod1_config, config); - - // elect 2 producers - issue_and_transfer( "bob111111111", core_sym::from_string("80000.0000"), config::system_account_name ); - ilog("stake"); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("40000.0000"), core_sym::from_string("40000.0000") ) ); - ilog("start vote"); - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer2) } ) ); - ilog("."); - produce_blocks(250); - producer_keys = control->head_block_state()->active_schedule.producers; - BOOST_REQUIRE_EQUAL( 2, producer_keys.size() ); - BOOST_REQUIRE_EQUAL( name("defproducer1"), producer_keys[0].producer_name ); - BOOST_REQUIRE_EQUAL( name("defproducer2"), producer_keys[1].producer_name ); - //config = config_to_variant( control->get_global_properties().configuration ); - //auto prod2_config = testing::filter_fields( config, producer_parameters_example( 2 ) ); - //REQUIRE_EQUAL_OBJECTS(prod2_config, config); - - // elect 3 producers - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer2), N(defproducer3) } ) ); - produce_blocks(250); - producer_keys = control->head_block_state()->active_schedule.producers; - BOOST_REQUIRE_EQUAL( 3, producer_keys.size() ); - BOOST_REQUIRE_EQUAL( name("defproducer1"), producer_keys[0].producer_name ); - BOOST_REQUIRE_EQUAL( name("defproducer2"), producer_keys[1].producer_name ); - BOOST_REQUIRE_EQUAL( name("defproducer3"), producer_keys[2].producer_name ); - //config = config_to_variant( control->get_global_properties().configuration ); - //REQUIRE_EQUAL_OBJECTS(prod2_config, config); - - // try to go back to 2 producers and fail - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer3) } ) ); - produce_blocks(250); - producer_keys = control->head_block_state()->active_schedule.producers; - BOOST_REQUIRE_EQUAL( 3, producer_keys.size() ); - - // The test below is invalid now, producer schedule is not updated if there are - // fewer producers in the new schedule - /* - BOOST_REQUIRE_EQUAL( 2, producer_keys.size() ); - BOOST_REQUIRE_EQUAL( name("defproducer1"), producer_keys[0].producer_name ); - BOOST_REQUIRE_EQUAL( name("defproducer3"), producer_keys[1].producer_name ); - //config = config_to_variant( control->get_global_properties().configuration ); - //auto prod3_config = testing::filter_fields( config, producer_parameters_example( 3 ) ); - //REQUIRE_EQUAL_OBJECTS(prod3_config, config); - */ - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( buyname, eosio_system_tester ) try { - create_accounts_with_resources( { N(dan), N(sam) } ); - transfer( config::system_account_name, "dan", core_sym::from_string( "10000.0000" ) ); - transfer( config::system_account_name, "sam", core_sym::from_string( "10000.0000" ) ); - stake_with_transfer( config::system_account_name, N(sam), core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); - stake_with_transfer( config::system_account_name, N(dan), core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); - - regproducer( config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), vote( N(sam), { config::system_account_name } ) ); - // wait 14 days after min required amount has been staked - produce_block( fc::days(7) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(dan), { config::system_account_name } ) ); - produce_block( fc::days(7) ); - produce_block(); - - BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { N(fail) }, N(dan) ), // dan shouldn't be able to create fail - eosio_assert_message_exception, eosio_assert_message_is( "no active bid for name" ) ); - bidname( "dan", "nofail", core_sym::from_string( "1.0000" ) ); - BOOST_REQUIRE_EQUAL( "assertion failure with message: must increase bid by 10%", bidname( "sam", "nofail", core_sym::from_string( "1.0000" ) )); // didn't increase bid by 10% - BOOST_REQUIRE_EQUAL( success(), bidname( "sam", "nofail", core_sym::from_string( "2.0000" ) )); // didn't increase bid by 10% - produce_block( fc::days(1) ); - produce_block(); - - BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { N(nofail) }, N(dan) ), // dan shoudn't be able to do this, sam won - eosio_assert_message_exception, eosio_assert_message_is( "only highest bidder can claim" ) ); - //wlog( "verify sam can create nofail" ); - create_accounts_with_resources( { N(nofail) }, N(sam) ); // sam should be able to do this, he won the bid - //wlog( "verify nofail can create test.nofail" ); - transfer( "eosio", "nofail", core_sym::from_string( "1000.0000" ) ); - create_accounts_with_resources( { N(test.nofail) }, N(nofail) ); // only nofail can create test.nofail - //wlog( "verify dan cannot create test.fail" ); - BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { N(test.fail) }, N(dan) ), // dan shouldn't be able to do this - eosio_assert_message_exception, eosio_assert_message_is( "only suffix may create this account" ) ); - - create_accounts_with_resources( { N(goodgoodgood) }, N(dan) ); /// 12 char names should succeed -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( bid_invalid_names, eosio_system_tester ) try { - create_accounts_with_resources( { N(dan) } ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "you can only bid on top-level suffix" ), - bidname( "dan", "abcdefg.12345", core_sym::from_string( "1.0000" ) ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "the empty name is not a valid account name to bid on" ), - bidname( "dan", "", core_sym::from_string( "1.0000" ) ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "13 character names are not valid account names to bid on" ), - bidname( "dan", "abcdefgh12345", core_sym::from_string( "1.0000" ) ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "accounts with 12 character names and no dots can be created without bidding required" ), - bidname( "dan", "abcdefg12345", core_sym::from_string( "1.0000" ) ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { - - const std::string not_closed_message("auction for name is not closed yet"); - - std::vector accounts = { N(alice), N(bob), N(carl), N(david), N(eve) }; - create_accounts_with_resources( accounts ); - for ( const auto& a: accounts ) { - transfer( config::system_account_name, a, core_sym::from_string( "10000.0000" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "10000.0000" ), get_balance(a) ); - } - create_accounts_with_resources( { N(producer) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(producer) ) ); - - produce_block(); - // stake but but not enough to go live - stake_with_transfer( config::system_account_name, N(bob), core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); - stake_with_transfer( config::system_account_name, N(carl), core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(bob), { N(producer) } ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(carl), { N(producer) } ) ); - - // start bids - bidname( "bob", "prefa", core_sym::from_string("1.0003") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.9997" ), get_balance("bob") ); - bidname( "bob", "prefb", core_sym::from_string("1.0000") ); - bidname( "bob", "prefc", core_sym::from_string("1.0000") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9996.9997" ), get_balance("bob") ); - - bidname( "carl", "prefd", core_sym::from_string("1.0000") ); - bidname( "carl", "prefe", core_sym::from_string("1.0000") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.0000" ), get_balance("carl") ); - - BOOST_REQUIRE_EQUAL( error("assertion failure with message: account is already highest bidder"), - bidname( "bob", "prefb", core_sym::from_string("1.1001") ) ); - BOOST_REQUIRE_EQUAL( error("assertion failure with message: must increase bid by 10%"), - bidname( "alice", "prefb", core_sym::from_string("1.0999") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9996.9997" ), get_balance("bob") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "10000.0000" ), get_balance("alice") ); - - // alice outbids bob on prefb - { - const asset initial_names_balance = get_balance(N(eosio.names)); - BOOST_REQUIRE_EQUAL( success(), - bidname( "alice", "prefb", core_sym::from_string("1.1001") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9997.9997" ), get_balance("bob") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.8999" ), get_balance("alice") ); - BOOST_REQUIRE_EQUAL( initial_names_balance + core_sym::from_string("0.1001"), get_balance(N(eosio.names)) ); - } - - // david outbids carl on prefd - { - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.0000" ), get_balance("carl") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "10000.0000" ), get_balance("david") ); - BOOST_REQUIRE_EQUAL( success(), - bidname( "david", "prefd", core_sym::from_string("1.9900") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9999.0000" ), get_balance("carl") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.0100" ), get_balance("david") ); - } - - // eve outbids carl on prefe - { - BOOST_REQUIRE_EQUAL( success(), - bidname( "eve", "prefe", core_sym::from_string("1.7200") ) ); - } - - produce_block( fc::days(14) ); - produce_block(); - - // highest bid is from david for prefd but no bids can be closed yet - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefd), N(david) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - - // stake enough to go above the 15% threshold - stake_with_transfer( config::system_account_name, N(alice), core_sym::from_string( "10000000.0000" ), core_sym::from_string( "10000000.0000" ) ); - BOOST_REQUIRE_EQUAL(0, get_producer_info("producer")["unpaid_blocks"].as()); - BOOST_REQUIRE_EQUAL( success(), vote( N(alice), { N(producer) } ) ); - - // need to wait for 14 days after going live - produce_blocks(10); - produce_block( fc::days(2) ); - produce_blocks( 10 ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefd), N(david) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - // it's been 14 days, auction for prefd has been closed - produce_block( fc::days(12) ); - create_account_with_resources( N(prefd), N(david) ); - produce_blocks(2); - produce_block( fc::hours(23) ); - // auctions for prefa, prefb, prefc, prefe haven't been closed - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefa), N(bob) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(alice) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefc), N(bob) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefe), N(eve) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - // attemp to create account with no bid - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefg), N(alice) ), - fc::exception, fc_assert_exception_message_is( "no active bid for name" ) ); - // changing highest bid pushes auction closing time by 24 hours - BOOST_REQUIRE_EQUAL( success(), - bidname( "eve", "prefb", core_sym::from_string("2.1880") ) ); - - produce_block( fc::hours(22) ); - produce_blocks(2); - - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(eve) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - // but changing a bid that is not the highest does not push closing time - BOOST_REQUIRE_EQUAL( success(), - bidname( "carl", "prefe", core_sym::from_string("2.0980") ) ); - produce_block( fc::hours(2) ); - produce_blocks(2); - // bid for prefb has closed, only highest bidder can claim - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(alice) ), - eosio_assert_message_exception, eosio_assert_message_is( "only highest bidder can claim" ) ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(carl) ), - eosio_assert_message_exception, eosio_assert_message_is( "only highest bidder can claim" ) ); - create_account_with_resources( N(prefb), N(eve) ); - - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefe), N(carl) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - produce_block(); - produce_block( fc::hours(24) ); - // by now bid for prefe has closed - create_account_with_resources( N(prefe), N(carl) ); - // prefe can now create *.prefe - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(xyz.prefe), N(carl) ), - fc::exception, fc_assert_exception_message_is("only suffix may create this account") ); - transfer( config::system_account_name, N(prefe), core_sym::from_string("10000.0000") ); - create_account_with_resources( N(xyz.prefe), N(prefe) ); - - // other auctions haven't closed - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefa), N(bob) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( namebid_pending_winner, eosio_system_tester ) try { - cross_15_percent_threshold(); - produce_block( fc::hours(14*24) ); //wait 14 day for name auction activation - transfer( config::system_account_name, N(alice1111111), core_sym::from_string("10000.0000") ); - transfer( config::system_account_name, N(bob111111111), core_sym::from_string("10000.0000") ); - - BOOST_REQUIRE_EQUAL( success(), bidname( "alice1111111", "prefa", core_sym::from_string( "50.0000" ) )); - BOOST_REQUIRE_EQUAL( success(), bidname( "bob111111111", "prefb", core_sym::from_string( "30.0000" ) )); - produce_block( fc::hours(100) ); //should close "perfa" - produce_block( fc::hours(100) ); //should close "perfb" - - //despite "perfa" account hasn't been created, we should be able to create "perfb" account - create_account_with_resources( N(prefb), N(bob111111111) ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( vote_producers_in_and_out, eosio_system_tester ) try { - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; - for (const auto& v: voters) { - create_account_with_resources(v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu); - } - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - setup_producer_accounts(producer_names); - for (const auto& p: producer_names) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - produce_blocks(1); - ilog( "------ get pro----------" ); - wdump((p)); - BOOST_TEST(0 == get_producer_info(p)["total_votes"].as()); - } - } - - for (const auto& v: voters) { - transfer( config::system_account_name, v, core_sym::from_string("200000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); - } - - { - BOOST_REQUIRE_EQUAL(success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.begin()+20))); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21))); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterc), vector(producer_names.begin(), producer_names.end()))); - } - - // give a chance for everyone to produce blocks - { - produce_blocks(23 * 12 + 20); - bool all_21_produced = true; - for (uint32_t i = 0; i < 21; ++i) { - if (0 == get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - all_21_produced = false; - } - } - bool rest_didnt_produce = true; - for (uint32_t i = 21; i < producer_names.size(); ++i) { - if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - rest_didnt_produce = false; - } - } - BOOST_REQUIRE(all_21_produced && rest_didnt_produce); - } - - { - produce_block(fc::hours(7)); - const uint32_t voted_out_index = 20; - const uint32_t new_prod_index = 23; - BOOST_REQUIRE_EQUAL(success(), stake("producvoterd", core_sym::from_string("40000000.0000"), core_sym::from_string("40000000.0000"))); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterd), { producer_names[new_prod_index] })); - BOOST_REQUIRE_EQUAL(0, get_producer_info(producer_names[new_prod_index])["unpaid_blocks"].as()); - produce_blocks(4 * 12 * 21); - BOOST_REQUIRE(0 < get_producer_info(producer_names[new_prod_index])["unpaid_blocks"].as()); - const uint32_t initial_unpaid_blocks = get_producer_info(producer_names[voted_out_index])["unpaid_blocks"].as(); - produce_blocks(2 * 12 * 21); - BOOST_REQUIRE_EQUAL(initial_unpaid_blocks, get_producer_info(producer_names[voted_out_index])["unpaid_blocks"].as()); - produce_block(fc::hours(24)); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterd), { producer_names[voted_out_index] })); - produce_blocks(2 * 12 * 21); - BOOST_REQUIRE(fc::crypto::public_key() != fc::crypto::public_key(get_producer_info(producer_names[voted_out_index])["producer_key"].as_string())); - BOOST_REQUIRE_EQUAL(success(), push_action(producer_names[voted_out_index], N(claimrewards), mvo()("owner", producer_names[voted_out_index]))); - } - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { - //install multisig contract - abi_serializer msig_abi_ser = initialize_multisig(); - auto producer_names = active_and_vote_producers(); - - //helper function - auto push_action_msig = [&]( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) -> action_result { - string action_type_name = msig_abi_ser.get_action_type(name); - - action act; - act.account = N(eosio.msig); - act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - - return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); - }; - - // test begins - vector prod_perms; - for ( auto& x : producer_names ) { - prod_perms.push_back( { name(x), config::active_name } ); - } - - eosio::chain::chain_config params; - params = control->get_global_properties().configuration; - //change some values - params.max_block_net_usage += 10; - params.max_transaction_lifetime += 1; - - transaction trx; - { - variant pretty_trx = fc::mutable_variant_object() - ("expiration", "2020-01-01T00:30") - ("ref_block_num", 2) - ("ref_block_prefix", 3) - ("net_usage_words", 0) - ("max_cpu_usage_ms", 0) - ("delay_sec", 0) - ("actions", fc::variants({ - fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("name", "setparams") - ("authorization", vector{ { config::system_account_name, config::active_name } }) - ("data", fc::mutable_variant_object() - ("params", params) - ) - }) - ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - } - - BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() - ("proposer", "alice1111111") - ("proposal_name", "setparams1") - ("trx", trx) - ("requested", prod_perms) - ) - ); - - // get 16 approvals - for ( size_t i = 0; i < 15; ++i ) { - BOOST_REQUIRE_EQUAL(success(), push_action_msig( name(producer_names[i]), N(approve), mvo() - ("proposer", "alice1111111") - ("proposal_name", "setparams1") - ("level", permission_level{ name(producer_names[i]), config::active_name }) - ) - ); - } - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(exec), mvo() - ("proposer", "alice1111111") - ("proposal_name", "setparams1") - ("executer", "alice1111111") - ) - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - - produce_blocks( 250 ); - - // make sure that changed parameters were applied - auto active_params = control->get_global_properties().configuration; - BOOST_REQUIRE_EQUAL( params.max_block_net_usage, active_params.max_block_net_usage ); - BOOST_REQUIRE_EQUAL( params.max_transaction_lifetime, active_params.max_transaction_lifetime ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( setram_effect, eosio_system_tester ) try { - - const asset net = core_sym::from_string("8.0000"); - const asset cpu = core_sym::from_string("8.0000"); - std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - for (const auto& a: accounts) { - create_account_with_resources(a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu); - } - - { - const auto name_a = accounts[0]; - transfer( config::system_account_name, name_a, core_sym::from_string("1000.0000") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance(name_a) ); - const uint64_t init_bytes_a = get_total_stake(name_a)["ram_bytes"].as_uint64(); - BOOST_REQUIRE_EQUAL( success(), buyram( name_a, name_a, core_sym::from_string("300.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance(name_a) ); - const uint64_t bought_bytes_a = get_total_stake(name_a)["ram_bytes"].as_uint64() - init_bytes_a; - - // after buying and selling balance should be 700 + 300 * 0.995 * 0.995 = 997.0075 (actually 997.0074 due to rounding fees up) - BOOST_REQUIRE_EQUAL( success(), sellram(name_a, bought_bytes_a ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("997.0074"), get_balance(name_a) ); - } - - { - const auto name_b = accounts[1]; - transfer( config::system_account_name, name_b, core_sym::from_string("1000.0000") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance(name_b) ); - const uint64_t init_bytes_b = get_total_stake(name_b)["ram_bytes"].as_uint64(); - // name_b buys ram at current price - BOOST_REQUIRE_EQUAL( success(), buyram( name_b, name_b, core_sym::from_string("300.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance(name_b) ); - const uint64_t bought_bytes_b = get_total_stake(name_b)["ram_bytes"].as_uint64() - init_bytes_b; - - // increase max_ram_size, ram bought by name_b loses part of its value - BOOST_REQUIRE_EQUAL( wasm_assert_msg("ram may only be increased"), - push_action(config::system_account_name, N(setram), mvo()("max_ram_size", 64ll*1024 * 1024 * 1024)) ); - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action(name_b, N(setram), mvo()("max_ram_size", 80ll*1024 * 1024 * 1024)) ); - BOOST_REQUIRE_EQUAL( success(), - push_action(config::system_account_name, N(setram), mvo()("max_ram_size", 80ll*1024 * 1024 * 1024)) ); - - BOOST_REQUIRE_EQUAL( success(), sellram(name_b, bought_bytes_b ) ); - BOOST_REQUIRE( core_sym::from_string("900.0000") < get_balance(name_b) ); - BOOST_REQUIRE( core_sym::from_string("950.0000") > get_balance(name_b) ); - } - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { - - const uint64_t init_max_ram_size = 64ll*1024 * 1024 * 1024; - - BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - produce_blocks(20); - BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - transfer( config::system_account_name, "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - produce_blocks(3); - BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - uint16_t rate = 1000; - BOOST_REQUIRE_EQUAL( success(), push_action( config::system_account_name, N(setramrate), mvo()("bytes_per_block", rate) ) ); - BOOST_REQUIRE_EQUAL( rate, get_global_state2()["new_ram_per_block"].as() ); - // last time update_ram_supply called is in buyram, num of blocks since then to - // the block that includes the setramrate action is 1 + 3 = 4. - // However, those 4 blocks were accumulating at a rate of 0, so the max_ram_size should not have changed. - BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - // But with additional blocks, it should start accumulating at the new rate. - uint64_t cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); - produce_blocks(10); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * rate, get_global_state()["max_ram_size"].as_uint64() ); - cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); - produce_blocks(5); - BOOST_REQUIRE_EQUAL( cur_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 100 ) ); - BOOST_REQUIRE_EQUAL( cur_ram_size + 6 * rate, get_global_state()["max_ram_size"].as_uint64() ); - cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); - produce_blocks(); - BOOST_REQUIRE_EQUAL( success(), buyrambytes( "alice1111111", "alice1111111", 100 ) ); - BOOST_REQUIRE_EQUAL( cur_ram_size + 2 * rate, get_global_state()["max_ram_size"].as_uint64() ); - - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action( N(alice1111111), N(setramrate), mvo()("bytes_per_block", rate) ) ); - - cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); - produce_blocks(10); - uint16_t old_rate = rate; - rate = 5000; - BOOST_REQUIRE_EQUAL( success(), push_action( config::system_account_name, N(setramrate), mvo()("bytes_per_block", rate) ) ); - BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * old_rate, get_global_state()["max_ram_size"].as_uint64() ); - produce_blocks(5); - BOOST_REQUIRE_EQUAL( success(), buyrambytes( "alice1111111", "alice1111111", 100 ) ); - BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * old_rate + 6 * rate, get_global_state()["max_ram_size"].as_uint64() ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - const asset initial_ram_balance = get_balance(N(eosio.ram)); - const asset initial_ramfee_balance = get_balance(N(eosio.ramfee)); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("1000.0000") ) ); - - BOOST_REQUIRE_EQUAL( false, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), account_name(symbol{CORE_SYM}.to_symbol_code()) ).empty() ); - - //remove row - base_tester::push_action( N(eosio.token), N(close), N(alice1111111), mvo() - ( "owner", "alice1111111" ) - ( "symbol", symbol{CORE_SYM} ) - ); - BOOST_REQUIRE_EQUAL( true, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), account_name(symbol{CORE_SYM}.to_symbol_code()) ).empty() ); - - auto rlm = control->get_resource_limits_manager(); - auto eosioram_ram_usage = rlm.get_account_ram_usage(N(eosio.ram)); - auto alice_ram_usage = rlm.get_account_ram_usage(N(alice1111111)); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 2048 ) ); - - //make sure that ram was billed to alice, not to eosio.ram - BOOST_REQUIRE_EQUAL( true, alice_ram_usage < rlm.get_account_ram_usage(N(alice1111111)) ); - BOOST_REQUIRE_EQUAL( eosioram_ram_usage, rlm.get_account_ram_usage(N(eosio.ram)) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { - active_and_vote_producers(); - - auto rlm = control->get_resource_limits_manager(); - int64_t ram_bytes_orig, net_weight, cpu_weight; - rlm.get_account_limits( N(alice1111111), ram_bytes_orig, net_weight, cpu_weight ); - - /* - * It seems impossible to write this test, because buyrambytes action doesn't give you exact amount of bytes requested - * - //check that it's possible to create account bying required_bytes(2724) + userres table(112) + userres row(160) - ram_gift_bytes(1400) - create_account_with_resources( N(abcdefghklmn), N(alice1111111), 2724 + 112 + 160 - 1400 ); - - //check that one byte less is not enough - BOOST_REQUIRE_THROW( create_account_with_resources( N(abcdefghklmn), N(alice1111111), 2724 + 112 + 160 - 1400 - 1 ), - ram_usage_exceeded ); - */ - - //check that stake/unstake keeps the gift - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - int64_t ram_bytes_after_stake; - rlm.get_account_limits( N(alice1111111), ram_bytes_after_stake, net_weight, cpu_weight ); - BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_stake ); - - BOOST_REQUIRE_EQUAL( success(), unstake( "eosio", "alice1111111", core_sym::from_string("20.0000"), core_sym::from_string("10.0000") ) ); - int64_t ram_bytes_after_unstake; - rlm.get_account_limits( N(alice1111111), ram_bytes_after_unstake, net_weight, cpu_weight ); - BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_unstake ); - - uint64_t ram_gift = 1400; - - int64_t ram_bytes; - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("1000.0000") ) ); - rlm.get_account_limits( N(alice1111111), ram_bytes, net_weight, cpu_weight ); - auto userres = get_total_stake( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, ram_bytes ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 1024 ) ); - rlm.get_account_limits( N(alice1111111), ram_bytes, net_weight, cpu_weight ); - userres = get_total_stake( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, ram_bytes ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_auth, eosio_system_tester ) try { - - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - const account_name alice = accounts[0], bob = accounts[1]; - const asset init_balance = core_sym::from_string("1000.0000"); - const asset one_eos = core_sym::from_string("1.0000"); - const asset one_rex = asset::from_string("1.0000 REX"); - setup_rex_accounts( accounts, init_balance ); - - const std::string error_msg("missing authority of aliceaccount"); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(deposit), mvo()("owner", alice)("amount", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(withdraw), mvo()("owner", alice)("amount", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(buyrex), mvo()("from", alice)("amount", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), - push_action( bob, N(unstaketorex), mvo()("owner", alice)("receiver", alice)("from_net", one_eos)("from_cpu", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(sellrex), mvo()("from", alice)("rex", one_rex) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(cnclrexorder), mvo()("owner", alice) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), - push_action( bob, N(rentcpu), mvo()("from", alice)("receiver", alice)("loan_payment", one_eos)("loan_fund", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), - push_action( bob, N(rentnet), mvo()("from", alice)("receiver", alice)("loan_payment", one_eos)("loan_fund", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(fundcpuloan), mvo()("from", alice)("loan_num", 1)("payment", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(fundnetloan), mvo()("from", alice)("loan_num", 1)("payment", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(defcpuloan), mvo()("from", alice)("loan_num", 1)("amount", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(defnetloan), mvo()("from", alice)("loan_num", 1)("amount", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(updaterex), mvo()("owner", alice) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(rexexec), mvo()("user", alice)("max", 1) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(consolidate), mvo()("owner", alice) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(mvtosavings), mvo()("owner", alice)("rex", one_rex) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(mvfrsavings), mvo()("owner", alice)("rex", one_rex) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(closerex), mvo()("owner", alice) ) ); - - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), push_action( alice, N(setrex), mvo()("balance", one_eos) ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_rent = core_sym::from_string("20000.0000"); - const asset init_balance = core_sym::from_string("1000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance ); - - const asset one_unit = core_sym::from_string("0.0001"); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), buyrex( alice, init_balance + one_unit ) ); - BOOST_REQUIRE_EQUAL( asset::from_string("25000.0000 REX"), get_buyrex_result( alice, core_sym::from_string("2.5000") ) ); - produce_blocks(2); - produce_block(fc::days(5)); - BOOST_REQUIRE_EQUAL( core_sym::from_string("2.5000"), get_sellrex_result( alice, asset::from_string("25000.0000 REX") ) ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("13.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("13.0000"), get_rex_vote_stake( alice ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("17.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), get_rex_vote_stake( alice ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("970.0000"), get_rex_fund(alice) ); - BOOST_REQUIRE_EQUAL( get_rex_balance(alice).get_amount(), ratio * asset::from_string("30.0000 REX").get_amount() ); - auto rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), rex_pool["total_unlent"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( init_rent, rex_pool["total_rent"].as() ); - BOOST_REQUIRE_EQUAL( get_rex_balance(alice), rex_pool["total_rex"].as() ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, core_sym::from_string("75.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("925.0000"), get_rex_fund(bob) ); - BOOST_REQUIRE_EQUAL( ratio * asset::from_string("75.0000 REX").get_amount(), get_rex_balance(bob).get_amount() ); - rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( core_sym::from_string("105.0000"), rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("105.0000"), rex_pool["total_unlent"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( init_rent, rex_pool["total_rent"].as() ); - BOOST_REQUIRE_EQUAL( get_rex_balance(alice) + get_rex_balance(bob), rex_pool["total_rex"].as() ); - - produce_block( fc::days(6) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("user must first buyrex"), sellrex( carol, asset::from_string("5.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), - sellrex( bob, core_sym::from_string("55.0000") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), - sellrex( bob, asset::from_string("-75.0030 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( bob, asset::from_string("750000.0030 REX") ) ); - - auto init_total_rex = rex_pool["total_rex"].as().get_amount(); - auto init_total_lendable = rex_pool["total_lendable"].as().get_amount(); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset::from_string("550001.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( asset::from_string("199999.0000 REX"), get_rex_balance(bob) ); - rex_pool = get_rex_pool(); - auto total_rex = rex_pool["total_rex"].as().get_amount(); - auto total_lendable = rex_pool["total_lendable"].as().get_amount(); - BOOST_REQUIRE_EQUAL( init_total_rex / init_total_lendable, total_rex / total_lendable ); - BOOST_REQUIRE_EQUAL( total_lendable, rex_pool["total_unlent"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( init_rent, rex_pool["total_rent"].as() ); - BOOST_REQUIRE_EQUAL( get_rex_balance(alice) + get_rex_balance(bob), rex_pool["total_rex"].as() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( buy_sell_small_rex, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("50000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; - setup_rex_accounts( accounts, init_balance ); - - const asset payment = core_sym::from_string("40000.0000"); - BOOST_REQUIRE_EQUAL( ratio * payment.get_amount(), get_buyrex_result( alice, payment ).get_amount() ); - - produce_blocks(2); - produce_block( fc::days(5) ); - produce_blocks(2); - - asset init_rex_stake = get_rex_vote_stake( alice ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("proceeds are negligible"), sellrex( alice, asset::from_string("0.0001 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("proceeds are negligible"), sellrex( alice, asset::from_string("0.9999 REX") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0001"), get_sellrex_result( alice, asset::from_string("1.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0001"), get_sellrex_result( alice, asset::from_string("1.9999 REX") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0002"), get_sellrex_result( alice, asset::from_string("2.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0002"), get_sellrex_result( alice, asset::from_string("2.9999 REX") ) ); - BOOST_REQUIRE_EQUAL( get_rex_vote_stake( alice ), init_rex_stake - core_sym::from_string("0.0006") ); - - BOOST_REQUIRE_EQUAL( success(), rentcpu( carol, bob, core_sym::from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("proceeds are negligible"), sellrex( alice, asset::from_string("0.4000 REX") ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { - - const int64_t ratio = 10000; - const asset zero_asset = core_sym::from_string("0.0000"); - const asset neg_asset = core_sym::from_string("-0.0001"); - const asset one_token = core_sym::from_string("1.0000"); - const asset init_balance = core_sym::from_string("10000.0000"); - const asset init_net = core_sym::from_string("70.0000"); - const asset init_cpu = core_sym::from_string("90.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance, init_net, init_cpu, false ); - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - - setup_producer_accounts(producer_names); - for ( const auto& p: producer_names ) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info(p)["total_votes"].as() ); - } - } - - const int64_t init_cpu_limit = get_cpu_limit( alice ); - const int64_t init_net_limit = get_net_limit( alice ); - - { - const asset net_stake = core_sym::from_string("25.5000"); - const asset cpu_stake = core_sym::from_string("12.4000"); - const asset tot_stake = net_stake + cpu_stake; - BOOST_REQUIRE_EQUAL( init_balance, get_balance( alice ) ); - BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit + cpu_stake.get_amount() ); - BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit + net_stake.get_amount() ); - BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 20) ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), - unstaketorex( alice, alice, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); - const asset init_eosio_stake_balance = get_balance( N(eosio.stake) ); - const auto init_voter_info = get_voter_info( alice ); - const auto init_prod_info = get_producer_info( producer_names[0] ); - BOOST_TEST_REQUIRE( init_prod_info["total_votes"].as_double() == - stake2votes( asset( init_voter_info["staked"].as(), symbol{CORE_SYM} ) ) ); - produce_block( fc::days(4) ); - BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_unstaketorex_result( alice, alice, net_stake, cpu_stake ).get_amount() ); - BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit ); - BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit ); - BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( tot_stake, get_rex_balance_obj( alice )["vote_stake"].as() ); - BOOST_REQUIRE_EQUAL( tot_stake, get_balance( N(eosio.rex) ) ); - BOOST_REQUIRE_EQUAL( tot_stake, init_eosio_stake_balance - get_balance( N(eosio.stake) ) ); - auto current_voter_info = get_voter_info( alice ); - auto current_prod_info = get_producer_info( producer_names[0] ); - BOOST_REQUIRE_EQUAL( init_voter_info["staked"].as(), current_voter_info["staked"].as() ); - BOOST_TEST_REQUIRE( current_prod_info["total_votes"].as_double() == - stake2votes( asset( current_voter_info["staked"].as(), symbol{CORE_SYM} ) ) ); - BOOST_TEST_REQUIRE( init_prod_info["total_votes"].as_double() < current_prod_info["total_votes"].as_double() ); - } - - { - const asset net_stake = core_sym::from_string("200.5000"); - const asset cpu_stake = core_sym::from_string("120.0000"); - const asset tot_stake = net_stake + cpu_stake; - BOOST_REQUIRE_EQUAL( success(), stake( bob, carol, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("amount exceeds tokens staked for net"), - unstaketorex( bob, carol, net_stake + one_token, zero_asset ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("amount exceeds tokens staked for cpu"), - unstaketorex( bob, carol, zero_asset, cpu_stake + one_token ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("delegated bandwidth record does not exist"), - unstaketorex( bob, emily, zero_asset, one_token ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount to buy rex"), - unstaketorex( bob, carol, zero_asset, zero_asset ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount to buy rex"), - unstaketorex( bob, carol, neg_asset, one_token ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount to buy rex"), - unstaketorex( bob, carol, one_token, neg_asset ) ); - BOOST_REQUIRE_EQUAL( init_net_limit + net_stake.get_amount(), get_net_limit( carol ) ); - BOOST_REQUIRE_EQUAL( init_cpu_limit + cpu_stake.get_amount(), get_cpu_limit( carol ) ); - BOOST_REQUIRE_EQUAL( false, get_dbw_obj( bob, carol ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), unstaketorex( bob, carol, net_stake, zero_asset ) ); - BOOST_REQUIRE_EQUAL( false, get_dbw_obj( bob, carol ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), unstaketorex( bob, carol, zero_asset, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( true, get_dbw_obj( bob, carol ).is_null() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance( carol ).get_amount() ); - BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_rex_balance( bob ).get_amount() ); - BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( bob ) ); - BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( bob ) ); - BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); - BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); - } - - { - const asset net_stake = core_sym::from_string("130.5000"); - const asset cpu_stake = core_sym::from_string("220.0800"); - const asset tot_stake = net_stake + cpu_stake; - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( emily, frank, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("delegated bandwidth record does not exist"), - unstaketorex( emily, frank, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( success(), unstaketorex( frank, frank, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( frank, asset::from_string("1.0000 REX") ) ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( frank, asset::from_string("1.0000 REX") ) ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("60000.0000"); - const asset init_net = core_sym::from_string("70.0000"); - const asset init_cpu = core_sym::from_string("90.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance, init_net, init_cpu ); - - const int64_t init_cpu_limit = get_cpu_limit( alice ); - const int64_t init_net_limit = get_net_limit( alice ); - - // bob tries to rent rex - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rentcpu( bob, carol, core_sym::from_string("5.0000") ) ); - // alice lends rex - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("50265.0000") ) ); - BOOST_REQUIRE_EQUAL( init_balance - core_sym::from_string("50265.0000"), get_rex_fund(alice) ); - auto rex_pool = get_rex_pool(); - const asset init_tot_unlent = rex_pool["total_unlent"].as(); - const asset init_tot_lendable = rex_pool["total_lendable"].as(); - const asset init_tot_rent = rex_pool["total_rent"].as(); - const int64_t init_stake = get_voter_info(alice)["staked"].as(); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); - - BOOST_REQUIRE( get_rex_return_pool().is_null() ); - - { - // bob rents cpu for carol - const asset fee = core_sym::from_string("17.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, carol, fee ) ); - BOOST_REQUIRE_EQUAL( init_balance - fee, get_rex_fund(bob) ); - rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_tot_lendable, rex_pool["total_lendable"].as() ); // 65 - BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 17 - int64_t expected_total_lent = bancor_convert( init_tot_rent.get_amount(), init_tot_unlent.get_amount(), fee.get_amount() ); - BOOST_REQUIRE_EQUAL( expected_total_lent, - rex_pool["total_lent"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( rex_pool["total_lent"].as() + rex_pool["total_unlent"].as(), - rex_pool["total_lendable"].as() ); - - auto rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE( !rex_return_pool.is_null() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - - // test that carol's resource limits have been updated properly - BOOST_REQUIRE_EQUAL( expected_total_lent, get_cpu_limit( carol ) - init_cpu_limit ); - BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net_limit ); - - // alice tries to sellrex, order gets scheduled then she cancels order - BOOST_REQUIRE_EQUAL( cancelrexorder( alice ), wasm_assert_msg("no sellrex order is scheduled") ); - produce_block( fc::days(6) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); - - produce_block( fc::days(20) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE( !rex_return_pool.is_null() ); - int64_t rate = fee.get_amount() / (30 * 144); - BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); - - produce_block( fc::days(10) ); - // alice is finally able to sellrex, she gains the fee paid by bob - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - auto expected_rex_fund = (init_balance + fee).get_amount(); - auto actual_rex_fund = get_rex_fund(alice).get_amount(); - BOOST_REQUIRE_EQUAL( expected_rex_fund, actual_rex_fund ); - // test that carol's resource limits have been updated properly when loan expires - BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); - BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); - - rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_unlent"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_rex"].as().get_amount() ); - } - - { - const int64_t init_net_limit = get_net_limit( emily ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("20050.0000") ) ); - rex_pool = get_rex_pool(); - const asset fee = core_sym::from_string("0.4560"); - int64_t expected_net = bancor_convert( rex_pool["total_rent"].as().get_amount(), - rex_pool["total_unlent"].as().get_amount(), - fee.get_amount() ); - BOOST_REQUIRE_EQUAL( success(), rentnet( emily, emily, fee ) ); - BOOST_REQUIRE_EQUAL( expected_net, get_net_limit( emily ) - init_net_limit ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("40000.0000"); - const asset init_net = core_sym::from_string("70.0000"); - const asset init_cpu = core_sym::from_string("90.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; - setup_rex_accounts( accounts, init_balance, init_net, init_cpu ); - - const int64_t init_cpu_limit = get_cpu_limit( alice ); - const int64_t init_net_limit = get_net_limit( alice ); - - // alice lends rex - const asset payment = core_sym::from_string("30250.0000"); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, core_sym::from_string("0.0005") ) ); - BOOST_REQUIRE_EQUAL( init_balance - payment, get_rex_fund(alice) ); - auto rex_pool = get_rex_pool(); - const asset init_tot_unlent = rex_pool["total_unlent"].as(); - const asset init_tot_lendable = rex_pool["total_lendable"].as(); - const asset init_tot_rent = rex_pool["total_rent"].as(); - const int64_t init_stake = get_voter_info(alice)["staked"].as(); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) + get_rex_balance(bob) ); - - // bob rents cpu for carol - const asset fee = core_sym::from_string("7.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, carol, fee ) ); - rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_tot_lendable, rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); - - produce_block( fc::days(5) ); - produce_blocks(2); - const asset rex_tok = asset::from_string("1.0000 REX"); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) - rex_tok ) ); - BOOST_REQUIRE_EQUAL( false, get_rex_order_obj( alice ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_tok ) ); - BOOST_REQUIRE_EQUAL( sellrex( alice, rex_tok ), wasm_assert_msg("insufficient funds for current and scheduled orders") ); - BOOST_REQUIRE_EQUAL( ratio * payment.get_amount() - rex_tok.get_amount(), get_rex_order( alice )["rex_requested"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( success(), consolidate( alice ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["rex_maturities"].get_array().size() ); - - produce_block( fc::days(26) ); - produce_blocks(2); - - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 2 ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["matured_rex"].as() ); - const asset init_fund = get_rex_fund( alice ); - BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["matured_rex"].as() ); - BOOST_REQUIRE ( init_fund < get_rex_fund( alice ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("3000000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance ); - - const auto purchase1 = core_sym::from_string("50000.0000"); - const auto purchase2 = core_sym::from_string("105500.0000"); - const auto purchase3 = core_sym::from_string("104500.0000"); - const auto init_stake = get_voter_info(alice)["staked"].as(); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase1) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, purchase2) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( carol, purchase3) ); - - BOOST_REQUIRE_EQUAL( init_balance - purchase1, get_rex_fund(alice) ); - BOOST_REQUIRE_EQUAL( purchase1.get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); - - BOOST_REQUIRE_EQUAL( init_balance - purchase2, get_rex_fund(bob) ); - BOOST_REQUIRE_EQUAL( init_balance - purchase3, get_rex_fund(carol) ); - - auto init_alice_rex = get_rex_balance(alice); - auto init_bob_rex = get_rex_balance(bob); - auto init_carol_rex = get_rex_balance(carol); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("20000.0000"), get_rex_pool()["total_rent"].as() ); - - for (uint8_t i = 0; i < 4; ++i) { - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, emily, core_sym::from_string("12000.0000") ) ); - } - - produce_block( fc::days(25) ); - - const asset rent_payment = core_sym::from_string("46000.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment, rent_payment ) ); - - produce_block( fc::days(4) ); - - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - - const auto init_rex_pool = get_rex_pool(); - const int64_t total_lendable = init_rex_pool["total_lendable"].as().get_amount(); - const int64_t total_rex = init_rex_pool["total_rex"].as().get_amount(); - const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_alice_rex.get_amount()) * total_lendable ) / total_rex; - - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 3 * get_rex_balance(alice).get_amount() / 4, symbol{SY(4,REX)} ) ) ); - - BOOST_TEST_REQUIRE( within_one( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); - - init_alice_rex = get_rex_balance(alice); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance(bob) ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( carol, get_rex_balance(carol) ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); - - BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_balance(bob) ); - BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); - BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); - - // now bob's, carol's and alice's sellrex orders have been queued - BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(bob)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); - - // wait for a total of 30 days minus 1 hour - produce_block( fc::hours(23) ); - BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); - - // wait for 2 more hours, by now frank's loan has expired and there is enough balance in - // total_unlent to close some sellrex orders. only two are processed, bob's and carol's. - // alices's order is still open. - // an action is needed to trigger queue processing - produce_block( fc::hours(2) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), - rentcpu( frank, frank, core_sym::from_string("0.0001") ) ); - { - auto trace = base_tester::push_action( config::system_account_name, N(rexexec), frank, - mvo()("user", frank)("max", 2) ); - auto output = get_rexorder_result( trace ); - BOOST_REQUIRE_EQUAL( output.size(), 1 ); - BOOST_REQUIRE_EQUAL( output[0].first, bob ); - BOOST_REQUIRE_EQUAL( output[0].second, get_rex_order(bob)["proceeds"].as() ); - } - - { - BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_TEST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), - rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); - } - - produce_blocks(2); - produce_block( fc::hours(13) ); - produce_blocks(2); - produce_block( fc::days(30) ); - produce_blocks(2); - - { - auto trace1 = base_tester::push_action( config::system_account_name, N(updaterex), bob, mvo()("owner", bob) ); - auto trace2 = base_tester::push_action( config::system_account_name, N(updaterex), carol, mvo()("owner", carol) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( bob ).get_amount() ); - BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( bob )["staked"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( carol ).get_amount() ); - BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( carol )["staked"].as() ); - auto output1 = get_rexorder_result( trace1 ); - auto output2 = get_rexorder_result( trace2 ); - BOOST_REQUIRE_EQUAL( 2, output1.size() + output2.size() ); - - BOOST_REQUIRE_EQUAL( false, get_rex_order_obj(alice).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order_obj(bob).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order_obj(carol).is_null() ); - BOOST_REQUIRE_EQUAL( false, get_rex_order(alice)["is_open"].as() ); - - const auto& rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_rex"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), - rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( emily, core_sym::from_string("22000.0000") ) ); - BOOST_REQUIRE_EQUAL( false, get_rex_order_obj(alice).is_null() ); - BOOST_REQUIRE_EQUAL( false, get_rex_order(alice)["is_open"].as() ); - - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("40000.0000"); - const asset one_unit = core_sym::from_string("0.0001"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("25000.0000") ) ); - - auto rex_pool = get_rex_pool(); - const asset payment = core_sym::from_string("30.0000"); - const asset zero_asset = core_sym::from_string("0.0000"); - const asset neg_asset = core_sym::from_string("-1.0000"); - BOOST_TEST_REQUIRE( 0 > neg_asset.get_amount() ); - asset cur_frank_balance = get_rex_fund( frank ); - int64_t expected_stake = bancor_convert( rex_pool["total_rent"].as().get_amount(), - rex_pool["total_unlent"].as().get_amount(), - payment.get_amount() ); - const int64_t init_stake = get_cpu_limit( frank ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use core token"), - rentcpu( frank, bob, asset::from_string("10.0000 RND") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use core token"), - rentcpu( frank, bob, payment, asset::from_string("10.0000 RND") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use positive asset amount"), - rentcpu( frank, bob, zero_asset ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use positive asset amount"), - rentcpu( frank, bob, payment, neg_asset ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use positive asset amount"), - rentcpu( frank, bob, neg_asset, payment ) ); - // create 2 cpu and 3 net loans - const asset rented_tokens{ expected_stake, symbol{CORE_SYM} }; - BOOST_REQUIRE_EQUAL( rented_tokens, get_rentcpu_result( frank, bob, payment ) ); // loan_num = 1 - BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, emily, payment ) ); // loan_num = 2 - BOOST_REQUIRE_EQUAL( 2, get_last_cpu_loan()["loan_num"].as_uint64() ); - - asset expected_rented_net; - { - const auto& pool = get_rex_pool(); - const int64_t r = bancor_convert( pool["total_rent"].as().get_amount(), - pool["total_unlent"].as().get_amount(), - payment.get_amount() ); - expected_rented_net = asset{ r, symbol{CORE_SYM} }; - } - BOOST_REQUIRE_EQUAL( expected_rented_net, get_rentnet_result( alice, emily, payment ) ); // loan_num = 3 - BOOST_REQUIRE_EQUAL( success(), rentnet( alice, alice, payment ) ); // loan_num = 4 - BOOST_REQUIRE_EQUAL( success(), rentnet( alice, frank, payment ) ); // loan_num = 5 - BOOST_REQUIRE_EQUAL( 5, get_last_net_loan()["loan_num"].as_uint64() ); - - auto loan_info = get_cpu_loan(1); - auto old_frank_balance = cur_frank_balance; - cur_frank_balance = get_rex_fund( frank ); - BOOST_REQUIRE_EQUAL( old_frank_balance, payment + cur_frank_balance ); - BOOST_REQUIRE_EQUAL( 1, loan_info["loan_num"].as_uint64() ); - BOOST_REQUIRE_EQUAL( payment, loan_info["payment"].as() ); - BOOST_REQUIRE_EQUAL( 0, loan_info["balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( expected_stake, loan_info["total_staked"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( expected_stake + init_stake, get_cpu_limit( bob ) ); - - // frank funds his loan enough to be renewed once - const asset fund = core_sym::from_string("35.0000"); - BOOST_REQUIRE_EQUAL( fundcpuloan( frank, 1, cur_frank_balance + one_unit), wasm_assert_msg("insufficient funds") ); - BOOST_REQUIRE_EQUAL( fundnetloan( frank, 1, fund ), wasm_assert_msg("loan not found") ); - BOOST_REQUIRE_EQUAL( fundcpuloan( alice, 1, fund ), wasm_assert_msg("user must be loan creator") ); - BOOST_REQUIRE_EQUAL( success(), fundcpuloan( frank, 1, fund ) ); - old_frank_balance = cur_frank_balance; - cur_frank_balance = get_rex_fund( frank ); - loan_info = get_cpu_loan(1); - BOOST_REQUIRE_EQUAL( old_frank_balance, fund + cur_frank_balance ); - BOOST_REQUIRE_EQUAL( fund, loan_info["balance"].as() ); - BOOST_REQUIRE_EQUAL( payment, loan_info["payment"].as() ); - - // in the meantime, defund then fund the same amount and test the balances - { - const asset amount = core_sym::from_string("7.5000"); - BOOST_REQUIRE_EQUAL( defundnetloan( frank, 1, fund ), wasm_assert_msg("loan not found") ); - BOOST_REQUIRE_EQUAL( defundcpuloan( alice, 1, fund ), wasm_assert_msg("user must be loan creator") ); - BOOST_REQUIRE_EQUAL( defundcpuloan( frank, 1, core_sym::from_string("75.0000") ), wasm_assert_msg("insufficent loan balance") ); - old_frank_balance = cur_frank_balance; - asset old_loan_balance = get_cpu_loan(1)["balance"].as(); - BOOST_REQUIRE_EQUAL( defundcpuloan( frank, 1, amount ), success() ); - BOOST_REQUIRE_EQUAL( old_loan_balance, get_cpu_loan(1)["balance"].as() + amount ); - cur_frank_balance = get_rex_fund( frank ); - old_loan_balance = get_cpu_loan(1)["balance"].as(); - BOOST_REQUIRE_EQUAL( old_frank_balance + amount, cur_frank_balance ); - old_frank_balance = cur_frank_balance; - BOOST_REQUIRE_EQUAL( fundcpuloan( frank, 1, amount ), success() ); - BOOST_REQUIRE_EQUAL( old_loan_balance + amount, get_cpu_loan(1)["balance"].as() ); - cur_frank_balance = get_rex_fund( frank ); - BOOST_REQUIRE_EQUAL( old_frank_balance - amount, cur_frank_balance ); - } - - // wait for 30 days, frank's loan will be renewed at the current price - produce_block( fc::minutes(30*24*60 - 1) ); - BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - rex_pool = get_rex_pool(); - { - int64_t unlent_tokens = bancor_convert( rex_pool["total_unlent"].as().get_amount(), - rex_pool["total_rent"].as().get_amount(), - expected_stake ); - - expected_stake = bancor_convert( rex_pool["total_rent"].as().get_amount() - unlent_tokens, - rex_pool["total_unlent"].as().get_amount() + expected_stake, - payment.get_amount() ); - } - - produce_block( fc::minutes(2) ); - - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); - - loan_info = get_cpu_loan(1); - BOOST_REQUIRE_EQUAL( payment, loan_info["payment"].as() ); - BOOST_REQUIRE_EQUAL( fund - payment, loan_info["balance"].as() ); - BOOST_REQUIRE_EQUAL( expected_stake, loan_info["total_staked"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( expected_stake + init_stake, get_cpu_limit( bob ) ); - - // check that loans have been processed in order - BOOST_REQUIRE_EQUAL( false, get_cpu_loan(1).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_cpu_loan(2).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_net_loan(3).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_net_loan(4).is_null() ); - BOOST_REQUIRE_EQUAL( false, get_net_loan(5).is_null() ); - BOOST_REQUIRE_EQUAL( 1, get_last_cpu_loan()["loan_num"].as_uint64() ); - BOOST_REQUIRE_EQUAL( 5, get_last_net_loan()["loan_num"].as_uint64() ); - - // wait for another month, frank's loan doesn't have enough funds and will be closed - produce_block( fc::hours(30*24) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( true, get_cpu_loan(1).is_null() ); - BOOST_REQUIRE_EQUAL( init_stake, get_cpu_limit( bob ) ); - old_frank_balance = cur_frank_balance; - cur_frank_balance = get_rex_fund( frank ); - BOOST_REQUIRE_EQUAL( fund - payment, cur_frank_balance - old_frank_balance ); - BOOST_REQUIRE ( old_frank_balance < cur_frank_balance ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_loan_checks, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("40000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance ); - - const asset payment1 = core_sym::from_string("20000.0000"); - const asset payment2 = core_sym::from_string("4.0000"); - const asset fee = core_sym::from_string("1.0000"); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment1 ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("loan price does not favor renting"), - rentcpu( bob, bob, fee ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment2 ) ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee, fee + fee + fee ) ); - BOOST_REQUIRE_EQUAL( true, !get_cpu_loan(1).is_null() ); - BOOST_REQUIRE_EQUAL( 3 * fee.get_amount(), get_last_cpu_loan()["balance"].as().get_amount() ); - - produce_block( fc::days(31) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 3) ); - BOOST_REQUIRE_EQUAL( 2 * fee.get_amount(), get_last_cpu_loan()["balance"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1000000.0000 REX") ) ); - produce_block( fc::days(31) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 3) ); - BOOST_REQUIRE_EQUAL( true, get_cpu_loan(1).is_null() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("10000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance, core_sym::from_string("80.0000"), core_sym::from_string("80.0000"), false ); - - asset cur_ramfee_balance = get_balance( N(eosio.ramfee) ); - BOOST_REQUIRE_EQUAL( success(), buyram( alice, alice, core_sym::from_string("20.0000") ) ); - BOOST_REQUIRE_EQUAL( get_balance( N(eosio.ramfee) ), core_sym::from_string("0.1000") + cur_ramfee_balance ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit to REX fund first"), - buyrex( alice, core_sym::from_string("350.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), deposit( alice, core_sym::from_string("350.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("350.0000") ) ); - cur_ramfee_balance = get_balance( N(eosio.ramfee) ); - asset cur_rex_balance = get_balance( N(eosio.rex) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("350.0000"), cur_rex_balance ); - BOOST_REQUIRE_EQUAL( success(), buyram( bob, carol, core_sym::from_string("70.0000") ) ); - BOOST_REQUIRE_EQUAL( cur_ramfee_balance, get_balance( N(eosio.ramfee) ) ); - BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_sym::from_string("0.3500") ); - - cur_rex_balance = get_balance( N(eosio.rex) ); - - produce_blocks( 1 ); - produce_block( fc::hours(30*24 + 12) ); - produce_blocks( 1 ); - - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - auto cur_rex_pool = get_rex_pool(); - - BOOST_TEST_REQUIRE( within_one( cur_rex_balance.get_amount(), cur_rex_pool["total_unlent"].as().get_amount() ) ); - BOOST_TEST_REQUIRE( cur_rex_balance >= cur_rex_pool["total_unlent"].as() ); - BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["total_lent"].as().get_amount() ); - BOOST_TEST_REQUIRE( within_one( cur_rex_balance.get_amount(), cur_rex_pool["total_lendable"].as().get_amount() ) ); - BOOST_TEST_REQUIRE( cur_rex_balance >= cur_rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["namebid_proceeds"].as().get_amount() ); - - // required for closing namebids - cross_15_percent_threshold(); - produce_block( fc::days(14) ); - - cur_rex_balance = get_balance( N(eosio.rex) ); - BOOST_REQUIRE_EQUAL( success(), bidname( carol, N(rndmbid), core_sym::from_string("23.7000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("23.7000"), get_balance( N(eosio.names) ) ); - BOOST_REQUIRE_EQUAL( success(), bidname( alice, N(rndmbid), core_sym::from_string("29.3500") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("29.3500"), get_balance( N(eosio.names) )); - - produce_block( fc::hours(24) ); - produce_blocks( 2 ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("29.3500"), get_rex_pool()["namebid_proceeds"].as() ); - BOOST_REQUIRE_EQUAL( success(), deposit( frank, core_sym::from_string("5.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( frank, core_sym::from_string("5.0000") ) ); - BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_sym::from_string("34.3500") ); - BOOST_REQUIRE_EQUAL( 0, get_balance( N(eosio.names) ).get_amount() ); - - cur_rex_balance = get_balance( N(eosio.rex) ); - produce_block( fc::hours(30*24 + 13) ); - produce_blocks( 1 ); - - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( get_rex_pool()["total_lendable"].as(), - get_rex_pool()["total_unlent"].as() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("1000000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance ); - - const int64_t rex_ratio = 10000; - const symbol rex_sym( SY(4, REX) ); - - { - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("11.5000") ) ); - produce_block( fc::hours(3) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("18.5000") ) ); - produce_block( fc::hours(25) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("25.0000") ) ); - - auto rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 550000 * rex_ratio, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string("115000.0000 REX") ) ); - produce_block( fc::hours( 3*24 + 20) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("300000.0000 REX") ) ); - rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 250000 * rex_ratio, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - produce_block( fc::hours(23) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string("250000.0000 REX") ) ); - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("130000.0000 REX") ) ); - rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 1200000000, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 1200000000, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string("130000.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("120000.0000 REX") ) ); - rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_maturities"].get_array().size() ); - } - - { - const asset payment1 = core_sym::from_string("14.8000"); - const asset payment2 = core_sym::from_string("15.2000"); - const asset payment = payment1 + payment2; - const asset rex_bucket( rex_ratio * payment.get_amount(), rex_sym ); - for ( uint8_t i = 0; i < 8; ++i ) { - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment1 ) ); - produce_block( fc::hours(2) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment2 ) ); - produce_block( fc::hours(24) ); - } - - auto rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 8 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 3 * rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - - BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - - produce_block( fc::hours(2) ); - BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); - - produce_block( fc::hours(1) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( 3 * rex_bucket.get_amount(), rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, asset( 2 * rex_bucket.get_amount(), rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( rex_bucket.get_amount(), rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - - produce_block( fc::hours(23) ); - BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - - BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - - produce_block( fc::days(3) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, asset( 4 * rex_bucket.get_amount(), rex_sym ) ) ); - produce_block( fc::hours(24 + 20) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( 4 * rex_bucket.get_amount(), rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - } - - { - const asset payment1 = core_sym::from_string("250000.0000"); - const asset payment2 = core_sym::from_string("10000.0000"); - const asset rex_bucket1( rex_ratio * payment1.get_amount(), rex_sym ); - const asset rex_bucket2( rex_ratio * payment2.get_amount(), rex_sym ); - const asset tot_rex = rex_bucket1 + rex_bucket2; - - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment1 ) ); - produce_block( fc::days(3) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment2 ) ); - produce_block( fc::days(2) ); - BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); - - auto rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( tot_rex, rex_balance["rex_balance"].as() ); - BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, alice, core_sym::from_string("8000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( rex_bucket1.get_amount() - 20, rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), get_rex_order( bob )["rex_requested"].as().get_amount() + 20 ); - BOOST_REQUIRE_EQUAL( tot_rex, rex_balance["rex_balance"].as() ); - BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() + 20 ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( bob ) ); - BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("100000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance ); - - const int64_t rex_ratio = 10000; - const symbol rex_sym( SY(4, REX) ); - - { - const asset payment1 = core_sym::from_string("14.8000"); - const asset payment2 = core_sym::from_string("15.2000"); - const asset payment = payment1 + payment2; - const asset rex_bucket( rex_ratio * payment.get_amount(), rex_sym ); - for ( uint8_t i = 0; i < 8; ++i ) { - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment1 ) ); - produce_block( fc::hours(12) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment2 ) ); - produce_block( fc::hours(14) ); - } - - auto rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 8 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - - BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( 8 * rex_bucket.get_amount(), rex_sym ) ) ); - rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - produce_block( fc::days(1000) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string( "1.0000 REX" ) ) ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( alice, asset::from_string( "10.0000 REX" ) ) ); - rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); - produce_block( fc::days(3) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string( "1.0000 REX" ) ) ); - produce_blocks( 2 ); - produce_block( fc::days(2) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string( "10.0001 REX" ) ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string( "10.0000 REX" ) ) ); - rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - produce_block( fc::days(100) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string( "0.0001 REX" ) ) ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( alice, get_rex_balance( alice ) ) ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); - } - - { - const asset payment = core_sym::from_string("20.0000"); - const asset rex_bucket( rex_ratio * payment.get_amount(), rex_sym ); - for ( uint8_t i = 0; i < 5; ++i ) { - produce_block( fc::hours(24) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment ) ); - } - - auto rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 5 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( success(), mvtosavings( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 6, rex_balance["rex_maturities"].get_array().size() ); - - BOOST_REQUIRE_EQUAL( success(), mvtosavings( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, rex_bucket ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( success(), mvtosavings( bob, asset( 3 * rex_bucket.get_amount() / 2, rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, rex_bucket ) ); - - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, rex_bucket ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 3 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, rex_bucket ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 5 * rex_bucket.get_amount(), 2 * rex_balance["rex_balance"].as().get_amount() ); - - produce_block( fc::days(20) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, rex_bucket ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient REX in savings"), - mvfrsavings( bob, asset( 3 * rex_bucket.get_amount(), rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, rex_bucket ) ); - BOOST_REQUIRE_EQUAL( 2, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient REX balance"), - mvtosavings( bob, asset( 3 * rex_bucket.get_amount() / 2, rex_sym ) ) ); - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, rex_bucket ) ); - BOOST_REQUIRE_EQUAL( 3, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); - produce_block( fc::days(4) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, rex_bucket ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, rex_bucket ) ); - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, rex_bucket ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( rex_bucket.get_amount() / 2, rex_balance["rex_balance"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, asset( rex_bucket.get_amount() / 4, rex_sym ) ) ); - produce_block( fc::days(2) ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, asset( rex_bucket.get_amount() / 8, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( 3, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); - BOOST_REQUIRE_EQUAL( 2, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); - - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( 3 * rex_bucket.get_amount() / 8, rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( rex_bucket.get_amount() / 8, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, get_rex_balance( bob ) ) ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); - } - - { - const asset payment = core_sym::from_string("40000.0000"); - const int64_t rex_bucket_amount = rex_ratio * payment.get_amount(); - const asset rex_bucket( rex_bucket_amount, rex_sym ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); - BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_balance( alice ) ); - BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_pool()["total_rex"].as() ); - - produce_block( fc::days(5) ); - - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, core_sym::from_string("3000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 9 * rex_bucket_amount / 10, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_balance( alice ) ); - BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( rex_bucket_amount / 10, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient REX balance"), - mvtosavings( alice, asset( rex_bucket_amount / 10, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( rex_bucket_amount / 10, rex_sym ) ) ); - auto rb = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( rb["matured_rex"].as(), 8 * rex_bucket_amount / 10 ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( alice, asset( 2 * rex_bucket_amount / 10, rex_sym ) ) ); - produce_block( fc::days(31) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); - } - - { - const asset payment = core_sym::from_string("250.0000"); - const asset half_payment = core_sym::from_string("125.0000"); - const int64_t rex_bucket_amount = rex_ratio * payment.get_amount(); - const int64_t half_rex_bucket_amount = rex_bucket_amount / 2; - const asset rex_bucket( rex_bucket_amount, rex_sym ); - const asset half_rex_bucket( half_rex_bucket_amount, rex_sym ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( carol, payment ) ); - BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_balance( carol ) ); - auto rex_balance = get_rex_balance_obj( carol ); - - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( carol, payment ) ); - rex_balance = get_rex_balance_obj( carol ); - BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - - BOOST_REQUIRE_EQUAL( success(), mvtosavings( carol, half_rex_bucket ) ); - rex_balance = get_rex_balance_obj( carol ); - BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( carol, half_payment ) ); - rex_balance = get_rex_balance_obj( carol ); - BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); - - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), - mvfrsavings( carol, asset::from_string("0.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), - mvfrsavings( carol, asset::from_string("1.0000 RND") ) ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( carol, half_rex_bucket ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient REX in savings"), - mvfrsavings( carol, asset::from_string("0.0001 REX") ) ); - rex_balance = get_rex_balance_obj( carol ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 5 * half_rex_bucket_amount, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 2 * rex_bucket_amount, rex_balance["matured_rex"].as() ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( carol, get_rex_balance( carol) ) ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { - - const asset init_balance = core_sym::from_string("30000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; - setup_rex_accounts( accounts, init_balance ); - - const int64_t init_stake = get_voter_info( alice )["staked"].as(); - - // alice buys rex - const asset payment = core_sym::from_string("25000.0000"); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); - BOOST_REQUIRE_EQUAL( payment, get_rex_vote_stake(alice) ); - BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); - - // emily rents cpu - const asset fee = core_sym::from_string("50.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, fee ) ); - BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - BOOST_REQUIRE_EQUAL( payment, get_rex_vote_stake(alice) ); - BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info( alice )["staked"].as() - init_stake ); - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - - setup_producer_accounts(producer_names); - for ( const auto& p: producer_names ) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info(p)["total_votes"].as() ); - } - } - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("voter holding REX tokens must vote for at least 21 producers or for a proxy"), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 20) ) ); - BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); - - BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) - == get_producer_info(producer_names[0])["total_votes"].as() ); - BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) - == get_producer_info(producer_names[20])["total_votes"].as() ); - - BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - produce_block( fc::days(10) ); - BOOST_TEST_REQUIRE( get_producer_info(producer_names[20])["total_votes"].as() - < stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) ); - - BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) - == get_producer_info(producer_names[20])["total_votes"].as() ); - - produce_block( fc::hours(19 * 24 + 23) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - const asset init_rex = get_rex_balance( alice ); - const auto current_rex_pool = get_rex_pool(); - const int64_t total_lendable = current_rex_pool["total_lendable"].as().get_amount(); - const int64_t total_rex = current_rex_pool["total_rex"].as().get_amount(); - const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_rex.get_amount()) * total_lendable ) / total_rex; - const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_sell_amount ) ); - BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance(alice) + rex_sell_amount ); - BOOST_REQUIRE_EQUAL( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); - BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) - == get_producer_info(producer_names[0])["total_votes"].as() ); - produce_block( fc::days(31) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names[0], producer_names[4] } ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), - buyrex( alice, core_sym::from_string("1.0000") ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_test::tolerance(1e-8) ) try { - - cross_15_percent_threshold(); - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - - setup_producer_accounts(producer_names); - for ( const auto& p: producer_names ) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info(p)["total_votes"].as() ); - } - } - - const asset init_balance = core_sym::from_string("30000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; - setup_rex_accounts( accounts, init_balance ); - - const int64_t init_stake_amount = get_voter_info( alice )["staked"].as(); - const asset init_stake( init_stake_amount, symbol{CORE_SYM} ); - - const asset purchase = core_sym::from_string("25000.0000"); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase ) ); - BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); - BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); - BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); - - BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); - BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); - BOOST_REQUIRE_EQUAL( purchase.get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); - - const auto init_rex_pool = get_rex_pool(); - const asset rent = core_sym::from_string("25.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); - - produce_block( fc::days(31) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - const auto curr_rex_pool = get_rex_pool(); - BOOST_TEST_REQUIRE( within_one( curr_rex_pool["total_lendable"].as().get_amount(), - init_rex_pool["total_lendable"].as().get_amount() + rent.get_amount() ) ); - - BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); - BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ) ); - BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_rex_vote_stake(alice).get_amount() ) ); - BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == - get_producer_info(producer_names[0])["total_votes"].as_double() ); - BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == - get_producer_info(producer_names[20])["total_votes"].as_double() ); - - const asset to_net_stake = core_sym::from_string("60.0000"); - const asset to_cpu_stake = core_sym::from_string("40.0000"); - transfer( config::system_account_name, alice, to_net_stake + to_cpu_stake, config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); - produce_block( fc::hours(30 * 24 + 13) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, to_net_stake, to_cpu_stake ) ); - BOOST_REQUIRE_EQUAL( purchase + rent + rent, get_rex_vote_stake(alice) ); - BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + to_net_stake + to_cpu_stake) == - get_producer_info(producer_names[0])["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); - produce_block( fc::hours(30 * 24 + 13) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - BOOST_REQUIRE_EQUAL( success(), unstake( alice, alice, to_net_stake, to_cpu_stake ) ); - BOOST_REQUIRE_EQUAL( purchase + rent + rent + rent, get_rex_vote_stake(alice) ); - BOOST_TEST_REQUIRE ( stake2votes(init_stake + get_rex_vote_stake(alice) ) == - get_producer_info(producer_names[0])["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("1000.0000"); - const asset init_net = core_sym::from_string("70.0000"); - const asset init_cpu = core_sym::from_string("90.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance, init_net, init_cpu, false ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_rex_fund( alice ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit to REX fund first"), withdraw( alice, core_sym::from_string("0.0001") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), deposit( alice, init_balance + init_balance ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit core token"), deposit( alice, asset::from_string("1.0000 RNDM") ) ); - - asset deposit_quant( init_balance.get_amount() / 5, init_balance.get_symbol() ); - BOOST_REQUIRE_EQUAL( success(), deposit( alice, deposit_quant ) ); - BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance - deposit_quant ); - BOOST_REQUIRE_EQUAL( get_rex_fund( alice ), deposit_quant ); - BOOST_REQUIRE_EQUAL( success(), deposit( alice, deposit_quant ) ); - BOOST_REQUIRE_EQUAL( get_rex_fund( alice ), deposit_quant + deposit_quant ); - BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance - deposit_quant - deposit_quant ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), withdraw( alice, get_rex_fund( alice ) + core_sym::from_string("0.0001")) ); - BOOST_REQUIRE_EQUAL( success(), withdraw( alice, deposit_quant ) ); - BOOST_REQUIRE_EQUAL( get_rex_fund( alice ), deposit_quant ); - BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance - deposit_quant ); - BOOST_REQUIRE_EQUAL( success(), withdraw( alice, get_rex_fund( alice ) ) ); - BOOST_REQUIRE_EQUAL( get_rex_fund( alice ).get_amount(), 0 ); - BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("25000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance ); - const symbol rex_sym( SY(4, REX) ); - - const asset payment = core_sym::from_string("25000.0000"); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); - const asset fee = core_sym::from_string("25.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); - - const auto rex_pool = get_rex_pool(); - const int64_t tot_rex = rex_pool["total_rex"].as().get_amount(); - const int64_t tot_unlent = rex_pool["total_unlent"].as().get_amount(); - const int64_t tot_lent = rex_pool["total_lent"].as().get_amount(); - const int64_t tot_lendable = rex_pool["total_lendable"].as().get_amount(); - double rex_per_eos = double(tot_rex) / double(tot_lendable); - int64_t sell_amount = rex_per_eos * ( tot_unlent - 0.09 * tot_lent ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - sell_amount = rex_per_eos * ( tot_unlent - 0.1 * tot_lent ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("no sellrex order is scheduled"), - cancelrexorder( alice ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("25000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; - setup_rex_accounts( accounts, init_balance ); - - BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( alice ).is_null() ); - BOOST_REQUIRE_EQUAL( init_balance, get_rex_fund( alice ) ); - BOOST_REQUIRE_EQUAL( success(), closerex( alice ) ); - BOOST_REQUIRE_EQUAL( success(), withdraw( alice, init_balance ) ); - BOOST_REQUIRE_EQUAL( success(), closerex( alice ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( alice ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), deposit( alice, init_balance ) ); - BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( alice ).is_null() ); - - BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, init_balance ) ); - BOOST_REQUIRE_EQUAL( true, !get_rex_balance_obj( bob ).is_null() ); - BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( bob ).is_null() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_fund( bob ).get_amount() ); - BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX balance, must sell first") ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); - BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); - BOOST_REQUIRE_EQUAL( success(), withdraw( bob, get_rex_fund( bob ) ) ); - BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( bob ).is_null() ); - - BOOST_REQUIRE_EQUAL( success(), deposit( bob, init_balance ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, init_balance ) ); - - const asset fee = core_sym::from_string("1.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( carol, emily, fee ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), - withdraw( carol, init_balance ) ); - BOOST_REQUIRE_EQUAL( success(), withdraw( carol, init_balance - fee ) ); - - produce_block( fc::days(20) ); - - BOOST_REQUIRE_EQUAL( success(), closerex( carol ) ); - BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( carol ).is_null() ); - - produce_block( fc::days(10) ); - - BOOST_REQUIRE_EQUAL( success(), closerex( carol ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( carol ).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( carol ).is_null() ); - - BOOST_REQUIRE_EQUAL( success(), rentnet( emily, emily, fee ) ); - BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( emily ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), closerex( emily ) ); - BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( emily ).is_null() ); - - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); - BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX balance, must sell first") ); - - produce_block( fc::days(30) ); - - BOOST_REQUIRE_EQUAL( closerex( bob ), success() ); - BOOST_REQUIRE ( 0 < get_rex_fund( bob ).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), withdraw( bob, get_rex_fund( bob ) ) ); - BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( bob ).is_null() ); - - BOOST_REQUIRE_EQUAL( 0, get_rex_pool()["total_rex"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_pool()["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), - rentcpu( emily, emily, core_sym::from_string("1.0000") ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( set_rex, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("25000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance ); - - const name act_name{ N(setrex) }; - const asset init_total_rent = core_sym::from_string("20000.0000"); - const asset set_total_rent = core_sym::from_string("10000.0000"); - const asset negative_balance = core_sym::from_string("-10000.0000"); - const asset different_symbol = asset::from_string("10000.0000 RND"); - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action( alice, act_name, mvo()("balance", set_total_rent) ) ); - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action( bob, act_name, mvo()("balance", set_total_rent) ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system is not initialized"), - push_action( config::system_account_name, act_name, mvo()("balance", set_total_rent) ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, init_balance ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("balance must be set to have a positive amount"), - push_action( config::system_account_name, act_name, mvo()("balance", negative_balance) ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("balance symbol must be core symbol"), - push_action( config::system_account_name, act_name, mvo()("balance", different_symbol) ) ); - const asset fee = core_sym::from_string("100.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); - const auto& init_rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_total_rent + fee, init_rex_pool["total_rent"].as() ); - BOOST_TEST_REQUIRE( set_total_rent != init_rex_pool["total_rent"].as() ); - BOOST_REQUIRE_EQUAL( success(), - push_action( config::system_account_name, act_name, mvo()("balance", set_total_rent) ) ); - const auto& curr_rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_rex_pool["total_lendable"].as(), curr_rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( init_rex_pool["total_lent"].as(), curr_rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( init_rex_pool["total_unlent"].as(), curr_rex_pool["total_unlent"].as() ); - BOOST_REQUIRE_EQUAL( init_rex_pool["namebid_proceeds"].as(), curr_rex_pool["namebid_proceeds"].as() ); - BOOST_REQUIRE_EQUAL( init_rex_pool["loan_num"].as_uint64(), curr_rex_pool["loan_num"].as_uint64() ); - BOOST_REQUIRE_EQUAL( set_total_rent, curr_rex_pool["total_rent"].as() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { - - cross_15_percent_threshold(); - - produce_block( fc::days(14) ); - - const asset init_balance = core_sym::from_string("25000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance ); - - const name b1{ N(b1) }; - - issue_and_transfer( alice, core_sym::from_string("20000.0000"), config::system_account_name ); - issue_and_transfer( bob, core_sym::from_string("20000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), bidname( bob, b1, core_sym::from_string( "0.5000" ) ) ); - BOOST_REQUIRE_EQUAL( success(), bidname( alice, b1, core_sym::from_string( "1.0000" ) ) ); - - produce_block( fc::days(1) ); - - create_accounts_with_resources( { b1 }, alice ); - - const asset stake_amount = core_sym::from_string("50000000.0000"); - const asset half_stake = core_sym::from_string("25000000.0000"); - const asset small_amount = core_sym::from_string("1000.0000"); - issue_and_transfer( b1, stake_amount + stake_amount + stake_amount, config::system_account_name ); - - stake( b1, b1, stake_amount, stake_amount ); - - BOOST_REQUIRE_EQUAL( 2 * stake_amount.get_amount(), get_voter_info( b1 )["staked"].as() ); - - BOOST_REQUIRE_EQUAL( success(), unstake( b1, b1, small_amount, small_amount ) ); - - produce_block( fc::days(4) ); - - BOOST_REQUIRE_EQUAL( success(), push_action( b1, N(refund), mvo()("owner", b1) ) ); - - BOOST_REQUIRE_EQUAL( 2 * ( stake_amount.get_amount() - small_amount.get_amount() ), - get_voter_info( b1 )["staked"].as() ); - - produce_block( fc::days( 3 * 364 ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("b1 can only claim their tokens over 10 years"), - unstake( b1, b1, half_stake, half_stake ) ); - - BOOST_REQUIRE_EQUAL( success(), vote( b1, { }, N(proxyaccount) ) ); - BOOST_REQUIRE_EQUAL( success(), unstaketorex( b1, b1, half_stake, half_stake ) ); - - produce_block( fc::days(5) ); - produce_blocks(1); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("b1 can only claim their tokens over 10 years"), - sellrex( b1, get_rex_balance( b1 ) ) ); - - produce_block( fc::days( 2 * 364 ) ); - - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, core_sym::from_string("10000.0000") ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("b1 sellrex orders should not be queued"), - sellrex( b1, get_rex_balance( b1 ) ) ); - - produce_block( fc::days( 30 ) ); - - BOOST_REQUIRE_EQUAL( success(), sellrex( b1, get_rex_balance( b1 ) ) ); - - produce_block( fc::days( 3 * 364 ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("b1 can only claim their tokens over 10 years"), - unstake( b1, b1, half_stake - small_amount, half_stake - small_amount ) ); - - produce_block( fc::days( 1 * 364 ) ); - - BOOST_REQUIRE_EQUAL( success(), - unstake( b1, b1, half_stake - small_amount, half_stake - small_amount ) ); - - produce_block( fc::days(4) ); - BOOST_REQUIRE_EQUAL( success(), push_action( b1, N(refund), mvo()("owner", b1) ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { - - constexpr uint32_t total_intervals = 30 * 144; - constexpr uint32_t dist_interval = 10 * 60; - BOOST_REQUIRE_EQUAL( true, get_rex_return_pool().is_null() ); - - const asset init_balance = core_sym::from_string("100000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance ); - - const asset payment = core_sym::from_string("100000.0000"); - { - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); - auto rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( payment, rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( payment, rex_pool["total_unlent"].as() ); - - BOOST_REQUIRE_EQUAL( true, get_rex_return_pool().is_null() ); - } - - { - const asset fee = core_sym::from_string("30.0000"); - const uint32_t bucket_interval_sec = fc::hours(12).to_seconds(); - const uint32_t current_time_sec = control->pending_block_time().sec_since_epoch(); - const time_point_sec expected_pending_bucket_time{current_time_sec - current_time_sec % bucket_interval_sec + bucket_interval_sec}; - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); - auto rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( false, rex_return_pool.is_null() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - BOOST_REQUIRE_EQUAL( expected_pending_bucket_time.sec_since_epoch(), - rex_return_pool["pending_bucket_time"].as().sec_since_epoch() ); - int32_t t0 = rex_return_pool["pending_bucket_time"].as().sec_since_epoch(); - - produce_block( fc::hours(13) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - rex_return_pool = get_rex_return_pool(); - int64_t rate = fee.get_amount() / total_intervals; - BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); - - int32_t t1 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); - int64_t change = rate * ((t1-t0) / dist_interval) + fee.get_amount() % total_intervals; - int64_t expected = payment.get_amount() + change; - - auto rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( expected, rex_pool["total_lendable"].as().get_amount() ); - - produce_blocks( 1 ); - produce_block( fc::days(25) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 1, get_rex_return_buckets()["return_buckets"].get_array().size() ); - int64_t t2 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); - change = rate * ((t2-t0) / dist_interval) + fee.get_amount() % total_intervals; - expected = payment.get_amount() + change; - - rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( expected, rex_pool["total_lendable"].as().get_amount() ); - - produce_blocks( 1 ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - - rex_pool = get_rex_pool(); - expected = payment.get_amount() + fee.get_amount(); - BOOST_REQUIRE_EQUAL( expected, rex_pool["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( rex_pool["total_lendable"].as(), - rex_pool["total_unlent"].as() ); - } - - produce_block( fc::hours(1) ); - - { - const asset init_lendable = get_rex_pool()["total_lendable"].as(); - const asset fee = core_sym::from_string("15.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); - auto rex_return_pool = get_rex_return_pool(); - uint32_t t0 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); - produce_block( fc::hours(1) ); - BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - uint32_t t1 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); - BOOST_REQUIRE_EQUAL( t1, t0 + 6 * dist_interval ); - - produce_block( fc::hours(12) ); - BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( 1, get_rex_return_buckets()["return_buckets"].get_array().size() ); - int64_t rate = 2 * fee.get_amount() / total_intervals; - BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); - produce_block( fc::hours(8) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); - - produce_block( fc::days(30) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( fee.get_amount() / total_intervals, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_TEST_REQUIRE( (init_lendable + fee + fee).get_amount() < get_rex_pool()["total_lendable"].as().get_amount() ); - - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - BOOST_REQUIRE_EQUAL( init_lendable.get_amount() + 3 * fee.get_amount(), - get_rex_pool()["total_lendable"].as().get_amount() ); - } - - { - const asset fee = core_sym::from_string("25.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); - produce_block( fc::hours(13) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - auto rex_pool_0 = get_rex_pool(); - auto rex_return_pool_0 = get_rex_return_pool(); - produce_block( fc::minutes(2) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - auto rex_pool_1 = get_rex_pool(); - auto rex_return_pool_1 = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( rex_return_pool_0["last_dist_time"].as().sec_since_epoch(), - rex_return_pool_1["last_dist_time"].as().sec_since_epoch() ); - BOOST_REQUIRE_EQUAL( rex_pool_0["total_lendable"].as(), - rex_pool_1["total_lendable"].as() ); - produce_block( fc::minutes(9) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - auto rex_pool_2 = get_rex_pool(); - auto rex_return_pool_2 = get_rex_return_pool(); - BOOST_TEST_REQUIRE( rex_return_pool_1["last_dist_time"].as().sec_since_epoch() < - rex_return_pool_2["last_dist_time"].as().sec_since_epoch() ); - BOOST_TEST_REQUIRE( rex_pool_1["total_lendable"].as().get_amount() < - rex_pool_2["total_lendable"].as().get_amount() ); - produce_block( fc::days(31) ); - produce_blocks( 1 ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_pool()["current_rate_of_increase"].as() ); - } - - { - const asset fee = core_sym::from_string("30.0000"); - for ( uint8_t i = 0; i < 5; ++i ) { - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); - produce_block( fc::days(1) ); - } - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - BOOST_REQUIRE_EQUAL( 5, get_rex_return_buckets()["return_buckets"].get_array().size() ); - produce_block( fc::days(30) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_AUTO_TEST_CASE( setabi_bios ) try { - fc::temp_directory tempdir; - validating_tester t( tempdir, true ); - t.execute_setup_policy( setup_policy::full ); - - abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::bios_abi().data()).template as(), abi_serializer::create_yield_function(base_tester::abi_serializer_max_time)); - t.set_code( config::system_account_name, contracts::bios_wasm() ); - t.set_abi( config::system_account_name, contracts::bios_abi().data() ); - t.create_account(N(eosio.token)); - t.set_abi( N(eosio.token), contracts::token_abi().data() ); - { - auto res = t.get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); - _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer::create_yield_function(base_tester::abi_serializer_max_time) ); - abi_serializer::from_variant( abi_hash_var, abi_hash, t.get_resolver(), abi_serializer::create_yield_function(base_tester::abi_serializer_max_time)); - auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::token_abi().data()).template as()); - auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); - - BOOST_REQUIRE( abi_hash.hash == result ); - } - - t.set_abi( N(eosio.token), contracts::system_abi().data() ); - { - auto res = t.get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); - _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer::create_yield_function(base_tester::abi_serializer_max_time) ); - abi_serializer::from_variant( abi_hash_var, abi_hash, t.get_resolver(), abi_serializer::create_yield_function(base_tester::abi_serializer_max_time)); - auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::system_abi().data()).template as()); - auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); - - BOOST_REQUIRE( abi_hash.hash == result ); - } -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( setabi, eosio_system_tester ) try { - set_abi( N(eosio.token), contracts::token_abi().data() ); - { - auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); - _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer::create_yield_function(abi_serializer_max_time) ); - abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::token_abi().data()).template as()); - auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); - - BOOST_REQUIRE( abi_hash.hash == result ); - } - - set_abi( N(eosio.token), contracts::system_abi().data() ); - { - auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); - _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer::create_yield_function(abi_serializer_max_time) ); - abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::system_abi().data()).template as()); - auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); - - BOOST_REQUIRE( abi_hash.hash == result ); - } - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( change_limited_account_back_to_unlimited, eosio_system_tester ) try { - BOOST_REQUIRE( get_total_stake( "eosio" ).is_null() ); - - transfer( N(eosio), N(alice1111111), core_sym::from_string("1.0000") ); - - auto error_msg = stake( N(alice1111111), N(eosio), core_sym::from_string("0.0000"), core_sym::from_string("1.0000") ); - auto semicolon_pos = error_msg.find(';'); - - BOOST_REQUIRE_EQUAL( error("account eosio has insufficient ram"), - error_msg.substr(0, semicolon_pos) ); - - int64_t ram_bytes_needed = 0; - { - std::istringstream s( error_msg ); - s.seekg( semicolon_pos + 7, std::ios_base::beg ); - s >> ram_bytes_needed; - ram_bytes_needed += 256; // enough room to cover total_resources_table - } - - push_action( N(eosio), N(setalimits), mvo() - ("account", "eosio") - ("ram_bytes", ram_bytes_needed) - ("net_weight", -1) - ("cpu_weight", -1) - ); - - stake( N(alice1111111), N(eosio), core_sym::from_string("0.0000"), core_sym::from_string("1.0000") ); - - REQUIRE_MATCHING_OBJECT( get_total_stake( "eosio" ), mvo() - ("owner", "eosio") - ("net_weight", core_sym::from_string("0.0000")) - ("cpu_weight", core_sym::from_string("1.0000")) - ("ram_bytes", 0) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "only supports unlimited accounts" ), - push_action( N(eosio), N(setalimits), mvo() - ("account", "eosio") - ("ram_bytes", ram_bytes_needed) - ("net_weight", -1) - ("cpu_weight", -1) - ) - ); - - BOOST_REQUIRE_EQUAL( error( "transaction net usage is too high: 128 > 0" ), - push_action( N(eosio), N(setalimits), mvo() - ("account", "eosio.saving") - ("ram_bytes", -1) - ("net_weight", -1) - ("cpu_weight", -1) - ) - ); - - BOOST_REQUIRE_EQUAL( success(), - push_action( N(eosio), N(setacctnet), mvo() - ("account", "eosio") - ("net_weight", -1) - ) - ); - - BOOST_REQUIRE_EQUAL( success(), - push_action( N(eosio), N(setacctcpu), mvo() - ("account", "eosio") - ("cpu_weight", -1) - - ) - ); - - BOOST_REQUIRE_EQUAL( success(), - push_action( N(eosio), N(setalimits), mvo() - ("account", "eosio.saving") - ("ram_bytes", ram_bytes_needed) - ("net_weight", -1) - ("cpu_weight", -1) - ) - ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( buy_pin_sell_ram, eosio_system_tester ) try { - BOOST_REQUIRE( get_total_stake( "eosio" ).is_null() ); - - transfer( N(eosio), N(alice1111111), core_sym::from_string("1020.0000") ); - - auto error_msg = stake( N(alice1111111), N(eosio), core_sym::from_string("10.0000"), core_sym::from_string("10.0000") ); - auto semicolon_pos = error_msg.find(';'); - - BOOST_REQUIRE_EQUAL( error("account eosio has insufficient ram"), - error_msg.substr(0, semicolon_pos) ); - - int64_t ram_bytes_needed = 0; - { - std::istringstream s( error_msg ); - s.seekg( semicolon_pos + 7, std::ios_base::beg ); - s >> ram_bytes_needed; - ram_bytes_needed += ram_bytes_needed/10; // enough buffer to make up for buyrambytes estimation errors - } - - auto alice_original_balance = get_balance( N(alice1111111) ); - - BOOST_REQUIRE_EQUAL( success(), buyrambytes( N(alice1111111), N(eosio), static_cast(ram_bytes_needed) ) ); - - auto tokens_paid_for_ram = alice_original_balance - get_balance( N(alice1111111) ); - - auto total_res = get_total_stake( "eosio" ); - - REQUIRE_MATCHING_OBJECT( total_res, mvo() - ("owner", "eosio") - ("net_weight", core_sym::from_string("0.0000")) - ("cpu_weight", core_sym::from_string("0.0000")) - ("ram_bytes", total_res["ram_bytes"].as_int64() ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "only supports unlimited accounts" ), - push_action( N(eosio), N(setalimits), mvo() - ("account", "eosio") - ("ram_bytes", ram_bytes_needed) - ("net_weight", -1) - ("cpu_weight", -1) - ) - ); - - BOOST_REQUIRE_EQUAL( success(), - push_action( N(eosio), N(setacctram), mvo() - ("account", "eosio") - ("ram_bytes", total_res["ram_bytes"].as_int64() ) - ) - ); - - auto eosio_original_balance = get_balance( N(eosio) ); - - BOOST_REQUIRE_EQUAL( success(), sellram( N(eosio), total_res["ram_bytes"].as_int64() ) ); - - auto tokens_received_by_selling_ram = get_balance( N(eosio) ) - eosio_original_balance; - - BOOST_REQUIRE( double(tokens_paid_for_ram.get_amount() - tokens_received_by_selling_ram.get_amount()) / tokens_paid_for_ram.get_amount() < 0.01 ); - -} FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 23de001a..e6e86135 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -1,10 +1,10 @@ #include #include #include -#include "eosio.system_tester.hpp" +// #include "eosio.system_tester.hpp" +#include "contracts.hpp" #include "Runtime/Runtime.h" - #include using namespace eosio::testing; @@ -22,15 +22,15 @@ class eosio_token_tester : public tester { eosio_token_tester() { produce_blocks( 2 ); - create_accounts( { N(alice), N(bob), N(carol), N(eosio.token) } ); + create_accounts( { "alice"_n, "bob"_n, "carol"_n, "eosio.token"_n } ); produce_blocks( 2 ); - set_code( N(eosio.token), contracts::token_wasm() ); - set_abi( N(eosio.token), contracts::token_abi().data() ); + set_code( "eosio.token"_n, contracts::token_wasm() ); + set_abi( "eosio.token"_n, contracts::token_abi().data() ); produce_blocks(); - const auto& accnt = control->db().get( N(eosio.token) ); + const auto& accnt = control->db().get( "eosio.token"_n ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); @@ -40,7 +40,7 @@ class eosio_token_tester : public tester { string action_type_name = abi_ser.get_action_type(name); action act; - act.account = N(eosio.token); + act.account = "eosio.token"_n; act.name = name; act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); @@ -51,7 +51,7 @@ class eosio_token_tester : public tester { { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; - vector data = get_row_by_account( N(eosio.token), name(symbol_code), N(stat), account_name(symbol_code) ); + vector data = get_row_by_account( "eosio.token"_n, name(symbol_code), "stat"_n, account_name(symbol_code) ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } @@ -59,21 +59,21 @@ class eosio_token_tester : public tester { { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; - vector data = get_row_by_account( N(eosio.token), acc, N(accounts), account_name(symbol_code) ); + vector data = get_row_by_account( "eosio.token"_n, acc, "accounts"_n, account_name(symbol_code) ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } action_result create( account_name issuer, asset maximum_supply ) { - return push_action( N(eosio.token), N(create), mvo() + return push_action( "eosio.token"_n, "create"_n, mvo() ( "issuer", issuer) ( "maximum_supply", maximum_supply) ); } action_result issue( account_name issuer, asset quantity, string memo ) { - return push_action( issuer, N(issue), mvo() + return push_action( issuer, "issue"_n, mvo() ( "to", issuer) ( "quantity", quantity) ( "memo", memo) @@ -81,7 +81,7 @@ class eosio_token_tester : public tester { } action_result retire( account_name issuer, asset quantity, string memo ) { - return push_action( issuer, N(retire), mvo() + return push_action( issuer, "retire"_n, mvo() ( "quantity", quantity) ( "memo", memo) ); @@ -92,7 +92,7 @@ class eosio_token_tester : public tester { account_name to, asset quantity, string memo ) { - return push_action( from, N(transfer), mvo() + return push_action( from, "transfer"_n, mvo() ( "from", from) ( "to", to) ( "quantity", quantity) @@ -103,7 +103,7 @@ class eosio_token_tester : public tester { action_result open( account_name owner, const string& symbolname, account_name ram_payer ) { - return push_action( ram_payer, N(open), mvo() + return push_action( ram_payer, "open"_n, mvo() ( "owner", owner ) ( "symbol", symbolname ) ( "ram_payer", ram_payer ) @@ -112,7 +112,7 @@ class eosio_token_tester : public tester { action_result close( account_name owner, const string& symbolname ) { - return push_action( owner, N(close), mvo() + return push_action( owner, "close"_n, mvo() ( "owner", owner ) ( "symbol", "0,CERO" ) ); @@ -125,7 +125,7 @@ BOOST_AUTO_TEST_SUITE(eosio_token_tests) BOOST_FIXTURE_TEST_CASE( create_tests, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1000.000 TKN")); + auto token = create( "alice"_n, asset::from_string("1000.000 TKN")); auto stats = get_stats("3,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() ("supply", "0.000 TKN") @@ -139,14 +139,14 @@ BOOST_FIXTURE_TEST_CASE( create_tests, eosio_token_tester ) try { BOOST_FIXTURE_TEST_CASE( create_negative_max_supply, eosio_token_tester ) try { BOOST_REQUIRE_EQUAL( wasm_assert_msg( "max-supply must be positive" ), - create( N(alice), asset::from_string("-1000.000 TKN")) + create( "alice"_n, asset::from_string("-1000.000 TKN")) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( symbol_already_exists, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("100 TKN")); + auto token = create( "alice"_n, asset::from_string("100 TKN")); auto stats = get_stats("0,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() ("supply", "0 TKN") @@ -156,14 +156,14 @@ BOOST_FIXTURE_TEST_CASE( symbol_already_exists, eosio_token_tester ) try { produce_blocks(1); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "token with symbol already exists" ), - create( N(alice), asset::from_string("100 TKN")) + create( "alice"_n, asset::from_string("100 TKN")) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( create_max_supply, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("4611686018427387903 TKN")); + auto token = create( "alice"_n, asset::from_string("4611686018427387903 TKN")); auto stats = get_stats("0,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() ("supply", "0 TKN") @@ -178,7 +178,7 @@ BOOST_FIXTURE_TEST_CASE( create_max_supply, eosio_token_tester ) try { static_assert(std::is_trivially_copyable::value, "asset is not trivially copyable"); memcpy(&max, &amount, sizeof(share_type)); // hack in an invalid amount - BOOST_CHECK_EXCEPTION( create( N(alice), max) , asset_type_exception, [](const asset_type_exception& e) { + BOOST_CHECK_EXCEPTION( create( "alice"_n, max) , asset_type_exception, [](const asset_type_exception& e) { return expect_assert_message(e, "magnitude of asset amount must be less than 2^62"); }); @@ -187,7 +187,7 @@ BOOST_FIXTURE_TEST_CASE( create_max_supply, eosio_token_tester ) try { BOOST_FIXTURE_TEST_CASE( create_max_decimals, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1.000000000000000000 TKN")); + auto token = create( "alice"_n, asset::from_string("1.000000000000000000 TKN")); auto stats = get_stats("18,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() ("supply", "0.000000000000000000 TKN") @@ -203,7 +203,7 @@ BOOST_FIXTURE_TEST_CASE( create_max_decimals, eosio_token_tester ) try { static_assert(std::is_trivially_copyable::value, "asset is not trivially copyable"); memcpy(&max, &amount, sizeof(share_type)); // hack in an invalid amount - BOOST_CHECK_EXCEPTION( create( N(alice), max) , asset_type_exception, [](const asset_type_exception& e) { + BOOST_CHECK_EXCEPTION( create( "alice"_n, max) , asset_type_exception, [](const asset_type_exception& e) { return expect_assert_message(e, "magnitude of asset amount must be less than 2^62"); }); @@ -211,10 +211,10 @@ BOOST_FIXTURE_TEST_CASE( create_max_decimals, eosio_token_tester ) try { BOOST_FIXTURE_TEST_CASE( issue_tests, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1000.000 TKN")); + auto token = create( "alice"_n, asset::from_string("1000.000 TKN")); produce_blocks(1); - issue( N(alice), asset::from_string("500.000 TKN"), "hola" ); + issue( "alice"_n, asset::from_string("500.000 TKN"), "hola" ); auto stats = get_stats("3,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() @@ -223,21 +223,21 @@ BOOST_FIXTURE_TEST_CASE( issue_tests, eosio_token_tester ) try { ("issuer", "alice") ); - auto alice_balance = get_account(N(alice), "3,TKN"); + auto alice_balance = get_account("alice"_n, "3,TKN"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "500.000 TKN") ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "quantity exceeds available supply" ), - issue( N(alice), asset::from_string("500.001 TKN"), "hola" ) + issue( "alice"_n, asset::from_string("500.001 TKN"), "hola" ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "must issue positive quantity" ), - issue( N(alice), asset::from_string("-1.000 TKN"), "hola" ) + issue( "alice"_n, asset::from_string("-1.000 TKN"), "hola" ) ); BOOST_REQUIRE_EQUAL( success(), - issue( N(alice), asset::from_string("1.000 TKN"), "hola" ) + issue( "alice"_n, asset::from_string("1.000 TKN"), "hola" ) ); @@ -245,10 +245,10 @@ BOOST_FIXTURE_TEST_CASE( issue_tests, eosio_token_tester ) try { BOOST_FIXTURE_TEST_CASE( retire_tests, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1000.000 TKN")); + auto token = create( "alice"_n, asset::from_string("1000.000 TKN")); produce_blocks(1); - BOOST_REQUIRE_EQUAL( success(), issue( N(alice), asset::from_string("500.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), issue( "alice"_n, asset::from_string("500.000 TKN"), "hola" ) ); auto stats = get_stats("3,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() @@ -257,55 +257,55 @@ BOOST_FIXTURE_TEST_CASE( retire_tests, eosio_token_tester ) try { ("issuer", "alice") ); - auto alice_balance = get_account(N(alice), "3,TKN"); + auto alice_balance = get_account("alice"_n, "3,TKN"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "500.000 TKN") ); - BOOST_REQUIRE_EQUAL( success(), retire( N(alice), asset::from_string("200.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), retire( "alice"_n, asset::from_string("200.000 TKN"), "hola" ) ); stats = get_stats("3,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() ("supply", "300.000 TKN") ("max_supply", "1000.000 TKN") ("issuer", "alice") ); - alice_balance = get_account(N(alice), "3,TKN"); + alice_balance = get_account("alice"_n, "3,TKN"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "300.000 TKN") ); //should fail to retire more than current supply - BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( N(alice), asset::from_string("500.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( "alice"_n, asset::from_string("500.000 TKN"), "hola" ) ); - BOOST_REQUIRE_EQUAL( success(), transfer( N(alice), N(bob), asset::from_string("200.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), transfer( "alice"_n, "bob"_n, asset::from_string("200.000 TKN"), "hola" ) ); //should fail to retire since tokens are not on the issuer's balance - BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( N(alice), asset::from_string("300.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( "alice"_n, asset::from_string("300.000 TKN"), "hola" ) ); //transfer tokens back - BOOST_REQUIRE_EQUAL( success(), transfer( N(bob), N(alice), asset::from_string("200.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), transfer( "bob"_n, "alice"_n, asset::from_string("200.000 TKN"), "hola" ) ); - BOOST_REQUIRE_EQUAL( success(), retire( N(alice), asset::from_string("300.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), retire( "alice"_n, asset::from_string("300.000 TKN"), "hola" ) ); stats = get_stats("3,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() ("supply", "0.000 TKN") ("max_supply", "1000.000 TKN") ("issuer", "alice") ); - alice_balance = get_account(N(alice), "3,TKN"); + alice_balance = get_account("alice"_n, "3,TKN"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "0.000 TKN") ); //trying to retire tokens with zero supply - BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( N(alice), asset::from_string("1.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( "alice"_n, asset::from_string("1.000 TKN"), "hola" ) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1000 CERO")); + auto token = create( "alice"_n, asset::from_string("1000 CERO")); produce_blocks(1); - issue( N(alice), asset::from_string("1000 CERO"), "hola" ); + issue( "alice"_n, asset::from_string("1000 CERO"), "hola" ); auto stats = get_stats("0,CERO"); REQUIRE_MATCHING_OBJECT( stats, mvo() @@ -314,21 +314,21 @@ BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { ("issuer", "alice") ); - auto alice_balance = get_account(N(alice), "0,CERO"); + auto alice_balance = get_account("alice"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "1000 CERO") ); - transfer( N(alice), N(bob), asset::from_string("300 CERO"), "hola" ); + transfer( "alice"_n, "bob"_n, asset::from_string("300 CERO"), "hola" ); - alice_balance = get_account(N(alice), "0,CERO"); + alice_balance = get_account("alice"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "700 CERO") ("frozen", 0) ("whitelist", 1) ); - auto bob_balance = get_account(N(bob), "0,CERO"); + auto bob_balance = get_account("bob"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( bob_balance, mvo() ("balance", "300 CERO") ("frozen", 0) @@ -336,11 +336,11 @@ BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "overdrawn balance" ), - transfer( N(alice), N(bob), asset::from_string("701 CERO"), "hola" ) + transfer( "alice"_n, "bob"_n, asset::from_string("701 CERO"), "hola" ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "must transfer positive quantity" ), - transfer( N(alice), N(bob), asset::from_string("-1000 CERO"), "hola" ) + transfer( "alice"_n, "bob"_n, asset::from_string("-1000 CERO"), "hola" ) ); @@ -348,75 +348,75 @@ BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { BOOST_FIXTURE_TEST_CASE( open_tests, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1000 CERO")); + auto token = create( "alice"_n, asset::from_string("1000 CERO")); - auto alice_balance = get_account(N(alice), "0,CERO"); + auto alice_balance = get_account("alice"_n, "0,CERO"); BOOST_REQUIRE_EQUAL(true, alice_balance.is_null() ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("tokens can only be issued to issuer account"), - push_action( N(alice), N(issue), mvo() + push_action( "alice"_n, "issue"_n, mvo() ( "to", "bob") ( "quantity", asset::from_string("1000 CERO") ) ( "memo", "") ) ); - BOOST_REQUIRE_EQUAL( success(), issue( N(alice), asset::from_string("1000 CERO"), "issue" ) ); + BOOST_REQUIRE_EQUAL( success(), issue( "alice"_n, asset::from_string("1000 CERO"), "issue" ) ); - alice_balance = get_account(N(alice), "0,CERO"); + alice_balance = get_account("alice"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "1000 CERO") ); - auto bob_balance = get_account(N(bob), "0,CERO"); + auto bob_balance = get_account("bob"_n, "0,CERO"); BOOST_REQUIRE_EQUAL(true, bob_balance.is_null() ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("owner account does not exist"), - open( N(nonexistent), "0,CERO", N(alice) ) ); + open( "nonexistent"_n, "0,CERO", "alice"_n ) ); BOOST_REQUIRE_EQUAL( success(), - open( N(bob), "0,CERO", N(alice) ) ); + open( "bob"_n, "0,CERO", "alice"_n ) ); - bob_balance = get_account(N(bob), "0,CERO"); + bob_balance = get_account("bob"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( bob_balance, mvo() ("balance", "0 CERO") ); - BOOST_REQUIRE_EQUAL( success(), transfer( N(alice), N(bob), asset::from_string("200 CERO"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), transfer( "alice"_n, "bob"_n, asset::from_string("200 CERO"), "hola" ) ); - bob_balance = get_account(N(bob), "0,CERO"); + bob_balance = get_account("bob"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( bob_balance, mvo() ("balance", "200 CERO") ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "symbol does not exist" ), - open( N(carol), "0,INVALID", N(alice) ) ); + open( "carol"_n, "0,INVALID", "alice"_n ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "symbol precision mismatch" ), - open( N(carol), "1,CERO", N(alice) ) ); + open( "carol"_n, "1,CERO", "alice"_n ) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( close_tests, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1000 CERO")); + auto token = create( "alice"_n, asset::from_string("1000 CERO")); - auto alice_balance = get_account(N(alice), "0,CERO"); + auto alice_balance = get_account("alice"_n, "0,CERO"); BOOST_REQUIRE_EQUAL(true, alice_balance.is_null() ); - BOOST_REQUIRE_EQUAL( success(), issue( N(alice), asset::from_string("1000 CERO"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), issue( "alice"_n, asset::from_string("1000 CERO"), "hola" ) ); - alice_balance = get_account(N(alice), "0,CERO"); + alice_balance = get_account("alice"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "1000 CERO") ); - BOOST_REQUIRE_EQUAL( success(), transfer( N(alice), N(bob), asset::from_string("1000 CERO"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), transfer( "alice"_n, "bob"_n, asset::from_string("1000 CERO"), "hola" ) ); - alice_balance = get_account(N(alice), "0,CERO"); + alice_balance = get_account("alice"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "0 CERO") ); - BOOST_REQUIRE_EQUAL( success(), close( N(alice), "0,CERO" ) ); - alice_balance = get_account(N(alice), "0,CERO"); + BOOST_REQUIRE_EQUAL( success(), close( "alice"_n, "0,CERO" ) ); + alice_balance = get_account("alice"_n, "0,CERO"); BOOST_REQUIRE_EQUAL(true, alice_balance.is_null() ); } FC_LOG_AND_RETHROW() -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/tests/eosio.wrap_tests.cpp b/tests/eosio.wrap_tests.cpp deleted file mode 100644 index 1f462bb8..00000000 --- a/tests/eosio.wrap_tests.cpp +++ /dev/null @@ -1,368 +0,0 @@ -#include -#include -#include - -#include - -#include - -#include "contracts.hpp" - -using namespace eosio::testing; -using namespace eosio; -using namespace eosio::chain; -using namespace eosio::testing; -using namespace fc; - -using mvo = fc::mutable_variant_object; - -class eosio_wrap_tester : public tester { -public: - - eosio_wrap_tester() { - create_accounts( { N(eosio.msig), N(prod1), N(prod2), N(prod3), N(prod4), N(prod5), N(alice), N(bob), N(carol) } ); - produce_block(); - - - base_tester::push_action(config::system_account_name, N(setpriv), - config::system_account_name, mutable_variant_object() - ("account", "eosio.msig") - ("is_priv", 1) - ); - - set_code( N(eosio.msig), contracts::msig_wasm() ); - set_abi( N(eosio.msig), contracts::msig_abi().data() ); - - produce_blocks(); - - signed_transaction trx; - set_transaction_headers(trx); - authority auth( 1, {}, {{{config::system_account_name, config::active_name}, 1}} ); - trx.actions.emplace_back( vector{{config::system_account_name, config::active_name}}, - newaccount{ - .creator = config::system_account_name, - .name = N(eosio.wrap), - .owner = auth, - .active = auth, - }); - - set_transaction_headers(trx); - trx.sign( get_private_key( config::system_account_name, "active" ), control->get_chain_id() ); - push_transaction( trx ); - - base_tester::push_action(config::system_account_name, N(setpriv), - config::system_account_name, mutable_variant_object() - ("account", "eosio.wrap") - ("is_priv", 1) - ); - - auto system_private_key = get_private_key( config::system_account_name, "active" ); - set_code( N(eosio.wrap), contracts::wrap_wasm(), &system_private_key ); - set_abi( N(eosio.wrap), contracts::wrap_abi().data(), &system_private_key ); - - produce_blocks(); - - set_authority( config::system_account_name, config::active_name, - authority( 1, {{get_public_key( config::system_account_name, "active" ), 1}}, - {{{config::producers_account_name, config::active_name}, 1}} ), - config::owner_name, - { { config::system_account_name, config::owner_name } }, - { get_private_key( config::system_account_name, "active" ) } - ); - - set_producers( {N(prod1), N(prod2), N(prod3), N(prod4), N(prod5)} ); - - produce_blocks(); - - const auto& accnt = control->db().get( N(eosio.wrap) ); - abi_def abi; - BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); - - while( control->pending_block_producer().to_string() == "eosio" ) { - produce_block(); - } - } - - void propose( name proposer, name proposal_name, vector requested_permissions, const transaction& trx ) { - push_action( N(eosio.msig), N(propose), proposer, mvo() - ("proposer", proposer) - ("proposal_name", proposal_name) - ("requested", requested_permissions) - ("trx", trx) - ); - } - - void approve( name proposer, name proposal_name, name approver ) { - push_action( N(eosio.msig), N(approve), approver, mvo() - ("proposer", proposer) - ("proposal_name", proposal_name) - ("level", permission_level{approver, config::active_name} ) - ); - } - - void unapprove( name proposer, name proposal_name, name unapprover ) { - push_action( N(eosio.msig), N(unapprove), unapprover, mvo() - ("proposer", proposer) - ("proposal_name", proposal_name) - ("level", permission_level{unapprover, config::active_name}) - ); - } - - transaction wrap_exec( account_name executer, const transaction& trx, uint32_t expiration = base_tester::DEFAULT_EXPIRATION_DELTA ); - - transaction reqauth( account_name from, const vector& auths, uint32_t expiration = base_tester::DEFAULT_EXPIRATION_DELTA ); - - abi_serializer abi_ser; -}; - -transaction eosio_wrap_tester::wrap_exec( account_name executer, const transaction& trx, uint32_t expiration ) { - fc::variants v; - v.push_back( fc::mutable_variant_object() - ("actor", executer) - ("permission", name{config::active_name}) - ); - v.push_back( fc::mutable_variant_object() - ("actor", "eosio.wrap") - ("permission", name{config::active_name}) - ); - auto act_obj = fc::mutable_variant_object() - ("account", "eosio.wrap") - ("name", "exec") - ("authorization", v) - ("data", fc::mutable_variant_object()("executer", executer)("trx", trx) ); - transaction trx2; - set_transaction_headers(trx2, expiration); - action act; - abi_serializer::from_variant( act_obj, act, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time) ); - trx2.actions.push_back( std::move(act) ); - return trx2; -} - -transaction eosio_wrap_tester::reqauth( account_name from, const vector& auths, uint32_t expiration ) { - fc::variants v; - for ( auto& level : auths ) { - v.push_back(fc::mutable_variant_object() - ("actor", level.actor) - ("permission", level.permission) - ); - } - auto act_obj = fc::mutable_variant_object() - ("account", name{config::system_account_name}) - ("name", "reqauth") - ("authorization", v) - ("data", fc::mutable_variant_object() ("from", from) ); - transaction trx; - set_transaction_headers(trx, expiration); - action act; - abi_serializer::from_variant( act_obj, act, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time) ); - trx.actions.push_back( std::move(act) ); - return trx; -} - -BOOST_AUTO_TEST_SUITE(eosio_wrap_tests) - -BOOST_FIXTURE_TEST_CASE( wrap_exec_direct, eosio_wrap_tester ) try { - auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - { - signed_transaction wrap_trx( wrap_exec( N(alice), trx ), {}, {} ); - /* - set_transaction_headers( wrap_trx ); - wrap_trx.actions.emplace_back( get_action( N(eosio.wrap), N(exec), - {{N(alice), config::active_name}, {N(eosio.wrap), config::active_name}}, - mvo() - ("executer", "alice") - ("trx", trx) - ) ); - */ - wrap_trx.sign( get_private_key( N(alice), "active" ), control->get_chain_id() ); - for( const auto& actor : {N(prod1), N(prod2), N(prod3), N(prod4)} ) { - wrap_trx.sign( get_private_key( actor, "active" ), control->get_chain_id() ); - } - push_transaction( wrap_trx ); - } - - produce_block(); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( config::system_account_name, name{trace->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( N(reqauth), name{trace->action_traces[0].act.name} ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( wrap_with_msig, eosio_wrap_tester ) try { - auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); - auto wrap_trx = wrap_exec( N(alice), trx ); - - propose( N(carol), N(first), - { {N(alice), N(active)}, - {N(prod1), N(active)}, {N(prod2), N(active)}, {N(prod3), N(active)}, {N(prod4), N(active)}, {N(prod5), N(active)} }, - wrap_trx ); - - approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the wrap::exec action - - // More than 2/3 of block producers approve - approve( N(carol), N(first), N(prod1) ); - approve( N(carol), N(first), N(prod2) ); - approve( N(carol), N(first), N(prod3) ); - approve( N(carol), N(first), N(prod4) ); - - vector traces; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { - traces.push_back( t ); - } - } ); - - // Now the proposal should be ready to execute - push_action( N(eosio.msig), N(exec), N(alice), mvo() - ("proposer", "carol") - ("proposal_name", "first") - ("executer", "alice") - ); - - produce_block(); - - BOOST_REQUIRE_EQUAL( 2, traces.size() ); - - BOOST_REQUIRE_EQUAL( 1, traces[0]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( N(eosio.wrap), name{traces[0]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( N(exec), name{traces[0]->action_traces[0].act.name} ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[0]->receipt->status ); - - BOOST_REQUIRE_EQUAL( 1, traces[1]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( config::system_account_name, name{traces[1]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( N(reqauth), name{traces[1]->action_traces[0].act.name} ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[1]->receipt->status ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( wrap_with_msig_unapprove, eosio_wrap_tester ) try { - auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); - auto wrap_trx = wrap_exec( N(alice), trx ); - - propose( N(carol), N(first), - { {N(alice), N(active)}, - {N(prod1), N(active)}, {N(prod2), N(active)}, {N(prod3), N(active)}, {N(prod4), N(active)}, {N(prod5), N(active)} }, - wrap_trx ); - - approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the wrap::exec action - - // 3 of the 4 needed producers approve - approve( N(carol), N(first), N(prod1) ); - approve( N(carol), N(first), N(prod2) ); - approve( N(carol), N(first), N(prod3) ); - - // first producer takes back approval - unapprove( N(carol), N(first), N(prod1) ); - - // fourth producer approves but the total number of approving producers is still 3 which is less than two-thirds of producers - approve( N(carol), N(first), N(prod4) ); - - produce_block(); - - // The proposal should not have sufficient approvals to pass the authorization checks of eosio.wrap::exec. - BOOST_REQUIRE_EXCEPTION( push_action( N(eosio.msig), N(exec), N(alice), mvo() - ("proposer", "carol") - ("proposal_name", "first") - ("executer", "alice") - ), eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( wrap_with_msig_producers_change, eosio_wrap_tester ) try { - create_accounts( { N(newprod1) } ); - - auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); - auto wrap_trx = wrap_exec( N(alice), trx, 36000 ); - - propose( N(carol), N(first), - { {N(alice), N(active)}, - {N(prod1), N(active)}, {N(prod2), N(active)}, {N(prod3), N(active)}, {N(prod4), N(active)}, {N(prod5), N(active)} }, - wrap_trx ); - - approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the wrap::exec action - - // 2 of the 4 needed producers approve - approve( N(carol), N(first), N(prod1) ); - approve( N(carol), N(first), N(prod2) ); - - produce_block(); - - set_producers( {N(prod1), N(prod2), N(prod3), N(prod4), N(prod5), N(newprod1)} ); // With 6 producers, the 2/3+1 threshold becomes 5 - - while( control->active_producers().producers.size() != 6 ) { - produce_block(); - } - - // Now two more block producers approve which would have been sufficient under the old schedule but not the new one. - approve( N(carol), N(first), N(prod3) ); - approve( N(carol), N(first), N(prod4) ); - - produce_block(); - - // The proposal has four of the five requested approvals but they are not sufficient to satisfy the authorization checks of eosio.wrap::exec. - BOOST_REQUIRE_EXCEPTION( push_action( N(eosio.msig), N(exec), N(alice), mvo() - ("proposer", "carol") - ("proposal_name", "first") - ("executer", "alice") - ), eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - - // Unfortunately the new producer cannot approve because they were not in the original requested approvals. - BOOST_REQUIRE_EXCEPTION( approve( N(carol), N(first), N(newprod1) ), - eosio_assert_message_exception, - eosio_assert_message_is("approval is not on the list of requested approvals") - ); - - // But prod5 still can provide the fifth approval necessary to satisfy the 2/3+1 threshold of the new producer set - approve( N(carol), N(first), N(prod5) ); - - vector traces; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { - traces.push_back( t ); - } - } ); - - // Now the proposal should be ready to execute - push_action( N(eosio.msig), N(exec), N(alice), mvo() - ("proposer", "carol") - ("proposal_name", "first") - ("executer", "alice") - ); - - produce_block(); - - BOOST_REQUIRE_EQUAL( 2, traces.size() ); - - BOOST_REQUIRE_EQUAL( 1, traces[0]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( N(eosio.wrap), name{traces[0]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( N(exec), name{traces[0]->action_traces[0].act.name} ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[0]->receipt->status ); - - BOOST_REQUIRE_EQUAL( 1, traces[1]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( config::system_account_name, name{traces[1]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( N(reqauth), name{traces[1]->action_traces[0].act.name} ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[1]->receipt->status ); - -} FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/main.cpp b/tests/main.cpp index e3d61750..f1f23ace 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -10,9 +10,7 @@ #include #include -#include "eosio.system_tester.hpp" - -using namespace eosio_system; +// using namespace eosio_system; #define BOOST_TEST_STATIC_LINK void translate_fc_exception(const fc::exception &e) { diff --git a/tests/test_contracts/exchange.wasm b/tests/test_contracts/exchange.wasm deleted file mode 100644 index 8880a905..00000000 Binary files a/tests/test_contracts/exchange.wasm and /dev/null differ diff --git a/tests/test_contracts/old_versions/v1.2.1/eosio.msig/Readme.txt b/tests/test_contracts/old_versions/v1.2.1/eosio.msig/Readme.txt deleted file mode 100644 index c229cbe6..00000000 --- a/tests/test_contracts/old_versions/v1.2.1/eosio.msig/Readme.txt +++ /dev/null @@ -1,3 +0,0 @@ -Compiled with -eosio.contracts: ee6415b0d3f9cff3bafebf98b2e06b80545dfa36 -eosio.wasmsdk: 0d4befeee7abbef1db775b2e8833f7db8fca7ad2 (v1.1.1), CORE_SYMBOL_NAME = "SYS" diff --git a/tests/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.abi b/tests/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.abi deleted file mode 100644 index 9fcf8a95..00000000 --- a/tests/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.abi +++ /dev/null @@ -1,152 +0,0 @@ -{ - "version": "eosio::abi/1.0", - "types": [{ - "new_type_name": "account_name", - "type": "name" - },{ - "new_type_name": "permission_name", - "type": "name" - },{ - "new_type_name": "action_name", - "type": "name" - }], - "structs": [{ - "name": "permission_level", - "base": "", - "fields": [ - {"name": "actor", "type": "account_name"}, - {"name": "permission", "type": "permission_name"} - ] - },{ - "name": "action", - "base": "", - "fields": [ - {"name": "account", "type": "account_name"}, - {"name": "name", "type": "action_name"}, - {"name": "authorization", "type": "permission_level[]"}, - {"name": "data", "type": "bytes"} - ] - },{ - "name": "transaction_header", - "base": "", - "fields": [ - {"name": "expiration", "type": "time_point_sec"}, - {"name": "ref_block_num", "type": "uint16"}, - {"name": "ref_block_prefix", "type": "uint32"}, - {"name": "max_net_usage_words", "type": "varuint32"}, - {"name": "max_cpu_usage_ms", "type": "uint8"}, - {"name": "delay_sec", "type": "varuint32"} - ] - },{ - "name": "extension", - "base": "", - "fields": [ - {"name": "type", "type" : "uint16" }, - {"name": "data", "type": "bytes"} - ] - },{ - "name": "transaction", - "base": "transaction_header", - "fields": [ - {"name": "context_free_actions", "type": "action[]"}, - {"name": "actions", "type": "action[]"}, - {"name": "transaction_extensions", "type": "extension[]"} - ] - },{ - "name": "propose", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"requested", "type":"permission_level[]"}, - {"name":"trx", "type":"transaction"} - ] - },{ - "name": "approve", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"level", "type":"permission_level"} - ] - },{ - "name": "unapprove", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"level", "type":"permission_level"} - ] - },{ - "name": "cancel", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"canceler", "type":"account_name"} - ] - },{ - "name": "exec", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"executer", "type":"account_name"} - ] - },{ - "name": "proposal", - "base": "", - "fields": [ - {"name": "proposal_name", "type": "name"}, - {"name": "packed_transaction", "type": "bytes"} - ] - },{ - "name": "approvals_info", - "base": "", - "fields": [ - {"name": "proposal_name", "type": "name"}, - {"name": "requested_approvals", "type": "permission_level[]"}, - {"name": "provided_approvals", "type": "permission_level[]"} - ] - } - ], - "actions": [{ - "name": "propose", - "type": "propose", - "ricardian_contract": "" - },{ - "name": "approve", - "type": "approve", - "ricardian_contract": "" - },{ - "name": "unapprove", - "type": "unapprove", - "ricardian_contract": "" - }, { - "name": "cancel", - "type": "cancel", - "ricardian_contract": "" - }, { - "name": "exec", - "type": "exec", - "ricardian_contract": "" - } - - ], - "tables": [{ - "name": "proposal", - "type": "proposal", - "index_type": "i64", - "key_names" : ["proposal_name"], - "key_types" : ["name"] - },{ - "name": "approvals", - "type": "approvals_info", - "index_type": "i64", - "key_names" : ["proposal_name"], - "key_types" : ["name"] - } - ], - "ricardian_clauses": [], - "abi_extensions": [] -} diff --git a/tests/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.wasm b/tests/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.wasm deleted file mode 100755 index 4c077557..00000000 Binary files a/tests/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.wasm and /dev/null differ diff --git a/tests/test_contracts/old_versions/v1.2.1/eosio.system/README.txt b/tests/test_contracts/old_versions/v1.2.1/eosio.system/README.txt deleted file mode 100644 index a9aa16fb..00000000 --- a/tests/test_contracts/old_versions/v1.2.1/eosio.system/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -Compiled with -eosio.contracts: bf28f8bbf9ee753966c95c586906e82d72f9dfac (v1.2.1) -eosio.wasmsdk: 2c106a018f2e69d34325ef2376cf085426068e93, CORE_SYMBOL_NAME = "SYS" diff --git a/tests/test_contracts/old_versions/v1.2.1/eosio.system/Readme.txt b/tests/test_contracts/old_versions/v1.2.1/eosio.system/Readme.txt deleted file mode 100644 index a9aa16fb..00000000 --- a/tests/test_contracts/old_versions/v1.2.1/eosio.system/Readme.txt +++ /dev/null @@ -1,3 +0,0 @@ -Compiled with -eosio.contracts: bf28f8bbf9ee753966c95c586906e82d72f9dfac (v1.2.1) -eosio.wasmsdk: 2c106a018f2e69d34325ef2376cf085426068e93, CORE_SYMBOL_NAME = "SYS" diff --git a/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.abi b/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.abi deleted file mode 100644 index 5445473a..00000000 --- a/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.abi +++ /dev/null @@ -1,626 +0,0 @@ -{ - "version": "eosio::abi/1.0", - "types": [{ - "new_type_name": "account_name", - "type": "name" - },{ - "new_type_name": "permission_name", - "type": "name" - },{ - "new_type_name": "action_name", - "type": "name" - },{ - "new_type_name": "transaction_id_type", - "type": "checksum256" - },{ - "new_type_name": "weight_type", - "type": "uint16" - }], - "____comment": "eosio.bios structs: set_account_limits, setpriv, set_global_limits, producer_key, set_producers, require_auth are provided so abi available for deserialization in future.", - "structs": [{ - "name": "permission_level", - "base": "", - "fields": [ - {"name":"actor", "type":"account_name"}, - {"name":"permission", "type":"permission_name"} - ] - },{ - "name": "key_weight", - "base": "", - "fields": [ - {"name":"key", "type":"public_key"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "bidname", - "base": "", - "fields": [ - {"name":"bidder", "type":"account_name"}, - {"name":"newname", "type":"account_name"}, - {"name":"bid", "type":"asset"} - ] - },{ - "name": "bidrefund", - "base": "", - "fields": [ - {"name":"bidder", "type":"account_name"}, - {"name":"newname", "type":"account_name"} - ] - },{ - "name": "permission_level_weight", - "base": "", - "fields": [ - {"name":"permission", "type":"permission_level"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "wait_weight", - "base": "", - "fields": [ - {"name":"wait_sec", "type":"uint32"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "authority", - "base": "", - "fields": [ - {"name":"threshold", "type":"uint32"}, - {"name":"keys", "type":"key_weight[]"}, - {"name":"accounts", "type":"permission_level_weight[]"}, - {"name":"waits", "type":"wait_weight[]"} - ] - },{ - "name": "newaccount", - "base": "", - "fields": [ - {"name":"creator", "type":"account_name"}, - {"name":"name", "type":"account_name"}, - {"name":"owner", "type":"authority"}, - {"name":"active", "type":"authority"} - ] - },{ - "name": "setcode", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"vmtype", "type":"uint8"}, - {"name":"vmversion", "type":"uint8"}, - {"name":"code", "type":"bytes"} - ] - },{ - "name": "setabi", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"abi", "type":"bytes"} - ] - },{ - "name": "updateauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"permission", "type":"permission_name"}, - {"name":"parent", "type":"permission_name"}, - {"name":"auth", "type":"authority"} - ] - },{ - "name": "deleteauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"permission", "type":"permission_name"} - ] - },{ - "name": "linkauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"code", "type":"account_name"}, - {"name":"type", "type":"action_name"}, - {"name":"requirement", "type":"permission_name"} - ] - },{ - "name": "unlinkauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"code", "type":"account_name"}, - {"name":"type", "type":"action_name"} - ] - },{ - "name": "canceldelay", - "base": "", - "fields": [ - {"name":"canceling_auth", "type":"permission_level"}, - {"name":"trx_id", "type":"transaction_id_type"} - ] - },{ - "name": "onerror", - "base": "", - "fields": [ - {"name":"sender_id", "type":"uint128"}, - {"name":"sent_trx", "type":"bytes"} - ] - },{ - "name": "buyrambytes", - "base": "", - "fields": [ - {"name":"payer", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"bytes", "type":"uint32"} - ] - },{ - "name": "sellram", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"bytes", "type":"uint64"} - ] - },{ - "name": "buyram", - "base": "", - "fields": [ - {"name":"payer", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"quant", "type":"asset"} - ] - },{ - "name": "delegatebw", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"stake_net_quantity", "type":"asset"}, - {"name":"stake_cpu_quantity", "type":"asset"}, - {"name":"transfer", "type":"bool"} - ] - },{ - "name": "undelegatebw", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"unstake_net_quantity", "type":"asset"}, - {"name":"unstake_cpu_quantity", "type":"asset"} - ] - },{ - "name": "refund", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"} - ] - },{ - "name": "delegated_bandwidth", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"to", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"} - ] - },{ - "name": "user_resources", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"}, - {"name":"ram_bytes", "type":"uint64"} - ] - },{ - "name": "total_resources", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"}, - {"name":"ram_bytes", "type":"uint64"} - ] - },{ - "name": "refund_request", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"request_time", "type":"time_point_sec"}, - {"name":"net_amount", "type":"asset"}, - {"name":"cpu_amount", "type":"asset"} - ] - },{ - "name": "blockchain_parameters", - "base": "", - "fields": [ - - {"name":"max_block_net_usage", "type":"uint64"}, - {"name":"target_block_net_usage_pct", "type":"uint32"}, - {"name":"max_transaction_net_usage", "type":"uint32"}, - {"name":"base_per_transaction_net_usage", "type":"uint32"}, - {"name":"net_usage_leeway", "type":"uint32"}, - {"name":"context_free_discount_net_usage_num", "type":"uint32"}, - {"name":"context_free_discount_net_usage_den", "type":"uint32"}, - {"name":"max_block_cpu_usage", "type":"uint32"}, - {"name":"target_block_cpu_usage_pct", "type":"uint32"}, - {"name":"max_transaction_cpu_usage", "type":"uint32"}, - {"name":"min_transaction_cpu_usage", "type":"uint32"}, - {"name":"max_transaction_lifetime", "type":"uint32"}, - {"name":"deferred_trx_expiration_window", "type":"uint32"}, - {"name":"max_transaction_delay", "type":"uint32"}, - {"name":"max_inline_action_size", "type":"uint32"}, - {"name":"max_inline_action_depth", "type":"uint16"}, - {"name":"max_authority_depth", "type":"uint16"} - ] - },{ - "name": "eosio_global_state2", - "fields": [ - {"name":"new_ram_per_block", "type":"uint16"}, - {"name":"last_ram_increase", "type":"block_timestamp_type"}, - {"name":"last_block_num", "type":"block_timestamp_type"}, - {"name":"reserved", "type":"float64"}, - {"name":"revision", "type":"uint8"} - ] - },{ - "name": "eosio_global_state", - "base": "blockchain_parameters", - "fields": [ - {"name":"max_ram_size", "type":"uint64"}, - {"name":"total_ram_bytes_reserved", "type":"uint64"}, - {"name":"total_ram_stake", "type":"int64"}, - {"name":"last_producer_schedule_update", "type":"block_timestamp_type"}, - {"name":"last_pervote_bucket_fill", "type":"uint64"}, - {"name":"pervote_bucket", "type":"int64"}, - {"name":"perblock_bucket", "type":"int64"}, - {"name":"total_unpaid_blocks", "type":"uint32"}, - {"name":"total_activated_stake", "type":"int64"}, - {"name":"thresh_activated_stake_time", "type":"uint64"}, - {"name":"last_producer_schedule_size", "type":"uint16"}, - {"name":"total_producer_vote_weight", "type":"float64"}, - {"name":"last_name_close", "type":"block_timestamp_type"} - ] - },{ - "name": "producer_info", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"total_votes", "type":"float64"}, - {"name":"producer_key", "type":"public_key"}, - {"name":"is_active", "type":"bool"}, - {"name":"url", "type":"string"}, - {"name":"unpaid_blocks", "type":"uint32"}, - {"name":"last_claim_time", "type":"uint64"}, - {"name":"location", "type":"uint16"} - ] - },{ - "name": "regproducer", - "base": "", - "fields": [ - {"name":"producer", "type":"account_name"}, - {"name":"producer_key", "type":"public_key"}, - {"name":"url", "type":"string"}, - {"name":"location", "type":"uint16"} - ] - },{ - "name": "unregprod", - "base": "", - "fields": [ - {"name":"producer", "type":"account_name"} - ] - },{ - "name": "setram", - "base": "", - "fields": [ - {"name":"max_ram_size", "type":"uint64"} - ] - },{ - "name": "setramrate", - "base": "", - "fields": [ - {"name":"bytes_per_block", "type":"uint16"} - ] - },{ - "name": "regproxy", - "base": "", - "fields": [ - {"name":"proxy", "type":"account_name"}, - {"name":"isproxy", "type":"bool"} - ] - },{ - "name": "voteproducer", - "base": "", - "fields": [ - {"name":"voter", "type":"account_name"}, - {"name":"proxy", "type":"account_name"}, - {"name":"producers", "type":"account_name[]"} - ] - },{ - "name": "voter_info", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"proxy", "type":"account_name"}, - {"name":"producers", "type":"account_name[]"}, - {"name":"staked", "type":"int64"}, - {"name":"last_vote_weight", "type":"float64"}, - {"name":"proxied_vote_weight", "type":"float64"}, - {"name":"is_proxy", "type":"bool"} - ] - },{ - "name": "claimrewards", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"} - ] - },{ - "name": "setpriv", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"is_priv", "type":"int8"} - ] - },{ - "name": "rmvproducer", - "base": "", - "fields": [ - {"name":"producer", "type":"account_name"} - ] - },{ - "name": "set_account_limits", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"ram_bytes", "type":"int64"}, - {"name":"net_weight", "type":"int64"}, - {"name":"cpu_weight", "type":"int64"} - ] - },{ - "name": "set_global_limits", - "base": "", - "fields": [ - {"name":"cpu_usec_per_period", "type":"int64"} - ] - },{ - "name": "producer_key", - "base": "", - "fields": [ - {"name":"producer_name", "type":"account_name"}, - {"name":"block_signing_key", "type":"public_key"} - ] - },{ - "name": "set_producers", - "base": "", - "fields": [ - {"name":"schedule", "type":"producer_key[]"} - ] - },{ - "name": "require_auth", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"} - ] - },{ - "name": "setparams", - "base": "", - "fields": [ - {"name":"params", "type":"blockchain_parameters"} - ] - },{ - "name": "connector", - "base": "", - "fields": [ - {"name":"balance", "type":"asset"}, - {"name":"weight", "type":"float64"} - ] - },{ - "name": "exchange_state", - "base": "", - "fields": [ - {"name":"supply", "type":"asset"}, - {"name":"base", "type":"connector"}, - {"name":"quote", "type":"connector"} - ] - }, { - "name": "name_bid", - "base": "", - "fields": [ - {"name":"newname", "type":"account_name"}, - {"name":"high_bidder", "type":"account_name"}, - {"name":"high_bid", "type":"int64"}, - {"name":"last_bid_time", "type":"uint64"} - ] - }, { - "name": "bid_refund", - "base": "", - "fields": [ - {"name":"bidder", "type":"account_name"}, - {"name":"amount", "type":"asset"} - ] - } - ], - "actions": [{ - "name": "newaccount", - "type": "newaccount", - "ricardian_contract": "" - },{ - "name": "setcode", - "type": "setcode", - "ricardian_contract": "" - },{ - "name": "setabi", - "type": "setabi", - "ricardian_contract": "" - },{ - "name": "updateauth", - "type": "updateauth", - "ricardian_contract": "" - },{ - "name": "deleteauth", - "type": "deleteauth", - "ricardian_contract": "" - },{ - "name": "linkauth", - "type": "linkauth", - "ricardian_contract": "" - },{ - "name": "unlinkauth", - "type": "unlinkauth", - "ricardian_contract": "" - },{ - "name": "canceldelay", - "type": "canceldelay", - "ricardian_contract": "" - },{ - "name": "onerror", - "type": "onerror", - "ricardian_contract": "" - },{ - "name": "buyrambytes", - "type": "buyrambytes", - "ricardian_contract": "" - },{ - "name": "buyram", - "type": "buyram", - "ricardian_contract": "" - },{ - "name": "sellram", - "type": "sellram", - "ricardian_contract": "" - },{ - "name": "delegatebw", - "type": "delegatebw", - "ricardian_contract": "" - },{ - "name": "undelegatebw", - "type": "undelegatebw", - "ricardian_contract": "" - },{ - "name": "refund", - "type": "refund", - "ricardian_contract": "" - },{ - "name": "regproducer", - "type": "regproducer", - "ricardian_contract": "" - },{ - "name": "setram", - "type": "setram", - "ricardian_contract": "" - },{ - "name": "setramrate", - "type": "setramrate", - "ricardian_contract": "Sets the number of new bytes of ram to create per block and resyncs bancor base connector balance" - },{ - "name": "bidname", - "type": "bidname", - "ricardian_contract": "" - },{ - "name": "bidrefund", - "type": "bidrefund", - "ricardian_contract": "" - },{ - "name": "unregprod", - "type": "unregprod", - "ricardian_contract": "" - },{ - "name": "regproxy", - "type": "regproxy", - "ricardian_contract": "" - },{ - "name": "voteproducer", - "type": "voteproducer", - "ricardian_contract": "" - },{ - "name": "claimrewards", - "type": "claimrewards", - "ricardian_contract": "" - },{ - "name": "setpriv", - "type": "setpriv", - "ricardian_contract": "" - },{ - "name": "rmvproducer", - "type": "rmvproducer", - "ricardian_contract": "" - },{ - "name": "setalimits", - "type": "set_account_limits", - "ricardian_contract": "" - },{ - "name": "setglimits", - "type": "set_global_limits", - "ricardian_contract": "" - },{ - "name": "setprods", - "type": "set_producers", - "ricardian_contract": "" - },{ - "name": "reqauth", - "type": "require_auth", - "ricardian_contract": "" - },{ - "name": "setparams", - "type": "setparams", - "ricardian_contract": "" - }], - "tables": [{ - "name": "producers", - "type": "producer_info", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "global", - "type": "eosio_global_state", - "index_type": "i64", - "key_names" : [], - "key_types" : [] - },{ - "name": "global2", - "type": "eosio_global_state2", - "index_type": "i64", - "key_names" : [], - "key_types" : [] - },{ - "name": "voters", - "type": "voter_info", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["account_name"] - },{ - "name": "userres", - "type": "user_resources", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "delband", - "type": "delegated_bandwidth", - "index_type": "i64", - "key_names" : ["to"], - "key_types" : ["uint64"] - },{ - "name": "rammarket", - "type": "exchange_state", - "index_type": "i64", - "key_names" : ["supply"], - "key_types" : ["uint64"] - },{ - "name": "refunds", - "type": "refund_request", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "namebids", - "type": "name_bid", - "index_type": "i64", - "key_names" : ["newname"], - "key_types" : ["account_name"] - },{ - "name": "bidrefunds", - "type": "bid_refund", - "index_type": "i64", - "key_names" : ["bidder"], - "key_types" : ["account_name"] - } - ], - "ricardian_clauses": [], - "abi_extensions": [] -} diff --git a/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.wasm b/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.wasm deleted file mode 100755 index 91260475..00000000 Binary files a/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.wasm and /dev/null differ diff --git a/tests/test_contracts/old_versions/v1.8.3/eosio.system/README.txt b/tests/test_contracts/old_versions/v1.8.3/eosio.system/README.txt deleted file mode 100644 index 61c7b168..00000000 --- a/tests/test_contracts/old_versions/v1.8.3/eosio.system/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -Compiled with -eosio.contracts: 7109f002fa9afff18edcafce5c32b224a21eef98 (v1.8.3) -eosio.cdt: 263e41cbb3e58dca71117401f43be104f1e58ae4 (v1.6.3) diff --git a/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.abi b/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.abi deleted file mode 100644 index 65afebad..00000000 --- a/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.abi +++ /dev/null @@ -1,2097 +0,0 @@ -{ - "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ", - "version": "eosio::abi/1.1", - "types": [], - "structs": [ - { - "name": "abi_hash", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "hash", - "type": "checksum256" - } - ] - }, - { - "name": "activate", - "base": "", - "fields": [ - { - "name": "feature_digest", - "type": "checksum256" - } - ] - }, - { - "name": "authority", - "base": "", - "fields": [ - { - "name": "threshold", - "type": "uint32" - }, - { - "name": "keys", - "type": "key_weight[]" - }, - { - "name": "accounts", - "type": "permission_level_weight[]" - }, - { - "name": "waits", - "type": "wait_weight[]" - } - ] - }, - { - "name": "bid_refund", - "base": "", - "fields": [ - { - "name": "bidder", - "type": "name" - }, - { - "name": "amount", - "type": "asset" - } - ] - }, - { - "name": "bidname", - "base": "", - "fields": [ - { - "name": "bidder", - "type": "name" - }, - { - "name": "newname", - "type": "name" - }, - { - "name": "bid", - "type": "asset" - } - ] - }, - { - "name": "bidrefund", - "base": "", - "fields": [ - { - "name": "bidder", - "type": "name" - }, - { - "name": "newname", - "type": "name" - } - ] - }, - { - "name": "block_header", - "base": "", - "fields": [ - { - "name": "timestamp", - "type": "uint32" - }, - { - "name": "producer", - "type": "name" - }, - { - "name": "confirmed", - "type": "uint16" - }, - { - "name": "previous", - "type": "checksum256" - }, - { - "name": "transaction_mroot", - "type": "checksum256" - }, - { - "name": "action_mroot", - "type": "checksum256" - }, - { - "name": "schedule_version", - "type": "uint32" - }, - { - "name": "new_producers", - "type": "producer_schedule?" - } - ] - }, - { - "name": "blockchain_parameters", - "base": "", - "fields": [ - { - "name": "max_block_net_usage", - "type": "uint64" - }, - { - "name": "target_block_net_usage_pct", - "type": "uint32" - }, - { - "name": "max_transaction_net_usage", - "type": "uint32" - }, - { - "name": "base_per_transaction_net_usage", - "type": "uint32" - }, - { - "name": "net_usage_leeway", - "type": "uint32" - }, - { - "name": "context_free_discount_net_usage_num", - "type": "uint32" - }, - { - "name": "context_free_discount_net_usage_den", - "type": "uint32" - }, - { - "name": "max_block_cpu_usage", - "type": "uint32" - }, - { - "name": "target_block_cpu_usage_pct", - "type": "uint32" - }, - { - "name": "max_transaction_cpu_usage", - "type": "uint32" - }, - { - "name": "min_transaction_cpu_usage", - "type": "uint32" - }, - { - "name": "max_transaction_lifetime", - "type": "uint32" - }, - { - "name": "deferred_trx_expiration_window", - "type": "uint32" - }, - { - "name": "max_transaction_delay", - "type": "uint32" - }, - { - "name": "max_inline_action_size", - "type": "uint32" - }, - { - "name": "max_inline_action_depth", - "type": "uint16" - }, - { - "name": "max_authority_depth", - "type": "uint16" - } - ] - }, - { - "name": "buyram", - "base": "", - "fields": [ - { - "name": "payer", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "quant", - "type": "asset" - } - ] - }, - { - "name": "buyrambytes", - "base": "", - "fields": [ - { - "name": "payer", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "bytes", - "type": "uint32" - } - ] - }, - { - "name": "buyrex", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "amount", - "type": "asset" - } - ] - }, - { - "name": "canceldelay", - "base": "", - "fields": [ - { - "name": "canceling_auth", - "type": "permission_level" - }, - { - "name": "trx_id", - "type": "checksum256" - } - ] - }, - { - "name": "claimrewards", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - } - ] - }, - { - "name": "closerex", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - } - ] - }, - { - "name": "cnclrexorder", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - } - ] - }, - { - "name": "connector", - "base": "", - "fields": [ - { - "name": "balance", - "type": "asset" - }, - { - "name": "weight", - "type": "float64" - } - ] - }, - { - "name": "consolidate", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - } - ] - }, - { - "name": "defcpuloan", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "loan_num", - "type": "uint64" - }, - { - "name": "amount", - "type": "asset" - } - ] - }, - { - "name": "defnetloan", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "loan_num", - "type": "uint64" - }, - { - "name": "amount", - "type": "asset" - } - ] - }, - { - "name": "delegatebw", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "stake_net_quantity", - "type": "asset" - }, - { - "name": "stake_cpu_quantity", - "type": "asset" - }, - { - "name": "transfer", - "type": "bool" - } - ] - }, - { - "name": "delegated_bandwidth", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "to", - "type": "name" - }, - { - "name": "net_weight", - "type": "asset" - }, - { - "name": "cpu_weight", - "type": "asset" - } - ] - }, - { - "name": "deleteauth", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "permission", - "type": "name" - } - ] - }, - { - "name": "deposit", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "amount", - "type": "asset" - } - ] - }, - { - "name": "eosio_global_state", - "base": "blockchain_parameters", - "fields": [ - { - "name": "max_ram_size", - "type": "uint64" - }, - { - "name": "total_ram_bytes_reserved", - "type": "uint64" - }, - { - "name": "total_ram_stake", - "type": "int64" - }, - { - "name": "last_producer_schedule_update", - "type": "block_timestamp_type" - }, - { - "name": "last_pervote_bucket_fill", - "type": "time_point" - }, - { - "name": "pervote_bucket", - "type": "int64" - }, - { - "name": "perblock_bucket", - "type": "int64" - }, - { - "name": "total_unpaid_blocks", - "type": "uint32" - }, - { - "name": "total_activated_stake", - "type": "int64" - }, - { - "name": "thresh_activated_stake_time", - "type": "time_point" - }, - { - "name": "last_producer_schedule_size", - "type": "uint16" - }, - { - "name": "total_producer_vote_weight", - "type": "float64" - }, - { - "name": "last_name_close", - "type": "block_timestamp_type" - } - ] - }, - { - "name": "eosio_global_state2", - "base": "", - "fields": [ - { - "name": "new_ram_per_block", - "type": "uint16" - }, - { - "name": "last_ram_increase", - "type": "block_timestamp_type" - }, - { - "name": "last_block_num", - "type": "block_timestamp_type" - }, - { - "name": "total_producer_votepay_share", - "type": "float64" - }, - { - "name": "revision", - "type": "uint8" - } - ] - }, - { - "name": "eosio_global_state3", - "base": "", - "fields": [ - { - "name": "last_vpay_state_update", - "type": "time_point" - }, - { - "name": "total_vpay_share_change_rate", - "type": "float64" - } - ] - }, - { - "name": "eosio_global_state4", - "base": "", - "fields": [ - { - "name": "continuous_rate", - "type": "float64" - }, - { - "name": "inflation_pay_factor", - "type": "int64" - }, - { - "name": "votepay_factor", - "type": "int64" - } - ] - }, - { - "name": "exchange_state", - "base": "", - "fields": [ - { - "name": "supply", - "type": "asset" - }, - { - "name": "base", - "type": "connector" - }, - { - "name": "quote", - "type": "connector" - } - ] - }, - { - "name": "fundcpuloan", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "loan_num", - "type": "uint64" - }, - { - "name": "payment", - "type": "asset" - } - ] - }, - { - "name": "fundnetloan", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "loan_num", - "type": "uint64" - }, - { - "name": "payment", - "type": "asset" - } - ] - }, - { - "name": "init", - "base": "", - "fields": [ - { - "name": "version", - "type": "varuint32" - }, - { - "name": "core", - "type": "symbol" - } - ] - }, - { - "name": "key_weight", - "base": "", - "fields": [ - { - "name": "key", - "type": "public_key" - }, - { - "name": "weight", - "type": "uint16" - } - ] - }, - { - "name": "linkauth", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "code", - "type": "name" - }, - { - "name": "type", - "type": "name" - }, - { - "name": "requirement", - "type": "name" - } - ] - }, - { - "name": "mvfrsavings", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "rex", - "type": "asset" - } - ] - }, - { - "name": "mvtosavings", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "rex", - "type": "asset" - } - ] - }, - { - "name": "name_bid", - "base": "", - "fields": [ - { - "name": "newname", - "type": "name" - }, - { - "name": "high_bidder", - "type": "name" - }, - { - "name": "high_bid", - "type": "int64" - }, - { - "name": "last_bid_time", - "type": "time_point" - } - ] - }, - { - "name": "newaccount", - "base": "", - "fields": [ - { - "name": "creator", - "type": "name" - }, - { - "name": "name", - "type": "name" - }, - { - "name": "owner", - "type": "authority" - }, - { - "name": "active", - "type": "authority" - } - ] - }, - { - "name": "onblock", - "base": "", - "fields": [ - { - "name": "header", - "type": "block_header" - } - ] - }, - { - "name": "onerror", - "base": "", - "fields": [ - { - "name": "sender_id", - "type": "uint128" - }, - { - "name": "sent_trx", - "type": "bytes" - } - ] - }, - { - "name": "pair_time_point_sec_int64", - "base": "", - "fields": [ - { - "name": "key", - "type": "time_point_sec" - }, - { - "name": "value", - "type": "int64" - } - ] - }, - { - "name": "permission_level", - "base": "", - "fields": [ - { - "name": "actor", - "type": "name" - }, - { - "name": "permission", - "type": "name" - } - ] - }, - { - "name": "permission_level_weight", - "base": "", - "fields": [ - { - "name": "permission", - "type": "permission_level" - }, - { - "name": "weight", - "type": "uint16" - } - ] - }, - { - "name": "producer_info", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "total_votes", - "type": "float64" - }, - { - "name": "producer_key", - "type": "public_key" - }, - { - "name": "is_active", - "type": "bool" - }, - { - "name": "url", - "type": "string" - }, - { - "name": "unpaid_blocks", - "type": "uint32" - }, - { - "name": "last_claim_time", - "type": "time_point" - }, - { - "name": "location", - "type": "uint16" - } - ] - }, - { - "name": "producer_info2", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "votepay_share", - "type": "float64" - }, - { - "name": "last_votepay_share_update", - "type": "time_point" - } - ] - }, - { - "name": "producer_key", - "base": "", - "fields": [ - { - "name": "producer_name", - "type": "name" - }, - { - "name": "block_signing_key", - "type": "public_key" - } - ] - }, - { - "name": "producer_schedule", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint32" - }, - { - "name": "producers", - "type": "producer_key[]" - } - ] - }, - { - "name": "refund", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - } - ] - }, - { - "name": "refund_request", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "request_time", - "type": "time_point_sec" - }, - { - "name": "net_amount", - "type": "asset" - }, - { - "name": "cpu_amount", - "type": "asset" - } - ] - }, - { - "name": "regproducer", - "base": "", - "fields": [ - { - "name": "producer", - "type": "name" - }, - { - "name": "producer_key", - "type": "public_key" - }, - { - "name": "url", - "type": "string" - }, - { - "name": "location", - "type": "uint16" - } - ] - }, - { - "name": "regproxy", - "base": "", - "fields": [ - { - "name": "proxy", - "type": "name" - }, - { - "name": "isproxy", - "type": "bool" - } - ] - }, - { - "name": "rentcpu", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "loan_payment", - "type": "asset" - }, - { - "name": "loan_fund", - "type": "asset" - } - ] - }, - { - "name": "rentnet", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "loan_payment", - "type": "asset" - }, - { - "name": "loan_fund", - "type": "asset" - } - ] - }, - { - "name": "rex_balance", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "owner", - "type": "name" - }, - { - "name": "vote_stake", - "type": "asset" - }, - { - "name": "rex_balance", - "type": "asset" - }, - { - "name": "matured_rex", - "type": "int64" - }, - { - "name": "rex_maturities", - "type": "pair_time_point_sec_int64[]" - } - ] - }, - { - "name": "rex_fund", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "owner", - "type": "name" - }, - { - "name": "balance", - "type": "asset" - } - ] - }, - { - "name": "rex_loan", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "from", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "payment", - "type": "asset" - }, - { - "name": "balance", - "type": "asset" - }, - { - "name": "total_staked", - "type": "asset" - }, - { - "name": "loan_num", - "type": "uint64" - }, - { - "name": "expiration", - "type": "time_point" - } - ] - }, - { - "name": "rex_order", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "owner", - "type": "name" - }, - { - "name": "rex_requested", - "type": "asset" - }, - { - "name": "proceeds", - "type": "asset" - }, - { - "name": "stake_change", - "type": "asset" - }, - { - "name": "order_time", - "type": "time_point" - }, - { - "name": "is_open", - "type": "bool" - } - ] - }, - { - "name": "rex_pool", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "total_lent", - "type": "asset" - }, - { - "name": "total_unlent", - "type": "asset" - }, - { - "name": "total_rent", - "type": "asset" - }, - { - "name": "total_lendable", - "type": "asset" - }, - { - "name": "total_rex", - "type": "asset" - }, - { - "name": "namebid_proceeds", - "type": "asset" - }, - { - "name": "loan_num", - "type": "uint64" - } - ] - }, - { - "name": "rex_return_buckets", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "return_buckets", - "type": "pair_time_point_sec_int64[]" - } - ] - }, - { - "name": "rex_return_pool", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "last_dist_time", - "type": "time_point_sec" - }, - { - "name": "pending_bucket_time", - "type": "time_point_sec" - }, - { - "name": "oldest_bucket_time", - "type": "time_point_sec" - }, - { - "name": "pending_bucket_proceeds", - "type": "int64" - }, - { - "name": "current_rate_of_increase", - "type": "int64" - }, - { - "name": "proceeds", - "type": "int64" - } - ] - }, - { - "name": "rexexec", - "base": "", - "fields": [ - { - "name": "user", - "type": "name" - }, - { - "name": "max", - "type": "uint16" - } - ] - }, - { - "name": "rmvproducer", - "base": "", - "fields": [ - { - "name": "producer", - "type": "name" - } - ] - }, - { - "name": "sellram", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "bytes", - "type": "int64" - } - ] - }, - { - "name": "sellrex", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "rex", - "type": "asset" - } - ] - }, - { - "name": "setabi", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "abi", - "type": "bytes" - } - ] - }, - { - "name": "setacctcpu", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "cpu_weight", - "type": "int64?" - } - ] - }, - { - "name": "setacctnet", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "net_weight", - "type": "int64?" - } - ] - }, - { - "name": "setacctram", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "ram_bytes", - "type": "int64?" - } - ] - }, - { - "name": "setalimits", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "ram_bytes", - "type": "int64" - }, - { - "name": "net_weight", - "type": "int64" - }, - { - "name": "cpu_weight", - "type": "int64" - } - ] - }, - { - "name": "setcode", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "vmtype", - "type": "uint8" - }, - { - "name": "vmversion", - "type": "uint8" - }, - { - "name": "code", - "type": "bytes" - } - ] - }, - { - "name": "setinflation", - "base": "", - "fields": [ - { - "name": "annual_rate", - "type": "int64" - }, - { - "name": "inflation_pay_factor", - "type": "int64" - }, - { - "name": "votepay_factor", - "type": "int64" - } - ] - }, - { - "name": "setparams", - "base": "", - "fields": [ - { - "name": "params", - "type": "blockchain_parameters" - } - ] - }, - { - "name": "setpriv", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "is_priv", - "type": "uint8" - } - ] - }, - { - "name": "setram", - "base": "", - "fields": [ - { - "name": "max_ram_size", - "type": "uint64" - } - ] - }, - { - "name": "setramrate", - "base": "", - "fields": [ - { - "name": "bytes_per_block", - "type": "uint16" - } - ] - }, - { - "name": "setrex", - "base": "", - "fields": [ - { - "name": "balance", - "type": "asset" - } - ] - }, - { - "name": "undelegatebw", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "unstake_net_quantity", - "type": "asset" - }, - { - "name": "unstake_cpu_quantity", - "type": "asset" - } - ] - }, - { - "name": "unlinkauth", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "code", - "type": "name" - }, - { - "name": "type", - "type": "name" - } - ] - }, - { - "name": "unregprod", - "base": "", - "fields": [ - { - "name": "producer", - "type": "name" - } - ] - }, - { - "name": "unstaketorex", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "from_net", - "type": "asset" - }, - { - "name": "from_cpu", - "type": "asset" - } - ] - }, - { - "name": "updateauth", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "permission", - "type": "name" - }, - { - "name": "parent", - "type": "name" - }, - { - "name": "auth", - "type": "authority" - } - ] - }, - { - "name": "updaterex", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - } - ] - }, - { - "name": "updtrevision", - "base": "", - "fields": [ - { - "name": "revision", - "type": "uint8" - } - ] - }, - { - "name": "user_resources", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "net_weight", - "type": "asset" - }, - { - "name": "cpu_weight", - "type": "asset" - }, - { - "name": "ram_bytes", - "type": "int64" - } - ] - }, - { - "name": "voteproducer", - "base": "", - "fields": [ - { - "name": "voter", - "type": "name" - }, - { - "name": "proxy", - "type": "name" - }, - { - "name": "producers", - "type": "name[]" - } - ] - }, - { - "name": "voter_info", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "proxy", - "type": "name" - }, - { - "name": "producers", - "type": "name[]" - }, - { - "name": "staked", - "type": "int64" - }, - { - "name": "last_vote_weight", - "type": "float64" - }, - { - "name": "proxied_vote_weight", - "type": "float64" - }, - { - "name": "is_proxy", - "type": "bool" - }, - { - "name": "flags1", - "type": "uint32" - }, - { - "name": "reserved2", - "type": "uint32" - }, - { - "name": "reserved3", - "type": "asset" - } - ] - }, - { - "name": "wait_weight", - "base": "", - "fields": [ - { - "name": "wait_sec", - "type": "uint32" - }, - { - "name": "weight", - "type": "uint16" - } - ] - }, - { - "name": "withdraw", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "amount", - "type": "asset" - } - ] - } - ], - "actions": [ - { - "name": "activate", - "type": "activate", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Activate Protocol Feature\nsummary: 'Activate protocol feature {{nowrap feature_digest}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} activates the protocol feature with a digest of {{feature_digest}}." - }, - { - "name": "bidname", - "type": "bidname", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Bid On a Premium Account Name\nsummary: '{{nowrap bidder}} bids on the premium account name {{nowrap newname}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{bidder}} bids {{bid}} on an auction to own the premium account name {{newname}}.\n\n{{bidder}} transfers {{bid}} to the system to cover the cost of the bid, which will be returned to {{bidder}} only if {{bidder}} is later outbid in the auction for {{newname}} by another account.\n\nIf the auction for {{newname}} closes with {{bidder}} remaining as the highest bidder, {{bidder}} will be authorized to create the account with name {{newname}}.\n\n## Bid refund behavior\n\nIf {{bidder}}’s bid on {{newname}} is later outbid by another account, {{bidder}} will be able to claim back the transferred amount of {{bid}}. The system will attempt to automatically do this on behalf of {{bidder}}, but the automatic refund may occasionally fail which will then require {{bidder}} to manually claim the refund with the bidrefund action.\n\n## Auction close criteria\n\nThe system should automatically close the auction for {{newname}} if it satisfies the condition that over a period of two minutes the following two properties continuously hold:\n\n- no one has bid on {{newname}} within the last 24 hours;\n- and, the value of the latest bid on {{newname}} is greater than the value of the bids on each of the other open auctions.\n\nBe aware that the condition to close the auction described above are sufficient but not necessary. The auction for {{newname}} cannot close unless both of the properties are simultaneously satisfied, but it may be closed without requiring the properties to hold for a period of 2 minutes." - }, - { - "name": "bidrefund", - "type": "bidrefund", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Claim Refund on Name Bid\nsummary: 'Claim refund on {{nowrap newname}} bid'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{bidder}} claims refund on {{newname}} bid after being outbid by someone else." - }, - { - "name": "buyram", - "type": "buyram", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Buy RAM\nsummary: '{{nowrap payer}} buys RAM on behalf of {{nowrap receiver}} by paying {{nowrap quant}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\n{{payer}} buys RAM on behalf of {{receiver}} by paying {{quant}}. This transaction will incur a 0.5% fee out of {{quant}} and the amount of RAM delivered will depend on market rates." - }, - { - "name": "buyrambytes", - "type": "buyrambytes", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Buy RAM\nsummary: '{{nowrap payer}} buys {{nowrap bytes}} bytes of RAM on behalf of {{nowrap receiver}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\n{{payer}} buys approximately {{bytes}} bytes of RAM on behalf of {{receiver}} by paying market rates for RAM. This transaction will incur a 0.5% fee and the cost will depend on market rates." - }, - { - "name": "buyrex", - "type": "buyrex", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Buy REX Tokens\nsummary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and their vote stake increases by {{nowrap amount}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{amount}} is taken out of {{from}}’s REX fund and used to purchase REX tokens at the current market exchange rate. In order for the action to succeed, {{from}} must have voted for a proxy or at least 21 block producers. {{amount}} is added to {{from}}’s vote stake.\n\nA sell order of the purchased amount can only be initiated after waiting for the maturity period of 4 to 5 days to pass. Even then, depending on the market conditions, the initiated sell order may not be executed immediately." - }, - { - "name": "canceldelay", - "type": "canceldelay", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Cancel Delayed Transaction\nsummary: '{{nowrap canceling_auth.actor}} cancels a delayed transaction'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{canceling_auth.actor}} cancels the delayed transaction with id {{trx_id}}." - }, - { - "name": "claimrewards", - "type": "claimrewards", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Claim Block Producer Rewards\nsummary: '{{nowrap owner}} claims block and vote rewards'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{owner}} claims block and vote rewards from the system." - }, - { - "name": "closerex", - "type": "closerex", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Cleanup Unused REX Data\nsummary: 'Delete REX related DB entries and free associated RAM'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nDelete REX related DB entries and free associated RAM for {{owner}}.\n\nTo fully delete all REX related DB entries, {{owner}} must ensure that their REX balance and REX fund amounts are both zero and they have no outstanding loans." - }, - { - "name": "cnclrexorder", - "type": "cnclrexorder", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Cancel Scheduled REX Sell Order\nsummary: '{{nowrap owner}} cancels a scheduled sell order if not yet filled'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{owner}} cancels their open sell order." - }, - { - "name": "consolidate", - "type": "consolidate", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Consolidate REX Maturity Buckets Into One\nsummary: 'Consolidate REX maturity buckets into one'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nConsolidate REX maturity buckets into one bucket that {{owner}} will not be able to sell until 4 to 5 days later." - }, - { - "name": "defcpuloan", - "type": "defcpuloan", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Withdraw from the Fund of a Specific CPU Loan\nsummary: '{{nowrap from}} transfers {{nowrap amount}} from the fund of CPU loan number {{nowrap loan_num}} back to REX fund'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} transfers {{amount}} from the fund of CPU loan number {{loan_num}} back to REX fund." - }, - { - "name": "defnetloan", - "type": "defnetloan", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Withdraw from the Fund of a Specific NET Loan\nsummary: '{{nowrap from}} transfers {{nowrap amount}} from the fund of NET loan number {{nowrap loan_num}} back to REX fund'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} transfers {{amount}} from the fund of NET loan number {{loan_num}} back to REX fund." - }, - { - "name": "delegatebw", - "type": "delegatebw", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Stake Tokens for NET and/or CPU\nsummary: 'Stake tokens for NET and/or CPU and optionally transfer ownership'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\n{{#if transfer}} {{from}} stakes on behalf of {{receiver}} {{stake_net_quantity}} for NET bandwidth and {{stake_cpu_quantity}} for CPU bandwidth.\n\nStaked tokens will also be transferred to {{receiver}}. The sum of these two quantities will be deducted from {{from}}’s liquid balance and add to the vote weight of {{receiver}}.\n{{else}}\n{{from}} stakes to self and delegates to {{receiver}} {{stake_net_quantity}} for NET bandwidth and {{stake_cpu_quantity}} for CPU bandwidth.\n\nThe sum of these two quantities add to the vote weight of {{from}}.\n{{/if}}" - }, - { - "name": "deleteauth", - "type": "deleteauth", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Delete Account Permission\nsummary: 'Delete the {{nowrap permission}} permission of {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nDelete the {{permission}} permission of {{account}}." - }, - { - "name": "deposit", - "type": "deposit", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deposit Into REX Fund\nsummary: 'Add to {{nowrap owner}}’s REX fund by transferring {{nowrap amount}} from {{nowrap owner}}’s liquid balance'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nTransfer {{amount}} from {{owner}}’s liquid balance to {{owner}}’s REX fund. All proceeds and expenses related to REX are added to or taken out of this fund." - }, - { - "name": "fundcpuloan", - "type": "fundcpuloan", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deposit into the Fund of a Specific CPU Loan\nsummary: '{{nowrap from}} funds a CPU loan'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} transfers {{payment}} from REX fund to the fund of CPU loan number {{loan_num}} in order to be used in loan renewal at expiry. {{from}} can withdraw the total balance of the loan fund at any time." - }, - { - "name": "fundnetloan", - "type": "fundnetloan", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deposit into the Fund of a Specific NET Loan\nsummary: '{{nowrap from}} funds a NET loan'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} transfers {{payment}} from REX fund to the fund of NET loan number {{loan_num}} in order to be used in loan renewal at expiry. {{from}} can withdraw the total balance of the loan fund at any time." - }, - { - "name": "init", - "type": "init", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Initialize System Contract\nsummary: 'Initialize system contract'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\nInitialize system contract. The core token symbol will be set to {{core}}." - }, - { - "name": "linkauth", - "type": "linkauth", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Link Action to Permission\nsummary: '{{nowrap account}} sets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract to {{nowrap requirement}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{account}} sets the minimum required permission for the {{#if type}}{{type}} action of the{{/if}} {{code}} contract to {{requirement}}.\n\n{{#if type}}{{else}}Any links explicitly associated to specific actions of {{code}} will take precedence.{{/if}}" - }, - { - "name": "mvfrsavings", - "type": "mvfrsavings", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Unlock REX Tokens\nsummary: '{{nowrap owner}} unlocks REX Tokens'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{owner}} unlocks {{rex}} by moving it out of the REX savings bucket. The unlocked REX tokens cannot be sold until 4 to 5 days later." - }, - { - "name": "mvtosavings", - "type": "mvtosavings", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Lock REX Tokens\nsummary: '{{nowrap owner}} locks REX Tokens'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{owner}} locks {{rex}} by moving it into the REX savings bucket. The locked REX tokens cannot be sold directly and will have to be unlocked explicitly before selling." - }, - { - "name": "newaccount", - "type": "newaccount", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Create New Account\nsummary: '{{nowrap creator}} creates a new account with the name {{nowrap name}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{creator}} creates a new account with the name {{name}} and the following permissions:\n\nowner permission with authority:\n{{to_json owner}}\n\nactive permission with authority:\n{{to_json active}}" - }, - { - "name": "onblock", - "type": "onblock", - "ricardian_contract": "" - }, - { - "name": "onerror", - "type": "onerror", - "ricardian_contract": "" - }, - { - "name": "refund", - "type": "refund", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Claim Unstaked Tokens\nsummary: 'Return previously unstaked tokens to {{nowrap owner}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nReturn previously unstaked tokens to {{owner}} after the unstaking period has elapsed." - }, - { - "name": "regproducer", - "type": "regproducer", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Register as a Block Producer Candidate\nsummary: 'Register {{nowrap producer}} account as a block producer candidate'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84\n---\n\nRegister {{producer}} account as a block producer candidate.\n\n{{$clauses.BlockProducerAgreement}}" - }, - { - "name": "regproxy", - "type": "regproxy", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Register/unregister as a Proxy\nsummary: 'Register/unregister {{nowrap proxy}} as a proxy account'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84\n---\n\n{{#if isproxy}}\n{{proxy}} registers as a proxy that can vote on behalf of accounts that appoint it as their proxy.\n{{else}}\n{{proxy}} unregisters as a proxy that can vote on behalf of accounts that appoint it as their proxy.\n{{/if}}" - }, - { - "name": "rentcpu", - "type": "rentcpu", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Rent CPU Bandwidth for 30 Days\nsummary: '{{nowrap from}} pays {{nowrap loan_payment}} to rent CPU bandwidth for {{nowrap receiver}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} pays {{loan_payment}} to rent CPU bandwidth on behalf of {{receiver}} for a period of 30 days.\n\n{{loan_payment}} is taken out of {{from}}’s REX fund. The market price determines the number of tokens to be staked to {{receiver}}’s CPU resources. In addition, {{from}} provides {{loan_fund}}, which is also taken out of {{from}}’s REX fund, to be used for automatic renewal of the loan.\n\nAt expiration, if the loan has less funds than {{loan_payment}}, it is closed and lent tokens that have been staked are taken out of {{receiver}}’s CPU bandwidth. Otherwise, it is renewed at the market price at the time of renewal, that is, the number of staked tokens is recalculated and {{receiver}}’s CPU bandwidth is updated accordingly. {{from}} can fund or defund a loan at any time before expiration. When the loan is closed, {{from}} is refunded any tokens remaining in the loan fund." - }, - { - "name": "rentnet", - "type": "rentnet", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Rent NET Bandwidth for 30 Days\nsummary: '{{nowrap from}} pays {{nowrap loan_payment}} to rent NET bandwidth for {{nowrap receiver}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} pays {{loan_payment}} to rent NET bandwidth on behalf of {{receiver}} for a period of 30 days.\n\n{{loan_payment}} is taken out of {{from}}’s REX fund. The market price determines the number of tokens to be staked to {{receiver}}’s NET resources for 30 days. In addition, {{from}} provides {{loan_fund}}, which is also taken out of {{from}}’s REX fund, to be used for automatic renewal of the loan.\n\nAt expiration, if the loan has less funds than {{loan_payment}}, it is closed and lent tokens that have been staked are taken out of {{receiver}}’s NET bandwidth. Otherwise, it is renewed at the market price at the time of renewal, that is, the number of staked tokens is recalculated and {{receiver}}’s NET bandwidth is updated accordingly. {{from}} can fund or defund a loan at any time before expiration. When the loan is closed, {{from}} is refunded any tokens remaining in the loan fund." - }, - { - "name": "rexexec", - "type": "rexexec", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Perform REX Maintenance\nsummary: 'Process sell orders and expired loans'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nPerforms REX maintenance by processing a maximum of {{max}} REX sell orders and expired loans. Any account can execute this action." - }, - { - "name": "rmvproducer", - "type": "rmvproducer", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Forcibly Unregister a Block Producer Candidate\nsummary: '{{nowrap producer}} is unregistered as a block producer candidate'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} unregisters {{producer}} as a block producer candidate. {{producer}} account will retain its votes and those votes can change based on voter stake changes or votes removed from {{producer}}. However new voters will not be able to vote for {{producer}} while it remains unregistered." - }, - { - "name": "sellram", - "type": "sellram", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Sell RAM From Account\nsummary: 'Sell unused RAM from {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\nSell {{bytes}} bytes of unused RAM from account {{account}} at market price. This transaction will incur a 0.5% fee on the proceeds which depend on market rates." - }, - { - "name": "sellrex", - "type": "sellrex", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Sell REX Tokens in Exchange for EOS\nsummary: '{{nowrap from}} sells {{nowrap rex}} tokens'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} initiates a sell order to sell {{rex}} tokens at the market exchange rate during the time at which the order is ultimately executed. If {{from}} already has an open sell order in the sell queue, {{rex}} will be added to the amount of the sell order without change the position of the sell order within the queue. Once the sell order is executed, proceeds are added to {{from}}’s REX fund, the value of sold REX tokens is deducted from {{from}}’s vote stake, and votes are updated accordingly.\n\nDepending on the market conditions, it may not be possible to fill the entire sell order immediately. In such a case, the sell order is added to the back of a sell queue. A sell order at the front of the sell queue will automatically be executed when the market conditions allow for the entire order to be filled. Regardless of the market conditions, the system is designed to execute this sell order within 30 days. {{from}} can cancel the order at any time before it is filled using the cnclrexorder action." - }, - { - "name": "setabi", - "type": "setabi", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deploy Contract ABI\nsummary: 'Deploy contract ABI on account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nDeploy the ABI file associated with the contract on account {{account}}." - }, - { - "name": "setacctcpu", - "type": "setacctcpu", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Explicitly Manage the CPU Quota of Account\nsummary: 'Explicitly manage the CPU bandwidth quota of account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{#if_has_value cpu_weight}}\nExplicitly manage the CPU bandwidth quota of account {{account}} by pinning it to a weight of {{cpu_weight}}.\n\n{{account}} can stake and unstake, however, it will not change their CPU bandwidth quota as long as it remains pinned.\n{{else}}\nUnpin the CPU bandwidth quota of account {{account}}. The CPU bandwidth quota of {{account}} will be driven by the current tokens staked for CPU bandwidth by {{account}}.\n{{/if_has_value}}" - }, - { - "name": "setacctnet", - "type": "setacctnet", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Explicitly Manage the NET Quota of Account\nsummary: 'Explicitly manage the NET bandwidth quota of account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{#if_has_value net_weight}}\nExplicitly manage the network bandwidth quota of account {{account}} by pinning it to a weight of {{net_weight}}.\n\n{{account}} can stake and unstake, however, it will not change their NET bandwidth quota as long as it remains pinned.\n{{else}}\nUnpin the NET bandwidth quota of account {{account}}. The NET bandwidth quota of {{account}} will be driven by the current tokens staked for NET bandwidth by {{account}}.\n{{/if_has_value}}" - }, - { - "name": "setacctram", - "type": "setacctram", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Explicitly Manage the RAM Quota of Account\nsummary: 'Explicitly manage the RAM quota of account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{#if_has_value ram_bytes}}\nExplicitly manage the RAM quota of account {{account}} by pinning it to {{ram_bytes}} bytes.\n\n{{account}} can buy and sell RAM, however, it will not change their RAM quota as long as it remains pinned.\n{{else}}\nUnpin the RAM quota of account {{account}}. The RAM quota of {{account}} will be driven by the current RAM holdings of {{account}}.\n{{/if_has_value}}" - }, - { - "name": "setalimits", - "type": "setalimits", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Adjust Resource Limits of Account\nsummary: 'Adjust resource limits of account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} updates {{account}}’s resource limits to have a RAM quota of {{ram_bytes}} bytes, a NET bandwidth quota of {{net_weight}} and a CPU bandwidth quota of {{cpu_weight}}." - }, - { - "name": "setcode", - "type": "setcode", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deploy Contract Code\nsummary: 'Deploy contract code on account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nDeploy compiled contract code to the account {{account}}." - }, - { - "name": "setinflation", - "type": "setinflation", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Set Inflation Parameters\nsummary: 'Set inflation parameters'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} sets the inflation parameters as follows:\n\n* Annual inflation rate (in units of a hundredth of a percent): {{annual_rate}}\n* Fraction of inflation used to reward block producers: 10000/{{inflation_pay_factor}}\n* Fraction of block producer rewards to be distributed proportional to blocks produced: 10000/{{votepay_factor}}" - }, - { - "name": "setparams", - "type": "setparams", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Set System Parameters\nsummary: 'Set System Parameters'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} sets system parameters to:\n{{to_json params}}" - }, - { - "name": "setpriv", - "type": "setpriv", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Make an Account Privileged or Unprivileged\nsummary: '{{#if is_priv}}Make {{nowrap account}} privileged{{else}}Remove privileged status of {{nowrap account}}{{/if}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{#if is_priv}}\n{{$action.account}} makes {{account}} privileged.\n{{else}}\n{{$action.account}} removes privileged status of {{account}}.\n{{/if}}" - }, - { - "name": "setram", - "type": "setram", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Configure the Available RAM\nsummary: 'Configure the available RAM'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} configures the available RAM to {{max_ram_size}} bytes." - }, - { - "name": "setramrate", - "type": "setramrate", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Set the Rate of Increase of RAM\nsummary: 'Set the rate of increase of RAM per block'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} sets the rate of increase of RAM to {{bytes_per_block}} bytes/block." - }, - { - "name": "setrex", - "type": "setrex", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Adjust REX Pool Virtual Balance\nsummary: 'Adjust REX Pool Virtual Balance'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} adjusts REX loan rate by setting REX pool virtual balance to {{balance}}. No token transfer or issue is executed in this action." - }, - { - "name": "undelegatebw", - "type": "undelegatebw", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Unstake Tokens for NET and/or CPU\nsummary: 'Unstake tokens for NET and/or CPU from {{nowrap receiver}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\n{{from}} unstakes from {{receiver}} {{unstake_net_quantity}} for NET bandwidth and {{unstake_cpu_quantity}} for CPU bandwidth.\n\nThe sum of these two quantities will be removed from the vote weight of {{receiver}} and will be made available to {{from}} after an uninterrupted 3 day period without further unstaking by {{from}}. After the uninterrupted 3 day period passes, the system will attempt to automatically return the funds to {{from}}’s regular token balance. However, this automatic refund may occasionally fail which will then require {{from}} to manually claim the funds with the refund action." - }, - { - "name": "unlinkauth", - "type": "unlinkauth", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Unlink Action from Permission\nsummary: '{{nowrap account}} unsets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{account}} removes the association between the {{#if type}}{{type}} action of the{{/if}} {{code}} contract and its minimum required permission.\n\n{{#if type}}{{else}}This will not remove any links explicitly associated to specific actions of {{code}}.{{/if}}" - }, - { - "name": "unregprod", - "type": "unregprod", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Unregister as a Block Producer Candidate\nsummary: '{{nowrap producer}} unregisters as a block producer candidate'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84\n---\n\n{{producer}} unregisters as a block producer candidate. {{producer}} account will retain its votes and those votes can change based on voter stake changes or votes removed from {{producer}}. However new voters will not be able to vote for {{producer}} while it remains unregistered." - }, - { - "name": "unstaketorex", - "type": "unstaketorex", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Buy REX Tokens Using Staked Tokens\nsummary: '{{nowrap owner}} buys REX tokens in exchange for tokens currently staked to NET and/or CPU'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from_net}} and {{from_cpu}} are withdrawn from {{receiver}}’s NET and CPU bandwidths respectively. These funds are used to purchase REX tokens at the current market exchange rate. In order for the action to succeed, {{owner}} must have voted for a proxy or at least 21 block producers.\n\nA sell order of the purchased amount can only be initiated after waiting for the maturity period of 4 to 5 days to pass. Even then, depending on the market conditions, the initiated sell order may not be executed immediately." - }, - { - "name": "updateauth", - "type": "updateauth", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Modify Account Permission\nsummary: 'Add or update the {{nowrap permission}} permission of {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nModify, and create if necessary, the {{permission}} permission of {{account}} to have a parent permission of {{parent}} and the following authority:\n{{to_json auth}}" - }, - { - "name": "updaterex", - "type": "updaterex", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Update REX Owner Vote Weight\nsummary: 'Update vote weight to current value of held REX tokens'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nUpdate vote weight of {{owner}} account to current value of held REX tokens." - }, - { - "name": "updtrevision", - "type": "updtrevision", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Update System Contract Revision Number\nsummary: 'Update system contract revision number'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} advances the system contract revision number to {{revision}}." - }, - { - "name": "voteproducer", - "type": "voteproducer", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Vote for Block Producers\nsummary: '{{nowrap voter}} votes for {{#if proxy}}the proxy {{nowrap proxy}}{{else}}up to 30 block producer candidates{{/if}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84\n---\n\n{{#if proxy}}\n{{voter}} votes for the proxy {{proxy}}.\nAt the time of voting the full weight of voter’s staked (CPU + NET) tokens will be cast towards each of the producers voted by {{proxy}}.\n{{else}}\n{{voter}} votes for the following block producer candidates:\n\n{{#each producers}}\n + {{this}}\n{{/each}}\n\nAt the time of voting the full weight of voter’s staked (CPU + NET) tokens will be cast towards each of the above producers.\n{{/if}}" - }, - { - "name": "withdraw", - "type": "withdraw", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Withdraw from REX Fund\nsummary: 'Withdraw {{nowrap amount}} from {{nowrap owner}}’s REX fund by transferring to {{owner}}’s liquid balance'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nWithdraws {{amount}} from {{owner}}’s REX fund and transfer them to {{owner}}’s liquid balance." - } - ], - "tables": [ - { - "name": "abihash", - "type": "abi_hash", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "bidrefunds", - "type": "bid_refund", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "cpuloan", - "type": "rex_loan", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "delband", - "type": "delegated_bandwidth", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "global", - "type": "eosio_global_state", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "global2", - "type": "eosio_global_state2", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "global3", - "type": "eosio_global_state3", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "global4", - "type": "eosio_global_state4", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "namebids", - "type": "name_bid", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "netloan", - "type": "rex_loan", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "producers", - "type": "producer_info", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "producers2", - "type": "producer_info2", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "rammarket", - "type": "exchange_state", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "refunds", - "type": "refund_request", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "retbuckets", - "type": "rex_return_buckets", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "rexbal", - "type": "rex_balance", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "rexfund", - "type": "rex_fund", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "rexpool", - "type": "rex_pool", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "rexqueue", - "type": "rex_order", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "rexretpool", - "type": "rex_return_pool", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "userres", - "type": "user_resources", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "voters", - "type": "voter_info", - "index_type": "i64", - "key_names": [], - "key_types": [] - } - ], - "ricardian_clauses": [ - { - "id": "UserAgreement", - "body": "User agreement for the chain can go here." - }, - { - "id": "BlockProducerAgreement", - "body": "I, {{producer}}, hereby nominate myself for consideration as an elected block producer.\n\nIf {{producer}} is selected to produce blocks by the system contract, I will sign blocks with {{producer_key}} and I hereby attest that I will keep this key secret and secure.\n\nIf {{producer}} is unable to perform obligations under this contract I will resign my position by resubmitting this contract with the null producer key.\n\nI acknowledge that a block is 'objectively valid' if it conforms to the deterministic blockchain rules in force at the time of its creation, and is 'objectively invalid' if it fails to conform to those rules.\n\n{{producer}} hereby agrees to only use {{producer_key}} to sign messages under the following scenarios:\n\n* proposing an objectively valid block at the time appointed by the block scheduling algorithm;\n* pre-confirming a block produced by another producer in the schedule when I find said block objectively valid;\n* and, confirming a block for which {{producer}} has received pre-confirmation messages from more than two-thirds of the active block producers.\n\nI hereby accept liability for any and all provable damages that result from my:\n\n* signing two different block proposals with the same timestamp with {{producer_key}};\n* signing two different block proposals with the same block number with {{producer_key}};\n* signing any block proposal which builds off of an objectively invalid block;\n* signing a pre-confirmation for an objectively invalid block;\n* or, signing a confirmation for a block for which I do not possess pre-confirmation messages from more than two-thirds of the active block producers.\n\nI hereby agree that double-signing for a timestamp or block number in concert with two or more other block producers shall automatically be deemed malicious and cause {{producer}} to be subject to:\n\n* a fine equal to the past year of compensation received,\n* immediate disqualification from being a producer,\n* and/or other damages.\n\nAn exception may be made if {{producer}} can demonstrate that the double-signing occurred due to a bug in the reference software; the burden of proof is on {{producer}}.\n\nI hereby agree not to interfere with the producer election process. I agree to process all producer election transactions that occur in blocks I create, to sign all objectively valid blocks I create that contain election transactions, and to sign all pre-confirmations and confirmations necessary to facilitate transfer of control to the next set of producers as determined by the system contract.\n\nI hereby acknowledge that more than two-thirds of the active block producers may vote to disqualify {{producer}} in the event {{producer}} is unable to produce blocks or is unable to be reached, according to criteria agreed to among block producers.\n\nIf {{producer}} qualifies for and chooses to collect compensation due to votes received, {{producer}} will provide a public endpoint allowing at least 100 peers to maintain synchronization with the blockchain and/or submit transactions to be included. {{producer}} shall maintain at least one validating node with full state and signature checking and shall report any objectively invalid blocks produced by the active block producers. Reporting shall be via a method to be agreed to among block producers, said method and reports to be made public.\n\nThe community agrees to allow {{producer}} to authenticate peers as necessary to prevent abuse and denial of service attacks; however, {{producer}} agrees not to discriminate against non-abusive peers.\n\nI agree to process transactions on a FIFO (first in, first out) best-effort basis and to honestly bill transactions for measured execution time.\n\nI {{producer}} agree not to manipulate the contents of blocks in order to derive profit from: the order in which transactions are included, or the hash of the block that is produced.\n\nI, {{producer}}, hereby agree to disclose and attest under penalty of perjury all ultimate beneficial owners of my business entity who own more than 10% and all direct shareholders.\n\nI, {{producer}}, hereby agree to cooperate with other block producers to carry out our respective and mutual obligations under this agreement, including but not limited to maintaining network stability and a valid blockchain.\n\nI, {{producer}}, agree to maintain a website hosted at {{url}} which contains up-to-date information on all disclosures required by this contract.\n\nI, {{producer}}, agree to set the location value of {{location}} such that {{producer}} is scheduled with minimal latency between my previous and next peer.\n\nI, {{producer}}, agree to maintain time synchronization within 10 ms of global atomic clock time, using a method agreed to among block producers.\n\nI, {{producer}}, agree not to produce blocks before my scheduled time unless I have received all blocks produced by the prior block producer.\n\nI, {{producer}}, agree not to publish blocks with timestamps more than 500ms in the future unless the prior block is more than 75% full by either NET or CPU bandwidth metrics.\n\nI, {{producer}}, agree not to set the RAM supply to more RAM than my nodes contain and to resign if I am unable to provide the RAM approved by more than two-thirds of active block producers, as shown in the system parameters." - } - ], - "variants": [] -} \ No newline at end of file diff --git a/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.wasm b/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.wasm deleted file mode 100755 index 7934a4a9..00000000 Binary files a/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.wasm and /dev/null differ diff --git a/tests/test_contracts/reject_all.wasm b/tests/test_contracts/reject_all.wasm deleted file mode 100755 index ee794557..00000000 Binary files a/tests/test_contracts/reject_all.wasm and /dev/null differ