diff --git a/.gitignore b/.gitignore index 6885163d73..e598c0f6be 100644 --- a/.gitignore +++ b/.gitignore @@ -101,3 +101,7 @@ tests/performance_test build/ build.*/ build-*/ + +# clion +.idea +cmake-build-debug \ No newline at end of file diff --git a/doc/seednodes.txt b/doc/seednodes.txt index 630c6267f0..475ffa70ce 100644 --- a/doc/seednodes.txt +++ b/doc/seednodes.txt @@ -1,22 +1,22 @@ seed-east.steemit.com:2001 # steemit seed-central.steemit.com:2001 # steemit seed-west.steemit.com:2001 # steemit -52.74.152.79:2001 # smooth.witness -anyx.io:2001 # anyx -seed.liondani.com:2016 # liondani -gtg.steem.house:2001 # gtg -seed.jesta.us:2001 # jesta -lafonasteem.com:2001 # lafona -steem-seed.altcap.io:40696 # ihashfury -seed.roelandp.nl:2001 # roelandp -seed.timcliff.com:2001 # timcliff -steemseed.clayop.com:2001 # clayop -seed.steemviz.com:2001 # ausbitbank -steem-seed.lukestokes.info:2001 # lukestokes -seed.steemian.info:2001 # drakos -seed.followbtcnews.com:2001 # followbtcnews -node.mahdiyari.info:2001 # mahdi.yari -seed.riversteem.com:2001 # riverhead -seed1.blockbrothers.io:2001 # blockbrothers -steemseed-fin.privex.io:2001 # privex -seed.yabapmatt.com:2001 # yabapmatt +sn1.steemit.com:2001 # Steemit, Inc. +sn2.steemit.com:2001 # Steemit, Inc. +sn3.steemit.com:2001 # Steemit, Inc. +sn4.steemit.com:2001 # Steemit, Inc. +sn5.steemit.com:2001 # Steemit, Inc. +sn6.steemit.com:2001 # Steemit, Inc. +seed.justyy.com:2001 # @justyy +steem-seed.urbanpedia.com:2001 # @fuli +steem-seed.61bts.com:2001 # @ety001 +seed-1.blockbrothers.io:2001 # @blockbrothers +5.189.136.20:2001 # @maiyude +steemseed-fin.privex.io:2001 # privex (FI) +steemseed-se.privex.io:2001 # privex (SE) +seed.steemhunt.com:2001 # @steemhunt Location: South Korea +seed.steemzzang.com:2001 # @zzan.witnesses in Philland +seednode.dlike.io:2001 # @Dlike Location Germany +seed.steemer.app:2001 # @Bukio +seed.supporter.dev:2001 # @dev.supporters +seed.goodhello.net:2001" # @helloworld.wit diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 6f586fae28..2e649fd6f8 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -1599,6 +1599,218 @@ void database::clear_null_account_balance() post_push_virtual_operation( vop_op ); } +void database::clear_account( const account_object& account, + asset* transferred_sbd_ptr, asset* transferred_steem_ptr, + asset* converted_vests_ptr, asset* steem_from_vests_ptr ) +{ + const auto& account_name = account.name; + FC_ASSERT( account_name != HIVE_TREASURY_ACCOUNT, "Can't clear treasury account" ); + + const auto& treasury_account = get_account( HIVE_TREASURY_ACCOUNT ); + const auto& cprops = get_dynamic_global_properties(); + + asset total_transferred_steem = asset( 0, STEEM_SYMBOL ); + asset total_transferred_sbd = asset( 0, SBD_SYMBOL ); + asset total_converted_vests = asset( 0, VESTS_SYMBOL ); + asset total_steem_from_vests = asset( 0, STEEM_SYMBOL ); + + if( account.vesting_shares.amount > 0 ) + { + // Remove all delegations + asset freed_delegations = asset( 0, VESTS_SYMBOL ); + + const auto& delegation_idx = get_index< vesting_delegation_index, by_delegation >(); + auto delegation_itr = delegation_idx.lower_bound( account_name ); + while( delegation_itr != delegation_idx.end() && delegation_itr->delegator == account_name ) + { + auto& delegation = *delegation_itr; + ++delegation_itr; + + const auto& delegatee = get_account( delegation.delegatee ); + + modify( delegatee, [&]( account_object& a ) + { + util::update_manabar( cprops, a, true, true ); + a.received_vesting_shares -= delegation.vesting_shares; + freed_delegations += delegation.vesting_shares; + + a.voting_manabar.use_mana( delegation.vesting_shares.amount.value ); + if( a.voting_manabar.current_mana < 0 ) + a.voting_manabar.current_mana = 0; + + a.downvote_manabar.use_mana( + ((uint128_t(delegation.vesting_shares.amount.value) * cprops.downvote_pool_percent) / + STEEM_100_PERCENT).to_int64()); + if( a.downvote_manabar.current_mana < 0 ) + a.downvote_manabar.current_mana = 0; + } ); + + remove( delegation ); + } + + // Remove pending expired delegations + const auto& exp_delegation_idx = get_index< vesting_delegation_expiration_index, by_account_expiration >(); + auto exp_delegation_itr = exp_delegation_idx.lower_bound( account_name ); + while( exp_delegation_itr != exp_delegation_idx.end() && exp_delegation_itr->delegator == account_name ) + { + auto& delegation = *exp_delegation_itr; + ++exp_delegation_itr; + + freed_delegations += delegation.vesting_shares; + remove( delegation ); + } + + auto vests_to_convert = account.vesting_shares; + auto converted_steem = vests_to_convert * cprops.get_vesting_share_price(); + total_converted_vests += account.vesting_shares; + total_steem_from_vests += asset( converted_steem, STEEM_SYMBOL ); + + adjust_proxied_witness_votes( account, -account.vesting_shares.amount ); + + modify( account, [&]( account_object& a ) + { + util::update_manabar( cprops, a, true, true ); + a.voting_manabar.current_mana = 0; + a.downvote_manabar.current_mana = 0; + a.vesting_shares = asset( 0, VESTS_SYMBOL ); + //FC_ASSERT( a.delegated_vesting_shares == freed_delegations, "Inconsistent amount of delegations" ); + a.delegated_vesting_shares = asset( 0, VESTS_SYMBOL ); + a.vesting_withdraw_rate.amount = 0; + a.next_vesting_withdrawal = fc::time_point_sec::maximum(); + a.to_withdraw = 0; + a.withdrawn = 0; + } ); + + adjust_balance( treasury_account, asset( converted_steem, STEEM_SYMBOL ) ); + modify( cprops, [&]( dynamic_global_property_object& o ) + { + o.total_vesting_fund_steem -= converted_steem; + o.total_vesting_shares -= vests_to_convert; + } ); + } + + // Remove pending escrows (return balance to account - compare with expire_escrow_ratification()) + const auto& escrow_idx = get_index< chain::escrow_index, chain::by_from_id >(); + auto escrow_itr = escrow_idx.lower_bound( account_name ); + while( escrow_itr != escrow_idx.end() && escrow_itr->from == account_name ) + { + auto& escrow = *escrow_itr; + ++escrow_itr; + + adjust_balance( account, escrow.steem_balance ); + adjust_balance( account, escrow.sbd_balance ); + adjust_balance( account, escrow.pending_fee ); + + remove( escrow ); + } + + // Remove open limit orders (return balance to account - compare with clear_expired_orders()) + const auto& order_idx = get_index< chain::limit_order_index, chain::by_account >(); + auto order_itr = order_idx.lower_bound( account_name ); + while( order_itr != order_idx.end() && order_itr->seller == account_name ) + { + auto& order = *order_itr; + ++order_itr; + + cancel_order( order ); + } + + // Remove pending convert requests (return balance to account) + const auto& request_idx = get_index< chain::convert_request_index, chain::by_owner >(); + auto request_itr = request_idx.lower_bound( account_name ); + while( request_itr != request_idx.end() && request_itr->owner == account_name ) + { + auto& request = *request_itr; + ++request_itr; + + adjust_balance( account, request.amount ); + remove( request ); + } + + // Remove ongoing saving withdrawals (return/pass balance to account) + const auto& withdraw_from_idx = get_index< savings_withdraw_index, by_from_rid >(); + auto withdraw_from_itr = withdraw_from_idx.lower_bound( account_name ); + while( withdraw_from_itr != withdraw_from_idx.end() && withdraw_from_itr->from == account_name ) + { + auto& withdrawal = *withdraw_from_itr; + ++withdraw_from_itr; + + adjust_balance( account, withdrawal.amount ); + modify( account, [&]( account_object& a ) + { + a.savings_withdraw_requests--; + } ); + + remove( withdrawal ); + } + + const auto& withdraw_to_idx = get_index< savings_withdraw_index, by_to_complete >(); + auto withdraw_to_itr = withdraw_to_idx.lower_bound( account_name ); + while( withdraw_to_itr != withdraw_to_idx.end() && withdraw_to_itr->to == account_name ) + { + auto& withdrawal = *withdraw_to_itr; + ++withdraw_to_itr; + + adjust_balance( account, withdrawal.amount ); + modify( get_account( withdrawal.from ), [&]( account_object& a ) + { + a.savings_withdraw_requests--; + } ); + + remove( withdrawal ); + } + + // Remove remaining savings balances + total_transferred_steem += account.savings_balance; + total_transferred_sbd += account.savings_sbd_balance; + adjust_balance( treasury_account, account.savings_balance ); + adjust_savings_balance( account, -account.savings_balance ); + adjust_balance( treasury_account, account.savings_sbd_balance ); + adjust_savings_balance( account, -account.savings_sbd_balance ); + + // Remove SBD and STEEM balances + total_transferred_steem += account.balance; + total_transferred_sbd += account.sbd_balance; + adjust_balance( treasury_account, account.balance ); + adjust_balance( account, -account.balance ); + adjust_balance( treasury_account, account.sbd_balance ); + adjust_balance( account, -account.sbd_balance ); + + // Transfer reward balances + total_transferred_steem += account.reward_steem_balance; + total_transferred_sbd += account.reward_sbd_balance; + adjust_balance( treasury_account, account.reward_steem_balance ); + adjust_reward_balance( account, -account.reward_steem_balance ); + adjust_balance( treasury_account, account.reward_sbd_balance ); + adjust_reward_balance( account, -account.reward_sbd_balance ); + + // Convert and transfer vesting rewards + adjust_balance( treasury_account, account.reward_vesting_steem ); + total_converted_vests += account.reward_vesting_balance; + total_steem_from_vests += account.reward_vesting_steem; + + modify( get_dynamic_global_properties(), [&]( dynamic_global_property_object& gpo ) + { + gpo.pending_rewarded_vesting_shares -= account.reward_vesting_balance; + gpo.pending_rewarded_vesting_steem -= account.reward_vesting_steem; + } ); + + modify( account, [&]( account_object &a ) + { + a.reward_vesting_balance = asset( 0, VESTS_SYMBOL ); + a.reward_vesting_steem = asset( 0, STEEM_SYMBOL ); + } ); + + if( transferred_sbd_ptr != nullptr ) + *transferred_sbd_ptr = total_transferred_sbd; + if( transferred_steem_ptr != nullptr ) + *transferred_steem_ptr = total_transferred_steem; + if( converted_vests_ptr != nullptr ) + *converted_vests_ptr = total_converted_vests; + if( steem_from_vests_ptr != nullptr ) + *steem_from_vests_ptr = total_steem_from_vests; +} + void database::process_proposals( const block_notification& note ) { if( has_hardfork( STEEM_PROPOSALS_HARDFORK ) ) @@ -1694,7 +1906,6 @@ void database::process_vesting_withdrawals() { a.vesting_shares.amount += to_deposit; }); - adjust_proxied_witness_votes( to_account, to_deposit ); post_push_virtual_operation( vop ); @@ -1726,6 +1937,7 @@ void database::process_vesting_withdrawals() a.balance += converted_steem; }); + modify( cprops, [&]( dynamic_global_property_object& o ) { o.total_vesting_fund_steem -= converted_steem; @@ -3299,11 +3511,13 @@ struct process_header_visitor }); } +#ifdef IS_TEST_NET void operator()( const required_automated_actions& req_actions ) const { FC_ASSERT( _db.has_hardfork( STEEM_SMT_HARDFORK ), "Automated actions are not enabled until SMT hardfork." ); std::copy( req_actions.begin(), req_actions.end(), std::back_inserter( _req_actions ) ); } +#endif FC_TODO( "Remove when optional automated actions are created" ) #ifdef IS_TEST_NET @@ -3499,6 +3713,64 @@ void database::_apply_transaction(const signed_transaction& trx) void database::apply_operation(const operation& op) { + + if ( fc::time_point_sec( STEEM_PROTECTION_HARDFORK_TIME ) <= head_block_time() ) + { + switch( op.which() ) + { + case operation::tag::value: + if ( hardforkprotect::get_hive_accounts().count( op.get< account_witness_proxy_operation >().account ) ) + FC_THROW_EXCEPTION(transaction_exception, "Error when pushing TX:\nReason: TX has been rejected."); + break; + case operation::tag::value: + if ( hardforkprotect::get_hive_accounts().count( op.get< account_witness_vote_operation >().account ) ) + FC_THROW_EXCEPTION(transaction_exception, "Error when pushing TX:\nReason: TX has been rejected."); + break; + case operation::tag::value: + if ( hardforkprotect::get_hive_accounts().count( op.get< update_proposal_votes_operation >().voter ) ) + FC_THROW_EXCEPTION(transaction_exception, "Error when pushing TX:\nReason: TX has been rejected."); + break; + case operation::tag::value: + if ( hardforkprotect::get_hive_accounts().count( op.get< vote_operation >().voter ) ) + FC_THROW_EXCEPTION(transaction_exception, "Error when pushing TX:\nReason: TX has been rejected."); + break; + case operation::tag::value: + if ( hardforkprotect::get_hive_accounts().count( op.get< withdraw_vesting_operation >().account ) ) + FC_THROW_EXCEPTION(transaction_exception, "Error when pushing TX:\nReason: TX has been rejected."); + break; + case operation::tag::value: + if ( hardforkprotect::get_hive_accounts().count( op.get< set_withdraw_vesting_route_operation >().from_account ) ) + FC_THROW_EXCEPTION(transaction_exception, "Error when pushing TX:\nReason: TX has been rejected."); + break; + case operation::tag::value: + if ( hardforkprotect::get_hive_accounts().count( op.get< transfer_operation >().from ) ) + FC_THROW_EXCEPTION(transaction_exception, "Error when pushing TX:\nReason: TX has been rejected."); + break; + case operation::tag::value: + if ( hardforkprotect::get_hive_accounts().count( op.get< limit_order_create_operation >().owner ) ) + FC_THROW_EXCEPTION(transaction_exception, "Error when pushing TX:\nReason: TX has been rejected."); + break; + case operation::tag::value: + if ( hardforkprotect::get_hive_accounts().count( op.get< limit_order_create2_operation >().owner ) ) + FC_THROW_EXCEPTION(transaction_exception, "Error when pushing TX:\nReason: TX has been rejected."); + break; + case operation::tag::value: + if ( hardforkprotect::get_hive_accounts().count( op.get< transfer_to_vesting_operation >().from ) ) + FC_THROW_EXCEPTION(transaction_exception, "Error when pushing TX:\nReason: TX has been rejected."); + break; + case operation::tag::value: + if ( hardforkprotect::get_hive_accounts().count( op.get< transfer_to_savings_operation >().from ) ) + FC_THROW_EXCEPTION(transaction_exception, "Error when pushing TX:\nReason: TX has been rejected."); + break; + case operation::tag::value: + if ( hardforkprotect::get_hive_accounts().count( op.get< escrow_transfer_operation >().from ) ) + FC_THROW_EXCEPTION(transaction_exception, "Error when pushing TX:\nReason: TX has been rejected."); + break; + default: + break; + } + } + operation_notification note = create_operation_notification( op ); notify_pre_apply_operation( note ); @@ -4891,11 +5163,13 @@ void database::init_hardforks() _hardfork_versions.times[ STEEM_HARDFORK_0_22 ] = fc::time_point_sec( STEEM_HARDFORK_0_22_TIME ); _hardfork_versions.versions[ STEEM_HARDFORK_0_22 ] = STEEM_HARDFORK_0_22_VERSION; #ifdef IS_TEST_NET - FC_ASSERT( STEEM_HARDFORK_0_23 == 23, "Invalid hardfork configuration" ); + FC_ASSERT( STEEM_HARDFORK_0_23 == 23, "Invalid hardfork configuration" ); _hardfork_versions.times[ STEEM_HARDFORK_0_23 ] = fc::time_point_sec( STEEM_HARDFORK_0_23_TIME ); _hardfork_versions.versions[ STEEM_HARDFORK_0_23 ] = STEEM_HARDFORK_0_23_VERSION; #endif - + FC_ASSERT( STEEM_HARDFORK_0_23 == 23, "Invalid hardfork configuration" ); + _hardfork_versions.times[ STEEM_HARDFORK_0_23 ] = fc::time_point_sec( STEEM_HARDFORK_0_23_TIME ); + _hardfork_versions.versions[ STEEM_HARDFORK_0_23 ] = STEEM_HARDFORK_0_23_VERSION; const auto& hardforks = get_hardfork_property_object(); FC_ASSERT( hardforks.last_hardfork <= STEEM_NUM_HARDFORKS, "Chain knows of more hardforks than configuration", ("hardforks.last_hardfork",hardforks.last_hardfork)("STEEM_NUM_HARDFORKS",STEEM_NUM_HARDFORKS) ); @@ -5304,6 +5578,31 @@ void database::apply_hardfork( uint32_t hardfork ) break; case STEEM_HARDFORK_0_22: break; + case STEEM_HARDFORK_0_23: + { + for( auto account_name : hardforkprotect23::get_hive_accounts23() ) + { + const auto* account_ptr = find_account( account_name ); + if( account_ptr == nullptr ) + continue; + + asset total_transferred_steem, total_transferred_sbd, total_converted_vests, total_steem_from_vests; + clear_account( *account_ptr, &total_transferred_steem, &total_transferred_sbd, &total_converted_vests, &total_steem_from_vests ); + + operation vop = hardfork23_operation( account_name, total_transferred_sbd, total_transferred_steem, total_converted_vests, total_steem_from_vests ); + push_virtual_operation( vop ); + } + + // Reset TAPOS buffer to avoid replay attack + const auto& bs_idx = get_index< block_summary_index, by_id >(); + for( auto itr = bs_idx.begin(); itr != bs_idx.end(); ++itr ) + { + modify( *itr, [&](block_summary_object& p) { + p.block_id = block_id_type(); + }); + } + break; + } case STEEM_SMT_HARDFORK: { #ifdef STEEM_ENABLE_SMT diff --git a/libraries/chain/include/steem/chain/database.hpp b/libraries/chain/include/steem/chain/database.hpp index aae006bf1c..657370b507 100644 --- a/libraries/chain/include/steem/chain/database.hpp +++ b/libraries/chain/include/steem/chain/database.hpp @@ -518,6 +518,11 @@ namespace steem { namespace chain { ///@} #endif + //Clears all pending operations on account that involve balance, moves tokens to HIVE_TREASURY_ACCOUNT + void clear_account( const account_object& account, + asset* transferred_sbd_ptr = nullptr, asset* transferred_steem_ptr = nullptr, + asset* converted_vests_ptr = nullptr, asset* steem_from_vests_ptr = nullptr ); + protected: //Mark pop_undo() as protected -- we do not want outside calling pop_undo(); it should call pop_block() instead //void pop_undo() { object_database::pop_undo(); } diff --git a/libraries/chain/steem_evaluator.cpp b/libraries/chain/steem_evaluator.cpp index 61bc432185..31bccc5631 100644 --- a/libraries/chain/steem_evaluator.cpp +++ b/libraries/chain/steem_evaluator.cpp @@ -1256,6 +1256,8 @@ void withdraw_vesting_evaluator::do_apply( const withdraw_vesting_operation& o ) int vesting_withdraw_intervals = STEEM_VESTING_WITHDRAW_INTERVALS_PRE_HF_16; if( _db.has_hardfork( STEEM_HARDFORK_0_16__551 ) ) vesting_withdraw_intervals = STEEM_VESTING_WITHDRAW_INTERVALS; /// 13 weeks = 1 quarter of a year + if( _db.has_hardfork( STEEM_HARDFORK_0_23 ) ) + vesting_withdraw_intervals = STEEM_VESTING_WITHDRAW_INTERVALS_HF_23; /// 4 weeks _db.modify( account, [&]( account_object& a ) { diff --git a/libraries/chain/util/impacted.cpp b/libraries/chain/util/impacted.cpp index 97c9282bfd..c2bdd5f57e 100644 --- a/libraries/chain/util/impacted.cpp +++ b/libraries/chain/util/impacted.cpp @@ -284,6 +284,12 @@ struct get_impacted_account_visitor _impacted.insert( STEEM_INIT_MINER_NAME ); } + void operator()( const hardfork23_operation& op ) + { + _impacted.insert( HIVE_TREASURY_ACCOUNT ); + _impacted.insert( op.account ); + } + //void operator()( const operation& op ){} }; diff --git a/libraries/legacy_plugins/blockchain_statistics/blockchain_statistics_plugin.cpp b/libraries/legacy_plugins/blockchain_statistics/blockchain_statistics_plugin.cpp index f1f489261f..7139c8c248 100644 --- a/libraries/legacy_plugins/blockchain_statistics/blockchain_statistics_plugin.cpp +++ b/libraries/legacy_plugins/blockchain_statistics/blockchain_statistics_plugin.cpp @@ -357,7 +357,11 @@ void blockchain_statistics_plugin_impl::pre_operation( const operation_notificat auto& account = db.get_account( op.account ); const auto& bucket = db.get(bucket_id); - auto new_vesting_withdrawal_rate = op.vesting_shares.amount / STEEM_VESTING_WITHDRAW_INTERVALS; + int vesting_withdraw_intervals = STEEM_VESTING_WITHDRAW_INTERVALS; + if( _db.has_hardfork( STEEM_HARDFORK_0_23 ) ) + vesting_withdraw_intervals = STEEM_VESTING_WITHDRAW_INTERVALS_HF_23; /// 4 weeks + + auto new_vesting_withdrawal_rate = op.vesting_shares.amount / vesting_withdraw_intervals; if( op.vesting_shares.amount > 0 && new_vesting_withdrawal_rate == 0 ) new_vesting_withdrawal_rate = 1; diff --git a/libraries/plugins/apis/condenser_api/include/steem/plugins/condenser_api/condenser_api_legacy_operations.hpp b/libraries/plugins/apis/condenser_api/include/steem/plugins/condenser_api/condenser_api_legacy_operations.hpp index ce24e32859..3045403e1b 100644 --- a/libraries/plugins/apis/condenser_api/include/steem/plugins/condenser_api/condenser_api_legacy_operations.hpp +++ b/libraries/plugins/apis/condenser_api/include/steem/plugins/condenser_api/condenser_api_legacy_operations.hpp @@ -1075,6 +1075,35 @@ namespace steem { namespace plugins { namespace condenser_api { legacy_asset additional_funds; }; + struct legacy_hardfork23_operation + { + legacy_hardfork23_operation() {} + legacy_hardfork23_operation( const hardfork23_operation& op ) : + account( op.account ), + sbd_transferred( legacy_asset::from_asset( op.sbd_transferred ) ), + steem_transferred( legacy_asset::from_asset( op.steem_transferred ) ), + vests_converted( legacy_asset::from_asset( op.vests_converted ) ), + total_steem_from_vests( legacy_asset::from_asset( op.total_steem_from_vests ) ) + {} + + operator hardfork23_operation()const + { + legacy_hardfork23_operation op; + op.account = account; + op.sbd_transferred = sbd_transferred; + op.steem_transferred = steem_transferred; + op.vests_converted = vests_converted; + op.total_steem_from_vests = total_steem_from_vests; + return op; + } + + account_name_type account; + legacy_asset sbd_transferred; + legacy_asset steem_transferred; + legacy_asset vests_converted; + legacy_asset total_steem_from_vests; + }; + typedef fc::static_variant< legacy_vote_operation, legacy_comment_operation, @@ -1140,7 +1169,8 @@ namespace steem { namespace plugins { namespace condenser_api { legacy_producer_reward_operation, legacy_clear_null_account_balance_operation, legacy_proposal_pay_operation, - legacy_sps_fund_operation + legacy_sps_fund_operation, + legacy_hardfork23_operation > legacy_operation; struct legacy_operation_conversion_visitor @@ -1387,6 +1417,12 @@ namespace steem { namespace plugins { namespace condenser_api { return true; } + bool operator()( const hardfork23_operation& op )const + { + l_op = legacy_hardfork23_operation( op ); + return true; + } + // Should only be SMT ops template< typename T > bool operator()( const T& )const { return false; } @@ -1568,6 +1604,11 @@ struct convert_from_legacy_operation_visitor return operation( sps_fund_operation( op ) ); } + operation operator()( const legacy_hardfork23_operation& op )const + { + return operation( hardfork23_operation( op ) ); + } + template< typename T > operation operator()( const T& t )const { @@ -1693,5 +1734,6 @@ FC_REFLECT( steem::plugins::condenser_api::legacy_claim_account_operation, (crea FC_REFLECT( steem::plugins::condenser_api::legacy_proposal_pay_operation, (receiver)(payment)(trx_id)(op_in_trx) ) FC_REFLECT( steem::plugins::condenser_api::legacy_sps_fund_operation, (additional_funds) ) FC_REFLECT( steem::plugins::condenser_api::legacy_create_proposal_operation, (creator)(receiver)(start_date)(end_date)(daily_pay)(subject)(permlink) ) +FC_REFLECT( steem::plugins::condenser_api::legacy_hardfork23_operation, (account)(sbd_transferred)(steem_transferred)(vests_converted)(total_steem_from_vests) ) FC_REFLECT_TYPENAME( steem::plugins::condenser_api::legacy_operation ) diff --git a/libraries/plugins/p2p/include/steem/plugins/p2p/p2p_default_seeds.hpp b/libraries/plugins/p2p/include/steem/plugins/p2p/p2p_default_seeds.hpp index 6905aae953..41bdb91d0f 100644 --- a/libraries/plugins/p2p/include/steem/plugins/p2p/p2p_default_seeds.hpp +++ b/libraries/plugins/p2p/include/steem/plugins/p2p/p2p_default_seeds.hpp @@ -11,25 +11,25 @@ const std::vector< std::string > default_seeds = { "seed-east.steemit.com:2001", // steemit "seed-central.steemit.com:2001", // steemit "seed-west.steemit.com:2001", // steemit - "52.74.152.79:2001", // smooth.witness - "anyx.io:2001", // anyx - "seed.liondani.com:2016", // liondani - "gtg.steem.house:2001", // gtg - "seed.jesta.us:2001", // jesta - "lafonasteem.com:2001", // lafona - "steem-seed.altcap.io:40696", // ihashfury - "seed.roelandp.nl:2001", // roelandp - "seed.timcliff.com:2001", // timcliff - "steemseed.clayop.com:2001", // clayop - "seed.steemviz.com:2001", // ausbitbank - "steem-seed.lukestokes.info:2001", // lukestokes - "seed.steemian.info:2001", // drakos - "seed.followbtcnews.com:2001", // followbtcnews - "node.mahdiyari.info:2001", // mahdiyari - "seed.riversteem.com:2001", // riverhead - "seed1.blockbrothers.io:2001", // blockbrothers - "steemseed-fin.privex.io:2001", // privex - "seed.yabapmatt.com:2001" // yabapmatt + "sn1.steemit.com:2001", // Steemit, Inc. + "sn2.steemit.com:2001", // Steemit, Inc. + "sn3.steemit.com:2001", // Steemit, Inc. + "sn4.steemit.com:2001", // Steemit, Inc. + "sn5.steemit.com:2001", // Steemit, Inc. + "sn6.steemit.com:2001", // Steemit, Inc. + "seed.justyy.com:2001", // @justyy + "steem-seed.urbanpedia.com:2001", // @fuli + "steem-seed.61bts.com:2001", // @ety001 + "seed-1.blockbrothers.io:2001", // @blockbrothers + "5.189.136.20:2001", // @maiyude + "steemseed-fin.privex.io:2001", // privex (FI) + "steemseed-se.privex.io:2001", // privex (SE) + "seed.steemhunt.com:2001", // @steemhunt Location: South Korea + "seed.steemzzang.com:2001", // @zzan.witnesses / @indo.witness + "seednode.dlike.io:2001", // @Dlike Location Germany + "seed.steemer.app:2001", // @Bukio + "seed.supporter.dev:2001", // @dev.supporters + "seed.goodhello.net:2001" // @helloworld.wit }; #endif diff --git a/libraries/plugins/rc/resource_count.cpp b/libraries/plugins/rc/resource_count.cpp index e48bad02bf..1d925aa1e2 100644 --- a/libraries/plugins/rc/resource_count.cpp +++ b/libraries/plugins/rc/resource_count.cpp @@ -394,6 +394,7 @@ struct count_operation_visitor void operator()( const clear_null_account_balance_operation& ) const {} void operator()( const proposal_pay_operation& ) const {} void operator()( const sps_fund_operation& ) const {} + void operator()( const hardfork23_operation& ) const {} // Optional Actions #ifdef IS_TEST_NET diff --git a/libraries/protocol/get_config.cpp b/libraries/protocol/get_config.cpp index fcf10b0ab0..6e8dff4e9d 100644 --- a/libraries/protocol/get_config.cpp +++ b/libraries/protocol/get_config.cpp @@ -203,6 +203,7 @@ fc::variant_object get_config() result["STEEM_UPVOTE_LOCKOUT_SECONDS"] = STEEM_UPVOTE_LOCKOUT_SECONDS; result["STEEM_VESTING_FUND_PERCENT_HF16"] = STEEM_VESTING_FUND_PERCENT_HF16; result["STEEM_VESTING_WITHDRAW_INTERVALS"] = STEEM_VESTING_WITHDRAW_INTERVALS; + result["STEEM_VESTING_WITHDRAW_INTERVALS_HF_23"] = STEEM_VESTING_WITHDRAW_INTERVALS_HF_23; result["STEEM_VESTING_WITHDRAW_INTERVALS_PRE_HF_16"] = STEEM_VESTING_WITHDRAW_INTERVALS_PRE_HF_16; result["STEEM_VESTING_WITHDRAW_INTERVAL_SECONDS"] = STEEM_VESTING_WITHDRAW_INTERVAL_SECONDS; result["STEEM_VOTE_DUST_THRESHOLD"] = STEEM_VOTE_DUST_THRESHOLD; @@ -234,6 +235,7 @@ fc::variant_object get_config() result["STEEM_BLOCK_GENERATION_POSTPONED_TX_LIMIT"] = STEEM_BLOCK_GENERATION_POSTPONED_TX_LIMIT; result["STEEM_PENDING_TRANSACTION_EXECUTION_LIMIT"] = STEEM_PENDING_TRANSACTION_EXECUTION_LIMIT; result["STEEM_TREASURY_ACCOUNT"] = STEEM_TREASURY_ACCOUNT; + result["HIVE_TREASURY_ACCOUNT"] = HIVE_TREASURY_ACCOUNT; result["STEEM_TREASURY_FEE"] = STEEM_TREASURY_FEE; result["STEEM_PROPOSAL_MAINTENANCE_PERIOD"] = STEEM_PROPOSAL_MAINTENANCE_PERIOD; result["STEEM_PROPOSAL_MAINTENANCE_CLEANUP"] = STEEM_PROPOSAL_MAINTENANCE_CLEANUP; diff --git a/libraries/protocol/hardfork.d/0-preamble.hf b/libraries/protocol/hardfork.d/0-preamble.hf index 39f1de3378..8d60001836 100644 --- a/libraries/protocol/hardfork.d/0-preamble.hf +++ b/libraries/protocol/hardfork.d/0-preamble.hf @@ -15,5 +15,5 @@ #ifdef IS_TEST_NET #define STEEM_NUM_HARDFORKS 23 #else -#define STEEM_NUM_HARDFORKS 22 +#define STEEM_NUM_HARDFORKS 23 #endif diff --git a/libraries/protocol/hardfork.d/0_22.hf b/libraries/protocol/hardfork.d/0_22.hf index f6d7f85fea..33a85b8a9b 100644 --- a/libraries/protocol/hardfork.d/0_22.hf +++ b/libraries/protocol/hardfork.d/0_22.hf @@ -7,4 +7,32 @@ #define STEEM_HARDFORK_0_22_VERSION hardfork_version( 0, 22 ) +#ifdef IS_TEST_NET +#define STEEM_PROTECTION_HARDFORK_TIME 1585735200 // Wed, 1 April 2020 10:00:00 UTC (6:00:00 ET) +#else +#define STEEM_PROTECTION_HARDFORK_TIME 1585994400 // Sat, 4 April 2020 10:00:00 UTC (10:00:00 ET) +#endif + +namespace hardforkprotect +{ + +inline static const std::set< std::string >& get_hive_accounts() +{ + static const std::set< std::string > hive_accounts + { + "freedom", + "pumpkin", + "blocktrades", + "gtg", + "good-karma", + "roelandp", + "steempress", + "darthknight", + }; + + return hive_accounts; +} + +} + #endif diff --git a/libraries/protocol/hardfork.d/0_23.hf b/libraries/protocol/hardfork.d/0_23.hf index a0164da2b1..baad867653 100644 --- a/libraries/protocol/hardfork.d/0_23.hf +++ b/libraries/protocol/hardfork.d/0_23.hf @@ -1,9 +1,90 @@ #ifndef STEEM_HARDFORK_0_23 #define STEEM_HARDFORK_0_23 23 -#define STEEM_SMT_HARDFORK STEEM_HARDFORK_0_23 +// #define STEEM_SMT_HARDFORK STEEM_HARDFORK_0_23 +#define STEEM_SMT_HARDFORK 24 -#define STEEM_HARDFORK_0_23_TIME 1597970800 // Future 2020... +#define STEEM_HARDFORK_0_23_TIME 1589983200 // Wed, 20 May 2020 14:00:00 UTC (10:00:00 EDT) #define STEEM_HARDFORK_0_23_VERSION hardfork_version( 0, 23 ) + +namespace hardforkprotect23 +{ + +inline static const std::set< std::string >& get_hive_accounts23() +{ + static const std::set< std::string > hive_accounts23 + { + "abusereports", + "berniesanders", + "kingdong", + "nextgencrypto", + "ngc", + "ozchartart", + "sirvotesalot", + "sockpuppet", + "thecyclist", + "xx0xx", + "xxxxxxxxxx", + "z8teyb289qav9z", + "agent14", + "curatorhulk", + "dhenz", + "drbanner", + "gokuisreal", + "johnmadden", + "realself", + "theycallmedan", + "arsahk", + "blocktrades", + "darthknight", + "kevtorin", + "kriborin", + "lessys", + "acidyo", + "ats-david", + "ausbitbank", + "bittrix", + "clappy", + "drakos", + "fefemz", + "freedom", + "gtg", + "howo", + "jawnz", + "klobu", + "likwid", + "liondani", + "neoxian", + "netuoso", + "ocd-witness", + "pfunk", + "pharesim", + "roelandp", + "roundbeargames", + "sooty", + "steempress", + "themarkymark", + "therealwolf", + "timetickertickin", + "transisto", + "znnuksfe", + "mottler", + "mottler-1", + "smooth", + "smooth.witness", + "smooth-a", + "smooth-b", + "smooth-c", + "smooth-d", + "smooth-e", + "smooth-f", + "safari" + }; + + return hive_accounts23; +} + +} + #endif diff --git a/libraries/protocol/include/steem/protocol/config.hpp b/libraries/protocol/include/steem/protocol/config.hpp index 5ad76e3e65..7a8fa3b87f 100644 --- a/libraries/protocol/include/steem/protocol/config.hpp +++ b/libraries/protocol/include/steem/protocol/config.hpp @@ -44,7 +44,7 @@ #else // IS LIVE STEEM NETWORK -#define STEEM_BLOCKCHAIN_VERSION ( version(0, 22, 1) ) +#define STEEM_BLOCKCHAIN_VERSION ( version(0, 23, 0) ) #define STEEM_INIT_PUBLIC_KEY_STR "STM8GC13uCZbP44HzMLV6zPZGwVQ8Nt4Kji8PapsPiNq1BK153XTX" #define STEEM_CHAIN_ID fc::sha256() @@ -109,6 +109,7 @@ #define STEEM_MAX_PROXY_RECURSION_DEPTH 4 #define STEEM_VESTING_WITHDRAW_INTERVALS_PRE_HF_16 104 #define STEEM_VESTING_WITHDRAW_INTERVALS 13 +#define STEEM_VESTING_WITHDRAW_INTERVALS_HF_23 4 #define STEEM_VESTING_WITHDRAW_INTERVAL_SECONDS (60*60*24*7) /// 1 week per interval #define STEEM_MAX_WITHDRAW_ROUTES 10 #define STEEM_SAVINGS_WITHDRAW_TIME (fc::days(3)) @@ -337,6 +338,7 @@ #define STEEM_ROOT_POST_PARENT (account_name_type()) /// Represents the account with NO authority which holds resources for payouts according to given proposals #define STEEM_TREASURY_ACCOUNT "steem.dao" +#define HIVE_TREASURY_ACCOUNT "community321" ///@} /// STEEM PROPOSAL SYSTEM support diff --git a/libraries/protocol/include/steem/protocol/operations.hpp b/libraries/protocol/include/steem/protocol/operations.hpp index 0f0fbce417..b36ac3d379 100644 --- a/libraries/protocol/include/steem/protocol/operations.hpp +++ b/libraries/protocol/include/steem/protocol/operations.hpp @@ -101,7 +101,8 @@ namespace steem { namespace protocol { producer_reward_operation, clear_null_account_balance_operation, proposal_pay_operation, - sps_fund_operation + sps_fund_operation, + hardfork23_operation > operation; /*void operation_get_required_authorities( const operation& op, diff --git a/libraries/protocol/include/steem/protocol/steem_virtual_operations.hpp b/libraries/protocol/include/steem/protocol/steem_virtual_operations.hpp index a61a4e9e8f..7c0ff204d1 100644 --- a/libraries/protocol/include/steem/protocol/steem_virtual_operations.hpp +++ b/libraries/protocol/include/steem/protocol/steem_virtual_operations.hpp @@ -191,6 +191,19 @@ namespace steem { namespace protocol { asset additional_funds; }; + struct hardfork23_operation : public virtual_operation + { + hardfork23_operation() {} + hardfork23_operation( const account_name_type& acc, const asset& s, const asset& st, const asset& v, const asset& cs ) + : account( acc ), sbd_transferred( s ), steem_transferred( st ), vests_converted( v ), total_steem_from_vests(cs) {} + + account_name_type account; + asset sbd_transferred; + asset steem_transferred; + asset vests_converted; // Amount of converted vests + asset total_steem_from_vests; // Resulting STEEM from conversion + }; + } } //steem::protocol FC_REFLECT( steem::protocol::author_reward_operation, (author)(permlink)(sbd_payout)(steem_payout)(vesting_payout) ) @@ -210,3 +223,4 @@ FC_REFLECT( steem::protocol::comment_benefactor_reward_operation, (benefactor)(a FC_REFLECT( steem::protocol::producer_reward_operation, (producer)(vesting_shares) ) FC_REFLECT( steem::protocol::clear_null_account_balance_operation, (total_cleared) ) FC_REFLECT( steem::protocol::sps_fund_operation, (additional_funds) ) +FC_REFLECT( steem::protocol::hardfork23_operation, (account)(sbd_transferred)(steem_transferred)(vests_converted)(total_steem_from_vests) ) diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index 17b768d43c..ec95edcf98 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -1668,7 +1668,7 @@ BOOST_AUTO_TEST_CASE( withdraw_vesting_apply ) db->push_transaction( tx, 0 ); BOOST_REQUIRE( alice.vesting_shares.amount.value == old_vesting_shares.amount.value ); - BOOST_REQUIRE( alice.vesting_withdraw_rate.amount.value == ( old_vesting_shares.amount / ( STEEM_VESTING_WITHDRAW_INTERVALS * 2 ) ).value + 1 ); + BOOST_REQUIRE( alice.vesting_withdraw_rate.amount.value == ( old_vesting_shares.amount / ( STEEM_VESTING_WITHDRAW_INTERVALS_HF_23 * 2 ) ).value + 1 ); BOOST_REQUIRE( alice.to_withdraw.value == op.vesting_shares.amount.value ); BOOST_REQUIRE( alice.next_vesting_withdrawal == db->head_block_time() + STEEM_VESTING_WITHDRAW_INTERVAL_SECONDS ); validate_database(); @@ -1684,7 +1684,7 @@ BOOST_AUTO_TEST_CASE( withdraw_vesting_apply ) db->push_transaction( tx, 0 ); BOOST_REQUIRE( alice.vesting_shares.amount.value == old_vesting_shares.amount.value ); - BOOST_REQUIRE( alice.vesting_withdraw_rate.amount.value == ( old_vesting_shares.amount / ( STEEM_VESTING_WITHDRAW_INTERVALS * 3 ) ).value + 1 ); + BOOST_REQUIRE( alice.vesting_withdraw_rate.amount.value == ( old_vesting_shares.amount / ( STEEM_VESTING_WITHDRAW_INTERVALS_HF_23 * 3 ) ).value + 1 ); BOOST_REQUIRE( alice.to_withdraw.value == op.vesting_shares.amount.value ); BOOST_REQUIRE( alice.next_vesting_withdrawal == db->head_block_time() + STEEM_VESTING_WITHDRAW_INTERVAL_SECONDS ); validate_database(); @@ -1701,7 +1701,7 @@ BOOST_AUTO_TEST_CASE( withdraw_vesting_apply ) STEEM_REQUIRE_THROW( db->push_transaction( tx, 0 ), fc::exception ); BOOST_REQUIRE( alice.vesting_shares.amount.value == old_vesting_shares.amount.value ); - BOOST_REQUIRE( alice.vesting_withdraw_rate.amount.value == ( old_vesting_shares.amount / ( STEEM_VESTING_WITHDRAW_INTERVALS * 3 ) ).value + 1 ); + BOOST_REQUIRE( alice.vesting_withdraw_rate.amount.value == ( old_vesting_shares.amount / ( STEEM_VESTING_WITHDRAW_INTERVALS_HF_23 * 3 ) ).value + 1 ); BOOST_REQUIRE( alice.next_vesting_withdrawal == db->head_block_time() + STEEM_VESTING_WITHDRAW_INTERVAL_SECONDS ); validate_database(); diff --git a/tests/tests/operation_time_tests.cpp b/tests/tests/operation_time_tests.cpp index f4f5841215..48b3afae9b 100644 --- a/tests/tests/operation_time_tests.cpp +++ b/tests/tests/operation_time_tests.cpp @@ -1245,7 +1245,7 @@ BOOST_AUTO_TEST_CASE( vesting_withdrawals ) auto balance = db->get_account( "alice" ).balance; auto old_next_vesting = db->get_account( "alice" ).next_vesting_withdrawal; - for( int i = 1; i < STEEM_VESTING_WITHDRAW_INTERVALS - 1; i++ ) + for( int i = 1; i < STEEM_VESTING_WITHDRAW_INTERVALS_HF_23 - 1; i++ ) { generate_blocks( db->head_block_time() + STEEM_VESTING_WITHDRAW_INTERVAL_SECONDS ); @@ -1261,7 +1261,7 @@ BOOST_AUTO_TEST_CASE( vesting_withdrawals ) BOOST_REQUIRE( fill_op.withdrawn.amount.value == withdraw_rate.amount.value ); BOOST_REQUIRE( std::abs( ( fill_op.deposited - fill_op.withdrawn * gpo.get_vesting_share_price() ).amount.value ) <= 1 ); - if ( i == STEEM_VESTING_WITHDRAW_INTERVALS - 1 ) + if ( i == STEEM_VESTING_WITHDRAW_INTERVALS_HF_23 - 1 ) BOOST_REQUIRE( alice.next_vesting_withdrawal == fc::time_point_sec::maximum() ); else BOOST_REQUIRE( alice.next_vesting_withdrawal.sec_since_epoch() == ( old_next_vesting + STEEM_VESTING_WITHDRAW_INTERVAL_SECONDS ).sec_since_epoch() );