diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 65014cfbf7..40bef592d1 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -156,7 +156,7 @@ jobs: chown -R $(id -u):$(id -g) $PWD zstdcat build.tar.zst | tar x cd build - ctest --output-on-failure -j $(nproc) -LE "(nonparallelizable_tests|long_running_tests)" --timeout 420 + ctest --output-on-failure -j $(nproc) -LE "(nonparallelizable_tests|long_running_tests)" --timeout 480 - name: Upload core files from failed tests uses: actions/upload-artifact@v4 if: failure() diff --git a/tests/get_producers_tests.cpp b/tests/get_producers_tests.cpp index e22620f887..c8d4f3d995 100644 --- a/tests/get_producers_tests.cpp +++ b/tests/get_producers_tests.cpp @@ -13,8 +13,8 @@ BOOST_AUTO_TEST_SUITE(get_producers_tests) using namespace eosio::testing; // this test verifies the exception case of get_producer, where it is populated by the active schedule of producers -BOOST_AUTO_TEST_CASE( get_producers) { try { - tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( get_producers, T, testers ) { try { + T chain; eosio::chain_apis::read_only plugin(*(chain.control), {}, fc::microseconds::maximum(), fc::microseconds::maximum(), {}); eosio::chain_apis::read_only::get_producers_params params = { .json = true, .lower_bound = "", .limit = 21 }; @@ -46,8 +46,8 @@ BOOST_AUTO_TEST_CASE( get_producers) { try { } FC_LOG_AND_RETHROW() } // this test verifies the normal case of get_producer, where the contents of the system contract's producers table is used -BOOST_AUTO_TEST_CASE( get_producers_from_table) { try { - eosio_system::eosio_system_tester chain; +BOOST_AUTO_TEST_CASE_TEMPLATE( get_producers_from_table, T, eosio_system::eosio_system_testers ) { try { + T chain; // ensure that enough voting is occurring so that producer1111 is elected as the producer chain.cross_15_percent_threshold(); diff --git a/tests/test_snapshot_information.cpp b/tests/test_snapshot_information.cpp index 7c089dadba..81ade5a2f4 100644 --- a/tests/test_snapshot_information.cpp +++ b/tests/test_snapshot_information.cpp @@ -31,9 +31,10 @@ void test_snapshot_information() { chain.set_abi("snapshot"_n, test_contracts::snapshot_test_abi()); chain.produce_blocks(1); + constexpr uint32_t savanna_base_block_num = 9; auto block = chain.produce_block(); if constexpr (std::is_same_v) { - BOOST_REQUIRE_EQUAL(block->block_num(), 15u); // ensure that test setup stays consistent with original snapshot setup + BOOST_REQUIRE_EQUAL(block->block_num(), 6u + savanna_base_block_num); // ensure that test setup stays consistent with original snapshot setup } else { BOOST_REQUIRE_EQUAL(block->block_num(), 6u); // ensure that test setup stays consistent with original snapshot setup } @@ -42,7 +43,7 @@ void test_snapshot_information() { auto block2 = chain.produce_block(); if constexpr (std::is_same_v) { - BOOST_REQUIRE_EQUAL(block2->block_num(), 16u); // ensure that test setup stays consistent with original snapshot setup + BOOST_REQUIRE_EQUAL(block2->block_num(), 7u + savanna_base_block_num); // ensure that test setup stays consistent with original snapshot setup } else { BOOST_REQUIRE_EQUAL(block2->block_num(), 7u); // ensure that test setup stays consistent with original snapshot setup } @@ -71,7 +72,7 @@ void test_snapshot_information() { pending_snapshot pending{ block2->previous, next, pending_path.generic_string(), final_path.generic_string() }; test_snap_info = pending.finalize(*chain.control); if constexpr (std::is_same_v) { - BOOST_REQUIRE_EQUAL(test_snap_info.head_block_num, 15u); + BOOST_REQUIRE_EQUAL(test_snap_info.head_block_num, 6u + savanna_base_block_num); } else { BOOST_REQUIRE_EQUAL(test_snap_info.head_block_num, 6u); } diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index e0476af8be..fa99d540c1 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -114,12 +114,14 @@ foreach(RUNTIME ${EOSIO_WASM_RUNTIMES}) set_tests_properties(api_part2_unit_test_${RUNTIME} PROPERTIES COST 5000) set_tests_properties(api_part3_unit_test_${RUNTIME} PROPERTIES COST 5000) set_tests_properties(api_part4_unit_test_${RUNTIME} PROPERTIES COST 5000) - set_tests_properties(wasm_part1_unit_test_${RUNTIME} PROPERTIES COST 4000) - set_tests_properties(wasm_part2_unit_test_${RUNTIME} PROPERTIES COST 4000) - set_tests_properties(wasm_part3_unit_test_${RUNTIME} PROPERTIES COST 4000) - set_tests_properties(wasm_config_part1_unit_test_${RUNTIME} PROPERTIES COST 4000) - set_tests_properties(wasm_config_part2_unit_test_${RUNTIME} PROPERTIES COST 4000) - set_tests_properties(wasm_config_part3_unit_test_${RUNTIME} PROPERTIES COST 4000) + set_tests_properties(wasm_part1_unit_test_${RUNTIME} PROPERTIES COST 5000) + set_tests_properties(wasm_part2_unit_test_${RUNTIME} PROPERTIES COST 5000) + set_tests_properties(wasm_part3_unit_test_${RUNTIME} PROPERTIES COST 5000) + set_tests_properties(wasm_config_part1_unit_test_${RUNTIME} PROPERTIES COST 5000) + set_tests_properties(wasm_config_part2_unit_test_${RUNTIME} PROPERTIES COST 5000) + set_tests_properties(wasm_config_part3_unit_test_${RUNTIME} PROPERTIES COST 5000) + set_tests_properties(snapshot_unit_test_${RUNTIME} PROPERTIES COST 4000) + set_tests_properties(finality_unit_test_${RUNTIME} PROPERTIES COST 4000) set_tests_properties(delay_unit_test_${RUNTIME} PROPERTIES COST 3000) endforeach() diff --git a/unittests/eosio.system_tests.cpp b/unittests/eosio.system_tests.cpp deleted file mode 100644 index 28f389e855..0000000000 --- a/unittests/eosio.system_tests.cpp +++ /dev/null @@ -1,2851 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "eosio_system_tester.hpp" - -struct _abi_hash { - eosio::chain::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; - -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_AUTO_TEST_SUITE(eosio_system_part1_tests) - -BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { - using namespace eosio::chain; - - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111"_n ) ); - - transfer( "eosio"_n, "alice1111111"_n, core_from_string("1000.0000"), "eosio"_n ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio"_n, "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - - auto total = get_total_stake( "alice1111111"_n ); - auto init_bytes = total["ram_bytes"].as_uint64(); - - const asset initial_ram_balance = get_balance("eosio.ram"_n); - const asset initial_ramfee_balance = get_balance("eosio.ramfee"_n); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("200.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("800.0000"), get_balance( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( initial_ram_balance + core_from_string("199.0000"), get_balance("eosio.ram"_n) ); - BOOST_REQUIRE_EQUAL( initial_ramfee_balance + core_from_string("1.0000"), get_balance("eosio.ramfee"_n) ); - - total = get_total_stake( "alice1111111"_n ); - 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"_n, bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_from_string("998.0049"), get_balance( "alice1111111"_n ) ); - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( true, total["ram_bytes"].as_uint64() == init_bytes ); - - transfer( "eosio"_n, "alice1111111"_n, core_from_string("100000000.0000"), "eosio"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("100000998.0049"), get_balance( "alice1111111"_n ) ); - // 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"_n, "alice1111111"_n, core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("90000998.0049"), get_balance( "alice1111111"_n ) ); - - total = get_total_stake( "alice1111111"_n ); - bytes = total["ram_bytes"].as_uint64(); - bought_bytes = bytes - init_bytes; - wdump((init_bytes)(bought_bytes)(bytes) ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111"_n, bought_bytes ) ); - total = get_total_stake( "alice1111111"_n ); - - 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_from_string("99901248.0048"), get_balance( "alice1111111"_n ) ); - - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("30.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("99900688.0048"), get_balance( "alice1111111"_n ) ); - - auto newtotal = get_total_stake( "alice1111111"_n ); - - auto newbytes = newtotal["ram_bytes"].as_uint64(); - bought_bytes = newbytes - bytes; - wdump((newbytes)(bytes)(bought_bytes) ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111"_n, bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_from_string("99901242.4187"), get_balance( "alice1111111"_n ) ); - - newtotal = get_total_stake( "alice1111111"_n ); - auto startbytes = newtotal["ram_bytes"].as_uint64(); - - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("100000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("100000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("100000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("300000.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("49301242.4187"), get_balance( "alice1111111"_n ) ); - - auto finaltotal = get_total_stake( "alice1111111"_n ); - auto endbytes = finaltotal["ram_bytes"].as_uint64(); - - bought_bytes = endbytes - startbytes; - wdump((startbytes)(endbytes)(bought_bytes) ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111"_n, bought_bytes ) ); - - BOOST_REQUIRE_EQUAL( false, get_row_by_account( config::system_account_name, config::system_account_name, - "rammarket"_n, 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, - "rammarket"_n, 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, "alice1111111"_n, core_from_string("10000000.0000"), config::system_account_name ); - uint64_t bytes0 = get_total_stake( "alice1111111"_n )["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_from_string("0.0000").get_symbol(), e0.get_symbol() ); - - const asset payment = core_from_string("10000000.0000"); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, payment ) ); - uint64_t bytes1 = get_total_stake( "alice1111111"_n )["ram_bytes"].as_uint64(); - - const int64_t fee = (payment.get_amount() + 199) / 200; - const double net_payment = payment.get_amount() - fee; - const uint64_t expected_delta = net_payment * r0.get_amount() / ( net_payment + e0.get_amount() ); - - BOOST_REQUIRE_EQUAL( expected_delta, bytes1 - bytes0 ); - } - -} 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_from_string("0.0000"), get_balance( "alice1111111"_n ) ); - transfer( "eosio"_n, "alice1111111"_n, core_from_string("1000.0000"), "eosio"_n ); - - BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio"_n, "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - - auto total = get_total_stake("alice1111111"_n); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - - const auto init_eosio_stake_balance = get_balance( "eosio.stake"_n ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( init_eosio_stake_balance + core_from_string("300.0000"), get_balance( "eosio.stake"_n ) ); - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - - produce_block( fc::hours(3*24-1) ); - produce_blocks(1); - // testing balance still the same - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( init_eosio_stake_balance + core_from_string("300.0000"), get_balance( "eosio.stake"_n ) ); - // call refund expected to fail too early - BOOST_REQUIRE_EQUAL( wasm_assert_msg("refund is not available yet"), - push_action( "alice1111111"_n, "refund"_n, mvo()("owner", "alice1111111"_n) ) ); - - // after 1 hour refund ready - produce_block( fc::hours(1) ); - produce_blocks(1); - // now we can do the refund - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "refund"_n, mvo()("owner", "alice1111111"_n) ) ); - BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( init_eosio_stake_balance, get_balance( "eosio.stake"_n ) ); - - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "bob111111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - total = get_total_stake("bob111111111"_n); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000").get_amount(), total["net_weight"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000").get_amount(), total["cpu_weight"].as().get_amount() ); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("300.0000")), get_voter_info( "alice1111111"_n ) ); - - auto bytes = total["ram_bytes"].as_uint64(); - BOOST_REQUIRE_EQUAL( true, 0 < bytes ); - - //unstake from bob111111111 - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, "bob111111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - total = get_total_stake("bob111111111"_n); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); - produce_block( fc::hours(3*24-1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - //after 3 days funds should be released - produce_block( fc::hours(1) ); - produce_blocks(1); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("0.0000") ), get_voter_info( "alice1111111"_n ) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "refund"_n, mvo()("owner", "alice1111111"_n) ) ); - BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111"_n ) ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111"_n ) ); - - //eosio stakes for alice with transfer flag - - transfer( "eosio"_n, "bob111111111"_n, core_from_string("1000.0000"), "eosio"_n ); - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111"_n, "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - - //check that alice has both bandwidth and voting power - auto total = get_total_stake("alice1111111"_n); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("300.0000")), get_voter_info( "alice1111111"_n ) ); - - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111"_n ) ); - - //alice stakes for herself - transfer( "eosio"_n, "alice1111111"_n, core_from_string("1000.0000"), "eosio"_n ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - //now alice's stake should be equal to transferred from eosio + own stake - total = get_total_stake("alice1111111"_n); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( core_from_string("410.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("600.0000")), get_voter_info( "alice1111111"_n ) ); - - //alice can unstake everything (including what was transferred) - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, "alice1111111"_n, core_from_string("400.0000"), core_from_string("200.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - - produce_block( fc::hours(3*24-1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - //after 3 days funds should be released - - produce_block( fc::hours(1) ); - produce_blocks(1); - - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "refund"_n, mvo()("owner", "alice1111111"_n) ) ); - BOOST_REQUIRE_EQUAL( core_from_string("1300.0000"), get_balance( "alice1111111"_n ) ); - - //stake should be equal to what was staked in constructor, voting power should be 0 - total = get_total_stake("alice1111111"_n); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("0.0000")), get_voter_info( "alice1111111"_n ) ); - - // Now alice stakes to bob with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111"_n, "bob111111111"_n, core_from_string("100.0000"), core_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_from_string("0.0000"), get_balance( "alice1111111"_n ) ); - transfer( "eosio"_n, "alice1111111"_n, core_from_string("1000.0000"), "eosio"_n ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot use transfer flag if delegating to self"), - stake_with_transfer( "alice1111111"_n, "alice1111111"_n, core_from_string("200.0000"), core_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_from_string("0.0000"), get_balance( "alice1111111"_n ) ); - - //eosio stakes for alice with transfer flag - transfer( "eosio"_n, "bob111111111"_n, core_from_string("1000.0000"), "eosio"_n ); - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111"_n, "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - - //check that alice has both bandwidth and voting power - auto total = get_total_stake("alice1111111"_n); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("300.0000")), get_voter_info( "alice1111111"_n ) ); - - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111"_n ) ); - - //alice stakes for herself - transfer( "eosio"_n, "alice1111111"_n, core_from_string("1000.0000"), "eosio"_n ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - //now alice's stake should be equal to transferred from eosio + own stake - total = get_total_stake("alice1111111"_n); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( core_from_string("410.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("600.0000")), get_voter_info( "alice1111111"_n ) ); - - //alice can unstake everything (including what was transferred) - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, "alice1111111"_n, core_from_string("400.0000"), core_from_string("200.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - - produce_block( fc::hours(3*24-1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - //after 3 days funds should be released - - produce_block( fc::hours(1) ); - produce_blocks(1); - - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "refund"_n, mvo()("owner", "alice1111111"_n) ) ); - BOOST_REQUIRE_EQUAL( core_from_string("1300.0000"), get_balance( "alice1111111"_n ) ); - - //stake should be equal to what was staked in constructor, voting power should be 0 - total = get_total_stake("alice1111111"_n); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("0.0000")), get_voter_info( "alice1111111"_n ) ); - - // Now alice stakes to bob with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111"_n, "bob111111111"_n, core_from_string("100.0000"), core_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"_n, core_from_string("1000.0000"), config::system_account_name ); - - BOOST_REQUIRE_EQUAL( success(), stake( "eosio"_n, "alice1111111"_n, core_from_string("2000.0000"), core_from_string("1000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "bob111111111"_n, core_from_string("10.0000"), core_from_string("10.0000") ) ); - - BOOST_REQUIRE_EQUAL( error("missing authority of alice1111111"), - push_action( "alice1111111"_n, "delegatebw"_n, mvo() - ("from", "alice1111111"_n) - ("receiver", "bob111111111"_n) - ("stake_net_quantity", core_from_string("10.0000")) - ("stake_cpu_quantity", core_from_string("10.0000")) - ("transfer", 0 ) - ,false - ) - ); - - BOOST_REQUIRE_EQUAL( error("missing authority of alice1111111"), - push_action("alice1111111"_n, "undelegatebw"_n, mvo() - ("from", "alice1111111"_n) - ("receiver", "bob111111111"_n) - ("unstake_net_quantity", core_from_string("200.0000")) - ("unstake_cpu_quantity", core_from_string("100.0000")) - ("transfer", 0 ) - ,false - ) - ); - //REQUIRE_MATCHING_OBJECT( , get_voter_info( "alice1111111"_n ) ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( stake_negative, eosio_system_tester ) try { - issue_and_transfer( "alice1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111"_n, core_from_string("-0.0001"), core_from_string("0.0000") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111"_n, core_from_string("0.0000"), core_from_string("-0.0001") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111"_n, core_from_string("00.0000"), core_from_string("00.0000") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111"_n, core_from_string("0.0000"), core_from_string("00.0000") ) - - ); - - BOOST_REQUIRE_EQUAL( true, get_voter_info( "alice1111111"_n ).is_null() ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( unstake_negative, eosio_system_tester ) try { - issue_and_transfer( "alice1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "bob111111111"_n, core_from_string("200.0001"), core_from_string("100.0001") ) ); - - auto total = get_total_stake( "bob111111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0001"), total["net_weight"].as()); - auto vinfo = get_voter_info("alice1111111"_n ); - wdump((vinfo)); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("300.0002") ), get_voter_info( "alice1111111"_n ) ); - - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), - unstake( "alice1111111"_n, "bob111111111"_n, core_from_string("-1.0000"), core_from_string("0.0000") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), - unstake( "alice1111111"_n, "bob111111111"_n, core_from_string("0.0000"), core_from_string("-1.0000") ) - ); - - //unstake all zeros - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), - unstake( "alice1111111"_n, "bob111111111"_n, core_from_string("0.0000"), core_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"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - - auto total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - - //trying to unstake more net bandwidth than at stake - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), - unstake( "alice1111111"_n, core_from_string("200.0001"), core_from_string("0.0000") ) - ); - - //trying to unstake more cpu bandwidth than at stake - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), - unstake( "alice1111111"_n, core_from_string("0.0000"), core_from_string("100.0001") ) - - ); - - //check that nothing has changed - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( delegate_to_another_user, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - - BOOST_REQUIRE_EQUAL( success(), stake ( "alice1111111"_n, "bob111111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - - auto total = get_total_stake( "bob111111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - //all voting power goes to alice1111111 - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("300.0000") ), get_voter_info( "alice1111111"_n ) ); - //but not to bob111111111 - BOOST_REQUIRE_EQUAL( true, get_voter_info( "bob111111111"_n ).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"_n, core_from_string("0.0000"), core_from_string("10.0000") ) - - ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), - unstake( "bob111111111"_n, core_from_string("10.0000"), core_from_string("0.0000") ) - ); - - issue_and_transfer( "carol1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111"_n, "bob111111111"_n, core_from_string("20.0000"), core_from_string("10.0000") ) ); - total = get_total_stake( "bob111111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("230.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("120.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("970.0000"), get_balance( "carol1111111"_n ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111"_n, core_from_string("30.0000") ), get_voter_info( "carol1111111"_n ) ); - - //alice1111111 should not be able to unstake money staked by carol1111111 - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), - unstake( "alice1111111"_n, "bob111111111"_n, core_from_string("2001.0000"), core_from_string("1.0000") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), - unstake( "alice1111111"_n, "bob111111111"_n, core_from_string("1.0000"), core_from_string("101.0000") ) - - ); - - total = get_total_stake( "bob111111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("230.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("120.0000"), total["cpu_weight"].as()); - //balance should not change after unsuccessful attempts to unstake - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - //voting power too - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("300.0000") ), get_voter_info( "alice1111111"_n ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111"_n, core_from_string("30.0000") ), get_voter_info( "carol1111111"_n ) ); - BOOST_REQUIRE_EQUAL( true, get_voter_info( "bob111111111"_n ).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"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111"_n ) ); - - //everything at once - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, core_from_string("10.0000"), core_from_string("20.0000") ) ); - auto total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("20.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("30.0000"), total["cpu_weight"].as()); - - //cpu - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, core_from_string("100.0000"), core_from_string("0.0000") ) ); - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("120.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("30.0000"), total["cpu_weight"].as()); - - //net - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, core_from_string("0.0000"), core_from_string("200.0000") ) ); - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("120.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("230.0000"), total["cpu_weight"].as()); - - //unstake cpu - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, core_from_string("100.0000"), core_from_string("0.0000") ) ); - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("20.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("230.0000"), total["cpu_weight"].as()); - - //unstake net - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, core_from_string("0.0000"), core_from_string("200.0000") ) ); - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("20.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_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"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "bob111111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("300.0000") ), get_voter_info( "alice1111111"_n ) ); - - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "bob111111111"_n, core_from_string("100.0000"), core_from_string("50.0000") ) ); - - auto total = get_total_stake( "bob111111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("310.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("160.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("450.0000") ), get_voter_info( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( core_from_string("550.0000"), get_balance( "alice1111111"_n ) ); - - //unstake a share - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, "bob111111111"_n, core_from_string("150.0000"), core_from_string("75.0000") ) ); - - total = get_total_stake( "bob111111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("160.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("85.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("225.0000") ), get_voter_info( "alice1111111"_n ) ); - - //unstake more - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, "bob111111111"_n, core_from_string("50.0000"), core_from_string("25.0000") ) ); - total = get_total_stake( "bob111111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("150.0000") ), get_voter_info( "alice1111111"_n ) ); - - //combined amount should be available only in 3 days - produce_block( fc::days(2) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("550.0000"), get_balance( "alice1111111"_n ) ); - produce_block( fc::days(1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "refund"_n, mvo()("owner", "alice1111111"_n) ) ); - BOOST_REQUIRE_EQUAL( core_from_string("850.0000"), get_balance( "alice1111111"_n ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - - auto total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "bob111111111"_n, core_from_string("50.0000"), core_from_string("50.0000") ) ); - - total = get_total_stake( "bob111111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("400.0000") ), get_voter_info( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( core_from_string("600.0000"), get_balance( "alice1111111"_n ) ); - - //unstake a share - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, "alice1111111"_n, core_from_string("100.0000"), core_from_string("50.0000") ) ); - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("250.0000") ), get_voter_info( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( core_from_string("600.0000"), get_balance( "alice1111111"_n ) ); - auto refund = get_refund_request( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_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"_n, "bob111111111"_n, core_from_string("50.0000"), core_from_string("50.0000") ) ); - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("350.0000") ), get_voter_info( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111"_n ) ); - refund = get_refund_request( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_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"_n, "alice1111111"_n, core_from_string("50.0000"), core_from_string("25.0000") ) ); - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("160.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("85.0000"), total["cpu_weight"].as()); - refund = get_refund_request( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("50.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_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_from_string("500.0000"), get_balance( "alice1111111"_n ) ); - - //stake exactly pending refund amount - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "alice1111111"_n, core_from_string("50.0000"), core_from_string("25.0000") ) ); - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - //pending refund should be removed - refund = get_refund_request( "alice1111111"_n ); - BOOST_TEST_REQUIRE( refund.is_null() ); - //balance should stay the same - BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111"_n ) ); - - //create pending refund again - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111"_n ) ); - refund = get_refund_request( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("200.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["cpu_amount"].as() ); - - //stake more than pending refund - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "alice1111111"_n, core_from_string("300.0000"), core_from_string("200.0000") ) ); - total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("310.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("700.0000") ), get_voter_info( "alice1111111"_n ) ); - refund = get_refund_request( "alice1111111"_n ); - BOOST_TEST_REQUIRE( refund.is_null() ); - //200 core tokens should be taken from alice's account - BOOST_REQUIRE_EQUAL( core_from_string("300.0000"), get_balance( "alice1111111"_n ) ); - -} 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"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - - auto total = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n, core_from_string("300.0000") ), get_voter_info( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111"_n ) ); - - //unstake - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - auto refund = get_refund_request( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("200.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_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"_n, "bob111111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - total = get_total_stake( "bob111111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - //stake should be taken from alice's balance, and refund request should stay the same - BOOST_REQUIRE_EQUAL( core_from_string("400.0000"), get_balance( "alice1111111"_n ) ); - refund = get_refund_request( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( core_from_string("200.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_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"_n, core_from_string("1000.0000"), config::system_account_name ); - - //fc::variant params = producer_parameters_example(1); - auto key = fc::crypto::public_key( std::string("EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV") ); // cspell:disable-line - BOOST_REQUIRE_EQUAL( success(), push_action("alice1111111"_n, "regproducer"_n, mvo() - ("producer", "alice1111111"_n) - ("producer_key", key ) - ("url", "http://block.one") - ("location", 1) - ) - ); - - auto info = get_producer_info( "alice1111111"_n ); - 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("alice1111111"_n, "regproducer"_n, mvo() - ("producer", "alice1111111"_n) - ("producer_key", key ) - ("url", "http://block.two") - ("location", 1) - ) - ); - info = get_producer_info( "alice1111111"_n ); - 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") ); // cspell:disable-line - BOOST_REQUIRE_EQUAL( success(), push_action("alice1111111"_n, "regproducer"_n, mvo() - ("producer", "alice1111111"_n) - ("producer_key", key2 ) - ("url", "http://block.two") - ("location", 2) - ) - ); - info = get_producer_info( "alice1111111"_n ); - 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("alice1111111"_n, "unregprod"_n, mvo() - ("producer", "alice1111111"_n) - ) - ); - info = get_producer_info( "alice1111111"_n ); - //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( "bob111111111"_n, "unregprod"_n, mvo() - ("producer", "bob111111111"_n) - ) - ); - -} 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"_n, core_from_string("1000.0000"), config::system_account_name ); - fc::variant params = producer_parameters_example(1); - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "regproducer"_n, mvo() - ("producer", "alice1111111"_n) - ("producer_key", get_public_key( "alice1111111"_n, "active") ) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - auto prod = get_producer_info( "alice1111111"_n ); - 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"_n, core_from_string("2000.0000"), config::system_account_name ); - issue_and_transfer( "carol1111111"_n, core_from_string("3000.0000"), config::system_account_name ); - - //bob111111111 makes stake - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("11.0000"), core_from_string("0.1111") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("1988.8889"), get_balance( "bob111111111"_n ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111"_n, core_from_string("11.1111") ), get_voter_info( "bob111111111"_n ) ); - - //bob111111111 votes for alice1111111 - BOOST_REQUIRE_EQUAL( success(), vote( "bob111111111"_n, { "alice1111111"_n } ) ); - - //check that producer parameters stay the same after voting - prod = get_producer_info( "alice1111111"_n ); - BOOST_TEST_REQUIRE( stake2votes(core_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"_n, core_from_string("22.0000"), core_from_string("0.2222") ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111"_n, core_from_string("22.2222") ), get_voter_info( "carol1111111"_n ) ); - BOOST_REQUIRE_EQUAL( core_from_string("2977.7778"), get_balance( "carol1111111"_n ) ); - //carol1111111 votes for alice1111111 - BOOST_REQUIRE_EQUAL( success(), vote( "carol1111111"_n, { "alice1111111"_n } ) ); - - //new stake votes be added to alice1111111's total_votes - prod = get_producer_info( "alice1111111"_n ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("33.3333")) == prod["total_votes"].as_double() ); - - //bob111111111 increases his stake - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("33.0000"), core_from_string("0.3333") ) ); - //alice1111111 stake with transfer to bob111111111 - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111"_n, "bob111111111"_n, core_from_string("22.0000"), core_from_string("0.2222") ) ); - //should increase alice1111111's total_votes - prod = get_producer_info( "alice1111111"_n ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("88.8888")) == prod["total_votes"].as_double() ); - - //carol1111111 unstakes part of the stake - BOOST_REQUIRE_EQUAL( success(), unstake( "carol1111111"_n, core_from_string("2.0000"), core_from_string("0.0002")/*"2.0000 EOS", "0.0002 EOS"*/ ) ); - - //should decrease alice1111111's total_votes - prod = get_producer_info( "alice1111111"_n ); - wdump((prod)); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("86.8886")) == prod["total_votes"].as_double() ); - - //bob111111111 revokes his vote - BOOST_REQUIRE_EQUAL( success(), vote( "bob111111111"_n, vector() ) ); - - //should decrease alice1111111's total_votes - prod = get_producer_info( "alice1111111"_n ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("20.2220")) == prod["total_votes"].as_double() ); - //but eos should still be at stake - BOOST_REQUIRE_EQUAL( core_from_string("1955.5556"), get_balance( "bob111111111"_n ) ); - - //carol1111111 unstakes rest of eos - BOOST_REQUIRE_EQUAL( success(), unstake( "carol1111111"_n, core_from_string("20.0000"), core_from_string("0.2220") ) ); - //should decrease alice1111111's total_votes to zero - prod = get_producer_info( "alice1111111"_n ); - BOOST_TEST_REQUIRE( 0.0 == prod["total_votes"].as_double() ); - - //carol1111111 should receive funds in 3 days - produce_block( fc::days(3) ); - produce_block(); - - // do a bid refund for carol - BOOST_REQUIRE_EQUAL( success(), push_action( "carol1111111"_n, "refund"_n, mvo()("owner", "carol1111111"_n) ) ); - BOOST_REQUIRE_EQUAL( core_from_string("3000.0000"), get_balance( "carol1111111"_n ) ); - -} 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"_n, core_from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("13.0000"), core_from_string("0.5791") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111"_n, core_from_string("13.5791") ), get_voter_info( "bob111111111"_n ) ); - - //bob111111111 should not be able to vote for alice1111111 who is not a producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer is not registered" ), - vote( "bob111111111"_n, { "alice1111111"_n } ) ); - - //alice1111111 registers as a producer - issue_and_transfer( "alice1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - fc::variant params = producer_parameters_example(1); - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "regproducer"_n, mvo() - ("producer", "alice1111111"_n) - ("producer_key", get_public_key( "alice1111111"_n, "active") ) - ("url", "") - ("location", 0) - ) - ); - //and then unregisters - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "unregprod"_n, mvo() - ("producer", "alice1111111"_n) - ) - ); - //key should be empty - auto prod = get_producer_info( "alice1111111"_n ); - 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 is not currently registered" ), - vote( "bob111111111"_n, { "alice1111111"_n } ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( more_than_30_producer_voting, eosio_system_tester ) try { - issue_and_transfer( "bob111111111"_n, core_from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("13.0000"), core_from_string("0.5791") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111"_n, core_from_string("13.5791") ), get_voter_info( "bob111111111"_n ) ); - - //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( "bob111111111"_n, vector(31, "alice1111111"_n) ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( vote_same_producer_30_times, eosio_system_tester ) try { - issue_and_transfer( "bob111111111"_n, core_from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("50.0000"), core_from_string("50.0000") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111"_n, core_from_string("100.0000") ), get_voter_info( "bob111111111"_n ) ); - - //alice1111111 becomes a producer - issue_and_transfer( "alice1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - fc::variant params = producer_parameters_example(1); - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "regproducer"_n, mvo() - ("producer", "alice1111111"_n) - ("producer_key", get_public_key("alice1111111"_n, "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( "bob111111111"_n, vector(30, "alice1111111"_n) ) ); - - auto prod = get_producer_info( "alice1111111"_n ); - 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"_n, core_from_string("1000.0000"), config::system_account_name ); - fc::variant params = producer_parameters_example(1); - vector key = fc::raw::pack( get_public_key( "alice1111111"_n, "active" ) ); - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "regproducer"_n, mvo() - ("producer", "alice1111111"_n) - ("producer_key", get_public_key( "alice1111111"_n, "active") ) - ("url", "") - ("location", 0) - ) - ); - - //bob111111111 makes stake - issue_and_transfer( "bob111111111"_n, core_from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("13.0000"), core_from_string("0.5791") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111"_n, core_from_string("13.5791") ), get_voter_info( "bob111111111"_n ) ); - - //bob111111111 votes for alice1111111 - BOOST_REQUIRE_EQUAL( success(), vote("bob111111111"_n, { "alice1111111"_n } ) ); - - auto prod = get_producer_info( "alice1111111"_n ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("13.5791")) == prod["total_votes"].as_double() ); - - //unregister producer - BOOST_REQUIRE_EQUAL( success(), push_action("alice1111111"_n, "unregprod"_n, mvo() - ("producer", "alice1111111"_n) - ) - ); - prod = get_producer_info( "alice1111111"_n ); - //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_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( "alice1111111"_n, "regproducer"_n, mvo() - ("producer", "alice1111111"_n) - ("producer_key", get_public_key( "alice1111111"_n, "active") ) - ("url", "") - ("location", 0) - ) - ); - prod = get_producer_info( "alice1111111"_n ); - //votes should stay the same - BOOST_TEST_REQUIRE( stake2votes(core_from_string("13.5791")), prod["total_votes"].as_double() ); - - //change parameters - params = producer_parameters_example(3); - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "regproducer"_n, mvo() - ("producer", "alice1111111"_n) - ("producer_key", get_public_key( "alice1111111"_n, "active") ) - ("url","") - ("location", 0) - ) - ); - prod = get_producer_info( "alice1111111"_n ); - //votes should stay the same - BOOST_TEST_REQUIRE( stake2votes(core_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( "alice1111111"_n, "active" ); - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "regproducer"_n, mvo() - ("producer", "alice1111111"_n) - ("producer_key", get_public_key( "alice1111111"_n, "active") ) - ("url","") - ("location", 0) - ) - ); - //bob111111111 becomes a producer - params = producer_parameters_example(2); - key = get_public_key( "bob111111111"_n, "active" ); - BOOST_REQUIRE_EQUAL( success(), push_action( "bob111111111"_n, "regproducer"_n, mvo() - ("producer", "bob111111111"_n) - ("producer_key", get_public_key( "alice1111111"_n, "active") ) - ("url","") - ("location", 0) - ) - ); - - //carol1111111 votes for alice1111111 and bob111111111 - issue_and_transfer( "carol1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111"_n, core_from_string("15.0005"), core_from_string("5.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( "carol1111111"_n, { "alice1111111"_n, "bob111111111"_n } ) ); - - auto alice_info = get_producer_info( "alice1111111"_n ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("20.0005")) == alice_info["total_votes"].as_double() ); - auto bob_info = get_producer_info( "bob111111111"_n ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("20.0005")) == bob_info["total_votes"].as_double() ); - - //carol1111111 votes for alice1111111 (but revokes vote for bob111111111) - BOOST_REQUIRE_EQUAL( success(), vote( "carol1111111"_n, { "alice1111111"_n } ) ); - - alice_info = get_producer_info( "alice1111111"_n ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("20.0005")) == alice_info["total_votes"].as_double() ); - bob_info = get_producer_info( "bob111111111"_n ); - BOOST_TEST_REQUIRE( 0 == bob_info["total_votes"].as_double() ); - - //alice1111111 votes for herself and bob111111111 - issue_and_transfer( "alice1111111"_n, core_from_string("2.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, core_from_string("1.0000"), core_from_string("1.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote("alice1111111"_n, { "alice1111111"_n, "bob111111111"_n } ) ); - - alice_info = get_producer_info( "alice1111111"_n ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("22.0005")) == alice_info["total_votes"].as_double() ); - - bob_info = get_producer_info( "bob111111111"_n ); - BOOST_TEST_REQUIRE( stake2votes(core_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("alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", true ) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111"_n ), get_voter_info( "alice1111111"_n ) ); - - //unregister proxy - BOOST_REQUIRE_EQUAL( success(), push_action("alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", false) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n ), get_voter_info( "alice1111111"_n ) ); - - //stake and then register as a proxy - issue_and_transfer( "bob111111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("200.0002"), core_from_string("100.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), push_action( "bob111111111"_n, "regproxy"_n, mvo() - ("proxy", "bob111111111"_n) - ("isproxy", true) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( "bob111111111"_n )( "staked", 3000003 ), get_voter_info( "bob111111111"_n ) ); - //unrgister and check that stake is still in place - BOOST_REQUIRE_EQUAL( success(), push_action( "bob111111111"_n, "regproxy"_n, mvo() - ("proxy", "bob111111111"_n) - ("isproxy", false) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111"_n, core_from_string("300.0003") ), get_voter_info( "bob111111111"_n ) ); - - //register as a proxy and then stake - BOOST_REQUIRE_EQUAL( success(), push_action( "carol1111111"_n, "regproxy"_n, mvo() - ("proxy", "carol1111111"_n) - ("isproxy", true) - ) - ); - issue_and_transfer( "carol1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111"_n, core_from_string("246.0002"), core_from_string("531.0001") ) ); - //check that both proxy flag and stake a correct - REQUIRE_MATCHING_OBJECT( proxy( "carol1111111"_n )( "staked", 7770003 ), get_voter_info( "carol1111111"_n ) ); - - //unregister - BOOST_REQUIRE_EQUAL( success(), push_action( "carol1111111"_n, "regproxy"_n, mvo() - ("proxy", "carol1111111"_n) - ("isproxy", false) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111"_n, core_from_string("777.0003") ), get_voter_info( "carol1111111"_n ) ); - -} 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( "alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", true) - ) - ); - issue_and_transfer( "alice1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111"_n ), get_voter_info( "alice1111111"_n ) ); - - //stake - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, core_from_string("100.0000"), core_from_string("50.0000") ) ); - //check that account is still a proxy - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111"_n )( "staked", 1500000 ), get_voter_info( "alice1111111"_n ) ); - - //stake more - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, core_from_string("30.0000"), core_from_string("20.0000") ) ); - //check that account is still a proxy - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111"_n )("staked", 2000000 ), get_voter_info( "alice1111111"_n ) ); - - //unstake more - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, core_from_string("65.0000"), core_from_string("35.0000") ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111"_n )("staked", 1000000 ), get_voter_info( "alice1111111"_n ) ); - - //unstake the rest - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, core_from_string("65.0000"), core_from_string("35.0000") ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111"_n )( "staked", 0 ), get_voter_info( "alice1111111"_n ) ); - -} 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( { "defproducer1"_n, "defproducer2"_n, "defproducer3"_n } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer1"_n, 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer2"_n, 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3"_n, 3) ); - - //register as a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", true) - ) - ); - - //accumulate proxied votes - issue_and_transfer( "bob111111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("100.0002"), core_from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote("bob111111111"_n, vector(), "alice1111111"_n ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111"_n )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")) ), get_voter_info( "alice1111111"_n ) ); - - //vote for producers - BOOST_REQUIRE_EQUAL( success(), vote("alice1111111"_n, { "defproducer1"_n, "defproducer2"_n } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_producer_info( "defproducer3"_n )["total_votes"].as_double() ); - - //vote for another producers - BOOST_REQUIRE_EQUAL( success(), vote( "alice1111111"_n, { "defproducer1"_n, "defproducer3"_n } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer3"_n )["total_votes"].as_double() ); - - //unregister proxy - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", false) - ) - ); - //REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")) ), get_voter_info( "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3"_n )["total_votes"].as_double() ); - - //register proxy again - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", true) - ) - ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer3"_n )["total_votes"].as_double() ); - - //stake increase by proxy itself affects producers - issue_and_transfer( "alice1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, core_from_string("30.0001"), core_from_string("20.0001") ) ); - BOOST_REQUIRE_EQUAL( stake2votes(core_from_string("200.0005")), get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( stake2votes(core_from_string("200.0005")), get_producer_info( "defproducer3"_n )["total_votes"].as_double() ); - - //stake decrease by proxy itself affects producers - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111"_n, core_from_string("10.0001"), core_from_string("10.0001") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("180.0003")) == get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("180.0003")) == get_producer_info( "defproducer3"_n )["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_SUITE_END() - -BOOST_AUTO_TEST_SUITE(eosio_system_part2_tests) - -BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); - const std::vector voters = { "producvotera"_n, "producvoterb"_n, "producvoterc"_n, "producvoterd"_n }; - for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_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("producvotera"_n, 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("producvoterb"_n, 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("producvoterc"_n, 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("producvoterd"_n, 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( "defproducera"_n ); - auto prodj = get_producer_info( "defproducerj"_n ); - auto prodk = get_producer_info( "defproducerk"_n ); - auto produ = get_producer_info( "defproduceru"_n ); - auto prodv = get_producer_info( "defproducerv"_n ); - auto prodz = get_producer_info( "defproducerz"_n ); - - 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, "claimrewards"_n, 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_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); - const std::vector accounts = { "aliceaccount"_n, "bobbyaccount"_n, "carolaccount"_n, "emilyaccount"_n }; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_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_from_string("100.0000"), core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( votb, core_from_string("100.0000"), core_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, "claimrewards"_n, 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, "claimrewards"_n, 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_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); - const std::vector accounts = { "aliceaccount"_n, "bobbyaccount"_n, "carolaccount"_n, "emilyaccount"_n }; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_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, "regproxy"_n, 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_from_string("100.0002"), core_from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( alice, core_from_string("150.0000"), core_from_string("150.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( bob, { }, alice ) ); - BOOST_TEST_REQUIRE( stake2votes(core_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_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_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_from_string("10.0002"), core_from_string("10.0001") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_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, "claimrewards"_n, mvo()("owner", carol)) ); - - produce_block( fc::hours(20) ); - - // bob votes for carol - BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_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, "claimrewards"_n, 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_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); - const std::vector accounts = { "aliceaccount"_n, "bobbyaccount"_n, "carolaccount"_n, "emilyaccount"_n }; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_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_from_string("100.0000"), core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( bob, core_from_string("100.0000"), core_from_string("100.0000") ) ); - - BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); - - - BOOST_REQUIRE_EQUAL( success(), push_action( carol, "claimrewards"_n, mvo()("owner", carol) ) ); - produce_block( fc::hours(1) ); - BOOST_REQUIRE_EQUAL( success(), push_action( emily, "claimrewards"_n, 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, "claimrewards"_n, { {carol, config::active_name} }, - mvo()("owner", carol) ) ); - - std::vector prods = { carol, emily }; - trx.actions.emplace_back( get_action( config::system_account_name, "voteproducer"_n, { {alice, config::active_name} }, - mvo()("voter", alice)("proxy", name(0))("producers", prods) ) ); - - trx.actions.emplace_back( get_action( config::system_account_name, "claimrewards"_n, { {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_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); - const std::vector voters = { "producvotera"_n, "producvoterb"_n, "producvoterc"_n, "producvoterd"_n }; - for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), 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)); - } - } - 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("producvotera"_n, vector(producer_names.begin(), producer_names.end())) ); - auto* tbl = control->db().find( - boost::make_tuple( config::system_account_name, - config::system_account_name, - "producers2"_n ) ); - BOOST_REQUIRE( tbl ); - BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( get_producer_info2("defproducera"_n)["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, - "producers2"_n ) ); - BOOST_REQUIRE( !tbl ); - - BOOST_REQUIRE_EQUAL( success(), vote("producvoterb"_n, vector(producer_names.begin(), producer_names.end())) ); - tbl = control->db().find( - boost::make_tuple( config::system_account_name, - config::system_account_name, - "producers2"_n ) ); - BOOST_REQUIRE( !tbl ); - BOOST_REQUIRE_EQUAL( success(), regproducer("defproducera"_n) ); - BOOST_REQUIRE( microseconds_since_epoch_of_iso_string( get_producer_info("defproducera"_n)["last_claim_time"] ) < microseconds_since_epoch_of_iso_string( get_producer_info2("defproducera"_n)["last_votepay_share_update"] ) ); - - create_account_with_resources( "defproducer1"_n, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - BOOST_REQUIRE_EQUAL( success(), regproducer("defproducer1"_n) ); - BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( get_producer_info("defproducer1"_n)["last_claim_time"] ) ); - BOOST_REQUIRE_EQUAL( get_producer_info("defproducer1"_n)["last_claim_time"].as_string(), - get_producer_info2("defproducer1"_n)["last_votepay_share_update"].as_string() ); - -} 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(); - - //change `default_max_inline_action_size` to 512 KB - eosio::chain::chain_config params = control->get_global_properties().configuration; - params.max_inline_action_size = 512 * 1024; - base_tester::push_action( config::system_account_name, "setparams"_n, config::system_account_name, mutable_variant_object() - ("params", params) ); - - produce_blocks(); - - //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 = "eosio.msig"_n; - 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 == "bob111111111"_n ? "alice1111111"_n : "bob111111111"_n).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 = test_contracts::eosio_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 ); - - fc::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( "alice1111111"_n, "propose"_n, mvo() - ("proposer", "alice1111111"_n) - ("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]), "approve"_n, mvo() - ("proposer", "alice1111111"_n) - ("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( "alice1111111"_n, "exec"_n, mvo() - ("proposer", "alice1111111"_n) - ("proposal_name", "upgrade1") - ("executer", "alice1111111"_n) - ) - ); - - // one more approval - BOOST_REQUIRE_EQUAL(success(), push_action_msig( name(producer_names[14]), "approve"_n, mvo() - ("proposer", "alice1111111"_n) - ("proposal_name", "upgrade1") - ("level", permission_level{ name(producer_names[14]), config::active_name }) - ) - ); - - transaction_trace_ptr trace; - control->applied_transaction().connect( - [&]( std::tuple p ) { - trace = std::get<0>(p); - } ); - - BOOST_REQUIRE_EQUAL(success(), push_action_msig( "alice1111111"_n, "exec"_n, mvo() - ("proposer", "alice1111111"_n) - ("proposal_name", "upgrade1") - ("executer", "alice1111111"_n) - ) - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1u, 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_from_string("80.0000"); - create_account_with_resources( "producvotera"_n, config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( "producvoterb"_n, config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( "producvoterc"_n, config::system_account_name, core_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"_n, core_from_string("200000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvotera"_n, core_from_string("70000000.0000"), core_from_string("70000000.0000") )); - BOOST_REQUIRE_EQUAL(success(), vote( "producvotera"_n, 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"_n, core_from_string("50.0000"), core_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(0u, get_global_state()["total_unpaid_blocks"].as()); - BOOST_REQUIRE_EQUAL(wasm_assert_msg( claimrewards_activation_error_message ), - push_action(producer_names.front(), "claimrewards"_n, 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(), "claimrewards"_n, 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"_n, core_from_string("100000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvoterb"_n, core_from_string("4000000.0000"), core_from_string("4000000.0000"))); - transfer(config::system_account_name, "producvoterc"_n, core_from_string("100000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvoterc"_n, core_from_string("2000000.0000"), core_from_string("2000000.0000"))); - - BOOST_REQUIRE_EQUAL(success(), vote( "producvoterb"_n, vector(producer_names.begin(), producer_names.begin()+21))); - BOOST_REQUIRE_EQUAL(success(), vote( "producvoterc"_n, 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(), "claimrewards"_n, mvo()("owner", producer_names.front()))); - BOOST_REQUIRE(0 < get_balance(producer_names.front()).get_amount()); - } - - BOOST_CHECK_EQUAL( success(), unstake( "producvotera"_n, core_from_string("50.0000"), core_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( { "donald111111"_n, "defproducer1"_n, "defproducer2"_n, "defproducer3"_n } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer1"_n, 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer2"_n, 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3"_n, 3) ); - - //alice1111111 becomes a producer - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", true) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111"_n ), get_voter_info( "alice1111111"_n ) ); - - //alice1111111 makes stake and votes - issue_and_transfer( "alice1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, core_from_string("30.0001"), core_from_string("20.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( "alice1111111"_n, { "defproducer1"_n, "defproducer2"_n } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("50.0002")) == get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("50.0002")) == get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3"_n )["total_votes"].as_double() ); - - BOOST_REQUIRE_EQUAL( success(), push_action( "donald111111"_n, "regproxy"_n, mvo() - ("proxy", "donald111111") - ("isproxy", true) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( "donald111111"_n ), get_voter_info( "donald111111"_n ) ); - - //bob111111111 chooses alice1111111 as a proxy - issue_and_transfer( "bob111111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("100.0002"), core_from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( "bob111111111"_n, vector(), "alice1111111"_n ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_voter_info( "alice1111111"_n )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("200.0005")) == get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("200.0005")) == get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3"_n )["total_votes"].as_double() ); - - //carol1111111 chooses alice1111111 as a proxy - issue_and_transfer( "carol1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111"_n, core_from_string("30.0001"), core_from_string("20.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( "carol1111111"_n, vector(), "alice1111111"_n ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("200.0005")) == get_voter_info( "alice1111111"_n )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("250.0007")) == get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("250.0007")) == get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3"_n )["total_votes"].as_double() ); - - //proxied voter carol1111111 increases stake - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111"_n, core_from_string("50.0000"), core_from_string("70.0000") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("320.0005")) == get_voter_info( "alice1111111"_n )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("370.0007")) == get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("370.0007")) == get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3"_n )["total_votes"].as_double() ); - - //proxied voter bob111111111 decreases stake - BOOST_REQUIRE_EQUAL( success(), unstake( "bob111111111"_n, core_from_string("50.0001"), core_from_string("50.0001") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("220.0003")) == get_voter_info( "alice1111111"_n )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("270.0005")) == get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("270.0005")) == get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3"_n )["total_votes"].as_double() ); - - //proxied voter carol1111111 chooses another proxy - BOOST_REQUIRE_EQUAL( success(), vote( "carol1111111"_n, vector(), "donald111111"_n ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("50.0001")), get_voter_info( "alice1111111"_n )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("170.0002")), get_voter_info( "donald111111"_n )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("100.0003")), get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("100.0003")), get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3"_n )["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( "bob111111111"_n, { "defproducer2"_n } ) ); - BOOST_TEST_REQUIRE( 0.0 == get_voter_info( "alice1111111"_n )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("50.0002")), get_producer_info( "defproducer1"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("100.0003")), get_producer_info( "defproducer2"_n )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( 0.0 == get_producer_info( "defproducer3"_n )["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( "alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", true) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111"_n ), get_voter_info( "alice1111111"_n ) ); - - //carol1111111 becomes a producer - BOOST_REQUIRE_EQUAL( success(), regproducer( "carol1111111"_n, 1) ); - - //bob111111111 chooses alice1111111 as a proxy - - issue_and_transfer( "bob111111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("100.0002"), core_from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot vote for producers and proxy at same time"), - vote( "bob111111111"_n, { "carol1111111"_n }, "alice1111111"_n ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( select_invalid_proxy, eosio_system_tester ) try { - //accumulate proxied votes - issue_and_transfer( "bob111111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("100.0002"), core_from_string("50.0001") ) ); - - //selecting account not registered as a proxy - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "invalid proxy specified" ), - vote( "bob111111111"_n, vector(), "alice1111111"_n ) ); - - //selecting not existing account as a proxy - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "invalid proxy specified" ), - vote( "bob111111111"_n, vector(), "notexist"_n ) ); - -} 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( "alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", 1) - ) - ); - issue_and_transfer( "alice1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, core_from_string("5.0000"), core_from_string("5.0000") ) ); - edump((get_voter_info("alice1111111"_n))); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111"_n )( "staked", 100000 ), get_voter_info( "alice1111111"_n ) ); - - //bob111111111 stakes and selects alice1111111 as a proxy - issue_and_transfer( "bob111111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("100.0002"), core_from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( "bob111111111"_n, vector(), "alice1111111"_n ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111"_n )( "proxied_vote_weight", stake2votes( core_from_string("150.0003") ))( "staked", 100000 ), get_voter_info( "alice1111111"_n ) ); - - //double regestering should fail without affecting total votes and stake - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "action has no effect" ), - push_action( "alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", 1) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111"_n )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111"_n ) ); - - //uregister - BOOST_REQUIRE_EQUAL( success(), push_action( "alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", 0) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111"_n ) ); - - //double unregistering should not affect proxied_votes and stake - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "action has no effect" ), - push_action( "alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", 0) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111"_n )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")))( "staked", 100000 ), get_voter_info( "alice1111111"_n ) ); - -} 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( "alice1111111"_n, "regproxy"_n, mvo() - ("proxy", "alice1111111"_n) - ("isproxy", 1) - ) - ); - - //bob111111111 becomes a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( "bob111111111"_n, "regproxy"_n, mvo() - ("proxy", "bob111111111"_n) - ("isproxy", 1) - ) - ); - - //proxy should not be able to use a proxy - issue_and_transfer( "bob111111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("100.0002"), core_from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "account registered as a proxy is not allowed to use a proxy" ), - vote( "bob111111111"_n, vector(), "alice1111111"_n ) ); - - //voter that uses a proxy should not be allowed to become a proxy - issue_and_transfer( "carol1111111"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111"_n, core_from_string("100.0002"), core_from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( "carol1111111"_n, vector(), "alice1111111"_n ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "account that uses a proxy is not allowed to become a proxy" ), - push_action( "carol1111111"_n, "regproxy"_n, mvo() - ("proxy", "carol1111111"_n) - ("isproxy", 1) - ) - ); - - //proxy should not be able to use itself as a proxy - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "cannot proxy to self" ), - vote( "bob111111111"_n, vector(), "bob111111111"_n ) ); - -} 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( { "defproducer1"_n, "defproducer2"_n, "defproducer3"_n } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer1"_n, 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer2"_n, 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3"_n, 3) ); - - //stake more than 15% of total EOS supply to activate chain - transfer( "eosio"_n, "alice1111111"_n, core_from_string("600000000.0000"), "eosio"_n ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111"_n, "alice1111111"_n, core_from_string("300000000.0000"), core_from_string("300000000.0000") ) ); - //vote for producers - BOOST_REQUIRE_EQUAL( success(), vote( "alice1111111"_n, { "defproducer1"_n } ) ); - produce_blocks(250); - auto producer_keys = control->active_producers(); - BOOST_REQUIRE_EQUAL( 1u, producer_keys.producers.size() ); - BOOST_REQUIRE_EQUAL( name("defproducer1"_n), producer_keys.producers[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"_n, core_from_string("80000.0000"), config::system_account_name ); - ilog("stake"); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111"_n, core_from_string("40000.0000"), core_from_string("40000.0000") ) ); - ilog("start vote"); - BOOST_REQUIRE_EQUAL( success(), vote( "bob111111111"_n, { "defproducer2"_n } ) ); - ilog("."); - produce_blocks(250); - producer_keys = control->active_producers(); - BOOST_REQUIRE_EQUAL( 2u, producer_keys.producers.size() ); - BOOST_REQUIRE_EQUAL( name("defproducer1"_n), producer_keys.producers[0].producer_name ); - BOOST_REQUIRE_EQUAL( name("defproducer2"_n), producer_keys.producers[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( "bob111111111"_n, { "defproducer2"_n, "defproducer3"_n } ) ); - produce_blocks(250); - producer_keys = control->active_producers(); - BOOST_REQUIRE_EQUAL( 3u, producer_keys.producers.size() ); - BOOST_REQUIRE_EQUAL( name("defproducer1"_n), producer_keys.producers[0].producer_name ); - BOOST_REQUIRE_EQUAL( name("defproducer2"_n), producer_keys.producers[1].producer_name ); - BOOST_REQUIRE_EQUAL( name("defproducer3"_n), producer_keys.producers[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( "bob111111111"_n, { "defproducer3"_n } ) ); - produce_blocks(250); - producer_keys = control->active_producers(); - BOOST_REQUIRE_EQUAL( 3u, producer_keys.producers.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"_n), producer_keys[0].producer_name ); - BOOST_REQUIRE_EQUAL( name("defproducer3"_n), 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( { "dan"_n, "sam"_n } ); - transfer( config::system_account_name, "dan"_n, core_from_string( "10000.0000" ) ); - transfer( config::system_account_name, "sam"_n, core_from_string( "10000.0000" ) ); - stake_with_transfer( config::system_account_name, "sam"_n, core_from_string( "80000000.0000" ), core_from_string( "80000000.0000" ) ); - stake_with_transfer( config::system_account_name, "dan"_n, core_from_string( "80000000.0000" ), core_from_string( "80000000.0000" ) ); - - regproducer( config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), vote( "sam"_n, { config::system_account_name } ) ); - // wait 14 days after min required amount has been staked - produce_block( fc::days(7) ); - BOOST_REQUIRE_EQUAL( success(), vote( "dan"_n, { config::system_account_name } ) ); - produce_block( fc::days(7) ); - produce_block(); - - BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { "fail"_n }, "dan"_n ), // dan shouldn't be able to create fail - eosio_assert_message_exception, eosio_assert_message_is( "no active bid for name" ) ); - bidname( "dan"_n, "nofail"_n, core_from_string( "1.0000" ) ); - BOOST_REQUIRE_EQUAL( "assertion failure with message: must increase bid by 10%", bidname( "sam"_n, "nofail"_n, core_from_string( "1.0000" ) )); // didn't increase bid by 10% - BOOST_REQUIRE_EQUAL( success(), bidname( "sam"_n, "nofail"_n, core_from_string( "2.0000" ) )); // didn't increase bid by 10% - produce_block( fc::days(1) ); - produce_block(); - - BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { "nofail"_n }, "dan"_n ), // 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( { "nofail"_n }, "sam"_n ); // sam should be able to do this, he won the bid - //wlog( "verify nofail can create test.nofail" ); - transfer( "eosio"_n, "nofail"_n, core_from_string( "1000.0000" ) ); - create_accounts_with_resources( { "test.nofail"_n }, "nofail"_n ); // only nofail can create test.nofail - //wlog( "verify dan cannot create test.fail" ); - BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { "test.fail"_n }, "dan"_n ), // 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( { "goodgoodgood"_n }, "dan"_n ); /// 12 char names should succeed -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( bid_invalid_names, eosio_system_tester ) try { - create_accounts_with_resources( { "dan"_n } ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "you can only bid on top-level suffix" ), - bidname( "dan"_n, "abcdefg.12345"_n, core_from_string( "1.0000" ) ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "the empty name is not a valid account name to bid on" ), - bidname( "dan"_n, ""_n, core_from_string( "1.0000" ) ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "13 character names are not valid account names to bid on" ), - bidname( "dan"_n, "abcdefgh12345"_n, core_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"_n, "abcdefg12345"_n, core_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 = { "alice"_n, "bob"_n, "carl"_n, "david"_n, "eve"_n }; - create_accounts_with_resources( accounts ); - for ( const auto& a: accounts ) { - transfer( config::system_account_name, a, core_from_string( "10000.0000" ) ); - BOOST_REQUIRE_EQUAL( core_from_string( "10000.0000" ), get_balance(a) ); - } - create_accounts_with_resources( { "producer"_n } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "producer"_n ) ); - - produce_block(); - // stake but not enough to go live - stake_with_transfer( config::system_account_name, "bob"_n, core_from_string( "35000000.0000" ), core_from_string( "35000000.0000" ) ); - stake_with_transfer( config::system_account_name, "carl"_n, core_from_string( "35000000.0000" ), core_from_string( "35000000.0000" ) ); - BOOST_REQUIRE_EQUAL( success(), vote( "bob"_n, { "producer"_n } ) ); - BOOST_REQUIRE_EQUAL( success(), vote( "carl"_n, { "producer"_n } ) ); - - // start bids - bidname( "bob"_n, "prefa"_n, core_from_string("1.0003") ); - BOOST_REQUIRE_EQUAL( core_from_string( "9998.9997" ), get_balance("bob"_n) ); - bidname( "bob"_n, "prefb"_n, core_from_string("1.0000") ); - bidname( "bob"_n, "prefc"_n, core_from_string("1.0000") ); - BOOST_REQUIRE_EQUAL( core_from_string( "9996.9997" ), get_balance("bob"_n) ); - - bidname( "carl"_n, "prefd"_n, core_from_string("1.0000") ); - bidname( "carl"_n, "prefe"_n, core_from_string("1.0000") ); - BOOST_REQUIRE_EQUAL( core_from_string( "9998.0000" ), get_balance("carl"_n) ); - - BOOST_REQUIRE_EQUAL( error("assertion failure with message: account is already highest bidder"), - bidname( "bob"_n, "prefb"_n, core_from_string("1.1001") ) ); - BOOST_REQUIRE_EQUAL( error("assertion failure with message: must increase bid by 10%"), - bidname( "alice"_n, "prefb"_n, core_from_string("1.0999") ) ); - BOOST_REQUIRE_EQUAL( core_from_string( "9996.9997" ), get_balance("bob"_n) ); - BOOST_REQUIRE_EQUAL( core_from_string( "10000.0000" ), get_balance("alice"_n) ); - - - // alice outbids bob on prefb - { - const asset initial_names_balance = get_balance("eosio.names"_n); - BOOST_REQUIRE_EQUAL( success(), - bidname( "alice"_n, "prefb"_n, core_from_string("1.1001") ) ); - // refund bob's failed bid on prefb - BOOST_REQUIRE_EQUAL( success(), push_action( "bob"_n, "bidrefund"_n, mvo()("bidder","bob")("newname", "prefb") ) ); - BOOST_REQUIRE_EQUAL( core_from_string( "9997.9997" ), get_balance("bob"_n) ); - BOOST_REQUIRE_EQUAL( core_from_string( "9998.8999" ), get_balance("alice"_n) ); - BOOST_REQUIRE_EQUAL( initial_names_balance + core_from_string("0.1001"), get_balance("eosio.names"_n) ); - } - - // david outbids carl on prefd - { - BOOST_REQUIRE_EQUAL( core_from_string( "9998.0000" ), get_balance("carl"_n) ); - BOOST_REQUIRE_EQUAL( core_from_string( "10000.0000" ), get_balance("david"_n) ); - BOOST_REQUIRE_EQUAL( success(), - bidname( "david"_n, "prefd"_n, core_from_string("1.9900") ) ); - // refund carls's failed bid on prefd - BOOST_REQUIRE_EQUAL( success(), push_action( "carl"_n, "bidrefund"_n, mvo()("bidder","carl")("newname", "prefd") ) ); - BOOST_REQUIRE_EQUAL( core_from_string( "9999.0000" ), get_balance("carl"_n) ); - BOOST_REQUIRE_EQUAL( core_from_string( "9998.0100" ), get_balance("david"_n) ); - } - - // eve outbids carl on prefe - { - BOOST_REQUIRE_EQUAL( success(), - bidname( "eve"_n, "prefe"_n, core_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( "prefd"_n, "david"_n ), - 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, "alice"_n, core_from_string( "10000000.0000" ), core_from_string( "10000000.0000" ) ); - BOOST_REQUIRE_EQUAL(0u, get_producer_info("producer"_n)["unpaid_blocks"].as()); - BOOST_REQUIRE_EQUAL( success(), vote( "alice"_n, { "producer"_n } ) ); - - // 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( "prefd"_n, "david"_n ), - 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( "prefd"_n, "david"_n ); - 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( "prefa"_n, "bob"_n ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( "prefb"_n, "alice"_n ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( "prefc"_n, "bob"_n ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( "prefe"_n, "eve"_n ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - // attemp to create account with no bid - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( "prefg"_n, "alice"_n ), - 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"_n, "prefb"_n, core_from_string("2.1880") ) ); - - produce_block( fc::hours(22) ); - produce_blocks(2); - - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( "prefb"_n, "eve"_n ), - 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"_n, "prefe"_n, core_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( "prefb"_n, "alice"_n ), - eosio_assert_message_exception, eosio_assert_message_is( "only highest bidder can claim" ) ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( "prefb"_n, "carl"_n ), - eosio_assert_message_exception, eosio_assert_message_is( "only highest bidder can claim" ) ); - create_account_with_resources( "prefb"_n, "eve"_n ); - - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( "prefe"_n, "carl"_n ), - 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( "prefe"_n, "carl"_n ); - // prefe can now create *.prefe - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( "xyz.prefe"_n, "carl"_n ), - fc::exception, fc_assert_exception_message_is("only suffix may create this account") ); - transfer( config::system_account_name, "prefe"_n, core_from_string("10000.0000") ); - create_account_with_resources( "xyz.prefe"_n, "prefe"_n ); - - // other auctions haven't closed - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( "prefa"_n, "bob"_n ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( vote_producers_in_and_out, eosio_system_tester ) try { - - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); - std::vector voters = { "producvotera"_n, "producvoterb"_n, "producvoterc"_n, "producvoterd"_n }; - for (const auto& v: voters) { - create_account_with_resources(v, config::system_account_name, core_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_from_string("200000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_from_string("30000000.0000")) ); - } - - { - BOOST_REQUIRE_EQUAL(success(), vote("producvotera"_n, vector(producer_names.begin(), producer_names.begin()+20))); - BOOST_REQUIRE_EQUAL(success(), vote("producvoterb"_n, vector(producer_names.begin(), producer_names.begin()+21))); - BOOST_REQUIRE_EQUAL(success(), vote("producvoterc"_n, 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"_n, core_from_string("40000000.0000"), core_from_string("40000000.0000"))); - BOOST_REQUIRE_EQUAL(success(), vote("producvoterd"_n, { producer_names[new_prod_index] })); - BOOST_REQUIRE_EQUAL(0u, 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("producvoterd"_n, { 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], "claimrewards"_n, 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 = "eosio.msig"_n; - 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 == "bob111111111"_n ? "alice1111111"_n : "bob111111111"_n).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; - { - fc::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( "alice1111111"_n, "propose"_n, mvo() - ("proposer", "alice1111111"_n) - ("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]), "approve"_n, mvo() - ("proposer", "alice1111111"_n) - ("proposal_name", "setparams1") - ("level", permission_level{ name(producer_names[i]), config::active_name }) - ) - ); - } - - transaction_trace_ptr trace; - control->applied_transaction().connect( - [&]( std::tuple p ) { - trace = std::get<0>(p); - } ); - - BOOST_REQUIRE_EQUAL(success(), push_action_msig( "alice1111111"_n, "exec"_n, mvo() - ("proposer", "alice1111111"_n) - ("proposal_name", "setparams1") - ("executer", "alice1111111"_n) - ) - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1u, 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_from_string("8.0000"); - const asset cpu = core_from_string("8.0000"); - std::vector accounts = { "aliceaccount"_n, "bobbyaccount"_n }; - for (const auto& a: accounts) { - create_account_with_resources(a, config::system_account_name, core_from_string("1.0000"), false, net, cpu); - } - - { - const auto name_a = accounts[0]; - transfer( config::system_account_name, name_a, core_from_string("1000.0000") ); - BOOST_REQUIRE_EQUAL( core_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_from_string("300.0000") ) ); - BOOST_REQUIRE_EQUAL( core_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_from_string("997.0074"), get_balance(name_a) ); - } - - { - const auto name_b = accounts[1]; - transfer( config::system_account_name, name_b, core_from_string("1000.0000") ); - BOOST_REQUIRE_EQUAL( core_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_from_string("300.0000") ) ); - BOOST_REQUIRE_EQUAL( core_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, "setram"_n, mvo()("max_ram_size", 64ll*1024 * 1024 * 1024)) ); - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action(name_b, "setram"_n, mvo()("max_ram_size", 80ll*1024 * 1024 * 1024)) ); - BOOST_REQUIRE_EQUAL( success(), - push_action(config::system_account_name, "setram"_n, mvo()("max_ram_size", 80ll*1024 * 1024 * 1024)) ); - - BOOST_REQUIRE_EQUAL( success(), sellram(name_b, bought_bytes_b ) ); - BOOST_REQUIRE( core_from_string("900.0000") < get_balance(name_b) ); - BOOST_REQUIRE( core_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"_n, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_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, "setramrate"_n, 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"_n, "alice1111111"_n, core_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"_n, 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"_n, "alice1111111"_n, 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( "alice1111111"_n, "setramrate"_n, 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, "setramrate"_n, 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"_n, "alice1111111"_n, 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_from_string("0.0000"), get_balance( "alice1111111"_n ) ); - transfer( "eosio"_n, "alice1111111"_n, core_from_string("1000.0000"), "eosio"_n ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio"_n, "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111"_n, "alice1111111"_n, core_from_string("1000.0000") ) ); - - BOOST_REQUIRE_EQUAL( false, get_row_by_account( "eosio.token"_n, "alice1111111"_n, "accounts"_n, account_name(symbol{}.to_symbol_code()) ).empty() ); - - //remove row - base_tester::push_action( "eosio.token"_n, "close"_n, "alice1111111"_n, mvo() - ( "owner", "alice1111111"_n ) - ( "symbol", symbol{} ) - ); - BOOST_REQUIRE_EQUAL( true, get_row_by_account( "eosio.token"_n, "alice1111111"_n, "accounts"_n, account_name(symbol{}.to_symbol_code()) ).empty() ); - - auto rlm = control->get_resource_limits_manager(); - auto eosioram_ram_usage = rlm.get_account_ram_usage("eosio.ram"_n); - auto alice_ram_usage = rlm.get_account_ram_usage("alice1111111"_n); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111"_n, 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("alice1111111"_n) ); - BOOST_REQUIRE_EQUAL( eosioram_ram_usage, rlm.get_account_ram_usage("eosio.ram"_n) ); - -} 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( "alice1111111"_n, 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( "abcdefghklmn"_n, "alice1111111"_n, 2724 + 112 + 160 - 1400 ); - - //check that one byte less is not enough - BOOST_REQUIRE_THROW( create_account_with_resources( "abcdefghklmn"_n, "alice1111111"_n, 2724 + 112 + 160 - 1400 - 1 ), - ram_usage_exceeded ); - */ - - //check that stake/unstake keeps the gift - transfer( "eosio"_n, "alice1111111"_n, core_from_string("1000.0000"), "eosio"_n ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio"_n, "alice1111111"_n, core_from_string("200.0000"), core_from_string("100.0000") ) ); - int64_t ram_bytes_after_stake; - rlm.get_account_limits( "alice1111111"_n, ram_bytes_after_stake, net_weight, cpu_weight ); - BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_stake ); - - BOOST_REQUIRE_EQUAL( success(), unstake( "eosio"_n, "alice1111111"_n, core_from_string("20.0000"), core_from_string("10.0000") ) ); - int64_t ram_bytes_after_unstake; - rlm.get_account_limits( "alice1111111"_n, 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"_n, "alice1111111"_n, core_from_string("1000.0000") ) ); - rlm.get_account_limits( "alice1111111"_n, ram_bytes, net_weight, cpu_weight ); - auto userres = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, static_cast(ram_bytes) ); // safe to cast in this case - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111"_n, 1024 ) ); - rlm.get_account_limits( "alice1111111"_n, ram_bytes, net_weight, cpu_weight ); - userres = get_total_stake( "alice1111111"_n ); - BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, static_cast(ram_bytes) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( change_limited_account_back_to_unlimited, eosio_system_tester ) try { - BOOST_REQUIRE( get_total_stake( "eosio"_n ).is_null() ); - - transfer( "eosio"_n, "alice1111111"_n, core_from_string("1.0000") ); - - auto error_msg = stake( "alice1111111"_n, "eosio"_n, core_from_string("0.0000"), core_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( "eosio"_n, "setalimits"_n, mvo() - ("account", "eosio"_n) - ("ram_bytes", ram_bytes_needed) - ("net_weight", -1) - ("cpu_weight", -1) - ); - - stake( "alice1111111"_n, "eosio"_n, core_from_string("0.0000"), core_from_string("1.0000") ); - - REQUIRE_MATCHING_OBJECT( get_total_stake( "eosio"_n ), mvo() - ("owner", "eosio"_n) - ("net_weight", core_from_string("0.0000")) - ("cpu_weight", core_from_string("1.0000")) - ("ram_bytes", 0) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "only supports unlimited accounts" ), - push_action( "eosio"_n, "setalimits"_n, mvo() - ("account", "eosio"_n) - ("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( "eosio"_n, "setalimits"_n, mvo() - ("account", "eosio.saving") - ("ram_bytes", -1) - ("net_weight", -1) - ("cpu_weight", -1) - ) - ); - -} FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_SUITE_END() diff --git a/unittests/eosio_system_tester.hpp b/unittests/eosio_system_tester.hpp index 650c5d48a0..f7f7422184 100644 --- a/unittests/eosio_system_tester.hpp +++ b/unittests/eosio_system_tester.hpp @@ -16,39 +16,40 @@ using mvo = fc::mutable_variant_object; namespace eosio_system { -class eosio_system_tester : public legacy_validating_tester { +template +class eosio_system_tester : public T { public: eosio_system_tester() - : eosio_system_tester([](legacy_validating_tester& ) {}){} + : eosio_system_tester([](validating_tester& ) {}){} template eosio_system_tester(Lambda setup) { setup(*this); - produce_blocks( 2 ); + T::produce_blocks( 2 ); - create_accounts({ "eosio.token"_n, "eosio.ram"_n, "eosio.ramfee"_n, "eosio.stake"_n, + T::create_accounts({ "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"_n }); - produce_blocks( 100 ); + T::produce_blocks( 100 ); - set_code( "eosio.token"_n, test_contracts::eosio_token_wasm() ); - set_abi( "eosio.token"_n, test_contracts::eosio_token_abi() ); + T::set_code( "eosio.token"_n, test_contracts::eosio_token_wasm() ); + T::set_abi( "eosio.token"_n, test_contracts::eosio_token_abi() ); { - const auto& accnt = control->db().get( "eosio.token"_n ); + const auto& accnt = T::control->db().template get( "eosio.token"_n ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - token_abi_ser.set_abi(std::move(abi), abi_serializer::create_yield_function( abi_serializer_max_time )); + token_abi_ser.set_abi(std::move(abi), abi_serializer::create_yield_function( T::abi_serializer_max_time )); } create_currency( "eosio.token"_n, config::system_account_name, core_from_string("10000000000.0000") ); issue(config::system_account_name, core_from_string("1000000000.0000")); BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), get_balance( name("eosio") ) ); - set_code( config::system_account_name, test_contracts::eosio_system_wasm() ); - set_abi( config::system_account_name, test_contracts::eosio_system_abi() ); + T::set_code( config::system_account_name, test_contracts::eosio_system_wasm() ); + T::set_abi( config::system_account_name, test_contracts::eosio_system_abi() ); base_tester::push_action(config::system_account_name, "init"_n, config::system_account_name, mutable_variant_object() @@ -56,13 +57,13 @@ class eosio_system_tester : public legacy_validating_tester { ("core", symbol(CORE_SYMBOL).to_string())); { - const auto& accnt = control->db().get( config::system_account_name ); + const auto& accnt = T::control->db().template get( config::system_account_name ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(std::move(abi), abi_serializer::create_yield_function( abi_serializer_max_time )); + abi_ser.set_abi(std::move(abi), abi_serializer::create_yield_function( T::abi_serializer_max_time )); } - produce_blocks(); + T::produce_blocks(); create_account_with_resources( "alice1111111"_n, config::system_account_name, core_from_string("1.0000"), false ); create_account_with_resources( "bob111111111"_n, config::system_account_name, core_from_string("0.4500"), false ); @@ -72,7 +73,7 @@ class eosio_system_tester : public legacy_validating_tester { get_balance(name("eosio")) + get_balance(name("eosio.ramfee")) + get_balance(name("eosio.stake")) + get_balance(name("eosio.ram")) ); } - action_result open( account_name owner, + T::action_result open( account_name owner, const string& symbolname, account_name ram_payer ) { return push_action( ram_payer, "open"_n, mvo() @@ -90,26 +91,26 @@ class eosio_system_tester : public legacy_validating_tester { 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); + T::set_transaction_headers(trx); authority owner_auth; - owner_auth = authority( get_public_key( a, "owner" ) ); + owner_auth = authority( T::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" ) ) + .active = authority( T::get_public_key( a, "active" ) ) }); - trx.actions.emplace_back( get_action( config::system_account_name, "buyrambytes"_n, vector{{creator,config::active_name}}, + trx.actions.emplace_back( T::get_action( config::system_account_name, "buyrambytes"_n, vector{{creator,config::active_name}}, mvo() ("payer", creator) ("receiver", a) ("bytes", ram_bytes) ) ); - trx.actions.emplace_back( get_action( config::system_account_name, "delegatebw"_n, vector{{creator,config::active_name}}, + trx.actions.emplace_back( T::get_action( config::system_account_name, "delegatebw"_n, vector{{creator,config::active_name}}, mvo() ("from", creator) ("receiver", a) @@ -119,22 +120,22 @@ class eosio_system_tester : public legacy_validating_tester { ) ); - set_transaction_headers(trx); - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - return push_transaction( trx ); + T::set_transaction_headers(trx); + trx.sign( T::get_private_key( creator, "active" ), T::control->get_chain_id() ); + return T::push_transaction( trx ); } transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, asset net = core_from_string("10.0000"), asset cpu = core_from_string("10.0000") ) { signed_transaction trx; - set_transaction_headers(trx); + T::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}}); + owner_auth = authority(2, {key_weight{T::get_public_key( a, "owner" ), 1}}, {permission_level_weight{{creator, config::active_name}, 1}}); } else { - owner_auth = authority( get_public_key( a, "owner" ) ); + owner_auth = authority( T::get_public_key( a, "owner" ) ); } trx.actions.emplace_back( vector{{creator,config::active_name}}, @@ -142,17 +143,17 @@ class eosio_system_tester : public legacy_validating_tester { .creator = creator, .name = a, .owner = owner_auth, - .active = authority( get_public_key( a, "active" ) ) + .active = authority( T::get_public_key( a, "active" ) ) }); - trx.actions.emplace_back( get_action( config::system_account_name, "buyram"_n, vector{{creator,config::active_name}}, + trx.actions.emplace_back( T::get_action( config::system_account_name, "buyram"_n, vector{{creator,config::active_name}}, mvo() ("payer", creator) ("receiver", a) ("quant", ramfunds) ) ); - trx.actions.emplace_back( get_action( config::system_account_name, "delegatebw"_n, vector{{creator,config::active_name}}, + trx.actions.emplace_back( T::get_action( config::system_account_name, "delegatebw"_n, vector{{creator,config::active_name}}, mvo() ("from", creator) ("receiver", a) @@ -162,37 +163,37 @@ class eosio_system_tester : public legacy_validating_tester { ) ); - set_transaction_headers(trx); - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - return push_transaction( trx ); + T::set_transaction_headers(trx); + trx.sign( T::get_private_key( creator, "active" ), T::control->get_chain_id() ); + return T::push_transaction( trx ); } transaction_trace_ptr setup_producer_accounts( const std::vector& accounts ) { account_name creator(config::system_account_name); signed_transaction trx; - set_transaction_headers(trx); + T::set_transaction_headers(trx); asset cpu = core_from_string("80.0000"); asset net = core_from_string("80.0000"); asset ram = core_from_string("1.0000"); for (const auto& a: accounts) { - authority owner_auth( get_public_key( a, "owner" ) ); + authority owner_auth( T::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" ) ) + .active = authority( T::get_public_key( a, "active" ) ) }); - trx.actions.emplace_back( get_action( config::system_account_name, "buyram"_n, vector{ {creator, config::active_name} }, + trx.actions.emplace_back( T::get_action( config::system_account_name, "buyram"_n, vector{ {creator, config::active_name} }, mvo() ("payer", creator) ("receiver", a) ("quant", ram) ) ); - trx.actions.emplace_back( get_action( config::system_account_name, "delegatebw"_n, vector{ {creator, config::active_name} }, + trx.actions.emplace_back( T::get_action( config::system_account_name, "delegatebw"_n, vector{ {creator, config::active_name} }, mvo() ("from", creator) ("receiver", a) @@ -203,35 +204,35 @@ class eosio_system_tester : public legacy_validating_tester { ); } - set_transaction_headers(trx); - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - return push_transaction( trx ); + T::set_transaction_headers(trx); + trx.sign( T::get_private_key( creator, "active" ), T::control->get_chain_id() ); + return T::push_transaction( trx ); } - action_result buyram( const account_name& payer, account_name receiver, const asset& eosin ) { + T::action_result buyram( const account_name& payer, account_name receiver, const asset& eosin ) { return push_action( payer, "buyram"_n, mvo()( "payer",payer)("receiver",receiver)("quant",eosin) ); } - action_result buyrambytes( const account_name& payer, account_name receiver, uint32_t numbytes ) { + T::action_result buyrambytes( const account_name& payer, account_name receiver, uint32_t numbytes ) { return push_action( payer, "buyrambytes"_n, mvo()( "payer",payer)("receiver",receiver)("bytes",numbytes) ); } - action_result sellram( const account_name& account, uint64_t numbytes ) { + T::action_result sellram( const account_name& account, uint64_t numbytes ) { return push_action( account, "sellram"_n, mvo()( "account", account)("bytes",numbytes) ); } - action_result push_action( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) { + T::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 ) ); + act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function( T::abi_serializer_max_time ) ); return base_tester::push_action( std::move(act), auth ? signer.to_uint64_t() : signer == "bob111111111"_n ? "alice1111111"_n.to_uint64_t() : "bob111111111"_n.to_uint64_t() ); } - action_result stake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { + T::action_result stake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { return push_action( name(from), "delegatebw"_n, mvo() ("from", from) ("receiver", to) @@ -241,11 +242,11 @@ class eosio_system_tester : public legacy_validating_tester { ); } - action_result stake( const account_name& acnt, const asset& net, const asset& cpu ) { + T::action_result stake( const account_name& acnt, const asset& net, const asset& cpu ) { return stake( acnt, acnt, net, cpu ); } - action_result stake_with_transfer( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { + T::action_result stake_with_transfer( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { return push_action( name(from), "delegatebw"_n, mvo() ("from", from) ("receiver", to) @@ -255,11 +256,11 @@ class eosio_system_tester : public legacy_validating_tester { ); } - action_result stake_with_transfer( const account_name& acnt, const asset& net, const asset& cpu ) { + T::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 unstake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { + T::action_result unstake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { return push_action( name(from), "undelegatebw"_n, mvo() ("from", from) ("receiver", to) @@ -268,11 +269,11 @@ class eosio_system_tester : public legacy_validating_tester { ); } - action_result unstake( const account_name& acnt, const asset& net, const asset& cpu ) { + T::action_result unstake( const account_name& acnt, const asset& net, const asset& cpu ) { return unstake( acnt, acnt, net, cpu ); } - action_result bidname( const account_name& bidder, const account_name& newname, const asset& bid ) { + T::action_result bidname( const account_name& bidder, const account_name& newname, const asset& bid ) { return push_action( name(bidder), "bidname"_n, mvo() ("bidder", bidder) ("newname", newname) @@ -280,14 +281,14 @@ class eosio_system_tester : public legacy_validating_tester { ); } - action_result deposit( const account_name& owner, const asset& amount ) { + T::action_result deposit( const account_name& owner, const asset& amount ) { return push_action( name(owner), "deposit"_n, mvo() ("owner", owner) ("amount", amount) ); } - action_result withdraw( const account_name& owner, const asset& amount ) { + T::action_result withdraw( const account_name& owner, const asset& amount ) { return push_action( name(owner), "withdraw"_n, mvo() ("owner", owner) ("amount", amount) @@ -295,13 +296,13 @@ class eosio_system_tester : public legacy_validating_tester { } asset get_rex_balance( const account_name& act ) const { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, "rexbal"_n, 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(); + vector data = T::get_row_by_account( config::system_account_name, config::system_account_name, "rexbal"_n, act ); + return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer::create_yield_function(T::abi_serializer_max_time))["rex_balance"].template as(); } asset get_rex_fund( const account_name& act ) const { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, "rexfund"_n, act ); - return data.empty() ? asset(0, symbol{}) : abi_ser.binary_to_variant("rex_fund", data, abi_serializer::create_yield_function(abi_serializer_max_time))["balance"].as(); + vector data = T::get_row_by_account( config::system_account_name, config::system_account_name, "rexfund"_n, act ); + return data.empty() ? asset(0, symbol{}) : abi_ser.binary_to_variant("rex_fund", data, abi_serializer::create_yield_function(T::abi_serializer_max_time))["balance"].template as(); } void setup_rex_accounts( const std::vector& accounts, @@ -312,16 +313,16 @@ class eosio_system_tester : public legacy_validating_tester { const asset nstake = core_from_string("10.0000"); const asset cstake = core_from_string("10.0000"); create_account_with_resources( "proxyaccount"_n, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - BOOST_REQUIRE_EQUAL( success(), push_action( "proxyaccount"_n, "regproxy"_n, mvo()("proxy", "proxyaccount")("isproxy", true) ) ); + BOOST_REQUIRE_EQUAL( T::success(), push_action( "proxyaccount"_n, "regproxy"_n, mvo()("proxy", "proxyaccount")("isproxy", true) ) ); for (const auto& a: accounts) { create_account_with_resources( a, config::system_account_name, core_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, { }, "proxyaccount"_n ) ); + BOOST_REQUIRE_EQUAL( T::success(), stake( a, a, nstake, cstake) ); + BOOST_REQUIRE_EQUAL( T::success(), vote( a, { }, "proxyaccount"_n ) ); 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( T::success(), deposit( a, init_balance ) ); BOOST_REQUIRE_EQUAL( init_balance, get_rex_fund( a ) ); BOOST_REQUIRE_EQUAL( 0, get_balance( a ).get_amount() ); } @@ -351,18 +352,18 @@ class eosio_system_tester : public legacy_validating_tester { ("ram_reserve_ratio", 100 + n); } - action_result regproducer( const account_name& acnt, int params_fixture = 1 ) { - action_result r = push_action( acnt, "regproducer"_n, mvo() + T::action_result regproducer( const account_name& acnt, int params_fixture = 1 ) { + typename T::action_result r = push_action( acnt, "regproducer"_n, mvo() ("producer", acnt ) - ("producer_key", get_public_key( acnt, "active" ) ) + ("producer_key", T::get_public_key( acnt, "active" ) ) ("url", "" ) ("location", 0 ) ); - BOOST_REQUIRE_EQUAL( success(), r); + BOOST_REQUIRE_EQUAL( T::success(), r); return r; } - action_result vote( const account_name& voter, const std::vector& producers, const account_name& proxy = name(0) ) { + T::action_result vote( const account_name& voter, const std::vector& producers, const account_name& proxy = name(0) ) { return push_action(voter, "voteproducer"_n, mvo() ("voter", voter) ("proxy", proxy) @@ -370,32 +371,32 @@ class eosio_system_tester : public legacy_validating_tester { } uint32_t last_block_time() const { - return time_point_sec( control->head_block_time() ).sec_since_epoch(); + return time_point_sec( T::control->head_block_time() ).sec_since_epoch(); } asset get_balance( const account_name& act ) { - vector data = get_row_by_account( "eosio.token"_n, act, "accounts"_n, name(symbol(CORE_SYMBOL).to_symbol_code().value) ); - return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data, abi_serializer::create_yield_function( abi_serializer_max_time ))["balance"].as(); + vector data = T::get_row_by_account( "eosio.token"_n, act, "accounts"_n, name(symbol(CORE_SYMBOL).to_symbol_code().value) ); + return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data, abi_serializer::create_yield_function( T::abi_serializer_max_time ))["balance"].template as(); } fc::variant get_total_stake( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, act, "userres"_n, act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer::create_yield_function( abi_serializer_max_time ) ); + vector data = T::get_row_by_account( config::system_account_name, act, "userres"_n, act ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer::create_yield_function( T::abi_serializer_max_time ) ); } fc::variant get_voter_info( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, "voters"_n, act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer::create_yield_function( abi_serializer_max_time ) ); + vector data = T::get_row_by_account( config::system_account_name, config::system_account_name, "voters"_n, act ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer::create_yield_function( T::abi_serializer_max_time ) ); } fc::variant get_producer_info( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, "producers"_n, act ); - return abi_ser.binary_to_variant( "producer_info", data, abi_serializer::create_yield_function( abi_serializer_max_time ) ); + vector data = T::get_row_by_account( config::system_account_name, config::system_account_name, "producers"_n, act ); + return abi_ser.binary_to_variant( "producer_info", data, abi_serializer::create_yield_function( T::abi_serializer_max_time ) ); } fc::variant get_producer_info2( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, "producers2"_n, act ); - return abi_ser.binary_to_variant( "producer_info2", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); + vector data = T::get_row_by_account( config::system_account_name, config::system_account_name, "producers2"_n, act ); + return abi_ser.binary_to_variant( "producer_info2", data, abi_serializer::create_yield_function(T::abi_serializer_max_time) ); } void create_currency( name contract, name manager, asset maxsupply ) { @@ -424,7 +425,7 @@ class eosio_system_tester : public legacy_validating_tester { 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( "eosio.token"_n, "issue"_n, + trx.actions.emplace_back( T::get_action( "eosio.token"_n, "issue"_n, vector{{manager, config::active_name}}, mutable_variant_object() ("to", manager ) @@ -433,7 +434,7 @@ class eosio_system_tester : public legacy_validating_tester { ) ); if ( to != manager ) { - trx.actions.emplace_back( get_action( "eosio.token"_n, "transfer"_n, + trx.actions.emplace_back( T::get_action( "eosio.token"_n, "transfer"_n, vector{{manager, config::active_name}}, mutable_variant_object() ("from", manager) @@ -443,13 +444,13 @@ class eosio_system_tester : public legacy_validating_tester { ) ); } - set_transaction_headers( trx ); - trx.sign( get_private_key( manager, "active" ), control->get_chain_id() ); - push_transaction( trx ); + T::set_transaction_headers( trx ); + trx.sign( T::get_private_key( manager, "active" ), T::control->get_chain_id() ); + T::push_transaction( trx ); } double stake2votes( asset stake ) { - auto now = control->pending_block_time().time_since_epoch().count() / 1000000; + auto now = T::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) } @@ -460,12 +461,12 @@ class eosio_system_tester : public legacy_validating_tester { 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( "eosio.token"_n, name(symbol_code), "stat"_n, 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 ) ); + vector data = T::get_row_by_account( "eosio.token"_n, name(symbol_code), "stat"_n, name(symbol_code) ); + return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data, abi_serializer::create_yield_function( T::abi_serializer_max_time ) ); } asset get_token_supply() { - return get_stats("4," CORE_SYMBOL_NAME)["supply"].as(); + return get_stats("4," CORE_SYMBOL_NAME)["supply"].template as(); } uint64_t microseconds_since_epoch_of_iso_string( const fc::variant& v ) { @@ -473,32 +474,32 @@ class eosio_system_tester : public legacy_validating_tester { } fc::variant get_global_state() { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, "global"_n, "global"_n ); + vector data = T::get_row_by_account( config::system_account_name, config::system_account_name, "global"_n, "global"_n ); 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 ) ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data, abi_serializer::create_yield_function( T::abi_serializer_max_time ) ); } fc::variant get_global_state2() { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, "global2"_n, "global2"_n ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); + vector data = T::get_row_by_account( config::system_account_name, config::system_account_name, "global2"_n, "global2"_n ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data, abi_serializer::create_yield_function(T::abi_serializer_max_time) ); } fc::variant get_global_state3() { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, "global3"_n, "global3"_n ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state3", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); + vector data = T::get_row_by_account( config::system_account_name, config::system_account_name, "global3"_n, "global3"_n ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state3", data, abi_serializer::create_yield_function(T::abi_serializer_max_time) ); } fc::variant get_refund_request( name account ) { - vector data = get_row_by_account( config::system_account_name, account, "refunds"_n, account ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data, abi_serializer::create_yield_function( abi_serializer_max_time ) ); + vector data = T::get_row_by_account( config::system_account_name, account, "refunds"_n, account ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data, abi_serializer::create_yield_function( T::abi_serializer_max_time ) ); } abi_serializer initialize_multisig() { abi_serializer msig_abi_ser; { create_account_with_resources( "eosio.msig"_n, config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), buyram( name("eosio"), name("eosio.msig"), core_from_string("5000.0000") ) ); - produce_block(); + BOOST_REQUIRE_EQUAL( T::success(), buyram( name("eosio"), name("eosio.msig"), core_from_string("5000.0000") ) ); + T::produce_block(); auto trace = base_tester::push_action(config::system_account_name, "setpriv"_n, config::system_account_name, mutable_variant_object() @@ -506,14 +507,14 @@ class eosio_system_tester : public legacy_validating_tester { ("is_priv", 1) ); - set_code( "eosio.msig"_n, test_contracts::eosio_msig_wasm() ); - set_abi( "eosio.msig"_n, test_contracts::eosio_msig_abi() ); + T::set_code( "eosio.msig"_n, test_contracts::eosio_msig_wasm() ); + T::set_abi( "eosio.msig"_n, test_contracts::eosio_msig_abi() ); - produce_blocks(); - const auto& accnt = control->db().get( "eosio.msig"_n ); + T::produce_blocks(); + const auto& accnt = T::control->db().template get( "eosio.msig"_n ); abi_def msig_abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, msig_abi), true); - msig_abi_ser.set_abi(std::move(msig_abi), abi_serializer::create_yield_function( abi_serializer_max_time )); + msig_abi_ser.set_abi(std::move(msig_abi), abi_serializer::create_yield_function( T::abi_serializer_max_time )); } return msig_abi_ser; } @@ -521,7 +522,7 @@ class eosio_system_tester : public legacy_validating_tester { vector active_and_vote_producers() { //stake more than 15% of total EOS supply to activate chain transfer( name("eosio"), name("alice1111111"), core_from_string("650000000.0000"), name("eosio") ); - BOOST_REQUIRE_EQUAL( success(), stake( name("alice1111111"), name("alice1111111"), core_from_string("300000000.0000"), core_from_string("300000000.0000") ) ); + BOOST_REQUIRE_EQUAL( T::success(), stake( name("alice1111111"), name("alice1111111"), core_from_string("300000000.0000"), core_from_string("300000000.0000") ) ); // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers std::vector producer_names; @@ -534,16 +535,16 @@ class eosio_system_tester : public legacy_validating_tester { setup_producer_accounts(producer_names); for (const auto& p: producer_names) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); + BOOST_REQUIRE_EQUAL( T::success(), regproducer(p) ); } } - produce_blocks( 250); + T::produce_blocks( 250); - auto trace_auth = legacy_validating_tester::push_action(config::system_account_name, updateauth::get_name(), config::system_account_name, mvo() + auto trace_auth = validating_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}}, { + ("auth", authority(1, {key_weight{T::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} } @@ -554,18 +555,18 @@ class eosio_system_tester : public legacy_validating_tester { //vote for producers { transfer( config::system_account_name, name("alice1111111"), core_from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake( name("alice1111111"), core_from_string("30000000.0000"), core_from_string("30000000.0000") ) ); - BOOST_REQUIRE_EQUAL(success(), buyram( name("alice1111111"), name("alice1111111"), core_from_string("30000000.0000") ) ); - BOOST_REQUIRE_EQUAL(success(), push_action("alice1111111"_n, "voteproducer"_n, mvo() + BOOST_REQUIRE_EQUAL(T::success(), stake( name("alice1111111"), core_from_string("30000000.0000"), core_from_string("30000000.0000") ) ); + BOOST_REQUIRE_EQUAL(T::success(), buyram( name("alice1111111"), name("alice1111111"), core_from_string("30000000.0000") ) ); + BOOST_REQUIRE_EQUAL(T::success(), push_action("alice1111111"_n, "voteproducer"_n, mvo() ("voter", "alice1111111") ("proxy", name(0).to_string()) ("producers", vector(producer_names.begin(), producer_names.begin()+21)) ) ); } - produce_blocks( 250 ); + T::produce_blocks( 250 ); - auto producer_keys = control->active_producers().producers; + auto producer_keys = T::control->active_producers().producers; BOOST_REQUIRE_EQUAL( 21u, producer_keys.size() ); BOOST_REQUIRE_EQUAL( name("defproducera"), producer_keys[0].producer_name ); @@ -577,9 +578,9 @@ class eosio_system_tester : public legacy_validating_tester { regproducer("producer1111"_n); { signed_transaction trx; - set_transaction_headers(trx); + T::set_transaction_headers(trx); - trx.actions.emplace_back( get_action( config::system_account_name, "delegatebw"_n, + trx.actions.emplace_back( T::get_action( config::system_account_name, "delegatebw"_n, vector{{config::system_account_name, config::active_name}}, mvo() ("from", name{config::system_account_name}) @@ -589,7 +590,7 @@ class eosio_system_tester : public legacy_validating_tester { ("transfer", 1 ) ) ); - trx.actions.emplace_back( get_action( config::system_account_name, "voteproducer"_n, + trx.actions.emplace_back( T::get_action( config::system_account_name, "voteproducer"_n, vector{{"producer1111"_n, config::active_name}}, mvo() ("voter", "producer1111") @@ -597,7 +598,7 @@ class eosio_system_tester : public legacy_validating_tester { ("producers", vector(1, "producer1111"_n)) ) ); - trx.actions.emplace_back( get_action( config::system_account_name, "undelegatebw"_n, + trx.actions.emplace_back( T::get_action( config::system_account_name, "undelegatebw"_n, vector{{"producer1111"_n, config::active_name}}, mvo() ("from", "producer1111") @@ -607,10 +608,10 @@ class eosio_system_tester : public legacy_validating_tester { ) ); - set_transaction_headers(trx); - trx.sign( get_private_key( config::system_account_name, "active" ), control->get_chain_id() ); - trx.sign( get_private_key( "producer1111"_n, "active" ), control->get_chain_id() ); - push_transaction( trx ); + T::set_transaction_headers(trx); + trx.sign( T::get_private_key( config::system_account_name, "active" ), T::control->get_chain_id() ); + trx.sign( T::get_private_key( "producer1111"_n, "active" ), T::control->get_chain_id() ); + T::push_transaction( trx ); } } @@ -645,4 +646,7 @@ inline uint64_t M( const string& eos_str ) { return core_from_string( eos_str ).get_amount(); } +using eosio_system_testers = boost::mpl::list, + eosio_system_tester>; + } diff --git a/unittests/producer_schedule_if_tests.cpp b/unittests/producer_schedule_if_tests.cpp index 3c0fae5ee4..8c6b6d55ad 100644 --- a/unittests/producer_schedule_if_tests.cpp +++ b/unittests/producer_schedule_if_tests.cpp @@ -20,6 +20,7 @@ inline account_name get_expected_producer(const vector& sche } // anonymous namespace +// Use legacy_validating_tester because it transitions to savanna as part of the test. BOOST_FIXTURE_TEST_CASE( verify_producer_schedule_after_instant_finality_activation, legacy_validating_tester ) try { // Utility function to ensure that producer schedule work as expected @@ -398,4 +399,36 @@ BOOST_FIXTURE_TEST_CASE( proposer_policy_misc_tests, legacy_validating_tester ) } FC_LOG_AND_RETHROW() +BOOST_AUTO_TEST_CASE( switch_producers_test ) try { + legacy_validating_tester chain; + + const std::vector accounts = { "aliceaccount"_n, "bobbyaccount"_n, "carolaccount"_n, "emilyaccount"_n }; + chain.create_accounts( accounts ); + chain.produce_block(); + + // activate instant_finality + chain.set_finalizers(accounts); + chain.set_producers( accounts ); + chain.produce_block(); + + // looping less than 20 did not reproduce the `producer_double_confirm: Producer is double confirming known range` error + for (size_t i = 0; i < 20; ++i) { + chain.set_producers( { "aliceaccount"_n, "bobbyaccount"_n } ); + chain.produce_block(); + + chain.set_producers( { "bobbyaccount"_n, "aliceaccount"_n } ); + chain.produce_block(); + chain.produce_block( fc::hours(1) ); + + chain.set_producers( accounts ); + chain.produce_block(); + chain.produce_block( fc::hours(1) ); + + chain.set_producers( { "carolaccount"_n } ); + chain.produce_block(); + chain.produce_block( fc::hours(1) ); + } + +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_SUITE_END() diff --git a/unittests/producer_schedule_tests.cpp b/unittests/producer_schedule_tests.cpp index 8f89d52a5b..ef6b374e17 100644 --- a/unittests/producer_schedule_tests.cpp +++ b/unittests/producer_schedule_tests.cpp @@ -108,19 +108,20 @@ BOOST_FIXTURE_TEST_CASE( verify_producer_schedule, legacy_validating_tester ) tr } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( verify_producers, legacy_validating_tester ) try { +BOOST_AUTO_TEST_CASE_TEMPLATE(verify_producers, T, validating_testers) try { + T chain; vector valid_producers = { "inita"_n, "initb"_n, "initc"_n, "initd"_n, "inite"_n, "initf"_n, "initg"_n, "inith"_n, "initi"_n, "initj"_n, "initk"_n, "initl"_n, "initm"_n, "initn"_n, "inito"_n, "initp"_n, "initq"_n, "initr"_n, "inits"_n, "initt"_n, "initu"_n }; - create_accounts(valid_producers); - set_producers(valid_producers); + chain.create_accounts(valid_producers); + chain.set_producers(valid_producers); // account initz does not exist vector nonexisting_producer = { "initz"_n }; - BOOST_CHECK_THROW(set_producers(nonexisting_producer), wasm_execution_error); + BOOST_CHECK_THROW(chain.set_producers(nonexisting_producer), wasm_execution_error); // replace initg with inita, inita is now duplicate vector invalid_producers = { @@ -129,7 +130,7 @@ BOOST_FIXTURE_TEST_CASE( verify_producers, legacy_validating_tester ) try { "inito"_n, "initp"_n, "initq"_n, "initr"_n, "inits"_n, "initt"_n, "initu"_n }; - BOOST_CHECK_THROW(set_producers(invalid_producers), wasm_execution_error); + BOOST_CHECK_THROW(chain.set_producers(invalid_producers), wasm_execution_error); } FC_LOG_AND_RETHROW() @@ -261,9 +262,9 @@ BOOST_FIXTURE_TEST_CASE( producer_schedule_reduction, legacy_tester ) try { BOOST_REQUIRE_EQUAL( validate(), true ); } FC_LOG_AND_RETHROW() -BOOST_AUTO_TEST_CASE( empty_producer_schedule_has_no_effect ) try { +BOOST_AUTO_TEST_CASE_TEMPLATE(empty_producer_schedule_has_no_effect, T, validating_testers) try { fc::temp_directory tempdir; - legacy_validating_tester c( tempdir, true ); + T c( tempdir, true ); c.execute_setup_policy( setup_policy::preactivate_feature_and_new_bios ); c.create_accounts( {"alice"_n,"bob"_n,"carol"_n} ); @@ -348,6 +349,36 @@ BOOST_AUTO_TEST_CASE( empty_producer_schedule_has_no_effect ) try { BOOST_REQUIRE_EQUAL( c.validate(), true ); } FC_LOG_AND_RETHROW() +BOOST_AUTO_TEST_CASE( switch_producers_test ) try { + validating_tester chain; + + const std::vector accounts = { "aliceaccount"_n, "bobbyaccount"_n, "carolaccount"_n, "emilyaccount"_n }; + chain.create_accounts( accounts ); + chain.produce_block(); + + chain.set_producers( accounts ); + chain.produce_block(); + + // looping less than 20 did not reproduce the `producer_double_confirm: Producer is double confirming known range` error + for (size_t i = 0; i < 20; ++i) { + chain.set_producers( { "aliceaccount"_n, "bobbyaccount"_n } ); + chain.produce_block(); + + chain.set_producers( { "bobbyaccount"_n, "aliceaccount"_n } ); + chain.produce_block(); + chain.produce_block( fc::hours(1) ); + + chain.set_producers( accounts ); + chain.produce_block(); + chain.produce_block( fc::hours(1) ); + + chain.set_producers( { "carolaccount"_n } ); + chain.produce_block(); + chain.produce_block( fc::hours(1) ); + } + +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_CASE( producer_watermark_test ) try { legacy_tester c; @@ -470,27 +501,31 @@ BOOST_AUTO_TEST_CASE( producer_watermark_test ) try { } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( producer_one_of_n_test, legacy_validating_tester ) try { - create_accounts( {"alice"_n,"bob"_n} ); - produce_block(); +BOOST_AUTO_TEST_CASE_TEMPLATE(producer_one_of_n_test, T, validating_testers) try { + T chain; + + chain.create_accounts( {"alice"_n,"bob"_n} ); + chain.produce_block(); vector sch1 = { producer_authority{"alice"_n, block_signing_authority_v0{1, {{get_public_key("alice"_n, "bs1"), 1}, {get_public_key("alice"_n, "bs2"), 1}}}}, producer_authority{"bob"_n, block_signing_authority_v0{1, {{get_public_key("bob"_n, "bs1"), 1}, {get_public_key("bob"_n, "bs2"), 1}}}} }; - auto res = set_producer_schedule( sch1 ); - block_signing_private_keys.emplace(get_public_key("alice"_n, "bs1"), get_private_key("alice"_n, "bs1")); - block_signing_private_keys.emplace(get_public_key("bob"_n, "bs1"), get_private_key("bob"_n, "bs1")); + auto res = chain.set_producer_schedule( sch1 ); + chain.block_signing_private_keys.emplace(get_public_key("alice"_n, "bs1"), get_private_key("alice"_n, "bs1")); + chain.block_signing_private_keys.emplace(get_public_key("bob"_n, "bs1"), get_private_key("bob"_n, "bs1")); - BOOST_REQUIRE(produce_until_blocks_from(*this, {"alice"_n, "bob"_n}, 300)); + BOOST_REQUIRE(produce_until_blocks_from(chain, {"alice"_n, "bob"_n}, 300)); - BOOST_REQUIRE_EQUAL( validate(), true ); + BOOST_REQUIRE_EQUAL( chain.validate(), true ); } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( producer_m_of_n_test, legacy_validating_tester ) try { - create_accounts( {"alice"_n,"bob"_n} ); - produce_block(); +BOOST_AUTO_TEST_CASE_TEMPLATE(producer_m_of_n_test, T, validating_testers) try { + T chain; + + chain.create_accounts( {"alice"_n,"bob"_n} ); + chain.produce_block(); vector sch1 = { @@ -498,20 +533,21 @@ BOOST_FIXTURE_TEST_CASE( producer_m_of_n_test, legacy_validating_tester ) try { producer_authority{"bob"_n, block_signing_authority_v0{2, {{get_public_key("bob"_n, "bs1"), 1}, {get_public_key("bob"_n, "bs2"), 1}}}} }; - auto res = set_producer_schedule( sch1 ); - block_signing_private_keys.emplace(get_public_key("alice"_n, "bs1"), get_private_key("alice"_n, "bs1")); - block_signing_private_keys.emplace(get_public_key("alice"_n, "bs2"), get_private_key("alice"_n, "bs2")); - block_signing_private_keys.emplace(get_public_key("bob"_n, "bs1"), get_private_key("bob"_n, "bs1")); - block_signing_private_keys.emplace(get_public_key("bob"_n, "bs2"), get_private_key("bob"_n, "bs2")); + auto res = chain.set_producer_schedule( sch1 ); + chain.block_signing_private_keys.emplace(get_public_key("alice"_n, "bs1"), get_private_key("alice"_n, "bs1")); + chain.block_signing_private_keys.emplace(get_public_key("alice"_n, "bs2"), get_private_key("alice"_n, "bs2")); + chain.block_signing_private_keys.emplace(get_public_key("bob"_n, "bs1"), get_private_key("bob"_n, "bs1")); + chain.block_signing_private_keys.emplace(get_public_key("bob"_n, "bs2"), get_private_key("bob"_n, "bs2")); - BOOST_REQUIRE(produce_until_blocks_from(*this, {"alice"_n, "bob"_n}, 300)); + BOOST_REQUIRE(produce_until_blocks_from(chain, {"alice"_n, "bob"_n}, 300)); - BOOST_REQUIRE_EQUAL( validate(), true ); + BOOST_REQUIRE_EQUAL( chain.validate(), true ); } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( satisfiable_msig_test, legacy_validating_tester ) try { - create_accounts( {"alice"_n,"bob"_n} ); - produce_block(); +BOOST_AUTO_TEST_CASE_TEMPLATE(satisfiable_msig_test, T, validating_testers) try { + T chain; + chain.create_accounts( {"alice"_n,"bob"_n} ); + chain.produce_block(); vector sch1 = { producer_authority{"alice"_n, block_signing_authority_v0{2, {{get_public_key("alice"_n, "bs1"), 1}}}} @@ -519,17 +555,19 @@ BOOST_FIXTURE_TEST_CASE( satisfiable_msig_test, legacy_validating_tester ) try { // ensure that the entries in a wtmsig schedule are rejected if not satisfiable BOOST_REQUIRE_EXCEPTION( - set_producer_schedule( sch1 ), wasm_execution_error, + chain.set_producer_schedule( sch1 ), wasm_execution_error, fc_exception_message_is( "producer schedule includes an unsatisfiable authority for alice" ) ); - BOOST_REQUIRE_EQUAL( false, control->proposed_producers_legacy().has_value() ); + BOOST_REQUIRE_EQUAL( false, chain.control->proposed_producers_legacy().has_value() ); } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( duplicate_producers_test, legacy_validating_tester ) try { - create_accounts( {"alice"_n} ); - produce_block(); +BOOST_AUTO_TEST_CASE_TEMPLATE(duplicate_producers_test, T, validating_testers) try { + T chain; + + chain.create_accounts( {"alice"_n} ); + chain.produce_block(); vector sch1 = { producer_authority{"alice"_n, block_signing_authority_v0{1, {{get_public_key("alice"_n, "bs1"), 1}}}}, @@ -538,11 +576,11 @@ BOOST_FIXTURE_TEST_CASE( duplicate_producers_test, legacy_validating_tester ) tr // ensure that the schedule is rejected if it has duplicate producers in it BOOST_REQUIRE_EXCEPTION( - set_producer_schedule( sch1 ), wasm_execution_error, + chain.set_producer_schedule( sch1 ), wasm_execution_error, fc_exception_message_is( "duplicate producer name in producer schedule" ) ); - BOOST_REQUIRE_EQUAL( false, control->proposed_producers_legacy().has_value() ); + BOOST_REQUIRE_EQUAL( false, chain.control->proposed_producers_legacy().has_value() ); } FC_LOG_AND_RETHROW() diff --git a/unittests/ram_tests.cpp b/unittests/ram_tests.cpp index a3f878421f..3ab27484ed 100644 --- a/unittests/ram_tests.cpp +++ b/unittests/ram_tests.cpp @@ -14,6 +14,8 @@ #include "eosio_system_tester.hpp" +using namespace eosio_system; + /* * register test suite `ram_tests` */ @@ -22,70 +24,71 @@ BOOST_AUTO_TEST_SUITE(ram_tests) /************************************************************************************* * ram_tests test case *************************************************************************************/ -BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { +BOOST_AUTO_TEST_CASE_TEMPLATE( ram_tests, T, eosio_system_testers ) { try { + T chain; auto init_request_bytes = 80000 + 7110; // `7110' is for table token row const auto increment_contract_bytes = 10000; const auto table_allocation_bytes = 12000; BOOST_REQUIRE_MESSAGE(table_allocation_bytes > increment_contract_bytes, "increment_contract_bytes must be less than table_allocation_bytes for this test setup to work"); - buyrambytes(config::system_account_name, config::system_account_name, 70000); - produce_blocks(10); - create_account_with_resources("testram11111"_n,config::system_account_name, init_request_bytes + 40); - create_account_with_resources("testram22222"_n,config::system_account_name, init_request_bytes + 1190); - produce_blocks(10); - BOOST_REQUIRE_EQUAL( success(), stake( name("eosio.stake"), name("testram11111"), core_from_string("10.0000"), core_from_string("5.0000") ) ); - produce_blocks(10); + chain.buyrambytes(config::system_account_name, config::system_account_name, 70000); + chain.produce_blocks(10); + chain.create_account_with_resources("testram11111"_n,config::system_account_name, init_request_bytes + 40); + chain.create_account_with_resources("testram22222"_n,config::system_account_name, init_request_bytes + 1190); + chain.produce_blocks(10); + BOOST_REQUIRE_EQUAL( chain.success(), chain.stake( name("eosio.stake"), name("testram11111"), core_from_string("10.0000"), core_from_string("5.0000") ) ); + chain.produce_blocks(10); for (auto i = 0; i < 10; ++i) { try { - set_code( "testram11111"_n, test_contracts::test_ram_limit_wasm() ); + chain.set_code( "testram11111"_n, test_contracts::test_ram_limit_wasm() ); break; } catch (const ram_usage_exceeded&) { init_request_bytes += increment_contract_bytes; - buyrambytes(config::system_account_name, "testram11111"_n, increment_contract_bytes); - buyrambytes(config::system_account_name, "testram22222"_n, increment_contract_bytes); + chain.buyrambytes(config::system_account_name, "testram11111"_n, increment_contract_bytes); + chain.buyrambytes(config::system_account_name, "testram22222"_n, increment_contract_bytes); } } - produce_blocks(10); + chain.produce_blocks(10); for (auto i = 0; i < 10; ++i) { try { - set_abi( "testram11111"_n, test_contracts::test_ram_limit_abi() ); + chain.set_abi( "testram11111"_n, test_contracts::test_ram_limit_abi() ); break; } catch (const ram_usage_exceeded&) { init_request_bytes += increment_contract_bytes; - buyrambytes(config::system_account_name, "testram11111"_n, increment_contract_bytes); - buyrambytes(config::system_account_name, "testram22222"_n, increment_contract_bytes); + chain.buyrambytes(config::system_account_name, "testram11111"_n, increment_contract_bytes); + chain.buyrambytes(config::system_account_name, "testram22222"_n, increment_contract_bytes); } } - produce_blocks(10); - set_code( "testram22222"_n, test_contracts::test_ram_limit_wasm() ); - set_abi( "testram22222"_n, test_contracts::test_ram_limit_abi() ); - produce_blocks(10); + chain.produce_blocks(10); + chain.set_code( "testram22222"_n, test_contracts::test_ram_limit_wasm() ); + chain.set_abi( "testram22222"_n, test_contracts::test_ram_limit_abi() ); + chain.produce_blocks(10); - auto total = get_total_stake( "testram11111"_n ); + auto total = chain.get_total_stake( "testram11111"_n ); const auto init_bytes = total["ram_bytes"].as_uint64(); - auto rlm = control->get_resource_limits_manager(); + auto rlm = chain.control->get_resource_limits_manager(); auto initial_ram_usage = rlm.get_account_ram_usage("testram11111"_n); // calculate how many more bytes we need to have table_allocation_bytes for database stores auto more_ram = table_allocation_bytes + init_bytes - init_request_bytes; BOOST_REQUIRE_MESSAGE(more_ram >= 0, "Underlying understanding changed, need to reduce size of init_request_bytes"); wdump((init_bytes)(initial_ram_usage)(init_request_bytes)(more_ram) ); - buyrambytes(config::system_account_name, "testram11111"_n, more_ram); - buyrambytes(config::system_account_name, "testram22222"_n, more_ram); + chain.buyrambytes(config::system_account_name, "testram11111"_n, more_ram); + chain.buyrambytes(config::system_account_name, "testram22222"_n, more_ram); - validating_tester* tester = this; + validating_tester* tester = &chain; // allocate just under the allocated bytes tester->push_action( "testram11111"_n, "setentry"_n, "testram11111"_n, mvo() ("payer", "testram11111") ("from", 1) ("to", 10) ("size", 1780 /*1910*/)); - produce_blocks(1); + chain.produce_blocks(1); auto ram_usage = rlm.get_account_ram_usage("testram11111"_n); - total = get_total_stake( "testram11111"_n ); + total = chain.get_total_stake( "testram11111"_n ); const auto ram_bytes = total["ram_bytes"].as_uint64(); wdump((ram_bytes)(ram_usage)(initial_ram_usage)(init_bytes)(ram_usage - initial_ram_usage)(init_bytes - ram_usage) ); @@ -100,7 +103,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ram_usage_exceeded, fc_exception_message_starts_with("account testram11111 has insufficient ram")); wlog("ram_tests 2 %%%%%%"); - produce_blocks(1); + chain.produce_blocks(1); BOOST_REQUIRE_EQUAL(ram_usage, rlm.get_account_ram_usage("testram11111"_n)); // update the entries with smaller allocations so that we can verify space is freed and new allocations can be made @@ -109,7 +112,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("from", 1) ("to", 10) ("size", 1680/*1810*/)); - produce_blocks(1); + chain.produce_blocks(1); BOOST_REQUIRE_EQUAL(ram_usage - 1000, rlm.get_account_ram_usage("testram11111"_n)); // verify the added entry is beyond the allocation bytes limit @@ -121,7 +124,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("size", 1680/*1810*/)), ram_usage_exceeded, fc_exception_message_starts_with("account testram11111 has insufficient ram")); - produce_blocks(1); + chain.produce_blocks(1); BOOST_REQUIRE_EQUAL(ram_usage - 1000, rlm.get_account_ram_usage("testram11111"_n)); // verify the new entry's bytes minus the freed up bytes for existing entries still exceeds the allocation bytes limit @@ -133,7 +136,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("size", 1760)), ram_usage_exceeded, fc_exception_message_starts_with("account testram11111 has insufficient ram")); - produce_blocks(1); + chain.produce_blocks(1); BOOST_REQUIRE_EQUAL(ram_usage - 1000, rlm.get_account_ram_usage("testram11111"_n)); // verify the new entry's bytes minus the freed up bytes for existing entries are under the allocation bytes limit @@ -142,12 +145,12 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("from", 1) ("to", 11) ("size", 1600/*1720*/)); - produce_blocks(1); + chain.produce_blocks(1); tester->push_action( "testram11111"_n, "rmentry"_n, "testram11111"_n, mvo() ("from", 3) ("to", 3)); - produce_blocks(1); + chain.produce_blocks(1); // verify that the new entry will exceed the allocation bytes limit BOOST_REQUIRE_EXCEPTION( @@ -158,7 +161,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("size", 1780)), ram_usage_exceeded, fc_exception_message_starts_with("account testram11111 has insufficient ram")); - produce_blocks(1); + chain.produce_blocks(1); // verify that the new entry is under the allocation bytes limit tester->push_action( "testram11111"_n, "setentry"_n, "testram11111"_n, mvo() @@ -166,7 +169,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("from", 12) ("to", 12) ("size", 1620/*1720*/)); - produce_blocks(1); + chain.produce_blocks(1); // verify that anoth new entry will exceed the allocation bytes limit, to setup testing of new payer BOOST_REQUIRE_EXCEPTION( @@ -177,7 +180,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("size", 1660)), ram_usage_exceeded, fc_exception_message_starts_with("account testram11111 has insufficient ram")); - produce_blocks(1); + chain.produce_blocks(1); // verify that the new entry is under the allocation bytes limit tester->push_action( "testram11111"_n, "setentry"_n, {"testram11111"_n,"testram22222"_n}, mvo() @@ -185,7 +188,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("from", 12) ("to", 12) ("size", 1720)); - produce_blocks(1); + chain.produce_blocks(1); // verify that another new entry that is too big will exceed the allocation bytes limit, to setup testing of new payer BOOST_REQUIRE_EXCEPTION( @@ -196,7 +199,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("size", 1900)), ram_usage_exceeded, fc_exception_message_starts_with("account testram11111 has insufficient ram")); - produce_blocks(1); + chain.produce_blocks(1); wlog("ram_tests 18 %%%%%%"); // verify that the new entry is under the allocation bytes limit, because entry 12 is now charged to testram22222 @@ -205,7 +208,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("from", 13) ("to", 13) ("size", 1720)); - produce_blocks(1); + chain.produce_blocks(1); // verify that new entries for testram22222 exceed the allocation bytes limit BOOST_REQUIRE_EXCEPTION( @@ -216,7 +219,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("size", 1930)), ram_usage_exceeded, fc_exception_message_starts_with("account testram22222 has insufficient ram")); - produce_blocks(1); + chain.produce_blocks(1); // verify that new entries for testram22222 are under the allocation bytes limit tester->push_action( "testram11111"_n, "setentry"_n, {"testram11111"_n,"testram22222"_n}, mvo() @@ -224,7 +227,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("from", 12) ("to", 21) ("size", 1910)); - produce_blocks(1); + chain.produce_blocks(1); // verify that new entry for testram22222 exceed the allocation bytes limit BOOST_REQUIRE_EXCEPTION( @@ -235,12 +238,12 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("size", 1910)), ram_usage_exceeded, fc_exception_message_starts_with("account testram22222 has insufficient ram")); - produce_blocks(1); + chain.produce_blocks(1); tester->push_action( "testram11111"_n, "rmentry"_n, "testram11111"_n, mvo() ("from", 20) ("to", 20)); - produce_blocks(1); + chain.produce_blocks(1); // verify that new entry for testram22222 are under the allocation bytes limit tester->push_action( "testram11111"_n, "setentry"_n, {"testram11111"_n,"testram22222"_n}, mvo() @@ -248,7 +251,7 @@ BOOST_FIXTURE_TEST_CASE(ram_tests, eosio_system::eosio_system_tester) { try { ("from", 22) ("to", 22) ("size", 1910)); - produce_blocks(1); + chain.produce_blocks(1); } FC_LOG_AND_RETHROW() } diff --git a/unittests/wasm-spec-tests/generated-tests/CMakeLists.txt b/unittests/wasm-spec-tests/generated-tests/CMakeLists.txt index 25169702fb..7b066eb988 100644 --- a/unittests/wasm-spec-tests/generated-tests/CMakeLists.txt +++ b/unittests/wasm-spec-tests/generated-tests/CMakeLists.txt @@ -37,3 +37,16 @@ foreach(TEST_SUITE ${WASM_TESTS}) # create an independent target for each test s endif() endforeach(TEST_SUITE) set(ctest_tests "'${ctest_tests}' -j8") # surround test list string in apostrophies + +# The following tests are known to take the longest, bump up their cost (priority) so that they'll run first +# even on fresh first time test runs before ctest auto-detects costs +foreach(RUNTIME ${EOSIO_WASM_RUNTIMES}) + set_tests_properties(memory_trap_1_check_throw_1_unit_test_${RUNTIME} PROPERTIES COST 4000) + set_tests_properties(memory_trap_1_check_throw_2_unit_test_${RUNTIME} PROPERTIES COST 4000) + set_tests_properties(conversions_0_check_throw_unit_test_${RUNTIME} PROPERTIES COST 2500) + set_tests_properties(unreachable_0_check_throw_unit_test_${RUNTIME} PROPERTIES COST 2500) + set_tests_properties(f64_0_pass_unit_test_${RUNTIME} PROPERTIES COST 2500) + set_tests_properties(f32_0_pass_unit_test_${RUNTIME} PROPERTIES COST 2500) + set_tests_properties(f32_cmp_0_pass_unit_test_${RUNTIME} PROPERTIES COST 2500) + set_tests_properties(f64_cmp_0_pass_unit_test_${RUNTIME} PROPERTIES COST 2500) +endforeach() diff --git a/unittests/wasm-spec-tests/generated-tests/memory_trap.cpp b/unittests/wasm-spec-tests/generated-tests/memory_trap.cpp index ee8c62abde..b0ef5afcca 100644 --- a/unittests/wasm-spec-tests/generated-tests/memory_trap.cpp +++ b/unittests/wasm-spec-tests/generated-tests/memory_trap.cpp @@ -41,8 +41,7 @@ BOOST_DATA_TEST_CASE(memory_trap_0_pass, boost::unit_test::data::xrange(10,11), const string wasm_str_memory_trap_1 = base_dir + "/memory_trap.1.wasm"; std::vector wasm_memory_trap_1= read_wasm(wasm_str_memory_trap_1.c_str()); -BOOST_DATA_TEST_CASE(memory_trap_1_check_throw, boost::unit_test::data::xrange(0,156), index) { try { - TESTER tester; +void memory_trap_1_check_throw_common(TESTER& tester, uint32_t index) { tester.produce_block(); tester.create_account( "wasmtest"_n ); tester.produce_block(); @@ -56,6 +55,16 @@ BOOST_DATA_TEST_CASE(memory_trap_1_check_throw, boost::unit_test::data::xrange(0 BOOST_CHECK_THROW(push_action(tester, std::move(test), "wasmtest"_n.to_uint64_t()), wasm_execution_error); tester.produce_block(); +} + +BOOST_DATA_TEST_CASE(memory_trap_1_check_throw_1, boost::unit_test::data::xrange(0,78), index) { try { + TESTER tester; + memory_trap_1_check_throw_common(tester, index); +} FC_LOG_AND_RETHROW() } + +BOOST_DATA_TEST_CASE(memory_trap_1_check_throw_2, boost::unit_test::data::xrange(78,156), index) { try { + TESTER tester; + memory_trap_1_check_throw_common(tester, index); } FC_LOG_AND_RETHROW() } BOOST_DATA_TEST_CASE(memory_trap_1_pass, boost::unit_test::data::xrange(156,157), index) { try {