From 55633fb7f69681280887c56f2def755f2eddc7c4 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Mon, 7 Mar 2022 18:25:31 +0300 Subject: [PATCH 1/3] #313 Add function sidechain_deposit_transaction --- .../wallet/include/graphene/wallet/wallet.hpp | 22 ++++++ libraries/wallet/wallet.cpp | 70 +++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 4b5013a8..bd6ad0c3 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -1786,6 +1786,27 @@ class wallet_api uint16_t desired_number_of_sons, bool broadcast = false); + + /** Broadcast signed transaction for manually sidechain deposit + * @param son_name_or_id ID or name of the son account + * @param account_from_name_or_id ID or name of the account transaction from + * @param account_to_name_or_id ID or name of the account transaction to + * @param sidechain Sidechain type (bitcoin, HIVE, etc) + * @param transaction_id ID of transaction + * @param operation_index Index of operation + * @param asset_name_or_id the symbol or id of the asset in question + * @param amount The amount to deposit. + * @returns the signed transaction. + */ + signed_transaction sidechain_deposit_transaction( const string &son_name_or_id, + const string &account_from_name_or_id, + const string &account_to_name_or_id, + const sidechain_type& sidechain, + const string &transaction_id, + uint32_t operation_index, + const string &asset_name_or_id, + const string &amount); + /** Vote for a given witness. * * An account can publish a list of all witnesses they approve of. This @@ -2712,6 +2733,7 @@ FC_API( graphene::wallet::wallet_api, (vote_for_committee_member) (vote_for_son) (update_son_votes) + (sidechain_deposit_transaction) (vote_for_witness) (update_witness_votes) (set_voting_proxy) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 71f6bc32..4b01890a 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -2830,6 +2830,57 @@ public: return sign_transaction( tx, broadcast ); } FC_CAPTURE_AND_RETHROW( (voting_account)(sons_to_approve)(sons_to_reject)(desired_number_of_sons)(broadcast) ) } + signed_transaction sidechain_deposit_transaction( const string &son_name_or_id, + const string &account_from_name_or_id, + const string &account_to_name_or_id, + const sidechain_type& sidechain, + const string &transaction_id, + uint32_t operation_index, + const string &asset_name_or_id, + const string &amount) + { + //! Get data we need to procced transaction + const auto dynamic_props = get_dynamic_global_properties(); + const auto son_obj = get_son(son_name_or_id); + FC_ASSERT(son_obj.status == son_status::active, "Son account is not active, current status: ${status}", ("status", son_obj.status)); + const auto account_obj_from = get_account(account_from_name_or_id); + const auto account_obj_to = get_account(account_to_name_or_id); + const std::string sidechain_str = [&sidechain](){ + switch (sidechain) { + case sidechain_type::peerplays : return "peerplays"; + case sidechain_type::bitcoin : return "bitcoin"; + case sidechain_type::hive : return "hive"; + default: + FC_THROW("Wrong sidechain type: ${sidechain}", ("sidechain", sidechain)); + } + }(); + fc::optional asset_obj = get_asset(asset_name_or_id); + FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", asset_name_or_id)); + const auto asset_val = asset_obj->amount_from_string(amount); + const auto asset_price = asset_obj->options.core_exchange_rate; + + //! Create transaction + signed_transaction son_wallet_deposit_create_transaction; + son_wallet_deposit_create_operation op; + op.payer = son_obj.son_account; + op.son_id = son_obj.id; + op.timestamp = dynamic_props.time; + op.block_num = dynamic_props.head_block_number; + op.sidechain = sidechain; + op.sidechain_uid = sidechain_str + "-" + transaction_id + "-" + std::to_string(operation_index); + op.sidechain_transaction_id = transaction_id; + op.sidechain_from = object_id_to_string(account_obj_from.id); + op.sidechain_to = object_id_to_string(account_obj_to.id); + op.sidechain_currency = object_id_to_string(asset_obj->id); + op.sidechain_amount = asset_val.amount; + op.peerplays_from = account_obj_from.id; + op.peerplays_to = account_obj_to.id; + op.peerplays_asset = asset(asset_val.amount * asset_price.base.amount / asset_price.quote.amount); + son_wallet_deposit_create_transaction.operations.push_back(op); + + return sign_transaction(son_wallet_deposit_create_transaction, true); + } + signed_transaction vote_for_witness(string voting_account, string witness, bool approve, @@ -5341,6 +5392,25 @@ signed_transaction wallet_api::update_son_votes(string voting_account, return my->update_son_votes(voting_account, sons_to_approve, sons_to_reject, desired_number_of_sons, broadcast); } +signed_transaction wallet_api::sidechain_deposit_transaction( const string &son_name_or_id, + const string &account_from_name_or_id, + const string &account_to_name_or_id, + const sidechain_type& sidechain, + const string &transaction_id, + uint32_t operation_index, + const string &asset_name_or_id, + const string &amount) +{ + return my->sidechain_deposit_transaction(son_name_or_id, + account_from_name_or_id, + account_to_name_or_id, + sidechain, + transaction_id, + operation_index, + asset_name_or_id, + amount); +} + signed_transaction wallet_api::vote_for_witness(string voting_account, string witness, bool approve, -- 2.45.2 From f7bee47fd29db2d5d652170908266983efc1dcde Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Tue, 8 Mar 2022 14:10:41 +0300 Subject: [PATCH 2/3] #313 sidechain_deposit_transaction - add all params to function manually --- .../wallet/include/graphene/wallet/wallet.hpp | 22 +++-- libraries/wallet/wallet.cpp | 86 ++++++++++++------- 2 files changed, 70 insertions(+), 38 deletions(-) diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index bd6ad0c3..89ba5e85 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -1789,23 +1789,27 @@ class wallet_api /** Broadcast signed transaction for manually sidechain deposit * @param son_name_or_id ID or name of the son account - * @param account_from_name_or_id ID or name of the account transaction from - * @param account_to_name_or_id ID or name of the account transaction to * @param sidechain Sidechain type (bitcoin, HIVE, etc) * @param transaction_id ID of transaction * @param operation_index Index of operation - * @param asset_name_or_id the symbol or id of the asset in question - * @param amount The amount to deposit. + * @param sidechain_from Sidechain address transaction from + * @param sidechain_to Sidechain address transaction to + * @param sidechain_currency Sidechain currency + * @param sidechain_amount Sidechain amount to deposit + * @param peerplays_from_name_or_id ID or name of the account transaction from + * @param peerplays_to_name_or_id ID or name of the account transaction to * @returns the signed transaction. */ - signed_transaction sidechain_deposit_transaction( const string &son_name_or_id, - const string &account_from_name_or_id, - const string &account_to_name_or_id, + signed_transaction sidechain_deposit_transaction( const string &son_name_or_id, const sidechain_type& sidechain, const string &transaction_id, uint32_t operation_index, - const string &asset_name_or_id, - const string &amount); + const string &sidechain_from, + const string &sidechain_to, + const string &sidechain_currency, + int64_t sidechain_amount, + const string &peerplays_from_name_or_id, + const string &peerplays_to_name_or_id); /** Vote for a given witness. * diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 4b01890a..40c6f361 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -2831,20 +2831,20 @@ public: } FC_CAPTURE_AND_RETHROW( (voting_account)(sons_to_approve)(sons_to_reject)(desired_number_of_sons)(broadcast) ) } signed_transaction sidechain_deposit_transaction( const string &son_name_or_id, - const string &account_from_name_or_id, - const string &account_to_name_or_id, const sidechain_type& sidechain, const string &transaction_id, uint32_t operation_index, - const string &asset_name_or_id, - const string &amount) + const string &sidechain_from, + const string &sidechain_to, + const string &sidechain_currency, + int64_t sidechain_amount, + const string &peerplays_from_name_or_id, + const string &peerplays_to_name_or_id ) { //! Get data we need to procced transaction - const auto dynamic_props = get_dynamic_global_properties(); + const auto dynamic_global_props = get_dynamic_global_properties(); + const auto global_props = get_global_properties(); const auto son_obj = get_son(son_name_or_id); - FC_ASSERT(son_obj.status == son_status::active, "Son account is not active, current status: ${status}", ("status", son_obj.status)); - const auto account_obj_from = get_account(account_from_name_or_id); - const auto account_obj_to = get_account(account_to_name_or_id); const std::string sidechain_str = [&sidechain](){ switch (sidechain) { case sidechain_type::peerplays : return "peerplays"; @@ -2854,28 +2854,52 @@ public: FC_THROW("Wrong sidechain type: ${sidechain}", ("sidechain", sidechain)); } }(); - fc::optional asset_obj = get_asset(asset_name_or_id); - FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", asset_name_or_id)); - const auto asset_val = asset_obj->amount_from_string(amount); - const auto asset_price = asset_obj->options.core_exchange_rate; + const auto peerplays_from_obj = get_account(peerplays_from_name_or_id); + const auto peerplays_to_obj = get_account(peerplays_to_name_or_id); + const price sidechain_currency_price = [this, &sidechain_currency, &global_props](){ + if(sidechain_currency == "BTC") + { + fc::optional asset_obj = get_asset(object_id_to_string(global_props.parameters.btc_asset())); + FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", "BTC")); + return asset_obj->options.core_exchange_rate; + } + else if(sidechain_currency == "HBD") + { + fc::optional asset_obj = get_asset(object_id_to_string(global_props.parameters.hbd_asset())); + FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", "HBD")); + return asset_obj->options.core_exchange_rate; + } + else if(sidechain_currency == "HIVE") + { + fc::optional asset_obj = get_asset(object_id_to_string(global_props.parameters.hive_asset())); + FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", "HIVE")); + return asset_obj->options.core_exchange_rate; + } + else + { + fc::optional asset_obj = get_asset(sidechain_currency); + FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", sidechain_currency)); + return asset_obj->options.core_exchange_rate; + } + }(); //! Create transaction signed_transaction son_wallet_deposit_create_transaction; son_wallet_deposit_create_operation op; op.payer = son_obj.son_account; op.son_id = son_obj.id; - op.timestamp = dynamic_props.time; - op.block_num = dynamic_props.head_block_number; + op.timestamp = dynamic_global_props.time; + op.block_num = dynamic_global_props.head_block_number; op.sidechain = sidechain; op.sidechain_uid = sidechain_str + "-" + transaction_id + "-" + std::to_string(operation_index); op.sidechain_transaction_id = transaction_id; - op.sidechain_from = object_id_to_string(account_obj_from.id); - op.sidechain_to = object_id_to_string(account_obj_to.id); - op.sidechain_currency = object_id_to_string(asset_obj->id); - op.sidechain_amount = asset_val.amount; - op.peerplays_from = account_obj_from.id; - op.peerplays_to = account_obj_to.id; - op.peerplays_asset = asset(asset_val.amount * asset_price.base.amount / asset_price.quote.amount); + op.sidechain_from = sidechain_from; + op.sidechain_to = sidechain_to; + op.sidechain_currency = sidechain_currency; + op.sidechain_amount = sidechain_amount; + op.peerplays_from = peerplays_from_obj.id; + op.peerplays_to = peerplays_to_obj.id; + op.peerplays_asset = asset(op.sidechain_amount * sidechain_currency_price.base.amount / sidechain_currency_price.quote.amount); son_wallet_deposit_create_transaction.operations.push_back(op); return sign_transaction(son_wallet_deposit_create_transaction, true); @@ -5393,22 +5417,26 @@ signed_transaction wallet_api::update_son_votes(string voting_account, } signed_transaction wallet_api::sidechain_deposit_transaction( const string &son_name_or_id, - const string &account_from_name_or_id, - const string &account_to_name_or_id, const sidechain_type& sidechain, const string &transaction_id, uint32_t operation_index, - const string &asset_name_or_id, - const string &amount) + const string &sidechain_from, + const string &sidechain_to, + const string &sidechain_currency, + int64_t sidechain_amount, + const string &peerplays_from_name_or_id, + const string &peerplays_to_name_or_id) { return my->sidechain_deposit_transaction(son_name_or_id, - account_from_name_or_id, - account_to_name_or_id, sidechain, transaction_id, operation_index, - asset_name_or_id, - amount); + sidechain_from, + sidechain_to, + sidechain_currency, + sidechain_amount, + peerplays_from_name_or_id, + peerplays_to_name_or_id); } signed_transaction wallet_api::vote_for_witness(string voting_account, -- 2.45.2 From 3242a6a8e55506034117fd797b28046faf1d801f Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Tue, 8 Mar 2022 14:11:01 +0300 Subject: [PATCH 3/3] #313 - sidechain_deposit_transaction_test --- tests/cli/son.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/cli/son.cpp b/tests/cli/son.cpp index 491ec8f9..26cee70e 100644 --- a/tests/cli/son.cpp +++ b/tests/cli/son.cpp @@ -782,6 +782,73 @@ BOOST_AUTO_TEST_CASE( maintenance_test ) BOOST_TEST_MESSAGE("SON maintenance cli wallet tests end"); } +BOOST_AUTO_TEST_CASE( sidechain_deposit_transaction_test ) +{ + BOOST_TEST_MESSAGE("SON sidechain_deposit_transaction_test cli wallet tests begin"); + try + { + son_test_helper sth(*this); + + std::string son_name("sonaccount1"); + std::string account_name("jmjatlanta"); + + global_property_object gpo; + gpo = con.wallet_api_ptr->get_global_properties(); + unsigned int son_number = gpo.parameters.maximum_son_count(); + + flat_map sidechain_public_keys; + + // create son accounts + for(unsigned int i = 0; i < son_number + 1; i++) + { + sidechain_public_keys.clear(); + sidechain_public_keys[sidechain_type::bitcoin] = "bitcoin_address " + fc::to_pretty_string(i); + sidechain_public_keys[sidechain_type::hive] = "hive account " + fc::to_pretty_string(i); + sth.create_son("sonaccount" + fc::to_pretty_string(i), + "http://son" + fc::to_pretty_string(i), + sidechain_public_keys, + false); + } + BOOST_CHECK(generate_maintenance_block()); + + BOOST_TEST_MESSAGE("Voting for SONs"); + for(unsigned int i = 1; i < son_number + 1; i++) + { + 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, true, true); + } + BOOST_CHECK(generate_maintenance_block()); + + // create a new account + graphene::wallet::brain_key_info bki = con.wallet_api_ptr->suggest_brain_key(); + BOOST_CHECK(!bki.brain_priv_key.empty()); + signed_transaction create_acct_tx = con.wallet_api_ptr->create_account_with_brain_key( + bki.brain_priv_key, account_name, "nathan", "nathan", true + ); + + generate_block(); + + //! sidechain_deposit_transaction for this account + for(unsigned int i = 0; i < son_number; i++) { + signed_transaction bitcoin_deposit_tx = con.wallet_api_ptr->sidechain_deposit_transaction("sonaccount" + fc::to_pretty_string(i), sidechain_type::bitcoin, "1db35f72d54eae871e9646c21bdba385f1f0920c", + 0, "bitcoin_address 0", "", "BTC", 1, son_name, account_name); + + signed_transaction hive_deposit_tx = con.wallet_api_ptr->sidechain_deposit_transaction("sonaccount" + fc::to_pretty_string(i), sidechain_type::hive, "1db35f72d54eae871e9646c21bdba385f1f0920d", + 0, "hive account 0", "son-account", "HIVE", 1, son_name, account_name); + } + + generate_block(); + + } catch( fc::exception& e ) { + BOOST_TEST_MESSAGE("SON cli wallet tests exception"); + edump((e.to_detail_string())); + throw; + } + BOOST_TEST_MESSAGE("SON sidechain_deposit_transaction_test cli wallet tests end"); +} + BOOST_AUTO_TEST_SUITE_END() -- 2.45.2