forked from lthn/blockchain
multiple fixes for wallet rpc api on_asset_send_ext_signed_tx on_attach_asset_descriptor and on_transfer_asset_ownership
This commit is contained in:
parent
0662f9bbed
commit
938050df0f
4 changed files with 143 additions and 37 deletions
|
|
@ -5682,11 +5682,12 @@ void wallet2::update_asset(const crypto::public_key& asset_id, const currency::a
|
|||
ctp.tx_meaning_for_logs = "asset update";
|
||||
|
||||
bool send_to_network = true;
|
||||
if (last_adb.owner_eth_pub_key.has_value())
|
||||
if (own_asset_entry_it->second.thirdparty_custody || last_adb.owner_eth_pub_key.has_value())
|
||||
{
|
||||
send_to_network = false;
|
||||
ctp.additional_transfer_flags_to_mark = WALLET_TRANSFER_DETAIL_FLAG_ASSET_OP_RESERVATION;
|
||||
ctp.tx_meaning_for_logs = "asset eth update";
|
||||
ctp.ado_sign_thirdparty = true;
|
||||
}
|
||||
|
||||
this->transfer(ctp, ft, send_to_network, nullptr);
|
||||
|
|
@ -5724,11 +5725,12 @@ void wallet2::transfer_asset_ownership(const crypto::public_key& asset_id, const
|
|||
ctp.tx_meaning_for_logs = "transfer asset ownership";
|
||||
|
||||
bool send_to_network = true;
|
||||
if (last_adb.owner_eth_pub_key.has_value())
|
||||
if (own_asset_entry_it->second.thirdparty_custody || last_adb.owner_eth_pub_key.has_value())
|
||||
{
|
||||
send_to_network = false;
|
||||
ctp.additional_transfer_flags_to_mark = WALLET_TRANSFER_DETAIL_FLAG_ASSET_OP_RESERVATION;
|
||||
ctp.tx_meaning_for_logs = "transfer asset eth ownership";
|
||||
ctp.ado_sign_thirdparty = true;
|
||||
}
|
||||
|
||||
this->transfer(ctp, ft, send_to_network, nullptr);
|
||||
|
|
|
|||
|
|
@ -2113,13 +2113,13 @@ namespace wallet_public
|
|||
struct request
|
||||
{
|
||||
crypto::public_key asset_id;
|
||||
crypto::eth_public_key owner_eth_pub_key = currency::null_eth_public_key; // note: the size is 33 bytes (if present)
|
||||
crypto::public_key owner = currency::null_pkey; // regular Zano Ed25519 public key
|
||||
crypto::eth_public_key new_owner_eth_pub_key = currency::null_eth_public_key; // note: the size is 33 bytes (if present)
|
||||
crypto::public_key new_owner = currency::null_pkey; // regular Zano Ed25519 public key
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("Own asset id, that would be transfered to someone else") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END
|
||||
KV_SERIALIZE_POD_AS_HEX_STRING(owner) DOC_DSCR("Public key of the new owner(default Ed25519 public key, 32 bytes)") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END
|
||||
KV_SERIALIZE_POD_AS_HEX_STRING(owner_eth_pub_key) DOC_DSCR("Public key of the new owner(ECDSA public key, 33 bytes) Used only if 'owner' field is empty") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a84d") DOC_END
|
||||
KV_SERIALIZE_POD_AS_HEX_STRING(new_owner) DOC_DSCR("Public key of the new owner(default Ed25519 public key, 32 bytes)") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END
|
||||
KV_SERIALIZE_POD_AS_HEX_STRING(new_owner_eth_pub_key) DOC_DSCR("Public key of the new owner(ECDSA public key, 33 bytes) Used only if 'owner' field is empty") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a84d") DOC_END
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1470,13 +1470,13 @@ namespace tools
|
|||
{
|
||||
WALLET_RPC_BEGIN_TRY_ENTRY();
|
||||
currency::asset_owner_pub_key_v new_owner_v;
|
||||
if (req.owner != currency::null_pkey)
|
||||
if (req.new_owner!= currency::null_pkey)
|
||||
{
|
||||
new_owner_v = req.owner;
|
||||
new_owner_v = req.new_owner;
|
||||
}
|
||||
else if(req.owner_eth_pub_key != currency::null_eth_public_key)
|
||||
else if(req.new_owner_eth_pub_key != currency::null_eth_public_key)
|
||||
{
|
||||
new_owner_v = req.owner_eth_pub_key;
|
||||
new_owner_v = req.new_owner_eth_pub_key;
|
||||
}else
|
||||
{
|
||||
res.status = API_RETURN_CODE_BAD_ARG_INVALID_ADDRESS;
|
||||
|
|
|
|||
|
|
@ -955,6 +955,64 @@ bool wallet_rpc_thirdparty_custody::generate(std::vector<test_event_entry>& even
|
|||
#define TEST_TOKEN_MAX_SUPPLY 2000
|
||||
#define TEST_TOKEN_CURRENT_SUPPLY 1000
|
||||
|
||||
|
||||
|
||||
typedef boost::variant<crypto::secret_key, crypto::eth_secret_key> secret_key_v;
|
||||
typedef boost::variant<crypto::public_key, crypto::eth_public_key> public_key_v;
|
||||
|
||||
|
||||
template<typename t_response>
|
||||
bool sign_signature_with_keys(const t_response& rsp_with_data, tools::wallet_rpc_server& attached_wallet_rpc, const secret_key_v& signer_v, const public_key_v& verifier)
|
||||
{
|
||||
bool r = false;
|
||||
tools::wallet_public::COMMAND_ASSET_SEND_EXT_SIGNED_TX::request send_signed_req = AUTO_VAL_INIT(send_signed_req);
|
||||
if (signer_v.type() == typeid(crypto::secret_key))
|
||||
{
|
||||
//schnor sig
|
||||
const crypto::secret_key& signer = boost::get<crypto::secret_key>(signer_v);
|
||||
crypto::signature sig = AUTO_VAL_INIT(sig);
|
||||
crypto::generic_schnorr_sig sig_sch = AUTO_VAL_INIT(sig_sch);
|
||||
r = crypto::generate_schnorr_sig(rsp_with_data.tx_id, signer, sig_sch);
|
||||
CHECK_AND_ASSERT_MES(r, false, "gailed to generate schnorr signature");
|
||||
|
||||
//crypto::generate_signature(emm_resp.tx_id, miner_wlt->get_account().get_keys().account_address.spend_public_key, miner_wlt->get_account().get_keys().spend_secret_key, sig);
|
||||
// instant verification, just in case
|
||||
r = crypto::verify_schnorr_sig(rsp_with_data.tx_id, boost::get<crypto::public_key>(verifier), sig_sch);
|
||||
CHECK_AND_ASSERT_MES(r, false, "verify_schnorr_sig failed");
|
||||
currency::schnor_new_to_schnor_old(sig_sch, sig);
|
||||
|
||||
send_signed_req.regular_sig = sig;
|
||||
}
|
||||
else if (signer_v.type() == typeid(crypto::eth_secret_key))
|
||||
{
|
||||
////ecdsa sig
|
||||
const crypto::eth_secret_key& signer = boost::get<crypto::eth_secret_key>(signer_v);
|
||||
r = crypto::generate_eth_signature(rsp_with_data.tx_id, signer, send_signed_req.eth_sig);
|
||||
CHECK_AND_ASSERT_MES(r, false, "gailed to generate schnorr signature");
|
||||
|
||||
r = crypto::verify_eth_signature(rsp_with_data.tx_id, boost::get<crypto::eth_public_key>(verifier), send_signed_req.eth_sig);
|
||||
CHECK_AND_ASSERT_MES(r, false, "verify_eth_signature failed");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
send_signed_req.unsigned_tx = rsp_with_data.data_for_external_signing->unsigned_tx;
|
||||
send_signed_req.expected_tx_id = rsp_with_data.tx_id;
|
||||
send_signed_req.finalized_tx = rsp_with_data.data_for_external_signing->finalized_tx;
|
||||
send_signed_req.unlock_transfers_on_fail = true;
|
||||
tools::wallet_public::COMMAND_ASSET_SEND_EXT_SIGNED_TX::response send_signed_resp{};
|
||||
|
||||
r = invoke_text_json_for_rpc(attached_wallet_rpc, "send_ext_signed_asset_tx", send_signed_req, send_signed_resp);
|
||||
CHECK_AND_ASSERT_MES(r, false, "RPC send_ext_signed_asset_tx failed: ");
|
||||
CHECK_AND_ASSERT_MES(send_signed_resp.status == API_RETURN_CODE_OK, false, "RPC send_ext_signed_asset_tx failed: ");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool wallet_rpc_thirdparty_custody::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
|
||||
|
|
@ -1040,9 +1098,10 @@ bool wallet_rpc_thirdparty_custody::c1(currency::core& c, size_t ev_index, const
|
|||
//let's emit it, but transfer actually to Bob, by using Alice wallet as attache
|
||||
tools::wallet_public::COMMAND_ASSETS_EMIT::request emm_req = AUTO_VAL_INIT(emm_req);
|
||||
tools::wallet_public::COMMAND_ASSETS_EMIT::response emm_resp = AUTO_VAL_INIT(emm_resp);
|
||||
#define COINS_TO_TRANSFER 10
|
||||
|
||||
emm_req.asset_id = resp.new_asset_id;
|
||||
emm_req.destinations.push_back(tools::wallet_public::transfer_destination{10, bob_wlt->get_account().get_public_address_str(), emm_req.asset_id });
|
||||
emm_req.destinations.push_back(tools::wallet_public::transfer_destination{ COINS_TO_TRANSFER, bob_wlt->get_account().get_public_address_str(), emm_req.asset_id });
|
||||
r = invoke_text_json_for_rpc(alice_wlt_rpc, "emit_asset", emm_req, emm_resp);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to call");
|
||||
if (!emm_resp.data_for_external_signing)
|
||||
|
|
@ -1051,33 +1110,9 @@ bool wallet_rpc_thirdparty_custody::c1(currency::core& c, size_t ev_index, const
|
|||
return false;
|
||||
}
|
||||
|
||||
crypto::signature sig = AUTO_VAL_INIT(sig);
|
||||
crypto::generic_schnorr_sig sig_sch = AUTO_VAL_INIT(sig_sch);
|
||||
r = crypto::generate_schnorr_sig(emm_resp.tx_id, miner_wlt->get_account().get_keys().spend_secret_key, sig_sch);
|
||||
CHECK_AND_ASSERT_MES(r, false, "gailed to generate schnorr signature");
|
||||
r = sign_signature_with_keys(emm_resp, alice_wlt_rpc, miner_wlt->get_account().get_keys().spend_secret_key, miner_wlt->get_account().get_keys().account_address.spend_public_key);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to call sign_signature_with_keys");
|
||||
|
||||
//crypto::generate_signature(emm_resp.tx_id, miner_wlt->get_account().get_keys().account_address.spend_public_key, miner_wlt->get_account().get_keys().spend_secret_key, sig);
|
||||
// instant verification, just in case
|
||||
r = crypto::verify_schnorr_sig(emm_resp.tx_id, miner_wlt->get_account().get_keys().account_address.spend_public_key, sig_sch);
|
||||
CHECK_AND_ASSERT_MES(r, false, "verify_schnorr_sig failed");
|
||||
currency::schnor_new_to_schnor_old(sig_sch, sig);
|
||||
|
||||
|
||||
//
|
||||
// send ETH signature alogn with all previous data to a wallet RPC call for final tx assembling and broadcasting
|
||||
//
|
||||
tools::wallet_public::COMMAND_ASSET_SEND_EXT_SIGNED_TX::request send_signed_req = AUTO_VAL_INIT(send_signed_req);
|
||||
send_signed_req.unsigned_tx = emm_resp.data_for_external_signing->unsigned_tx;
|
||||
send_signed_req.regular_sig = sig;
|
||||
send_signed_req.expected_tx_id = emm_resp.tx_id;
|
||||
send_signed_req.finalized_tx = emm_resp.data_for_external_signing->finalized_tx;
|
||||
send_signed_req.unlock_transfers_on_fail = true;
|
||||
tools::wallet_public::COMMAND_ASSET_SEND_EXT_SIGNED_TX::response send_signed_resp{};
|
||||
|
||||
r = invoke_text_json_for_rpc(alice_wlt_rpc, "send_ext_signed_asset_tx", send_signed_req, send_signed_resp);
|
||||
CHECK_AND_ASSERT_MES(r, false, "RPC send_ext_signed_asset_tx failed: ");
|
||||
CHECK_AND_ASSERT_MES(send_signed_resp.status == API_RETURN_CODE_OK, false, "RPC send_ext_signed_asset_tx failed: ");
|
||||
|
||||
r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, 3);
|
||||
|
||||
|
||||
|
|
@ -1097,6 +1132,75 @@ bool wallet_rpc_thirdparty_custody::c1(currency::core& c, size_t ev_index, const
|
|||
CHECK_AND_ASSERT_MES(r, false, "RPC send_ext_signed_asset_tx failed: ");
|
||||
|
||||
|
||||
bool found_asset = false;
|
||||
for (auto& bal : balance_resp.balances)
|
||||
{
|
||||
if (bal.asset_info.asset_id == resp.new_asset_id)
|
||||
{
|
||||
found_asset = true;
|
||||
CHECK_AND_ASSERT_MES(bal.total == COINS_TO_TRANSFER, false, "Amount is unexpected");
|
||||
}
|
||||
}
|
||||
CHECK_AND_ASSERT_MES(found_asset, false, "Asset not found ");
|
||||
|
||||
|
||||
|
||||
//transfer ownership of the asset to new address
|
||||
//let's change the owner to ecdsa
|
||||
crypto::eth_secret_key eth_sk_2{};
|
||||
crypto::eth_public_key eth_pk_2{};
|
||||
r = crypto::generate_eth_key_pair(eth_sk_2, eth_pk_2);
|
||||
CHECK_AND_ASSERT_MES(r, false, "generate_eth_key_pair failed");
|
||||
|
||||
tools::wallet_public::COMMAND_TRANSFER_ASSET_OWNERSHIP::request req_own = AUTO_VAL_INIT(req_own);
|
||||
tools::wallet_public::COMMAND_TRANSFER_ASSET_OWNERSHIP::response res_own = AUTO_VAL_INIT(res_own);
|
||||
req_own.asset_id = resp.new_asset_id;
|
||||
req_own.new_owner_eth_pub_key = eth_pk_2;
|
||||
|
||||
|
||||
r = invoke_text_json_for_rpc(alice_wlt_rpc, "transfer_asset_ownership", req_own, res_own);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to call");
|
||||
if (!res_own.data_for_external_signing)
|
||||
{
|
||||
LOG_ERROR("Missing data_for_external_signing");
|
||||
return false;
|
||||
}
|
||||
|
||||
r = sign_signature_with_keys(res_own, alice_wlt_rpc, miner_wlt->get_account().get_keys().spend_secret_key, miner_wlt->get_account().get_keys().account_address.spend_public_key);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to call sign_signature_with_keys");
|
||||
|
||||
r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, 3);
|
||||
|
||||
|
||||
//now make another tx and see of ownership got changed
|
||||
emm_resp = AUTO_VAL_INIT(emm_resp);
|
||||
r = invoke_text_json_for_rpc(alice_wlt_rpc, "emit_asset", emm_req, emm_resp);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to call");
|
||||
if (!emm_resp.data_for_external_signing)
|
||||
{
|
||||
LOG_ERROR("Missing data_for_external_signing");
|
||||
return false;
|
||||
}
|
||||
|
||||
r = sign_signature_with_keys(emm_resp, alice_wlt_rpc, eth_sk_2, eth_pk_2);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to call sign_signature_with_keys");
|
||||
|
||||
r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, 3);
|
||||
|
||||
r = invoke_text_json_for_rpc(bob_wlt_rpc, "getbalance", balance_req, balance_resp);
|
||||
CHECK_AND_ASSERT_MES(r, false, "RPC send_ext_signed_asset_tx failed: ");
|
||||
|
||||
found_asset = false;
|
||||
for (auto& bal : balance_resp.balances)
|
||||
{
|
||||
if (bal.asset_info.asset_id == resp.new_asset_id)
|
||||
{
|
||||
found_asset = true;
|
||||
CHECK_AND_ASSERT_MES(bal.total == COINS_TO_TRANSFER, false, "Amount is unexpected");
|
||||
}
|
||||
}
|
||||
CHECK_AND_ASSERT_MES(found_asset, false, "Asset not found ");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue