diff --git a/contracts/enumivo.system/delegate_bandwidth.cpp b/contracts/enumivo.system/delegate_bandwidth.cpp index ad91f783097..1ec7c7d30b7 100644 --- a/contracts/enumivo.system/delegate_bandwidth.cpp +++ b/contracts/enumivo.system/delegate_bandwidth.cpp @@ -73,7 +73,7 @@ namespace enumivosystem { }; /** - * These tables are designed to be constructed in the scope of the relevant user, this + * These tables are designed to be constructed in the scope of the relevant user, this * facilitates simpler API for per-user queries */ typedef enumivo::multi_index< N(userres), user_resources> user_resources_table; @@ -100,9 +100,9 @@ namespace enumivosystem { * storage of all database records associated with this action. * * RAM is a scarce resource whose supply is defined by global properties max_ram_size. RAM is - * priced using the bancor algorithm such that price-per-byte with a constant reserve ratio of 100:1. + * priced using the bancor algorithm such that price-per-byte with a constant reserve ratio of 100:1. */ - void system_contract::buyram( account_name payer, account_name receiver, asset quant ) + void system_contract::buyram( account_name payer, account_name receiver, asset quant ) { require_auth( payer ); enumivo_assert( quant.amount > 0, "must purchase a positive amount" ); @@ -316,7 +316,7 @@ namespace enumivosystem { auto transfer_amount = net_balance + cpu_balance; if ( asset(0) < transfer_amount ) { - INLINE_ACTION_SENDER(enumivo::token, transfer)( N(enumivo.coin), {from,N(active)}, + INLINE_ACTION_SENDER(enumivo::token, transfer)( N(enumivo.coin), {source_stake_from, N(active)}, { source_stake_from, N(enumivo), asset(transfer_amount), std::string("stake bandwidth") } ); } } diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 53cb59f44a1..6593bd5ca65 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -343,6 +343,7 @@ namespace enumivo { bool is_known_by_peer = false; ///< true if we sent or received this trx to this peer or received notice from peer bool is_noticed_to_peer = false; ///< have we sent peer notice we know it (true if we receive from this peer) uint32_t block_num = 0; ///< the block number the transaction was included in + time_point_sec expires; time_point requested_time; /// in case we fetch large trx }; @@ -362,10 +363,19 @@ namespace enumivo { } }; + struct update_txn_expiry { + time_point_sec new_expiry; + update_txn_expiry(time_point_sec e) : new_expiry(e) {} + void operator() (transaction_state& ts) { + ts.expires = new_expiry; + } + }; + typedef multi_index_container< transaction_state, indexed_by< ordered_unique< tag, member >, + ordered_non_unique< tag< by_expiry >, member< transaction_state,fc::time_point_sec,&transaction_state::expires >>, ordered_non_unique< tag, member< transaction_state, @@ -1655,6 +1665,8 @@ namespace enumivo { uint32_t packsiz = 0; uint32_t bufsiz = 0; + time_point_sec trx_expiration = trx.expiration(); + net_message msg(trx); packsiz = fc::raw::pack_size(msg); bufsiz = packsiz + sizeof(packsiz); @@ -1663,7 +1675,7 @@ namespace enumivo { ds.write( reinterpret_cast(&packsiz), sizeof(packsiz) ); fc::raw::pack( ds, msg ); node_transaction_state nts = {id, - trx.expiration(), + trx_expiration, trx, std::move(buff), 0, 0, 0}; @@ -1671,15 +1683,18 @@ namespace enumivo { if(bufsiz <= just_send_it_max) { connection_wptr weak_skip = skip; - my_impl->send_all( trx, [weak_skip, id](connection_ptr c) -> bool { + my_impl->send_all( trx, [weak_skip, id, trx_expiration](connection_ptr c) -> bool { if(c == weak_skip.lock() || c->syncing ) { return false; } const auto& bs = c->trx_state.find(id); bool unknown = bs == c->trx_state.end(); if( unknown) { - c->trx_state.insert(transaction_state({id,true,true,0,time_point() })); + c->trx_state.insert(transaction_state({id,true,true,0,trx_expiration,time_point() })); fc_dlog(logger, "sending whole trx to ${n}", ("n",c->peer_name() ) ); + } else { + update_txn_expiry ute(trx_expiration); + c->trx_state.modify(bs, ute); } return unknown; }); @@ -1690,7 +1705,7 @@ namespace enumivo { pending_notify.known_trx.ids.push_back( id ); pending_notify.known_blocks.mode = none; connection_wptr weak_skip = skip; - my_impl->send_all(pending_notify, [weak_skip, id](connection_ptr c) -> bool { + my_impl->send_all(pending_notify, [weak_skip, id, trx_expiration](connection_ptr c) -> bool { if (c == weak_skip.lock() || c->syncing) { return false; } @@ -1698,7 +1713,10 @@ namespace enumivo { bool unknown = bs == c->trx_state.end(); if( unknown) { fc_dlog(logger, "sending notice to ${n}", ("n",c->peer_name() ) ); - c->trx_state.insert(transaction_state({id,false,true,0, time_point() })); + c->trx_state.insert(transaction_state({id,false,true,0,trx_expiration,time_point() })); + } else { + update_txn_expiry ute(trx_expiration); + c->trx_state.modify(bs, ute); } return unknown; }); @@ -1832,7 +1850,10 @@ namespace enumivo { if( tx == my_impl->local_txns.end( ) ) { fc_dlog(logger,"did not find ${id}",("id",t)); - c->trx_state.insert( (transaction_state){t,true,true,0, + //At this point the details of the txn are not known, just its id. This + //effectively gives 120 seconds to learn of the details of the txn which + //will update the expiry in bcast_transaction + c->trx_state.insert( (transaction_state){t,true,true,0,time_point_sec(time_point::now()) + 120, time_point()} ); req.req_trx.ids.push_back( t ); @@ -2595,6 +2616,8 @@ namespace enumivo { for ( auto &c : connections ) { auto &stale_txn = c->trx_state.get(); stale_txn.erase( stale_txn.lower_bound(1), stale_txn.upper_bound(bn) ); + auto &stale_txn_e = c->trx_state.get(); + stale_txn_e.erase(stale_txn_e.lower_bound(time_point_sec()), stale_txn_e.upper_bound(time_point::now())); auto &stale_blk = c->blk_state.get(); stale_blk.erase( stale_blk.lower_bound(1), stale_blk.upper_bound(bn) ); } diff --git a/unittests/enumivo.system_tests.cpp b/unittests/enumivo.system_tests.cpp index 1d5e5a09295..38dedec1e58 100644 --- a/unittests/enumivo.system_tests.cpp +++ b/unittests/enumivo.system_tests.cpp @@ -170,7 +170,8 @@ BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, enumivo_system_tester ) tr BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); //enumivo stakes for alice with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "enumivo", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + transfer( "enumivo", "bob111111111", core_from_string("1000.0000"), "enumivo" ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111", "alice1111111", 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"); @@ -208,6 +209,10 @@ BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, enumivo_system_tester ) tr 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", core_from_string("0.0000")), get_voter_info( "alice1111111" ) ); + + // Now alice stakes to bob with transfer flag + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_from_string("100.0000"), core_from_string("100.0000") ) ); + } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( fail_without_auth, enumivo_system_tester ) try { @@ -2247,7 +2252,7 @@ BOOST_FIXTURE_TEST_CASE( buyname, enumivo_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), bidname( "sam", "nofail", core_from_string( "2.0000" ) )); // didn't increase bid by 10% produce_block( fc::days(1) ); produce_block(); - + BOOST_REQUIRE_THROW( create_accounts_with_resources( { N(nofail) }, N(dan) ), fc::exception); // dan shoudn't be able to do this, sam won //wlog( "verify sam can create nofail" ); create_accounts_with_resources( { N(nofail) }, N(sam) ); // sam should be able to do this, he won the bid @@ -2257,7 +2262,7 @@ BOOST_FIXTURE_TEST_CASE( buyname, enumivo_system_tester ) try { //wlog( "verify dan cannot create test.fail" ); BOOST_REQUIRE_THROW( create_accounts_with_resources( { N(test.fail) }, N(dan) ), fc::exception ); // dan shouldn't be able to do this -} FC_LOG_AND_RETHROW() +} FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( multiple_namebids, enumivo_system_tester ) try { @@ -2280,12 +2285,12 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, enumivo_system_tester ) try { ("voter", "bob") ("proxy", name(0).to_string() ) ("producers", vector{ N(producer) } ) - ) + ) ); BOOST_REQUIRE_EQUAL( success(), push_action( N(carl), N(voteproducer), mvo() ("voter", "carl") ("proxy", name(0).to_string() ) - ("producers", vector{ N(producer) } ) + ("producers", vector{ N(producer) } ) ) ); @@ -2299,7 +2304,7 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, enumivo_system_tester ) try { bidname( "carl", "prefd", core_from_string("1.0000") ); bidname( "carl", "prefe", core_from_string("1.0000") ); BOOST_REQUIRE_EQUAL( core_from_string( "9998.0000" ), get_balance("carl") ); - + BOOST_REQUIRE_EQUAL( error("assertion failure with message: account is already high bidder"), bidname( "bob", "prefb", core_from_string("1.1001") ) ); BOOST_REQUIRE_EQUAL( error("assertion failure with message: must increase bid by 10%"), @@ -2347,7 +2352,7 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, enumivo_system_tester ) try { ("producers", vector{ N(producer) } ) ) ); - + // need to wait for 14 days after going live produce_blocks(10); produce_block( fc::days(2) ); @@ -2355,7 +2360,7 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, enumivo_system_tester ) try { BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefd), N(david) ), fc::exception, fc_assert_exception_message_is( not_closed_message ) ); // it's been 14 days, auction for prefd has been closed - produce_block( fc::days(12) ); + produce_block( fc::days(12) ); create_account_with_resources( N(prefd), N(david) ); produce_blocks(2); produce_block( fc::hours(23) ); @@ -2381,7 +2386,7 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, enumivo_system_tester ) try { BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(eve) ), fc::exception, fc_assert_exception_message_is( not_closed_message ) ); // but changing a bid that is not the highest does not push closing time - BOOST_REQUIRE_EQUAL( success(), + BOOST_REQUIRE_EQUAL( success(), bidname( "carl", "prefe", core_from_string("2.0980") ) ); produce_block( fc::hours(2) ); produce_blocks(2); @@ -2393,12 +2398,12 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, enumivo_system_tester ) try { create_account_with_resources( N(prefb), N(eve) ); BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefe), N(carl) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); + fc::exception, fc_assert_exception_message_is( not_closed_message ) ); produce_block(); produce_block( fc::hours(24) ); // by now bid for prefe has closed create_account_with_resources( N(prefe), N(carl) ); - // prefe can now create *.prefe + // prefe can now create *.prefe BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(xyz.prefe), N(carl) ), fc::exception, fc_assert_exception_message_is("only suffix may create this account") ); transfer( config::system_account_name, N(prefe), core_from_string("10000.0000") );