1
0
Fork 0
forked from lthn/blockchain

wallet rpc: split destinations by default (for users convenience)

This commit is contained in:
sowle 2024-08-13 02:07:25 +02:00
parent 2c06293f24
commit 88a1e96820
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
3 changed files with 51 additions and 23 deletions

View file

@ -1987,10 +1987,12 @@ namespace wallet_public
{
std::list<transfer_destination> destinations;
currency::asset_descriptor_base asset_descriptor;
bool use_destinations_as_is = false;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(destinations) DOC_DSCR("Addresses where to receive emitted coins. Asset id in the destinations is irreleant and can be omitted.") DOC_EXMP_AUTO(1) DOC_END
KV_SERIALIZE(asset_descriptor) DOC_DSCR("Descriptor that holds all information about asset - ticker, emission, description etc") DOC_END
KV_SERIALIZE(destinations) DOC_DSCR("Addresses where to receive emitted coins. Asset id in the destinations is irreleant and can be omitted.") DOC_EXMP_AUTO(1) DOC_END
KV_SERIALIZE(asset_descriptor) DOC_DSCR("Descriptor that holds all information about asset - ticker, emission, description etc") DOC_END
KV_SERIALIZE(use_destinations_as_is) DOC_DSCR("If true, the provided destinations will be used as-is and won't be splitted (or altered) to avoid common issues. Default is false.") DOC_EXMP(false) DOC_END
END_KV_SERIALIZE_MAP()
};
@ -2015,10 +2017,12 @@ namespace wallet_public
{
crypto::public_key asset_id;
std::list<transfer_destination> destinations;
bool use_destinations_as_is = false;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("Id of the asset to emit more coins") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END
KV_SERIALIZE(destinations) DOC_DSCR("Addresses where to receive emitted coins. Asset id in the destinations is irreleant and can be omitted.") DOC_EXMP_AUTO(1) DOC_END
KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("Id of the asset to emit more coins") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END
KV_SERIALIZE(destinations) DOC_DSCR("Addresses where to receive emitted coins. Asset id in the destinations is irreleant and can be omitted.") DOC_EXMP_AUTO(1) DOC_END
KV_SERIALIZE(use_destinations_as_is) DOC_DSCR("If true, the provided destinations will be used as-is and won't be splitted (or altered) to avoid common issues. Default is false.") DOC_EXMP(false) DOC_END
END_KV_SERIALIZE_MAP()
};

View file

@ -1260,13 +1260,46 @@ namespace tools
WALLET_RPC_CATCH_TRY_ENTRY();
}
//------------------------------------------------------------------------------------------------------------------------------
void wallet_rpc_server::rpc_destinations_to_currency_destination(const std::list<wallet_public::transfer_destination>& rpc_destinations, std::vector<currency::tx_destination_entry>& currency_destinations)
#define DESTINATIONS_COUNT_FOR_DEPLOY_OR_EMIT 10
static_assert(DESTINATIONS_COUNT_FOR_DEPLOY_OR_EMIT >= CURRENCY_TX_MIN_ALLOWED_OUTS, "DESTINATIONS_COUNT_FOR_DEPLOY_OR_EMIT must be >= min allowed tx outs");
void wallet_rpc_server::rpc_destinations_to_currency_destinations(const std::list<wallet_public::transfer_destination>& rpc_destinations, bool nullify_asset_id, bool try_to_split, std::vector<currency::tx_destination_entry>& result_destinations)
{
GET_WALLET();
std::vector<currency::tx_destination_entry>& dsts = currency_destinations;
for (auto it = rpc_destinations.begin(); it != rpc_destinations.end(); it++)
WLT_THROW_IF_FALSE_WITH_CODE(!rpc_destinations.empty(), "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT", "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT");
std::list<wallet_public::transfer_destination> local_destinations;
if (nullify_asset_id && try_to_split)
{
currency::tx_destination_entry de;
bool do_split = true;
uint64_t total_amount = rpc_destinations.front().amount;
std::string first_address = rpc_destinations.front().address;
for(auto it = std::next(rpc_destinations.begin()); it != rpc_destinations.end(); ++it)
{
total_amount += it->amount;
if (first_address != it->address)
{
do_split = false;
break;
}
}
if (do_split)
{
const uint64_t el_amount = total_amount / DESTINATIONS_COUNT_FOR_DEPLOY_OR_EMIT; // approximation, see below
wallet_public::transfer_destination td{};
td.address = first_address;
td.amount = el_amount;
for(size_t i = 0; i < DESTINATIONS_COUNT_FOR_DEPLOY_OR_EMIT - 1; ++i)
local_destinations.push_back(td);
td.amount = total_amount - (DESTINATIONS_COUNT_FOR_DEPLOY_OR_EMIT - 1) * el_amount; // the last element must account for division error
local_destinations.push_back(td);
}
}
const std::list<wallet_public::transfer_destination>& destinations = local_destinations.size() != 0 ? local_destinations : rpc_destinations;
for (auto it = destinations.begin(); it != destinations.end(); ++it)
{
currency::tx_destination_entry de{};
de.addr.resize(1);
std::string embedded_payment_id;
//check if address looks like wrapped address
@ -1274,8 +1307,8 @@ namespace tools
WLT_THROW_IF_FALSE_WITH_CODE(w.get_wallet()->get_transfer_address(it->address, de.addr.back(), embedded_payment_id), "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS", "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS");
WLT_THROW_IF_FALSE_WITH_CODE(embedded_payment_id.size() == 0, "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS", "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS");
de.amount = it->amount;
de.asset_id = it->asset_id;
dsts.push_back(de);
de.asset_id = nullify_asset_id ? currency::null_pkey : it->asset_id;
result_destinations.push_back(de);
}
}
//------------------------------------------------------------------------------------------------------------------------------
@ -1285,12 +1318,7 @@ namespace tools
currency::transaction result_tx;
std::vector<currency::tx_destination_entry> currency_destinations;
rpc_destinations_to_currency_destination(req.destinations, currency_destinations);
//fix for default asset_id
for (auto& d : currency_destinations)
{
d.asset_id = currency::null_pkey;
}
rpc_destinations_to_currency_destinations(req.destinations, true, !req.use_destinations_as_is, currency_destinations);
w.get_wallet()->deploy_new_asset(req.asset_descriptor, currency_destinations, result_tx, res.new_asset_id);
res.result_tx = currency::get_transaction_hash(result_tx);
@ -1303,12 +1331,7 @@ namespace tools
WALLET_RPC_BEGIN_TRY_ENTRY();
currency::transaction result_tx;
std::vector<currency::tx_destination_entry> currency_destinations;
rpc_destinations_to_currency_destination(req.destinations, currency_destinations);
//fix for default asset_id
for (auto& d : currency_destinations)
{
d.asset_id = currency::null_pkey;
}
rpc_destinations_to_currency_destinations(req.destinations, true, !req.use_destinations_as_is, currency_destinations);
w.get_wallet()->emit_asset(req.asset_id, currency_destinations, result_tx);
res.result_tx = currency::get_transaction_hash(result_tx);

View file

@ -238,7 +238,8 @@ namespace tools
//bool reset_active_wallet(std::shared_ptr<wallet2> w);
bool handle_command_line(const boost::program_options::variables_map& vm);
void rpc_destinations_to_currency_destination(const std::list<wallet_public::transfer_destination>& rpc_destinations, std::vector<currency::tx_destination_entry>& currency_destinations);
void rpc_destinations_to_currency_destinations(const std::list<wallet_public::transfer_destination>& rpc_destinations, bool nullify_asset_id, bool try_to_split, std::vector<currency::tx_destination_entry>& currency_destinations);
private:
std::shared_ptr<i_wallet_provider> m_pwallet_provider_sh_ptr;