40 #include <boost/regex.hpp> 49 namespace po = boost::program_options;
61 #define HW_TREZOR_NAME "Trezor" 62 #define TREZOR_ACCOUNT_ORDERING &m_miner_account, &m_alice_account, &m_bob_account, &m_eve_account 63 #define TREZOR_COMMON_TEST_CASE(genclass, CORE, BASE) do { \ 64 rollback_chain(CORE, BASE.head_block()); \ 68 GENERATE_AND_PLAY_INSTANCE(genclass, ctest, *(CORE)); \ 72 #define TREZOR_SETUP_CHAIN(NAME) do { \ 75 setup_chain(core, trezor_base, chain_path, fix_chain, vm_core); \ 76 } catch (const std::exception& ex) { \ 77 failed_tests.emplace_back("gen_trezor_base " #NAME); \ 87 static long get_env_long(
const char * flag_name, boost::optional<long> def = boost::none){
88 const char *env_data = getenv(flag_name);
89 return env_data ? atol(env_data) : (def ? def.
get() : 0);
92 int main(
int argc,
char* argv[])
102 po::options_description desc_options(
"Allowed options");
110 po::variables_map vm;
122 std::cout << desc_options << std::endl;
129 size_t tests_count = 0;
130 std::vector<std::string> failed_tests;
139 const uint8_t initial_hf = (
uint8_t)get_env_long(
"TEST_MIN_HF", 11);
142 MINFO(
"Testing hardforks [" << (
int)initial_hf <<
", " << (
int)max_hf <<
"]");
146 std::shared_ptr<mock_daemon>
daemon =
nullptr;
149 trezor_base.
setup_args(trezor_path, heavy_tests);
153 po::variables_map vm_core;
154 po::options_description desc_params_core(
"Core");
160 for(
uint8_t hf=initial_hf; hf <= max_hf + 1; ++hf)
162 if (hf > initial_hf || hf > max_hf)
164 daemon->stop_and_deinit();
166 trezor_base.
daemon(
nullptr);
173 MDEBUG(
"Transaction tests for HF " << (
int)hf);
177 daemon = std::make_shared<mock_daemon>(
core, vm_core);
180 daemon->try_init_and_run();
184 if (hf == initial_hf)
212 MLOG(level,
"\nREPORT:");
213 MLOG(level,
" Test run: " << tests_count);
214 MLOG(level,
" Failures: " << failed_tests.size());
215 if (!failed_tests.empty())
217 MLOG(level,
"FAILED TESTS:");
218 BOOST_FOREACH(
auto test_name, failed_tests)
220 MLOG(level,
" " << test_name);
224 return failed_tests.empty() ? 0 : 1;
234 std::vector<transaction> popped_txs;
238 MDEBUG(
"Rollbacking to " <<
height <<
" to hash " << head_hash);
243 if (cur_height <=
height && head_hash == cur_hash)
251 static bool unserialize_chain_from_file(std::vector<test_event_entry>& events,
gen_trezor_base &test_base,
const std::string& file_path)
254 std::ifstream data_file;
255 data_file.open( file_path, std::ios_base::binary | std::ios_base::in);
269 MWARNING(
"Chain deserialization failed");
275 static bool serialize_chain_to_file(std::vector<test_event_entry>& events,
gen_trezor_base &test_base,
const std::string& file_path)
278 std::ofstream data_file;
279 data_file.open( file_path, std::ios_base::binary | std::ios_base::out | std::ios::trunc);
288 return !data_file.fail();
292 MWARNING(
"Chain deserialization failed");
299 template<
class t_test_
class>
300 static bool init_core_replay_events(std::vector<test_event_entry>& events,
cryptonote::core *
core,
const po::variables_map & vm_core)
311 test_options_tmp.
hard_forks = hardforks.data();
312 test_options_ = &test_options_tmp;
320 std::vector<crypto::hash> pool_txs;
324 t_test_class validator;
325 return replay_events_through_core<t_test_class>(*
core, events, validator);
330 std::vector<test_event_entry> events;
332 const bool chain_file_exists =
do_serialize && boost::filesystem::exists(chain_path);
334 bool generated =
false;
336 if (chain_file_exists)
338 if (!unserialize_chain_from_file(events, trezor_base, chain_path))
340 MERROR(
"Failed to deserialize data from file: " << chain_path);
343 throw std::runtime_error(
"Chain load error");
347 trezor_base.
load(events);
358 generated = trezor_base.
generate(events);
363 if (!serialize_chain_to_file(events, trezor_base, chain_path))
365 MERROR(
"Failed to serialize data to file: " << chain_path);
372 trezor_base.
fix_hf(events);
373 if (generated && init_core_replay_events<gen_trezor_base>(events,
core, vm_core))
379 MERROR(
"#TEST-chain-init# Failed ");
380 throw std::runtime_error(
"Chain init error");
385 if (!trezor_device) {
389 return trezor_device;
392 static void add_hforks(std::vector<test_event_entry>& events,
const v_hardforks_t& hard_forks)
395 repl_set.
hard_forks = boost::make_optional(hard_forks);
396 events.push_back(repl_set);
399 static void add_top_hfork(std::vector<test_event_entry>& events,
const v_hardforks_t& hard_forks)
403 top_fork.push_back(hard_forks.back());
404 repl_set.
hard_forks = boost::make_optional(top_fork);
405 events.push_back(repl_set);
410 std::vector<tx_extra_field> tx_extra_fields;
415 "Public key wasn't found in the transaction extra");
421 throw std::runtime_error(
"Unsupported tx pub resolution");
432 std::vector<tx_extra_field> tx_extra_fields;
439 if (ptx.
dests.empty())
441 MWARNING(
"Encrypted payment id found, but no destinations public key, cannot decrypt");
461 memcpy(payment_id.data,
info.payment_id.data, 8);
462 memset(payment_id.data + 8, 0, 24);
467 MDEBUG(
"Payment ID: " << payment_id);
469 return construction_data;
472 static std::string get_payment_id(
const std::vector<uint8_t> &tx_extra)
474 std::vector<cryptonote::tx_extra_field> tx_extra_fields;
485 memcpy(payment_id.data, payment_id8.data, 8);
486 memset(payment_id.data + 8, 0, 24);
501 memcpy(payment_id_short.data, payment_id.data(), 8);
502 return payment_id_short;
509 memcpy(payment_id_long.data, payment_id.data(), 32);
510 return payment_id_long;
513 static std::vector<uint8_t> build_payment_id_extra(
const std::string & payment_id)
515 std::vector<uint8_t>
res;
517 if (payment_id.size() == 8) {
520 memcpy(payment_id.data,
info.payment_id.data, 8);
521 memset(payment_id.data + 8, 0, 24);
526 }
else if (payment_id.size() == 32){
540 res.is_subaddress = is_sub;
542 res.has_payment_id =
true;
543 res.payment_id = payment_id.get();
545 res.has_payment_id =
false;
556 rv.p.MGs[0].II.resize(tx.
vin.size());
557 for (
size_t n = 0; n < tx.
vin.size(); ++n)
558 rv.p.MGs[0].II[n] = rct::ki2rct(boost::get<txin_to_key>(tx.
vin[n]).k_image);
563 for (
size_t n = 0; n < tx.
vin.size(); ++n)
565 rv.p.MGs[n].II.resize(1);
566 rv.p.MGs[n].II[0] = rct::ki2rct(boost::get<txin_to_key>(tx.
vin[n]).k_image);
573 std::vector<tools::wallet2*>
res;
592 for(
const auto & cur : transfers)
594 sum += !cur.m_spent && cur.m_subaddr_index.major == account ? cur.amount() : 0;
604 const std::string gen_trezor_base::m_device_seed =
"permit universe parent weapon amused modify essay borrow tobacco budget walnut lunch consider gallery ride amazing frog forget treat market chapter velvet useless topple";
610 m_test_get_tx_key =
true;
615 m_generator(other.m_generator), m_bt(other.m_bt), m_miner_account(other.m_miner_account),
616 m_bob_account(other.m_bob_account), m_alice_account(other.m_alice_account), m_eve_account(other.m_eve_account),
617 m_hard_forks(other.m_hard_forks), m_trezor(other.m_trezor), m_rct_config(other.m_rct_config), m_top_hard_fork(other.m_top_hard_fork),
618 m_heavy_tests(other.m_heavy_tests), m_test_get_tx_key(other.m_test_get_tx_key), m_live_refresh_enabled(other.m_live_refresh_enabled),
619 m_network_type(other.m_network_type), m_daemon(other.m_daemon)
694 auto dev_trezor =
dynamic_cast<::hw::trezor::device_trezor*
>(
m_trezor);
715 std::vector<size_t> block_weights;
717 events.push_back(blk_gen);
718 generator.add_block(blk_gen, 0, block_weights, 0);
727 events.push_back(*ac);
734 std::list<cryptonote::transaction> tx_list;
736 const uint64_t already_generated_coins = generator.get_already_generated_coins(prev_id);
737 block_weights.clear();
739 generator.construct_block(blk_0, 1, prev_id,
m_miner_account,
m_ts_start, already_generated_coins, block_weights, tx_list);
742 events.push_back(blk_0);
776 auto addr_alice_sub_0_1 =
m_wl_alice->get_subaddress({0, 1});
777 auto addr_alice_sub_0_2 =
m_wl_alice->get_subaddress({0, 2});
778 auto addr_alice_sub_0_3 =
m_wl_alice->get_subaddress({0, 3});
779 auto addr_alice_sub_0_4 =
m_wl_alice->get_subaddress({0, 4});
780 auto addr_alice_sub_0_5 =
m_wl_alice->get_subaddress({0, 5});
781 auto addr_alice_sub_1_0 =
m_wl_alice->get_subaddress({1, 0});
782 auto addr_alice_sub_1_1 =
m_wl_alice->get_subaddress({1, 1});
783 auto addr_alice_sub_1_2 =
m_wl_alice->get_subaddress({1, 2});
789 for(
size_t i = 0; i < target_rct; ++i)
801 MAKE_TX_MIX_DEST_LIST_RCT(events, txs_blk_5,
m_miner_account,
build_dsts({{addr_alice_sub_0_1,
true,
MK_COINS(1) >> 1}, {addr_alice_sub_0_2,
true,
MK_COINS(1) >> 1}}), 10, blk_4);
802 MAKE_TX_MIX_DEST_LIST_RCT(events, txs_blk_5,
m_miner_account,
build_dsts({{addr_alice_sub_0_1,
true,
MK_COINS(1) >> 1}, {addr_alice_sub_0_2,
true,
MK_COINS(1) >> 1}, {addr_alice_sub_0_3,
true,
MK_COINS(1) >> 1}}), 10, blk_4);
803 MAKE_TX_MIX_DEST_LIST_RCT(events, txs_blk_5,
m_miner_account,
build_dsts({{
m_miner_account,
false,
MK_COINS(1) >> 1}, {addr_alice_sub_0_2,
true,
MK_COINS(1) >> 1}, {addr_alice_sub_0_3,
true,
MK_COINS(1) >> 1}}), 10, blk_4);
804 MAKE_TX_MIX_DEST_LIST_RCT(events, txs_blk_5,
m_miner_account,
build_dsts({{
m_miner_account,
false,
MK_COINS(1) >> 1}, {addr_alice_sub_0_2,
true,
MK_COINS(1) >> 1}, {addr_alice_sub_0_3,
true,
MK_COINS(1) >> 1}}), 10, blk_4);
809 MAKE_TX_MIX_DEST_LIST_RCT(events, txs_blk_5,
m_miner_account,
build_dsts({{addr_alice_sub_1_0,
true,
MK_COINS(1) >> 1}, {addr_alice_sub_1_1,
true,
MK_COINS(1) >> 1}, {addr_alice_sub_0_3,
true,
MK_COINS(1) >> 1}}), 10, blk_4);
810 MAKE_TX_MIX_DEST_LIST_RCT(events, txs_blk_5,
m_miner_account,
build_dsts({{addr_alice_sub_1_1,
true,
MK_COINS(1) >> 1}, {addr_alice_sub_1_1,
true,
MK_COINS(1) >> 1}, {addr_alice_sub_0_2,
true,
MK_COINS(1) >> 1}}), 10, blk_4);
811 MAKE_TX_MIX_DEST_LIST_RCT(events, txs_blk_5,
m_miner_account,
build_dsts({{addr_alice_sub_1_2,
true,
MK_COINS(1) >> 1}, {addr_alice_sub_1_1,
true,
MK_COINS(1) >> 1}, {addr_alice_sub_0_5,
true,
MK_COINS(1) >> 1}}), 10, blk_4);
834 std::vector<size_t> selected_transfers;
835 std::vector<tx_source_entry> sources;
840 events.push_back(tx_1);
853 MDEBUG(
"Available funds on Alice: " << get_available_funds(
m_wl_alice.get()));
854 MDEBUG(
"Available funds on Bob: " << get_available_funds(
m_wl_bob.get()));
866 unsigned acc_idx = 0;
868 unsigned accounts_num = (
sizeof(accounts) /
sizeof(accounts[0]));
870 for(
auto & ev : events)
874 m_head = boost::get<cryptonote::block>(ev);
878 const auto & acc = boost::get<cryptonote::account_base>(ev);
879 if (acc_idx < accounts_num)
881 *accounts[acc_idx++] = acc;
886 const auto & rep_settings = boost::get<event_replay_settings>(ev);
887 if (rep_settings.hard_forks)
889 const auto & hf = rep_settings.hard_forks.get();
913 MDEBUG(
"Available funds on Alice: " << get_available_funds(
m_wl_alice.get()));
914 MDEBUG(
"Available funds on Bob: " << get_available_funds(
m_wl_bob.get()));
923 MDEBUG(
"Blocks rewound: " << rewind_n <<
", #blocks: " <<
num_blocks(events) <<
", #events: " << events.size());
936 throw std::runtime_error(
"Generated chain hardfork is higher than desired maximum");
941 throw std::runtime_error(
"Desired maximum is too low for BPv2");
949 MDEBUG(
"Hardfork added at height: " << hardfork_height <<
", from " << (
int)current_hf <<
" to " << (
int)
m_top_hard_fork);
985 std::vector<test_event_entry>& events,
987 const std::vector<cryptonote::transaction> &txs)
995 std::list<cryptonote::transaction> tx_list;
996 for(
const auto & tx : txs)
998 events.push_back(tx);
999 tx_list.push_back(tx);
1008 void gen_trezor_base::test_trezor_tx(std::vector<test_event_entry>& events, std::vector<tools::wallet2::pending_tx>& ptxs, std::vector<cryptonote::address_parse_info>& dsts_info,
test_generator &generator, std::vector<tools::wallet2*> wallets,
bool is_sweep)
1016 std::vector<cryptonote::transaction> tx_list;
1018 for(
auto &ptx : ptxs) {
1019 txs.
txes.push_back(get_construction_data_with_decrypted_short_payment_id(ptx, *
m_trezor));
1032 dev_cold->tx_sign(&
wallet_shim, txs, exported_txs, aux_data);
1034 MDEBUG(
"Signed tx data from hw: " << exported_txs.
ptx.size() <<
" transactions");
1037 for (
size_t i = 0; i < exported_txs.
ptx.size(); ++i){
1038 auto &c_ptx = exported_txs.
ptx[i];
1039 c_ptx.tx.rct_signatures.mixRing = ptxs[i].tx.rct_signatures.mixRing;
1040 expand_tsx(c_ptx.tx);
1049 tx_list.push_back(c_ptx.tx);
1059 for(
size_t txid = 0; txid < exported_txs.
ptx.size(); ++txid) {
1060 auto &c_ptx = exported_txs.
ptx[txid];
1061 auto &c_tx = c_ptx.tx;
1063 const size_t num_outs = c_tx.vout.size();
1064 size_t num_received = 0;
1068 std::unordered_set<size_t> recv_out_idx;
1069 std::string exp_payment_id = get_payment_id(c_ptx.construction_data.extra);
1070 std::string enc_payment_id = get_payment_id(c_tx.extra);
1071 size_t num_payment_id_checks_done = 0;
1073 CHECK_AND_ASSERT_THROW_MES(exp_payment_id.empty() || exp_payment_id.size() == 8 || exp_payment_id.size() == 32,
"Required payment ID invalid");
1074 CHECK_AND_ASSERT_THROW_MES((exp_payment_id.size() == 32) == (enc_payment_id.size() == 32),
"Required and built payment ID size mismatch");
1077 for(
auto &src : c_ptx.construction_data.sources){
1078 cur_sum_in += src.amount;
1081 for(
auto &dst : c_ptx.construction_data.splitted_dsts){
1082 cur_sum_out += dst.amount;
1087 for (
size_t widx = 0; widx < wallets.size(); ++widx) {
1088 const bool sender = widx == 0;
1098 return item.m_txid == txhash;
1102 num_received += m_trans_txid.size();
1103 for (
auto & ctran : m_trans_txid){
1104 cur_sum_out_recv += ctran.amount();
1105 recv_out_idx.insert(ctran.m_internal_output_index);
1112 std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>> confirmed_transfers;
1113 std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>> confirmed_transfers_txid;
1116 std::copy_if(confirmed_transfers.begin(), confirmed_transfers.end(), std::back_inserter(confirmed_transfers_txid), [&txhash](
const std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>& item) {
1117 return item.first == txhash;
1120 CHECK_AND_ASSERT_THROW_MES(confirmed_transfers_txid.size() == 1,
"Sender does not have outgoing transfer for the transaction");
1124 std::list<std::pair<crypto::hash, tools::wallet2::payment_details>> payments;
1125 std::list<std::pair<crypto::hash, tools::wallet2::payment_details>> payments_txid;
1128 std::copy_if(payments.begin(), payments.end(), std::back_inserter(payments_txid), [&txhash](
const std::pair<crypto::hash, tools::wallet2::payment_details>& item) {
1129 return item.second.m_tx_hash == txhash;
1132 for(
auto &paydet : payments_txid){
1133 CHECK_AND_ASSERT_THROW_MES(exp_payment_id.empty() || (memcmp(exp_payment_id.data(), paydet.first.data, exp_payment_id.size()) == 0),
"Payment ID mismatch");
1134 num_payment_id_checks_done += 1;
1149 sum_in += cur_sum_in;
1150 sum_out += cur_sum_out + c_tx.rct_signatures.txnFee;
1163 if (tx_pub == tx_pub_c)
1166 for(
const auto & elem : subs)
1168 tx_pub_c = rct::rct2pk(
rct::scalarmultKey(rct::pk2rct(elem.first), rct::sk2rct(tx_priv)));
1169 if (tx_pub == tx_pub_c)
1176 std::vector<test_event_entry>& events,
1177 std::vector<tools::wallet2*> wallets,
1178 const std::vector<tools::wallet2::pending_tx> &ptxs,
1179 const std::vector<std::string> &aux_tx_info)
1189 if (!dev_cold->is_get_tx_key_supported())
1191 MERROR(
"Get TX key is not supported by the connected Trezor");
1198 wlt->expand_subaddresses({10, 20});
1201 all_subs.insert(cur_sub.begin(), cur_sub.end());
1204 for(
size_t txid = 0; txid < ptxs.size(); ++txid)
1206 const auto &c_ptx = ptxs[txid];
1207 const auto &c_tx = c_ptx.tx;
1214 std::vector<::crypto::secret_key> tx_keys;
1216 dev_cold->load_tx_key_data(tx_key_data, aux_tx_info[txid]);
1224 for(
size_t i = 0; i < additional_pub_keys.size(); ++i)
1237 daemon()->mine_blocks(1, miner_address);
1247 std::vector<cryptonote::transaction> txs_found;
1248 std::vector<crypto::hash> txs_missed;
1254 events.push_back(txs_found[0]);
1255 events.push_back(top_block);
1262 throw std::runtime_error(
"Minimal supported Hardfork is 9");
1263 }
else if (hf == 9){
1270 #define TREZOR_TEST_PREFIX() \ 1271 test_generator generator(m_generator); \ 1272 test_setup(events); \ 1273 tsx_builder t_builder_o(this); \ 1274 tsx_builder * t_builder = &t_builder_o 1276 #define TREZOR_TEST_SUFFIX() \ 1277 auto _dsts = t_builder->build(); \ 1278 auto _dsts_info = t_builder->dest_info(); \ 1279 test_trezor_tx(events, _dsts, _dsts_info, generator, vct_wallets(m_wl_alice.get(), m_wl_bob.get(), m_wl_eve.get())); \ 1282 #define TREZOR_SKIP_IF_VERSION_LEQ(x) if (m_trezor->get_version() <= x) { MDEBUG("Test skipped"); return true; } 1283 #define TREZOR_TEST_PAYMENT_ID "\xde\xad\xc0\xde\xde\xad\xc0\xde" 1284 #define TREZOR_TEST_PAYMENT_ID_LONG "\xde\xad\xc0\xde\xde\xad\xc0\xde\xde\xad\xc0\xde\xde\xad\xc0\xde\xde\xad\xc0\xde\xde\xad\xc0\xde\xde\xad\xc0\xde\xde\xad\xc0\xde" 1299 boost::optional<fnc_accept_tx_source_t> fnc_accept_to_use = boost::none;
1303 if (
info.td->m_subaddr_index.major != c_account){
1307 return (fnc_accept.get())(
info, abort);
1312 fnc_accept_to_use = fnc_acc;
1313 bool res =
wallet_tools::fill_tx_sources(
m_from,
m_sources,
m_mixin, num_utxo, min_amount,
m_tester->
m_bt,
m_selected_transfers,
m_cur_height, offset, step, fnc_accept_to_use);
1321 if (
info.td->m_subaddr_index.minor == 0){
1325 return (fnc_accept.get())(
info, abort);
1336 if (
info.td->m_subaddr_index.minor == 0 ||
info.src->real_out_additional_tx_keys.size() == 0){
1340 return (fnc_accept.get())(
info, abort);
1403 auto & ptx =
m_ptxs.back();
1405 std::vector<uint8_t> extra = build_payment_id_extra(
m_payment_id);
1417 info.has_payment_id =
true;
1434 std::vector<crypto::secret_key> additional_tx_keys;
1435 std::vector<tx_destination_entry> destinations_copy =
m_destinations;
1439 change_addr, extra ? extra.get() : std::vector<uint8_t>(), tx, 0, tx_key,
1487 this->set_callback(
nullptr);
1488 this->set_debug(
true);
1492 this->set_derivation_path(
"");
1496 this->wipe_device();
1497 this->load_device(seed);
1504 const ::cryptonote::subaddress_index &received_index,
1507 bool res = device_trezor::compute_key_image(ack, out_key, recv_derivation, real_output_index, received_index,
1515 hw::tx_aux_data &aux_data, std::shared_ptr<hw::trezor::protocol::tx::Signer> &signer) {
1517 device_trezor::tx_sign(wallet, unsigned_tx, idx, aux_data, signer);
1528 std::vector<std::pair<crypto::key_image, crypto::signature>> ski;
1536 for(
size_t i = 0; i < transfers.size(); ++i)
1538 auto & td = transfers[i];
1539 auto & kip = ski[i];
1544 m_wl_alice->import_key_images(ski, 0, spent, unspent,
false);
1549 CHECK_AND_ASSERT_THROW_MES(dev_trezor_test->m_compute_key_image_ctr == 0,
"Live refresh should not happen: " << dev_trezor_test->m_compute_key_image_ctr);
1576 if (!dev_cold->is_live_refresh_supported()){
1577 MDEBUG(
"Trezor does not support live refresh");
1583 dev_cold->live_refresh_start();
1584 for(
unsigned i=0; i<50; ++i)
1603 scalar_step2 = scalar_step1;
1608 sw_device.
sc_secret_add(scalar_step2, scalar_step1, subaddr_sk);
1612 ::crypto::generate_key_image(pub_ver, scalar_step2, ki);
1617 dev_cold->live_refresh(
1630 dev_cold->live_refresh_finish();
1637 t_builder->cur_height(
num_blocks(events) - 1)
1641 ->compute_sources(boost::none,
MK_COINS(1), -1, -1)
1653 t_builder->cur_height(
num_blocks(events) - 1)
1657 ->compute_sources(boost::none,
MK_COINS(1), -1, -1)
1670 t_builder->cur_height(
num_blocks(events) - 1)
1674 ->compute_sources(boost::none,
MK_COINS(1), -1, -1)
1687 t_builder->cur_height(
num_blocks(events) - 1)
1691 ->compute_sources(boost::none,
MK_COINS(1), -1, -1)
1703 t_builder->cur_height(
num_blocks(events) - 1)
1707 ->compute_sources(4,
MK_COINS(1), -1, -1)
1718 t_builder->cur_height(
num_blocks(events) - 1)
1722 ->compute_sources(4,
MK_COINS(1), -1, -1)
1723 ->add_destination(
m_wl_eve->get_subaddress({0, 1}),
true, 1000)
1733 t_builder->cur_height(
num_blocks(events) - 1)
1737 ->compute_sources(4,
MK_COINS(1), -1, -1)
1738 ->add_destination(
m_wl_eve->get_subaddress({0, 1}),
true, 1000)
1748 t_builder->cur_height(
num_blocks(events) - 1)
1752 ->compute_sources(4,
MK_COINS(1), -1, -1)
1753 ->add_destination(
m_wl_eve->get_subaddress({0, 1}),
true, 1000)
1754 ->add_destination(
m_wl_eve->get_subaddress({1, 3}),
true, 1000)
1764 t_builder->cur_height(
num_blocks(events) - 1)
1768 ->compute_sources(4,
MK_COINS(1), -1, -1)
1769 ->add_destination(
m_wl_eve->get_subaddress({1, 1}),
true, 1000)
1770 ->add_destination(
m_wl_eve->get_subaddress({2, 1}),
true, 1000)
1771 ->add_destination(
m_wl_eve.get(),
false, 1000)
1781 t_builder->cur_height(
num_blocks(events) - 1)
1785 ->compute_sources_to_sub_acc(2,
MK_COINS(1) >> 2, -1, -1)
1786 ->add_destination(
m_wl_eve->get_subaddress({1, 1}),
true, 1000)
1787 ->add_destination(
m_wl_eve->get_subaddress({2, 1}),
true, 1000)
1788 ->add_destination(
m_wl_eve.get(),
false, 1000)
1798 t_builder->cur_height(
num_blocks(events) - 1)
1802 ->compute_sources(4,
MK_COINS(1), -1, -1)
1803 ->add_destination(
m_wl_eve->get_subaddress({1, 1}),
true, 1000)
1804 ->add_destination(
m_wl_eve->get_subaddress({2, 1}),
true, 1000)
1805 ->add_destination(
m_wl_eve->get_subaddress({0, 1}),
true, 1000)
1806 ->add_destination(
m_wl_eve->get_subaddress({0, 2}),
true, 1000)
1807 ->add_destination(
m_wl_eve->get_subaddress({0, 3}),
true, 1000)
1808 ->add_destination(
m_wl_eve->get_subaddress({0, 4}),
true, 1000)
1809 ->add_destination(
m_wl_eve.get(),
false, 1000)
1819 t_builder->cur_height(
num_blocks(events) - 1)
1823 ->compute_sources(110,
MK_COINS(1), -1, -1)
1848 MERROR(
"Could not remove wallet directory");
1864 MDEBUG(
"Balance: " << balance);
1875 std::set<uint32_t>{});
bool generate(std::vector< test_event_entry > &events) override
const char *const ELECTRONEUM_RELEASE_NAME
bool parse_tx_extra(const std::vector< uint8_t > &tx_extra, std::vector< tx_extra_field > &tx_extra_fields)
bool compute_key_image(const ::cryptonote::account_keys &ack, const ::crypto::public_key &out_key, const ::crypto::key_derivation &recv_derivation, size_t real_output_index, const ::cryptonote::subaddress_index &received_index, ::cryptonote::keypair &in_ephemeral, ::crypto::key_image &ki) override
const config_t & get_config(network_type nettype)
bool generate(std::vector< test_event_entry > &events) override
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
cryptonote::network_type m_network_type
virtual bool verify_tx_key(const ::crypto::secret_key &tx_priv, const ::crypto::public_key &tx_pub, const subaddresses_t &subs)
boost::function< crypto::public_key(const tools::wallet2::transfer_details &td)> get_tx_pub_key_from_received_outs
bool deinit()
performs safe shutdown steps for core and core components
virtual void test_setup(std::vector< test_event_entry > &events)
rct::RCTConfig m_rct_config
bool extract_hard_forks(const std::vector< test_event_entry > &events, v_hardforks_t &hard_forks)
void rct_config(rct::RCTConfig rct_config)
void derive_secret_key(const key_derivation &derivation, std::size_t output_index, const secret_key &base, secret_key &derived_key)
std::string get_account_address_as_str(network_type nettype, bool subaddress, account_public_address const &adr)
bool init(const boost::program_options::variables_map &vm, const test_options *test_options=NULL, const GetCheckpointsCallback &get_checkpoints=nullptr)
initializes the core as needed
bool generate(std::vector< test_event_entry > &events) override
std::vector< cryptonote::tx_source_entry > m_sources
Information representing errors in application but application will keep running. ...
virtual bool sc_secret_add(crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b)=0
boost::optional< v_hardforks_t > hard_forks
tsx_builder * compute_sources_to_sub_acc(boost::optional< size_t > num_utxo=boost::none, boost::optional< uint64_t > min_amount=boost::none, ssize_t offset=-1, int step=1, boost::optional< fnc_accept_tx_source_t > fnc_accept=boost::none)
virtual bool closeWallet(Wallet *wallet, bool store=true)=0
Closes wallet. In case operation succeeded, wallet object deleted. in case operation failed...
bool generate(std::vector< test_event_entry > &events) override
virtual void add_shared_events(std::vector< test_event_entry > &events)
std::vector< size_t > m_selected_transfers
static subaddresses_t & get_subaddresses(tools::wallet2 *wallet)
virtual void test_trezor_tx(std::vector< test_event_entry > &events, std::vector< tools::wallet2::pending_tx > &ptxs, std::vector< cryptonote::address_parse_info > &dsts_info, test_generator &generator, std::vector< tools::wallet2 *> wallets, bool is_sweep=false)
static void set_account(tools::wallet2 *wallet, cryptonote::account_base &account)
void scalarmultKey(key &aP, const key &P, const key &a)
void create_from_device(const std::string &device_name)
static const uint64_t m_wallet_ts
#define ADD_HARDFORK(HARDFORKS, FORK, HEIGHT)
static void init_options(boost::program_options::options_description &option_spec)
std::vector< std::string > tx_device_aux
bool m_live_refresh_enabled
#define MAKE_NEXT_BLOCK_TX_LIST_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TXLIST, HF)
std::string mlog_get_default_log_path(const char *default_filename)
std::unordered_map< crypto::public_key, cryptonote::subaddress_index > subaddresses_t
tsx_builder * sources(std::vector< cryptonote::tx_source_entry > &sources, std::vector< size_t > &selected_transfers)
bool generate(std::vector< test_event_entry > &events) override
void mlog_configure(const std::string &filename_base, bool console, const std::size_t max_log_file_size=MAX_LOG_FILE_SIZE, const std::size_t max_log_files=MAX_LOG_FILES)
std::vector< cryptonote::tx_destination_entry > build_dsts(const var_addr_t &to1, bool sub1, uint64_t am1)
boost::filesystem::path m_wallet_dir
uint64_t sum_amount(const std::vector< tx_destination_entry > &destinations)
uint64_t num_blocks(const std::vector< test_event_entry > &events)
std::unordered_set< size_t > m_integrated
cryptonote::account_base m_alice_account
#define REWIND_BLOCKS_N(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT)
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
#define TREZOR_TEST_SUFFIX()
gen_trezor_base * m_tester
bool register_device(const std::string &device_name, device *hw_device)
bool find_tx_extra_field_by_type(const std::vector< tx_extra_field > &tx_extra_fields, T &field, size_t index=0)
tsx_builder * compute_sources_to_sub(boost::optional< size_t > num_utxo=boost::none, boost::optional< uint64_t > min_amount=boost::none, ssize_t offset=-1, int step=1, boost::optional< fnc_accept_tx_source_t > fnc_accept=boost::none)
const arg_descriptor< bool > arg_help
#define TESTS_DEFAULT_FEE
bool generate(std::vector< test_event_entry > &events) override
boost::variant< cryptonote::account_public_address, cryptonote::account_keys, cryptonote::account_base, cryptonote::tx_destination_entry > var_addr_t
virtual void setup_args(const std::string &trezor_path, bool heavy_tests=false)
bool generate(std::vector< test_event_entry > &events) override
boost::variant< cryptonote::block, cryptonote::transaction, std::vector< cryptonote::transaction >, cryptonote::account_base, callback_entry, serialized_block, serialized_transaction, event_visitor_settings, event_replay_settings > test_event_entry
crypto::secret_key generate(const crypto::secret_key &recovery_key=crypto::secret_key(), bool recover=false, bool two_random=false)
Level
Represents enumeration for severity level used to determine level of logging.
#define MAKE_TX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD)
cryptonote::tx_destination_entry build_dst(const var_addr_t &to, bool is_subaddr, uint64_t amount)
cryptonote::block head_block() const
#define REWIND_BLOCKS_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, HF)
virtual void set_batch_transactions(bool)=0
sets whether or not to batch transactions
void copy(key &AA, const key &A)
static const std::string m_alice_view_private
virtual void test_get_tx(std::vector< test_event_entry > &events, std::vector< tools::wallet2 *> wallets, const std::vector< tools::wallet2::pending_tx > &ptxs, const std::vector< std::string > &aux_tx_info)
WalletManager - provides functions to manage wallets.
std::string m_trezor_path
std::vector< uint8_t > extra
bool generate(std::vector< test_event_entry > &events) override
std::vector< cryptonote::tx_destination_entry > m_destinations
void random32_unbiased(unsigned char *bytes)
tools::wallet2::unsigned_tx_set unsigned_tx_set
#define TREZOR_TEST_PREFIX()
int main(int argc, char *argv[])
const account_keys & get_keys() const
virtual ~wallet_api_tests()
bool generate(std::vector< test_event_entry > &events) override
#define TREZOR_ACCOUNT_ORDERING
Holds cryptonote related classes and helpers.
cryptonote::account_base m_miner_account
bool generate(std::vector< test_event_entry > &events) override
void tx_sign(hw::wallet_shim *wallet, const ::tools::wallet2::unsigned_tx_set &unsigned_tx, size_t idx, hw::tx_aux_data &aux_data, std::shared_ptr< hw::trezor::protocol::tx::Signer > &signer) override
std::vector< cryptonote::tx_destination_entry > m_destinations_orig
const char *const ELECTRONEUM_VERSION_FULL
std::vector< txin_v > vin
bool flush_txes_from_pool(const std::vector< crypto::hash > &txids)
remove transactions from the transaction pool (if present)
std::unique_ptr< tools::wallet2 > m_wl_bob
bool construct_tx_to_key(const std::vector< test_event_entry > &events, cryptonote::transaction &tx, const cryptonote::block &blk_head, const cryptonote::account_base &from, const var_addr_t &to, uint64_t amount, uint64_t fee, size_t nmix, bool rct, rct::RangeProofType range_proof_type, int bp_version)
virtual void fork(gen_trezor_base &other)
tsx_builder * construct_pending_tx(tools::wallet2::pending_tx &ptx, boost::optional< std::vector< uint8_t >> extra=boost::none)
bool generate_genesis_block(block &bl, std::string const &genesis_tx, uint32_t nonce)
virtual void update_trackers(std::vector< test_event_entry > &events)
void setup_for_tests(const std::string &trezor_path, const std::string &seed, cryptonote::network_type network_type)
bool handle_error_helper(const boost::program_options::options_description &desc, F parser)
static WalletManager * getWalletManager()
virtual Wallet * createWalletFromDevice(const std::string &path, const std::string &password, NetworkType nettype, const std::string &deviceName, uint64_t restoreHeight=0, const std::string &subaddressLookahead="", uint64_t kdf_rounds=1, WalletListener *listener=nullptr)=0
creates wallet using hardware device.
struct hw::wallet_shim wallet_shim
rct::rctSig rct_signatures
virtual void init_fields()
bool get_block_hash(const block &b, crypto::hash &res)
bool generate(std::vector< test_event_entry > &events) override
#define TREZOR_TEST_MIXIN
void get_blockchain_top(uint64_t &height, crypto::hash &top_id) const
get the hash and height of the most recent block
void fill_tx_destinations(const var_addr_t &from, const std::vector< tx_destination_entry > &dests, uint64_t fee, const std::vector< tx_source_entry > &sources, std::vector< tx_destination_entry > &destinations, bool always_change)
v_hardforks_t m_hard_forks
bool generate(std::vector< test_event_entry > &events) override
device & get_device(const std::string &device_descriptor)
std::string const GENESIS_TX
bool generate(std::vector< test_event_entry > &events) override
bool get_short_payment_id(crypto::hash8 &payment_id8, const tools::wallet2::pending_tx &ptx, hw::device &hwdev)
virtual void add_transactions_to_events(std::vector< test_event_entry > &events, test_generator &generator, const std::vector< cryptonote::transaction > &txs)
static const std::string m_alice_spend_private
#define CATCH_REPLAY(genclass)
handles core cryptonote functionality
virtual void fix_hf(std::vector< test_event_entry > &events)
std::string obj_to_json_str(T &obj)
#define TREZOR_SKIP_IF_VERSION_LEQ(x)
unsigned __int64 uint64_t
bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key)
std::string dump_data(const cryptonote::transaction &tx)
bool get_payment_id_from_tx_extra_nonce(const blobdata &extra_nonce, crypto::hash &payment_id)
crypto::public_key get_tx_pub_key_from_extra(const std::vector< uint8_t > &tx_extra, size_t pk_index)
std::string tx_prefix_hash
bool generate(std::vector< test_event_entry > &events) override
rct::RCTConfig m_rct_config
static const std::string m_device_name
#define TREZOR_TEST_PAYMENT_ID_LONG
Transaction-like interface for sending etn.
void set_createtime(uint64_t val)
crypto::hash head_hash() const
#define MAKE_TX_LIST_START(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD)
static const std::string m_device_seed
cryptonote::account_public_address get_address(const var_addr_t &inp)
void do_serialize(boost::mpl::false_, Archive &a, epee::net_utils::network_address &na)
bool get_encrypted_payment_id_from_tx_extra_nonce(const blobdata &extra_nonce, crypto::hash8 &payment_id)
void add_arg(boost::program_options::options_description &description, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg, bool unique=true)
const BlockchainDB & get_db() const
get a reference to the BlockchainDB in use by Blockchain
bool get_transactions(const t_ids_container &txs_ids, t_tx_container &txs, t_missed_container &missed_txs) const
hw::trezor::device_trezor * m_trezor
crypto::secret_key m_view_secret_key
uint64_t pack_version(uint32_t major, uint32_t minor, uint32_t patch)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
size_t m_compute_key_image_ctr
std::vector< tools::wallet2::pending_tx > build()
crypto::hash get_block_id_by_height(uint64_t height) const
gets a block's hash given a height
#define CRYPTONOTE_REWARD_BLOCKS_WINDOW
static const std::string m_master_seed_str
virtual void rewind_blocks(std::vector< test_event_entry > &events, size_t rewind_n, uint8_t hf)
account_public_address m_account_address
#define TREZOR_COMMON_TEST_CASE(genclass, CORE, BASE)
Mainly useful to represent current progress of application.
void get_transaction_prefix_hash(const transaction_prefix &tx, crypto::hash &h)
Blockchain & get_blockchain_storage()
gets the Blockchain instance
virtual bool generate(std::vector< test_event_entry > &events)
#define REWIND_BLOCKS(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC)
std::unique_ptr< tools::wallet2 > m_wl_eve
std::vector< test_event_entry > m_events
std::shared_ptr< mock_daemon > m_daemon
cryptonote::account_base m_bob_account
test_generator m_generator
std::shared_ptr< mock_daemon > daemon() const
std::vector< cryptonote::address_parse_info > m_dsts_info
#define TREZOR_TEST_PAYMENT_ID
#define THROW_WALLET_EXCEPTION_IF(cond, err_type,...)
void * memcpy(void *a, const void *b, size_t c)
static void default_options(boost::program_options::variables_map &vm)
crypto::secret_key m_spend_secret_key
bool generate(std::vector< test_event_entry > &events) override
#define DEFAULT_HARDFORKS(HARDFORKS)
crypto::hash get_transaction_hash(const transaction &t)
bool remove_field_from_tx_extra(std::vector< uint8_t > &tx_extra, const std::type_info &type)
T get_arg(const boost::program_options::variables_map &vm, const arg_descriptor< T, false, true > &arg)
bool add_extra_nonce_to_tx_extra(std::vector< uint8_t > &tx_extra, const blobdata &extra_nonce)
boost::program_options::basic_parsed_options< charT > parse_command_line(int argc, const charT *const argv[], const boost::program_options::options_description &desc, bool allow_unregistered=false)
#define MAKE_TX_MIX_DEST_LIST_RCT(VEC_EVENTS, SET_NAME, FROM, TO, NMIX, HEAD)
bool verRctNonSemanticsSimple(const rctSig &rv)
uint32_t const GENESIS_NONCE
const cryptonote::test_options test_options
virtual void setup_trezor()
std::vector< tools::wallet2::pending_tx > m_ptxs
virtual crypto::secret_key get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index)=0
#define TREZOR_SETUP_CHAIN(NAME)
bool generate(std::vector< test_event_entry > &events) override
crypto::hash get_block_hash(uint64_t height)
boost::optional< int > bp_version
virtual void update_client_settings()
bool get_block_by_hash(const crypto::hash &h, block &blk, bool *orphan=NULL) const
gets the block with a given hash
std::vector< cryptonote::address_parse_info > tx_recipients
bool secret_key_to_public_key(const secret_key &sec, public_key &pub)
std::string to_string(t_connection_type type)
void set_payment_id_to_tx_extra_nonce(blobdata &extra_nonce, const crypto::hash &payment_id)
std::vector< crypto::public_key > get_additional_tx_pub_keys_from_extra(const std::vector< uint8_t > &tx_extra)
bool generate(std::vector< test_event_entry > &events) override
void clear_test_counters()
static const uint64_t m_ts_start
tsx_builder * destinations(std::vector< cryptonote::tx_destination_entry > &dsts)
cryptonote::account_base m_eve_account
cryptonote::block get_head_block(const std::vector< test_event_entry > &events)
#define MAKE_TX_LIST_START_RCT(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD)
const std::pair< uint8_t, uint64_t > * hard_forks
void get(std::istream &input, bool &res)
bool construct_tx_and_get_tx_key(const account_keys &sender_account_keys, const std::unordered_map< crypto::public_key, subaddress_index > &subaddresses, std::vector< tx_source_entry > &sources, std::vector< tx_destination_entry > &destinations, const boost::optional< cryptonote::account_public_address > &change_addr, const std::vector< uint8_t > &extra, transaction &tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector< crypto::secret_key > &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, rct::multisig_out *msout, const uint32_t account_major_offset, const cryptonote::network_type nettype)
static tools::wallet2::transfer_container & get_transfers(tools::wallet2 *wallet)
tsx_builder * compute_sources(boost::optional< size_t > num_utxo=boost::none, boost::optional< uint64_t > min_amount=boost::none, ssize_t offset=-1, int step=1, boost::optional< fnc_accept_tx_source_t > fnc_accept=boost::none)
#define MAKE_TX_MIX_LIST_RCT(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD)
#define CATCH_ENTRY_L0(lacation, return_val)
tsx_builder * add_destination(const cryptonote::tx_destination_entry &dst)
void mlog_set_log_level(int level)
#define MAKE_NEXT_BLOCK_TX_LIST(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TXLIST)
std::unique_ptr< tools::wallet2 > m_wl_alice
virtual void load(std::vector< test_event_entry > &events)
tsx_builder * set_integrated(size_t idx)
bool verRctSemanticsSimple(const std::vector< const rctSig *> &rvv)
uint64_t get_block_height(const block &b)
virtual void set_hard_fork(uint8_t hf)
std::vector< std::pair< uint8_t, uint64_t > > v_hardforks_t
tsx_builder * clear_current()
#define MAKE_NEXT_BLOCK_TX1_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TX1, HF)
virtual void mine_and_test(std::vector< test_event_entry > &events)
cryptonote::network_type nettype() const
#define REWIND_BLOCKS_N_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT, HF)
bool get_pool_transaction_hashes(std::vector< crypto::hash > &txs, bool include_unrelayed_txes=true) const
get a list of all transactions in the pool