diff --git a/main.cpp b/main.cpp index b257bf6..e1c56e9 100644 --- a/main.cpp +++ b/main.cpp @@ -214,7 +214,7 @@ int main(int ac, const char* av[]) { return xmrblocks.show_rawtx(); }); - CROW_ROUTE(app, "/checkrawtx").methods("POST"_method) + CROW_ROUTE(app, "/checkandpush").methods("POST"_method) ([&](const crow::request& req) { map post_body = xmreg::parse_crow_post_data(req.body); @@ -227,23 +227,11 @@ int main(int ac, const char* av[]) { string raw_tx_data = post_body["rawtxdata"]; string action = post_body["action"]; - return xmrblocks.show_checkrawtx(raw_tx_data, action); - }); - - CROW_ROUTE(app, "/pushrawtx").methods("POST"_method) - ([&](const crow::request& req) { - - map post_body = xmreg::parse_crow_post_data(req.body); - - if (post_body.count("rawtxdata") == 0 || post_body.count("action") == 0) - { - return string("Raw tx data or action not provided"); - } - - string raw_tx_data = post_body["rawtxdata"]; - string action = post_body["action"]; + if (action == "check") + return xmrblocks.show_checkrawtx(raw_tx_data, action); + else if (action == "push") + return xmrblocks.show_pushrawtx(raw_tx_data, action); - return xmrblocks.show_pushrawtx(raw_tx_data, action); }); diff --git a/src/page.h b/src/page.h index 2587bb7..9781922 100644 --- a/src/page.h +++ b/src/page.h @@ -1511,6 +1511,9 @@ namespace xmreg { mstch::map tx_context = construct_tx_context(ptx.tx); + // mark that we have signed tx data for use in mstch + tx_context["have_raw_tx"] = true; + // get reference to inputs array created of the tx mstch::array& inputs = boost::get(tx_context["inputs"]); @@ -1622,7 +1625,7 @@ namespace xmreg { const size_t magiclen = strlen(SIGNED_TX_PREFIX); - if (!strncmp(decoded_raw_tx_data.c_str(), SIGNED_TX_PREFIX, magiclen) != 0) + if (strncmp(decoded_raw_tx_data.c_str(), SIGNED_TX_PREFIX, magiclen) != 0) { cout << "The data does not appear to be signed raw tx!" << endl; return string( "The data does not appear to be signed raw tx!"); @@ -1647,9 +1650,60 @@ namespace xmreg { // actually commit the transactions while (!ptx_vector.empty()) { - auto & ptx = ptx_vector.back(); - //m_wallet->commit_tx(ptx); - //success_msg_writer(true) << tr("Money successfully sent, transaction: ") << get_transaction_hash(ptx.tx); + tools::wallet2::pending_tx& ptx = ptx_vector.back(); + + tx_details txd = get_tx_details(ptx.tx); + + string tx_hash_str = REMOVE_HASH_BRAKETS(fmt::format("{:s}", txd.hash)); + + // check in mempool already contains tx to be submited + vector> found_mempool_txs + = search_mempool(txd.hash); + + if (!found_mempool_txs.empty()) + { + cerr << "Tx already exist in the mempool: " << tx_hash_str << endl; + return string("Tx already exist in the mempool: " + tx_hash_str); + } + + // check if tx to be submited already exists in the blockchain + if (core_storage->have_tx(txd.hash)) + { + cerr << "Tx already exist in the blockchain: " << tx_hash_str << endl; + return string("Tx already exist in the blockchain: " + tx_hash_str); + } + + // check if any key images of the tx to be submited are already spend + vector key_images_spent; + + for (const txin_to_key& tx_in: txd.input_key_imgs) + { + if (core_storage->have_tx_keyimg_as_spent(tx_in.k_image)) + key_images_spent.push_back(tx_in.k_image); + } + + if (!key_images_spent.empty()) + { + string key_images_str("Already spent inputs's key images:
"); + + for (key_image& k_img: key_images_spent) + { + key_images_str += REMOVE_HASH_BRAKETS(fmt::format("{:s}", k_img)); + key_images_str += "
"; + } + + cerr << "submitting signed tx has already spend inputs: " << key_images_str << endl; + + return string("submitting signed tx has already spend inputs: " + key_images_str); + } + + string error_msg; + + if (!rpc.commit_tx(ptx, error_msg)) + { + cerr << "submitting signed tx to daemon failed: " << error_msg << endl; + return string("submitting signed tx to daemon failed: " + error_msg); + } // if no exception, remove element from vector ptx_vector.pop_back(); diff --git a/src/rpccalls.h b/src/rpccalls.h index f2368b7..ac92807 100644 --- a/src/rpccalls.h +++ b/src/rpccalls.h @@ -105,6 +105,38 @@ namespace xmreg return true; } + + + bool + commit_tx(tools::wallet2::pending_tx& ptx, string& error_msg) + { + COMMAND_RPC_SEND_RAW_TX::request req; + COMMAND_RPC_SEND_RAW_TX::response res; + + req.tx_as_hex = epee::string_tools::buff_to_hex_nodelimer( + tx_to_blob(ptx.tx) + ); + + req.do_not_relay = false; + + std::lock_guard guard(m_daemon_rpc_mutex); + + bool r = epee::net_utils::invoke_http_json_remote_command2(deamon_url + + "/sendrawtransaction", + req, res, + m_http_client, 200000);; + + if (!r || res.status == "Failed") + { + error_msg = res.reason; + + cerr << "Error sending tx: " << res.reason << endl; + return false; + } + + return true; + } + }; diff --git a/src/templates/checkrawtx.html b/src/templates/checkrawtx.html index 724fd98..bde313b 100644 --- a/src/templates/checkrawtx.html +++ b/src/templates/checkrawtx.html @@ -136,10 +136,9 @@
-

Details of submitted raw tx data

- {{#unsigned_tx_given}} -

unsigned_tx_given: {{unsigned_tx_given}}

+

Details of unsigned raw tx data given

+ {{#txs}}

Destination information

@@ -182,7 +181,8 @@ {{/unsigned_tx_given}} {{^unsigned_tx_given}} -

signed_tx_given

+

Details of signed raw tx data given

+ {{#txs}} {{>tx_details}} {{/txs}} diff --git a/src/templates/rawtx.html b/src/templates/rawtx.html index 9141b68..d412230 100644 --- a/src/templates/rawtx.html +++ b/src/templates/rawtx.html @@ -145,6 +145,7 @@
Paste base64 encoded, signed transaction data here
+ (In Linux, can get base64 signed raw tx data: base64 signed_monero_tx | xclip -selection clipboard)