From 0536d6e616403dcb325a45e59e700953a8cb44e8 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 21 May 2018 12:04:52 -0400 Subject: [PATCH] system contract: unit-test for taking stake from pednding refund #3213 bugfix #3180 --- contracts/eosio.system/delegate_bandwidth.cpp | 4 + contracts/eosio.system/eosio.system.abi | 3 +- unittests/eosio.system_tests.cpp | 75 +++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/delegate_bandwidth.cpp b/contracts/eosio.system/delegate_bandwidth.cpp index 0eb77a591..166f21835 100644 --- a/contracts/eosio.system/delegate_bandwidth.cpp +++ b/contracts/eosio.system/delegate_bandwidth.cpp @@ -303,11 +303,15 @@ namespace eosiosystem { if ( r.net_amount < asset(0) ) { net_balance = -r.net_amount; r.net_amount = asset(0); + } else { + net_balance = asset(0); } r.cpu_amount -= cpu_balance; if ( r.cpu_amount < asset(0) ){ cpu_balance = -r.cpu_amount; r.cpu_amount = asset(0); + } else { + cpu_balance = asset(0); } }); eosio_assert( asset(0) <= req->net_amount, "negative net refund amount" ); //should never happen diff --git a/contracts/eosio.system/eosio.system.abi b/contracts/eosio.system/eosio.system.abi index 0e11106d2..d5b98c456 100644 --- a/contracts/eosio.system/eosio.system.abi +++ b/contracts/eosio.system/eosio.system.abi @@ -207,7 +207,8 @@ "fields": [ {"name":"owner", "type":"account_name"}, {"name":"request_time", "type":"time_point_sec"}, - {"name":"amount", "type":"uint64"} + {"name":"net_amount", "type":"asset"}, + {"name":"cpu_amount", "type":"asset"} ] },{ "name": "blockchain_parameters", diff --git a/unittests/eosio.system_tests.cpp b/unittests/eosio.system_tests.cpp index 80b5d98c3..761b60eab 100644 --- a/unittests/eosio.system_tests.cpp +++ b/unittests/eosio.system_tests.cpp @@ -378,6 +378,11 @@ public: } + fc::variant get_refund_request( name account ) { + vector data = get_row_by_account( N(eosio), account, N(refunds), account ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data ); + } + abi_serializer abi_ser; abi_serializer token_abi_ser; }; @@ -856,6 +861,76 @@ BOOST_FIXTURE_TEST_CASE( adding_stake_partial_unstake, eosio_system_tester ) try } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + + auto total = get_total_stake( "bob111111111" ); + 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", core_from_string("300.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + + //unstake a share + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_from_string("100.0000"), core_from_string("50.0000") ) ); + total = get_total_stake( "bob111111111" ); + 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", core_from_string("150.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + auto refund = get_refund_request( "alice1111111" ); + 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(); + + //std::cout << std::endl << std::endl << "Stake from refund" << std::endl; + //stake less than pending refund, entire amount should be traken from refund + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("50.0000"), core_from_string("25.0000") ) ); + total = get_total_stake( "bob111111111" ); + 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" ); + 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 shoud stay the same + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + + //stake exactly pending refund amount + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("50.0000"), core_from_string("25.0000") ) ); + total = get_total_stake( "bob111111111" ); + 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" ); + BOOST_TEST_REQUIRE( refund.is_null() ); + //balance shoud stay the same + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + + //create pending refund again + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + total = get_total_stake( "bob111111111" ); + 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("700.0000"), get_balance( "alice1111111" ) ); + refund = get_refund_request( "alice1111111" ); + 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", "bob111111111", core_from_string("300.0000"), core_from_string("200.0000") ) ); + total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("310.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["cpu_weight"].as()); + refund = get_refund_request( "alice1111111" ); + BOOST_TEST_REQUIRE( refund.is_null() ); + //200 EOS should be taken from alice's account + BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111" ) ); + +} FC_LOG_AND_RETHROW() + // Tests for voting BOOST_FIXTURE_TEST_CASE( producer_register_unregister, eosio_system_tester ) try { -- GitLab