forked from lthn/blockchain
payment_id improved
This commit is contained in:
parent
93b3ca4b66
commit
fa606c1665
9 changed files with 107 additions and 52 deletions
|
|
@ -8,14 +8,54 @@
|
|||
|
||||
namespace bc_services
|
||||
{
|
||||
template<typename T>
|
||||
struct is_boost_variant : std::false_type {};
|
||||
|
||||
template<typename... Args>
|
||||
struct is_boost_variant<boost::variant<Args...>> : std::true_type {};
|
||||
|
||||
template<bool is_variant>
|
||||
struct type_selector;
|
||||
|
||||
template<>
|
||||
struct type_selector<true>
|
||||
{
|
||||
template<typename t_type>
|
||||
static const std::type_info& get_type(const t_type& t)
|
||||
{
|
||||
return t.type();
|
||||
}
|
||||
template<typename t_type, typename t_return_type>
|
||||
static const t_return_type& get(const t_type& t)
|
||||
{
|
||||
return boost::get<t_return_type>(t);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct type_selector<false>
|
||||
{
|
||||
template<typename t_type>
|
||||
static const std::type_info& get_type(const t_type& t)
|
||||
{
|
||||
return typeid(t);
|
||||
}
|
||||
template<typename t_type, typename t_return_type>
|
||||
static const t_return_type& get(const t_type& t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
template<class t_attachment_type_container_t>
|
||||
bool get_first_service_attachment_by_id(const t_attachment_type_container_t& tx_items, const std::string& id, const std::string& instruction, currency::tx_service_attachment& res)
|
||||
{
|
||||
for (const auto& item : tx_items)
|
||||
{
|
||||
if (item.type() == typeid(currency::tx_service_attachment))
|
||||
if (/*item.type()*/ type_selector<is_boost_variant<t_attachment_type_container_t::value_type>::value>::get_type(item) == typeid(currency::tx_service_attachment))
|
||||
{
|
||||
const currency::tx_service_attachment& tsa = boost::get<currency::tx_service_attachment>(item);
|
||||
const currency::tx_service_attachment& tsa = type_selector<is_boost_variant<t_attachment_type_container_t::value_type>::value>::get<t_attachment_type_container_t::value_type, currency::tx_service_attachment>(item);
|
||||
//const currency::tx_service_attachment& tsa = boost::get<currency::tx_service_attachment>(item);
|
||||
if (tsa.service_id == id && tsa.instruction == instruction)
|
||||
{
|
||||
res = tsa;
|
||||
|
|
|
|||
|
|
@ -3361,7 +3361,7 @@ namespace currency
|
|||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool set_payment_id_to_tx(std::vector<attachment_v>& att, const std::string& payment_id)
|
||||
bool set_payment_id_to_tx(std::vector<attachment_v>& att, const std::string& payment_id, bool is_in_hardfork4)
|
||||
{
|
||||
if (!is_payment_id_size_ok(payment_id))
|
||||
return false;
|
||||
|
|
@ -3369,6 +3369,10 @@ namespace currency
|
|||
tx_service_attachment tsa = AUTO_VAL_INIT(tsa);
|
||||
tsa.service_id = BC_PAYMENT_ID_SERVICE_ID;
|
||||
tsa.body = payment_id;
|
||||
if (is_in_hardfork4)
|
||||
{
|
||||
tsa.flags = TX_SERVICE_ATTACHMENT_ENCRYPT_BODY;
|
||||
}
|
||||
att.push_back(tsa);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -431,7 +431,7 @@ namespace currency
|
|||
|
||||
bool addendum_to_hexstr(const std::vector<crypto::hash>& add, std::string& hex_buff);
|
||||
bool hexstr_to_addendum(const std::string& hex_buff, std::vector<crypto::hash>& add);
|
||||
bool set_payment_id_to_tx(std::vector<attachment_v>& att, const std::string& payment_id);
|
||||
bool set_payment_id_to_tx(std::vector<attachment_v>& att, const std::string& payment_id, bool is_in_hardfork4 = false);
|
||||
bool add_padding_to_tx(transaction& tx, size_t count);
|
||||
bool is_service_tx(const transaction& tx);
|
||||
bool does_tx_have_only_mixin_inputs(const transaction& tx);
|
||||
|
|
@ -672,7 +672,7 @@ namespace currency
|
|||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename t_container>
|
||||
bool get_payment_id_from_tx(const t_container& att, std::string& payment_id)
|
||||
bool get_payment_id_from_decrypted_container(const t_container& att, std::string& payment_id)
|
||||
{
|
||||
tx_service_attachment sa = AUTO_VAL_INIT(sa);
|
||||
if (bc_services::get_first_service_attachment_by_id(att, BC_PAYMENT_ID_SERVICE_ID, "", sa))
|
||||
|
|
|
|||
|
|
@ -1681,7 +1681,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
|||
|
||||
|
||||
std::vector<currency::attachment_v> attachments;
|
||||
if (!payment_id.empty() && !set_payment_id_to_tx(attachments, payment_id))
|
||||
if (!payment_id.empty() && !set_payment_id_to_tx(attachments, payment_id, m_wallet->is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM)))
|
||||
{
|
||||
fail_msg_writer() << "provided (or embedded) payment id can't be set: \"" << payment_id << "\"";
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
|
|||
all values m_payments entry, use this strict policy is required to protect exchanges from being feeded with
|
||||
useless outputs
|
||||
*/
|
||||
uint64_t max_out_unlock_time = 0;
|
||||
ptc.max_out_unlock_time = 0;
|
||||
|
||||
std::vector<wallet_out_info> outs;
|
||||
//uint64_t sum_of_native_outs = 0; // TODO: @#@# correctly calculate tx_money_got_in_outs for post-HF4
|
||||
|
|
@ -833,8 +833,8 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
|
|||
m_amount_gindex_to_transfer_id[amount_gindex_pair] = transfer_index;
|
||||
}
|
||||
|
||||
if (max_out_unlock_time < get_tx_unlock_time(tx, o))
|
||||
max_out_unlock_time = get_tx_unlock_time(tx, o);
|
||||
if (ptc.max_out_unlock_time < get_tx_unlock_time(tx, o))
|
||||
ptc.max_out_unlock_time = get_tx_unlock_time(tx, o);
|
||||
|
||||
if (out_type_to_key || out_type_zc)
|
||||
{
|
||||
|
|
@ -888,32 +888,6 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
|
|||
}
|
||||
}
|
||||
|
||||
std::string payment_id;
|
||||
if (has_in_transfers && get_payment_id_from_tx(tx.attachment, payment_id) && payment_id.size())
|
||||
{
|
||||
payment_details payment;
|
||||
payment.m_tx_hash = ptc.tx_hash();
|
||||
payment.m_amount = 0;
|
||||
payment.m_block_height = height;
|
||||
payment.m_unlock_time = max_out_unlock_time;
|
||||
|
||||
for (const auto& bce : ptc.total_balance_change)
|
||||
{
|
||||
if (bce.second > 0)
|
||||
{
|
||||
if (bce.first == currency::native_coin_asset_id)
|
||||
{
|
||||
payment.m_amount = static_cast<uint64_t>(bce.second);
|
||||
}else
|
||||
{
|
||||
payment.subtransfers.push_back(payment_details_subtransfer{ bce.first, static_cast<uint64_t>(bce.second)});
|
||||
}
|
||||
}
|
||||
}
|
||||
m_payments.emplace(payment_id, payment);
|
||||
WLT_LOG_L2("Payment found, id (hex): " << epee::string_tools::buff_to_hex_nodelimer(payment_id) << ", tx: " << payment.m_tx_hash << ", amount: " << print_money_brief(payment.m_amount) << "subtransfers = " << payment.subtransfers.size());
|
||||
}
|
||||
|
||||
//check if there are asset_registration that belong to this wallet
|
||||
const asset_descriptor_operation* pado = get_type_in_variant_container<const asset_descriptor_operation>(tx.extra);
|
||||
if (pado && (ptc.employed_entries.receive.size() || ptc.employed_entries.spent.size() || pado->descriptor.owner == m_account.get_public_address().spend_public_key))
|
||||
|
|
@ -971,7 +945,7 @@ void wallet2::prepare_wti_decrypted_attachments(wallet_public::wallet_transfer_i
|
|||
{
|
||||
LOG_ERROR("wti.payment_id is expected to be empty. Go ahead.");
|
||||
}
|
||||
get_payment_id_from_tx(decrypted_att, wti.payment_id);
|
||||
get_payment_id_from_decrypted_container(decrypted_att, wti.payment_id);
|
||||
|
||||
for (const auto& item : decrypted_att)
|
||||
{
|
||||
|
|
@ -1315,7 +1289,7 @@ bool wallet2::handle_proposal(wallet_public::wallet_transfer_info& wti, const bc
|
|||
ed.is_a = cpd.a_addr.spend_public_key == m_account.get_keys().account_address.spend_public_key;
|
||||
change_contract_state(ed, wallet_public::escrow_contract_details_basic::proposal_sent, ms_id, wti);
|
||||
ed.private_detailes = cpd;
|
||||
currency::get_payment_id_from_tx(decrypted_items, ed.payment_id);
|
||||
currency::get_payment_id_from_decrypted_container(decrypted_items, ed.payment_id);
|
||||
ed.proposal = prop;
|
||||
ed.height = wti.height;
|
||||
wti.contract.resize(1);
|
||||
|
|
@ -1584,8 +1558,42 @@ void wallet2::prepare_wti(wallet_public::wallet_transfer_info& wti, const proces
|
|||
}
|
||||
prepare_wti_decrypted_attachments(wti, decrypted_att);
|
||||
process_contract_info(wti, decrypted_att);
|
||||
process_payment_id_for_wti(wti, tx_process_context);
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::process_payment_id_for_wti(wallet_public::wallet_transfer_info& wti, const process_transaction_context& ptc)
|
||||
{
|
||||
//if(this->is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM))
|
||||
{
|
||||
if (wti.get_native_is_income() && wti.payment_id.size())
|
||||
{
|
||||
payment_details payment;
|
||||
payment.m_tx_hash = wti.tx_hash;
|
||||
payment.m_amount = 0;
|
||||
payment.m_block_height = wti.height;
|
||||
payment.m_unlock_time = ptc.max_out_unlock_time;
|
||||
|
||||
for (const auto& bce : ptc.total_balance_change)
|
||||
{
|
||||
if (bce.second > 0)
|
||||
{
|
||||
if (bce.first == currency::native_coin_asset_id)
|
||||
{
|
||||
payment.m_amount = static_cast<uint64_t>(bce.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
payment.subtransfers.push_back(payment_details_subtransfer{ bce.first, static_cast<uint64_t>(bce.second) });
|
||||
}
|
||||
}
|
||||
}
|
||||
m_payments.emplace(wti.payment_id, payment);
|
||||
WLT_LOG_L2("Payment found, id (hex): " << epee::string_tools::buff_to_hex_nodelimer(wti.payment_id) << ", tx: " << payment.m_tx_hash << ", amount: " << print_money_brief(payment.m_amount) << "subtransfers = " << payment.subtransfers.size());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void wallet2::rise_on_transfer2(const wallet_public::wallet_transfer_info& wti)
|
||||
{
|
||||
PROFILE_FUNC("wallet2::rise_on_transfer2");
|
||||
|
|
@ -3864,7 +3872,7 @@ void wallet2::submit_transfer(const std::string& signed_tx_blob, currency::trans
|
|||
throw;
|
||||
}
|
||||
|
||||
add_sent_tx_detailed_info(tx, ft.ftp.prepared_destinations, ft.ftp.selected_transfers);
|
||||
add_sent_tx_detailed_info(tx, ft.ftp.attachments, ft.ftp.prepared_destinations, ft.ftp.selected_transfers);
|
||||
m_tx_keys.insert(std::make_pair(tx_hash, ft.one_time_key));
|
||||
|
||||
if (m_watch_only)
|
||||
|
|
@ -5467,7 +5475,7 @@ void wallet2::send_escrow_proposal(const bc_services::contract_private_details&
|
|||
send_transaction_to_network(tx);
|
||||
|
||||
mark_transfers_as_spent(ftp.selected_transfers, std::string("escrow proposal sent, tx <") + epee::string_tools::pod_to_hex(get_transaction_hash(tx)) + ">, contract: " + epee::string_tools::pod_to_hex(ms_id));
|
||||
add_sent_tx_detailed_info(tx, ftp.prepared_destinations, ftp.selected_transfers);
|
||||
add_sent_tx_detailed_info(tx, ftp.attachments, ftp.prepared_destinations, ftp.selected_transfers);
|
||||
|
||||
print_tx_sent_message(tx, "(from multisig)", fee);
|
||||
}
|
||||
|
|
@ -6337,12 +6345,12 @@ void wallet2::send_transaction_to_network(const transaction& tx)
|
|||
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
void wallet2::add_sent_tx_detailed_info(const transaction& tx,
|
||||
void wallet2::add_sent_tx_detailed_info(const transaction& tx, const std::vector<currency::attachment_v>& decrypted_att,
|
||||
const std::vector<currency::tx_destination_entry>& destinations,
|
||||
const std::vector<uint64_t>& selected_transfers)
|
||||
{
|
||||
payment_id_t payment_id;
|
||||
get_payment_id_from_tx(tx.attachment, payment_id);
|
||||
get_payment_id_from_decrypted_container(decrypted_att, payment_id);
|
||||
|
||||
std::vector<std::string> recipients;
|
||||
std::unordered_set<account_public_address> used_addresses;
|
||||
|
|
@ -7145,7 +7153,7 @@ void wallet2::finalize_transaction(currency::finalize_tx_param& ftp, currency::f
|
|||
|
||||
//TIME_MEASURE_START(add_sent_tx_detailed_info_time);
|
||||
if (broadcast_tx)
|
||||
add_sent_tx_detailed_info(result.tx, ftp.prepared_destinations, ftp.selected_transfers);
|
||||
add_sent_tx_detailed_info(result.tx, ftp.attachments, ftp.prepared_destinations, ftp.selected_transfers);
|
||||
//TIME_MEASURE_FINISH(add_sent_tx_detailed_info_time);
|
||||
|
||||
/* TODO
|
||||
|
|
@ -7269,7 +7277,7 @@ void wallet2::check_and_throw_if_self_directed_tx_with_payment_id_requested(cons
|
|||
|
||||
// it's self-directed tx
|
||||
payment_id_t pid;
|
||||
bool has_payment_id = get_payment_id_from_tx(ctp.attachments, pid) && !pid.empty();
|
||||
bool has_payment_id = get_payment_id_from_decrypted_container(ctp.attachments, pid) && !pid.empty();
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(!has_payment_id, "sending funds to yourself with payment id is not allowed");
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
|
@ -7419,8 +7427,9 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public
|
|||
|
||||
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
|
||||
ftp.tx_version = this->get_current_tx_version();
|
||||
bool is_hf4 = this->is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM);
|
||||
if (!payment_id.empty())
|
||||
set_payment_id_to_tx(ftp.attachments, payment_id);
|
||||
set_payment_id_to_tx(ftp.attachments, payment_id, is_hf4);
|
||||
// put encrypted payer info into the extra
|
||||
ftp.crypt_address = destination_addr;
|
||||
|
||||
|
|
|
|||
|
|
@ -323,6 +323,7 @@ namespace tools
|
|||
multisig_entries_map* pmultisig_entries = nullptr;
|
||||
crypto::public_key tx_pub_key = currency::null_pkey;
|
||||
uint64_t tx_expiration_ts_median = 0;
|
||||
uint64_t max_out_unlock_time = 0;
|
||||
|
||||
const crypto::hash& tx_hash() const
|
||||
{
|
||||
|
|
@ -690,6 +691,7 @@ namespace tools
|
|||
bool validate_sign(const std::string& buff, const crypto::signature& sig, const crypto::public_key& pkey);
|
||||
bool encrypt_buffer(const std::string& buff, std::string& res_buff);
|
||||
bool decrypt_buffer(const std::string& buff, std::string& res_buff);
|
||||
bool is_in_hardfork_zone(uint64_t hardfork_index) const;
|
||||
|
||||
construct_tx_param get_default_construct_tx_param();
|
||||
|
||||
|
|
@ -741,6 +743,7 @@ private:
|
|||
void prepare_wti_decrypted_attachments(wallet_public::wallet_transfer_info& wti, const std::vector<currency::payload_items_v>& decrypted_att);
|
||||
void handle_money(const currency::block& b, const process_transaction_context& tx_process_context);
|
||||
void load_wti_from_process_transaction_context(wallet_public::wallet_transfer_info& wti, const process_transaction_context& tx_process_context);
|
||||
bool process_payment_id_for_wti(wallet_public::wallet_transfer_info& wti, const process_transaction_context& tx_process_context);
|
||||
|
||||
void handle_pulled_blocks(size_t& blocks_added, std::atomic<bool>& stop,
|
||||
currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& blocks);
|
||||
|
|
@ -817,7 +820,8 @@ private:
|
|||
void load_keys2ki(bool create_if_not_exist, bool& need_to_resync);
|
||||
|
||||
void send_transaction_to_network(const currency::transaction& tx);
|
||||
void add_sent_tx_detailed_info(const currency::transaction& tx,
|
||||
void add_sent_tx_detailed_info(const currency::transaction& tx,
|
||||
const std::vector<currency::attachment_v>& decrypted_att,
|
||||
const std::vector<currency::tx_destination_entry>& destinations,
|
||||
const std::vector<uint64_t>& selected_indicies);
|
||||
void mark_transfers_as_spent(const std::vector<uint64_t>& selected_transfers, const std::string& reason = std::string());
|
||||
|
|
@ -838,7 +842,6 @@ private:
|
|||
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(uint64_t amount, const std::vector<currency::txout_ref_v> & key_offsets);
|
||||
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::txin_to_key& intk);
|
||||
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::txin_zc_input& inzc);
|
||||
bool is_in_hardfork_zone(uint64_t hardfork_index) const;
|
||||
uint8_t out_get_mixin_attr(const currency::tx_out_v& out_t);
|
||||
const crypto::public_key& out_get_pub_key(const currency::tx_out_v& out_t, std::list<currency::htlc_info>& htlc_info_list);
|
||||
bool expand_selection_with_zc_input(assets_selection_context& needed_money_map, uint64_t fake_outputs_count, std::vector<uint64_t>& selected_indexes);
|
||||
|
|
|
|||
|
|
@ -410,7 +410,7 @@ namespace tools
|
|||
|
||||
std::vector<currency::attachment_v>& attachments = ctp.attachments;
|
||||
std::vector<currency::extra_v>& extra = ctp.extra;
|
||||
if (!payment_id.empty() && !currency::set_payment_id_to_tx(attachments, payment_id))
|
||||
if (!payment_id.empty() && !currency::set_payment_id_to_tx(attachments, payment_id, w.get_wallet()->is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM)))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID;
|
||||
er.message = std::string("payment id ") + payment_id + " is invalid and can't be set";
|
||||
|
|
|
|||
|
|
@ -1533,18 +1533,17 @@ std::string wallets_manager::transfer(uint64_t wallet_id, const view::transfer_p
|
|||
dsts.back().asset_id = d.asset_id;
|
||||
}
|
||||
|
||||
GET_WALLET_BY_ID(wallet_id, w);
|
||||
|
||||
if (payment_id.size())
|
||||
{
|
||||
if (!currency::is_payment_id_size_ok(payment_id))
|
||||
return API_RETURN_CODE_BAD_ARG_WRONG_PAYMENT_ID; // payment id is too big
|
||||
|
||||
if (!currency::set_payment_id_to_tx(attachments, payment_id))
|
||||
if (!currency::set_payment_id_to_tx(attachments, payment_id, w->get()->is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM)))
|
||||
return API_RETURN_CODE_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
GET_WALLET_BY_ID(wallet_id, w);
|
||||
|
||||
|
||||
|
||||
//set transaction unlock time if it was specified by user
|
||||
uint64_t unlock_time = 0;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ TEST(parse_and_validate_tx_extra, test_payment_ids)
|
|||
ASSERT_TRUE(r);
|
||||
|
||||
std::string h2;
|
||||
r = currency::get_payment_id_from_tx(tx.attachment, h2);
|
||||
r = currency::get_payment_id_from_decrypted_container(tx.attachment, h2);
|
||||
ASSERT_TRUE(r);
|
||||
ASSERT_EQ(h, h2);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue