From 342b0917f32bedb58ec73bc2cf132c49a6197215 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Tue, 22 Mar 2022 09:52:06 +0300 Subject: [PATCH 01/15] #328 - fix build error in sidechain_withdraw_transaction_test --- tests/cli/son.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/cli/son.cpp b/tests/cli/son.cpp index 377f8244..5aaf4626 100644 --- a/tests/cli/son.cpp +++ b/tests/cli/son.cpp @@ -805,7 +805,6 @@ BOOST_AUTO_TEST_CASE( sidechain_deposit_transaction_test ) BOOST_TEST_MESSAGE("SON sidechain_deposit_transaction_test cli wallet tests begin"); try { - const sidechain_type type = sidechain_type::bitcoin; son_test_helper sth(*this); std::string son_name("sonaccount1"); @@ -836,7 +835,8 @@ BOOST_AUTO_TEST_CASE( sidechain_deposit_transaction_test ) con.wallet_api_ptr->transfer( "nathan", "sonaccount" + fc::to_pretty_string(i), "1000", "1.3.0", "Here are some CORE tokens for your new account", true ); con.wallet_api_ptr->create_vesting_balance("sonaccount" + fc::to_pretty_string(i), "500", "1.3.0", vesting_balance_type::gpos, true); - con.wallet_api_ptr->vote_for_son("sonaccount" + fc::to_pretty_string(i), son_name, type, true, true); + con.wallet_api_ptr->vote_for_son("sonaccount" + fc::to_pretty_string(i), son_name, sidechain_type::bitcoin, true, true); + con.wallet_api_ptr->vote_for_son("sonaccount" + fc::to_pretty_string(i), son_name, sidechain_type::hive, true, true); } BOOST_CHECK(generate_maintenance_block()); @@ -900,7 +900,8 @@ BOOST_AUTO_TEST_CASE( sidechain_withdraw_transaction_test ) con.wallet_api_ptr->transfer( "nathan", "sonaccount" + fc::to_pretty_string(i), "1000", "1.3.0", "Here are some CORE tokens for your new account", true ); con.wallet_api_ptr->create_vesting_balance("sonaccount" + fc::to_pretty_string(i), "500", "1.3.0", vesting_balance_type::gpos, true); - con.wallet_api_ptr->vote_for_son("sonaccount" + fc::to_pretty_string(i), name, true, true); + con.wallet_api_ptr->vote_for_son("sonaccount" + fc::to_pretty_string(i), name, sidechain_type::bitcoin, true, true); + con.wallet_api_ptr->vote_for_son("sonaccount" + fc::to_pretty_string(i), name, sidechain_type::hive, true, true); } BOOST_CHECK(generate_maintenance_block()); -- 2.45.2 From 97cdf1b6f00182c710715bd5c359663fd0b795d2 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Tue, 22 Mar 2022 12:12:01 +0300 Subject: [PATCH 02/15] #328 - Add additional checks for "create_sons" test --- tests/cli/son.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/cli/son.cpp b/tests/cli/son.cpp index 5aaf4626..5a1dad62 100644 --- a/tests/cli/son.cpp +++ b/tests/cli/son.cpp @@ -138,10 +138,18 @@ BOOST_AUTO_TEST_CASE( create_sons ) auto son1_obj = con.wallet_api_ptr->get_son("son1account"); BOOST_CHECK(son1_obj.son_account == con.wallet_api_ptr->get_account_id("son1account")); BOOST_CHECK_EQUAL(son1_obj.url, "http://son1"); + BOOST_CHECK_EQUAL(son1_obj.sidechain_public_keys[sidechain_type::bitcoin], "bitcoin_address 1"); + BOOST_CHECK_EQUAL(son1_obj.sidechain_public_keys[sidechain_type::hive], "hive account 1"); + BOOST_CHECK_EQUAL(son1_obj.get_sidechain_vote_id(sidechain_type::bitcoin).instance(), 22); + BOOST_CHECK_EQUAL(son1_obj.get_sidechain_vote_id(sidechain_type::hive).instance(), 23); auto son2_obj = con.wallet_api_ptr->get_son("son2account"); BOOST_CHECK(son2_obj.son_account == con.wallet_api_ptr->get_account_id("son2account")); BOOST_CHECK_EQUAL(son2_obj.url, "http://son2"); + BOOST_CHECK_EQUAL(son2_obj.sidechain_public_keys[sidechain_type::bitcoin], "bitcoin_address 2"); + BOOST_CHECK_EQUAL(son2_obj.sidechain_public_keys[sidechain_type::hive], "hive account 2"); + BOOST_CHECK_EQUAL(son2_obj.get_sidechain_vote_id(sidechain_type::bitcoin).instance(), 24); + BOOST_CHECK_EQUAL(son2_obj.get_sidechain_vote_id(sidechain_type::hive).instance(), 25); } catch( fc::exception& e ) { BOOST_TEST_MESSAGE("SON cli wallet tests exception"); -- 2.45.2 From 5c5116f3fc608c545ba6585d71f1fa2a112a9b7f Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Tue, 22 Mar 2022 13:58:37 +0300 Subject: [PATCH 03/15] #328 - update "cli_update_son" test --- tests/cli/son.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/cli/son.cpp b/tests/cli/son.cpp index 5a1dad62..928d3a07 100644 --- a/tests/cli/son.cpp +++ b/tests/cli/son.cpp @@ -180,6 +180,10 @@ BOOST_AUTO_TEST_CASE( cli_update_son ) auto son_data = con.wallet_api_ptr->get_son("sonmember"); BOOST_CHECK(son_data.url == "http://sonmember"); BOOST_CHECK(son_data.son_account == sonmember_acct.get_id()); + BOOST_CHECK_EQUAL(son_data.sidechain_public_keys[sidechain_type::bitcoin], "bitcoin_address 1"); + BOOST_CHECK_EQUAL(son_data.sidechain_public_keys[sidechain_type::hive], "hive account 1"); + BOOST_CHECK_EQUAL(son_data.get_sidechain_vote_id(sidechain_type::bitcoin).instance(), 22); + BOOST_CHECK_EQUAL(son_data.get_sidechain_vote_id(sidechain_type::hive).instance(), 23); // update SON sidechain_public_keys.clear(); @@ -189,6 +193,8 @@ BOOST_AUTO_TEST_CASE( cli_update_son ) con.wallet_api_ptr->update_son("sonmember", "http://sonmember_updated", "", sidechain_public_keys, true); son_data = con.wallet_api_ptr->get_son("sonmember"); BOOST_CHECK(son_data.url == "http://sonmember_updated"); + BOOST_CHECK_EQUAL(son_data.sidechain_public_keys[sidechain_type::bitcoin], "bitcoin_address 2"); + BOOST_CHECK_EQUAL(son_data.sidechain_public_keys[sidechain_type::hive], "hive account 2"); // update SON signing key sidechain_public_keys.clear(); -- 2.45.2 From eec19a350b1138497feabac48c70396fabf3561d Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Wed, 23 Mar 2022 08:59:22 +0300 Subject: [PATCH 04/15] #328 - total_votes as map of sidechain_type --- libraries/chain/db_maint.cpp | 11 ++--- .../include/graphene/chain/son_object.hpp | 2 +- tests/cli/son.cpp | 44 ++++++++++--------- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index f5f52c8c..02afb7e2 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -716,11 +716,12 @@ void database::update_active_sons() }); } modify( son, [local_vote_buffer_ref]( son_object& obj ){ - //! FIXME - only bitcoin_vote_id ??? - obj.total_votes = local_vote_buffer_ref[obj.get_bitcoin_vote_id()]; - if(obj.status == son_status::request_maintenance) - obj.status = son_status::in_maintenance; - }); + for(const auto& sidechain_vote_id : obj.sidechain_vote_ids ){ + obj.total_votes[sidechain_vote_id.first] = local_vote_buffer_ref[sidechain_vote_id.second]; + } + if(obj.status == son_status::request_maintenance) + obj.status = son_status::in_maintenance; + }); } // Update SON authority diff --git a/libraries/chain/include/graphene/chain/son_object.hpp b/libraries/chain/include/graphene/chain/son_object.hpp index 65ef0a2a..b1274f06 100644 --- a/libraries/chain/include/graphene/chain/son_object.hpp +++ b/libraries/chain/include/graphene/chain/son_object.hpp @@ -65,7 +65,7 @@ namespace graphene { namespace chain { account_id_type son_account; flat_map sidechain_vote_ids; - uint64_t total_votes = 0; + flat_map total_votes; string url; vesting_balance_id_type deposit; public_key_type signing_key; diff --git a/tests/cli/son.cpp b/tests/cli/son.cpp index 928d3a07..87fbf2ad 100644 --- a/tests/cli/son.cpp +++ b/tests/cli/son.cpp @@ -235,8 +235,8 @@ BOOST_AUTO_TEST_CASE( son_voting ) son_object son2_obj; signed_transaction vote_son1_tx; signed_transaction vote_son2_tx; - uint64_t son1_start_votes, son1_end_votes; - uint64_t son2_start_votes, son2_end_votes; + flat_map son1_start_votes, son1_end_votes; + flat_map son2_start_votes, son2_end_votes; son1_obj = con.wallet_api_ptr->get_son("son1account"); son1_start_votes = son1_obj.total_votes; @@ -253,7 +253,8 @@ BOOST_AUTO_TEST_CASE( son_voting ) // Verify that the vote is there son1_obj = con.wallet_api_ptr->get_son("son1account"); son1_end_votes = son1_obj.total_votes; - BOOST_CHECK(son1_end_votes > son1_start_votes); + BOOST_CHECK(son1_end_votes[sidechain_type::bitcoin] > son1_start_votes[sidechain_type::bitcoin]); + BOOST_CHECK(son1_end_votes[sidechain_type::hive] > son1_start_votes[sidechain_type::hive]); // Vote for a son2account BOOST_TEST_MESSAGE("Voting for son2account"); @@ -264,7 +265,8 @@ BOOST_AUTO_TEST_CASE( son_voting ) // Verify that the vote is there son2_obj = con.wallet_api_ptr->get_son("son2account"); son2_end_votes = son2_obj.total_votes; - BOOST_CHECK(son2_end_votes > son2_start_votes); + BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] > son2_start_votes[sidechain_type::bitcoin]); + BOOST_CHECK(son2_end_votes[sidechain_type::hive] > son2_start_votes[sidechain_type::hive]); //! Get nathan account const auto nathan_account_object = con.wallet_api_ptr->get_account("nathan"); @@ -304,7 +306,8 @@ BOOST_AUTO_TEST_CASE( son_voting ) // Verify that the vote is removed son1_obj = con.wallet_api_ptr->get_son("son1account"); son1_end_votes = son1_obj.total_votes; - BOOST_CHECK(son1_end_votes == son1_start_votes); + BOOST_CHECK(son1_end_votes[sidechain_type::bitcoin] == son1_start_votes[sidechain_type::bitcoin]); + BOOST_CHECK(son1_end_votes[sidechain_type::hive] == son1_start_votes[sidechain_type::hive]); //! Check son1account voters voters_for_son1account = con.wallet_api_ptr->get_voters("son1account"); @@ -329,7 +332,8 @@ BOOST_AUTO_TEST_CASE( son_voting ) // Verify that the vote is removed son2_obj = con.wallet_api_ptr->get_son("son2account"); son2_end_votes = son2_obj.total_votes; - BOOST_CHECK(son2_end_votes == son2_start_votes); + BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] == son2_start_votes[sidechain_type::bitcoin]); + BOOST_CHECK(son2_end_votes[sidechain_type::hive] == son2_start_votes[sidechain_type::hive]); //! Check son2account voters voters_for_son2account = con.wallet_api_ptr->get_voters("son2account"); @@ -495,8 +499,8 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) son_object son1_obj; son_object son2_obj; - uint64_t son1_start_votes, son1_end_votes; - uint64_t son2_start_votes, son2_end_votes; + flat_map son1_start_votes, son1_end_votes; + flat_map son2_start_votes, son2_end_votes; // Get votes at start son1_obj = con.wallet_api_ptr->get_son("son1account"); @@ -522,11 +526,11 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) // Verify the votes son1_obj = con.wallet_api_ptr->get_son("son1account"); son1_end_votes = son1_obj.total_votes; - BOOST_CHECK(son1_end_votes > son1_start_votes); + BOOST_CHECK(son1_end_votes[sidechain_type::bitcoin] > son1_start_votes[sidechain_type::bitcoin]); son1_start_votes = son1_end_votes; son2_obj = con.wallet_api_ptr->get_son("son2account"); son2_end_votes = son2_obj.total_votes; - BOOST_CHECK(son2_end_votes > son2_start_votes); + BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] > son2_start_votes[sidechain_type::bitcoin]); son2_start_votes = son2_end_votes; @@ -542,12 +546,12 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) // Verify the votes son1_obj = con.wallet_api_ptr->get_son("son1account"); son1_end_votes = son1_obj.total_votes; - BOOST_CHECK(son1_end_votes < son1_start_votes); + BOOST_CHECK(son1_end_votes[sidechain_type::bitcoin] < son1_start_votes[sidechain_type::bitcoin]); son1_start_votes = son1_end_votes; son2_obj = con.wallet_api_ptr->get_son("son2account"); // voice distribution changed, SON2 now has all voices son2_end_votes = son2_obj.total_votes; - BOOST_CHECK((son2_end_votes > son2_start_votes)); // nathan spent funds for vb, it has different voting power + BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] > son2_start_votes[sidechain_type::bitcoin]); // nathan spent funds for vb, it has different voting power son2_start_votes = son2_end_votes; // Try to reject incorrect SON @@ -561,11 +565,11 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) // Verify the votes son1_obj = con.wallet_api_ptr->get_son("son1account"); son1_end_votes = son1_obj.total_votes; - BOOST_CHECK(son1_end_votes == son1_start_votes); + BOOST_CHECK(son1_end_votes[sidechain_type::bitcoin] == son1_start_votes[sidechain_type::bitcoin]); son1_start_votes = son1_end_votes; son2_obj = con.wallet_api_ptr->get_son("son2account"); son2_end_votes = son2_obj.total_votes; - BOOST_CHECK(son2_end_votes == son2_start_votes); + BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] == son2_start_votes[sidechain_type::bitcoin]); son2_start_votes = son2_end_votes; // Reject SON2 @@ -579,11 +583,11 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) // Verify the votes son1_obj = con.wallet_api_ptr->get_son("son1account"); son1_end_votes = son1_obj.total_votes; - BOOST_CHECK(son1_end_votes == son1_start_votes); + BOOST_CHECK(son1_end_votes[sidechain_type::bitcoin] == son1_start_votes[sidechain_type::bitcoin]); son1_start_votes = son1_end_votes; son2_obj = con.wallet_api_ptr->get_son("son2account"); son2_end_votes = son2_obj.total_votes; - BOOST_CHECK(son2_end_votes < son2_start_votes); + BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] < son2_start_votes[sidechain_type::bitcoin]); son2_start_votes = son2_end_votes; // Try to accept and reject the same SON @@ -598,11 +602,11 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) // Verify the votes son1_obj = con.wallet_api_ptr->get_son("son1account"); son1_end_votes = son1_obj.total_votes; - BOOST_CHECK(son1_end_votes == son1_start_votes); + BOOST_CHECK(son1_end_votes[sidechain_type::bitcoin] == son1_start_votes[sidechain_type::bitcoin]); son1_start_votes = son1_end_votes; son2_obj = con.wallet_api_ptr->get_son("son2account"); son2_end_votes = son2_obj.total_votes; - BOOST_CHECK(son2_end_votes == son2_start_votes); + BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] == son2_start_votes[sidechain_type::bitcoin]); son2_start_votes = son2_end_votes; // Try to accept and reject empty lists @@ -615,11 +619,11 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) // Verify the votes son1_obj = con.wallet_api_ptr->get_son("son1account"); son1_end_votes = son1_obj.total_votes; - BOOST_CHECK(son1_end_votes == son1_start_votes); + BOOST_CHECK(son1_end_votes[sidechain_type::bitcoin] == son1_start_votes[sidechain_type::bitcoin]); son1_start_votes = son1_end_votes; son2_obj = con.wallet_api_ptr->get_son("son2account"); son2_end_votes = son2_obj.total_votes; - BOOST_CHECK(son2_end_votes == son2_start_votes); + BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] == son2_start_votes[sidechain_type::bitcoin]); son2_start_votes = son2_end_votes; } catch( fc::exception& e ) { -- 2.45.2 From 9c73357d9717d15ce3505f1f4731e92322cd2a4b Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Thu, 24 Mar 2022 08:27:51 +0300 Subject: [PATCH 05/15] =?UTF-8?q?=E2=84=96328=20-=20Fix=20needed=5Fsons=20?= =?UTF-8?q?in=20account=5Foptions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libraries/chain/db_maint.cpp | 24 ++++++++++--------- .../graphene/chain/protocol/account.hpp | 3 ++- libraries/chain/protocol/account.cpp | 15 ++++++------ libraries/wallet/wallet.cpp | 2 +- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index 02afb7e2..66647569 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -2236,17 +2236,19 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g // same rationale as for witnesses d._committee_count_histogram_buffer[offset] += voting_stake; } - if( opinion_account.options.num_son <= props.parameters.maximum_son_count() ) - { - uint16_t offset = std::min(size_t(opinion_account.options.num_son/2), - d._son_count_histogram_buffer.size() - 1); - // votes for a number greater than maximum_son_count - // are turned into votes for maximum_son_count. - // - // in particular, this takes care of the case where a - // member was voting for a high number, then the - // parameter was lowered. - d._son_count_histogram_buffer[offset] += voting_stake; + for(const auto& num_sidechain_son : opinion_account.options.num_son) { + const auto& num_son = num_sidechain_son.second; + if (num_son <= props.parameters.maximum_son_count()) { + uint16_t offset = std::min(size_t(num_son / 2), + d._son_count_histogram_buffer.size() - 1); + // votes for a number greater than maximum_son_count + // are turned into votes for maximum_son_count. + // + // in particular, this takes care of the case where a + // member was voting for a high number, then the + // parameter was lowered. + d._son_count_histogram_buffer[offset] += voting_stake; + } } d._total_voting_stake += voting_stake; diff --git a/libraries/chain/include/graphene/chain/protocol/account.hpp b/libraries/chain/include/graphene/chain/protocol/account.hpp index 50ccb8ae..cbd39770 100644 --- a/libraries/chain/include/graphene/chain/protocol/account.hpp +++ b/libraries/chain/include/graphene/chain/protocol/account.hpp @@ -28,6 +28,7 @@ #include #include #include +#include namespace graphene { namespace chain { @@ -54,7 +55,7 @@ namespace graphene { namespace chain { uint16_t num_committee = 0; /// The number of active son members this account votes the blockchain should appoint /// Must not exceed the actual number of son members voted for in @ref votes - uint16_t num_son = 0; + flat_map num_son; /// This is the list of vote IDs this account votes for. The weight of these votes is determined by this /// account's balance of core asset. flat_set votes; diff --git a/libraries/chain/protocol/account.cpp b/libraries/chain/protocol/account.cpp index 435dfa57..178c447a 100644 --- a/libraries/chain/protocol/account.cpp +++ b/libraries/chain/protocol/account.cpp @@ -174,26 +174,25 @@ void account_options::validate() const { auto needed_witnesses = num_witness; auto needed_committee = num_committee; - auto needed_sons_bitcoin = num_son; - auto needed_sons_hive = num_son; + auto needed_sons = num_son; for( vote_id_type id : votes ) if( id.type() == vote_id_type::witness && needed_witnesses ) --needed_witnesses; else if ( id.type() == vote_id_type::committee && needed_committee ) --needed_committee; - else if ( id.type() == vote_id_type::son_bitcoin && needed_sons_bitcoin ) - --needed_sons_bitcoin; - else if ( id.type() == vote_id_type::son_hive && needed_sons_hive ) - --needed_sons_hive; + else if ( id.type() == vote_id_type::son_bitcoin && needed_sons[sidechain_type::bitcoin] ) + --needed_sons[sidechain_type::bitcoin]; + else if ( id.type() == vote_id_type::son_hive && needed_sons[sidechain_type::hive] ) + --needed_sons[sidechain_type::hive]; FC_ASSERT( needed_witnesses == 0, "May not specify fewer witnesses than the number voted for."); FC_ASSERT( needed_committee == 0, "May not specify fewer committee members than the number voted for."); - FC_ASSERT( needed_sons_bitcoin == 0, + FC_ASSERT( needed_sons[sidechain_type::bitcoin] == 0, "May not specify fewer Bitcoin SONs than the number voted for."); - FC_ASSERT( needed_sons_hive == 0, + FC_ASSERT( needed_sons[sidechain_type::hive] == 0, "May not specify fewer Hive SONs than the number voted for."); } diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 19719ff0..6d7af8d1 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -2878,7 +2878,7 @@ public: if (!votes_removed) FC_THROW("Account ${account} is already not voting for SON ${son}", ("account", voting_account)("son", son)); } - voting_account_object.options.num_son = desired_number_of_sons; + voting_account_object.options.num_son[sidechain] = desired_number_of_sons; account_update_operation account_update_op; account_update_op.account = voting_account_object.id; -- 2.45.2 From 645fb32fc54b5ef8a44d705c2d7a11106cb798a7 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Thu, 24 Mar 2022 12:39:02 +0300 Subject: [PATCH 06/15] #328 - Fix SON tests --- tests/cli/son.cpp | 180 +++++++++++++++++++++++++++++++++------------- 1 file changed, 131 insertions(+), 49 deletions(-) diff --git a/tests/cli/son.cpp b/tests/cli/son.cpp index 87fbf2ad..8e448143 100644 --- a/tests/cli/son.cpp +++ b/tests/cli/son.cpp @@ -238,6 +238,9 @@ BOOST_AUTO_TEST_CASE( son_voting ) flat_map son1_start_votes, son1_end_votes; flat_map son2_start_votes, son2_end_votes; + //! Get nathan account + const auto nathan_account_object = con.wallet_api_ptr->get_account("nathan"); + son1_obj = con.wallet_api_ptr->get_son("son1account"); son1_start_votes = son1_obj.total_votes; son2_obj = con.wallet_api_ptr->get_son("son2account"); @@ -268,34 +271,31 @@ BOOST_AUTO_TEST_CASE( son_voting ) BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] > son2_start_votes[sidechain_type::bitcoin]); BOOST_CHECK(son2_end_votes[sidechain_type::hive] > son2_start_votes[sidechain_type::hive]); - //! Get nathan account - const auto nathan_account_object = con.wallet_api_ptr->get_account("nathan"); - //! Check son1account voters - auto voters_for_son1account = con.wallet_api_ptr->get_voters("son1account"); - BOOST_REQUIRE(voters_for_son1account.voters_for_son); - BOOST_CHECK_EQUAL(voters_for_son1account.voters_for_son->at(sidechain_type::bitcoin).voters.size(), 1); - BOOST_CHECK_EQUAL((uint32_t)voters_for_son1account.voters_for_son->at(sidechain_type::bitcoin).voters[0].instance, nathan_account_object.id.instance()); - BOOST_CHECK_EQUAL(voters_for_son1account.voters_for_son->at(sidechain_type::hive).voters.size(), 1); - BOOST_CHECK_EQUAL((uint32_t)voters_for_son1account.voters_for_son->at(sidechain_type::hive).voters[0].instance, nathan_account_object.id.instance()); + auto voters_for_son1account = con.wallet_api_ptr->get_voters("son1account").voters_for_son; + BOOST_REQUIRE(voters_for_son1account); + BOOST_REQUIRE_EQUAL(voters_for_son1account->at(sidechain_type::bitcoin).voters.size(), 1); + BOOST_CHECK_EQUAL((uint32_t)voters_for_son1account->at(sidechain_type::bitcoin).voters[0].instance, nathan_account_object.id.instance()); + BOOST_REQUIRE_EQUAL(voters_for_son1account->at(sidechain_type::hive).voters.size(), 1); + BOOST_CHECK_EQUAL((uint32_t)voters_for_son1account->at(sidechain_type::hive).voters[0].instance, nathan_account_object.id.instance()); //! Check son2account voters - auto voters_for_son2account = con.wallet_api_ptr->get_voters("son2account"); - BOOST_REQUIRE(voters_for_son2account.voters_for_son); - BOOST_CHECK_EQUAL(voters_for_son2account.voters_for_son->at(sidechain_type::bitcoin).voters.size(), 1); - BOOST_CHECK_EQUAL((uint32_t)voters_for_son2account.voters_for_son->at(sidechain_type::bitcoin).voters[0].instance, nathan_account_object.id.instance()); - BOOST_CHECK_EQUAL(voters_for_son2account.voters_for_son->at(sidechain_type::hive).voters.size(), 1); - BOOST_CHECK_EQUAL((uint32_t)voters_for_son2account.voters_for_son->at(sidechain_type::hive).voters[0].instance, nathan_account_object.id.instance()); + auto voters_for_son2account = con.wallet_api_ptr->get_voters("son2account").voters_for_son; + BOOST_REQUIRE(voters_for_son2account); + BOOST_REQUIRE_EQUAL(voters_for_son2account->at(sidechain_type::bitcoin).voters.size(), 1); + BOOST_CHECK_EQUAL((uint32_t)voters_for_son2account->at(sidechain_type::bitcoin).voters[0].instance, nathan_account_object.id.instance()); + BOOST_REQUIRE_EQUAL(voters_for_son2account->at(sidechain_type::hive).voters.size(), 1); + BOOST_CHECK_EQUAL((uint32_t)voters_for_son2account->at(sidechain_type::hive).voters[0].instance, nathan_account_object.id.instance()); //! Check votes of nathan - auto nathan_votes = con.wallet_api_ptr->get_votes("nathan"); - BOOST_REQUIRE(nathan_votes.votes_for_sons); - BOOST_CHECK_EQUAL(nathan_votes.votes_for_sons->at(sidechain_type::bitcoin).size(), 2); - BOOST_CHECK_EQUAL(nathan_votes.votes_for_sons->at(sidechain_type::bitcoin).at(0).id.instance(), son1_obj.id.instance()); - BOOST_CHECK_EQUAL(nathan_votes.votes_for_sons->at(sidechain_type::bitcoin).at(1).id.instance(), son2_obj.id.instance()); - BOOST_CHECK_EQUAL(nathan_votes.votes_for_sons->at(sidechain_type::hive).size(), 2); - BOOST_CHECK_EQUAL(nathan_votes.votes_for_sons->at(sidechain_type::hive).at(0).id.instance(), son1_obj.id.instance()); - BOOST_CHECK_EQUAL(nathan_votes.votes_for_sons->at(sidechain_type::hive).at(1).id.instance(), son2_obj.id.instance()); + auto nathan_votes_for_son = con.wallet_api_ptr->get_votes("nathan").votes_for_sons; + BOOST_REQUIRE(nathan_votes_for_son); + BOOST_REQUIRE_EQUAL(nathan_votes_for_son->at(sidechain_type::bitcoin).size(), 2); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::bitcoin).at(0).id.instance(), son1_obj.id.instance()); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::bitcoin).at(1).id.instance(), son2_obj.id.instance()); + BOOST_REQUIRE_EQUAL(nathan_votes_for_son->at(sidechain_type::hive).size(), 2); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::hive).at(0).id.instance(), son1_obj.id.instance()); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::hive).at(1).id.instance(), son2_obj.id.instance()); // Withdraw vote for a son1account BOOST_TEST_MESSAGE("Withdraw vote for a son1account"); @@ -310,18 +310,18 @@ BOOST_AUTO_TEST_CASE( son_voting ) BOOST_CHECK(son1_end_votes[sidechain_type::hive] == son1_start_votes[sidechain_type::hive]); //! Check son1account voters - voters_for_son1account = con.wallet_api_ptr->get_voters("son1account"); - BOOST_REQUIRE(voters_for_son1account.voters_for_son); - BOOST_CHECK_EQUAL(voters_for_son1account.voters_for_son->at(sidechain_type::bitcoin).voters.size(), 0); - BOOST_CHECK_EQUAL(voters_for_son1account.voters_for_son->at(sidechain_type::hive).voters.size(), 0); + voters_for_son1account = con.wallet_api_ptr->get_voters("son1account").voters_for_son; + BOOST_REQUIRE(voters_for_son1account); + BOOST_CHECK_EQUAL(voters_for_son1account->at(sidechain_type::bitcoin).voters.size(), 0); + BOOST_CHECK_EQUAL(voters_for_son1account->at(sidechain_type::hive).voters.size(), 0); //! Check votes of nathan - nathan_votes = con.wallet_api_ptr->get_votes("nathan"); - BOOST_REQUIRE(nathan_votes.votes_for_sons); - BOOST_CHECK_EQUAL(nathan_votes.votes_for_sons->at(sidechain_type::bitcoin).size(), 1); - BOOST_CHECK_EQUAL(nathan_votes.votes_for_sons->at(sidechain_type::bitcoin).at(0).id.instance(), son2_obj.id.instance()); - BOOST_CHECK_EQUAL(nathan_votes.votes_for_sons->at(sidechain_type::hive).size(), 1); - BOOST_CHECK_EQUAL(nathan_votes.votes_for_sons->at(sidechain_type::hive).at(0).id.instance(), son2_obj.id.instance()); + nathan_votes_for_son = con.wallet_api_ptr->get_votes("nathan").votes_for_sons; + BOOST_REQUIRE(nathan_votes_for_son); + BOOST_REQUIRE_EQUAL(nathan_votes_for_son->at(sidechain_type::bitcoin).size(), 1); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::bitcoin).at(0).id.instance(), son2_obj.id.instance()); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::hive).size(), 1); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::hive).at(0).id.instance(), son2_obj.id.instance()); // Withdraw vote for a son2account BOOST_TEST_MESSAGE("Withdraw vote for a son2account"); @@ -336,14 +336,14 @@ BOOST_AUTO_TEST_CASE( son_voting ) BOOST_CHECK(son2_end_votes[sidechain_type::hive] == son2_start_votes[sidechain_type::hive]); //! Check son2account voters - voters_for_son2account = con.wallet_api_ptr->get_voters("son2account"); - BOOST_REQUIRE(voters_for_son2account.voters_for_son); - BOOST_CHECK_EQUAL(voters_for_son2account.voters_for_son->at(sidechain_type::bitcoin).voters.size(), 0); - BOOST_CHECK_EQUAL(voters_for_son2account.voters_for_son->at(sidechain_type::hive).voters.size(), 0); + voters_for_son2account = con.wallet_api_ptr->get_voters("son2account").voters_for_son; + BOOST_REQUIRE(voters_for_son2account); + BOOST_CHECK_EQUAL(voters_for_son2account->at(sidechain_type::bitcoin).voters.size(), 0); + BOOST_CHECK_EQUAL(voters_for_son2account->at(sidechain_type::hive).voters.size(), 0); //! Check votes of nathan - nathan_votes = con.wallet_api_ptr->get_votes("nathan"); - BOOST_CHECK(!nathan_votes.votes_for_sons.valid()); + nathan_votes_for_son = con.wallet_api_ptr->get_votes("nathan").votes_for_sons; + BOOST_CHECK(!nathan_votes_for_son); } catch( fc::exception& e ) { BOOST_TEST_MESSAGE("SON cli wallet tests exception"); @@ -358,7 +358,6 @@ BOOST_FIXTURE_TEST_CASE( select_top_fifteen_sons, cli_fixture ) BOOST_TEST_MESSAGE("SON cli wallet tests begin"); try { - const sidechain_type type = sidechain_type::bitcoin; son_test_helper sth(*this); graphene::wallet::brain_key_info bki; @@ -396,7 +395,8 @@ BOOST_FIXTURE_TEST_CASE( select_top_fifteen_sons, cli_fixture ) con.wallet_api_ptr->create_vesting_balance("sonaccount" + fc::to_pretty_string(i), "500", "1.3.0", vesting_balance_type::gpos, true); std::string name = "sonaccount" + fc::to_pretty_string(i); - vote_tx = con.wallet_api_ptr->vote_for_son(name, name, type, true, true); + vote_tx = con.wallet_api_ptr->vote_for_son(name, name, sidechain_type::bitcoin, true, true); + vote_tx = con.wallet_api_ptr->vote_for_son(name, name, sidechain_type::hive, true, true); } BOOST_CHECK(generate_maintenance_block()); @@ -404,7 +404,8 @@ BOOST_FIXTURE_TEST_CASE( select_top_fifteen_sons, cli_fixture ) { std::string name1 = "sonaccount" + fc::to_pretty_string(i); std::string name2 = "sonaccount" + fc::to_pretty_string(i + 1); - vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, type, true, true); + vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, sidechain_type::bitcoin, true, true); + vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, sidechain_type::hive, true, true); } gpo = con.wallet_api_ptr->get_global_properties(); BOOST_TEST_MESSAGE("gpo: " << gpo.active_sons.size()); @@ -416,7 +417,8 @@ BOOST_FIXTURE_TEST_CASE( select_top_fifteen_sons, cli_fixture ) { std::string name1 = "sonaccount" + fc::to_pretty_string(i + 2); std::string name2 = "sonaccount" + fc::to_pretty_string(i); - vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, type, true, true); + vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, sidechain_type::bitcoin, true, true); + vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, sidechain_type::hive, true, true); } gpo = con.wallet_api_ptr->get_global_properties(); BOOST_TEST_MESSAGE("gpo: " << gpo.active_sons.size()); @@ -428,7 +430,8 @@ BOOST_FIXTURE_TEST_CASE( select_top_fifteen_sons, cli_fixture ) { std::string name1 = "sonaccount" + fc::to_pretty_string(i + 3); std::string name2 = "sonaccount" + fc::to_pretty_string(i); - vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, type, true, true); + vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, sidechain_type::bitcoin, true, true); + vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, sidechain_type::hive, true, true); } gpo = con.wallet_api_ptr->get_global_properties(); BOOST_TEST_MESSAGE("gpo: " << gpo.active_sons.size()); @@ -502,6 +505,9 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) flat_map son1_start_votes, son1_end_votes; flat_map son2_start_votes, son2_end_votes; + //! Get nathan account + const auto nathan_account_object = con.wallet_api_ptr->get_account("nathan"); + // Get votes at start son1_obj = con.wallet_api_ptr->get_son("son1account"); son1_start_votes = son1_obj.total_votes; @@ -520,6 +526,8 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) con.wallet_api_ptr->create_vesting_balance("nathan", "1000", "1.3.0", vesting_balance_type::gpos, true); update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, sidechain_type::bitcoin, 2, true); + update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, + sidechain_type::hive, 2, true); generate_block(); BOOST_CHECK(generate_maintenance_block()); @@ -533,6 +541,31 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] > son2_start_votes[sidechain_type::bitcoin]); son2_start_votes = son2_end_votes; + //! Check son1account voters + auto voters_for_son1account = con.wallet_api_ptr->get_voters("son1account").voters_for_son; + BOOST_REQUIRE(voters_for_son1account); + BOOST_REQUIRE_EQUAL(voters_for_son1account->at(sidechain_type::bitcoin).voters.size(), 1); + BOOST_CHECK_EQUAL((uint32_t)voters_for_son1account->at(sidechain_type::bitcoin).voters[0].instance, nathan_account_object.id.instance()); + BOOST_REQUIRE_EQUAL(voters_for_son1account->at(sidechain_type::hive).voters.size(), 1); + BOOST_CHECK_EQUAL((uint32_t)voters_for_son1account->at(sidechain_type::hive).voters[0].instance, nathan_account_object.id.instance()); + + //! Check son2account voters + auto voters_for_son2account = con.wallet_api_ptr->get_voters("son2account").voters_for_son; + BOOST_REQUIRE(voters_for_son2account); + BOOST_REQUIRE_EQUAL(voters_for_son2account->at(sidechain_type::bitcoin).voters.size(), 1); + BOOST_CHECK_EQUAL((uint32_t)voters_for_son2account->at(sidechain_type::bitcoin).voters[0].instance, nathan_account_object.id.instance()); + BOOST_REQUIRE_EQUAL(voters_for_son2account->at(sidechain_type::hive).voters.size(), 1); + BOOST_CHECK_EQUAL((uint32_t)voters_for_son2account->at(sidechain_type::hive).voters[0].instance, nathan_account_object.id.instance()); + + //! Check votes of nathan + auto nathan_votes_for_son = con.wallet_api_ptr->get_votes("nathan").votes_for_sons; + BOOST_REQUIRE(nathan_votes_for_son); + BOOST_REQUIRE_EQUAL(nathan_votes_for_son->at(sidechain_type::bitcoin).size(), 2); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::bitcoin).at(0).id.instance(), son1_obj.id.instance()); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::bitcoin).at(1).id.instance(), son2_obj.id.instance()); + BOOST_REQUIRE_EQUAL(nathan_votes_for_son->at(sidechain_type::hive).size(), 2); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::hive).at(0).id.instance(), son1_obj.id.instance()); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::hive).at(1).id.instance(), son2_obj.id.instance()); // Withdraw vote for SON 1 accepted.clear(); @@ -541,6 +574,8 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) con.wallet_api_ptr->create_vesting_balance("nathan", "1000", "1.3.0", vesting_balance_type::gpos, true); update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, sidechain_type::bitcoin, 1, true); + update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, + sidechain_type::hive, 1, true); BOOST_CHECK(generate_maintenance_block()); // Verify the votes @@ -554,12 +589,28 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] > son2_start_votes[sidechain_type::bitcoin]); // nathan spent funds for vb, it has different voting power son2_start_votes = son2_end_votes; + //! Check son1account voters + voters_for_son1account = con.wallet_api_ptr->get_voters("son1account").voters_for_son; + BOOST_REQUIRE(voters_for_son1account); + BOOST_CHECK_EQUAL(voters_for_son1account->at(sidechain_type::bitcoin).voters.size(), 0); + BOOST_CHECK_EQUAL(voters_for_son1account->at(sidechain_type::hive).voters.size(), 0); + + //! Check votes of nathan + nathan_votes_for_son = con.wallet_api_ptr->get_votes("nathan").votes_for_sons; + BOOST_REQUIRE(nathan_votes_for_son); + BOOST_REQUIRE_EQUAL(nathan_votes_for_son->at(sidechain_type::bitcoin).size(), 1); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::bitcoin).at(0).id.instance(), son2_obj.id.instance()); + BOOST_REQUIRE_EQUAL(nathan_votes_for_son->at(sidechain_type::hive).size(), 1); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::hive).at(0).id.instance(), son2_obj.id.instance()); + // Try to reject incorrect SON accepted.clear(); rejected.clear(); rejected.push_back("son1accnt"); BOOST_CHECK_THROW(update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, sidechain_type::bitcoin, 1, true), fc::exception); + BOOST_CHECK_THROW(update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, + sidechain_type::hive, 1, true), fc::exception); generate_block(); // Verify the votes @@ -572,12 +623,22 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] == son2_start_votes[sidechain_type::bitcoin]); son2_start_votes = son2_end_votes; + //! Check votes of nathan + nathan_votes_for_son = con.wallet_api_ptr->get_votes("nathan").votes_for_sons; + BOOST_REQUIRE(nathan_votes_for_son); + BOOST_REQUIRE_EQUAL(nathan_votes_for_son->at(sidechain_type::bitcoin).size(), 1); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::bitcoin).at(0).id.instance(), son2_obj.id.instance()); + BOOST_REQUIRE_EQUAL(nathan_votes_for_son->at(sidechain_type::hive).size(), 1); + BOOST_CHECK_EQUAL(nathan_votes_for_son->at(sidechain_type::hive).at(0).id.instance(), son2_obj.id.instance()); + // Reject SON2 accepted.clear(); rejected.clear(); rejected.push_back("son2account"); update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, sidechain_type::bitcoin, 0, true); + update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, + sidechain_type::hive, 0, true); BOOST_CHECK(generate_maintenance_block()); // Verify the votes @@ -590,6 +651,16 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] < son2_start_votes[sidechain_type::bitcoin]); son2_start_votes = son2_end_votes; + //! Check son2account voters + voters_for_son2account = con.wallet_api_ptr->get_voters("son2account").voters_for_son; + BOOST_REQUIRE(voters_for_son2account); + BOOST_CHECK_EQUAL(voters_for_son2account->at(sidechain_type::bitcoin).voters.size(), 0); + BOOST_CHECK_EQUAL(voters_for_son2account->at(sidechain_type::hive).voters.size(), 0); + + //! Check votes of nathan + nathan_votes_for_son = con.wallet_api_ptr->get_votes("nathan").votes_for_sons; + BOOST_REQUIRE(!nathan_votes_for_son); + // Try to accept and reject the same SON accepted.clear(); rejected.clear(); @@ -597,6 +668,8 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) accepted.push_back("son1accnt"); BOOST_REQUIRE_THROW(update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, sidechain_type::bitcoin, 1, true), fc::exception); + BOOST_REQUIRE_THROW(update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, + sidechain_type::hive, 1, true), fc::exception); BOOST_CHECK(generate_maintenance_block()); // Verify the votes @@ -609,6 +682,10 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] == son2_start_votes[sidechain_type::bitcoin]); son2_start_votes = son2_end_votes; + //! Check votes of nathan + nathan_votes_for_son = con.wallet_api_ptr->get_votes("nathan").votes_for_sons; + BOOST_REQUIRE(!nathan_votes_for_son); + // Try to accept and reject empty lists accepted.clear(); rejected.clear(); @@ -626,6 +703,10 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) BOOST_CHECK(son2_end_votes[sidechain_type::bitcoin] == son2_start_votes[sidechain_type::bitcoin]); son2_start_votes = son2_end_votes; + //! Check votes of nathan + nathan_votes_for_son = con.wallet_api_ptr->get_votes("nathan").votes_for_sons; + BOOST_REQUIRE(!nathan_votes_for_son); + } catch( fc::exception& e ) { BOOST_TEST_MESSAGE("SON cli wallet tests exception"); edump((e.to_detail_string())); @@ -672,7 +753,6 @@ BOOST_FIXTURE_TEST_CASE( cli_list_active_sons, cli_fixture ) BOOST_TEST_MESSAGE("SON cli wallet tests for list_active_sons begin"); try { - const sidechain_type type = sidechain_type::bitcoin; son_test_helper sth(*this); signed_transaction vote_tx; @@ -703,7 +783,8 @@ BOOST_FIXTURE_TEST_CASE( cli_list_active_sons, cli_fixture ) for(unsigned int i = 1; i < son_number + 1; i++) { std::string name = "sonaccount" + fc::to_pretty_string(i); - vote_tx = con.wallet_api_ptr->vote_for_son(name, name, type, true, true); + vote_tx = con.wallet_api_ptr->vote_for_son(name, name, sidechain_type::bitcoin, true, true); + vote_tx = con.wallet_api_ptr->vote_for_son(name, name, sidechain_type::hive, true, true); } BOOST_CHECK(generate_maintenance_block()); @@ -711,7 +792,8 @@ BOOST_FIXTURE_TEST_CASE( cli_list_active_sons, cli_fixture ) { std::string name1 = "sonaccount" + fc::to_pretty_string(i); std::string name2 = "sonaccount" + fc::to_pretty_string(i + 1); - vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, type, true, true); + vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, sidechain_type::bitcoin, true, true); + vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, sidechain_type::hive, true, true); } BOOST_CHECK(generate_maintenance_block()); gpo = con.wallet_api_ptr->get_global_properties(); @@ -741,7 +823,6 @@ BOOST_AUTO_TEST_CASE( maintenance_test ) BOOST_TEST_MESSAGE("SON maintenance cli wallet tests begin"); try { - const sidechain_type type = sidechain_type::bitcoin; son_test_helper sth(*this); std::string name("sonaccount1"); @@ -771,7 +852,8 @@ BOOST_AUTO_TEST_CASE( maintenance_test ) con.wallet_api_ptr->transfer( "nathan", "sonaccount" + fc::to_pretty_string(i), "1000", "1.3.0", "Here are some CORE tokens for your new account", true ); con.wallet_api_ptr->create_vesting_balance("sonaccount" + fc::to_pretty_string(i), "500", "1.3.0", vesting_balance_type::gpos, true); - con.wallet_api_ptr->vote_for_son("sonaccount" + fc::to_pretty_string(i), name, type, true, true); + con.wallet_api_ptr->vote_for_son("sonaccount" + fc::to_pretty_string(i), name, sidechain_type::bitcoin, true, true); + con.wallet_api_ptr->vote_for_son("sonaccount" + fc::to_pretty_string(i), name, sidechain_type::hive, true, true); } BOOST_CHECK(generate_maintenance_block()); -- 2.45.2 From cbca83a90e3c8e6c45ab7ee2b8c73d18a28c9ee2 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Sat, 26 Mar 2022 12:03:13 +0300 Subject: [PATCH 07/15] #308 - multiple lists of active_sons --- libraries/chain/db_getter.cpp | 12 +- libraries/chain/db_maint.cpp | 308 +++++++++--------- libraries/chain/db_witness_schedule.cpp | 166 +++++----- .../chain/include/graphene/chain/database.hpp | 25 +- .../graphene/chain/global_property_object.hpp | 8 +- .../graphene/chain/protocol/son_wallet.hpp | 2 +- .../chain/include/graphene/chain/son_info.hpp | 4 +- .../include/graphene/chain/son_object.hpp | 8 +- .../graphene/chain/son_wallet_object.hpp | 2 +- .../chain/witness_schedule_object.hpp | 2 +- .../chain/sidechain_address_evaluator.cpp | 2 +- libraries/chain/son_evaluator.cpp | 60 ++-- .../chain/son_wallet_deposit_evaluator.cpp | 8 +- libraries/chain/son_wallet_evaluator.cpp | 12 +- .../chain/son_wallet_withdraw_evaluator.cpp | 8 +- .../peerplays_sidechain_plugin.cpp | 25 +- .../sidechain_net_handler_bitcoin.cpp | 53 +-- .../sidechain_net_handler_hive.cpp | 15 +- .../sidechain_net_handler_peerplays.cpp | 2 +- libraries/wallet/wallet.cpp | 116 ++++--- tests/tests/sidechain_addresses_test.cpp | 3 +- tests/tests/son_operations_tests.cpp | 12 +- tests/tests/son_wallet_tests.cpp | 5 +- 23 files changed, 448 insertions(+), 410 deletions(-) diff --git a/libraries/chain/db_getter.cpp b/libraries/chain/db_getter.cpp index 78740c9b..54126320 100644 --- a/libraries/chain/db_getter.cpp +++ b/libraries/chain/db_getter.cpp @@ -293,7 +293,7 @@ bool database::is_son_dereg_valid( son_id_type son_id ) (head_block_time() - son->statistics(*this).last_down_timestamp >= fc::seconds(get_global_properties().parameters.son_deregister_time()))); } -bool database::is_son_active( son_id_type son_id ) +bool database::is_son_active( sidechain_type type, son_id_type son_id ) { const auto& son_idx = get_index_type().indices().get< by_id >(); auto son = son_idx.find( son_id ); @@ -303,9 +303,15 @@ bool database::is_son_active( son_id_type son_id ) } const global_property_object& gpo = get_global_properties(); + if(!gpo.active_sons.contains(type)) + { + return false; + } + + const auto& gpo_as = gpo.active_sons.at(type); vector active_son_ids; - active_son_ids.reserve(gpo.active_sons.size()); - std::transform(gpo.active_sons.begin(), gpo.active_sons.end(), + active_son_ids.reserve(gpo_as.size()); + std::transform(gpo_as.cbegin(), gpo_as.cend(), std::inserter(active_son_ids, active_son_ids.end()), [](const son_info& swi) { return swi.son_id; diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index 66647569..4df01acf 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -280,122 +280,121 @@ void database::pay_sons() } } -void database::update_son_metrics(const vector& curr_active_sons) +void database::update_son_metrics(const flat_map >& curr_active_sons) { - vector current_sons; + for(const auto& curr_active_sidechain_sons : curr_active_sons) { + const auto& sidechain = curr_active_sidechain_sons.first; + const auto& _curr_active_sidechain_sons = curr_active_sidechain_sons.second; - current_sons.reserve(curr_active_sons.size()); - std::transform(curr_active_sons.begin(), curr_active_sons.end(), - std::inserter(current_sons, current_sons.end()), - [](const son_info &swi) { - return swi.son_id; - }); + vector current_sons; - const auto& son_idx = get_index_type().indices().get< by_id >(); - for( auto& son : son_idx ) - { - auto& stats = son.statistics(*this); - bool is_active_son = (std::find(current_sons.begin(), current_sons.end(), son.id) != current_sons.end()); - modify( stats, [&]( son_statistics_object& _stats ) - { - if(is_active_son) { - _stats.total_voted_time = _stats.total_voted_time + get_global_properties().parameters.maintenance_interval; - } - _stats.total_downtime += _stats.current_interval_downtime; - _stats.current_interval_downtime = 0; - for (const auto &str : _stats.sidechain_txs_reported) { - _stats.sidechain_txs_reported.at(str.first) = 0; - } - }); + current_sons.reserve(_curr_active_sidechain_sons.size()); + std::transform(_curr_active_sidechain_sons.cbegin(), _curr_active_sidechain_sons.cend(), + std::inserter(current_sons, current_sons.end()), + [](const son_info &swi) { + return swi.son_id; + }); + + const auto &son_idx = get_index_type().indices().get(); + for (auto &son : son_idx) { + auto &stats = son.statistics(*this); + bool is_active_son = (std::find(current_sons.begin(), current_sons.end(), son.id) != current_sons.end()); + modify(stats, [&](son_statistics_object &_stats) { + if (is_active_son) { + _stats.total_voted_time[sidechain] = _stats.total_voted_time[sidechain] + get_global_properties().parameters.maintenance_interval; + } + _stats.total_downtime[sidechain] += _stats.current_interval_downtime[sidechain]; + _stats.current_interval_downtime[sidechain] = 0; + _stats.sidechain_txs_reported[sidechain] = 0; + }); + } } } -void database::update_son_statuses(const vector& curr_active_sons, const vector& new_active_sons) +void database::update_son_statuses( const flat_map >& curr_active_sons, + const flat_map >& new_active_sons ) { - vector current_sons, new_sons; - vector sons_to_remove, sons_to_add; - const auto& idx = get_index_type().indices().get(); + FC_ASSERT(curr_active_sons.size() == new_active_sons.size(), "Invalid size in SON active lists," + " curr_active_sons_size={curr_active_sons_size}, new_active_sons_size={new_active_sons_size}", + ("curr_active_sons_size", curr_active_sons.size())("new_active_sons_size", new_active_sons.size())); - current_sons.reserve(curr_active_sons.size()); - std::transform(curr_active_sons.begin(), curr_active_sons.end(), - std::inserter(current_sons, current_sons.end()), - [](const son_info &swi) { - return swi.son_id; - }); + for(const auto& curr_active_sidechain_sons : curr_active_sons) { + const auto& sidechain = curr_active_sidechain_sons.first; - new_sons.reserve(new_active_sons.size()); - std::transform(new_active_sons.begin(), new_active_sons.end(), - std::inserter(new_sons, new_sons.end()), - [](const son_info &swi) { - return swi.son_id; - }); + vector current_sons, new_sons; + vector sons_to_remove, sons_to_add; + const auto &idx = get_index_type().indices().get(); - // find all cur_active_sons members that is not in new_active_sons - for_each(current_sons.begin(), current_sons.end(), - [&sons_to_remove, &new_sons](const son_id_type& si) - { - if(std::find(new_sons.begin(), new_sons.end(), si) == - new_sons.end()) - { - sons_to_remove.push_back(si); - } - } - ); + current_sons.reserve(curr_active_sons.at(sidechain).size()); + std::transform(curr_active_sons.at(sidechain).cbegin(), curr_active_sons.at(sidechain).cend(), + std::inserter(current_sons, current_sons.end()), + [](const son_info &swi) { + return swi.son_id; + }); - for( const auto& sid : sons_to_remove ) - { - auto son = idx.find( sid ); - if(son == idx.end()) // SON is deleted already - continue; - // keep maintenance status for nodes becoming inactive - if(son->status == son_status::active) - { - modify( *son, [&]( son_object& obj ){ - obj.status = son_status::inactive; - }); - } - } + new_sons.reserve(new_active_sons.at(sidechain).size()); + std::transform(new_active_sons.at(sidechain).cbegin(), new_active_sons.at(sidechain).cend(), + std::inserter(new_sons, new_sons.end()), + [](const son_info &swi) { + return swi.son_id; + }); - // find all new_active_sons members that is not in cur_active_sons - for_each(new_sons.begin(), new_sons.end(), - [&sons_to_add, ¤t_sons](const son_id_type& si) - { - if(std::find(current_sons.begin(), current_sons.end(), si) == - current_sons.end()) - { - sons_to_add.push_back(si); - } - } - ); + // find all cur_active_sons members that is not in new_active_sons + for_each(current_sons.begin(), current_sons.end(), + [&sons_to_remove, &new_sons](const son_id_type &si) { + if (std::find(new_sons.begin(), new_sons.end(), si) == + new_sons.end()) { + sons_to_remove.push_back(si); + } + }); - for( const auto& sid : sons_to_add ) - { - auto son = idx.find( sid ); - FC_ASSERT(son != idx.end(), "Invalid SON in active list, id={sonid}.", ("sonid", sid)); - // keep maintenance status for new nodes - if(son->status == son_status::inactive) - { - modify( *son, [&]( son_object& obj ){ - obj.status = son_status::active; - }); - } - } - - ilog("New SONS"); - for(size_t i = 0; i < new_sons.size(); i++) { - auto son = idx.find( new_sons[i] ); - if(son == idx.end()) // SON is deleted already + for (const auto &sid : sons_to_remove) { + auto son = idx.find(sid); + if (son == idx.end()) // SON is deleted already continue; - ilog( "${s}, status = ${ss}, total_votes = ${sv}", ("s", new_sons[i])("ss", son->status)("sv", son->total_votes) ); - } + // keep maintenance status for nodes becoming inactive + if (son->status == son_status::active) { + modify(*son, [&](son_object &obj) { + obj.status = son_status::inactive; + }); + } + } - if( sons_to_remove.size() > 0 ) - { - remove_inactive_son_proposals(sons_to_remove); + // find all new_active_sons members that is not in cur_active_sons + for_each(new_sons.begin(), new_sons.end(), + [&sons_to_add, ¤t_sons](const son_id_type &si) { + if (std::find(current_sons.begin(), current_sons.end(), si) == + current_sons.end()) { + sons_to_add.push_back(si); + } + }); + + for (const auto &sid : sons_to_add) { + auto son = idx.find(sid); + FC_ASSERT(son != idx.end(), "Invalid SON in active list, id={sonid}.", ("sonid", sid)); + // keep maintenance status for new nodes + if (son->status == son_status::inactive) { + modify(*son, [&](son_object &obj) { + obj.status = son_status::active; + }); + } + } + + ilog("New SONS for sidechain = ${sidechain}", ("sidechain", sidechain)); + for (size_t i = 0; i < new_sons.size(); i++) { + auto son = idx.find(new_sons[i]); + if (son == idx.end()) // SON is deleted already + continue; + ilog("${s}, status = ${ss}, total_votes = ${sv}", ("s", new_sons[i])("ss", son->status)("sv", son->total_votes)); + } + + if (sons_to_remove.size() > 0) { + remove_inactive_son_proposals(sons_to_remove); + } } } -void database::update_son_wallet(const vector& new_active_sons) +void database::update_son_wallet(const flat_map >& new_active_sons) { bool should_recreate_pw = true; @@ -408,8 +407,16 @@ void database::update_son_wallet(const vector& new_active_sons) bool wallet_son_sets_equal = (cur_wallet_sons.size() == new_active_sons.size()); if (wallet_son_sets_equal) { - for( size_t i = 0; i < cur_wallet_sons.size(); i++ ) { - wallet_son_sets_equal = wallet_son_sets_equal && cur_wallet_sons.at(i) == new_active_sons.at(i); + for( const auto& cur_wallet_sidechain_sons : cur_wallet_sons ) { + const auto& sidechain = cur_wallet_sidechain_sons.first; + const auto& _cur_wallet_sidechain_sons = cur_wallet_sidechain_sons.second; + + wallet_son_sets_equal = wallet_son_sets_equal && (_cur_wallet_sidechain_sons.size() == new_active_sons.at(sidechain).size()); + if (wallet_son_sets_equal) { + for (size_t i = 0; i < _cur_wallet_sidechain_sons.size(); i++) { + wallet_son_sets_equal = wallet_son_sets_equal && (_cur_wallet_sidechain_sons.at(i) == new_active_sons.at(sidechain).at(i)); + } + } } } @@ -429,7 +436,12 @@ void database::update_son_wallet(const vector& new_active_sons) create( [&]( son_wallet_object& obj ) { obj.valid_from = head_block_time(); obj.expires = time_point_sec::maximum(); - obj.sons.insert(obj.sons.end(), new_active_sons.begin(), new_active_sons.end()); + for(const auto& new_active_sidechain_sons : new_active_sons){ + const auto& sidechain = new_active_sidechain_sons.first; + const auto& _new_active_sidechain_sons = new_active_sidechain_sons.second; + + obj.sons[sidechain].insert(obj.sons[sidechain].end(), _new_active_sidechain_sons.cbegin(), _new_active_sidechain_sons.cend()); + } }); } } @@ -701,7 +713,10 @@ void database::update_active_sons() const global_property_object& gpo = get_global_properties(); const chain_parameters& cp = gpo.parameters; - auto sons = sort_votable_objects(sidechain_type::bitcoin, cp.maximum_son_count()); + //! Fixme - sort_votable_objects - fix bitcoin + hive -> deduce auto + flat_map > > sons; + sons[sidechain_type::bitcoin] = sort_votable_objects(sidechain_type::bitcoin, cp.maximum_son_count()); + sons[sidechain_type::hive] = sort_votable_objects(sidechain_type::hive, cp.maximum_son_count()); const auto& all_sons = get_index_type().indices(); @@ -729,21 +744,24 @@ void database::update_active_sons() { modify( get(gpo.parameters.son_account()), [&]( account_object& a ) { + set account_ids; + for(const auto& sidechain_sons : sons) + { + for( const son_object& son : sidechain_sons.second ) + { + account_ids.emplace(son.son_account); + } + } + if( head_block_time() < HARDFORK_533_TIME ) { - map weights; a.active.weight_threshold = 0; a.active.account_auths.clear(); - for( const son_object& son : sons ) - { - weights.emplace(son.son_account, uint64_t(1)); - } - - for( const auto& weight : weights ) + for( const auto& account_id : account_ids ) { // Ensure that everyone has at least one vote. Zero weights aren't allowed. - a.active.account_auths[weight.first] += 1; + a.active.account_auths[account_id] += 1; a.active.weight_threshold += 1; } @@ -754,8 +772,10 @@ void database::update_active_sons() else { vote_counter vc; - for( const son_object& son : sons ) - vc.add( son.son_account, UINT64_C(1) ); + for( const auto& account_id : account_ids ) + { + vc.add(account_id, UINT64_C(1)); + } vc.finish_2_3( a.active ); } } ); @@ -763,22 +783,32 @@ void database::update_active_sons() // Compare current and to-be lists of active sons - auto cur_active_sons = gpo.active_sons; - vector new_active_sons; + const auto& cur_active_sons = gpo.active_sons; + flat_map > new_active_sons; const auto &acc = get(gpo.parameters.son_account()); - for( const son_object& son : sons ) { - son_info swi; - swi.son_id = son.id; - swi.weight = acc.active.account_auths.at(son.son_account); - swi.signing_key = son.signing_key; - swi.sidechain_public_keys = son.sidechain_public_keys; - new_active_sons.push_back(swi); + for( const auto& sidechain_sons : sons ){ + for( const son_object& son : sidechain_sons.second ) { + son_info swi; + swi.son_id = son.id; + swi.weight = acc.active.account_auths.at(son.son_account); + swi.signing_key = son.signing_key; + swi.sidechain_public_keys = son.sidechain_public_keys; + new_active_sons[sidechain_sons.first].push_back(swi); + } } bool son_sets_equal = (cur_active_sons.size() == new_active_sons.size()); if (son_sets_equal) { - for( size_t i = 0; i < cur_active_sons.size(); i++ ) { - son_sets_equal = son_sets_equal && cur_active_sons.at(i) == new_active_sons.at(i); + for( const auto& cur_active_sidechain_sons : cur_active_sons ){ + const auto& sidechain = cur_active_sidechain_sons.first; + const auto& _cur_active_sidechain_sons = cur_active_sidechain_sons.second; + + son_sets_equal = son_sets_equal && (_cur_active_sidechain_sons.size() == new_active_sons.at(sidechain).size()); + if (son_sets_equal) { + for (size_t i = 0; i < _cur_active_sidechain_sons.size(); i++) { + son_sets_equal = son_sets_equal && (_cur_active_sidechain_sons.at(i) == new_active_sons.at(sidechain).at(i)); + } + } } } @@ -797,26 +827,12 @@ void database::update_active_sons() modify(gpo, [&]( global_property_object& gp ){ gp.active_sons.clear(); gp.active_sons.reserve(new_active_sons.size()); - gp.active_sons.insert(gp.active_sons.end(), new_active_sons.begin(), new_active_sons.end()); - }); + for( const auto& new_active_sidechain_sons : new_active_sons ) { + const auto& sidechain = new_active_sidechain_sons.first; + const auto& _new_active_sidechain_sons = new_active_sidechain_sons.second; - const son_schedule_object& sso = son_schedule_id_type()(*this); - modify(sso, [&](son_schedule_object& _sso) - { - flat_set active_sons; - active_sons.reserve(gpo.active_sons.size()); - std::transform(gpo.active_sons.begin(), gpo.active_sons.end(), - std::inserter(active_sons, active_sons.end()), - [](const son_info& swi) { - return swi.son_id; - }); - _sso.scheduler.update(active_sons); - // similar to witness, produce schedule for sons - if(cur_active_sons.size() == 0 && new_active_sons.size() > 0) - { - witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV); - for( size_t i=0; i active_sons; - active_sons.reserve(gpo.active_sons.size()); - std::transform(gpo.active_sons.begin(), gpo.active_sons.end(), + active_sons.reserve(gpo.active_sons.at(sidechain_type::hive).size()); + std::transform(gpo.active_sons.at(sidechain_type::hive).cbegin(), gpo.active_sons.at(sidechain_type::hive).cend(), std::inserter(active_sons, active_sons.end()), [](const son_info& swi) { return swi.son_id; @@ -850,8 +866,8 @@ void database::update_active_sons() modify(ssobitcoin, [&](son_schedule_object& _sso) { flat_set active_sons; - active_sons.reserve(gpo.active_sons.size()); - std::transform(gpo.active_sons.begin(), gpo.active_sons.end(), + active_sons.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size()); + std::transform(gpo.active_sons.at(sidechain_type::bitcoin).cbegin(), gpo.active_sons.at(sidechain_type::bitcoin).cend(), std::inserter(active_sons, active_sons.end()), [](const son_info& swi) { return swi.son_id; diff --git a/libraries/chain/db_witness_schedule.cpp b/libraries/chain/db_witness_schedule.cpp index 88fb19ad..9ccdcf8a 100644 --- a/libraries/chain/db_witness_schedule.cpp +++ b/libraries/chain/db_witness_schedule.cpp @@ -74,49 +74,6 @@ witness_id_type database::get_scheduled_witness( uint32_t slot_num )const return wid; } -son_id_type database::get_scheduled_son( uint32_t slot_num )const -{ - son_id_type sid; - const global_property_object& gpo = get_global_properties(); - if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM) - { - const dynamic_global_property_object& dpo = get_dynamic_global_properties(); - const son_schedule_object& sso = son_schedule_id_type()(*this); - uint64_t current_aslot = dpo.current_aslot + slot_num; - return sso.current_shuffled_sons[ current_aslot % sso.current_shuffled_sons.size() ]; - } - if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM && - slot_num != 0 ) - { - const son_schedule_object& sso = son_schedule_id_type()(*this); - // ask the near scheduler who goes in the given slot - bool slot_is_near = sso.scheduler.get_slot(slot_num-1, sid); - if(! slot_is_near) - { - // if the near scheduler doesn't know, we have to extend it to - // a far scheduler. - // n.b. instantiating it is slow, but block gaps long enough to - // need it are likely pretty rare. - - witness_scheduler_rng far_rng(sso.rng_seed.begin(), GRAPHENE_FAR_SCHEDULE_CTR_IV); - - far_future_son_scheduler far_scheduler = - far_future_son_scheduler(sso.scheduler, far_rng); - if(!far_scheduler.get_slot(slot_num-1, sid)) - { - // no scheduled son -- somebody set up us the bomb - // n.b. this code path is impossible, the present - // implementation of far_future_son_scheduler - // returns true unconditionally - assert( false ); - } - } - } - return sid; -} - -// this is just prototype to prove that active_sons are in hive schedule_object and -// bitcoin schedule object son_id_type database::get_scheduled_son( sidechain_type type, uint32_t slot_num )const { son_id_type sid; @@ -126,7 +83,7 @@ son_id_type database::get_scheduled_son( sidechain_type type, uint32_t slot_num const dynamic_global_property_object& dpo = get_dynamic_global_properties(); const son_schedule_object& sso = type == sidechain_type::hive ? son_schedule_id_type(1)(*this) : son_schedule_id_type(2)(*this); uint64_t current_aslot = dpo.current_aslot + slot_num; - return sso.current_shuffled_sons[ current_aslot % sso.current_shuffled_sons.size() ]; + return sso.current_shuffled_sons.at(type)[ current_aslot % sso.current_shuffled_sons.size() ]; } if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM && slot_num != 0 ) @@ -246,24 +203,37 @@ void database::update_son_schedule() _sso.current_shuffled_sons.clear(); _sso.current_shuffled_sons.reserve( gpo.active_sons.size() ); - for( const son_info& w : gpo.active_sons ) - _sso.current_shuffled_sons.push_back( w.son_id ); + for(const auto& sidechain_sons : gpo.active_sons) + { + const auto& sidechain = sidechain_sons.first; + const auto& active_sons = sidechain_sons.second; + + _sso.current_shuffled_sons[sidechain].reserve( active_sons.size() ); + for (const son_info &w : active_sons) + _sso.current_shuffled_sons[sidechain].push_back(w.son_id); + } auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32; - for( uint32_t i = 0; i < _sso.current_shuffled_sons.size(); ++i ) + for(const auto& sidechain_current_shuffled_sons : _sso.current_shuffled_sons) { - /// High performance random generator - /// http://xorshift.di.unimi.it/ - uint64_t k = now_hi + uint64_t(i)*2685821657736338717ULL; - k ^= (k >> 12); - k ^= (k << 25); - k ^= (k >> 27); - k *= 2685821657736338717ULL; + const auto& sidechain = sidechain_current_shuffled_sons.first; + const auto& current_shuffled_sons = sidechain_current_shuffled_sons.second; - uint32_t jmax = _sso.current_shuffled_sons.size() - i; - uint32_t j = i + k%jmax; - std::swap( _sso.current_shuffled_sons[i], - _sso.current_shuffled_sons[j] ); + for (uint32_t i = 0; i < current_shuffled_sons.size(); ++i) + { + /// High performance random generator + /// http://xorshift.di.unimi.it/ + uint64_t k = now_hi + uint64_t(i) * 2685821657736338717ULL; + k ^= (k >> 12); + k ^= (k << 25); + k ^= (k >> 27); + k *= 2685821657736338717ULL; + + uint32_t jmax = current_shuffled_sons.size() - i; + uint32_t j = i + k % jmax; + std::swap(_sso.current_shuffled_sons[sidechain][i], + _sso.current_shuffled_sons[sidechain][j]); + } } }); @@ -272,24 +242,36 @@ void database::update_son_schedule() _sso.current_shuffled_sons.clear(); _sso.current_shuffled_sons.reserve( gpo.active_sons.size() ); - for( const son_info& w : gpo.active_sons ) - _sso.current_shuffled_sons.push_back( w.son_id ); + for(const auto& sidechain_sons : gpo.active_sons) + { + const auto& sidechain = sidechain_sons.first; + const auto& active_sons = sidechain_sons.second; + + for (const son_info &w : active_sons) + _sso.current_shuffled_sons[sidechain].push_back(w.son_id); + } auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32; - for( uint32_t i = 0; i < _sso.current_shuffled_sons.size(); ++i ) + for(const auto& sidechain_current_shuffled_sons : _sso.current_shuffled_sons) { - /// High performance random generator - /// http://xorshift.di.unimi.it/ - uint64_t k = now_hi + uint64_t(i)*2685821657736338717ULL; - k ^= (k >> 12); - k ^= (k << 25); - k ^= (k >> 27); - k *= 2685821657736338717ULL; + const auto& sidechain = sidechain_current_shuffled_sons.first; + const auto& current_shuffled_sons = sidechain_current_shuffled_sons.second; - uint32_t jmax = _sso.current_shuffled_sons.size() - i; - uint32_t j = i + k%jmax; - std::swap( _sso.current_shuffled_sons[i], - _sso.current_shuffled_sons[j] ); + for (uint32_t i = 0; i < current_shuffled_sons.size(); ++i) + { + /// High performance random generator + /// http://xorshift.di.unimi.it/ + uint64_t k = now_hi + uint64_t(i) * 2685821657736338717ULL; + k ^= (k >> 12); + k ^= (k << 25); + k ^= (k >> 27); + k *= 2685821657736338717ULL; + + uint32_t jmax = current_shuffled_sons.size() - i; + uint32_t j = i + k % jmax; + std::swap(_sso.current_shuffled_sons[sidechain][i], + _sso.current_shuffled_sons[sidechain][j]); + } } }); @@ -298,24 +280,36 @@ void database::update_son_schedule() _sso.current_shuffled_sons.clear(); _sso.current_shuffled_sons.reserve( gpo.active_sons.size() ); - for( const son_info& w : gpo.active_sons ) - _sso.current_shuffled_sons.push_back( w.son_id ); + for(const auto& sidechain_sons : gpo.active_sons) + { + const auto& sidechain = sidechain_sons.first; + const auto& active_sons = sidechain_sons.second; + + for (const son_info &w : active_sons) + _sso.current_shuffled_sons[sidechain].push_back(w.son_id); + } auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32; - for( uint32_t i = 0; i < _sso.current_shuffled_sons.size(); ++i ) + for(const auto& sidechain_current_shuffled_sons : _sso.current_shuffled_sons) { - /// High performance random generator - /// http://xorshift.di.unimi.it/ - uint64_t k = now_hi + uint64_t(i)*2685821657736338717ULL; - k ^= (k >> 12); - k ^= (k << 25); - k ^= (k >> 27); - k *= 2685821657736338717ULL; + const auto& sidechain = sidechain_current_shuffled_sons.first; + const auto& current_shuffled_sons = sidechain_current_shuffled_sons.second; - uint32_t jmax = _sso.current_shuffled_sons.size() - i; - uint32_t j = i + k%jmax; - std::swap( _sso.current_shuffled_sons[i], - _sso.current_shuffled_sons[j] ); + for (uint32_t i = 0; i < current_shuffled_sons.size(); ++i) + { + /// High performance random generator + /// http://xorshift.di.unimi.it/ + uint64_t k = now_hi + uint64_t(i) * 2685821657736338717ULL; + k ^= (k >> 12); + k ^= (k << 25); + k ^= (k >> 27); + k *= 2685821657736338717ULL; + + uint32_t jmax = current_shuffled_sons.size() - i; + uint32_t j = i + k % jmax; + std::swap(_sso.current_shuffled_sons[sidechain][i], + _sso.current_shuffled_sons[sidechain][j]); + } } }); } diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index 28dbc795..0d2c330f 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -242,22 +242,6 @@ namespace graphene { namespace chain { */ witness_id_type get_scheduled_witness(uint32_t slot_num)const; - /** - * @brief Get the son scheduled for block production in a slot. - * - * slot_num always corresponds to a time in the future. - * - * If slot_num == 1, returns the next scheduled son. - * If slot_num == 2, returns the next scheduled son after - * 1 block gap. - * - * Use the get_slot_time() and get_slot_at_time() functions - * to convert between slot_num and timestamp. - * - * Passing slot_num == 0 returns GRAPHENE_NULL_WITNESS - */ - son_id_type get_scheduled_son(uint32_t slot_num)const; - /** * @brief Get the bitcoin or hive son scheduled for block production in a slot. * @@ -327,7 +311,7 @@ namespace graphene { namespace chain { fc::optional create_son_deregister_proposal( son_id_type son_id, account_id_type paying_son ); signed_transaction create_signed_transaction( const fc::ecc::private_key& signing_private_key, const operation& op ); bool is_son_dereg_valid( son_id_type son_id ); - bool is_son_active( son_id_type son_id ); + bool is_son_active( sidechain_type type, son_id_type son_id ); bool is_asset_creation_allowed(const string& symbol); time_point_sec head_block_time()const; @@ -586,13 +570,14 @@ namespace graphene { namespace chain { void perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props); void update_active_witnesses(); void update_active_committee_members(); - void update_son_metrics( const vector& curr_active_sons ); + void update_son_metrics( const flat_map >& curr_active_sons ); void update_active_sons(); void remove_son_proposal( const proposal_object& proposal ); void remove_inactive_son_down_proposals( const vector& son_ids_to_remove ); void remove_inactive_son_proposals( const vector& son_ids_to_remove ); - void update_son_statuses( const vector& cur_active_sons, const vector& new_active_sons ); - void update_son_wallet( const vector& new_active_sons ); + void update_son_statuses( const flat_map >& curr_active_sons, + const flat_map >& new_active_sons ); + void update_son_wallet( const flat_map >& new_active_sons ); void update_worker_votes(); public: diff --git a/libraries/chain/include/graphene/chain/global_property_object.hpp b/libraries/chain/include/graphene/chain/global_property_object.hpp index 0f95a6e3..592eddf0 100644 --- a/libraries/chain/include/graphene/chain/global_property_object.hpp +++ b/libraries/chain/include/graphene/chain/global_property_object.hpp @@ -49,10 +49,10 @@ namespace graphene { namespace chain { chain_parameters parameters; optional pending_parameters; - uint32_t next_available_vote_id = 0; - vector active_committee_members; // updated once per maintenance interval - flat_set active_witnesses; // updated once per maintenance interval - vector active_sons; // updated once per maintenance interval + uint32_t next_available_vote_id = 0; + vector active_committee_members; // updated once per maintenance interval + flat_set active_witnesses; // updated once per maintenance interval + flat_map > active_sons; // updated once per maintenance interval // n.b. witness scheduling is done by witness_schedule object }; diff --git a/libraries/chain/include/graphene/chain/protocol/son_wallet.hpp b/libraries/chain/include/graphene/chain/protocol/son_wallet.hpp index 5194bed2..75c3db85 100644 --- a/libraries/chain/include/graphene/chain/protocol/son_wallet.hpp +++ b/libraries/chain/include/graphene/chain/protocol/son_wallet.hpp @@ -11,7 +11,7 @@ namespace graphene { namespace chain { asset fee; account_id_type payer; - vector sons; + flat_map > sons; account_id_type fee_payer()const { return payer; } share_type calculate_fee(const fee_parameters_type& k)const { return 0; } diff --git a/libraries/chain/include/graphene/chain/son_info.hpp b/libraries/chain/include/graphene/chain/son_info.hpp index 2bfecac4..e32c9bd5 100644 --- a/libraries/chain/include/graphene/chain/son_info.hpp +++ b/libraries/chain/include/graphene/chain/son_info.hpp @@ -14,9 +14,9 @@ namespace graphene { namespace chain { son_id_type son_id; weight_type weight = 0; public_key_type signing_key; - flat_map sidechain_public_keys; + flat_map sidechain_public_keys; //! Fixme - delete map from here - bool operator==(const son_info& rhs) { + bool operator==(const son_info& rhs) const { bool son_sets_equal = (son_id == rhs.son_id) && (weight == rhs.weight) && diff --git a/libraries/chain/include/graphene/chain/son_object.hpp b/libraries/chain/include/graphene/chain/son_object.hpp index b1274f06..24891d91 100644 --- a/libraries/chain/include/graphene/chain/son_object.hpp +++ b/libraries/chain/include/graphene/chain/son_object.hpp @@ -35,11 +35,11 @@ namespace graphene { namespace chain { // Transactions signed since the last son payouts flat_map txs_signed; // Total Voted Active time i.e. duration selected as part of voted active SONs - uint64_t total_voted_time = 0; + flat_map total_voted_time; // Total Downtime barring the current down time in seconds, used for stats to present to user - uint64_t total_downtime = 0; + flat_map total_downtime; // Current Interval Downtime since last maintenance - uint64_t current_interval_downtime = 0; + flat_map current_interval_downtime; // Down timestamp, if son status is in_maintenance use this fc::time_point_sec last_down_timestamp; // Last Active heartbeat timestamp @@ -71,7 +71,7 @@ namespace graphene { namespace chain { public_key_type signing_key; vesting_balance_id_type pay_vb; son_statistics_id_type statistics; - son_status status = son_status::inactive; + son_status status = son_status::inactive; //! Fixme -> as map of sidechain_type flat_map sidechain_public_keys; void pay_son_fee(share_type pay, database& db); diff --git a/libraries/chain/include/graphene/chain/son_wallet_object.hpp b/libraries/chain/include/graphene/chain/son_wallet_object.hpp index 315def33..63b546ea 100644 --- a/libraries/chain/include/graphene/chain/son_wallet_object.hpp +++ b/libraries/chain/include/graphene/chain/son_wallet_object.hpp @@ -21,7 +21,7 @@ namespace graphene { namespace chain { time_point_sec expires; flat_map addresses; - vector sons; + flat_map > sons; }; struct by_valid_from; diff --git a/libraries/chain/include/graphene/chain/witness_schedule_object.hpp b/libraries/chain/include/graphene/chain/witness_schedule_object.hpp index 2eff563f..d8f1c9ee 100644 --- a/libraries/chain/include/graphene/chain/witness_schedule_object.hpp +++ b/libraries/chain/include/graphene/chain/witness_schedule_object.hpp @@ -96,7 +96,7 @@ class son_schedule_object : public graphene::db::abstract_object current_shuffled_sons; + flat_map > current_shuffled_sons; son_scheduler scheduler; uint32_t last_scheduling_block; diff --git a/libraries/chain/sidechain_address_evaluator.cpp b/libraries/chain/sidechain_address_evaluator.cpp index 625ef2f0..bd97fef5 100644 --- a/libraries/chain/sidechain_address_evaluator.cpp +++ b/libraries/chain/sidechain_address_evaluator.cpp @@ -47,7 +47,7 @@ void_result update_sidechain_address_evaluator::do_evaluate(const sidechain_addr { try { const auto& sidx = db().get_index_type().indices().get(); const auto& son_obj = sidx.find(op.payer); - FC_ASSERT( son_obj != sidx.end() && db().is_son_active(son_obj->id), "Non active SON trying to update deposit address object" ); + FC_ASSERT( son_obj != sidx.end() && db().is_son_active(op.sidechain, son_obj->id), "Non active SON trying to update deposit address object" ); const auto& sdpke_idx = db().get_index_type().indices().get(); FC_ASSERT( op.deposit_address.valid() && op.deposit_public_key.valid() && op.deposit_address_data.valid(), "Update operation by SON is not valid"); FC_ASSERT( (*op.deposit_address).length() > 0 && (*op.deposit_public_key).length() > 0 && (*op.deposit_address_data).length() > 0, "SON should create a valid deposit address with valid deposit public key"); diff --git a/libraries/chain/son_evaluator.cpp b/libraries/chain/son_evaluator.cpp index 255bd8eb..903b171b 100644 --- a/libraries/chain/son_evaluator.cpp +++ b/libraries/chain/son_evaluator.cpp @@ -171,40 +171,44 @@ object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation& if(itr != idx.end()) { const global_property_object& gpo = db().get_global_properties(); - vector active_son_ids; - active_son_ids.reserve(gpo.active_sons.size()); - std::transform(gpo.active_sons.begin(), gpo.active_sons.end(), - std::inserter(active_son_ids, active_son_ids.end()), - [](const son_info& swi) { - return swi.son_id; - }); - auto it_son = std::find(active_son_ids.begin(), active_son_ids.end(), op.son_id); - bool is_son_active = true; + for(const auto& active_sidechain_sons : gpo.active_sons) { + const auto& sidechain = active_sidechain_sons.first; + const auto& active_sons = active_sidechain_sons.second; - if(it_son == active_son_ids.end()) { - is_son_active = false; - } + vector active_son_ids; + active_son_ids.reserve(active_sons.size()); + std::transform(active_sons.cbegin(), active_sons.cend(), + std::inserter(active_son_ids, active_son_ids.end()), + [](const son_info &swi) { + return swi.son_id; + }); - if(itr->status == son_status::in_maintenance) { - db().modify( itr->statistics( db() ), [&]( son_statistics_object& sso ) - { - sso.current_interval_downtime += op.ts.sec_since_epoch() - sso.last_down_timestamp.sec_since_epoch(); - sso.last_active_timestamp = op.ts; - } ); + auto it_son = std::find(active_son_ids.begin(), active_son_ids.end(), op.son_id); + bool is_son_active = true; - db().modify(*itr, [&is_son_active](son_object &so) { - if(is_son_active) { + if (it_son == active_son_ids.end()) { + is_son_active = false; + } + + if (itr->status == son_status::in_maintenance) { + db().modify(itr->statistics(db()), [&](son_statistics_object &sso) { + sso.current_interval_downtime[sidechain] += op.ts.sec_since_epoch() - sso.last_down_timestamp.sec_since_epoch(); + sso.last_active_timestamp = op.ts; + }); + + db().modify(*itr, [&is_son_active](son_object &so) { + if (is_son_active) { so.status = son_status::active; - } else { + } else { so.status = son_status::inactive; - } - }); - } else if ((itr->status == son_status::active) || (itr->status == son_status::request_maintenance)) { - db().modify( itr->statistics( db() ), [&]( son_statistics_object& sso ) - { - sso.last_active_timestamp = op.ts; - } ); + } + }); + } else if ((itr->status == son_status::active) || (itr->status == son_status::request_maintenance)) { + db().modify(itr->statistics(db()), [&](son_statistics_object &sso) { + sso.last_active_timestamp = op.ts; + }); + } } } return op.son_id; diff --git a/libraries/chain/son_wallet_deposit_evaluator.cpp b/libraries/chain/son_wallet_deposit_evaluator.cpp index f9620282..e109c2f8 100644 --- a/libraries/chain/son_wallet_deposit_evaluator.cpp +++ b/libraries/chain/son_wallet_deposit_evaluator.cpp @@ -23,9 +23,9 @@ void_result create_son_wallet_deposit_evaluator::do_evaluate(const son_wallet_de const auto &swdo_idx = db().get_index_type().indices().get(); const auto swdo = swdo_idx.find(op.sidechain_uid); if (swdo == swdo_idx.end()) { - auto &gpo = db().get_global_properties(); + const auto &gpo = db().get_global_properties(); bool expected = false; - for (auto &si : gpo.active_sons) { + for (auto &si : gpo.active_sons.at(op.sidechain)) { if (op.son_id == si.son_id) { expected = true; break; @@ -78,8 +78,8 @@ object_id_type create_son_wallet_deposit_evaluator::do_apply(const son_wallet_de swdo.peerplays_to = op.peerplays_to; swdo.peerplays_asset = op.peerplays_asset; - auto &gpo = db().get_global_properties(); - for (auto &si : gpo.active_sons) { + const auto &gpo = db().get_global_properties(); + for (auto &si : gpo.active_sons.at(op.sidechain)) { swdo.expected_reports.insert(std::make_pair(si.son_id, si.weight)); auto stats_itr = db().get_index_type().indices().get().find(si.son_id); diff --git a/libraries/chain/son_wallet_evaluator.cpp b/libraries/chain/son_wallet_evaluator.cpp index 0baed1cb..9b1ff1b7 100644 --- a/libraries/chain/son_wallet_evaluator.cpp +++ b/libraries/chain/son_wallet_evaluator.cpp @@ -20,8 +20,16 @@ void_result recreate_son_wallet_evaluator::do_evaluate(const son_wallet_recreate bool son_sets_equal = (cur_wallet_sons.size() == new_wallet_sons.size()); if (son_sets_equal) { - for( size_t i = 0; i < cur_wallet_sons.size(); i++ ) { - son_sets_equal = son_sets_equal && cur_wallet_sons.at(i) == new_wallet_sons.at(i); + for( const auto& cur_wallet_sidechain_sons : cur_wallet_sons ) { + const auto& sidechain = cur_wallet_sidechain_sons.first; + const auto& _cur_wallet_sidechain_sons = cur_wallet_sidechain_sons.second; + + son_sets_equal = son_sets_equal && (_cur_wallet_sidechain_sons.size() == new_wallet_sons.at(sidechain).size()); + if (son_sets_equal) { + for (size_t i = 0; i < cur_wallet_sons.size(); i++) { + son_sets_equal = son_sets_equal && _cur_wallet_sidechain_sons.at(i) == new_wallet_sons.at(sidechain).at(i); + } + } } } diff --git a/libraries/chain/son_wallet_withdraw_evaluator.cpp b/libraries/chain/son_wallet_withdraw_evaluator.cpp index 2110e49d..3fb04ae2 100644 --- a/libraries/chain/son_wallet_withdraw_evaluator.cpp +++ b/libraries/chain/son_wallet_withdraw_evaluator.cpp @@ -23,9 +23,9 @@ void_result create_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_w const auto &swwo_idx = db().get_index_type().indices().get(); const auto swwo = swwo_idx.find(op.peerplays_uid); if (swwo == swwo_idx.end()) { - auto &gpo = db().get_global_properties(); + const auto &gpo = db().get_global_properties(); bool expected = false; - for (auto &si : gpo.active_sons) { + for (auto &si : gpo.active_sons.at(op.sidechain)) { if (op.son_id == si.son_id) { expected = true; break; @@ -76,8 +76,8 @@ object_id_type create_son_wallet_withdraw_evaluator::do_apply(const son_wallet_w swwo.withdraw_currency = op.withdraw_currency; swwo.withdraw_amount = op.withdraw_amount; - auto &gpo = db().get_global_properties(); - for (auto &si : gpo.active_sons) { + const auto &gpo = db().get_global_properties(); + for (auto &si : gpo.active_sons.at(op.sidechain)) { swwo.expected_reports.insert(std::make_pair(si.son_id, si.weight)); auto stats_itr = db().get_index_type().indices().get().find(si.son_id); diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 411e7515..cee74c2a 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -316,10 +316,12 @@ bool peerplays_sidechain_plugin_impl::is_active_son(son_id_type son_id) { if (son_obj == idx.end()) return false; + //! Fixme - now only bitcoin, fix according to sidechain_type + const chain::global_property_object &gpo = plugin.database().get_global_properties(); vector active_son_ids; - active_son_ids.reserve(gpo.active_sons.size()); - std::transform(gpo.active_sons.begin(), gpo.active_sons.end(), + active_son_ids.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size()); + std::transform(gpo.active_sons.at(sidechain_type::bitcoin).cbegin(), gpo.active_sons.at(sidechain_type::bitcoin).cend(), std::inserter(active_son_ids, active_son_ids.end()), [](const son_info &swi) { return swi.son_id; @@ -452,19 +454,18 @@ void peerplays_sidechain_plugin_impl::son_processing() { return; // Not synced } - chain::son_id_type scheduled_son_id = plugin.database().get_scheduled_son(1); - ilog("Scheduled SON: ${scheduled_son_id} Now: ${now} ", - ("scheduled_son_id", scheduled_son_id)("now", now)); + //! Fixme - get real scheduled_son_id according to sidechain_type + chain::son_id_type scheduled_son_id; // for the test prove that in hive scheduled son is active son chain::son_id_type scheduled_hive_son_id = plugin.database().get_scheduled_son(sidechain_type::hive ,1); - ilog("Scheduled SON[!HIVE!]: ${scheduled_son_id} Now: ${now} ", - ("scheduled_son_id", scheduled_hive_son_id)("now", now)); + ilog("Scheduled SON[!HIVE!]: ${scheduled_hive_son_id} Now: ${now} ", + ("scheduled_hive_son_id", scheduled_hive_son_id)("now", now)); // for the test prove that in hive scheduled son is active son chain::son_id_type scheduled_bitcoin_son_id = plugin.database().get_scheduled_son(sidechain_type::bitcoin ,1); - ilog("Scheduled SON[!HIVE!]: ${scheduled_son_id} Now: ${now} ", - ("scheduled_son_id", scheduled_bitcoin_son_id)("now", now)); + ilog("Scheduled SON[!HIVE!]: ${scheduled_bitcoin_son_id} Now: ${now} ", + ("scheduled_bitcoin_son_id", scheduled_bitcoin_son_id)("now", now)); for (son_id_type son_id : plugin.get_sons()) { if (plugin.is_son_deregistered(son_id)) { @@ -612,7 +613,11 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals() { const auto &idx = d.get_index_type().indices().get(); std::set sons_being_reported_down = d.get_sons_being_reported_down(); chain::son_id_type my_son_id = get_current_son_id(); - for (auto son_inf : gpo.active_sons) { + + //! Fixme - now set bitcoin + //! Do we need to separate create_son_down_proposals for different sidechain_types + + for (auto son_inf : gpo.active_sons.at(sidechain_type::bitcoin)) { if (my_son_id == son_inf.son_id || (sons_being_reported_down.find(son_inf.son_id) != sons_being_reported_down.end())) { continue; } diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index 04a0e604..09aaf323 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -904,8 +904,9 @@ void zmq_listener::handle_zmq() { // ============================================================================= -sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) : - sidechain_net_handler(_plugin, options) { +sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) + : sidechain_net_handler(_plugin, options) +{ sidechain = sidechain_type::bitcoin; if (options.count("debug-rpc-calls")) { @@ -1024,8 +1025,8 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po) const auto swo = idx.find(swo_id); if (swo != idx.end()) { - auto active_sons = gpo.active_sons; - vector wallet_sons = swo->sons; + const auto& active_sons = gpo.active_sons.at(sidechain); + vector wallet_sons = swo->sons.at(sidechain); bool son_sets_equal = (active_sons.size() == wallet_sons.size()); @@ -1036,10 +1037,10 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po) } if (son_sets_equal) { - auto active_sons = gpo.active_sons; + const auto& active_sons = gpo.active_sons.at(sidechain); vector son_pubkeys_bitcoin; for (const son_info &si : active_sons) { - son_pubkeys_bitcoin.push_back(si.sidechain_public_keys.at(sidechain_type::bitcoin)); + son_pubkeys_bitcoin.push_back(si.sidechain_public_keys.at(sidechain)); } string reply_str = create_primary_wallet_address(active_sons); @@ -1242,7 +1243,7 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po) read_transaction_data(sto->transaction, tx_hex, in_amounts, redeem_script); bitcoin_transaction tx = unpack(parse_hex(tx_hex)); - bitcoin::bytes pubkey = parse_hex(son->sidechain_public_keys.at(sidechain_type::bitcoin)); + bitcoin::bytes pubkey = parse_hex(son->sidechain_public_keys.at(sidechain)); vector sigs = read_byte_arrays_from_string(signature); for (size_t i = 0; i < tx.vin.size(); i++) { const auto &sighash_str = get_signature_hash(tx, parse_hex(redeem_script), static_cast(in_amounts[i]), i, 1, true).str(); @@ -1272,8 +1273,8 @@ void sidechain_net_handler_bitcoin::process_primary_wallet() { const auto &active_sw = swi.rbegin(); if (active_sw != swi.rend()) { - if ((active_sw->addresses.find(sidechain_type::bitcoin) == active_sw->addresses.end()) || - (active_sw->addresses.at(sidechain_type::bitcoin).empty())) { + if ((active_sw->addresses.find(sidechain) == active_sw->addresses.end()) || + (active_sw->addresses.at(sidechain).empty())) { if (proposal_exists(chain::operation::tag::value, active_sw->id)) { return; @@ -1281,7 +1282,7 @@ void sidechain_net_handler_bitcoin::process_primary_wallet() { const chain::global_property_object &gpo = database.get_global_properties(); - auto active_sons = gpo.active_sons; + const auto& active_sons = gpo.active_sons.at(sidechain); string reply_str = create_primary_wallet_address(active_sons); std::stringstream active_pw_ss(reply_str); @@ -1303,7 +1304,7 @@ void sidechain_net_handler_bitcoin::process_primary_wallet() { son_wallet_update_operation swu_op; swu_op.payer = gpo.parameters.son_account(); swu_op.son_wallet_id = active_sw->id; - swu_op.sidechain = sidechain_type::bitcoin; + swu_op.sidechain = sidechain; swu_op.address = res.str(); proposal_op.proposed_ops.emplace_back(swu_op); @@ -1318,7 +1319,7 @@ void sidechain_net_handler_bitcoin::process_primary_wallet() { stc_op.object_id = prev_sw->id; stc_op.sidechain = sidechain; stc_op.transaction = tx_str; - stc_op.signers = prev_sw->sons; + stc_op.signers = prev_sw->sons.at(sidechain); proposal_op.proposed_ops.emplace_back(stc_op); } } @@ -1344,8 +1345,8 @@ void sidechain_net_handler_bitcoin::process_sidechain_addresses() { const chain::global_property_object &gpo = database.get_global_properties(); std::vector> pubkeys; - for (auto &son : gpo.active_sons) { - std::string pub_key_str = son.sidechain_public_keys.at(sidechain_type::bitcoin); + for (auto &son : gpo.active_sons.at(sidechain)) { + std::string pub_key_str = son.sidechain_public_keys.at(sidechain); auto pubkey = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str))); pubkeys.push_back(std::make_pair(pubkey, son.weight)); } @@ -1422,7 +1423,7 @@ bool sidechain_net_handler_bitcoin::process_deposit(const son_wallet_deposit_obj stc_op.object_id = swdo.id; stc_op.sidechain = sidechain; stc_op.transaction = tx_str; - stc_op.signers = gpo.active_sons; + stc_op.signers = gpo.active_sons.at(sidechain); proposal_op.proposed_ops.emplace_back(stc_op); signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op); @@ -1466,7 +1467,7 @@ bool sidechain_net_handler_bitcoin::process_withdrawal(const son_wallet_withdraw stc_op.object_id = swwo.id; stc_op.sidechain = sidechain; stc_op.transaction = tx_str; - stc_op.signers = gpo.active_sons; + stc_op.signers = gpo.active_sons.at(sidechain); proposal_op.proposed_ops.emplace_back(stc_op); signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op); @@ -1517,7 +1518,7 @@ bool sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidechain using namespace bitcoin; std::vector> pubkey_weights; for (auto si : sto.signers) { - std::string pub_key_str = si.sidechain_public_keys.at(sidechain_type::bitcoin); + std::string pub_key_str = si.sidechain_public_keys.at(sidechain); auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str))); pubkey_weights.push_back(std::make_pair(pub_key, si.weight)); } @@ -1558,7 +1559,7 @@ std::string sidechain_net_handler_bitcoin::create_primary_wallet_address(const s std::vector> pubkey_weights; for (auto &son : son_pubkeys) { - std::string pub_key_str = son.sidechain_public_keys.at(sidechain_type::bitcoin); + std::string pub_key_str = son.sidechain_public_keys.at(sidechain); auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str))); pubkey_weights.push_back(std::make_pair(pub_key, son.weight)); } @@ -1576,7 +1577,7 @@ std::string sidechain_net_handler_bitcoin::create_primary_wallet_address(const s std::string sidechain_net_handler_bitcoin::create_primary_wallet_transaction(const son_wallet_object &prev_swo, std::string new_sw_address) { - const auto &address_data = prev_swo.addresses.find(sidechain_type::bitcoin); + const auto &address_data = prev_swo.addresses.find(sidechain); if (address_data == prev_swo.addresses.end()) { return ""; } @@ -1627,12 +1628,12 @@ std::string sidechain_net_handler_bitcoin::create_primary_wallet_transaction(con std::string sidechain_net_handler_bitcoin::create_deposit_transaction(const son_wallet_deposit_object &swdo) { const auto &idx = database.get_index_type().indices().get(); auto obj = idx.rbegin(); - if (obj == idx.rend() || obj->addresses.find(sidechain_type::bitcoin) == obj->addresses.end()) { + if (obj == idx.rend() || obj->addresses.find(sidechain) == obj->addresses.end()) { return ""; } //Get redeem script for deposit address std::string redeem_script = get_redeemscript_for_userdeposit(swdo.sidechain_from); - std::string pw_address_json = obj->addresses.find(sidechain_type::bitcoin)->second; + std::string pw_address_json = obj->addresses.find(sidechain)->second; std::stringstream ss(pw_address_json); boost::property_tree::ptree json; @@ -1668,11 +1669,11 @@ std::string sidechain_net_handler_bitcoin::create_deposit_transaction(const son_ std::string sidechain_net_handler_bitcoin::create_withdrawal_transaction(const son_wallet_withdraw_object &swwo) { const auto &idx = database.get_index_type().indices().get(); auto obj = idx.rbegin(); - if (obj == idx.rend() || obj->addresses.find(sidechain_type::bitcoin) == obj->addresses.end()) { + if (obj == idx.rend() || obj->addresses.find(sidechain) == obj->addresses.end()) { return ""; } - std::string pw_address_json = obj->addresses.find(sidechain_type::bitcoin)->second; + std::string pw_address_json = obj->addresses.find(sidechain)->second; std::stringstream ss(pw_address_json); boost::property_tree::ptree json; @@ -1847,13 +1848,13 @@ std::string sidechain_net_handler_bitcoin::get_redeemscript_for_userdeposit(cons const auto &idx = database.get_index_type().indices().get(); auto obj = idx.rbegin(); - if (obj == idx.rend() || obj->addresses.find(sidechain_type::bitcoin) == obj->addresses.end()) { + if (obj == idx.rend() || obj->addresses.find(sidechain) == obj->addresses.end()) { return ""; } std::vector> pubkey_weights; - for (auto &son : obj->sons) { - std::string pub_key_str = son.sidechain_public_keys.at(sidechain_type::bitcoin); + for (auto &son : obj->sons.at(sidechain)) { + std::string pub_key_str = son.sidechain_public_keys.at(sidechain); auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str))); pubkey_weights.push_back(std::make_pair(pub_key, son.weight)); } diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp index 0cbdef29..bc748243 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp @@ -114,8 +114,9 @@ std::string hive_node_rpc_client::get_last_irreversible_block_num() { return retrieve_value_from_reply(reply_str, "last_irreversible_block_num"); } -sidechain_net_handler_hive::sidechain_net_handler_hive(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) : - sidechain_net_handler(_plugin, options) { +sidechain_net_handler_hive::sidechain_net_handler_hive(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) + : sidechain_net_handler(_plugin, options) +{ sidechain = sidechain_type::hive; if (options.count("debug-rpc-calls")) { @@ -214,13 +215,13 @@ bool sidechain_net_handler_hive::process_proposal(const proposal_object &po) { if (swo != idx.end()) { auto active_sons = gpo.active_sons; - vector wallet_sons = swo->sons; + vector wallet_sons = swo->sons.at(sidechain); bool son_sets_equal = (active_sons.size() == wallet_sons.size()); if (son_sets_equal) { for (size_t i = 0; i < active_sons.size(); i++) { - son_sets_equal = son_sets_equal && active_sons.at(i) == wallet_sons.at(i); + son_sets_equal = son_sets_equal && active_sons.at(sidechain).at(i) == wallet_sons.at(i); } } @@ -487,7 +488,7 @@ void sidechain_net_handler_hive::process_primary_wallet() { const chain::global_property_object &gpo = database.get_global_properties(); - auto active_sons = gpo.active_sons; + const auto& active_sons = gpo.active_sons.at(sidechain); fc::flat_map account_auths; uint32_t total_weight = 0; for (const auto &active_son : active_sons) { @@ -547,7 +548,7 @@ void sidechain_net_handler_hive::process_primary_wallet() { stc_op.object_id = active_sw->id; stc_op.sidechain = sidechain; stc_op.transaction = tx_str; - stc_op.signers = gpo.active_sons; + stc_op.signers = gpo.active_sons.at(sidechain); proposal_op.proposed_ops.emplace_back(stc_op); @@ -704,7 +705,7 @@ bool sidechain_net_handler_hive::process_withdrawal(const son_wallet_withdraw_ob stc_op.object_id = swwo.id; stc_op.sidechain = sidechain; stc_op.transaction = tx_str; - stc_op.signers = gpo.active_sons; + stc_op.signers = gpo.active_sons.at(sidechain); proposal_op.proposed_ops.emplace_back(stc_op); signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_peerplays.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_peerplays.cpp index d5a9ec32..0b8461cb 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_peerplays.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_peerplays.cpp @@ -197,7 +197,7 @@ bool sidechain_net_handler_peerplays::process_deposit(const son_wallet_deposit_o stc_op.object_id = swdo.id; stc_op.sidechain = sidechain; stc_op.transaction = tx_str; - stc_op.signers = gpo.active_sons; + stc_op.signers = gpo.active_sons.at(sidechain); proposal_create_operation proposal_op; proposal_op.fee_paying_account = plugin.get_current_son_object().son_account; diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 6d7af8d1..0b1789a6 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -2232,68 +2232,80 @@ public: } FC_CAPTURE_AND_RETHROW( (owner_account) ) } map list_active_sons() - { try { - global_property_object gpo = get_global_properties(); - vector son_ids; - son_ids.reserve(gpo.active_sons.size()); - std::transform(gpo.active_sons.begin(), gpo.active_sons.end(), - std::inserter(son_ids, son_ids.end()), - [](const son_info& swi) { - return swi.son_id; - }); - std::vector> son_objects = _remote_db->get_sons(son_ids); - vector owners; - for(auto obj: son_objects) + { + try { - std::string acc_id = account_id_to_string(obj->son_account); - owners.push_back(acc_id); + //! Fixme - now only bitcoin, fix according to sidechain_type + + const global_property_object& gpo = get_global_properties(); + vector son_ids; + son_ids.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size()); + std::transform(gpo.active_sons.at(sidechain_type::bitcoin).cbegin(), gpo.active_sons.at(sidechain_type::bitcoin).cend(), + std::inserter(son_ids, son_ids.end()), + [](const son_info& swi) { + return swi.son_id; + }); + std::vector> son_objects = _remote_db->get_sons(son_ids); + vector owners; + for(auto obj: son_objects) + { + std::string acc_id = account_id_to_string(obj->son_account); + owners.push_back(acc_id); + } + vector< optional< account_object> > accs = _remote_db->get_accounts(owners); + std::remove_if(son_objects.begin(), son_objects.end(), + [](const fc::optional& obj) -> bool { return obj.valid(); }); + map result; + std::transform(accs.begin(), accs.end(), son_objects.begin(), + std::inserter(result, result.end()), + [](fc::optional& acct, fc::optional son) { + FC_ASSERT(acct, "Invalid active SONs list in global properties."); + return std::make_pair(string(acct->name), std::move(son->id)); + }); + return result; } - vector< optional< account_object> > accs = _remote_db->get_accounts(owners); - std::remove_if(son_objects.begin(), son_objects.end(), - [](const fc::optional& obj) -> bool { return obj.valid(); }); - map result; - std::transform(accs.begin(), accs.end(), son_objects.begin(), - std::inserter(result, result.end()), - [](fc::optional& acct, fc::optional son) { - FC_ASSERT(acct, "Invalid active SONs list in global properties."); - return std::make_pair(string(acct->name), std::move(son->id)); - }); - return result; - } FC_CAPTURE_AND_RETHROW() } + FC_CAPTURE_AND_RETHROW() + } map get_son_network_status() - { try { - global_property_object gpo = get_global_properties(); - vector son_ids; - son_ids.reserve(gpo.active_sons.size()); - std::transform(gpo.active_sons.begin(), gpo.active_sons.end(), - std::inserter(son_ids, son_ids.end()), - [](const son_info& swi) { - return swi.son_id; - }); + { + try + { + //! Fixme - now only bitcoin, fix according to sidechain_type - map result; - std::vector> son_objects = _remote_db->get_sons(son_ids); - for(auto son_obj: son_objects) { - string status; - if (son_obj) { - son_statistics_object sso = get_object(son_obj->statistics); - if (sso.last_active_timestamp + fc::seconds(gpo.parameters.son_heartbeat_frequency()) > time_point::now()) { - status = "OK, regular SON heartbeat"; - } else { - if (sso.last_active_timestamp + fc::seconds(gpo.parameters.son_down_time()) > time_point::now()) { - status = "OK, irregular SON heartbeat, but not triggering SON down proposal"; + const global_property_object& gpo = get_global_properties(); + vector son_ids; + son_ids.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size()); + std::transform(gpo.active_sons.at(sidechain_type::bitcoin).cbegin(), gpo.active_sons.at(sidechain_type::bitcoin).cend(), + std::inserter(son_ids, son_ids.end()), + [](const son_info& swi) { + return swi.son_id; + }); + + map result; + std::vector> son_objects = _remote_db->get_sons(son_ids); + for(auto son_obj: son_objects) { + string status; + if (son_obj) { + son_statistics_object sso = get_object(son_obj->statistics); + if (sso.last_active_timestamp + fc::seconds(gpo.parameters.son_heartbeat_frequency()) > time_point::now()) { + status = "OK, regular SON heartbeat"; } else { - status = "NOT OK, irregular SON heartbeat, triggering SON down proposal"; + if (sso.last_active_timestamp + fc::seconds(gpo.parameters.son_down_time()) > time_point::now()) { + status = "OK, irregular SON heartbeat, but not triggering SON down proposal"; + } else { + status = "NOT OK, irregular SON heartbeat, triggering SON down proposal"; + } } + } else { + status = "NOT OK, invalid SON id"; } - } else { - status = "NOT OK, invalid SON id"; + result[son_obj->id] = status; } - result[son_obj->id] = status; + return result; } - return result; - } FC_CAPTURE_AND_RETHROW() } + FC_CAPTURE_AND_RETHROW() + } optional get_active_son_wallet() { try { diff --git a/tests/tests/sidechain_addresses_test.cpp b/tests/tests/sidechain_addresses_test.cpp index 755ad37f..1ee08c6d 100644 --- a/tests/tests/sidechain_addresses_test.cpp +++ b/tests/tests/sidechain_addresses_test.cpp @@ -87,7 +87,8 @@ BOOST_AUTO_TEST_CASE( sidechain_address_update_test ) { { son_info sinfo; sinfo.son_id = son.id; - _gpo.active_sons.push_back(sinfo); + _gpo.active_sons[sidechain_type::bitcoin].push_back(sinfo); + _gpo.active_sons[sidechain_type::hive].push_back(sinfo); }); generate_block(); { diff --git a/tests/tests/son_operations_tests.cpp b/tests/tests/son_operations_tests.cpp index 1e3bb7e4..17585ea6 100644 --- a/tests/tests/son_operations_tests.cpp +++ b/tests/tests/son_operations_tests.cpp @@ -668,7 +668,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { PUSH_TX( db, trx, ~0); generate_block(); trx.clear(); - BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime, op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch()); + BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::bitcoin), op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch()); + BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::hive), op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch()); downtime += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch(); BOOST_CHECK( obj->status == son_status::inactive); BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts); @@ -685,7 +686,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { { son_info son_inf; son_inf.son_id = son_id_type(0); - _gpo.active_sons.push_back(son_inf); + _gpo.active_sons[sidechain_type::bitcoin].push_back(son_inf); + _gpo.active_sons[sidechain_type::hive].push_back(son_inf); }); { @@ -702,7 +704,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { PUSH_TX( db, trx, ~0); generate_block(); trx.clear(); - BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime, downtime + op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch()); + BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::bitcoin), downtime + op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch()); + BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::hive), downtime + op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch()); downtime += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch(); BOOST_CHECK( obj->status == son_status::active); BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts); @@ -722,7 +725,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { PUSH_TX( db, trx, ~0); generate_block(); trx.clear(); - BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime, downtime); + BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::bitcoin), downtime); + BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::hive), downtime); BOOST_CHECK( obj->status == son_status::active); BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts); } diff --git a/tests/tests/son_wallet_tests.cpp b/tests/tests/son_wallet_tests.cpp index cef29b54..c6a6e809 100644 --- a/tests/tests/son_wallet_tests.cpp +++ b/tests/tests/son_wallet_tests.cpp @@ -154,13 +154,14 @@ BOOST_AUTO_TEST_CASE( son_wallet_recreate_test ) { op.payer = db.get_global_properties().parameters.son_account(); + //! Fixme - add hive tests { son_info si; si.son_id = son_id_type(0); si.weight = 1000; si.signing_key = alice_public_key; si.sidechain_public_keys[sidechain_type::bitcoin] = ""; - op.sons.push_back(si); + op.sons[sidechain_type::bitcoin].push_back(si); } { @@ -169,7 +170,7 @@ BOOST_AUTO_TEST_CASE( son_wallet_recreate_test ) { si.weight = 1000; si.signing_key = bob_public_key; si.sidechain_public_keys[sidechain_type::bitcoin] = ""; - op.sons.push_back(si); + op.sons[sidechain_type::bitcoin].push_back(si); } trx.operations.push_back(op); -- 2.45.2 From 32d67b2c30f0814eec9798180d5bdccdc8279efe Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Mon, 28 Mar 2022 16:01:00 +0300 Subject: [PATCH 08/15] #308 - delete sidechain_type map for public_key in son_info (we store son_info as map itself) --- libraries/chain/db_maint.cpp | 5 +++-- .../chain/include/graphene/chain/son_info.hpp | 17 +++-------------- .../sidechain_net_handler_bitcoin.cpp | 15 ++++++--------- .../sidechain_net_handler_hive.cpp | 4 ++-- tests/tests/son_wallet_tests.cpp | 4 ++-- 5 files changed, 16 insertions(+), 29 deletions(-) diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index 4df01acf..688cd984 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -787,13 +787,14 @@ void database::update_active_sons() flat_map > new_active_sons; const auto &acc = get(gpo.parameters.son_account()); for( const auto& sidechain_sons : sons ){ + const auto& sidechain = sidechain_sons.first; for( const son_object& son : sidechain_sons.second ) { son_info swi; swi.son_id = son.id; swi.weight = acc.active.account_auths.at(son.son_account); swi.signing_key = son.signing_key; - swi.sidechain_public_keys = son.sidechain_public_keys; - new_active_sons[sidechain_sons.first].push_back(swi); + swi.public_key = son.sidechain_public_keys.at(sidechain); + new_active_sons[sidechain].push_back(swi); } } diff --git a/libraries/chain/include/graphene/chain/son_info.hpp b/libraries/chain/include/graphene/chain/son_info.hpp index e32c9bd5..75e58319 100644 --- a/libraries/chain/include/graphene/chain/son_info.hpp +++ b/libraries/chain/include/graphene/chain/son_info.hpp @@ -14,26 +14,15 @@ namespace graphene { namespace chain { son_id_type son_id; weight_type weight = 0; public_key_type signing_key; - flat_map sidechain_public_keys; //! Fixme - delete map from here + string public_key; bool operator==(const son_info& rhs) const { bool son_sets_equal = (son_id == rhs.son_id) && (weight == rhs.weight) && (signing_key == rhs.signing_key) && - (sidechain_public_keys.size() == rhs.sidechain_public_keys.size()); + (public_key == rhs.public_key); - if (son_sets_equal) { - bool sidechain_public_keys_equal = true; - for (size_t i = 0; i < sidechain_public_keys.size(); i++) { - const auto lhs_scpk = sidechain_public_keys.nth(i); - const auto rhs_scpk = rhs.sidechain_public_keys.nth(i); - sidechain_public_keys_equal = sidechain_public_keys_equal && - (lhs_scpk->first == rhs_scpk->first) && - (lhs_scpk->second == rhs_scpk->second); - } - son_sets_equal = son_sets_equal && sidechain_public_keys_equal; - } return son_sets_equal; } }; @@ -44,4 +33,4 @@ FC_REFLECT( graphene::chain::son_info, (son_id) (weight) (signing_key) - (sidechain_public_keys) ) + (public_key) ) diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index 09aaf323..2970b011 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -1040,7 +1040,7 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po) const auto& active_sons = gpo.active_sons.at(sidechain); vector son_pubkeys_bitcoin; for (const son_info &si : active_sons) { - son_pubkeys_bitcoin.push_back(si.sidechain_public_keys.at(sidechain)); + son_pubkeys_bitcoin.push_back(si.public_key); } string reply_str = create_primary_wallet_address(active_sons); @@ -1346,8 +1346,7 @@ void sidechain_net_handler_bitcoin::process_sidechain_addresses() { const chain::global_property_object &gpo = database.get_global_properties(); std::vector> pubkeys; for (auto &son : gpo.active_sons.at(sidechain)) { - std::string pub_key_str = son.sidechain_public_keys.at(sidechain); - auto pubkey = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str))); + auto pubkey = fc::ecc::public_key(create_public_key_data(parse_hex(son.public_key))); pubkeys.push_back(std::make_pair(pubkey, son.weight)); } @@ -1518,8 +1517,8 @@ bool sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidechain using namespace bitcoin; std::vector> pubkey_weights; for (auto si : sto.signers) { - std::string pub_key_str = si.sidechain_public_keys.at(sidechain); - auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str))); + //! Fixme - check public_key here + auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(si.public_key))); pubkey_weights.push_back(std::make_pair(pub_key, si.weight)); } btc_weighted_multisig_address addr(pubkey_weights, network_type); @@ -1559,8 +1558,7 @@ std::string sidechain_net_handler_bitcoin::create_primary_wallet_address(const s std::vector> pubkey_weights; for (auto &son : son_pubkeys) { - std::string pub_key_str = son.sidechain_public_keys.at(sidechain); - auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str))); + auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(son.public_key))); pubkey_weights.push_back(std::make_pair(pub_key, son.weight)); } @@ -1854,8 +1852,7 @@ std::string sidechain_net_handler_bitcoin::get_redeemscript_for_userdeposit(cons std::vector> pubkey_weights; for (auto &son : obj->sons.at(sidechain)) { - std::string pub_key_str = son.sidechain_public_keys.at(sidechain); - auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str))); + auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(son.public_key))); pubkey_weights.push_back(std::make_pair(pub_key, son.weight)); } auto user_pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(addr_itr->deposit_public_key))); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp index bc748243..c03d2eb3 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp @@ -252,7 +252,7 @@ bool sidechain_net_handler_hive::process_proposal(const proposal_object &po) { uint32_t total_weight = 0; for (const auto &wallet_son : wallet_sons) { total_weight = total_weight + wallet_son.weight; - account_auths[wallet_son.sidechain_public_keys.at(sidechain)] = wallet_son.weight; + account_auths[wallet_son.public_key] = wallet_son.weight; } std::string memo_key = node_rpc_client->get_account_memo_key("son-account"); @@ -493,7 +493,7 @@ void sidechain_net_handler_hive::process_primary_wallet() { uint32_t total_weight = 0; for (const auto &active_son : active_sons) { total_weight = total_weight + active_son.weight; - account_auths[active_son.sidechain_public_keys.at(sidechain)] = active_son.weight; + account_auths[active_son.public_key] = active_son.weight; } std::string memo_key = node_rpc_client->get_account_memo_key("son-account"); diff --git a/tests/tests/son_wallet_tests.cpp b/tests/tests/son_wallet_tests.cpp index c6a6e809..4b1e4fe2 100644 --- a/tests/tests/son_wallet_tests.cpp +++ b/tests/tests/son_wallet_tests.cpp @@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE( son_wallet_recreate_test ) { si.son_id = son_id_type(0); si.weight = 1000; si.signing_key = alice_public_key; - si.sidechain_public_keys[sidechain_type::bitcoin] = ""; + si.public_key = ""; op.sons[sidechain_type::bitcoin].push_back(si); } @@ -169,7 +169,7 @@ BOOST_AUTO_TEST_CASE( son_wallet_recreate_test ) { si.son_id = son_id_type(1); si.weight = 1000; si.signing_key = bob_public_key; - si.sidechain_public_keys[sidechain_type::bitcoin] = ""; + si.public_key = ""; op.sons[sidechain_type::bitcoin].push_back(si); } -- 2.45.2 From 467522f7d87814fee2012adf2eddd81316a13ea6 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Wed, 30 Mar 2022 15:31:41 +0300 Subject: [PATCH 09/15] #308 - son_status as map --- libraries/chain/db_getter.cpp | 22 +++- libraries/chain/db_maint.cpp | 37 ++++-- .../chain/include/graphene/chain/database.hpp | 1 + .../include/graphene/chain/son_object.hpp | 10 +- libraries/chain/son_evaluator.cpp | 123 +++++++++++++----- .../peerplays_sidechain_plugin.cpp | 35 ++++- tests/cli/son.cpp | 18 ++- tests/tests/son_operations_tests.cpp | 36 +++-- 8 files changed, 200 insertions(+), 82 deletions(-) diff --git a/libraries/chain/db_getter.cpp b/libraries/chain/db_getter.cpp index 54126320..f2c03140 100644 --- a/libraries/chain/db_getter.cpp +++ b/libraries/chain/db_getter.cpp @@ -222,11 +222,18 @@ std::set database::get_sons_to_be_deregistered() for( auto& son : son_idx ) { - if(son.status == son_status::in_maintenance) + bool need_to_be_deregistered = true; + for(const auto& status : son.statuses) + { + if(status.second != son_status::in_maintenance) + need_to_be_deregistered = false; + } + + if(need_to_be_deregistered) { auto stats = son.statistics(*this); - // TODO : We need to add a function that returns if we can deregister SON - // i.e. with introduction of PW code, we have to make a decision if the SON + // TODO : We need to add a function that returns if we can deregister SON + // i.e. with introduction of PW code, we have to make a decision if the SON // is needed for release of funds from the PW if(head_block_time() - stats.last_down_timestamp >= fc::seconds(get_global_properties().parameters.son_deregister_time())) { @@ -289,7 +296,14 @@ bool database::is_son_dereg_valid( son_id_type son_id ) return false; } - return (son->status == son_status::in_maintenance && + bool status_in_maintenance = true; + for(const auto& status : son->statuses) + { + if(status.second != son_status::in_maintenance) + status_in_maintenance = false; + } + + return (status_in_maintenance && (head_block_time() - son->statistics(*this).last_down_timestamp >= fc::seconds(get_global_properties().parameters.son_deregister_time()))); } diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index 688cd984..cf5f2f64 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -84,7 +84,7 @@ vector> database::sort_votable_objects< std::vector> refs; for( auto& son : all_sons ) { - if(son.has_valid_config(head_block_time()) && son.status != son_status::deregistered) + if(son.has_valid_config(head_block_time()) && son.statuses.at(sidechain) != son_status::deregistered) { refs.push_back(std::cref(son)); } @@ -186,6 +186,7 @@ void database::pay_sons() const dynamic_global_property_object& dpo = get_dynamic_global_properties(); // Current requirement is that we have to pay every 24 hours, so the following check if( dpo.son_budget.value > 0 && ((now - dpo.last_son_payout_time) >= fc::seconds(get_global_properties().parameters.son_pay_time()))) { + //! Fixme - sort_votable_objects only for bitcoin auto sons = sort_votable_objects(sidechain_type::bitcoin, get_global_properties().parameters.maximum_son_count()); // After SON2 HF uint64_t total_votes = 0; @@ -353,9 +354,9 @@ void database::update_son_statuses( const flat_mapstatus == son_status::active) { + if (son->statuses.at(sidechain) == son_status::active) { modify(*son, [&](son_object &obj) { - obj.status = son_status::inactive; + obj.statuses.at(sidechain) = son_status::inactive; }); } } @@ -373,9 +374,9 @@ void database::update_son_statuses( const flat_mapstatus == son_status::inactive) { + if (son->statuses.at(sidechain) == son_status::inactive) { modify(*son, [&](son_object &obj) { - obj.status = son_status::active; + obj.statuses.at(sidechain) = son_status::active; }); } } @@ -385,7 +386,7 @@ void database::update_son_statuses( const flat_mapstatus)("sv", son->total_votes)); + ilog("${s}, status = ${ss}, total_votes = ${sv}", ("s", new_sons[i])("ss", son->statuses.at(sidechain))("sv", son->total_votes)); } if (sons_to_remove.size() > 0) { @@ -723,19 +724,29 @@ void database::update_active_sons() auto& local_vote_buffer_ref = _vote_tally_buffer; for( const son_object& son : all_sons ) { - if(son.status == son_status::request_maintenance) + bool status_in_maintenance = true; + for(const auto& status: son.statuses) { - auto& stats = son.statistics(*this); - modify( stats, [&]( son_statistics_object& _s){ - _s.last_down_timestamp = head_block_time(); - }); + if(status.second != son_status::in_maintenance) + status_in_maintenance = false; } + if(status_in_maintenance) + { + auto &stats = son.statistics(*this); + modify(stats, [&](son_statistics_object &_s) { + _s.last_down_timestamp = head_block_time(); + }); + } + modify( son, [local_vote_buffer_ref]( son_object& obj ){ for(const auto& sidechain_vote_id : obj.sidechain_vote_ids ){ obj.total_votes[sidechain_vote_id.first] = local_vote_buffer_ref[sidechain_vote_id.second]; } - if(obj.status == son_status::request_maintenance) - obj.status = son_status::in_maintenance; + for(auto& status: obj.statuses) + { + if (status.second == son_status::request_maintenance) + status.second = son_status::in_maintenance; + } }); } diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index 0d2c330f..643bf477 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -513,6 +513,7 @@ namespace graphene { namespace chain { template vector> sort_votable_objects(size_t count)const; + //! Fixme return map here template vector> sort_votable_objects(sidechain_type sidechain, size_t count)const; diff --git a/libraries/chain/include/graphene/chain/son_object.hpp b/libraries/chain/include/graphene/chain/son_object.hpp index 24891d91..31094563 100644 --- a/libraries/chain/include/graphene/chain/son_object.hpp +++ b/libraries/chain/include/graphene/chain/son_object.hpp @@ -35,11 +35,11 @@ namespace graphene { namespace chain { // Transactions signed since the last son payouts flat_map txs_signed; // Total Voted Active time i.e. duration selected as part of voted active SONs - flat_map total_voted_time; + flat_map total_voted_time; //! Fixme - check if we need map of sidechain_type here // Total Downtime barring the current down time in seconds, used for stats to present to user - flat_map total_downtime; + flat_map total_downtime; //! Fixme - check if we need map of sidechain_type here // Current Interval Downtime since last maintenance - flat_map current_interval_downtime; + flat_map current_interval_downtime; //! Fixme - check if we need map of sidechain_type here // Down timestamp, if son status is in_maintenance use this fc::time_point_sec last_down_timestamp; // Last Active heartbeat timestamp @@ -71,7 +71,7 @@ namespace graphene { namespace chain { public_key_type signing_key; vesting_balance_id_type pay_vb; son_statistics_id_type statistics; - son_status status = son_status::inactive; //! Fixme -> as map of sidechain_type + flat_map statuses; flat_map sidechain_public_keys; void pay_son_fee(share_type pay, database& db); @@ -132,7 +132,7 @@ FC_REFLECT_DERIVED( graphene::chain::son_object, (graphene::db::object), (signing_key) (pay_vb) (statistics) - (status) + (statuses) (sidechain_public_keys) ) diff --git a/libraries/chain/son_evaluator.cpp b/libraries/chain/son_evaluator.cpp index 903b171b..930c384a 100644 --- a/libraries/chain/son_evaluator.cpp +++ b/libraries/chain/son_evaluator.cpp @@ -97,7 +97,8 @@ object_id_type update_son_evaluator::do_apply(const son_update_operation& op) if(op.new_signing_key.valid()) so.signing_key = *op.new_signing_key; if(op.new_sidechain_public_keys.valid()) so.sidechain_public_keys = *op.new_sidechain_public_keys; if(op.new_pay_vb.valid()) so.pay_vb = *op.new_pay_vb; - if(so.status == son_status::deregistered) so.status = son_status::inactive; + for(auto& status : so.statuses) + if(status.second == son_status::deregistered) status.second = son_status::inactive; }); } return op.son_id; @@ -130,7 +131,8 @@ void_result deregister_son_evaluator::do_apply(const son_deregister_operation& o }); db().modify(*son, [&op](son_object &so) { - so.status = son_status::deregistered; + for(auto& status : so.statuses) + status.second = son_status::deregistered; }); auto stats_obj = ss_idx.find(son->statistics); @@ -147,12 +149,18 @@ void_result son_heartbeat_evaluator::do_evaluate(const son_heartbeat_operation& { try { FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); // can be removed after HF date pass const auto& idx = db().get_index_type().indices().get(); - auto itr = idx.find(op.son_id); + const auto itr = idx.find(op.son_id); FC_ASSERT( itr != idx.end() ); FC_ASSERT(itr->son_account == op.owner_account); auto stats = itr->statistics( db() ); // Inactive SONs need not send heartbeats - FC_ASSERT((itr->status == son_status::active) || (itr->status == son_status::in_maintenance) || (itr->status == son_status::request_maintenance), "Inactive SONs need not send heartbeats"); + bool status_need_to_send_heartbeats = false; + for(const auto& status : itr->statuses) + { + if( (status.second == son_status::active) || (status.second == son_status::in_maintenance) || (status.second == son_status::request_maintenance) ) + status_need_to_send_heartbeats = true; + } + FC_ASSERT(status_need_to_send_heartbeats, "Inactive SONs need not send heartbeats"); // Account for network delays fc::time_point_sec min_ts = db().head_block_time() - fc::seconds(5 * db().block_interval()); // Account for server ntp sync difference @@ -167,7 +175,7 @@ void_result son_heartbeat_evaluator::do_evaluate(const son_heartbeat_operation& object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation& op) { try { const auto& idx = db().get_index_type().indices().get(); - auto itr = idx.find(op.son_id); + const auto itr = idx.find(op.son_id); if(itr != idx.end()) { const global_property_object& gpo = db().get_global_properties(); @@ -184,27 +192,27 @@ object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation& return swi.son_id; }); - auto it_son = std::find(active_son_ids.begin(), active_son_ids.end(), op.son_id); + const auto it_son = std::find(active_son_ids.begin(), active_son_ids.end(), op.son_id); bool is_son_active = true; if (it_son == active_son_ids.end()) { is_son_active = false; } - if (itr->status == son_status::in_maintenance) { + if (itr->statuses.at(sidechain) == son_status::in_maintenance) { db().modify(itr->statistics(db()), [&](son_statistics_object &sso) { sso.current_interval_downtime[sidechain] += op.ts.sec_since_epoch() - sso.last_down_timestamp.sec_since_epoch(); sso.last_active_timestamp = op.ts; }); - db().modify(*itr, [&is_son_active](son_object &so) { + db().modify(*itr, [&is_son_active, &sidechain](son_object &so) { if (is_son_active) { - so.status = son_status::active; + so.statuses[sidechain] = son_status::active; } else { - so.status = son_status::inactive; + so.statuses[sidechain] = son_status::inactive; } }); - } else if ((itr->status == son_status::active) || (itr->status == son_status::request_maintenance)) { + } else if ((itr->statuses.at(sidechain) == son_status::active) || (itr->statuses.at(sidechain) == son_status::request_maintenance)) { db().modify(itr->statistics(db()), [&](son_statistics_object &sso) { sso.last_active_timestamp = op.ts; }); @@ -220,9 +228,15 @@ void_result son_report_down_evaluator::do_evaluate(const son_report_down_operati FC_ASSERT(op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer."); const auto& idx = db().get_index_type().indices().get(); FC_ASSERT( idx.find(op.son_id) != idx.end() ); - auto itr = idx.find(op.son_id); - auto stats = itr->statistics( db() ); - FC_ASSERT(itr->status == son_status::active || itr->status == son_status::request_maintenance, "Inactive/Deregistered/in_maintenance SONs cannot be reported on as down"); + const auto itr = idx.find(op.son_id); + const auto stats = itr->statistics( db() ); + bool status_need_to_report_down = false; + for(const auto& status : itr->statuses) + { + if( (status.second == son_status::active) || (status.second == son_status::request_maintenance) ) + status_need_to_report_down = true; + } + FC_ASSERT(status_need_to_report_down, "Inactive/Deregistered/in_maintenance SONs cannot be reported on as down"); FC_ASSERT(op.down_ts >= stats.last_active_timestamp, "down_ts should be greater than last_active_timestamp"); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } @@ -230,19 +244,28 @@ void_result son_report_down_evaluator::do_evaluate(const son_report_down_operati object_id_type son_report_down_evaluator::do_apply(const son_report_down_operation& op) { try { const auto& idx = db().get_index_type().indices().get(); - auto itr = idx.find(op.son_id); + const auto itr = idx.find(op.son_id); if(itr != idx.end()) { - if ((itr->status == son_status::active) || (itr->status == son_status::request_maintenance)) { - db().modify( itr->statistics( db() ), [&]( son_statistics_object& sso ) - { - sso.last_down_timestamp = op.down_ts; - }); + bool status_report_down = true; - db().modify(*itr, [&op](son_object &so) { - so.status = son_status::in_maintenance; - }); - } + for( const auto& status : itr->statuses ) { + const auto& sidechain = status.first; + + if ((status.second == son_status::active) || (status.second == son_status::request_maintenance)) { + db().modify(*itr, [&sidechain](son_object &so) { + so.statuses[sidechain] = son_status::in_maintenance; + }); + } + else + status_report_down = false; + } + + if(status_report_down) { + db().modify(itr->statistics(db()), [&](son_statistics_object &sso) { + sso.last_down_timestamp = op.down_ts; + }); + } } return op.son_id; } FC_CAPTURE_AND_RETHROW( (op) ) } @@ -256,9 +279,19 @@ void_result son_maintenance_evaluator::do_evaluate(const son_maintenance_operati FC_ASSERT( itr != idx.end() ); // Inactive SONs can't go to maintenance, toggle between active and request_maintenance states if(op.request_type == son_maintenance_request_type::request_maintenance) { - FC_ASSERT(itr->status == son_status::active, "Inactive SONs can't request for maintenance"); - } else if(op.request_type == son_maintenance_request_type::cancel_request_maintenance) { - FC_ASSERT(itr->status == son_status::request_maintenance, "Only maintenance requested SONs can cancel the request"); + bool status_active = false; + for(const auto& status : itr->statuses) { + if( (status.second == son_status::active) ) + status_active = true; + } + FC_ASSERT(status_active, "Inactive SONs can't request for maintenance"); + } else if(op.request_type == son_maintenance_request_type::cancel_request_maintenance) { + bool status_request_maintenance = false; + for(const auto& status : itr->statuses) { + if( (status.second == son_status::request_maintenance) ) + status_request_maintenance = true; + } + FC_ASSERT(status_request_maintenance, "Only maintenance requested SONs can cancel the request"); } else { FC_ASSERT(false, "Invalid maintenance operation"); } @@ -271,15 +304,33 @@ object_id_type son_maintenance_evaluator::do_apply(const son_maintenance_operati auto itr = idx.find(op.son_id); if(itr != idx.end()) { - if(itr->status == son_status::active && op.request_type == son_maintenance_request_type::request_maintenance) { - db().modify(*itr, [](son_object &so) { - so.status = son_status::request_maintenance; - }); - } else if(itr->status == son_status::request_maintenance && op.request_type == son_maintenance_request_type::cancel_request_maintenance) { - db().modify(*itr, [](son_object &so) { - so.status = son_status::active; - }); - } + bool status_active = false; + for(const auto& status : itr->statuses) { + if( (status.second == son_status::active) ) + status_active = true; + } + if(status_active && op.request_type == son_maintenance_request_type::request_maintenance) { + db().modify(*itr, [](son_object &so) { + for(auto& status : so.statuses) { + status.second = son_status::request_maintenance; + } + }); + } + else + { + bool status_request_maintenance = false; + for(const auto& status : itr->statuses) { + if( (status.second == son_status::request_maintenance) ) + status_request_maintenance = true; + } + if(status_request_maintenance && op.request_type == son_maintenance_request_type::cancel_request_maintenance) { + db().modify(*itr, [](son_object &so) { + for(auto& status : so.statuses) { + status.second = son_status::active; + } + }); + } + } } return op.son_id; } FC_CAPTURE_AND_RETHROW( (op) ) } diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index cee74c2a..80bebc59 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -338,7 +338,13 @@ bool peerplays_sidechain_plugin_impl::is_son_deregistered(son_id_type son_id) { if (son_obj == idx.end()) return true; - if (son_obj->status == chain::son_status::deregistered) { + bool status_deregistered = true; + for(const auto& status : son_obj->statuses) { + if( (status.second != son_status::deregistered) ) + status_deregistered = false; + } + + if (status_deregistered) { return true; } @@ -364,8 +370,13 @@ bool peerplays_sidechain_plugin_impl::is_son_down_op_valid(const chain::operatio fc::time_point_sec last_maintenance_time = dgpo.next_maintenance_time - gpo.parameters.maintenance_interval; fc::time_point_sec last_active_ts = ((stats.last_active_timestamp > last_maintenance_time) ? stats.last_active_timestamp : last_maintenance_time); int64_t down_threshold = gpo.parameters.son_down_time(); - if (((son_obj->status == chain::son_status::active) || (son_obj->status == chain::son_status::request_maintenance)) && - ((fc::time_point::now() - last_active_ts) > fc::seconds(down_threshold))) { + + bool status_son_down_op_valid = true; + for(const auto& status : son_obj->statuses) { + if( (status.second != son_status::active) && (status.second != son_status::request_maintenance) ) + status_son_down_op_valid = false; + } + if ((status_son_down_op_valid) && ((fc::time_point::now() - last_active_ts) > fc::seconds(down_threshold))) { return true; } return false; @@ -400,7 +411,14 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() { chain::database &d = plugin.database(); for (son_id_type son_id : sons) { - if (is_active_son(son_id) || get_son_object(son_id).status == chain::son_status::in_maintenance) { + const auto& son_obj = get_son_object(son_id); + bool status_in_maintenance= false; + for(const auto& status : son_obj.statuses) { + if( (status.second == son_status::in_maintenance) ) + status_in_maintenance = true; + } + + if (is_active_son(son_id) || status_in_maintenance) { ilog("Sending heartbeat for SON ${son}", ("son", son_id)); chain::son_heartbeat_operation op; @@ -626,8 +644,13 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals() { fc::time_point_sec last_maintenance_time = dgpo.next_maintenance_time - gpo.parameters.maintenance_interval; fc::time_point_sec last_active_ts = ((stats.last_active_timestamp > last_maintenance_time) ? stats.last_active_timestamp : last_maintenance_time); int64_t down_threshold = gpo.parameters.son_down_time(); - if (((son_obj->status == chain::son_status::active) || (son_obj->status == chain::son_status::request_maintenance)) && - ((fc::time_point::now() - last_active_ts) > fc::seconds(down_threshold))) { + + bool status_son_down_valid = true; + for(const auto& status : son_obj->statuses) { + if( (status.second != son_status::active) && (status.second != son_status::request_maintenance) ) + status_son_down_valid = false; + } + if ((status_son_down_valid) && ((fc::time_point::now() - last_active_ts) > fc::seconds(down_threshold))) { ilog("Sending son down proposal for ${t} from ${s}", ("t", std::string(object_id_type(son_obj->id)))("s", std::string(object_id_type(my_son_id)))); chain::proposal_create_operation op = create_son_down_proposal(son_inf.son_id, last_active_ts); chain::signed_transaction trx = d.create_signed_transaction(plugin.get_private_key(get_son_object(my_son_id).signing_key), op); diff --git a/tests/cli/son.cpp b/tests/cli/son.cpp index 8e448143..3fd9909a 100644 --- a/tests/cli/son.cpp +++ b/tests/cli/son.cpp @@ -858,7 +858,8 @@ BOOST_AUTO_TEST_CASE( maintenance_test ) BOOST_CHECK(generate_maintenance_block()); son_object son_obj = con.wallet_api_ptr->get_son(name); - BOOST_CHECK(son_obj.status == son_status::active); + BOOST_CHECK(son_obj.statuses.at(sidechain_type::bitcoin) == son_status::active); + BOOST_CHECK(son_obj.statuses.at(sidechain_type::hive) == son_status::active); // put SON in maintenance mode con.wallet_api_ptr->request_son_maintenance(name, true); @@ -866,7 +867,8 @@ BOOST_AUTO_TEST_CASE( maintenance_test ) // check SON is in request_maintenance son_obj = con.wallet_api_ptr->get_son(name); - BOOST_CHECK(son_obj.status == son_status::request_maintenance); + BOOST_CHECK(son_obj.statuses.at(sidechain_type::bitcoin) == son_status::request_maintenance); + BOOST_CHECK(son_obj.statuses.at(sidechain_type::hive) == son_status::request_maintenance); // restore SON activity con.wallet_api_ptr->cancel_request_son_maintenance(name, true); @@ -874,7 +876,8 @@ BOOST_AUTO_TEST_CASE( maintenance_test ) // check SON is active son_obj = con.wallet_api_ptr->get_son(name); - BOOST_CHECK(son_obj.status == son_status::active); + BOOST_CHECK(son_obj.statuses.at(sidechain_type::bitcoin) == son_status::active); + BOOST_CHECK(son_obj.statuses.at(sidechain_type::hive) == son_status::active); // put SON in maintenance mode con.wallet_api_ptr->request_son_maintenance(name, true); @@ -882,14 +885,16 @@ BOOST_AUTO_TEST_CASE( maintenance_test ) // check SON is in request_maintenance son_obj = con.wallet_api_ptr->get_son(name); - BOOST_CHECK(son_obj.status == son_status::request_maintenance); + BOOST_CHECK(son_obj.statuses.at(sidechain_type::bitcoin) == son_status::request_maintenance); + BOOST_CHECK(son_obj.statuses.at(sidechain_type::hive) == son_status::request_maintenance); // process maintenance BOOST_CHECK(generate_maintenance_block()); // check SON is in maintenance son_obj = con.wallet_api_ptr->get_son(name); - BOOST_CHECK(son_obj.status == son_status::in_maintenance); + BOOST_CHECK(son_obj.statuses.at(sidechain_type::bitcoin) == son_status::in_maintenance); + BOOST_CHECK(son_obj.statuses.at(sidechain_type::hive) == son_status::in_maintenance); } catch( fc::exception& e ) { @@ -1006,7 +1011,8 @@ BOOST_AUTO_TEST_CASE( sidechain_withdraw_transaction_test ) BOOST_CHECK(generate_maintenance_block()); son_object son_obj = con.wallet_api_ptr->get_son(name); - BOOST_CHECK(son_obj.status == son_status::active); + BOOST_CHECK(son_obj.statuses.at(sidechain_type::bitcoin) == son_status::active); + BOOST_CHECK(son_obj.statuses.at(sidechain_type::hive) == son_status::active); // create son account std::string account_name("peerplaystest"); diff --git a/tests/tests/son_operations_tests.cpp b/tests/tests/son_operations_tests.cpp index 17585ea6..2e123eb2 100644 --- a/tests/tests/son_operations_tests.cpp +++ b/tests/tests/son_operations_tests.cpp @@ -193,7 +193,8 @@ try { // Modify SON's status to active db.modify( *obj, [&]( son_object& _s) { - _s.status = son_status::in_maintenance; + _s.statuses[sidechain_type::bitcoin] = son_status::in_maintenance; + _s.statuses[sidechain_type::hive] = son_status::in_maintenance; }); db.modify( *son_stats_obj, [&]( son_statistics_object& _s) @@ -218,7 +219,8 @@ try { generate_block(); BOOST_REQUIRE( idx.size() == 1 ); - BOOST_REQUIRE( obj->status == son_status::deregistered ); + BOOST_REQUIRE( obj->statuses.at(sidechain_type::bitcoin) == son_status::deregistered ); + BOOST_REQUIRE( obj->statuses.at(sidechain_type::hive) == son_status::deregistered ); BOOST_REQUIRE( son_stats_obj->deregistered_timestamp == now ); deposit_vesting = db.get(vesting_balance_id_type(0)); @@ -604,7 +606,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { // Modify SON's status to active db.modify( *obj, [&]( son_object& _s) { - _s.status = son_status::active; + _s.statuses[sidechain_type::bitcoin] = son_status::active; + _s.statuses[sidechain_type::hive] = son_status::active; }); db.modify( *son_stats_obj, [&]( son_statistics_object& _s) @@ -626,7 +629,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { PUSH_TX( db, trx, ~0); generate_block(); trx.clear(); - BOOST_CHECK( obj->status == son_status::request_maintenance); + BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::request_maintenance); + BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::request_maintenance); } { @@ -643,13 +647,15 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { PUSH_TX( db, trx, ~0); generate_block(); trx.clear(); - BOOST_CHECK( obj->status == son_status::active); + BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::active); + BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::active); } // Modify SON's status to in_maintenance db.modify( *obj, [&]( son_object& _s) { - _s.status = son_status::in_maintenance; + _s.statuses[sidechain_type::bitcoin] = son_status::in_maintenance; + _s.statuses[sidechain_type::hive] = son_status::in_maintenance; }); uint64_t downtime = 0; @@ -671,14 +677,16 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::bitcoin), op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch()); BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::hive), op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch()); downtime += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch(); - BOOST_CHECK( obj->status == son_status::inactive); + BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::inactive); + BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::inactive); BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts); } // Modify SON's status to in_maintenance db.modify( *obj, [&]( son_object& _s) { - _s.status = son_status::in_maintenance; + _s.statuses[sidechain_type::bitcoin] = son_status::in_maintenance; + _s.statuses[sidechain_type::bitcoin] = son_status::in_maintenance; }); // SON is selected as one of the active SONs @@ -707,7 +715,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::bitcoin), downtime + op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch()); BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::hive), downtime + op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch()); downtime += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch(); - BOOST_CHECK( obj->status == son_status::active); + BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::active); + BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::active); BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts); } @@ -727,7 +736,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { trx.clear(); BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::bitcoin), downtime); BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::hive), downtime); - BOOST_CHECK( obj->status == son_status::active); + BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::active); + BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::active); BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts); } } FC_LOG_AND_RETHROW() @@ -753,7 +763,8 @@ BOOST_AUTO_TEST_CASE( son_report_down_test ) { auto son_stats_obj = sidx.find( obj->statistics ); BOOST_REQUIRE( son_stats_obj != sidx.end() ); - BOOST_CHECK( obj->status == son_status::active); + BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::active); + BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::active); { // Check that transaction fails if down_ts < last_active_timestamp @@ -805,7 +816,8 @@ BOOST_AUTO_TEST_CASE( son_report_down_test ) { generate_block(); trx.clear(); - BOOST_CHECK( obj->status == son_status::in_maintenance); + BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::in_maintenance); + BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::in_maintenance); BOOST_CHECK( son_stats_obj->last_down_timestamp == op.down_ts); } -- 2.45.2 From f6c9b1b7a6675414ebe6e0c19f24040a54aa7f54 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Thu, 31 Mar 2022 15:31:56 +0300 Subject: [PATCH 10/15] #308 - fix update_son_statuses + son_schedule --- libraries/chain/db_maint.cpp | 64 +++++++++++++++++++------ libraries/chain/db_witness_schedule.cpp | 6 +-- 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index cf5f2f64..cc2687e2 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -315,23 +315,21 @@ void database::update_son_metrics(const flat_map >& curr_active_sons, const flat_map >& new_active_sons ) { - FC_ASSERT(curr_active_sons.size() == new_active_sons.size(), "Invalid size in SON active lists," - " curr_active_sons_size={curr_active_sons_size}, new_active_sons_size={new_active_sons_size}", - ("curr_active_sons_size", curr_active_sons.size())("new_active_sons_size", new_active_sons.size())); - - for(const auto& curr_active_sidechain_sons : curr_active_sons) { - const auto& sidechain = curr_active_sidechain_sons.first; + for(const auto& new_active_sidechain_sons : new_active_sons) { + const auto& sidechain = new_active_sidechain_sons.first; vector current_sons, new_sons; vector sons_to_remove, sons_to_add; const auto &idx = get_index_type().indices().get(); - current_sons.reserve(curr_active_sons.at(sidechain).size()); - std::transform(curr_active_sons.at(sidechain).cbegin(), curr_active_sons.at(sidechain).cend(), - std::inserter(current_sons, current_sons.end()), - [](const son_info &swi) { - return swi.son_id; - }); + if(curr_active_sons.contains(sidechain)) { + current_sons.reserve(curr_active_sons.at(sidechain).size()); + std::transform(curr_active_sons.at(sidechain).cbegin(), curr_active_sons.at(sidechain).cend(), + std::inserter(current_sons, current_sons.end()), + [](const son_info &swi) { + return swi.son_id; + }); + } new_sons.reserve(new_active_sons.at(sidechain).size()); std::transform(new_active_sons.at(sidechain).cbegin(), new_active_sons.at(sidechain).cend(), @@ -388,10 +386,22 @@ void database::update_son_statuses( const flat_mapstatuses.at(sidechain))("sv", son->total_votes)); } + } - if (sons_to_remove.size() > 0) { - remove_inactive_son_proposals(sons_to_remove); + //! Remove inactive sons (when all sidechain inactive) + vector sons_to_remove; + const auto &idx = get_index_type().indices().get(); + for(const auto& son : idx) { + bool inactive_son = true; + for(const auto& status : son.statuses) { + if (status.second != son_status::inactive) + inactive_son = false; } + if (inactive_son) + sons_to_remove.emplace_back(son.id); + } + if (sons_to_remove.size() > 0) { + remove_inactive_son_proposals(sons_to_remove); } } @@ -799,7 +809,10 @@ void database::update_active_sons() const auto &acc = get(gpo.parameters.son_account()); for( const auto& sidechain_sons : sons ){ const auto& sidechain = sidechain_sons.first; - for( const son_object& son : sidechain_sons.second ) { + const auto& sons_array = sidechain_sons.second; + + new_active_sons[sidechain].reserve(sons_array.size()); + for( const son_object& son : sons_array ) { son_info swi; swi.son_id = son.id; swi.weight = acc.active.account_auths.at(son.son_account); @@ -848,6 +861,27 @@ void database::update_active_sons() } }); + //! Fixme - fix this schedule + const son_schedule_object& sso = son_schedule_id_type()(*this); + modify(sso, [&](son_schedule_object& _sso) + { + flat_set active_sons; + active_sons.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size()); + std::transform(gpo.active_sons.at(sidechain_type::bitcoin).cbegin(), gpo.active_sons.at(sidechain_type::bitcoin).cend(), + std::inserter(active_sons, active_sons.end()), + [](const son_info& swi) { + return swi.son_id; + }); + _sso.scheduler.update(active_sons); + // similar to witness, produce schedule for sons + if(cur_active_sons.size() == 0 && new_active_sons.size() > 0) + { + witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV); + for( size_t i=0; i Date: Mon, 4 Apr 2022 08:36:13 +0300 Subject: [PATCH 11/15] #308 - fix global_property_object active_sons initialization --- libraries/chain/db_block.cpp | 7 ++++++- libraries/chain/db_maint.cpp | 12 ++++++------ .../graphene/chain/global_property_object.hpp | 10 +++++++++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index 67601c2e..9ce436a7 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -700,7 +700,12 @@ void database::_apply_block( const signed_block& next_block ) if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM) { update_witness_schedule(next_block); - if(global_props.active_sons.size() > 0) { + bool need_to_update_son_schedule = false; + for(const auto& active_sons : global_props.active_sons){ + if(!active_sons.second.empty()) + need_to_update_son_schedule = true; + } + if(need_to_update_son_schedule) { update_son_schedule(next_block); } } diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index cc2687e2..632415ce 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -874,10 +874,10 @@ void database::update_active_sons() }); _sso.scheduler.update(active_sons); // similar to witness, produce schedule for sons - if(cur_active_sons.size() == 0 && new_active_sons.size() > 0) + if(cur_active_sons.at(sidechain_type::bitcoin).size() == 0 && new_active_sons.at(sidechain_type::bitcoin).size() > 0) { witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV); - for( size_t i=0; i 0) + if(cur_active_sons.at(sidechain_type::hive).size() == 0 && new_active_sons.at(sidechain_type::hive).size() > 0) { witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV); - for( size_t i=0; i 0) + if(cur_active_sons.at(sidechain_type::bitcoin).size() == 0 && new_active_sons.at(sidechain_type::bitcoin).size() > 0) { witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV); - for( size_t i=0; i active_committee_members; // updated once per maintenance interval flat_set active_witnesses; // updated once per maintenance interval - flat_map > active_sons; // updated once per maintenance interval + + //! Fixme - delete sidechain type from here + flat_map > active_sons = []() // updated once per maintenance interval + { + flat_map > active_sons; + active_sons[sidechain_type::bitcoin] = vector(); + active_sons[sidechain_type::hive] = vector(); + return active_sons; + }(); // n.b. witness scheduling is done by witness_schedule object }; -- 2.45.2 From 0d74fcf675fd0d85f0c7343fc363ae608b7bf277 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Mon, 4 Apr 2022 11:19:57 +0300 Subject: [PATCH 12/15] #308 - fix son_object statuses initialization --- libraries/chain/include/graphene/chain/son_object.hpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libraries/chain/include/graphene/chain/son_object.hpp b/libraries/chain/include/graphene/chain/son_object.hpp index 31094563..a291ca2f 100644 --- a/libraries/chain/include/graphene/chain/son_object.hpp +++ b/libraries/chain/include/graphene/chain/son_object.hpp @@ -71,7 +71,14 @@ namespace graphene { namespace chain { public_key_type signing_key; vesting_balance_id_type pay_vb; son_statistics_id_type statistics; - flat_map statuses; + //! Fixme - delete sidechain type from here + flat_map statuses = []() + { + flat_map statuses; + statuses[sidechain_type::bitcoin] = son_status::inactive; + statuses[sidechain_type::hive] = son_status::inactive; + return statuses; + }(); flat_map sidechain_public_keys; void pay_son_fee(share_type pay, database& db); -- 2.45.2 From 550727757f763af014fc6ea08f2c20cc8a5f6881 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Mon, 4 Apr 2022 11:20:22 +0300 Subject: [PATCH 13/15] #308 - get cur_active_sons as copy, not reference --- libraries/chain/db_maint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index 632415ce..d6f830ea 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -804,7 +804,7 @@ void database::update_active_sons() // Compare current and to-be lists of active sons - const auto& cur_active_sons = gpo.active_sons; + const auto cur_active_sons = gpo.active_sons; flat_map > new_active_sons; const auto &acc = get(gpo.parameters.son_account()); for( const auto& sidechain_sons : sons ){ -- 2.45.2 From 446d89764cf6ca6fce74737c453c8c48d2b5e7a4 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Tue, 5 Apr 2022 08:05:42 +0300 Subject: [PATCH 14/15] #308 - fix global_props.active_sons.size --- libraries/chain/db_block.cpp | 2 ++ libraries/chain/db_witness_schedule.cpp | 17 ++++++++--- .../chain/son_wallet_deposit_evaluator.cpp | 2 +- .../chain/son_wallet_withdraw_evaluator.cpp | 2 +- .../peerplays_sidechain_plugin.cpp | 1 + .../sidechain_net_handler.cpp | 3 ++ .../sidechain_net_handler_hive.cpp | 4 +-- tests/cli/son.cpp | 30 ++++++++++++------- 8 files changed, 43 insertions(+), 18 deletions(-) diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index 9ce436a7..62fee47f 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -742,6 +742,8 @@ void database::_apply_block( const signed_block& next_block ) update_maintenance_flag( maint_needed ); if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM) { update_witness_schedule(); + + //! Fixme - here we should take active_sons size for sidechain if(global_props.active_sons.size() > 0) { update_son_schedule(); } diff --git a/libraries/chain/db_witness_schedule.cpp b/libraries/chain/db_witness_schedule.cpp index 5d940a17..54a798cb 100644 --- a/libraries/chain/db_witness_schedule.cpp +++ b/libraries/chain/db_witness_schedule.cpp @@ -196,6 +196,7 @@ void database::update_son_schedule() const son_schedule_object& ssobitcoin = son_schedule_id_type(2)(*this); const global_property_object& gpo = get_global_properties(); + //! Fixme - here we should take active_sons size for sidechain if( head_block_num() % gpo.active_sons.size() == 0 ) { modify( sso, [&]( son_schedule_object& _sso ) @@ -402,7 +403,15 @@ void database::update_son_schedule(const signed_block& next_block) const son_schedule_object& sso = get(son_schedule_id_type()); const son_schedule_object& ssohive = get(son_schedule_id_type(1)); const son_schedule_object& ssobitcoin = get(son_schedule_id_type(2)); - uint32_t schedule_needs_filled = gpo.active_sons.size(); + const flat_map schedule_needs_filled = [&gpo]() + { + flat_map schedule_needs_filled; + for(const auto& sidechain_active_sons : gpo.active_sons) + { + schedule_needs_filled[sidechain_active_sons.first] = sidechain_active_sons.second.size(); + } + return schedule_needs_filled; + }(); uint32_t schedule_slot = get_slot_at_time(next_block.timestamp); // We shouldn't be able to generate _pending_block with timestamp @@ -451,7 +460,7 @@ void database::update_son_schedule(const signed_block& next_block) { _sso.scheduler.reset_schedule( first_son ); } - while( !_sso.scheduler.get_slot(schedule_needs_filled, son) ) + while( !_sso.scheduler.get_slot(schedule_needs_filled.at(sidechain_type::bitcoin), son) ) { if( _sso.scheduler.produce_schedule(rng) & emit_turn ) memcpy(_sso.rng_seed.begin(), dpo.random.data(), dpo.random.data_size()); @@ -484,7 +493,7 @@ void database::update_son_schedule(const signed_block& next_block) { _sso.scheduler.reset_schedule( first_son_hive ); } - while( !_sso.scheduler.get_slot(schedule_needs_filled, son_hive) ) + while( !_sso.scheduler.get_slot(schedule_needs_filled.at(sidechain_type::hive), son_hive) ) { if( _sso.scheduler.produce_schedule(rng) & emit_turn ) memcpy(_sso.rng_seed.begin(), dpo.random.data(), dpo.random.data_size()); @@ -517,7 +526,7 @@ void database::update_son_schedule(const signed_block& next_block) { _sso.scheduler.reset_schedule( first_son_bitcoin ); } - while( !_sso.scheduler.get_slot(schedule_needs_filled, son_bitcoin) ) + while( !_sso.scheduler.get_slot(schedule_needs_filled.at(sidechain_type::bitcoin), son_bitcoin) ) { if( _sso.scheduler.produce_schedule(rng) & emit_turn ) memcpy(_sso.rng_seed.begin(), dpo.random.data(), dpo.random.data_size()); diff --git a/libraries/chain/son_wallet_deposit_evaluator.cpp b/libraries/chain/son_wallet_deposit_evaluator.cpp index e109c2f8..8d0199d4 100644 --- a/libraries/chain/son_wallet_deposit_evaluator.cpp +++ b/libraries/chain/son_wallet_deposit_evaluator.cpp @@ -142,11 +142,11 @@ void_result process_son_wallet_deposit_evaluator::do_evaluate(const son_wallet_d { try{ FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); FC_ASSERT( op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer." ); - FC_ASSERT(db().get_global_properties().active_sons.size() >= db().get_chain_properties().immutable_parameters.min_son_count, "Min required voted SONs not present"); const auto& idx = db().get_index_type().indices().get(); const auto& itr = idx.find(op.son_wallet_deposit_id); FC_ASSERT(itr != idx.end(), "Son wallet deposit not found"); + FC_ASSERT(db().get_global_properties().active_sons.at(itr->sidechain).size() >= db().get_chain_properties().immutable_parameters.min_son_count, "Min required voted SONs not present"); FC_ASSERT(!itr->processed, "Son wallet deposit is already processed"); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } diff --git a/libraries/chain/son_wallet_withdraw_evaluator.cpp b/libraries/chain/son_wallet_withdraw_evaluator.cpp index 3fb04ae2..d3f24f19 100644 --- a/libraries/chain/son_wallet_withdraw_evaluator.cpp +++ b/libraries/chain/son_wallet_withdraw_evaluator.cpp @@ -140,11 +140,11 @@ void_result process_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_ { try{ FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); FC_ASSERT( op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer." ); - FC_ASSERT(db().get_global_properties().active_sons.size() >= db().get_chain_properties().immutable_parameters.min_son_count, "Min required voted SONs not present"); const auto& idx = db().get_index_type().indices().get(); const auto& itr = idx.find(op.son_wallet_withdraw_id); FC_ASSERT(itr != idx.end(), "Son wallet withdraw not found"); + FC_ASSERT(db().get_global_properties().active_sons.at(itr->sidechain).size() >= db().get_chain_properties().immutable_parameters.min_son_count, "Min required voted SONs not present"); FC_ASSERT(!itr->processed, "Son wallet withdraw is already processed"); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 80bebc59..3b4faeff 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -456,6 +456,7 @@ void peerplays_sidechain_plugin_impl::schedule_son_processing() { } void peerplays_sidechain_plugin_impl::son_processing() { + //! Fixme - here we must check size for every sidechain if (plugin.database().get_global_properties().active_sons.size() <= 0) { return; } diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp index 86876782..b4b2ba01 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp @@ -399,6 +399,7 @@ void sidechain_net_handler::process_active_sons_change() { } void sidechain_net_handler::create_deposit_addresses() { + //! Fixme - here we must consider sidechain size if (database.get_global_properties().active_sons.size() < database.get_chain_properties().immutable_parameters.min_son_count) { return; } @@ -406,6 +407,7 @@ void sidechain_net_handler::create_deposit_addresses() { } void sidechain_net_handler::process_deposits() { + //! Fixme - here we must consider sidechain size if (database.get_global_properties().active_sons.size() < database.get_chain_properties().immutable_parameters.min_son_count) { return; } @@ -441,6 +443,7 @@ void sidechain_net_handler::process_deposits() { } void sidechain_net_handler::process_withdrawals() { + //! Fixme - here we must consider sidechain size if (database.get_global_properties().active_sons.size() < database.get_chain_properties().immutable_parameters.min_son_count) { return; } diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp index c03d2eb3..6e840be9 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp @@ -214,14 +214,14 @@ bool sidechain_net_handler_hive::process_proposal(const proposal_object &po) { const auto swo = idx.find(swo_id); if (swo != idx.end()) { - auto active_sons = gpo.active_sons; + auto active_sons = gpo.active_sons.at(sidechain); vector wallet_sons = swo->sons.at(sidechain); bool son_sets_equal = (active_sons.size() == wallet_sons.size()); if (son_sets_equal) { for (size_t i = 0; i < active_sons.size(); i++) { - son_sets_equal = son_sets_equal && active_sons.at(sidechain).at(i) == wallet_sons.at(i); + son_sets_equal = son_sets_equal && active_sons.at(i) == wallet_sons.at(i); } } diff --git a/tests/cli/son.cpp b/tests/cli/son.cpp index 3fd9909a..25d96aee 100644 --- a/tests/cli/son.cpp +++ b/tests/cli/son.cpp @@ -408,10 +408,12 @@ BOOST_FIXTURE_TEST_CASE( select_top_fifteen_sons, cli_fixture ) vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, sidechain_type::hive, true, true); } gpo = con.wallet_api_ptr->get_global_properties(); - BOOST_TEST_MESSAGE("gpo: " << gpo.active_sons.size()); + BOOST_TEST_MESSAGE("gpo active_sons[bitcoin]: " << gpo.active_sons.at(sidechain_type::bitcoin).size()); + BOOST_TEST_MESSAGE("gpo active_sons[hive]: " << gpo.active_sons.at(sidechain_type::hive).size()); BOOST_CHECK(generate_maintenance_block()); gpo = con.wallet_api_ptr->get_global_properties(); - BOOST_TEST_MESSAGE("gpo: " << gpo.active_sons.size()); + BOOST_TEST_MESSAGE("gpo active_sons[bitcoin]: " << gpo.active_sons.at(sidechain_type::bitcoin).size()); + BOOST_TEST_MESSAGE("gpo active_sons[hive]: " << gpo.active_sons.at(sidechain_type::hive).size()); for(unsigned int i = 0; i < son_number - 1; i++) { @@ -421,10 +423,12 @@ BOOST_FIXTURE_TEST_CASE( select_top_fifteen_sons, cli_fixture ) vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, sidechain_type::hive, true, true); } gpo = con.wallet_api_ptr->get_global_properties(); - BOOST_TEST_MESSAGE("gpo: " << gpo.active_sons.size()); + BOOST_TEST_MESSAGE("gpo active_sons[bitcoin]: " << gpo.active_sons.at(sidechain_type::bitcoin).size()); + BOOST_TEST_MESSAGE("gpo active_sons[hive]: " << gpo.active_sons.at(sidechain_type::hive).size()); BOOST_CHECK(generate_maintenance_block()); gpo = con.wallet_api_ptr->get_global_properties(); - BOOST_TEST_MESSAGE("gpo: " << gpo.active_sons.size()); + BOOST_TEST_MESSAGE("gpo active_sons[bitcoin]: " << gpo.active_sons.at(sidechain_type::bitcoin).size()); + BOOST_TEST_MESSAGE("gpo active_sons[hive]: " << gpo.active_sons.at(sidechain_type::hive).size()); for(unsigned int i = 0; i < son_number - 2; i++) { @@ -434,10 +438,12 @@ BOOST_FIXTURE_TEST_CASE( select_top_fifteen_sons, cli_fixture ) vote_tx = con.wallet_api_ptr->vote_for_son(name1, name2, sidechain_type::hive, true, true); } gpo = con.wallet_api_ptr->get_global_properties(); - BOOST_TEST_MESSAGE("gpo: " << gpo.active_sons.size()); + BOOST_TEST_MESSAGE("gpo active_sons[bitcoin]: " << gpo.active_sons.at(sidechain_type::bitcoin).size()); + BOOST_TEST_MESSAGE("gpo active_sons[hive]: " << gpo.active_sons.at(sidechain_type::hive).size()); BOOST_CHECK(generate_maintenance_block()); - BOOST_CHECK(gpo.active_sons.size() == gpo.parameters.maximum_son_count()); + BOOST_CHECK(gpo.active_sons.at(sidechain_type::bitcoin).size() == gpo.parameters.maximum_son_count()); + BOOST_CHECK(gpo.active_sons.at(sidechain_type::hive).size() == gpo.parameters.maximum_son_count()); } catch( fc::exception& e ) { BOOST_TEST_MESSAGE("SON cli wallet tests exception"); @@ -721,7 +727,8 @@ BOOST_AUTO_TEST_CASE( related_functions ) try { global_property_object gpo = con.wallet_api_ptr->get_global_properties(); - BOOST_CHECK(gpo.active_sons.size() == 0); + BOOST_CHECK(gpo.active_sons.at(sidechain_type::bitcoin).size() == 0); + BOOST_CHECK(gpo.active_sons.at(sidechain_type::hive).size() == 0); flat_map sidechain_public_keys; @@ -738,7 +745,8 @@ BOOST_AUTO_TEST_CASE( related_functions ) sth.create_son("son2account", "http://son2", sidechain_public_keys); gpo = con.wallet_api_ptr->get_global_properties(); - BOOST_CHECK(gpo.active_sons.size() == 2); + BOOST_CHECK(gpo.active_sons.at(sidechain_type::bitcoin).size() == 2); + BOOST_CHECK(gpo.active_sons.at(sidechain_type::hive).size() == 2); } catch( fc::exception& e ) { BOOST_TEST_MESSAGE("SON cli wallet tests exception"); @@ -797,9 +805,11 @@ BOOST_FIXTURE_TEST_CASE( cli_list_active_sons, cli_fixture ) } BOOST_CHECK(generate_maintenance_block()); gpo = con.wallet_api_ptr->get_global_properties(); - BOOST_TEST_MESSAGE("gpo: " << gpo.active_sons.size()); + BOOST_TEST_MESSAGE("gpo active_sons[bitcoin]: " << gpo.active_sons.at(sidechain_type::bitcoin).size()); + BOOST_TEST_MESSAGE("gpo active_sons[hive]: " << gpo.active_sons.at(sidechain_type::hive).size()); - BOOST_CHECK(gpo.active_sons.size() == son_number); + BOOST_CHECK(gpo.active_sons.at(sidechain_type::bitcoin).size() == son_number); + BOOST_CHECK(gpo.active_sons.at(sidechain_type::hive).size() == son_number); map active_sons = con.wallet_api_ptr->list_active_sons(); BOOST_CHECK(active_sons.size() == son_number); -- 2.45.2 From 7a4130771291f9283e5697c84ce6490d00a9d22d Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Tue, 5 Apr 2022 15:24:05 +0300 Subject: [PATCH 15/15] #308 - fix active_sons in son_processing function --- .../peerplays_sidechain/peerplays_sidechain_plugin.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 3b4faeff..aaaeb801 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -457,7 +457,8 @@ void peerplays_sidechain_plugin_impl::schedule_son_processing() { void peerplays_sidechain_plugin_impl::son_processing() { //! Fixme - here we must check size for every sidechain - if (plugin.database().get_global_properties().active_sons.size() <= 0) { + if (plugin.database().get_global_properties().active_sons.at(sidechain_type::bitcoin).size() <= 0 && + plugin.database().get_global_properties().active_sons.at(sidechain_type::hive).size() <= 0) { return; } @@ -483,7 +484,7 @@ void peerplays_sidechain_plugin_impl::son_processing() { // for the test prove that in hive scheduled son is active son chain::son_id_type scheduled_bitcoin_son_id = plugin.database().get_scheduled_son(sidechain_type::bitcoin ,1); - ilog("Scheduled SON[!HIVE!]: ${scheduled_bitcoin_son_id} Now: ${now} ", + ilog("Scheduled SON[!BITCOIN!]: ${scheduled_bitcoin_son_id} Now: ${now} ", ("scheduled_bitcoin_son_id", scheduled_bitcoin_son_id)("now", now)); for (son_id_type son_id : plugin.get_sons()) { -- 2.45.2