diff options
author | stoffu <stoffu@protonmail.ch> | 2017-09-12 10:05:41 +0900 |
---|---|---|
committer | stoffu <stoffu@protonmail.ch> | 2017-11-18 20:44:27 +0900 |
commit | 998777ecd71fee25636f6ef40f05f88251d03e96 (patch) | |
tree | d3cc8cf38b70cd10678e9ef1d3a36f2ac7e8386d /src/wallet/wallet_rpc_server.cpp | |
parent | Merge pull request #2818 (diff) | |
download | monero-998777ecd71fee25636f6ef40f05f88251d03e96.tar.xz |
Tx proof (revised):
- refactoring: proof generation/checking code was moved from simplewallet.cpp to wallet2.cpp
- allow an arbitrary message to be signed together with txid
- introduce two types (outbound & inbound) of tx proofs; with the same syntax, inbound is selected when <address> belongs to this wallet, outbound otherwise. see GitHub thread for more discussion
- wallet RPC: added get_tx_key, check_tx_key, get_tx_proof, check_tx_proof
- wallet API: moved WalletManagerImpl::checkPayment to Wallet::checkTxKey, added Wallet::getTxProof/checkTxProof
- get_tx_key/check_tx_key: handle additional tx keys by concatenating them into a single string
Diffstat (limited to 'src/wallet/wallet_rpc_server.cpp')
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index f5838d013..dca8ebd7e 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -623,6 +623,8 @@ namespace tools if (req.get_tx_key) { res.tx_key = epee::string_tools::pod_to_hex(ptx_vector.back().tx_key); + for (const crypto::secret_key& additional_tx_key : ptx_vector.back().additional_tx_keys) + res.tx_key += epee::string_tools::pod_to_hex(additional_tx_key); } res.fee = ptx_vector.back().fee; @@ -685,6 +687,8 @@ namespace tools if (req.get_tx_keys) { res.tx_key_list.push_back(epee::string_tools::pod_to_hex(ptx.tx_key)); + for (const crypto::secret_key& additional_tx_key : ptx.additional_tx_keys) + res.tx_key_list.back() += epee::string_tools::pod_to_hex(additional_tx_key); } // Compute amount leaving wallet in tx. By convention dests does not include change outputs ptx_amount = 0; @@ -1396,6 +1400,163 @@ namespace tools res.value = m_wallet->get_attribute(req.key); return true; } + bool wallet_rpc_server::on_get_tx_key(const wallet_rpc::COMMAND_RPC_GET_TX_KEY::request& req, wallet_rpc::COMMAND_RPC_GET_TX_KEY::response& res, epee::json_rpc::error& er) + { + if (!m_wallet) return not_open(er); + + crypto::hash txid; + if (!epee::string_tools::hex_to_pod(req.txid, txid)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_TXID; + er.message = "TX ID has invalid format"; + return false; + } + + crypto::secret_key tx_key; + std::vector<crypto::secret_key> additional_tx_keys; + if (!m_wallet->get_tx_key(txid, tx_key, additional_tx_keys)) + { + er.code = WALLET_RPC_ERROR_CODE_NO_TXKEY; + er.message = "No tx secret key is stored for this tx"; + return false; + } + + std::ostringstream oss; + oss << epee::string_tools::pod_to_hex(tx_key); + for (size_t i = 0; i < additional_tx_keys.size(); ++i) + oss << epee::string_tools::pod_to_hex(additional_tx_keys[i]); + res.tx_key = oss.str(); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_check_tx_key(const wallet_rpc::COMMAND_RPC_CHECK_TX_KEY::request& req, wallet_rpc::COMMAND_RPC_CHECK_TX_KEY::response& res, epee::json_rpc::error& er) + { + if (!m_wallet) return not_open(er); + + crypto::hash txid; + if (!epee::string_tools::hex_to_pod(req.txid, txid)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_TXID; + er.message = "TX ID has invalid format"; + return false; + } + + std::string tx_key_str = req.tx_key; + crypto::secret_key tx_key; + if (!epee::string_tools::hex_to_pod(tx_key_str.substr(0, 64), tx_key)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY; + er.message = "Tx key has invalid format"; + return false; + } + tx_key_str = tx_key_str.substr(64); + std::vector<crypto::secret_key> additional_tx_keys; + while (!tx_key_str.empty()) + { + additional_tx_keys.resize(additional_tx_keys.size() + 1); + if (!epee::string_tools::hex_to_pod(tx_key_str.substr(0, 64), additional_tx_keys.back())) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY; + er.message = "Tx key has invalid format"; + return false; + } + tx_key_str = tx_key_str.substr(64); + } + + cryptonote::address_parse_info info; + if(!get_account_address_from_str(info, m_wallet->testnet(), req.address)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; + er.message = "Invalid address"; + return false; + } + + try + { + m_wallet->check_tx_key(txid, tx_key, additional_tx_keys, info.address, res.received, res.in_pool, res.confirmations); + } + catch (const std::exception &e) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = e.what(); + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_get_tx_proof(const wallet_rpc::COMMAND_RPC_GET_TX_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_TX_PROOF::response& res, epee::json_rpc::error& er) + { + if (!m_wallet) return not_open(er); + + crypto::hash txid; + if (!epee::string_tools::hex_to_pod(req.txid, txid)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_TXID; + er.message = "TX ID has invalid format"; + return false; + } + + cryptonote::address_parse_info info; + if(!get_account_address_from_str(info, m_wallet->testnet(), req.address)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; + er.message = "Invalid address"; + return false; + } + + try + { + res.signature = m_wallet->get_tx_proof(txid, info.address, info.is_subaddress, req.message, er.message); + if (res.signature.empty()) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + return false; + } + } + catch (const std::exception &e) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = e.what(); + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_check_tx_proof(const wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF::response& res, epee::json_rpc::error& er) + { + if (!m_wallet) return not_open(er); + + crypto::hash txid; + if (!epee::string_tools::hex_to_pod(req.txid, txid)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_TXID; + er.message = "TX ID has invalid format"; + return false; + } + + cryptonote::address_parse_info info; + if(!get_account_address_from_str(info, m_wallet->testnet(), req.address)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; + er.message = "Invalid address"; + return false; + } + + try + { + uint64_t received; + bool in_pool; + uint64_t confirmations; + res.good = m_wallet->check_tx_proof(txid, info.address, info.is_subaddress, req.message, req.signature, res.received, res.in_pool, res.confirmations); + } + catch (const std::exception &e) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = e.what(); + return false; + } + return true; + } //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_get_transfers(const wallet_rpc::COMMAND_RPC_GET_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFERS::response& res, epee::json_rpc::error& er) { |