From f169e7a7ef2b5c8b6acc0904840827ff8f518684 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Tue, 8 Mar 2022 23:21:28 +0000 Subject: [PATCH] #313 son deposit manually --- .../wallet/include/graphene/wallet/wallet.hpp | 26 +++++ libraries/wallet/wallet.cpp | 98 +++++++++++++++++++ tests/cli/son.cpp | 67 +++++++++++++ 3 files changed, 191 insertions(+) diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 4b5013a8a..89ba5e856 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -1786,6 +1786,31 @@ 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 sidechain Sidechain type (bitcoin, HIVE, etc) + * @param transaction_id ID of transaction + * @param operation_index Index of operation + * @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 sidechain_type& sidechain, + const string &transaction_id, + uint32_t operation_index, + 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. * * An account can publish a list of all witnesses they approve of. This @@ -2712,6 +2737,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 71f6bc32b..40c6f3614 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -2830,6 +2830,81 @@ class wallet_api_impl 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 sidechain_type& sidechain, + const string &transaction_id, + uint32_t operation_index, + 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_global_props = get_dynamic_global_properties(); + const auto global_props = get_global_properties(); + const auto son_obj = get_son(son_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)); + } + }(); + 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_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 = 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); + } + signed_transaction vote_for_witness(string voting_account, string witness, bool approve, @@ -5341,6 +5416,29 @@ 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 sidechain_type& sidechain, + const string &transaction_id, + uint32_t operation_index, + 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, + sidechain, + transaction_id, + operation_index, + 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, string witness, bool approve, diff --git a/tests/cli/son.cpp b/tests/cli/son.cpp index 491ec8f96..26cee70ec 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()