diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index af9929ec..5c72d1bc 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -447,6 +447,16 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.network_fee_percentage = 0; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT; }).get_id() == GRAPHENE_RAKE_FEE_ACCOUNT_ID); + FC_ASSERT(create([this](account_object& a) { + a.name = "son-account"; + a.statistics = create([&](account_statistics_object& s){s.owner = a.id;}).id; + a.owner.weight_threshold = 0; + a.active.weight_threshold = 0; + a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_SON_ACCOUNT; + a.membership_expiration_date = time_point_sec::maximum(); + a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; + a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; + }).get_id() == GRAPHENE_SON_ACCOUNT); // Create more special accounts while( true ) { diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index 935e520e..708d8f57 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -422,14 +422,14 @@ void database::update_active_sons() } // Update SON authority - modify( get(GRAPHENE_SON_ACCOUNT_ID), [&]( account_object& a ) + modify( get(GRAPHENE_SON_ACCOUNT), [&]( account_object& a ) { if( head_block_time() < HARDFORK_533_TIME ) { uint64_t total_votes = 0; map weights; a.active.weight_threshold = 0; - a.active.clear(); + a.active.account_auths.clear(); for( const son_object& son : sons ) { diff --git a/libraries/chain/db_notify.cpp b/libraries/chain/db_notify.cpp index 299cd9d0..98e02a1b 100644 --- a/libraries/chain/db_notify.cpp +++ b/libraries/chain/db_notify.cpp @@ -417,6 +417,10 @@ void get_relevant_accounts( const object* obj, flat_set& accoun assert( aobj != nullptr ); accounts.insert( aobj->son_account ); break; + } case son_wallet_object_type:{ + break; + } case son_wallet_transfer_object_type:{ + break; } case sidechain_address_object_type:{ const auto& aobj = dynamic_cast(obj); assert( aobj != nullptr ); diff --git a/libraries/chain/get_config.cpp b/libraries/chain/get_config.cpp index c961b950..68d0c951 100644 --- a/libraries/chain/get_config.cpp +++ b/libraries/chain/get_config.cpp @@ -108,6 +108,12 @@ fc::variant_object get_config() result[ "GRAPHENE_RELAXED_COMMITTEE_ACCOUNT" ] = fc::variant(GRAPHENE_RELAXED_COMMITTEE_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS); result[ "GRAPHENE_NULL_ACCOUNT" ] = fc::variant(GRAPHENE_NULL_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS); result[ "GRAPHENE_TEMP_ACCOUNT" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS); + result[ "GRAPHENE_PROXY_TO_SELF_ACCOUNT" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS); + result[ "GRAPHENE_RAKE_FEE_ACCOUNT_ID" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS); + result[ "GRAPHENE_SON_ACCOUNT" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS); + result[ "GRAPHENE_NULL_WITNESS" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS); + result[ "GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS); + result[ "GRAPHENE_DEFAULT_RAKE_FEE_PERCENTAGE" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS); return result; } diff --git a/libraries/chain/include/graphene/chain/config.hpp b/libraries/chain/include/graphene/chain/config.hpp index 37b0885d..e44d2fcf 100644 --- a/libraries/chain/include/graphene/chain/config.hpp +++ b/libraries/chain/include/graphene/chain/config.hpp @@ -176,7 +176,7 @@ /// #define GRAPHENE_RAKE_FEE_ACCOUNT_ID (graphene::chain::account_id_type(6)) /// -#define GRAPHENE_SON_ACCOUNT_ID (graphene::chain::account_id_type(7)) +#define GRAPHENE_SON_ACCOUNT (graphene::chain::account_id_type(7)) /// Sentinel value used in the scheduler. #define GRAPHENE_NULL_WITNESS (graphene::chain::witness_id_type(0)) ///@} diff --git a/libraries/chain/son_wallet_evaluator.cpp b/libraries/chain/son_wallet_evaluator.cpp index 55d4645d..045ef45a 100644 --- a/libraries/chain/son_wallet_evaluator.cpp +++ b/libraries/chain/son_wallet_evaluator.cpp @@ -9,7 +9,7 @@ void_result recreate_son_wallet_evaluator::do_evaluate(const son_wallet_recreate { try{ FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); //FC_ASSERT(db().get_global_properties().parameters.get_son_btc_account_id() != GRAPHENE_NULL_ACCOUNT, "SON paying account not set."); - FC_ASSERT( op.payer == db().get_global_properties().parameters.get_son_btc_account_id() ); + FC_ASSERT( op.payer == db().get_global_properties().parameters.get_son_btc_account_id(), "SON paying account must be set as payer." ); const auto& idx = db().get_index_type().indices().get(); auto itr = idx.rbegin(); @@ -55,13 +55,13 @@ void_result update_son_wallet_evaluator::do_evaluate(const son_wallet_update_ope { try{ FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); //FC_ASSERT(db().get_global_properties().parameters.get_son_btc_account_id() != GRAPHENE_NULL_ACCOUNT, "SON paying account not set."); - FC_ASSERT( op.payer == db().get_global_properties().parameters.get_son_btc_account_id() ); + FC_ASSERT( op.payer == db().get_global_properties().parameters.get_son_btc_account_id(), "SON paying account must be set as payer." ); const auto& idx = db().get_index_type().indices().get(); FC_ASSERT( idx.find(op.son_wallet_id) != idx.end() ); - auto itr = idx.find(op.son_wallet_id); - FC_ASSERT( itr->addresses.find(peerplays_sidechain::sidechain_type::bitcoin) == itr->addresses.end() || - itr->addresses.at(peerplays_sidechain::sidechain_type::bitcoin).empty(), "Sidechain wallet address already set"); + //auto itr = idx.find(op.son_wallet_id); + //FC_ASSERT( itr->addresses.find(op.sidechain) == itr->addresses.end() || + // itr->addresses.at(peerplays_sidechain::sidechain_type::bitcoin).empty(), "Sidechain wallet address already set"); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } @@ -69,11 +69,13 @@ object_id_type update_son_wallet_evaluator::do_apply(const son_wallet_update_ope { try { const auto& idx = db().get_index_type().indices().get(); auto itr = idx.find(op.son_wallet_id); - if(itr != idx.end()) + if (itr != idx.end()) { - db().modify(*itr, [&op](son_wallet_object &swo) { - swo.addresses[op.sidechain] = op.address; - }); + if (itr->addresses.find(op.sidechain) == itr->addresses.end()) { + db().modify(*itr, [&op](son_wallet_object &swo) { + swo.addresses[op.sidechain] = op.address; + }); + } } return op.son_wallet_id; } FC_CAPTURE_AND_RETHROW( (op) ) } diff --git a/libraries/chain/son_wallet_transfer_evaluator.cpp b/libraries/chain/son_wallet_transfer_evaluator.cpp index c5e9e5a1..4a20f91b 100644 --- a/libraries/chain/son_wallet_transfer_evaluator.cpp +++ b/libraries/chain/son_wallet_transfer_evaluator.cpp @@ -9,7 +9,7 @@ void_result create_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_t { try{ FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); //FC_ASSERT(db().get_global_properties().parameters.get_son_btc_account_id() != GRAPHENE_NULL_ACCOUNT, "SON paying account not set."); - FC_ASSERT( op.payer == db().get_global_properties().parameters.get_son_btc_account_id() ); + FC_ASSERT( op.payer == db().get_global_properties().parameters.get_son_btc_account_id(), "SON paying account must be set as payer." ); //const auto& idx = db().get_index_type().indices().get(); //FC_ASSERT(idx.find(op.sidechain_uid) == idx.end(), "Already registered " + op.sidechain_uid); @@ -47,7 +47,7 @@ void_result process_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_ { try{ FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); //FC_ASSERT(db().get_global_properties().parameters.get_son_btc_account_id() != GRAPHENE_NULL_ACCOUNT, "SON paying account not set."); - FC_ASSERT( op.payer == db().get_global_properties().parameters.get_son_btc_account_id() ); + FC_ASSERT( op.payer == db().get_global_properties().parameters.get_son_btc_account_id(), "SON paying account must be set as payer." ); const auto& idx = db().get_index_type().indices().get(); const auto& itr = idx.find(op.son_wallet_transfer_id); diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 081d5090..2e8008a5 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -279,7 +279,7 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() chain::signed_transaction trx = d.create_signed_transaction(plugin.get_private_key(son_id), op); fc::future fut = fc::async( [&](){ try { - d.push_transaction(trx); + d.push_transaction(trx, database::validation_steps::skip_block_size_check); if(plugin.app().p2p_node()) plugin.app().p2p_node()->broadcast(net::trx_message(trx)); return true; @@ -336,7 +336,7 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals() chain::signed_transaction trx = d.create_signed_transaction(plugin.get_private_key(son_obj->signing_key), op); fc::future fut = fc::async( [&](){ try { - d.push_transaction(trx); + d.push_transaction(trx, database::validation_steps::skip_block_size_check); if(plugin.app().p2p_node()) plugin.app().p2p_node()->broadcast(net::trx_message(trx)); return true; @@ -357,13 +357,6 @@ void peerplays_sidechain_plugin_impl::recreate_primary_wallet() void peerplays_sidechain_plugin_impl::process_deposits() { - // Account who issues tokens to the user who made deposit - account_id_type pay_from = GRAPHENE_NULL_ACCOUNT; - const auto& account_idx = plugin.database().get_index_type().indices().get(); - const auto& account_itr = account_idx.find("nathan"); - if (account_itr != account_idx.end()) - pay_from = (*account_itr).id; - const auto& idx = plugin.database().get_index_type().indices().get(); const auto& idx_range = idx.equal_range(false); @@ -376,24 +369,26 @@ void peerplays_sidechain_plugin_impl::process_deposits() { p_op.payer = gpo.parameters.get_son_btc_account_id(); p_op.son_wallet_transfer_id = swto.id; - //transfer_operation t_op; - //t_op.from = pay_from; - //t_op.to = swto.peerplays_from; - //t_op.amount = asset(swto.sidechain_amount); // For Bitcoin, the exchange rate is 1:1, for others, get the exchange rate from market + transfer_operation t_op; + t_op.from = gpo.parameters.get_son_btc_account_id();; + t_op.to = swto.peerplays_from; + t_op.amount = asset(swto.sidechain_amount / 1000000); // For Bitcoin, the exchange rate is 1:1, for others, get the exchange rate from market for (son_id_type son_id : plugin.get_sons()) { if (plugin.is_active_son(son_id)) { proposal_create_operation proposal_op; proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; - proposal_op.proposed_ops.push_back( op_wrapper( p_op ) ); - //proposal_op.proposed_ops.push_back( op_wrapper( t_op ) ); + proposal_op.proposed_ops.emplace_back( op_wrapper( p_op ) ); + //proposal_op.proposed_ops.emplace_back( op_wrapper( t_op ) ); uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; proposal_op.expiration_time = time_point_sec( plugin.database().head_block_time().sec_since_epoch() + lifetime ); ilog("sidechain_net_handler: sending proposal for transfer operation ${swto} by ${son}", ("swto", swto.id) ("son", son_id)); signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op); + trx.validate(); + ilog("sidechain_net_handler: transaction validated ${swto} by ${son}", ("swto", swto.id) ("son", son_id)); try { - plugin.database().push_transaction(trx); + plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check); } catch(fc::exception e){ ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}",("e", e.what())); } @@ -444,7 +439,7 @@ void peerplays_sidechain_plugin_impl::on_objects_new(const vector fut = fc::async( [&](){ try { - plugin.database().push_transaction(trx); + plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check); if(plugin.app().p2p_node()) plugin.app().p2p_node()->broadcast(net::trx_message(trx)); return true; @@ -490,6 +485,17 @@ void peerplays_sidechain_plugin_impl::on_objects_new(const vectorproposed_transaction.operations[1].which() == chain::operation::tag::value*/) { approve_proposal( son_id, proposal->id ); } + + if(proposal->proposed_transaction.operations.size() == 1 + && proposal->proposed_transaction.operations[1].which() == chain::operation::tag::value) { + approve_proposal( son_id, proposal->id ); + } + + if(proposal->proposed_transaction.operations.size() == 2 + && proposal->proposed_transaction.operations[0].which() == chain::operation::tag::value + && proposal->proposed_transaction.operations[1].which() == chain::operation::tag::value) { + approve_proposal( son_id, proposal->id ); + } } } } diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp index 16750bf4..90618929 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp @@ -71,14 +71,14 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_ if (plugin.is_active_son(son_id)) { proposal_create_operation proposal_op; proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; - proposal_op.proposed_ops.push_back( op_wrapper( op ) ); + proposal_op.proposed_ops.emplace_back( op_wrapper( op ) ); uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; proposal_op.expiration_time = time_point_sec( database.head_block_time().sec_since_epoch() + lifetime ); ilog("sidechain_net_handler: sending proposal for son wallet transfer create operation by ${son}", ("son", son_id)); signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op); try { - database.push_transaction(trx); + database.push_transaction(trx, database::validation_steps::skip_block_size_check); } catch(fc::exception e){ ilog("sidechain_net_handler: sending proposal for son wallet transfer create operation by ${son} failed with exception ${e}", ("son", son_id) ("e", e.what())); } diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index 0596f9fc..ee7a195a 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -290,13 +290,13 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() { for (son_id_type son_id : plugin.get_sons()) { proposal_create_operation proposal_op; proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; - proposal_op.proposed_ops.push_back( op_wrapper( op ) ); + proposal_op.proposed_ops.emplace_back( op_wrapper( op ) ); uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; proposal_op.expiration_time = time_point_sec( database.head_block_time().sec_since_epoch() + lifetime ); signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(son_id), proposal_op); try { - database.push_transaction(trx); + database.push_transaction(trx, database::validation_steps::skip_block_size_check); } catch(fc::exception e){ ilog("sidechain_net_handler: sending proposal for son wallet update operation failed with exception ${e}",("e", e.what())); } @@ -359,7 +359,7 @@ void sidechain_net_handler_bitcoin::handle_event( const std::string& event_data sed.sidechain_to = v.address; sed.sidechain_amount = v.out.amount; sed.peerplays_from = addr_itr->sidechain_address_account; - sed.peerplays_to = GRAPHENE_SON_ACCOUNT_ID; + sed.peerplays_to = GRAPHENE_SON_ACCOUNT; sidechain_event_data_received(sed); } }