You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1665 lines
262 KiB

//
// test_all.cpp
// MyMonero
//
5 years ago
// Copyright (c) 2014-2019, MyMonero.com
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
// Test module setup
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE LibMoneroTests
#include <boost/test/unit_test.hpp> // last
//
// Includes & namespaces
#include <iostream>
#include <iterator>
#include <sstream>
using namespace std;
#include "string_tools.h"
using namespace epee;
using namespace boost;
#include "cryptonote_format_utils.h"
#include <boost/property_tree/json_parser.hpp>
//
#include "monero_fork_rules.hpp"
//
#include "serial_bridge_utils.hpp"
using namespace serial_bridge_utils;
//
// Shared code
//
// Test suites
#include "../src/monero_address_utils.hpp"
BOOST_AUTO_TEST_CASE(decodeAddress)
{
string address = "43zxvpcj5Xv9SEkNXbMCG7LPQStHMpFCQCmkmR4u5nzjWwq5Xkv5VmGgYEsHXg4ja2FGRD5wMWbBVMijDTqmmVqm93wHGkg";
auto result = monero::address_utils::decodedAddress(address, cryptonote::MAINNET);
if (result.err_string) {
std::cout << *result.err_string << endl;
BOOST_REQUIRE(!result.err_string);
}
BOOST_REQUIRE(result.pub_viewKey_string != none);
BOOST_REQUIRE(result.pub_spendKey_string != none);
BOOST_REQUIRE(result.isSubaddress == false);
BOOST_REQUIRE(result.paymentID_string == none);
std::cout << "decodeAddress: " << address << std::endl;
}
//
//
#include "../src/monero_paymentID_utils.hpp"
BOOST_AUTO_TEST_CASE(paymentID)
{
string paymentID_string = monero_paymentID_utils::new_short_plain_paymentID_string();
std::cout << "paymentID: paymentID_string: " << paymentID_string << std::endl;
BOOST_REQUIRE_MESSAGE(paymentID_string.size() == 16, "Expected payment ID to be of length 16");
//
crypto::hash parsed__payment_id;
bool didParse = monero_paymentID_utils::parse_payment_id(paymentID_string, parsed__payment_id);
BOOST_REQUIRE_MESSAGE(didParse, "Couldn't parse payment ID");
std::string parsed__payment_id_as_string = epee::string_tools::pod_to_hex(parsed__payment_id);
BOOST_REQUIRE_MESSAGE(paymentID_string.compare(parsed__payment_id_as_string), "Expected parsed payment ID to equal original payment ID");
std::cout << "paymentID: parsed__payment_id: " << parsed__payment_id << std::endl;
}
//
//
#include "../src/monero_key_image_utils.hpp"
BOOST_AUTO_TEST_CASE(keyImage)
{
}
//
//
#include "../src/monero_wallet_utils.hpp"
BOOST_AUTO_TEST_CASE(wallet)
{
}
//
//
#include "../src/monero_transfer_utils.hpp"
#include "../src/monero_fork_rules.hpp"
BOOST_AUTO_TEST_CASE(transfers__fee)
{
uint8_t fork_version = 10;
auto use_fork_rules_fn = monero_fork_rules::make_use_fork_rules_fn(fork_version);
uint64_t fee_per_b = 24658;
uint32_t priority = 2;
uint64_t est_fee = monero_fee_utils::estimated_tx_network_fee(fee_per_b, priority, use_fork_rules_fn);
std::cout << "transfers__fee: est_fee with fee_per_b " << fee_per_b << ": " << est_fee << std::endl;
BOOST_REQUIRE(est_fee > 0);
}
//
//
// Serialization bridge
//
#include "../src/serial_bridge_index.hpp"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
//
string args_string_from_root(const boost::property_tree::ptree &root)
{
stringstream args_ss;
boost::property_tree::write_json(args_ss, root, false/*pretty*/);
//
return args_ss.str();
}
//
string DG_presweep__unspent_outs_json = "{\"unspent_outs\":[{\"amount\":\"210000000\",\"public_key\":\"89eb08cf704d4473a17646331d2c425307ef03477e5f18ee6a31a3601ba9cdd0\",\"index\":0,\"global_index\":7510705,\"rct\":\"befe623ad1dcae239e4d9d31e3080db5c339ea8c5c2894444966967a051f27839f1f713d6f6bdc13fec3c20f78bbae6cf08ce185273fa6c913db6ae1f44e270ea9dcfa48ecbae364125e0c4b0cb7a11fe6c250ec9aca1a668a0708e821d6550b\",\"tx_id\":5292354,\"tx_hash\":\"22fa4aaee9399901ece7d9521067aa7791a727ade2dfe9d5e17481800ccbc625\",\"tx_pub_key\":\"4f151192723d3d45372b43e4bf93df8ad7ba5283513c09226fd0603c60683e00\",\"tx_prefix_hash\":\"689580f0804eff0fd9bd76587ed9656e4cda8e70a33f065b5461206bcf9051b7\",\"height\":1681636},{\"amount\":\"230000000\",\"public_key\":\"f659694299d97fc93db504122d40dea1681a896567933635dc6337abc4339c10\",\"index\":1,\"global_index\":7551823,\"rct\":\"dd06d546553044cda0f083fd189cd8ad93ebeca557169eefe1e34dc48c6fac27110a3ff8dc24a61b595a03a034009a6d1f0ced61f19fb6e0d7c2b1a67bb39d06c7d5713e0a394551ec978b64927802f9307ac29c8ddec3857f551b945ef6a407\",\"tx_id\":5309604,\"tx_hash\":\"05704e7402d1373d14dccd383e4071bfae0c2af6eb075e67075b43fd7d26b4c4\",\"tx_pub_key\":\"3511d9117fdeac0423314827188aa187f1eb742a44ab0c01390053b68b00909c\",\"tx_prefix_hash\":\"1b89ac0c818454806686073cd2d6bd501923d6eec2c0e54e300e3ae68a2c5344\",\"height\":1684479},{\"amount\":\"50000000\",\"public_key\":\"6c0828f041fd3383b4823bd619fa9d130b83da8b10aa81bec1f1529890548542\",\"index\":0,\"global_index\":7552032,\"rct\":\"eb3291bd81992ec300e94e8f1bbf0bdfd7bb8b8ac5e1969f985f5642961e30f1bfaf72e1a284ac62da47184165091e2b8673143f8b5d533b9d2143c9e64e5f091a14169fa79f151579eac8e41102244aa148b6142121f5ad1b85d6404c04fd08\",\"tx_id\":5309676,\"tx_hash\":\"22c79cc2e5cefe5b1ed608021efc281f0eab6dbe4cc11051d59cb30b367a5120\",\"tx_pub_key\":\"471fe593e98e65529eeb2b60ad23ad0f7f879a51ef0a41ed34bb371bf346663f\",\"tx_prefix_hash\":\"6551844de3ba9ca5c0a58a8dfcb3fa6b74439c0f1054563ba7cd9a5eee26425d\",\"height\":1684494},{\"amount\":\"100000000\",\"public_key\":\"2721b9cf6cb9e4227cd4c58ea73be9c6e6ebf949d07e90f3cbfc624a18c91933\",\"index\":0,\"global_index\":7571542,\"rct\":\"14972c0692f37de21d4fe2e989262aaef574699258812b39908c6f9f28bfe80f07cae2373c7419eb41bde8425107cd3d87dd0211b1a59e92bad0b09789109d06620a1e4f80dbfa4ada1d432e55b3c23e965e858bc04effb64c473de0da3e4f0a\",\"tx_id\":5318071,\"tx_hash\":\"33fb202b7e1b2382838f17e5078311944870197536df0a560d73605023befcf7\",\"tx_pub_key\":\"3cb2a8fc531565dcc20477ec624fc1ffd60af9f491ab4ec5d54d4e4d6441d0c0\",\"tx_prefix_hash\":\"ce7bec7db0171da5e345103b7d38cdc19fc1db0655e4de8ecbf9b52d11b0ff51\",\"height\":1685790},{\"amount\":\"1630320000\",\"public_key\":\"437e101b61a526098adc98e46c8a674d2b3af3b79cf6ce8947e4effa2b545069\",\"index\":0,\"global_index\":7571614,\"rct\":\"026064f4989c3b19d99d4e3902a6800cdda39127449c639d0d9fcc31d9e4b297211cf6275f64d613cb7b553be07e1d738f72b138c4eaccb91970a10c513f2a005471ce338c4f3ea6bc07a37d10c32236af28c0e85d39ebdf8aa37ce2b9e5060f\",\"tx_id\":5318107,\"tx_hash\":\"19a98217e48c4db9c527dde5c7498317e2a6f258e31c87c3fe8d872d695b44f4\",\"tx_pub_key\":\"95c66b323352e10e7eee3220cc328f89b1b9dd5bfd2da4f61ba5dfcef923722c\",\"tx_prefix_hash\":\"0e053ddb7e60a64a8b501525963a61d8c182f82a66933486e77233055dbce3ac\",\"height\":1685794},{\"amount\":\"100000000\",\"public_key\":\"6a5982bf097116b68fe817abbd31b95821a0d851ac8e4ca34517b1cbe4449501\",\"index\":1,\"global_index\":7571710,\"rct\":\"6d8cd50a778f658b5e2ec7e7e1b8e19e80bb2ece759ed5e40398c33e5983722e45078078a6195d92c3f83d0f443d178a31156702c42f5c4b3e897e9931055f07173349088339daaa080c1f747a9025db0baa60b12beded6c7bc8ce893bda1700\",\"tx_id\":5318152,\"tx_hash\":\"7010c701459d2b897abbfed8f1dbc60b84c4fcd111afd7fcaf60eb1167c0a7a6\",\"tx_pub_key\":\"9321878b374c7f40021635bb03ed966217e5b8e7eb3e125839c55ae48d04ef81\",\"tx_prefix_hash\":\"edb575b5fd86b3e45214742454a4cfcc3d55f1ad457cc598c290dd69d9ebfa73\",\"height\":1685804}]}";
//
string DG_presweep__rand_outs_json = "{\"mix_outs\":[{\"amount\":\"0\",\"outputs\":[{\"global_index\":\"6986524\",\"public_key\":\"3ce9f1231ecebf100a8d0e9c165a2b88a766249cb03eac2c6dbe7587a1f0e9ae\",\"rct\":\"c3b81a937c12c017b4c4eee0ab9acbd10d83f28c1586971b13791c7b475e469b\"},{\"global_index\":\"7282304\",\"public_key\":\"278450b855e4d66dbc1a9ae2801a2f101a10afd22c27466c3cfcc3b434a25047\",\"rct\":\"dd05d1d973be19b4e754c24c6d21e9252a9b99db52ff291930d4cd8c1cd344df\"},{\"global_index\":\"7386837\",\"public_key\":\"0d3cf94dd4e9059900f14bd8d5b71ce43e444efd2b8a1a63a1f9705851d195a1\",\"rct\":\"5c124e0c007e8a2f6371a6d35d50165178667fa9470270e8d7a95ffda34df30d\"},{\"global_index\":\"7459325\",\"public_key\":\"badabeeb71f08917b0cb76ae128e869dab7291d58c7a6b2fbd31d3eed0f003df\",\"rct\":\"a5ca005346fad19624c185dfefb2c4013f6b769f0f0de4b2c8f507ede1cb46a5\"},{\"global_index\":\"7507948\",\"public_key\":\"6f08278bc9d064cfdaa6d896ef70d28fbb3dca84e0a99ea21325f9aaef3bd783\",\"rct\":\"4a70f95a4cc19d9e43cc6b60f30f60571029240df21fb06188766bf92e8d8738\"},{\"global_index\":\"7529692\",\"public_key\":\"8b13f88507f5ca60c72c076ce6bc8ee142abc6e5115ab0c08e10a919c93f912a\",\"rct\":\"6055a2a847938471bd6f00a4d9789e6dc9d70962bb1dc2f51879d04211aaa0b7\"},{\"global_index\":\"7563051\",\"public_key\":\"d44a722cdca3c372081af6e32b758a2bbab9f2534f68a08b71d38c3540209c50\",\"rct\":\"b5ebd41d0c75877cdf109d6b5939072c22a84aee4c46a8299bec8eafc82789e9\"},{\"global_index\":\"7564143\",\"public_key\":\"c12f9e3c53dee0d1327dbca66129b27f8c6174a777976615ee442278960ba369\",\"rct\":\"a8423b9491162813589d3af5e18677f2f38050c10cb5074c097f101ccef089c5\"},{\"global_index\":\"7567982\",\"public_key\":\"9e4347089b0e1cb065cb443899d77b4bd4d61598e80a8946336440920c8a6731\",\"rct\":\"00fc0e9c631a4a2538785b647e6146ba39743d9dc987059f850d1c5a4f97bd2b\"},{\"global_index\":\"7570259\",\"public_key\":\"1be949046425c646a86ac37961a6301ea3d25711426d80a48b11e9282acd222b\",\"rct\":\"7db9d60ac0286189a1833f39db7f3e5372763c557fe2240b4537bf580a902798\"},{\"global_index\":\"7570451\",\"public_key\":\"82a27a521340220805de27aae18a4663b81067145c0b0c3e7ec42341067bf270\",\"rct\":\"a3f46fdc3e4a252604e3f3d082ab1d2cbc3ce34bf62b641b76849c5382199a32\"}]},{\"amount\":\"0\",\"outputs\":[{\"global_index\":\"7442603\",\"public_key\":\"ba89de37e26056629c89b14b3b05a73400c62149fa0de2794d3876f17faeb28f\",\"rct\":\"aa2edfca6622db354add0813ff2b471f6dc20f0d9e56d1f9b6c04b1369ceb1a9\"},{\"global_index\":\"7445670\",\"public_key\":\"a0c3a8bd0d6fa37e7bd514a10ebe6970609919e2f781dc489b771f305f1da4cc\",\"rct\":\"eb78b914307a54cd95481ba8844df3dd2d12cd14cee07de441c2c607b9cfcb24\"},{\"global_index\":\"7474646\",\"public_key\":\"3d325a1222b77d82192e1c051b241e0f79e1cc731c5f03749df33cf1a7165be8\",\"rct\":\"821bfcb255fc815aeab23d890ba252dc590c743c5733bcd278dbd1763e921e4d\"},{\"global_index\":\"7545722\",\"public_key\":\"ec62838ef1ab75055940fd8f31126698af9ff2128a53def09bdaa0d315174d80\",\"rct\":\"547de3a10658167afee6aaf8f3481921d2b1ee3014d40fa4cacc86940b244985\"},{\"global_index\":\"7556262\",\"public_key\":\"4dab027c001473b775f70503b9d68c156d2a8bfa0d7534aaff12a2ab1d8d5f89\",\"rct\":\"5aa838a2f5450408932b53181899861600d3cac864dee8197ac7e9543fbab148\"},{\"global_index\":\"7557709\",\"public_key\":\"bd1813a780e4df3c8ba25b825c3d7be12ce8c5d05f6731384e0d2d8cb8bf3134\",\"rct\":\"49ce757933cdca4a51f77ae41b951a2175d0a0a0378c10c3a02432e5aeb9f79f\"},{\"global_index\":\"7560040\",\"public_key\":\"ea53143df34ccba3c29743964ddc14094f224fa92d45c8fa8e86d7ff1394e51a\",\"rct\":\"455a6083ab6c3d4f026d2b4e1545467666f7affa0cdec365a295c097eefeac46\"},{\"global_index\":\"7563671\",\"public_key\":\"9af80a727bdb148851e79a9a11f55e97435daf65b3d57b54f4d64833cd483f2b\",\"rct\":\"622855010cd03a04d66d71a20d6113cb0507276b4c6ef050297a12e0a6767004\"},{\"global_index\":\"7564234\",\"public_key\":\"404aedc1c299e9a1538bdf7619f42cbf92cb3bb556e0356dce275945e318633d\",\"rct\":\"a1978e496622c2fac054939227a4edb31c4a50215cf8db74b0f1a7ce3477e3cf\"},{\"global_index\":\"7565705\",\"public_key\":\"070c5adc791d0a33390fecb02376e8953e46661a0173a64c003b5ae5709eea3c\",\"rct\":\"09f6c3c9139eef
//
BOOST_AUTO_TEST_CASE(bridge__transfers__send__sweepDust)
{
using namespace serial_bridge;
using namespace monero_transfer_utils;
//
// this being input as JSON merely for convenience
boost::property_tree::ptree pt;
stringstream ss;
ss << DG_presweep__unspent_outs_json;
boost::property_tree::json_parser::read_json(ss, pt);
boost::property_tree::ptree unspent_outs = pt.get_child("unspent_outs");
//
// NOTE: in the real algorithm you should re-request this _each time step2 must be called_
// this being input as JSON merely for convenience
boost::property_tree::ptree mix_outs;
{
boost::property_tree::ptree pt;
stringstream ss;
ss << DG_presweep__rand_outs_json;
boost::property_tree::json_parser::read_json(ss, pt);
mix_outs = pt.get_child("mix_outs");
}
//
// Send algorithm:
// (Not implemented in C++ b/c the algorithm is split at the points (function interfaces) where requests must be done in e.g. JS-land, and implementing the retry integration in C++ would effectively be emscripten-only since it'd have to call out to C++. Plus this lets us retain the choice to retain synchrony
bool tx_must_be_reconstructed = true; // for ease of writing this code, start this off true & structure whole thing as while loop
optional<string> fee_actually_needed_string = none;
size_t construction_attempt_n = 0;
while (tx_must_be_reconstructed) {
construction_attempt_n += 1; // merely kept for assertion purposes
//
optional<string> mixin_string;
optional<string> change_amount_string;
optional<string> using_fee_string;
optional<string> final_total_wo_fee_string;
boost::property_tree::ptree using_outs;
{
boost::property_tree::ptree root;
root.put("is_sweeping", "true");
root.put("payment_id_string", "d2f602b240fbe624"); // optl
root.put("sending_amount", "0");
root.put("fee_per_b", "24658");
root.put("fee_mask", "10000");
root.put("fork_version", "10");
root.put("priority", "1");
root.add_child("unspent_outs", unspent_outs);
if (fee_actually_needed_string != none) {
BOOST_REQUIRE(construction_attempt_n > 1);
//
// for next round's integration - if it needs to re-enter... arg "passedIn_attemptAt_fee"
root.put("passedIn_attemptAt_fee", *fee_actually_needed_string);
}
auto ret_string = serial_bridge::send_step1__prepare_params_for_get_decoys(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<uint32_t> err_code = ret_tree.get_optional<uint32_t>(ret_json_key__any__err_code());
if (err_code != none && (CreateTransactionErrorCode)*err_code != monero_transfer_utils::noError) {
if ((CreateTransactionErrorCode)*err_code == monero_transfer_utils::needMoreMoneyThanFound) {
optional<string> spendable_balance_string = ret_tree.get_optional<string>(ret_json_key__send__spendable_balance());
BOOST_REQUIRE(spendable_balance_string != none);
BOOST_REQUIRE((*spendable_balance_string).size() > 0);
// uint64_t fee = stoull(*fee_string);
// BOOST_REQUIRE(fee == 135000000);
cout << "bridge__transfers__send__sweepDust: step1: needMoreMoneyThanFound: spendable_balance " << *spendable_balance_string << endl;
//
optional<string> required_balance_string = ret_tree.get_optional<string>(ret_json_key__send__required_balance());
BOOST_REQUIRE(required_balance_string != none);
BOOST_REQUIRE((*required_balance_string).size() > 0);
// uint64_t fee = stoull(*fee_string);
// BOOST_REQUIRE(fee == 135000000);
cout << "bridge__transfers__send__sweepDust: step1: needMoreMoneyThanFound: required_balance " << *required_balance_string << endl;
}
auto err_msg = err_msg_from_err_code__create_transaction((CreateTransactionErrorCode)*err_code);
BOOST_REQUIRE_MESSAGE(false, err_msg);
// ^--- not expecting anything like needMoreMoneyThanFound errors here
}
mixin_string = ret_tree.get_optional<string>(ret_json_key__send__mixin());
BOOST_REQUIRE(mixin_string != none);
BOOST_REQUIRE((*mixin_string).size() > 0);
uint64_t mixin = stoull(*mixin_string);
BOOST_REQUIRE(mixin == 10);
cout << "bridge__transfers__send__sweepDust: mixin " << *mixin_string << endl;
//
using_fee_string = ret_tree.get_optional<string>(ret_json_key__send__using_fee()); // save this
BOOST_REQUIRE(using_fee_string != none);
BOOST_REQUIRE((*using_fee_string).size() > 0);
// uint64_t using_fee = stoull(*using_fee_string);
// BOOST_REQUIRE(using_fee == 10); // TODO:?
cout << "bridge__transfers__send__sweepDust: step1: using_fee " << *using_fee_string << endl;
//
using_outs = ret_tree.get_child(ret_json_key__send__using_outs()); // save this for step2
BOOST_FOREACH(boost::property_tree::ptree::value_type &output_desc, using_outs)
{
assert(output_desc.first.empty()); // array elements have no names
cout << "bridge__transfers__send__sweepDust: step1: using_out " << output_desc.second.get<string>("public_key") << endl;
}
//
change_amount_string = ret_tree.get_optional<string>(ret_json_key__send__change_amount());
BOOST_REQUIRE(change_amount_string != none);
BOOST_REQUIRE((*change_amount_string).size() > 0);
// uint64_t change_amount = stoull(*change_amount_string);
// BOOST_REQUIRE(change_amount == 10); // TODO:?
cout << "bridge__transfers__send__sweepDust: step1: change_amount " << *change_amount_string << endl;
//
final_total_wo_fee_string = ret_tree.get_optional<string>(ret_json_key__send__final_total_wo_fee());
BOOST_REQUIRE(final_total_wo_fee_string != none);
BOOST_REQUIRE((*final_total_wo_fee_string).size() > 0);
// uint64_t final_total_wo_fee = stoull(*final_total_wo_fee_string);
// BOOST_REQUIRE(final_total_wo_fee == 10); // TODO:?
cout << "bridge__transfers__send__sweepDust: step1: final_total_wo_fee " << *final_total_wo_fee_string << endl;
//
}
{
boost::property_tree::ptree root;
root.put("final_total_wo_fee", *final_total_wo_fee_string);
root.put("change_amount", *change_amount_string); // from step1
root.put("fee_amount", *using_fee_string); // from step1
root.add_child("using_outs", using_outs); // from step1
//
root.put("payment_id_string", "d2f602b240fbe624"); // optl
root.put("nettype_string", string_from_nettype(MAINNET));
root.put("to_address_string", "4APbcAKxZ2KPVPMnqa5cPtJK25tr7maE7LrJe67vzumiCtWwjDBvYnHZr18wFexJpih71Mxsjv8b7EpQftpB9NjPPXmZxHN");
root.put("from_address_string", "43zxvpcj5Xv9SEkNXbMCG7LPQStHMpFCQCmkmR4u5nzjWwq5Xkv5VmGgYEsHXg4ja2FGRD5wMWbBVMijDTqmmVqm93wHGkg");
root.put("sec_viewKey_string", "7bea1907940afdd480eff7c4bcadb478a0fbb626df9e3ed74ae801e18f53e104");
root.put("sec_spendKey_string", "4e6d43cd03812b803c6f3206689f5fcc910005fc7e91d50d79b0776dbefcd803");
root.put("fee_per_b", "24658");
root.put("fee_mask", "10000");
root.put("fork_version", "10");
root.put("unlock_time", "0");
root.put("priority", "1");
root.add_child("mix_outs", mix_outs);
//
boost::property_tree::ptree ret_tree;
auto ret_string = serial_bridge::send_step2__try_create_transaction(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<uint32_t> err_code = ret_tree.get_optional<uint32_t>(ret_json_key__any__err_code());
if (err_code != none && (CreateTransactionErrorCode)*err_code != monero_transfer_utils::noError) {
auto err_msg = err_msg_from_err_code__create_transaction((CreateTransactionErrorCode)*err_code);
BOOST_REQUIRE_MESSAGE(false, err_msg);
}
//
tx_must_be_reconstructed = ret_tree.get<bool>(ret_json_key__send__tx_must_be_reconstructed());
cout << "bridge__transfers__send__sweepDust: step2: must tx be reconstructed? " << tx_must_be_reconstructed << endl;
if (tx_must_be_reconstructed) {
// declared outside the for-loop so that we can use it for subsequent iterations if needed:
fee_actually_needed_string = ret_tree.get_optional<string>(ret_json_key__send__fee_actually_needed());
BOOST_REQUIRE(fee_actually_needed_string != none);
BOOST_REQUIRE((*fee_actually_needed_string).size() > 0);
//
// This means we must go back through step1 to re-pick using_outs
BOOST_REQUIRE(construction_attempt_n < 7); // not generally expecting to have to do this more than once or twice - i did see < 3 insufficient once so raised this
continue; // proceed to next iteration (re-enter tx construction at step1(II) with fee_actually_needed_string from step2(I))
}
optional<string> tx_hash = ret_tree.get_optional<string>(ret_json_key__send__tx_hash());
optional<string> tx_key_string = ret_tree.get_optional<string>(ret_json_key__send__tx_key());
optional<string> serialized_signed_tx = ret_tree.get_optional<string>(ret_json_key__send__serialized_signed_tx());
BOOST_REQUIRE(serialized_signed_tx != none);
BOOST_REQUIRE((*serialized_signed_tx).size() > 0);
cout << "bridge__transfers__send__sweepDust: serialized_signed_tx: " << *serialized_signed_tx << endl;
BOOST_REQUIRE(tx_hash != none);
BOOST_REQUIRE((*tx_hash).size() > 0);
cout << "bridge__transfers__send__sweepDust: tx_hash: " << *tx_hash << endl;
BOOST_REQUIRE(tx_key_string != none);
BOOST_REQUIRE((*tx_key_string).size() > 0);
cout << "bridge__transfers__send__sweepDust: tx_key_string: " << *tx_key_string << endl;
}
}
}
BOOST_AUTO_TEST_CASE(bridge__transfers__send__amountWOnlyDusty)
{
using namespace serial_bridge;
using namespace monero_transfer_utils;
//
// this being input as JSON merely for convenience
boost::property_tree::ptree pt;
stringstream ss;
ss << DG_presweep__unspent_outs_json;
boost::property_tree::json_parser::read_json(ss, pt);
boost::property_tree::ptree unspent_outs = pt.get_child("unspent_outs");
//
optional<string> mixin_string;
optional<string> change_amount_string;
optional<string> using_fee_string;
optional<string> final_total_wo_fee_string;
boost::property_tree::ptree using_outs;
boost::property_tree::ptree root;
root.put("is_sweeping", "false");
root.put("payment_id_string", "d2f602b240fbe624"); // optl
root.put("sending_amount", "1000000");
root.put("fee_per_b", "24658");
root.put("fee_mask", "10000");
root.put("fork_version", "10");
root.put("priority", "1");
root.add_child("unspent_outs", unspent_outs);
auto ret_string = serial_bridge::send_step1__prepare_params_for_get_decoys(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<uint32_t> err_code = ret_tree.get_optional<uint32_t>(ret_json_key__any__err_code());
BOOST_REQUIRE_MESSAGE(err_code == none, "Expected no error");
BOOST_REQUIRE_MESSAGE(ret_tree.get<string>("using_fee") == string("66290000"), "Expected using_fee of 66290000");
BOOST_REQUIRE_MESSAGE(ret_tree.get<string>("final_total_wo_fee") == string("1000000"), "Expected final_total_wo_fee of 1000000");
}
string DG_postsweep__unspent_outs_json = "{\"unspent_outs\":[{\"amount\":\"3000000000\",\"public_key\":\"41be1978f58cabf69a9bed5b6cb3c8d588621ef9b67602328da42a213ee42271\",\"index\":1,\"global_index\":7611174,\"rct\":\"86a2c9f1f8e66848cd99bfda7a14d4ac6c3525d06947e21e4e55fe42a368507eb5b234ccdd70beca8b1fc8de4f2ceb1374e0f1fd8810849e7f11316c2cc063060008ffa5ac9827b776993468df21af8c963d12148622354f950cbe1369a92a0c\",\"tx_id\":5334971,\"tx_hash\":\"9d37c7fdeab91abfd1e7e120f5c49eac17b7ac04a97a0c93b51c172115df21ea\",\"tx_pub_key\":\"bd703d7f37995cc7071fb4d2929594b5e2a4c27d2b7c68a9064500ca7bc638b8\"}]}";
string DG_postsweep__rand_outs_json = "{\"mix_outs\":[{\"amount\":\"0\",\"outputs\":[{\"global_index\":\"7453099\",\"public_key\":\"31f3a7fec0f6f09067e826b6c2904fd4b1684d7893dcf08c5b5d22e317e148bb\",\"rct\":\"ea6bcb193a25ce2787dd6abaaeef1ee0c924b323c6a5873db1406261e86145fc\"},{\"global_index\":\"7500097\",\"public_key\":\"f9d923500671da05a1bf44b932b872f0c4a3c88e6b3d4bf774c8be915e25f42b\",\"rct\":\"dcae4267a6c382bcd71fd1af4d2cbceb3749d576d7a3acc473dd579ea9231a52\"},{\"global_index\":\"7548483\",\"public_key\":\"839cbbb73685654b93e824c4843e745e8d5f7742e83494932307bf300641c480\",\"rct\":\"aa99d492f1d6f1b20dcd95b8fff8f67a219043d0d94b4551759016b4888573e7\"},{\"global_index\":\"7554755\",\"public_key\":\"b8860f0697988c8cefd7b4285fbb8bec463f136c2b9a9cadb3e57cebee10717f\",\"rct\":\"327f9b07bee9c4c25b5a990123cd2444228e5704ebe32016cd632866710279b5\"},{\"global_index\":\"7561477\",\"public_key\":\"561d734cb90bc4a64d49d37f85ea85575243e2ed749a3d6dcb4d27aa6bec6e88\",\"rct\":\"b5393e038df95b94bfda62b44a29141cac9e356127270af97193460d51949841\"},{\"global_index\":\"7567062\",\"public_key\":\"db1024ef67e7e73608ef8afab62f49e2402c8da3dc3197008e3ba720ad3c94a8\",\"rct\":\"1fedf95621881b77f823a70aa83ece26aef62974976d2b8cd87ed4862a4ec92c\"},{\"global_index\":\"7567508\",\"public_key\":\"6283f3cd2f050bba90276443fe04f6076ad2ad46a515bf07b84d424a3ba43d27\",\"rct\":\"10e16bb8a8b7b0c8a4b193467b010976b962809c9f3e6c047335dba09daa351f\"},{\"global_index\":\"7568716\",\"public_key\":\"7a7deb4eef81c1f5ce9cbd0552891cb19f1014a03a5863d549630824c7c7c0d3\",\"rct\":\"735d059dc3526334ac705ddc44c4316bb8805d2426dcea9544cde50cf6c7a850\"},{\"global_index\":\"7571196\",\"public_key\":\"535208e354cae530ed7ce752935e555d630cf2edd7f91525024ed9c332b2a347\",\"rct\":\"c3cf838faa14e993536c5581ca582fb0d96b70f713cf88f7f15c89336e5853ec\"},{\"global_index\":\"7571333\",\"public_key\":\"e73f27b7eb001aa7eac13df82814cda65b42ceeb6ef36227c25d5cbf82f6a5e4\",\"rct\":\"5f45f33c6800cdae202b37abe6d87b53d6873e7b30f3527161f44fa8db3104b6\"},{\"global_index\":\"7571335\",\"public_key\":\"fce982dbz8e7a6b71a1e632c7de8c5cbf54e8bacdfbf250f1ffc2a8d2f7055ce3\",\"rct\":\"407bdcc48e70eb3ef2cc22cefee6c6b5a3c59fd17bde12fda5f1a44a0fb39d14\"}]}]}";
BOOST_AUTO_TEST_CASE(bridge__transfers__send__amount)
{
using namespace serial_bridge;
using namespace monero_transfer_utils;
//
// this being input as JSON merely for convenience
boost::property_tree::ptree pt;
stringstream ss;
ss << DG_postsweep__unspent_outs_json;
boost::property_tree::json_parser::read_json(ss, pt);
boost::property_tree::ptree unspent_outs = pt.get_child("unspent_outs");
//
// NOTE: in the real algorithm you should re-request this _each time step2 must be called_
// this being input as JSON merely for convenience
boost::property_tree::ptree mix_outs;
{
boost::property_tree::ptree pt;
stringstream ss;
ss << DG_postsweep__rand_outs_json;
boost::property_tree::json_parser::read_json(ss, pt);
mix_outs = pt.get_child("mix_outs");
}
//
// Send algorithm:
bool tx_must_be_reconstructed = true; // for ease of writing this code, start this off true & structure whole thing as while loop
optional<string> fee_actually_needed_string = none;
size_t construction_attempt_n = 0;
while (tx_must_be_reconstructed) {
construction_attempt_n += 1; // merely kept for assertion purposes
//
optional<string> mixin_string;
optional<string> change_amount_string;
optional<string> using_fee_string;
optional<string> final_total_wo_fee_string;
boost::property_tree::ptree using_outs;
{
boost::property_tree::ptree root;
root.put("is_sweeping", "false");
root.put("payment_id_string", "d2f602b240fbe624"); // optl
root.put("sending_amount", "200000000");
root.put("fee_per_b", "24658");
root.put("fee_mask", "10000");
root.put("fork_version", "10");
root.put("priority", "1");
root.add_child("unspent_outs", unspent_outs);
if (fee_actually_needed_string != none) {
BOOST_REQUIRE(construction_attempt_n > 1);
//
// for next round's integration - if it needs to re-enter... arg "passedIn_attemptAt_fee"
root.put("passedIn_attemptAt_fee", *fee_actually_needed_string);
}
auto ret_string = serial_bridge::send_step1__prepare_params_for_get_decoys(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<uint32_t> err_code = ret_tree.get_optional<uint32_t>(ret_json_key__any__err_code());
if (err_code != none && (CreateTransactionErrorCode)*err_code != monero_transfer_utils::noError) {
if ((CreateTransactionErrorCode)*err_code == monero_transfer_utils::needMoreMoneyThanFound) {
optional<string> spendable_balance_string = ret_tree.get_optional<string>(ret_json_key__send__spendable_balance());
BOOST_REQUIRE(spendable_balance_string != none);
BOOST_REQUIRE((*spendable_balance_string).size() > 0);
// uint64_t fee = stoull(*fee_string);
// BOOST_REQUIRE(fee == 135000000);
cout << "bridge__transfers__send__amount: step1: needMoreMoneyThanFound: spendable_balance " << *spendable_balance_string << endl;
//
optional<string> required_balance_string = ret_tree.get_optional<string>(ret_json_key__send__required_balance());
BOOST_REQUIRE(required_balance_string != none);
BOOST_REQUIRE((*required_balance_string).size() > 0);
// uint64_t fee = stoull(*fee_string);
// BOOST_REQUIRE(fee == 135000000);
cout << "bridge__transfers__send__amount: step1: needMoreMoneyThanFound: required_balance " << *required_balance_string << endl;
}
auto err_msg = err_msg_from_err_code__create_transaction((CreateTransactionErrorCode)*err_code);
BOOST_REQUIRE_MESSAGE(false, err_msg);
// ^--- not expecting anything like needMoreMoneyThanFound errors here
}
mixin_string = ret_tree.get_optional<string>(ret_json_key__send__mixin());
BOOST_REQUIRE(mixin_string != none);
BOOST_REQUIRE((*mixin_string).size() > 0);
uint64_t mixin = stoull(*mixin_string);
BOOST_REQUIRE(mixin == 10);
cout << "bridge__transfers__send__amount: mixin " << *mixin_string << endl;
//
using_fee_string = ret_tree.get_optional<string>(ret_json_key__send__using_fee()); // save this
BOOST_REQUIRE(using_fee_string != none);
BOOST_REQUIRE((*using_fee_string).size() > 0);
// uint64_t using_fee = stoull(*using_fee_string);
// BOOST_REQUIRE(using_fee == 10); // TODO:?
cout << "bridge__transfers__send__amount: step1: using_fee " << *using_fee_string << endl;
//
using_outs = ret_tree.get_child(ret_json_key__send__using_outs()); // save this for step2
BOOST_FOREACH(boost::property_tree::ptree::value_type &output_desc, using_outs)
{
assert(output_desc.first.empty()); // array elements have no names
cout << "bridge__transfers__send__amount: step1: using_out " << output_desc.second.get<string>("public_key") << endl;
}
//
change_amount_string = ret_tree.get_optional<string>(ret_json_key__send__change_amount());
BOOST_REQUIRE(change_amount_string != none);
BOOST_REQUIRE((*change_amount_string).size() > 0);
// uint64_t change_amount = stoull(*change_amount_string);
// BOOST_REQUIRE(change_amount == 10); // TODO:?
cout << "bridge__transfers__send__amount: step1: change_amount " << *change_amount_string << endl;
//
final_total_wo_fee_string = ret_tree.get_optional<string>(ret_json_key__send__final_total_wo_fee());
BOOST_REQUIRE(final_total_wo_fee_string != none);
BOOST_REQUIRE((*final_total_wo_fee_string).size() > 0);
// uint64_t final_total_wo_fee = stoull(*final_total_wo_fee_string);
// BOOST_REQUIRE(final_total_wo_fee == 10); // TODO:?
cout << "bridge__transfers__send__amount: step1: final_total_wo_fee " << *final_total_wo_fee_string << endl;
//
}
{
boost::property_tree::ptree root;
root.put("final_total_wo_fee", *final_total_wo_fee_string);
cout << "change_amount_string: " << *change_amount_string << endl;
root.put("change_amount", *change_amount_string); // from step1
root.put("fee_amount", *using_fee_string); // from step1
root.add_child("using_outs", using_outs); // from step1
//
root.put("payment_id_string", "d2f602b240fbe624"); // optl
root.put("nettype_string", string_from_nettype(MAINNET));
root.put("to_address_string", "4APbcAKxZ2KPVPMnqa5cPtJK25tr7maE7LrJe67vzumiCtWwjDBvYnHZr18wFexJpih71Mxsjv8b7EpQftpB9NjPPXmZxHN");
root.put("from_address_string", "43zxvpcj5Xv9SEkNXbMCG7LPQStHMpFCQCmkmR4u5nzjWwq5Xkv5VmGgYEsHXg4ja2FGRD5wMWbBVMijDTqmmVqm93wHGkg");
root.put("sec_viewKey_string", "7bea1907940afdd480eff7c4bcadb478a0fbb626df9e3ed74ae801e18f53e104");
root.put("sec_spendKey_string", "4e6d43cd03812b803c6f3206689f5fcc910005fc7e91d50d79b0776dbefcd803");
root.put("fee_per_b", "24658");
root.put("fee_mask", "10000");
root.put("fork_version", "10");
root.put("unlock_time", "0");
root.put("priority", "1");
root.add_child("mix_outs", mix_outs);
//
boost::property_tree::ptree ret_tree;
auto ret_string = serial_bridge::send_step2__try_create_transaction(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<uint32_t> err_code = ret_tree.get_optional<uint32_t>(ret_json_key__any__err_code());
if (err_code != none && (CreateTransactionErrorCode)*err_code != monero_transfer_utils::noError) {
auto err_msg = err_msg_from_err_code__create_transaction((CreateTransactionErrorCode)*err_code);
BOOST_REQUIRE_MESSAGE(false, err_msg);
}
//
tx_must_be_reconstructed = ret_tree.get<bool>(ret_json_key__send__tx_must_be_reconstructed());
cout << "bridge__transfers__send__amount: step2: must tx be reconstructed? " << tx_must_be_reconstructed << endl;
if (tx_must_be_reconstructed) {
// declared outside the for-loop so that we can use it for subsequent iterations if needed:
fee_actually_needed_string = ret_tree.get_optional<string>(ret_json_key__send__fee_actually_needed());
BOOST_REQUIRE(fee_actually_needed_string != none);
BOOST_REQUIRE((*fee_actually_needed_string).size() > 0);
//
// This means we must go back through step1 to re-pick using_outs
BOOST_REQUIRE(construction_attempt_n < 3); // not generally expecting to have to do this more than once or twice
continue; // proceed to next iteration (re-enter tx construction at step1(II) with fee_actually_needed_string from step2(I))
}
optional<string> tx_hash = ret_tree.get_optional<string>(ret_json_key__send__tx_hash());
optional<string> tx_key_string = ret_tree.get_optional<string>(ret_json_key__send__tx_key());
optional<string> tx_pub_key_string = ret_tree.get_optional<string>(ret_json_key__send__tx_pub_key());
optional<string> serialized_signed_tx = ret_tree.get_optional<string>(ret_json_key__send__serialized_signed_tx());
BOOST_REQUIRE(serialized_signed_tx != none);
BOOST_REQUIRE((*serialized_signed_tx).size() > 0);
cout << "bridge__transfers__send__amount: serialized_signed_tx: " << *serialized_signed_tx << endl;
BOOST_REQUIRE(tx_hash != none);
BOOST_REQUIRE((*tx_hash).size() > 0);
cout << "bridge__transfers__send__amount: tx_hash: " << *tx_hash << endl;
BOOST_REQUIRE(tx_key_string != none);
BOOST_REQUIRE((*tx_key_string).size() > 0);
cout << "bridge__transfers__send__amount: tx_key_string: " << *tx_key_string << endl;
BOOST_REQUIRE(tx_pub_key_string != none);
BOOST_REQUIRE((*tx_pub_key_string).size() > 0);
cout << "bridge__transfers__send__amount: tx_pub_key_string: " << *tx_pub_key_string << endl;
}
}
}
//
BOOST_AUTO_TEST_CASE(bridged__decode_address)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("nettype_string", string_from_nettype(MAINNET));
root.put("address", "4L6Gcy9TAHqPVPMnqa5cPtJK25tr7maE7LrJe67vzumiCtWwjDBvYnHZr18wFexJpih71Mxsjv8b7EpQftpB9NjPaL41VrjstLM5WevLZx");
//
auto ret_string = serial_bridge::decode_address(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> pub_viewKey_string = ret_tree.get_optional<string>(ret_json_key__pub_viewKey_string());
BOOST_REQUIRE(pub_viewKey_string != none);
BOOST_REQUIRE((*pub_viewKey_string).size() > 0);
cout << "bridged__decode_address: pub_viewKey_string: " << *pub_viewKey_string << endl;
optional<string> pub_spendKey_string = ret_tree.get_optional<string>(ret_json_key__pub_spendKey_string());
BOOST_REQUIRE(pub_spendKey_string != none);
BOOST_REQUIRE((*pub_spendKey_string).size() > 0);
cout << "bridged__decode_address: pub_spendKey_string: " << *pub_spendKey_string << endl;
optional<string> paymentID_string = ret_tree.get_optional<string>(ret_json_key__paymentID_string());
BOOST_REQUIRE(paymentID_string != none);
BOOST_REQUIRE((*paymentID_string).size() > 0);
cout << "bridged__decode_address: paymentID_string: " << *paymentID_string << endl;
optional<bool> isSubaddress = ret_tree.get_optional<bool>(ret_json_key__isSubaddress());
BOOST_REQUIRE(isSubaddress != none);
BOOST_REQUIRE(*isSubaddress == false);
cout << "bridged__decode_address: isSubaddress: " << *isSubaddress << endl;
}
//
BOOST_AUTO_TEST_CASE(bridged__is_subaddress)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("nettype_string", string_from_nettype(MAINNET));
root.put("address", "4L6Gcy9TAHqPVPMnqa5cPtJK25tr7maE7LrJe67vzumiCtWwjDBvYnHZr18wFexJpih71Mxsjv8b7EpQftpB9NjPaL41VrjstLM5WevLZx");
//
auto ret_string = serial_bridge::is_subaddress(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<bool> value = ret_tree.get_optional<bool>(ret_json_key__generic_retVal());
BOOST_REQUIRE(value != none);
BOOST_REQUIRE(*value == false);
cout << "bridged__is_subaddress: " << *value << endl;
}
//
BOOST_AUTO_TEST_CASE(bridged__is_integrated_address)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("nettype_string", string_from_nettype(MAINNET));
root.put("address", "4L6Gcy9TAHqPVPMnqa5cPtJK25tr7maE7LrJe67vzumiCtWwjDBvYnHZr18wFexJpih71Mxsjv8b7EpQftpB9NjPaL41VrjstLM5WevLZx");
//
auto ret_string = serial_bridge::is_integrated_address(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<bool> value = ret_tree.get_optional<bool>(ret_json_key__generic_retVal());
BOOST_REQUIRE(value != none);
BOOST_REQUIRE(*value == true);
cout << "bridged__is_integrated_address: " << *value << endl;
}
//
#include <boost/algorithm/string/predicate.hpp>
BOOST_AUTO_TEST_CASE(bridged__new_integrated_address)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("nettype_string", string_from_nettype(MAINNET));
root.put("address", "43zxvpcj5Xv9SEkNXbMCG7LPQStHMpFCQCmkmR4u5nzjWwq5Xkv5VmGgYEsHXg4ja2FGRD5wMWbBVMijDTqmmVqm93wHGkg");
root.put("short_pid", "b79f8efc81f58f67");
//
auto ret_string = serial_bridge::new_integrated_address(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> value = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(value != none);
BOOST_REQUIRE((*value).size() > 0);
BOOST_REQUIRE(boost::equal(*value, string("4DhdwdSDgoS9SEkNXbMCG7LPQStHMpFCQCmkmR4u5nzjWwq5Xkv5VmGgYEsHXg4ja2FGRD5wMWbBVMijDTqmmVqmCzkMP1DMV6WCiNCdsp")));
cout << "bridged__new_integrated_address: " << *value << endl;
}
//
BOOST_AUTO_TEST_CASE(bridged__new_short_payment_id)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
//
auto ret_string = serial_bridge::new_payment_id(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> value = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(value != none);
BOOST_REQUIRE((*value).size() > 0);
cout << "bridged__new_short_payment_id: " << *value << endl;
}
//
BOOST_AUTO_TEST_CASE(bridged__new_wallet)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("nettype_string", string_from_nettype(MAINNET));
root.put("locale_language_code", "en-US");
//
auto ret_string = serial_bridge::newly_created_wallet(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> mnemonic_string = ret_tree.get_optional<string>(ret_json_key__mnemonic_string());
BOOST_REQUIRE(mnemonic_string != none);
BOOST_REQUIRE((*mnemonic_string).size() > 0);
cout << "bridged__new_wallet: mnemonic: " << *mnemonic_string << endl;
optional<string> mnemonic_language = ret_tree.get_optional<string>(ret_json_key__mnemonic_language());
BOOST_REQUIRE(mnemonic_language != none);
BOOST_REQUIRE((*mnemonic_language).size() > 0);
cout << "bridged__new_wallet: mnemonic_language: " << *mnemonic_language << endl;
optional<string> sec_seed_string = ret_tree.get_optional<string>(ret_json_key__sec_seed_string());
BOOST_REQUIRE(sec_seed_string != none);
BOOST_REQUIRE((*sec_seed_string).size() > 0);
cout << "bridged__new_wallet: sec_seed: " << *sec_seed_string << endl;
optional<string> address_string = ret_tree.get_optional<string>(ret_json_key__address_string());
BOOST_REQUIRE(address_string != none);
BOOST_REQUIRE((*address_string).size() > 0);
cout << "bridged__new_wallet: address: " << *address_string << endl;
optional<string> pub_viewKey_string = ret_tree.get_optional<string>(ret_json_key__pub_viewKey_string());
BOOST_REQUIRE(pub_viewKey_string != none);
BOOST_REQUIRE((*pub_viewKey_string).size() > 0);
cout << "bridged__new_wallet: pub_viewKey_string: " << *pub_viewKey_string << endl;
optional<string> pub_spendKey_string = ret_tree.get_optional<string>(ret_json_key__pub_spendKey_string());
BOOST_REQUIRE(pub_spendKey_string != none);
BOOST_REQUIRE((*pub_spendKey_string).size() > 0);
cout << "bridged__new_wallet: pub_spendKey_string: " << *pub_spendKey_string << endl;
optional<string> sec_viewKey_string = ret_tree.get_optional<string>(ret_json_key__sec_viewKey_string());
BOOST_REQUIRE(sec_viewKey_string != none);
BOOST_REQUIRE((*sec_viewKey_string).size() > 0);
cout << "bridged__new_wallet: sec_viewKey_string: " << *sec_viewKey_string << endl;
optional<string> sec_spendKey_string = ret_tree.get_optional<string>(ret_json_key__sec_spendKey_string());
BOOST_REQUIRE(sec_spendKey_string != none);
BOOST_REQUIRE((*sec_spendKey_string).size() > 0);
cout << "bridged__new_wallet: sec_spendKey_string: " << *sec_spendKey_string << endl;
}
//
BOOST_AUTO_TEST_CASE(bridged__are_equal_mnemonics)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("a", "foxe selfish hum nexus juven dodeg pepp ember biscuti elap jazz vibrate biscui");
root.put("b", "fox sel hum nex juv\r \ndod pep emb bis ela jaz vib bis");
//
auto ret_string = serial_bridge::are_equal_mnemonics(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<bool> value = ret_tree.get_optional<bool>(ret_json_key__generic_retVal());
BOOST_REQUIRE(value != none);
BOOST_REQUIRE(*value != false);
cout << "bridged__are_equal_mnemonics: " << *value << endl;
}
BOOST_AUTO_TEST_CASE(bridged__are_equal_mnemonics__caps)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("a", "Neubau umarmen Abart umarmen Turban feilen Brett Bargeld Episode Milchkuh Substanz Jahr Armband Maibaum Tand Grünalge Tabak erziehen Federboa Lobrede Tenor Leuchter Curry Diskurs Tenor");
root.put("b", "neubau umarm Abart umarmen Turban feilen Brett Bargel Epis Milchkuh Subst Jahr Armband Maib Tand Grüna Tabak erzie Feder Lobre Tenor Leuch Curry Diskurs tenor");
//
auto ret_string = serial_bridge::are_equal_mnemonics(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<bool> value = ret_tree.get_optional<bool>(ret_json_key__generic_retVal());
BOOST_REQUIRE(value != none);
BOOST_REQUIRE(*value != false);
cout << "bridged__are_equal_mnemonics__caps: " << *value << endl;
}
//
BOOST_AUTO_TEST_CASE(bridged__mnemonic_from_seed)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("seed_string", "9c973aa296b79bbf452781dd3d32ad7f");
root.put("wordset_name", "English");
//
auto ret_string = serial_bridge::mnemonic_from_seed(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> mnemonic_string = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(mnemonic_string != none);
BOOST_REQUIRE((*mnemonic_string).size() > 0);
cout << "bridged__mnemonic_from_seed: mnemonic: " << *mnemonic_string << endl;
}
//
BOOST_AUTO_TEST_CASE(bridged__seed_and_keys_from_mnemonic)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("mnemonic_string", "foxe selfish\n\r \t hum nexus juven dodeg pepp \r\n\r\n ember biscuti elap jazz vibrate biscui");
root.put("nettype_string", string_from_nettype(MAINNET));
//
auto ret_string = serial_bridge::seed_and_keys_from_mnemonic(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> mnemonic_language = ret_tree.get_optional<string>(ret_json_key__mnemonic_language());
BOOST_REQUIRE(mnemonic_language != none);
BOOST_REQUIRE((*mnemonic_language).size() > 0);
cout << "bridged__seed_and_keys_from_mnemonic: mnemonic_language: " << *mnemonic_language << endl;
optional<string> sec_seed_string = ret_tree.get_optional<string>(ret_json_key__sec_seed_string());
BOOST_REQUIRE(sec_seed_string != none);
BOOST_REQUIRE((*sec_seed_string).size() > 0);
cout << "bridged__seed_and_keys_from_mnemonic: sec_seed: " << *sec_seed_string << endl;
optional<string> address_string = ret_tree.get_optional<string>(ret_json_key__address_string());
BOOST_REQUIRE(address_string != none);
BOOST_REQUIRE((*address_string).size() > 0);
cout << "bridged__seed_and_keys_from_mnemonic: address: " << *address_string << endl;
BOOST_REQUIRE((*address_string) == "43zxvpcj5Xv9SEkNXbMCG7LPQStHMpFCQCmkmR4u5nzjWwq5Xkv5VmGgYEsHXg4ja2FGRD5wMWbBVMijDTqmmVqm93wHGkg");
optional<string> pub_viewKey_string = ret_tree.get_optional<string>(ret_json_key__pub_viewKey_string());
BOOST_REQUIRE(pub_viewKey_string != none);
BOOST_REQUIRE((*pub_viewKey_string).size() > 0);
cout << "bridged__seed_and_keys_from_mnemonic: pub_viewKey_string: " << *pub_viewKey_string << endl;
optional<string> pub_spendKey_string = ret_tree.get_optional<string>(ret_json_key__pub_spendKey_string());
BOOST_REQUIRE(pub_spendKey_string != none);
BOOST_REQUIRE((*pub_spendKey_string).size() > 0);
cout << "bridged__seed_and_keys_from_mnemonic: pub_spendKey_string: " << *pub_spendKey_string << endl;
optional<string> sec_viewKey_string = ret_tree.get_optional<string>(ret_json_key__sec_viewKey_string());
BOOST_REQUIRE(sec_viewKey_string != none);
BOOST_REQUIRE((*sec_viewKey_string).size() > 0);
cout << "bridged__seed_and_keys_from_mnemonic: sec_viewKey_string: " << *sec_viewKey_string << endl;
optional<string> sec_spendKey_string = ret_tree.get_optional<string>(ret_json_key__sec_spendKey_string());
BOOST_REQUIRE(sec_spendKey_string != none);
BOOST_REQUIRE((*sec_spendKey_string).size() > 0);
cout << "bridged__seed_and_keys_from_mnemonic: sec_spendKey_string: " << *sec_spendKey_string << endl;
}
BOOST_AUTO_TEST_CASE(bridged__validate_components_for_login__subaddress)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("address_string", "852t3x5nfQ7PLnavxP1Q6S2ff18tvy8Cih4ikkd61aqd2BV5iTaeY6PFBeLPcHZdrvfumGJx9z1Md6fwyxKSykyHKJAMrk6");
root.put("sec_viewKey_string", "");
root.put("sec_spendKey_string", "");
root.put("seed_string", "");
root.put("nettype_string", string_from_nettype(MAINNET));
//
auto ret_string = serial_bridge::validate_components_for_login(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
BOOST_REQUIRE(err_string != none);
BOOST_REQUIRE((*err_string).compare("Can't log in with a sub-address") == 0);
optional<bool> isValid = ret_tree.get_optional<bool>(ret_json_key__isValid());
BOOST_REQUIRE(isValid == none || *isValid == false);
}
BOOST_AUTO_TEST_CASE(bridged__validate_components_for_login)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("address_string", "43zxvpcj5Xv9SEkNXbMCG7LPQStHMpFCQCmkmR4u5nzjWwq5Xkv5VmGgYEsHXg4ja2FGRD5wMWbBVMijDTqmmVqm93wHGkg");
root.put("sec_viewKey_string", "7bea1907940afdd480eff7c4bcadb478a0fbb626df9e3ed74ae801e18f53e104");
root.put("sec_spendKey_string", "4e6d43cd03812b803c6f3206689f5fcc910005fc7e91d50d79b0776dbefcd803");
root.put("seed_string", "9c973aa296b79bbf452781dd3d32ad7f");
root.put("nettype_string", string_from_nettype(MAINNET));
//
auto ret_string = serial_bridge::validate_components_for_login(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<bool> isValid = ret_tree.get_optional<bool>(ret_json_key__isValid());
BOOST_REQUIRE(isValid == true);
cout << "bridged__validate_components_for_login: isValid: " << isValid << endl;
optional<bool> isInViewOnlyMode = ret_tree.get_optional<bool>(ret_json_key__isInViewOnlyMode());
BOOST_REQUIRE(isInViewOnlyMode == false);
cout << "bridged__validate_components_for_login: isInViewOnlyMode: " << isInViewOnlyMode << endl;
optional<string> pub_viewKey_string = ret_tree.get_optional<string>(ret_json_key__pub_viewKey_string());
BOOST_REQUIRE(pub_viewKey_string != none);
BOOST_REQUIRE((*pub_viewKey_string).size() > 0);
cout << "bridged__validate_components_for_login: pub_viewKey_string: " << *pub_viewKey_string << endl;
optional<string> pub_spendKey_string = ret_tree.get_optional<string>(ret_json_key__pub_spendKey_string());
BOOST_REQUIRE(pub_spendKey_string != none);
BOOST_REQUIRE((*pub_spendKey_string).size() > 0);
cout << "bridged__validate_components_for_login: pub_spendKey_string: " << *pub_spendKey_string << endl;
}
6 years ago
BOOST_AUTO_TEST_CASE(bridged__estimated_tx_network_fee)
{
6 years ago
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("fee_per_b", "24658");
root.put("fee_mask", "10000");
root.put("fork_version", "10");
6 years ago
root.put("priority", "2");
//
auto ret_string = serial_bridge::estimated_tx_network_fee(args_string_from_root(root));
6 years ago
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> fee_string = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(fee_string != none);
BOOST_REQUIRE((*fee_string).size() > 0);
uint64_t fee = stoull(*fee_string);
BOOST_REQUIRE(fee == 330047330);
cout << "bridged__estimated_tx_network_fee: " << fee << endl;
6 years ago
}
BOOST_AUTO_TEST_CASE(bridged__estimate_rct_tx_size)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("n_inputs", "1");
root.put("mixin", "10");
root.put("n_outputs", "2");
root.put("extra_size", "0");
root.put("bulletproof", "true");
//
auto ret_string = serial_bridge::estimate_rct_tx_size(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> size_string = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(size_string != none);
BOOST_REQUIRE((*size_string).size() > 0);
size_t size = stoul(*size_string);
BOOST_REQUIRE(size == 1848);
cout << "bridged__estimate_rct_tx_size: " << size << endl;
}
BOOST_AUTO_TEST_CASE(bridged__generate_key_image)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("sec_viewKey_string", "7bea1907940afdd480eff7c4bcadb478a0fbb626df9e3ed74ae801e18f53e104");
root.put("sec_spendKey_string", "4e6d43cd03812b803c6f3206689f5fcc910005fc7e91d50d79b0776dbefcd803");
root.put("pub_spendKey_string", "3eb884d3440d71326e27cc07a861b873e72abd339feb654660c36a008a0028b3");
root.put("tx_pub_key", "fc7f85bf64c6e4f6aa612dbc8ddb1bb77a9283656e9c2b9e777c9519798622b2");
root.put("out_index", "0");
//
auto ret_string = serial_bridge::generate_key_image(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> key_image_string = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(key_image_string != none);
BOOST_REQUIRE((*key_image_string).size() > 0);
BOOST_REQUIRE(*key_image_string == "ae30ee23051dc0bdf10303fbd3b7d8035a958079eb66516b1740f2c9b02c804e");
cout << "bridged__generate_key_image: " << *key_image_string << endl;
}
//
BOOST_AUTO_TEST_CASE(bridged__address_and_keys_from_seed)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("seed_string", "9c973aa296b79bbf452781dd3d32ad7f");
root.put("nettype_string", string_from_nettype(MAINNET));
//
auto ret_string = serial_bridge::address_and_keys_from_seed(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> address_string = ret_tree.get_optional<string>(ret_json_key__address_string());
BOOST_REQUIRE(address_string != none);
BOOST_REQUIRE((*address_string).size() > 0);
cout << "bridged__address_and_keys_from_seed: address: " << *address_string << endl;
BOOST_REQUIRE(*address_string == "43zxvpcj5Xv9SEkNXbMCG7LPQStHMpFCQCmkmR4u5nzjWwq5Xkv5VmGgYEsHXg4ja2FGRD5wMWbBVMijDTqmmVqm93wHGkg");
optional<string> pub_viewKey_string = ret_tree.get_optional<string>(ret_json_key__pub_viewKey_string());
BOOST_REQUIRE(pub_viewKey_string != none);
BOOST_REQUIRE((*pub_viewKey_string).size() > 0);
cout << "bridged__address_and_keys_from_seed: pub_viewKey_string: " << *pub_viewKey_string << endl;
optional<string> pub_spendKey_string = ret_tree.get_optional<string>(ret_json_key__pub_spendKey_string());
BOOST_REQUIRE(pub_spendKey_string != none);
BOOST_REQUIRE((*pub_spendKey_string).size() > 0);
cout << "bridged__address_and_keys_from_seed: pub_spendKey_string: " << *pub_spendKey_string << endl;
optional<string> sec_viewKey_string = ret_tree.get_optional<string>(ret_json_key__sec_viewKey_string());
BOOST_REQUIRE(sec_viewKey_string != none);
BOOST_REQUIRE((*sec_viewKey_string).size() > 0);
BOOST_REQUIRE(*sec_viewKey_string == "7bea1907940afdd480eff7c4bcadb478a0fbb626df9e3ed74ae801e18f53e104");
cout << "bridged__address_and_keys_from_seed: sec_viewKey_string: " << *sec_viewKey_string << endl;
optional<string> sec_spendKey_string = ret_tree.get_optional<string>(ret_json_key__sec_spendKey_string());
BOOST_REQUIRE(sec_spendKey_string != none);
BOOST_REQUIRE((*sec_spendKey_string).size() > 0);
BOOST_REQUIRE(*sec_spendKey_string == "4e6d43cd03812b803c6f3206689f5fcc910005fc7e91d50d79b0776dbefcd803");
cout << "bridged__address_and_keys_from_seed: sec_spendKey_string: " << *sec_spendKey_string << endl;
}
//
BOOST_AUTO_TEST_CASE(bridged__derive_public_key)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("derivation", "591c749f1868c58f37ec3d2a9d2f08e7f98417ac4f8131e3a57c1fd71273ad00");
root.put("out_index", "1");
root.put("pub", "904e49462268d771cc1649084c35aa1296bfb214880fe2e7f373620a3e2ba597");
//
auto ret_string = serial_bridge::derive_public_key(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> str = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(str != none);
BOOST_REQUIRE((*str).size() > 0);
BOOST_REQUIRE(*str == "da26518ddb54cde24ccfc59f36df13bbe9bdfcb4ef1b223d9ab7bef0a50c8be3");
cout << "bridged__derive_public_key: " << *str << endl;
}
BOOST_AUTO_TEST_CASE(bridged__derive_subaddress_public_key)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("derivation", "591c749f1868c58f37ec3d2a9d2f08e7f98417ac4f8131e3a57c1fd71273ad00");
root.put("out_index", "1");
root.put("output_key", "904e49462268d771cc1649084c35aa1296bfb214880fe2e7f373620a3e2ba597");
//
auto ret_string = serial_bridge::derive_subaddress_public_key(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> str = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(str != none);
BOOST_REQUIRE((*str).size() > 0);
BOOST_REQUIRE(*str == "dfc9e4a0039e913204c1c0f78e954a7ec7ce291d8ffe88265632f0da9d8de1be");
cout << "bridged__derive_subaddress_public_key: " << *str << endl;
}
BOOST_AUTO_TEST_CASE(bridged__generate_key_derivation)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("pub", "904e49462268d771cc1649084c35aa1296bfb214880fe2e7f373620a3e2ba597");
root.put("sec", "52aa4c69b93b780885c9d7f51e6fd5795904962c61a2e07437e130784846f70d");
//
auto ret_string = serial_bridge::generate_key_derivation(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> derivation = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(derivation != none);
BOOST_REQUIRE((*derivation).size() > 0);
BOOST_REQUIRE(*derivation == "591c749f1868c58f37ec3d2a9d2f08e7f98417ac4f8131e3a57c1fd71273ad00");
cout << "bridged__generate_key_derivation: derivation: " << *derivation << endl;
}
//
BOOST_AUTO_TEST_CASE(bridge__mainnet_pubKeyDerivations)
{
using namespace serial_bridge;
//
string arg__txPubKey = "5b7bc9532af303b7742dfceb04a5a3989f2433caa0ca75f58df4eaa1a4422d96";
string arg__secViewKey = "7bea1907940afdd480eff7c4bcadb478a0fbb626df9e3ed74ae801e18f53e104";
string arg__pubSpendKey = "3eb884d3440d71326e27cc07a861b873e72abd339feb654660c36a008a0028b3";
//
string arg__TxOwnOutIdx = "0";
string arg__TxOwnOutPubKey = "f43366980f7b0c2094023171cf8275210e7d0dae03cca0e8161a2f0aa4625e63";
//
cout << "bridge__mainnet_pubKeyDerivations: arg__TxOwnOutPubKey " << arg__TxOwnOutPubKey << endl;
//
optional<string> key_derivation = none; // to derive
{
boost::property_tree::ptree root;
root.put("pub", arg__txPubKey);
root.put("sec", arg__secViewKey);
//
auto ret_string = serial_bridge::generate_key_derivation(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
key_derivation = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(key_derivation != none);
BOOST_REQUIRE((*key_derivation).size() > 0);
cout << "bridge__mainnet_pubKeyDerivations: key_derivation " << *key_derivation << endl;
}
{
boost::property_tree::ptree root;
root.put("derivation", *key_derivation);
root.put("out_index", arg__TxOwnOutIdx);
root.put("pub", arg__pubSpendKey);
//
auto ret_string = serial_bridge::derive_public_key(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> derived_pub_key = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(derived_pub_key != none);
BOOST_REQUIRE((*derived_pub_key).size() > 0);
cout << "bridge__mainnet_pubKeyDerivations: Derived pub key " << *derived_pub_key << endl;
//
// The critical tests
BOOST_REQUIRE(*derived_pub_key == arg__TxOwnOutPubKey);
}
}
//
BOOST_AUTO_TEST_CASE(bridged__derivation_to_scalar)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("derivation", "7a4c13a037d4bd2a7dd99a8c24669e9e04ca4e8a90e5b6703e88e87ad51c1849");
root.put("output_index", "1");
//
auto ret_string = serial_bridge::derivation_to_scalar(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> str = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(str != none);
BOOST_REQUIRE((*str).size() > 0);
BOOST_REQUIRE(*str == "767a2b9b814b78d55e27ab7fc9bae03253a810c820e7abb4cabadde44b599d04");
cout << "bridged__derivation_to_scalar: " << *str << endl;
}
//
BOOST_AUTO_TEST_CASE(bridged__decodeRct)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("i", "1");
root.put("sk", "9b1529acb638f497d05677d7505d354b4ba6bc95484008f6362f93160ef3e503");
boost::property_tree::ptree rv;
{
rv.put("type", "1");
//
boost::property_tree::ptree ecdhInfo;
{
boost::property_tree::ptree ecdh_info;
ecdh_info.put("mask", "3ad9d0b3398691b94558e0f750e07e5e0d7d12411cd70b3841159e6c6b10db02");
ecdh_info.put("amount", "b3189d8adb5a26568e497eb8e376a7d7d946ebb1daef4c2c87a2c30b65915506");
ecdhInfo.push_back(std::make_pair("", ecdh_info));
}
{
boost::property_tree::ptree ecdh_info;
ecdh_info.put("mask", "97b00af8ecba3cb71b9660cc9e1ac110abd21a4c5e50a2c125f964caa96bef0c");
ecdh_info.put("amount", "60269d8adb5a26568e497eb8e376a7d7d946ebb1daef4c2c87a2c30b65915506");
ecdhInfo.push_back(std::make_pair("", ecdh_info));
}
{
boost::property_tree::ptree ecdh_info;
ecdh_info.put("mask", "db67f5066d9455db404aeaf435ad948bc9f27344bc743e3a32583a9e6695cb08");
ecdh_info.put("amount", "b3189d8adb5a26568e497eb8e376a7d7d946ebb1daef4c2c87a2c30b65915506");
ecdhInfo.push_back(std::make_pair("", ecdh_info));
}
rv.add_child("ecdhInfo", ecdhInfo);
//
boost::property_tree::ptree outPk;
{
boost::property_tree::ptree an_outPk;
an_outPk.put("mask", "9adc531a9c79a49a4257f24e5e5ea49c2fc1fb4eef49e00d5e5aba6cb6963a7d");
outPk.push_back(std::make_pair("", an_outPk));
}
{
boost::property_tree::ptree an_outPk;
an_outPk.put("mask", "89f40499d6786a4027a24d6674d0940146fd12d8bc6007d338f19f05040e7a41");
outPk.push_back(std::make_pair("", an_outPk));
}
{
boost::property_tree::ptree an_outPk;
an_outPk.put("mask", "f413d28bd5ffdc020528bcb2c19919d7484fbc9c3dd30de34ecff5b8a904e7f6");
outPk.push_back(std::make_pair("", an_outPk));
}
rv.add_child("outPk", outPk);
}
root.add_child("rv", rv);
//
auto ret_string = serial_bridge::decodeRct(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
string mask_string = ret_tree.get<string>(ret_json_key__decodeRct_mask());
BOOST_REQUIRE(mask_string.size() > 0);
cout << "bridged__decodeRct: mask_string: " << mask_string << endl;
BOOST_REQUIRE(mask_string == "3f59c741c9ad560bfea92f42449a180bc8362f1b5ddd957e3b5772dbaf7f840e");
string amount_string = ret_tree.get<string>(ret_json_key__decodeRct_amount());
BOOST_REQUIRE(amount_string.size() > 0);
cout << "bridged__decodeRct: amount_string: " << amount_string << endl;
BOOST_REQUIRE(amount_string == "4501"); // FIXME is this correct?
}
//
BOOST_AUTO_TEST_CASE(bridged__decodeRctSimple)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("i", "0");
root.put("sk", "a2259749f7aad692e000af4b7f383f4441ba4085bf70e518081365750db73b06");
boost::property_tree::ptree rv;
{
rv.put("type", "3");
//
boost::property_tree::ptree ecdhInfo;
{
boost::property_tree::ptree ecdh_info;
ecdh_info.put("mask", "dc9a2e8a66a336f67bb1a150f6de4522f09c451a10f450d7ee096baa75660a05");
ecdh_info.put("amount", "0c8f7514fd1d7c4f49795f33254739ce8e96275b17f50a03c877ed4b56896601");
ecdhInfo.push_back(std::make_pair("", ecdh_info));
}
{
boost::property_tree::ptree ecdh_info;
ecdh_info.put("mask", "f0d94c21aa892ad4e0d492f5fce4b8e99ff5e1ed687134b9419a2290e8701004");
ecdh_info.put("amount", "dbaeca613d37b53ff0a22a1fb6e09150baa6f4f5f6e145ef78a78cc19624a702");
ecdhInfo.push_back(std::make_pair("", ecdh_info));
}
rv.add_child("ecdhInfo", ecdhInfo);
//
boost::property_tree::ptree outPk;
{
boost::property_tree::ptree an_outPk;
an_outPk.put("mask", "4dd9e7e2a2d8f31f065562923079399ec6c90d4b155d289208001994815bd01f");
outPk.push_back(std::make_pair("", an_outPk));
}
{
boost::property_tree::ptree an_outPk;
an_outPk.put("mask", "c23cdb07e56bcb6a9ad087122b7079f2c34e217bcbddd16ca6031ab8828f7a84");
outPk.push_back(std::make_pair("", an_outPk));
}
rv.add_child("outPk", outPk);
}
root.add_child("rv", rv);
//
auto ret_string = serial_bridge::decodeRctSimple(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
string mask_string = ret_tree.get<string>(ret_json_key__decodeRct_mask());
BOOST_REQUIRE(mask_string.size() > 0);
cout << "bridged__decodeRctSimple: mask_string: " << mask_string << endl;
BOOST_REQUIRE(mask_string == "51bdfc13c6757758148dd493a77e94073a062622a056a915a457abe6ca6c050b");
string amount_string = ret_tree.get<string>(ret_json_key__decodeRct_amount());
BOOST_REQUIRE(amount_string.size() > 0);
cout << "bridged__decodeRctSimple: amount_string: " << amount_string << endl;
BOOST_REQUIRE(amount_string == "10000000000");
}
// with bulletproof2
BOOST_AUTO_TEST_CASE(bridged__decodeRctSimple_with_bulletproof2)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("i", "1");
root.put("sk", "6d610888e25f36701f394ffdd90a65b0dabcf9af5e08dc1508f261d1518ef302");
boost::property_tree::ptree rv;
{
rv.put("type", "4");
//
boost::property_tree::ptree ecdhInfo;
{
boost::property_tree::ptree ecdh_info;
ecdh_info.put("amount", "4ecd30261cf20abd");
ecdhInfo.push_back(std::make_pair("", ecdh_info));
}
{
boost::property_tree::ptree ecdh_info;
ecdh_info.put("amount", "f024c943ea864831");
ecdhInfo.push_back(std::make_pair("", ecdh_info));
}
rv.add_child("ecdhInfo", ecdhInfo);
//
boost::property_tree::ptree outPk;
{
boost::property_tree::ptree an_outPk;
an_outPk.put("mask", "f665a172ea10f19da0d5af66554951ea94d36ee2570e34e1ce4f65aa55c5f53b");
outPk.push_back(std::make_pair("", an_outPk));
}
{
boost::property_tree::ptree an_outPk;
an_outPk.put("mask", "a3befe86882b1dac68c34d907168a41939603e4bcb0b61500e526d54c44000f0");
outPk.push_back(std::make_pair("", an_outPk));
}
rv.add_child("outPk", outPk);
}
root.add_child("rv", rv);
//
auto ret_string = serial_bridge::decodeRctSimple(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
string mask_string = ret_tree.get<string>(ret_json_key__decodeRct_mask());
BOOST_REQUIRE(mask_string.size() > 0);
cout << "bridged__decodeRctSimple_with_bulletproof2: mask_string: " << mask_string << endl;
BOOST_REQUIRE(mask_string == "b90780ff4f16d9ae3d3e3b84aebd5ebc0c7d37e5197fef9353a400409b743903");
string amount_string = ret_tree.get<string>(ret_json_key__decodeRct_amount());
BOOST_REQUIRE(amount_string.size() > 0);
cout << "bridged__decodeRctSimple_with_bulletproof2: amount_string: " << amount_string << endl;
BOOST_REQUIRE(amount_string == "2000000000");
}
//
BOOST_AUTO_TEST_CASE(bridged__encrypt_payment_id)
{
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("payment_id", "f0756322689f8299");
root.put("public_key", "9c8bd8a9ff8703ddd5e28a36dc5c5586d2ec0b4bfd9190adeea825db5808ead2");
root.put("secret_key", "74f277a60613a4efa33258b9814c78e0ff7a53cf8d2cd248ee921ac7f607f800");
//
auto ret_string = serial_bridge::encrypt_payment_id(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<string> str = ret_tree.get_optional<string>(ret_json_key__generic_retVal());
BOOST_REQUIRE(str != none);
BOOST_REQUIRE((*str).size() > 0);
cout << "bridged__encrypt_payment_id: " << *str << endl;
BOOST_REQUIRE(*str == "6565253f11d43de5");
}
//
//
// NOTE: output 0's rct field is actually borrowed from output 1 since it got deleted (and the stagenet account which produced this data has since been swept).
string OM_stagenet__unspent_outs_json = "{\"unspent_outs\":[{\"amount\":\"25281219529517\",\"rct\":\"8b22c4fadb152cb8e6c6dd21d2cf46b668a3657fcf666973c7f2a8354eae384501000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"global_index\":642806,\"height\":189324,\"index\":0,\"public_key\":\"4e8f890509b157125cc529218a97f4c5e5711af3b36e6d04881391105b8de2c7\",\"tx_hash\":\"0bb8cfdb2c5c142c87faaf3cc6523fdf82fb5435cb382218a5df3e338202fa8e\",\"tx_id\":257,\"tx_prefix_hash\":\"51799f1647ec5d98255db8a51ecea3aebdc7c6015f6cef166643d0334f592915\",\"tx_pub_key\":\"e8cd4671aa2be2f1b169c1dc0c5e80ed6b19149b336bb02d825fb1728677eae2\"},{\"amount\":\"25280399800334\",\"global_index\":642823,\"height\":189341,\"index\":0,\"public_key\":\"6c69745ebadc04ff068e55ff113d1c44658f7b5b4311e748a8fcccb261dac263\",\"rct\":\"8b22c4fadb152cb8e6c6dd21d2cf46b668a3657fcf666973c7f2a8354eae384501000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"tx_hash\":\"70d1678c23289d45f6d556bdfed0de52559141edb2645a62935027032c8e891e\",\"tx_id\":258,\"tx_prefix_hash\":\"1e43e7aefcea766096d7ab902dc63dc11dc6cb4d7db8511eb01ef65457c69d9a\",\"tx_pub_key\":\"36fc11368f364e85e3863176487b06d705c3bf901d997b7a2683c567a95e2777\"},{\"amount\":\"25280158708574\",\"global_index\":642828,\"height\":189346,\"index\":0,\"public_key\":\"977f3d24792f583a8c8fc3123c35589c83e1a29e573cfaf35d6957f9bb286469\",\"rct\":\"761f8ac29fc66b8d004600155caf98c5a1db7173d616a696a520969425cd647a01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"tx_hash\":\"45c7151f27376cdabf3e0e6c0a6412ad7b74cf06e8aff1f1f18eda96c7aa2755\",\"tx_id\":259,\"tx_prefix_hash\":\"67c48668d2340692a348d89b55e6888833a2b219028b29947cebb6b1210b14f3\",\"tx_pub_key\":\"f21b25d38bf0b64eda40434f88fffa2e574d894ee788a97710acea189978a180\"},{\"amount\":\"25280062272513\",\"global_index\":642830,\"height\":189348,\"index\":0,\"public_key\":\"21df141a799f53b262c89293e2dc4f99fa661de3378cd65ad709608720b2ded8\",\"rct\":\"92c27bb967345986e94b02ec14558eaf7d93168f2e7a4376c22e9d55a5fb89b801000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"tx_hash\":\"3a42dc8deaf1a9d1188e36b2354eb140fdd34c36c18b9232b0c163b480ffb762\",\"tx_id\":260,\"tx_prefix_hash\":\"76e3943d64f731071f35b0e0f28b7e084285ff32ee91d4eb4affb51f39bd26e1\",\"tx_pub_key\":\"e1eb916dc0c92c05da1bfa620af6750b8d8713a552e03d470b113d73f84f489f\"},{\"amount\":\"25279628314794\",\"global_index\":642839,\"height\":189357,\"index\":0,\"public_key\":\"0bfe8c187810c13ed423cbeb19219ec41732489a492b492e4069c448eef94b1c\",\"rct\":\"8f4c588457e4c162d12a1927307fa1c4065fff90da75a400629415dddc655b3b01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"tx_hash\":\"ef9fde50a44ea003d51fe555f75f73995135e10f1783aa095fd4f494a026dde4\",\"tx_id\":261,\"tx_prefix_hash\":\"a1b0cf4ec0415257da3cc4854a9da975a3a5673b161dab2ec31da3858cdfa1f8\",\"tx_pub_key\":\"d2f0cbb319de4de653e683ea552d9856d0de99c323078c74bbcae5d2a6784328\"},{\"amount\":\"25279242580853\",\"global_index\":642847,\"height\":189365,\"index\":0,\"public_key\":\"f7d0bfea20a9a73346c868af3a925e17f30f3eda513023c513a59883e7edfd3d\",\"rct\":\"7f91e3fd454d27e231f5b90909be59f067ca704d9e9e92555b6a255145c369cd01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"tx_hash\":\"f982fd2b94333f63ac8294037cc6a8afdf6cd87f024fb453a24bad1e6259393d\",\"tx_id\":262,\"tx_prefix_hash\":\"d8c283e8f8d79a72c02c0869d9b629e7d8dafe7f8a32e17e12e16bd68d5fce6c\",\"tx_pub_key\":\"edcdafda5b834b0dd7ecd748a2b73b65c36c09853c32345d4146579eecb9614c\"},{\"amount\":\"25280290942143\",\"global_index\":642850,\"height\":189368,\"index\":0,\"public_key\":\"9e9b9ec98bf50382ad64ae178eda96455cce5b494623f28fb36b09dc750b7f28\",\"rct\":\"f604
string OM_stagenet__rand_outs_json = "{\"mix_outs\":[{\"amount\":\"0\",\"outputs\":[{\"global_index\":396567,\"public_key\":\"841c0540176bf72d0cf44806cb481fd1c1ddb1423c8e158ecb154626de4aa219\",\"rct\":\"66c40a4cda875983e23ae7fa23fab2c3b0ec210b5aad838d85583eb0185b78ea987ca3b45e1c5396a0b493a21e4c765a1dae6e3fdf428d7b6b9718e47557910bf52392367413b6d6901624ee0df46fe2b1b2b820c68b36029677b35d18c55408\"},{\"global_index\":549126,\"public_key\":\"931063eda20cbbccfbec5ca1e776123d84eb9b524c0e10f2e8b9c9245f60ed12\",\"rct\":\"052756b6c25633a544ebda021de45bdca71c13d75dad47550bfde2300bb0effa479b2e96bf533a9342ae66d06fe05d8b6ad0d63d40e5bcee1e1949c015d5fc0e8bee43e1b67cecee6c990fe026c5ad8eb23f46f09f5bbf1132b695a0d295a205\"},{\"global_index\":107684,\"public_key\":\"4c72b36d9fe5cb85a99bd3e2092ea3cc405ee6c8a23d2062f9909b8be17ba68f\",\"rct\":\"f610785155c4841ce28cff5a524eb5a89206667b3886cdf361b5181e2698618900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"},{\"global_index\":599301,\"public_key\":\"50fa87714baaa3c4aa0a1521e034c142c33016600c2993707b950233f89cd88d\",\"rct\":\"deb98ad8d8ebb48f977e0b6c7b5631cef2edb071ee6b5336302db3cb1a76db2900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"},{\"global_index\":440995,\"public_key\":\"5b38f11f0b532c7bb168fc53180b5044fce17b65f8c46b25d661c3bef7a84d9b\",\"rct\":\"7e097bd6e2655c678d134789c09b6cf8b5f408ab5daf438d5b09d8629e09f6ce429d1d3f8ed030c2b9386c91f2166c65f7bd022e21e7f9d49785abc2dc081609fdabe18cc6216be4148419786299282d6229af1b3242ec1579beb571afcfa607\"},{\"global_index\":623015,\"public_key\":\"07137bc9e412eecae31871279fb80896c771b0ea408cb40d9f9e683de13de6ff\",\"rct\":\"8565e3131cf34a4cb0a62c1f340cfb313d32010786e0ad88fcbdfaec1d3c0c8b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"},{\"global_index\":317661,\"public_key\":\"f50a4d572230aba56cb08ca84429dfd77a8564304ef4ba8ba847e00345a655c9\",\"rct\":\"d0d0be0296aad2412058fc65372aee9a61fa7df0efc6bb6cca6b5bec131dc9957573322031219bb1cbaa108a3ecbd3e5cc13a3c7d48dd70c792c80fe6c43640057f55f71b565dd90ca24a403ba93fe48ffae36b6a94d1b773be008fbfd513e05\"},{\"global_index\":153786,\"public_key\":\"68bae4aa3a12b2ccfe4a82f2ca90c9f0a1dade21744a383de26d8e366f468ab8\",\"rct\":\"32e0d57de61a3b4bf70a08686be1b1592db72f9e0be0123df8095d9a4b98b62dd2f283a225d57ccf768be2c4004c875e36371681dc5fb030ef348ba8c22be40740e531ea20c8dd200823c9363eb37a11a1121a83cfe063ca3547d58745a6d101\"},{\"global_index\":360768,\"public_key\":\"758b308d7297d2da2d4872c2db6f61100f5fb7eb7aaa6357aacc69e5ef61280b\",\"rct\":\"54f2c2c827dbbf80a131bb27ac9ab6724001eafb136bd5916c202236211bcfe4d9f68dcb00bfb3fb01e41c91f07d06016db9e420e7277a21cd72b7b52dab7a011f5b7a4c5abf0d9013b42e98b6f16f06c4f61dd8468089002e169058292b1e0a\"},{\"global_index\":613372,\"public_key\":\"e31fa7b495c6e2d1a12511a2833fbd224bb1c8463ecc15d4ba44cd32c6856103\",\"rct\":\"e1a9e52ec110a580f2a444f70efe24c019ca4dac8cafa0c8dca61d26bc0591f200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"},{\"global_index\":630358,\"public_key\":\"8ab2e91d587142844107cb220dbddfa5f1c49f08c5144b637419165eb15b510c\",\"rct\":\"740969143db8beb3b1d886bfc6a534cfffddc4b4548192a7f9dd67730e1aa8f7c27cb174dd7de99007097c14798f323be74c5f456a38bdb873101998fe35c40f26d3f37113f6f868e0551b8ad53d8cea066ff1faae460efdea4b975e2369840e\"}]}]}";
BOOST_AUTO_TEST_CASE(bridge__transfers__send_stagenet_coinbase)
{
using namespace serial_bridge;
using namespace monero_transfer_utils;
//
// this being input as JSON merely for convenience
boost::property_tree::ptree pt;
stringstream ss;
ss << OM_stagenet__unspent_outs_json;
boost::property_tree::json_parser::read_json(ss, pt);
boost::property_tree::ptree unspent_outs = pt.get_child("unspent_outs");
//
// NOTE: in the real algorithm you should re-request this _each time step2 must be called_
// this being input as JSON merely for convenience
boost::property_tree::ptree mix_outs;
{
boost::property_tree::ptree pt;
stringstream ss;
ss << OM_stagenet__rand_outs_json;
boost::property_tree::json_parser::read_json(ss, pt);
mix_outs = pt.get_child("mix_outs");
}
//
// Send algorithm:
bool tx_must_be_reconstructed = true; // for ease of writing this code, start this off true & structure whole thing as while loop
optional<string> fee_actually_needed_string = none;
size_t construction_attempt_n = 0;
while (tx_must_be_reconstructed) {
construction_attempt_n += 1; // merely kept for assertion purposes
//
optional<string> mixin_string;
optional<string> change_amount_string;
optional<string> using_fee_string;
optional<string> final_total_wo_fee_string;
boost::property_tree::ptree using_outs;
{
boost::property_tree::ptree root;
root.put("is_sweeping", "false");
root.put("payment_id_string", "d2f602b240fbe624"); // optl
root.put("sending_amount", "1000000000000");
root.put("fee_per_b", "166333");
root.put("fee_mask", "10000");
root.put("fork_version", "10");
root.put("priority", "1");
root.add_child("unspent_outs", unspent_outs);
if (fee_actually_needed_string != none) {
BOOST_REQUIRE(construction_attempt_n > 1);
//
// for next round's integration - if it needs to re-enter... arg "passedIn_attemptAt_fee"
root.put("passedIn_attemptAt_fee", *fee_actually_needed_string);
}
auto ret_string = serial_bridge::send_step1__prepare_params_for_get_decoys(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<uint32_t> err_code = ret_tree.get_optional<uint32_t>(ret_json_key__any__err_code());
if (err_code != none && (CreateTransactionErrorCode)*err_code != monero_transfer_utils::noError) {
if ((CreateTransactionErrorCode)*err_code == monero_transfer_utils::needMoreMoneyThanFound) {
optional<string> spendable_balance_string = ret_tree.get_optional<string>(ret_json_key__send__spendable_balance());
BOOST_REQUIRE(spendable_balance_string != none);
BOOST_REQUIRE((*spendable_balance_string).size() > 0);
// uint64_t fee = stoull(*fee_string);
// BOOST_REQUIRE(fee == 135000000);
cout << "bridge__transfers__send_stagenet_coinbase: step1: needMoreMoneyThanFound: spendable_balance " << *spendable_balance_string << endl;
//
optional<string> required_balance_string = ret_tree.get_optional<string>(ret_json_key__send__required_balance());
BOOST_REQUIRE(required_balance_string != none);
BOOST_REQUIRE((*required_balance_string).size() > 0);
// uint64_t fee = stoull(*fee_string);
// BOOST_REQUIRE(fee == 135000000);
cout << "bridge__transfers__send_stagenet_coinbase: step1: needMoreMoneyThanFound: required_balance " << *required_balance_string << endl;
}
auto err_msg = err_msg_from_err_code__create_transaction((CreateTransactionErrorCode)*err_code);
BOOST_REQUIRE_MESSAGE(false, err_msg);
// ^--- not expecting anything like needMoreMoneyThanFound errors here
}
mixin_string = ret_tree.get_optional<string>(ret_json_key__send__mixin());
BOOST_REQUIRE(mixin_string != none);
BOOST_REQUIRE((*mixin_string).size() > 0);
uint64_t mixin = stoull(*mixin_string);
BOOST_REQUIRE(mixin == 10);
cout << "bridge__transfers__send_stagenet_coinbase: mixin " << *mixin_string << endl;
//
using_fee_string = ret_tree.get_optional<string>(ret_json_key__send__using_fee()); // save this
BOOST_REQUIRE(using_fee_string != none);
BOOST_REQUIRE((*using_fee_string).size() > 0);
// uint64_t using_fee = stoull(*using_fee_string);
// BOOST_REQUIRE(using_fee == 10); // TODO:?
cout << "bridge__transfers__send_stagenet_coinbase: step1: using_fee " << *using_fee_string << endl;
//
using_outs = ret_tree.get_child(ret_json_key__send__using_outs()); // save this for step2
BOOST_FOREACH(boost::property_tree::ptree::value_type &output_desc, using_outs)
{
assert(output_desc.first.empty()); // array elements have no names
cout << "bridge__transfers__send_stagenet_coinbase: step1: using_out " << output_desc.second.get<string>("public_key") << endl;
}
//
change_amount_string = ret_tree.get_optional<string>(ret_json_key__send__change_amount());
BOOST_REQUIRE(change_amount_string != none);
BOOST_REQUIRE((*change_amount_string).size() > 0);
// uint64_t change_amount = stoull(*change_amount_string);
// BOOST_REQUIRE(change_amount == 10); // TODO:?
cout << "bridge__transfers__send_stagenet_coinbase: step1: change_amount " << *change_amount_string << endl;
//
final_total_wo_fee_string = ret_tree.get_optional<string>(ret_json_key__send__final_total_wo_fee());
BOOST_REQUIRE(final_total_wo_fee_string != none);
BOOST_REQUIRE((*final_total_wo_fee_string).size() > 0);
// uint64_t final_total_wo_fee = stoull(*final_total_wo_fee_string);
// BOOST_REQUIRE(final_total_wo_fee == 10); // TODO:?
cout << "bridge__transfers__send_stagenet_coinbase: step1: final_total_wo_fee " << *final_total_wo_fee_string << endl;
//
}
{
boost::property_tree::ptree root;
root.put("final_total_wo_fee", *final_total_wo_fee_string);
root.put("change_amount", *change_amount_string); // from step1
root.put("fee_amount", *using_fee_string); // from step1
root.add_child("using_outs", using_outs); // from step1
//
root.put("payment_id_string", "d2f602b240fbe624"); // optl
root.put("nettype_string", string_from_nettype(STAGENET));
root.put("to_address_string", "57Hx8QpLUSMjhgoCNkvJ2Ch91mVyxcffESCprnRPrtbphMCv8iGUEfCUJxrpUWUeWrS9vPWnFrnMmTwnFpSKJrSKNuaXc5q");
root.put("from_address_string", "56bY2v2RJZNEvrKdYuwG73Q2idshQyGc5fV74BZqoVv72MPSBEakPbfWYtQH4PLGhk3uaCjNZ81XJ7o9pimAXzQFCv7bxxf");
root.put("sec_viewKey_string", "9ef8e116d2c774b207a2dd6a234dab8f5d54becc04aa26ccbd6f1f67e8427308");
root.put("sec_spendKey_string", "4acde2a96d5085423fcc8713c878448b35e45900f4e9cf2c0b643eb4268e140e");
root.put("fee_per_b", "166333");
root.put("fee_mask", "10000");
root.put("fork_version", "10");
root.put("unlock_time", "0");
root.put("priority", "1");
root.add_child("mix_outs", mix_outs);
//
boost::property_tree::ptree ret_tree;
auto ret_string = serial_bridge::send_step2__try_create_transaction(args_string_from_root(root));
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<uint32_t> err_code = ret_tree.get_optional<uint32_t>(ret_json_key__any__err_code());
if (err_code != none && (CreateTransactionErrorCode)*err_code != monero_transfer_utils::noError) {
auto err_msg = err_msg_from_err_code__create_transaction((CreateTransactionErrorCode)*err_code);
BOOST_REQUIRE_MESSAGE(false, err_msg);
}
//
tx_must_be_reconstructed = ret_tree.get<bool>(ret_json_key__send__tx_must_be_reconstructed());
cout << "bridge__transfers__send_stagenet_coinbase: step2: must tx be reconstructed? " << tx_must_be_reconstructed << endl;
if (tx_must_be_reconstructed) {
// declared outside the for-loop so that we can use it for subsequent iterations if needed:
fee_actually_needed_string = ret_tree.get_optional<string>(ret_json_key__send__fee_actually_needed());
BOOST_REQUIRE(fee_actually_needed_string != none);
BOOST_REQUIRE((*fee_actually_needed_string).size() > 0);
//
// This means we must go back through step1 to re-pick using_outs
BOOST_REQUIRE(construction_attempt_n < 3); // not generally expecting to have to do this more than once or twice
continue; // proceed to next iteration (re-enter tx construction at step1(II) with fee_actually_needed_string from step2(I))
}
optional<string> tx_hash = ret_tree.get_optional<string>(ret_json_key__send__tx_hash());
optional<string> tx_key_string = ret_tree.get_optional<string>(ret_json_key__send__tx_key());
optional<string> serialized_signed_tx = ret_tree.get_optional<string>(ret_json_key__send__serialized_signed_tx());
BOOST_REQUIRE(serialized_signed_tx != none);
BOOST_REQUIRE((*serialized_signed_tx).size() > 0);
cout << "bridge__transfers__send_stagenet_coinbase: serialized_signed_tx: " << *serialized_signed_tx << endl;
BOOST_REQUIRE(tx_hash != none);
BOOST_REQUIRE((*tx_hash).size() > 0);
cout << "bridge__transfers__send_stagenet_coinbase: tx_hash: " << *tx_hash << endl;
BOOST_REQUIRE(tx_key_string != none);
BOOST_REQUIRE((*tx_key_string).size() > 0);
cout << "bridge__transfers__send_stagenet_coinbase: tx_key_string: " << *tx_key_string << endl;
}
}
}
//
//#include "../src/emscr_async_bridge_index.hpp"
//BOOST_AUTO_TEST_CASE(emscr_bridge__send_funds__sweep)
//{
// using namespace emscr_async_bridge;
// using namespace monero_transfer_utils;
// //
// boost::property_tree::ptree root;
// root.put("task_id", "some guid");
// root.put("nettype_string", string_from_nettype(MAINNET));
// root.put("to_address_string", "4APbcAKxZ2KPVPMnqa5cPtJK25tr7maE7LrJe67vzumiCtWwjDBvYnHZr18wFexJpih71Mxsjv8b7EpQftpB9NjPPXmZxHN");
// root.put("from_address_string", "43zxvpcj5Xv9SEkNXbMCG7LPQStHMpFCQCmkmR4u5nzjWwq5Xkv5VmGgYEsHXg4ja2FGRD5wMWbBVMijDTqmmVqm93wHGkg");
// root.put("sec_viewKey_string", "7bea1907940afdd480eff7c4bcadb478a0fbb626df9e3ed74ae801e18f53e104");
// root.put("sec_spendKey_string", "4e6d43cd03812b803c6f3206689f5fcc910005fc7e91d50d79b0776dbefcd803");
// root.put("pub_spendKey_string", "3eb884d3440d71326e27cc07a861b873e72abd339feb654660c36a008a0028b3");
// root.put("sending_amount", "0");
// root.put("is_sweeping", "true");
// root.put("payment_id_string", "d2f602b240fbe624"); // optl
// root.put("priority", "1");
// root.put("unlock_time", "0");
// //
// emscr_async_bridge::send_funds(args_string_from_root(root));
//}
//
string _send_routine__sweep_getUnspentOuts_dummyReplyJSONStr = "{\"per_kb_fee\":24450000,\"amount\":\"4911514979789\",\"outputs\":[{\"amount\":\"400000000000\",\"public_key\":\"cfdbedf495dc30be82d4934b72af8b1af98b4a35faf984f2c16e4866f45330ae\",\"index\":0,\"global_index\":660333,\"rct\":\"40dd3f5c6c1ff8fe353cb08881c182c29ff7d9ab0055ef36f54514db7e894ef17b1117f21a7ec92dae74f07a6dfdf791eb6d8946615c16ea38ab5a0fb0538d056eb5f5bcd5cccb8b91744845d4f3486eaa9e7d9d2ac51f7364628abf44150100\",\"tx_id\":2455631,\"tx_hash\":\"354d9874b7b13befcf8f079520ad72b78dc62de6081765ce5490345c7623d41a\",\"tx_pub_key\":\"fc7f85bf64c6e4f6aa612dbc8ddb1bb77a9283656e9c2b9e777c9519798622b2\",\"tx_prefix_hash\":\"4448cbd20af2f4f14286707cc35b742e5eaf184037317017794d003457d720e2\",\"spend_key_images\":[\"ae30ee23051dc0bdf10303fbd3b7d8035a958079eb66516b1740f2c9b02c804e\",\"3eb5bdbf119de8b0fea2b52e2c63ebfd2be152713326f7e0acb9c996a9007611\",\"3c8ee840913cb4163f5b705aeb1da0b9b234be67cb61abf21c6648f40964479f\",\"72fb0972751bfbcdd3ba62114d4371a25d54cf0e4c6c8ecb5bc0e3af1fafadab\",\"810aca616598c564ca856330a3677592a5390bdddadf3e82d1563731dd2eef3c\",\"423b9e89ed014f453eed8e914d7d8e77ca9f75805e5251750c35b09120b38755\",\"dde80dee4ed041ffc2d85c020509fbd568e0ce440b9a12a3268ffe5490d027f8\"],\"timestamp\":\"2018-11-14T19:31:53Z\",\"height\":1293044},{\"amount\":\"364000000000\",\"public_key\":\"583ee3787e11559d0440a2edbdc8ec993f68913a234875d2df401f7726c1dad5\",\"index\":1,\"global_index\":664673,\"rct\":\"98caf1149c4bfdac3603df8649721074aeb36d072a78dedc00c23ad9037ff4b89716ecc91c27637dde21492c6820dbbd4d7be5cc6a1e0ddbb6750a6802f042083f5ebc5807837be21951cf833674a7ea8896661cf6eaa45c0736ffc5fb88fd0a\",\"tx_id\":2457238,\"tx_hash\":\"a727cbcf59cc35f07066b314b53bc6239c4129f60e9ba1c7a8d5591b7a0b3055\",\"tx_pub_key\":\"74b6ba3dd36a85e6e9b5fe4fc093c1e57ec0dc52cbac5e487a2b7a8da091893d\",\"tx_prefix_hash\":\"e6d3a3cf89fa01b093abaeff0085919331ca9cfdadeccfa58ed0d8de528b29ae\",\"spend_key_images\":[\"673ca2516ebb41d612692f3223c367457f685e92c3b6556b28630f9231bf5f54\",\"169baea6bc976ef3bd689e8e810d5d33ca80e2cea6ef28903db324b975a2156b\",\"e848a44a4aefea9d0870bc96d87707e0bf123f311682f252481bbe553e1a91ed\",\"5ddeb3b324094dec2a7ad6091937370c847c870c9abd730ee86062f8a4a93b24\",\"033f1c75e5c5682725f392dc722a14aa28aa6bb05823277065a09e4dd5005881\",\"dbb8e201a3635adf1cddfcd7053eb4d5c3e38afbb41f6cd1311bcf98adda1700\"],\"timestamp\":\"2018-11-14T19:31:53Z\",\"height\":1293420},{\"amount\":\"238000000000\",\"public_key\":\"fa933b1558dab5303b3e8cb58bf936138bf480bae78c16ca258ab10408d88ccf\",\"index\":1,\"global_index\":666623,\"rct\":\"95f97e430358a5f163b5c26e11a3306bbe9b27275daecc0f013426db9041c00e55efd221fbb8fd0b49c85184b968f2a342c1d09d853272f497da357d78f68d02d4f4b44284ee0468ffa8a05739a2cfd292958e8fdc01d5eaa789d4c9689e3204\",\"tx_id\":2457958,\"tx_hash\":\"cfeef2b05585a781f9310dc0e4d46ab1e9d052cfce11bfd0a58b2b519d20ff49\",\"tx_pub_key\":\"4296d3473870305a732a7bc6a9290f0ec3ced426312ac75501a4211d4ef04c58\",\"tx_prefix_hash\":\"3cbdd08ac6ac67738f871eb254fced02559937c148cd848a616ea5bca9e71e76\",\"spend_key_images\":[\"3bf1610dc8e8dbf16d28400b3bd8c0cc4e673b79152593cc709f88b7b12892d5\",\"ab99d869af5ba68c806e0a8ce2cc1ae2f9b8cf8166162c01523641de5cc1df6b\",\"602b8b4b6c9aa86d9b2ace0b1bfdf9f4b3721650304bf5e79fd0f08ac6b8c363\",\"bda71e2b0b7c501e46e0c4489d1a1f167e1e46c472e78ad7f093d5e52daa386a\",\"a4ccce434fb8d0ec049ab1faf615e965e5024fdd36ff35c856f2cacec34461c0\"],\"timestamp\":\"2018-11-14T19:31:53Z\",\"height\":1293554},{\"amount\":\"202000000000\",\"public_key\":\"2ee8b8b5a2201ef17bdd4112cdd80242dcaab30826b87206973c8347c8ffa4dc\",\"index\":1,\"global_index\":689429,\"rct\":\"14051b217814eae62febf95e9ee0fa92f5aa7714b1a05ca89ae096494ff81eeee416437476f845c0b2891e9f1d4ef25c283eebd72dbd532463de0b7b74b2b604b29478a9ea4c16d01e67716a8b9d29cb9f49703a15b16f37b73f9e5a2bf2230d\",\"tx_id\":2466863,\"tx_hash\":\"26966c9217160117dc465e959be39264b84819d9875cecc6c8a63c26c7bfc3a3\",\"tx_pub_key\":\"4ff9f870ac27c8f91a8e87d678304801155242c71832dff41a1b64fa8f1fb486\",\"tx_prefix_hash\":\"e4cd3a2ea71bd7c63d8958785c98337bff59dbfda2f
string _send_routine__sweep_getRandomOuts_dummyReplyJSONStr = "{\"amount_outs\":[{\"amount\":\"0\",\"outputs\":[{\"global_index\":\"6478600\",\"public_key\":\"1a51a97c32b92ee16bcbdefcd572f36610cd76823a44528a96ff0d024e2a6b6d\",\"rct\":\"3c3a83bedf703b50da3ea1f001a794a03e36199c8289e80dbf4834c0b32d8bd5\"},{\"global_index\":\"7387285\",\"public_key\":\"6fdaa719986cf4b1f0c0ab057796c8d292c51e2c6f4fa988a8f85517b3d0d3df\",\"rct\":\"52a20ff6e02c18c10a7b91de3ce94f36de3287e4e77400fc140032184ff30dfe\"},{\"global_index\":\"7680334\",\"public_key\":\"c8de7e6b67ab6e4033590ab423382b9d9c290b3be037360637b3c050a75e9280\",\"rct\":\"83ed23ab140d68a712782ee39494d7f691d6afe44782e818af7292bdb51f4db8\"},{\"global_index\":\"7722664\",\"public_key\":\"8f7e355241f03105faf475f3070b11ef1b0cdecabf165c39a92564c32d09756f\",\"rct\":\"f43c2a397de781d18a9b0b242265263cb2ed26fb40cc9fac1228e2434ddc866f\"},{\"global_index\":\"7829810\",\"public_key\":\"ffffb90a2fa4a30eab0dc89d0fe7fbdbe95055b49001fc163756dca8982163d0\",\"rct\":\"ef12dd0adc8aa6051c18f9846900bb279f8c9e9b97930a8aae37911e30a7aedd\"},{\"global_index\":\"7861666\",\"public_key\":\"bf243c7511088ca6065b71bbe47c69056e1517b159d659c5b82f0c7f841259a4\",\"rct\":\"b8a348ed838b7bf556827745b7ef71c7fef2cbe4c2b83c67f5eb903e081c23c3\"},{\"global_index\":\"7866897\",\"public_key\":\"18df6f38df05eb1cae8119073fdcc3cc09fc79b3ec4baaa3bb3cc63d93e76d82\",\"rct\":\"927d87944cfb827033c685d05d907c4455f662d64efd397566799f7aa8006cb9\"},{\"global_index\":\"7867193\",\"public_key\":\"d1ad81ab293058a548f5b168e5ddadb1447c7b7914031053149eb53973be3620\",\"rct\":\"0160dd071e3859deefa289d27e996e356169f90985d75006741b6a36c71c38da\"},{\"global_index\":\"7876522\",\"public_key\":\"f46ee44b2ef816e7427a9bce0964b07592c86e23429a1c20602e64bcf0139bae\",\"rct\":\"8b1ffcdd2e86e5207672233a9cb30d2b8729fac1cb9f326023ffa65db4e09bdf\"},{\"global_index\":\"7885794\",\"public_key\":\"bc6e9dfe5354fbee384fdb11e23b3a244228027b85af52eac4362438bcd20e23\",\"rct\":\"f59c663f7d415dfbf6459ae7337c29b9f81ae1f7ffdf3b4f452611ea9b838d8c\"},{\"global_index\":\"7826288\",\"public_key\":\"bcdf302f813eb0d1f10046538e6d226344197a12f1f2b54e2f095ca234799818\",\"rct\":\"76d3bc9e1147252be5a4bd45f4552427e93ead62b69be93f1bfb73645d4b94fb\"}]},{\"amount\":\"0\",\"outputs\":[{\"global_index\":\"7572314\",\"public_key\":\"0477758ef7a78fb0c99cbb2a0f9faa4c85e1ee8b99cd9ffb102a539e570b3b44\",\"rct\":\"34e6aaa6f3aeb45df8dc74e626cc0845e3db6f5f9bd59506cc1fee7e7dddffbe\"},{\"global_index\":\"7772070\",\"public_key\":\"e74d40544df0746c613a854f6401b544999ce4242eb1718b5e1ab7ca3ecda08d\",\"rct\":\"a827403583c7283c05cb3db3ec2930ed14684afa4b5b906b63a71d19e2cc2ad2\"},{\"global_index\":\"7783300\",\"public_key\":\"c2416f761ce191530bc84253fea43cf83e3fb7d03cfd5befdcf84aeed8cde2bd\",\"rct\":\"2498a64a44d6b1dd6ae87e66bb9cf51e9a46f93a964c9645e7316cf5ded3761e\"},{\"global_index\":\"7835881\",\"public_key\":\"3878b4d45c1fdb9afc8d177e427fad6b6609cc1382efeec9138e4e759baee6a4\",\"rct\":\"2ea2bab06178288253ec4d46f3d16d419d7f9cbfa2d4d8b7586a2e044c14f87d\"},{\"global_index\":\"7845569\",\"public_key\":\"bf78585e53b21925dfff9462e0928479f3892cd98b991f5973a85ddff1b63267\",\"rct\":\"dc539fbee461867eada54ee4c46becdc505e4f79a0c9c2d5e6587ca9e8bd10da\"},{\"global_index\":\"7877601\",\"public_key\":\"939b7fca3c60bd00e63328daffc51bfc6f9d85cb402c9e740a7773a84f98957d\",\"rct\":\"a2f921124806ac9204a1a06afbaedcb305a26b01027ab381292ffe4074c40022\"},{\"global_index\":\"7883058\",\"public_key\":\"977f6e676a84a91d5120a534ec531ed22b1d60725da8d5a32628aa753b0eebb7\",\"rct\":\"fbf474120aac8003388b2af9706ae2502a1fee6b1bd692776b5b9d1aa2b3a977\"},{\"global_index\":\"7884736\",\"public_key\":\"3fe000a8d5b63150c38f0ebf9995848a3f7e86470efeb9eee0e89817b2d90f7c\",\"rct\":\"d0d85fc88b015dfb2c056d36a43bb7a6858c9b67a1062096964e5e935aa2854f\"},{\"global_index\":\"7885562\",\"public_key\":\"d361e28435b72229dd3d532c60df465a84a478d495226915ed959d12e75f6fa2\",\"rct\":\"b55ad4ed092a446da60ddb2edd6ab287a05cc329b580c7c99ec46327378dbe86\"},{\"global_index\":\"7886354\",\"public_key\":\"918ff14531d53b667b361ff1a5a04f6cc5eaa90f4053cbef99e060841516cbb
//
string _send_routine__sweep_submitRawTx_dummyReplyJSONStr = "{}";
//
#include "../src/monero_send_routine.hpp"
BOOST_AUTO_TEST_CASE(send_routine__sweep)
{
using namespace monero_send_routine;
using namespace monero_transfer_utils;
//
string payment_id_string = "d2f602b240fbe624";
Async_SendFunds_Args args = {
"43zxvpcj5Xv9SEkNXbMCG7LPQStHMpFCQCmkmR4u5nzjWwq5Xkv5VmGgYEsHXg4ja2FGRD5wMWbBVMijDTqmmVqm93wHGkg",
"7bea1907940afdd480eff7c4bcadb478a0fbb626df9e3ed74ae801e18f53e104",
"4e6d43cd03812b803c6f3206689f5fcc910005fc7e91d50d79b0776dbefcd803",
"3eb884d3440d71326e27cc07a861b873e72abd339feb654660c36a008a0028b3",
"4APbcAKxZ2KPVPMnqa5cPtJK25tr7maE7LrJe67vzumiCtWwjDBvYnHZr18wFexJpih71Mxsjv8b7EpQftpB9NjPPXmZxHN",
payment_id_string, // optl
0, // sending amount
true, // is sweeping
1, // priority
[] ( // get_unspent_outs
const LightwalletAPI_Req_GetUnspentOuts &req_params,
api_fetch_cb_fn get_unspent_outs_fn__cb_fn
) -> void {
boost::property_tree::ptree res;
stringstream ss;
ss << _send_routine__sweep_getUnspentOuts_dummyReplyJSONStr;
boost::property_tree::json_parser::read_json(ss, res);
//
get_unspent_outs_fn__cb_fn(res);
},
[] ( // get_random_outs_fn
const LightwalletAPI_Req_GetRandomOuts &req_params,
const api_fetch_cb_fn get_random_outs_fn__cb_fn
) -> void {
boost::property_tree::ptree res;
stringstream ss;
ss << _send_routine__sweep_getRandomOuts_dummyReplyJSONStr;
boost::property_tree::json_parser::read_json(ss, res);
//
get_random_outs_fn__cb_fn(res);
},
[] ( // submit_raw_tx_fn
const LightwalletAPI_Req_SubmitRawTx &req_params,
const api_fetch_cb_fn submit_raw_tx_fn__cb_fn
) -> void {
boost::property_tree::ptree res;
stringstream ss;
ss << _send_routine__sweep_submitRawTx_dummyReplyJSONStr;
boost::property_tree::json_parser::read_json(ss, res);
//
submit_raw_tx_fn__cb_fn(res);
},
[] ( // status update fn
SendFunds_ProcessStep code
) -> void {
cout << "send_routine__sweep: status update: " << err_msg_from_err_code__send_funds_step(code) << endl;
},
[] ( // error
const SendFunds_Error_RetVals &err_retVals
) -> void {
if (err_retVals.explicit_errMsg != none) {
BOOST_REQUIRE_MESSAGE(false, *(err_retVals.explicit_errMsg));
} else { // manually constructing the reply json to include spendable_balance and required_balance:
BOOST_REQUIRE_MESSAGE(false, err_msg_from_err_code__create_transaction(*(err_retVals.errCode)));
}
},
[] ( // success
const SendFunds_Success_RetVals &success_retVals
) -> void {
BOOST_REQUIRE(success_retVals.used_fee > 0);
BOOST_REQUIRE(success_retVals.total_sent > 0);
BOOST_REQUIRE(success_retVals.mixin == monero_fork_rules::fixed_mixinsize());
BOOST_REQUIRE(success_retVals.signed_serialized_tx_string.size() > 0);
cout << "send_routine__sweep: serialized_signed_tx: " << success_retVals.signed_serialized_tx_string << endl;
BOOST_REQUIRE(success_retVals.tx_hash_string.size() > 0);
cout << "send_routine__sweep: tx_hash: " << success_retVals.tx_hash_string << endl;
BOOST_REQUIRE((success_retVals.tx_key_string).size() > 0);
cout << "send_routine__sweep: tx_key_string: " << success_retVals.tx_key_string << endl;
BOOST_REQUIRE((success_retVals.tx_pub_key_string).size() > 0);
cout << "send_routine__sweep: tx_pub_key_string: " << success_retVals.tx_pub_key_string << endl;
},
0,
MAINNET
};
async__send_funds(args);
}