diff --git a/contracts/eosio.init/eosio.init.hpp.in b/contracts/eosio.init/eosio.init.hpp.in index 8b0b30d9e9a..d711fadeb7a 100644 --- a/contracts/eosio.init/eosio.init.hpp.in +++ b/contracts/eosio.init/eosio.init.hpp.in @@ -9,6 +9,8 @@ #include #include +#include + namespace eosio { struct beos_global_state_element @@ -170,6 +172,14 @@ namespace eosio { void changeparams( beos_global_state new_params ); inline beos_global_state get_beos_global_state() const; + /* + current block is inside [ starting_block_for_distribution : ending_block_for_distribution ) + */ + inline bool is_active_distribution_period() const; + /* + current block is at or above ending_block_for_distribution + */ + inline bool is_past_distribution_period() const; }; inline beos_global_state init::get_beos_global_state() const @@ -177,4 +187,17 @@ namespace eosio { return _beos_gstate; } + inline bool init::is_active_distribution_period() const + { + auto block_no = get_blockchain_block_number(); + return _beos_gstate.beos.starting_block_for_distribution <= block_no && + block_no < _beos_gstate.beos.ending_block_for_distribution; + } + + inline bool init::is_past_distribution_period() const + { + auto block_no = get_blockchain_block_number(); + return _beos_gstate.beos.ending_block_for_distribution <= block_no; + } + } /// namespace eosio diff --git a/contracts/eosio.system/delegate_bandwidth.cpp b/contracts/eosio.system/delegate_bandwidth.cpp index d1ab361a65c..d84eb78aa24 100644 --- a/contracts/eosio.system/delegate_bandwidth.cpp +++ b/contracts/eosio.system/delegate_bandwidth.cpp @@ -472,6 +472,7 @@ namespace eosiosystem { void system_contract::undelegatebw( account_name from, account_name receiver, asset unstake_net_quantity, asset unstake_cpu_quantity ) { + eosio_assert( eosio::init( N(beos.init) ).is_past_distribution_period(), "cannot unstake during distribution period" ); eosio_assert( asset() <= unstake_cpu_quantity, "must unstake a positive amount" ); eosio_assert( asset() <= unstake_net_quantity, "must unstake a positive amount" ); eosio_assert( asset() < unstake_cpu_quantity + unstake_net_quantity, "must unstake a positive amount" ); diff --git a/libraries/chain/wasm_interface.cpp b/libraries/chain/wasm_interface.cpp index 0ea29d3c6d8..94dbf467817 100644 --- a/libraries/chain/wasm_interface.cpp +++ b/libraries/chain/wasm_interface.cpp @@ -987,32 +987,45 @@ class console_api : public context_aware_api { : context_aware_api(ctx,true) , ignore(!ctx.control.contracts_console()) {} +//ABW: uncomment the following symbol to unconditionally write eosio::print calls to file (works even during unit tests) +//#define CAVEMEN_DEBUG +#ifdef CAVEMEN_DEBUG +#define DBG(format,value) { FILE *pFile = fopen("debug.log","a"); fprintf(pFile,format "\n",value); fclose(pFile); } +#else +#define DBG(format,value) +#endif + // Kept as intrinsic rather than implementing on WASM side (using prints_l and strlen) because strlen is faster on native side. void prints(null_terminated_ptr str) { + DBG("%s",(const char *)(str)) if ( !ignore ) { context.console_append(str); } } void prints_l(array_ptr str, size_t str_len ) { + DBG("%s",string(str, str_len).c_str()) if ( !ignore ) { context.console_append(string(str, str_len)); } } void printi(int64_t val) { + DBG("%lli",val) if ( !ignore ) { context.console_append(val); } } void printui(uint64_t val) { + DBG("%lli",val) if ( !ignore ) { context.console_append(val); } } void printi128(const __int128& val) { + DBG("%lli",val) if ( !ignore ) { bool is_negative = (val < 0); unsigned __int128 val_magnitude; @@ -1033,6 +1046,7 @@ class console_api : public context_aware_api { } void printui128(const unsigned __int128& val) { + DBG("%lli",val) if ( !ignore ) { fc::uint128_t v(val>>64, static_cast(val) ); context.console_append(fc::variant(v).get_string()); @@ -1040,6 +1054,7 @@ class console_api : public context_aware_api { } void printsf( float val ) { + DBG("%e",val) if ( !ignore ) { // Assumes float representation on native side is the same as on the WASM side auto& console = context.get_console_stream(); @@ -1053,6 +1068,7 @@ class console_api : public context_aware_api { } void printdf( double val ) { + DBG("%e",val) if ( !ignore ) { // Assumes double representation on native side is the same as on the WASM side auto& console = context.get_console_stream(); @@ -1066,6 +1082,7 @@ class console_api : public context_aware_api { } void printqf( const float128_t& val ) { + DBG("%Le",val) /* * Native-side long double uses an 80-bit extended-precision floating-point number. * The easiest solution for now was to use the Berkeley softfloat library to round the 128-bit @@ -1093,12 +1110,14 @@ class console_api : public context_aware_api { } void printn(const name& value) { + DBG("%s",value.to_string().c_str()) if ( !ignore ) { context.console_append(value.to_string()); } } void printhex(array_ptr data, size_t data_len ) { + DBG("%s",fc::to_hex(data, data_len).c_str()) if ( !ignore ) { context.console_append(fc::to_hex(data, data_len)); } diff --git a/libraries/testing/tester.cpp b/libraries/testing/tester.cpp index dbba9fef2ba..cbbbb009429 100644 --- a/libraries/testing/tester.cpp +++ b/libraries/testing/tester.cpp @@ -600,6 +600,8 @@ namespace eosio { namespace testing { tgs.ram.starting_block_for_distribution = 1; tgs.ram.ending_block_for_distribution = 2; tgs.starting_block_for_initial_witness_election = 1; + tgs.beos.starting_block_for_distribution = 1; + tgs.beos.ending_block_for_distribution = 2; produce_block(); diff --git a/unittests/eosio.interchain_tests.cpp b/unittests/eosio.interchain_tests.cpp index 75db9ec32ad..627bc048de7 100644 --- a/unittests/eosio.interchain_tests.cpp +++ b/unittests/eosio.interchain_tests.cpp @@ -166,6 +166,18 @@ struct actions: public tester ); } + action_result unstake( account_name who, asset unstake_net_quantity, asset unstake_cpu_quantity ) + { + return push_action( who, N(undelegatebw), mvo() + ( "from", who ) + ( "receiver", who ) + ( "unstake_net_quantity", unstake_net_quantity ) + ( "unstake_cpu_quantity", unstake_cpu_quantity ), + system_abi_ser, + config::system_account_name + ); + } + }; class eosio_interchain_tester : public actions @@ -708,6 +720,30 @@ BOOST_FIXTURE_TEST_CASE( basic_vote_test2, eosio_init_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( undelegate_block_test, eosio_init_tester ) try { + //see issue #15 + + test_global_state tgs; + + tgs.beos.starting_block_for_distribution = 100; + tgs.beos.ending_block_for_distribution = 105; + tgs.beos.distribution_payment_block_interval_for_distribution = 8; + + BOOST_REQUIRE_EQUAL( success(), change_params( tgs ) ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot unstake during distribution period"), unstake( N(alice), asset::from_string("10.0000 BEOS"), asset::from_string("10.0000 BEOS") ) ); + + produce_blocks( 105 - control->head_block_num() ); + BOOST_REQUIRE_EQUAL( control->head_block_num(), 105u ); + + //ABW: first we need to extend the test with voting (15% required to allow successful unstake) but to do that + //we need delegations working on stake (issue #13) - supplement once it is done + //BOOST_REQUIRE_EQUAL( success(), unstake( N(alice), asset::from_string("10.0000 BEOS"), asset::from_string("10.0000 BEOS") ) ); + //CHECK_STATS(alice, "0.0000 PROXY", "20.0000 BEOS", ""); + +} FC_LOG_AND_RETHROW() + + BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(eosio_interchain_tests)