aboutsummaryrefslogtreecommitdiff
path: root/tests/unit_tests/serialization.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit_tests/serialization.cpp')
-rw-r--r--tests/unit_tests/serialization.cpp555
1 files changed, 542 insertions, 13 deletions
diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp
index f51f9ec67..6f9fe7d11 100644
--- a/tests/unit_tests/serialization.cpp
+++ b/tests/unit_tests/serialization.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2016, The Monero Project
+// Copyright (c) 2014-2017, The Monero Project
//
// All rights reserved.
//
@@ -34,8 +34,9 @@
#include <iostream>
#include <vector>
#include <boost/foreach.hpp>
-#include "cryptonote_core/cryptonote_basic.h"
-#include "cryptonote_core/cryptonote_basic_impl.h"
+#include <boost/archive/portable_binary_iarchive.hpp>
+#include "cryptonote_basic/cryptonote_basic.h"
+#include "cryptonote_basic/cryptonote_basic_impl.h"
#include "ringct/rctSigs.h"
#include "serialization/serialization.h"
#include "serialization/binary_archive.h"
@@ -44,6 +45,7 @@
#include "serialization/variant.h"
#include "serialization/vector.h"
#include "serialization/binary_utils.h"
+#include "wallet/wallet2.h"
#include "gtest/gtest.h"
using namespace std;
@@ -329,6 +331,7 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
// Miner tx with empty signatures 2nd vector
tx.signatures.resize(1);
+ tx.invalidate_hashes();
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(7, blob.size()); // 5 bytes + 2 bytes vin[0] + 0 bytes extra + 0 bytes signatures
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
@@ -343,16 +346,19 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
tx.signatures.resize(2);
tx.signatures[0].resize(0);
tx.signatures[1].resize(0);
+ tx.invalidate_hashes();
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Miner tx with 2 signatures
tx.signatures[0].resize(1);
tx.signatures[1].resize(1);
+ tx.invalidate_hashes();
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Two txin_gen, no signatures
tx.vin.push_back(txin_gen1);
tx.signatures.resize(0);
+ tx.invalidate_hashes();
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(9, blob.size()); // 5 bytes + 2 * 2 bytes vins + 0 bytes extra + 0 bytes signatures
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
@@ -361,10 +367,12 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
// Two txin_gen, signatures vector contains only one empty element
tx.signatures.resize(1);
+ tx.invalidate_hashes();
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Two txin_gen, signatures vector contains two empty elements
tx.signatures.resize(2);
+ tx.invalidate_hashes();
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(9, blob.size()); // 5 bytes + 2 * 2 bytes vins + 0 bytes extra + 0 bytes signatures
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
@@ -373,18 +381,21 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
// Two txin_gen, signatures vector contains three empty elements
tx.signatures.resize(3);
+ tx.invalidate_hashes();
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Two txin_gen, signatures vector contains two non empty elements
tx.signatures.resize(2);
tx.signatures[0].resize(1);
tx.signatures[1].resize(1);
+ tx.invalidate_hashes();
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// A few bytes instead of signature
tx.vin.clear();
tx.vin.push_back(txin_gen1);
tx.signatures.clear();
+ tx.invalidate_hashes();
ASSERT_TRUE(serialization::dump_binary(tx, blob));
blob.append(std::string(sizeof(crypto::signature) / 2, 'x'));
ASSERT_FALSE(serialization::parse_binary(blob, tx1));
@@ -395,12 +406,16 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
// Not enough signature vectors for all inputs
txin_to_key txin_to_key1;
- txin_to_key1.key_offsets.resize(2);
+ txin_to_key1.amount = 1;
+ memset(&txin_to_key1.k_image, 0x42, sizeof(crypto::key_image));
+ txin_to_key1.key_offsets.push_back(12);
+ txin_to_key1.key_offsets.push_back(3453);
tx.vin.clear();
tx.vin.push_back(txin_to_key1);
tx.vin.push_back(txin_to_key1);
tx.signatures.resize(1);
tx.signatures[0].resize(2);
+ tx.invalidate_hashes();
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Too much signatures for two inputs
@@ -408,24 +423,28 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
tx.signatures[0].resize(2);
tx.signatures[1].resize(2);
tx.signatures[2].resize(2);
+ tx.invalidate_hashes();
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// First signatures vector contains too little elements
tx.signatures.resize(2);
tx.signatures[0].resize(1);
tx.signatures[1].resize(2);
+ tx.invalidate_hashes();
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// First signatures vector contains too much elements
tx.signatures.resize(2);
tx.signatures[0].resize(3);
tx.signatures[1].resize(2);
+ tx.invalidate_hashes();
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// There are signatures for each input
tx.signatures.resize(2);
tx.signatures[0].resize(2);
tx.signatures[1].resize(2);
+ tx.invalidate_hashes();
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
ASSERT_EQ(tx, tx1);
@@ -454,7 +473,7 @@ TEST(Serialization, serializes_ringct_types)
rct::ctkeyV ctkeyv0, ctkeyv1;
rct::ctkeyM ctkeym0, ctkeym1;
rct::ecdhTuple ecdh0, ecdh1;
- rct::asnlSig asnl0, asnl1;
+ rct::boroSig boro0, boro1;
rct::mgSig mg0, mg1;
rct::rangeSig rg0, rg1;
rct::rctSig s0, s1;
@@ -538,13 +557,13 @@ TEST(Serialization, serializes_ringct_types)
for (size_t n = 0; n < 64; ++n)
{
- asnl0.L1[n] = rct::skGen();
- asnl0.s2[n] = rct::skGen();
+ boro0.s0[n] = rct::skGen();
+ boro0.s1[n] = rct::skGen();
}
- asnl0.s = rct::skGen();
- ASSERT_TRUE(serialization::dump_binary(asnl0, blob));
- ASSERT_TRUE(serialization::parse_binary(blob, asnl1));
- ASSERT_TRUE(!memcmp(&asnl0, &asnl1, sizeof(asnl0)));
+ boro0.ee = rct::skGen();
+ ASSERT_TRUE(serialization::dump_binary(boro0, blob));
+ ASSERT_TRUE(serialization::parse_binary(blob, boro1));
+ ASSERT_TRUE(!memcmp(&boro0, &boro1, sizeof(boro0)));
// create a full rct signature to use its innards
rct::ctkeyV sc, pc;
@@ -559,6 +578,7 @@ TEST(Serialization, serializes_ringct_types)
rct::keyV amount_keys;
//add output 500
amounts.push_back(500);
+ amount_keys.push_back(rct::hash_to_scalar(rct::zero()));
rct::keyV destinations;
rct::key Sk, Pk;
rct::skpkGen(Sk, Pk);
@@ -626,9 +646,11 @@ TEST(Serialization, serializes_ringct_types)
tx0.set_null();
tx0.version = 2;
- cryptonote::txin_to_key txin_to_key1;
+ cryptonote::txin_to_key txin_to_key1{};
+ txin_to_key1.amount = 100;
txin_to_key1.key_offsets.resize(4);
- cryptonote::txin_to_key txin_to_key2;
+ cryptonote::txin_to_key txin_to_key2{};
+ txin_to_key2.amount = 200;
txin_to_key2.key_offsets.resize(4);
tx0.vin.push_back(txin_to_key1);
tx0.vin.push_back(txin_to_key2);
@@ -643,3 +665,510 @@ TEST(Serialization, serializes_ringct_types)
ASSERT_TRUE(serialization::dump_binary(tx1, blob2));
ASSERT_TRUE(blob == blob2);
}
+
+TEST(Serialization, portability_wallet)
+{
+ const bool testnet = true;
+ const bool restricted = false;
+ tools::wallet2 w(testnet, restricted);
+ string wallet_file = epee::string_tools::get_current_module_folder() + "/../../../../tests/data/wallet_9svHk1";
+ string password = "test";
+ bool r = false;
+ try
+ {
+ w.load(wallet_file, password);
+ r = true;
+ }
+ catch (const exception& e)
+ {}
+ ASSERT_TRUE(r);
+ /*
+ fields of tools::wallet2 to be checked:
+ std::vector<crypto::hash> m_blockchain
+ std::vector<transfer_details> m_transfers // TODO
+ cryptonote::account_public_address m_account_public_address
+ std::unordered_map<crypto::key_image, size_t> m_key_images
+ std::unordered_map<crypto::hash, unconfirmed_transfer_details> m_unconfirmed_txs
+ std::unordered_multimap<crypto::hash, payment_details> m_payments
+ std::unordered_map<crypto::hash, crypto::secret_key> m_tx_keys
+ std::unordered_map<crypto::hash, confirmed_transfer_details> m_confirmed_txs
+ std::unordered_map<crypto::hash, std::string> m_tx_notes
+ std::unordered_map<crypto::hash, payment_details> m_unconfirmed_payments
+ std::unordered_map<crypto::public_key, size_t> m_pub_keys
+ std::vector<tools::wallet2::address_book_row> m_address_book
+ */
+ // blockchain
+ ASSERT_TRUE(w.m_blockchain.size() == 1);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(w.m_blockchain[0]) == "48ca7cd3c8de5b6a4d53d2861fbdaedca141553559f9be9520068053cda8430b");
+ // transfers (TODO)
+ ASSERT_TRUE(w.m_transfers.size() == 3);
+ // account public address
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(w.m_account_public_address.m_view_public_key) == "e47d4b6df6ab7339539148c2a03ad3e2f3434e5ab2046848e1f21369a3937cad");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(w.m_account_public_address.m_spend_public_key) == "13daa2af00ad26a372d317195de0bdd716f7a05d33bc4d7aff1664b6ee93c060");
+ // key images
+ ASSERT_TRUE(w.m_key_images.size() == 3);
+ {
+ crypto::key_image ki[3];
+ epee::string_tools::hex_to_pod("c5680d3735b90871ca5e3d90cd82d6483eed1151b9ab75c2c8c3a7d89e00a5a8", ki[0]);
+ epee::string_tools::hex_to_pod("d54cbd435a8d636ad9b01b8d4f3eb13bd0cf1ce98eddf53ab1617f9b763e66c0", ki[1]);
+ epee::string_tools::hex_to_pod("6c3cd6af97c4070a7aef9b1344e7463e29c7cd245076fdb65da447a34da3ca76", ki[2]);
+ ASSERT_TRUE(w.m_key_images.find(ki[0])->second == 0);
+ ASSERT_TRUE(w.m_key_images.find(ki[1])->second == 1);
+ ASSERT_TRUE(w.m_key_images.find(ki[2])->second == 2);
+ }
+ // unconfirmed txs
+ ASSERT_TRUE(w.m_unconfirmed_txs.size() == 0);
+ // payments
+ ASSERT_TRUE(w.m_payments.size() == 2);
+ {
+ auto pd0 = w.m_payments.begin();
+ auto pd1 = pd0;
+ ++pd1;
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(pd0->first) == "0000000000000000000000000000000000000000000000000000000000000000");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(pd1->first) == "0000000000000000000000000000000000000000000000000000000000000000");
+ if (epee::string_tools::pod_to_hex(pd0->second.m_tx_hash) == "ec34c9bb12b99af33d49691384eee5bed9171498ff04e59516505f35d1fc5efc")
+ swap(pd0, pd1);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(pd0->second.m_tx_hash) == "15024343b38e77a1a9860dfed29921fa17e833fec837191a6b04fa7cb9605b8e");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(pd1->second.m_tx_hash) == "ec34c9bb12b99af33d49691384eee5bed9171498ff04e59516505f35d1fc5efc");
+ ASSERT_TRUE(pd0->second.m_amount == 13400845012231);
+ ASSERT_TRUE(pd1->second.m_amount == 1200000000000);
+ ASSERT_TRUE(pd0->second.m_block_height == 818424);
+ ASSERT_TRUE(pd1->second.m_block_height == 818522);
+ ASSERT_TRUE(pd0->second.m_unlock_time == 818484);
+ ASSERT_TRUE(pd1->second.m_unlock_time == 0);
+ ASSERT_TRUE(pd0->second.m_timestamp == 1483263366);
+ ASSERT_TRUE(pd1->second.m_timestamp == 1483272963);
+ }
+ // tx keys
+ ASSERT_TRUE(w.m_tx_keys.size() == 2);
+ {
+ auto tx_key0 = w.m_tx_keys.begin();
+ auto tx_key1 = tx_key0;
+ ++tx_key1;
+ if (epee::string_tools::pod_to_hex(tx_key0->first) == "6e7013684d35820f66c6679197ded9329bfe0e495effa47e7b25258799858dba")
+ swap(tx_key0, tx_key1);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(tx_key0->first) == "b9aac8c020ab33859e0c0b6331f46a8780d349e7ac17b067116e2d87bf48daad");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(tx_key1->first) == "6e7013684d35820f66c6679197ded9329bfe0e495effa47e7b25258799858dba");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(tx_key0->second) == "bf3614c6de1d06c09add5d92a5265d8c76af706f7bc6ac830d6b0d109aa87701");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(tx_key1->second) == "e556884246df5a787def6732c6ea38f1e092fa13e5ea98f732b99c07a6332003");
+ }
+ // confirmed txs
+ ASSERT_TRUE(w.m_confirmed_txs.size() == 1);
+ // tx notes
+ ASSERT_TRUE(w.m_tx_notes.size() == 2);
+ {
+ crypto::hash h[2];
+ epee::string_tools::hex_to_pod("15024343b38e77a1a9860dfed29921fa17e833fec837191a6b04fa7cb9605b8e", h[0]);
+ epee::string_tools::hex_to_pod("6e7013684d35820f66c6679197ded9329bfe0e495effa47e7b25258799858dba", h[1]);
+ ASSERT_TRUE(w.m_tx_notes.find(h[0])->second == "sample note");
+ ASSERT_TRUE(w.m_tx_notes.find(h[1])->second == "sample note 2");
+ }
+ // unconfirmed payments
+ ASSERT_TRUE(w.m_unconfirmed_payments.size() == 0);
+ // pub keys
+ ASSERT_TRUE(w.m_pub_keys.size() == 3);
+ {
+ crypto::public_key pubkey[3];
+ epee::string_tools::hex_to_pod("33f75f264574cb3a9ea5b24220a5312e183d36dc321c9091dfbb720922a4f7b0", pubkey[0]);
+ epee::string_tools::hex_to_pod("5066ff2ce9861b1d131cf16eeaa01264933a49f28242b97b153e922ec7b4b3cb", pubkey[1]);
+ epee::string_tools::hex_to_pod("0d8467e16e73d16510452b78823e082e05ee3a63788d40de577cf31eb555f0c8", pubkey[2]);
+ ASSERT_TRUE(w.m_pub_keys.find(pubkey[0])->second == 0);
+ ASSERT_TRUE(w.m_pub_keys.find(pubkey[1])->second == 1);
+ ASSERT_TRUE(w.m_pub_keys.find(pubkey[2])->second == 2);
+ }
+ // address book
+ ASSERT_TRUE(w.m_address_book.size() == 1);
+ {
+ auto address_book_row = w.m_address_book.begin();
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(address_book_row->m_address.m_spend_public_key) == "9bc53a6ff7b0831c9470f71b6b972dbe5ad1e8606f72682868b1dda64e119fb3");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(address_book_row->m_address.m_view_public_key) == "49fece1ef97dc0c0f7a5e2106e75e96edd910f7e86b56e1e308cd0cf734df191");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(address_book_row->m_payment_id) == "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef");
+ ASSERT_TRUE(address_book_row->m_description == "testnet wallet 9y52S6");
+ }
+}
+
+#define OUTPUT_EXPORT_FILE_MAGIC "Monero output export\003"
+TEST(Serialization, portability_outputs)
+{
+ // read file
+ const std::string filename = epee::string_tools::get_current_module_folder() + "/../../../../tests/data/outputs";
+ std::string data;
+ bool r = epee::file_io_utils::load_file_to_string(filename, data);
+ ASSERT_TRUE(r);
+ const size_t magiclen = strlen(OUTPUT_EXPORT_FILE_MAGIC);
+ ASSERT_FALSE(data.size() < magiclen || memcmp(data.data(), OUTPUT_EXPORT_FILE_MAGIC, magiclen));
+ // decrypt (copied from wallet2::decrypt)
+ auto decrypt = [] (const std::string &ciphertext, const crypto::secret_key &skey, bool authenticated) -> string
+ {
+ const size_t prefix_size = sizeof(chacha8_iv) + (authenticated ? sizeof(crypto::signature) : 0);
+ if(ciphertext.size() < prefix_size)
+ return {};
+ crypto::chacha8_key key;
+ crypto::generate_chacha8_key(&skey, sizeof(skey), key);
+ const crypto::chacha8_iv &iv = *(const crypto::chacha8_iv*)&ciphertext[0];
+ std::string plaintext;
+ plaintext.resize(ciphertext.size() - prefix_size);
+ if (authenticated)
+ {
+ crypto::hash hash;
+ crypto::cn_fast_hash(ciphertext.data(), ciphertext.size() - sizeof(signature), hash);
+ crypto::public_key pkey;
+ crypto::secret_key_to_public_key(skey, pkey);
+ const crypto::signature &signature = *(const crypto::signature*)&ciphertext[ciphertext.size() - sizeof(crypto::signature)];
+ if(!crypto::check_signature(hash, pkey, signature))
+ return {};
+ }
+ crypto::chacha8(ciphertext.data() + sizeof(iv), ciphertext.size() - prefix_size, key, iv, &plaintext[0]);
+ return std::move(plaintext);
+ };
+ crypto::secret_key view_secret_key;
+ epee::string_tools::hex_to_pod("339673bb1187e2f73ba7841ab6841c5553f96e9f13f8fe6612e69318db4e9d0a", view_secret_key);
+ bool authenticated = true;
+ data = decrypt(std::string(data, magiclen), view_secret_key, authenticated);
+ ASSERT_FALSE(data.empty());
+ // check public view/spend keys
+ const size_t headerlen = 2 * sizeof(crypto::public_key);
+ ASSERT_FALSE(data.size() < headerlen);
+ const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[0];
+ const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[sizeof(crypto::public_key)];
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(public_spend_key) == "13daa2af00ad26a372d317195de0bdd716f7a05d33bc4d7aff1664b6ee93c060");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(public_view_key) == "e47d4b6df6ab7339539148c2a03ad3e2f3434e5ab2046848e1f21369a3937cad");
+ r = false;
+ std::vector<tools::wallet2::transfer_details> outputs;
+ try
+ {
+ std::istringstream iss(std::string(data, headerlen));
+ boost::archive::portable_binary_iarchive ar(iss);
+ ar >> outputs;
+ r = true;
+ }
+ catch (...)
+ {}
+ ASSERT_TRUE(r);
+ /*
+ fields of tools::wallet2::transfer_details to be checked:
+ uint64_t m_block_height
+ cryptonote::transaction_prefix m_tx // TODO
+ crypto::hash m_txid
+ size_t m_internal_output_index
+ uint64_t m_global_output_index
+ bool m_spent
+ uint64_t m_spent_height
+ crypto::key_image m_key_image
+ rct::key m_mask
+ uint64_t m_amount
+ bool m_rct
+ bool m_key_image_known
+ size_t m_pk_index
+ */
+ ASSERT_TRUE(outputs.size() == 3);
+ auto& td0 = outputs[0];
+ auto& td1 = outputs[1];
+ auto& td2 = outputs[2];
+ ASSERT_TRUE(td0.m_block_height == 818424);
+ ASSERT_TRUE(td1.m_block_height == 818522);
+ ASSERT_TRUE(td2.m_block_height == 818522);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td0.m_txid) == "15024343b38e77a1a9860dfed29921fa17e833fec837191a6b04fa7cb9605b8e");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td1.m_txid) == "ec34c9bb12b99af33d49691384eee5bed9171498ff04e59516505f35d1fc5efc");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td2.m_txid) == "6e7013684d35820f66c6679197ded9329bfe0e495effa47e7b25258799858dba");
+ ASSERT_TRUE(td0.m_internal_output_index == 0);
+ ASSERT_TRUE(td1.m_internal_output_index == 0);
+ ASSERT_TRUE(td2.m_internal_output_index == 1);
+ ASSERT_TRUE(td0.m_global_output_index == 19642);
+ ASSERT_TRUE(td1.m_global_output_index == 19757);
+ ASSERT_TRUE(td2.m_global_output_index == 19760);
+ ASSERT_TRUE (td0.m_spent);
+ ASSERT_FALSE(td1.m_spent);
+ ASSERT_FALSE(td2.m_spent);
+ ASSERT_TRUE(td0.m_spent_height == 0);
+ ASSERT_TRUE(td1.m_spent_height == 0);
+ ASSERT_TRUE(td2.m_spent_height == 0);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td0.m_key_image) == "c5680d3735b90871ca5e3d90cd82d6483eed1151b9ab75c2c8c3a7d89e00a5a8");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td1.m_key_image) == "d54cbd435a8d636ad9b01b8d4f3eb13bd0cf1ce98eddf53ab1617f9b763e66c0");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td2.m_key_image) == "6c3cd6af97c4070a7aef9b1344e7463e29c7cd245076fdb65da447a34da3ca76");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td0.m_mask) == "0100000000000000000000000000000000000000000000000000000000000000");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td1.m_mask) == "d3997a7b27fa199a377643b88cbd3f20f447496746dabe92d288730ecaeda007");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td2.m_mask) == "789bafff169ef206aa21219342c69ca52ce1d78d776c10b21d14bdd960fc7703");
+ ASSERT_TRUE(td0.m_amount == 13400845012231);
+ ASSERT_TRUE(td1.m_amount == 1200000000000);
+ ASSERT_TRUE(td2.m_amount == 11066009260865);
+ ASSERT_TRUE(td0.m_rct);
+ ASSERT_TRUE(td1.m_rct);
+ ASSERT_TRUE(td2.m_rct);
+ ASSERT_TRUE(td0.m_key_image_known);
+ ASSERT_TRUE(td1.m_key_image_known);
+ ASSERT_TRUE(td2.m_key_image_known);
+ ASSERT_TRUE(td0.m_pk_index == 0);
+ ASSERT_TRUE(td1.m_pk_index == 0);
+ ASSERT_TRUE(td2.m_pk_index == 0);
+}
+
+#define UNSIGNED_TX_PREFIX "Monero unsigned tx set\003"
+TEST(Serialization, portability_unsigned_tx)
+{
+ const string filename = epee::string_tools::get_current_module_folder() + "/../../../../tests/data/unsigned_monero_tx";
+ std::string s;
+ const bool testnet = true;
+ bool r = epee::file_io_utils::load_file_to_string(filename, s);
+ ASSERT_TRUE(r);
+ const size_t magiclen = strlen(UNSIGNED_TX_PREFIX);
+ ASSERT_FALSE(strncmp(s.c_str(), UNSIGNED_TX_PREFIX, magiclen));
+ tools::wallet2::unsigned_tx_set exported_txs;
+ s = s.substr(magiclen);
+ r = false;
+ try
+ {
+ std::istringstream iss(s);
+ boost::archive::portable_binary_iarchive ar(iss);
+ ar >> exported_txs;
+ r = true;
+ }
+ catch (...)
+ {}
+ ASSERT_TRUE(r);
+ /*
+ fields of tools::wallet2::unsigned_tx_set to be checked:
+ std::vector<tx_construction_data> txes
+ std::vector<wallet2::transfer_details> m_transfers
+
+ fields of toolw::wallet2::tx_construction_data to be checked:
+ std::vector<cryptonote::tx_source_entry> sources
+ cryptonote::tx_destination_entry change_dts
+ std::vector<cryptonote::tx_destination_entry> splitted_dsts
+ std::list<size_t> selected_transfers
+ std::vector<uint8_t> extra
+ uint64_t unlock_time
+ bool use_rct
+ std::vector<cryptonote::tx_destination_entry> dests
+
+ fields of cryptonote::tx_source_entry to be checked:
+ std::vector<std::pair<uint64_t, rct::ctkey>> outputs
+ size_t real_output
+ crypto::public_key real_out_tx_key
+ size_t real_output_in_tx_index
+ uint64_t amount
+ bool rct
+ rct::key mask
+
+ fields of cryptonote::tx_destination_entry to be checked:
+ uint64_t amount
+ account_public_address addr
+ */
+ // txes
+ ASSERT_TRUE(exported_txs.txes.size() == 1);
+ auto& tcd = exported_txs.txes[0];
+ // tcd.sources
+ ASSERT_TRUE(tcd.sources.size() == 1);
+ auto& tse = tcd.sources[0];
+ // tcd.sources[0].outputs
+ ASSERT_TRUE(tse.outputs.size() == 5);
+ auto& out0 = tse.outputs[0];
+ auto& out1 = tse.outputs[1];
+ auto& out2 = tse.outputs[2];
+ auto& out3 = tse.outputs[3];
+ auto& out4 = tse.outputs[4];
+ ASSERT_TRUE(out0.first == 6295);
+ ASSERT_TRUE(out1.first == 14302);
+ ASSERT_TRUE(out2.first == 17598);
+ ASSERT_TRUE(out3.first == 18671);
+ ASSERT_TRUE(out4.first == 19760);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(out0.second) == "e7272cb589954ddeedd20de9411ed57265f154d41f33cec9ff69e5d642e09814096490b0ac85308342acf436cc0270d53abef9dc04c6202f2459e879bfd40ce6");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(out1.second) == "c3a9f49d1fe75939cc3feb39871ce0a7366c2879a63faa1a5cf34e65723b120a272ff0c7d84ab8b6ee3528d196450b0e28b3fed276bc2597a2b5b17afb9354ab");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(out2.second) == "176e239c8c39000c2275e2f63ed7d55c55e0843524091522bbd3d3b869044969021fad70fc1244115449d4754829ae7c47346342ee5d52a2cdd47dfc351d0ab0");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(out3.second) == "ef12d7946302fb064f2ba9df1a73d72233ac74664ed3b370580fa3bdc377542ad93f64898bd95851d6efe0d7bf2dbbea9b7c6b3c57e2c807e7b17d55b4622259");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(out4.second) == "0d8467e16e73d16510452b78823e082e05ee3a63788d40de577cf31eb555f0c8525096cbc88d00a841eed66f3cdb6f0a018e6ce9fb9433ed61afba15cbbebd04");
+ // tcd.sources[0].{real_output, real_out_tx_key, real_output_in_tx_index, amount, rct, mask}
+ ASSERT_TRUE(tse.real_output == 4);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(tse.real_out_tx_key) == "4d86c7ba1c285fe4bc1cd7b54ba894fa89fa02fc6b0bbeea67d53251acd14a05");
+ ASSERT_TRUE(tse.real_output_in_tx_index == 1);
+ ASSERT_TRUE(tse.amount == 11066009260865);
+ ASSERT_TRUE(tse.rct);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(tse.mask) == "789bafff169ef206aa21219342c69ca52ce1d78d776c10b21d14bdd960fc7703");
+ // tcd.change_dts
+ ASSERT_TRUE(tcd.change_dts.amount == 9631208773403);
+ ASSERT_TRUE(cryptonote::get_account_address_as_str(testnet, tcd.change_dts.addr) == "9svHk1wHPo3ULf2AZykghzcye6sitaRE4MaDjPC6uanTHCynHjJHZaiAb922PojE1GexhhRt1LVf5DC43feyrRZMLXQr3mk");
+ // tcd.splitted_dsts
+ ASSERT_TRUE(tcd.splitted_dsts.size() == 2);
+ auto& splitted_dst0 = tcd.splitted_dsts[0];
+ auto& splitted_dst1 = tcd.splitted_dsts[1];
+ ASSERT_TRUE(splitted_dst0.amount == 1400000000000);
+ ASSERT_TRUE(splitted_dst1.amount == 9631208773403);
+ ASSERT_TRUE(cryptonote::get_account_address_as_str(testnet, splitted_dst0.addr) == "9xnhrMczQkPeoGi6dyu6BgKAYX4tZsDs6KHCkyTStDBKL4M4pM1gfCR3utmTAcSaKHGa1R5o266FbdnubErmij3oMdLyYgA");
+ ASSERT_TRUE(cryptonote::get_account_address_as_str(testnet, splitted_dst1.addr) == "9svHk1wHPo3ULf2AZykghzcye6sitaRE4MaDjPC6uanTHCynHjJHZaiAb922PojE1GexhhRt1LVf5DC43feyrRZMLXQr3mk");
+ // tcd.selected_transfers
+ ASSERT_TRUE(tcd.selected_transfers.size() == 1);
+ ASSERT_TRUE(tcd.selected_transfers.front() == 2);
+ // tcd.extra
+ ASSERT_TRUE(tcd.extra.size() == 68);
+ // tcd.{unlock_time, use_rct}
+ ASSERT_TRUE(tcd.unlock_time == 0);
+ ASSERT_TRUE(tcd.use_rct);
+ // tcd.dests
+ ASSERT_TRUE(tcd.dests.size() == 1);
+ auto& dest = tcd.dests[0];
+ ASSERT_TRUE(dest.amount == 1400000000000);
+ ASSERT_TRUE(cryptonote::get_account_address_as_str(testnet, dest.addr) == "9xnhrMczQkPeoGi6dyu6BgKAYX4tZsDs6KHCkyTStDBKL4M4pM1gfCR3utmTAcSaKHGa1R5o266FbdnubErmij3oMdLyYgA");
+ // transfers
+ ASSERT_TRUE(exported_txs.transfers.size() == 3);
+ auto& td0 = exported_txs.transfers[0];
+ auto& td1 = exported_txs.transfers[1];
+ auto& td2 = exported_txs.transfers[2];
+ ASSERT_TRUE(td0.m_block_height == 818424);
+ ASSERT_TRUE(td1.m_block_height == 818522);
+ ASSERT_TRUE(td2.m_block_height == 818522);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td0.m_txid) == "15024343b38e77a1a9860dfed29921fa17e833fec837191a6b04fa7cb9605b8e");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td1.m_txid) == "ec34c9bb12b99af33d49691384eee5bed9171498ff04e59516505f35d1fc5efc");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td2.m_txid) == "6e7013684d35820f66c6679197ded9329bfe0e495effa47e7b25258799858dba");
+ ASSERT_TRUE(td0.m_internal_output_index == 0);
+ ASSERT_TRUE(td1.m_internal_output_index == 0);
+ ASSERT_TRUE(td2.m_internal_output_index == 1);
+ ASSERT_TRUE(td0.m_global_output_index == 19642);
+ ASSERT_TRUE(td1.m_global_output_index == 19757);
+ ASSERT_TRUE(td2.m_global_output_index == 19760);
+ ASSERT_TRUE (td0.m_spent);
+ ASSERT_FALSE(td1.m_spent);
+ ASSERT_FALSE(td2.m_spent);
+ ASSERT_TRUE(td0.m_spent_height == 0);
+ ASSERT_TRUE(td1.m_spent_height == 0);
+ ASSERT_TRUE(td2.m_spent_height == 0);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td0.m_key_image) == "c5680d3735b90871ca5e3d90cd82d6483eed1151b9ab75c2c8c3a7d89e00a5a8");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td1.m_key_image) == "d54cbd435a8d636ad9b01b8d4f3eb13bd0cf1ce98eddf53ab1617f9b763e66c0");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td2.m_key_image) == "6c3cd6af97c4070a7aef9b1344e7463e29c7cd245076fdb65da447a34da3ca76");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td0.m_mask) == "0100000000000000000000000000000000000000000000000000000000000000");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td1.m_mask) == "d3997a7b27fa199a377643b88cbd3f20f447496746dabe92d288730ecaeda007");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(td2.m_mask) == "789bafff169ef206aa21219342c69ca52ce1d78d776c10b21d14bdd960fc7703");
+ ASSERT_TRUE(td0.m_amount == 13400845012231);
+ ASSERT_TRUE(td1.m_amount == 1200000000000);
+ ASSERT_TRUE(td2.m_amount == 11066009260865);
+ ASSERT_TRUE(td0.m_rct);
+ ASSERT_TRUE(td1.m_rct);
+ ASSERT_TRUE(td2.m_rct);
+ ASSERT_TRUE(td0.m_key_image_known);
+ ASSERT_TRUE(td1.m_key_image_known);
+ ASSERT_TRUE(td2.m_key_image_known);
+ ASSERT_TRUE(td0.m_pk_index == 0);
+ ASSERT_TRUE(td1.m_pk_index == 0);
+ ASSERT_TRUE(td2.m_pk_index == 0);
+}
+
+#define SIGNED_TX_PREFIX "Monero signed tx set\003"
+TEST(Serialization, portability_signed_tx)
+{
+ const string filename = epee::string_tools::get_current_module_folder() + "/../../../../tests/data/signed_monero_tx";
+ const bool testnet = true;
+ std::string s;
+ bool r = epee::file_io_utils::load_file_to_string(filename, s);
+ ASSERT_TRUE(r);
+ const size_t magiclen = strlen(SIGNED_TX_PREFIX);
+ ASSERT_FALSE(strncmp(s.c_str(), SIGNED_TX_PREFIX, magiclen));
+ tools::wallet2::signed_tx_set exported_txs;
+ s = s.substr(magiclen);
+ r = false;
+ try
+ {
+ std::istringstream iss(s);
+ boost::archive::portable_binary_iarchive ar(iss);
+ ar >> exported_txs;
+ r = true;
+ }
+ catch (...)
+ {}
+ ASSERT_TRUE(r);
+ /*
+ fields of tools::wallet2::signed_tx_set to be checked:
+ std::vector<pending_tx> ptx
+ std::vector<crypto::key_image> key_images
+
+ fields of tools::walllet2::pending_tx to be checked:
+ cryptonote::transaction tx // TODO
+ uint64_t dust
+ uint64_t fee
+ bool dust_added_to_fee
+ cryptonote::tx_destination_entry change_dts
+ std::list<size_t> selected_transfers
+ std::string key_images
+ crypto::secret_key tx_key
+ std::vector<cryptonote::tx_destination_entry> dests
+ tx_construction_data construction_data
+ */
+ // ptx
+ ASSERT_TRUE(exported_txs.ptx.size() == 1);
+ auto& ptx = exported_txs.ptx[0];
+ // ptx.{dust, fee, dust_added_to_fee}
+ ASSERT_TRUE (ptx.dust == 0);
+ ASSERT_TRUE (ptx.fee == 34800487462);
+ ASSERT_FALSE(ptx.dust_added_to_fee);
+ // ptx.change.{amount, addr}
+ ASSERT_TRUE(ptx.change_dts.amount == 9631208773403);
+ ASSERT_TRUE(cryptonote::get_account_address_as_str(testnet, ptx.change_dts.addr) == "9svHk1wHPo3ULf2AZykghzcye6sitaRE4MaDjPC6uanTHCynHjJHZaiAb922PojE1GexhhRt1LVf5DC43feyrRZMLXQr3mk");
+ // ptx.selected_transfers
+ ASSERT_TRUE(ptx.selected_transfers.size() == 1);
+ ASSERT_TRUE(ptx.selected_transfers.front() == 2);
+ // ptx.{key_images, tx_key}
+ ASSERT_TRUE(ptx.key_images == "<6c3cd6af97c4070a7aef9b1344e7463e29c7cd245076fdb65da447a34da3ca76> ");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(ptx.tx_key) == "0100000000000000000000000000000000000000000000000000000000000000");
+ // ptx.dests
+ ASSERT_TRUE(ptx.dests.size() == 1);
+ ASSERT_TRUE(ptx.dests[0].amount == 1400000000000);
+ ASSERT_TRUE(cryptonote::get_account_address_as_str(testnet, ptx.dests[0].addr) == "9xnhrMczQkPeoGi6dyu6BgKAYX4tZsDs6KHCkyTStDBKL4M4pM1gfCR3utmTAcSaKHGa1R5o266FbdnubErmij3oMdLyYgA");
+ // ptx.construction_data
+ auto& tcd = ptx.construction_data;
+ ASSERT_TRUE(tcd.sources.size() == 1);
+ auto& tse = tcd.sources[0];
+ // ptx.construction_data.sources[0].outputs
+ ASSERT_TRUE(tse.outputs.size() == 5);
+ auto& out0 = tse.outputs[0];
+ auto& out1 = tse.outputs[1];
+ auto& out2 = tse.outputs[2];
+ auto& out3 = tse.outputs[3];
+ auto& out4 = tse.outputs[4];
+ ASSERT_TRUE(out0.first == 6295);
+ ASSERT_TRUE(out1.first == 14302);
+ ASSERT_TRUE(out2.first == 17598);
+ ASSERT_TRUE(out3.first == 18671);
+ ASSERT_TRUE(out4.first == 19760);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(out0.second) == "e7272cb589954ddeedd20de9411ed57265f154d41f33cec9ff69e5d642e09814096490b0ac85308342acf436cc0270d53abef9dc04c6202f2459e879bfd40ce6");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(out1.second) == "c3a9f49d1fe75939cc3feb39871ce0a7366c2879a63faa1a5cf34e65723b120a272ff0c7d84ab8b6ee3528d196450b0e28b3fed276bc2597a2b5b17afb9354ab");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(out2.second) == "176e239c8c39000c2275e2f63ed7d55c55e0843524091522bbd3d3b869044969021fad70fc1244115449d4754829ae7c47346342ee5d52a2cdd47dfc351d0ab0");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(out3.second) == "ef12d7946302fb064f2ba9df1a73d72233ac74664ed3b370580fa3bdc377542ad93f64898bd95851d6efe0d7bf2dbbea9b7c6b3c57e2c807e7b17d55b4622259");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(out4.second) == "0d8467e16e73d16510452b78823e082e05ee3a63788d40de577cf31eb555f0c8525096cbc88d00a841eed66f3cdb6f0a018e6ce9fb9433ed61afba15cbbebd04");
+ // ptx.construction_data.sources[0].{real_output, real_out_tx_key, real_output_in_tx_index, amount, rct, mask}
+ ASSERT_TRUE(tse.real_output == 4);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(tse.real_out_tx_key) == "4d86c7ba1c285fe4bc1cd7b54ba894fa89fa02fc6b0bbeea67d53251acd14a05");
+ ASSERT_TRUE(tse.real_output_in_tx_index == 1);
+ ASSERT_TRUE(tse.amount == 11066009260865);
+ ASSERT_TRUE(tse.rct);
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(tse.mask) == "789bafff169ef206aa21219342c69ca52ce1d78d776c10b21d14bdd960fc7703");
+ // ptx.construction_data.change_dts
+ ASSERT_TRUE(tcd.change_dts.amount == 9631208773403);
+ ASSERT_TRUE(cryptonote::get_account_address_as_str(testnet, tcd.change_dts.addr) == "9svHk1wHPo3ULf2AZykghzcye6sitaRE4MaDjPC6uanTHCynHjJHZaiAb922PojE1GexhhRt1LVf5DC43feyrRZMLXQr3mk");
+ // ptx.construction_data.splitted_dsts
+ ASSERT_TRUE(tcd.splitted_dsts.size() == 2);
+ auto& splitted_dst0 = tcd.splitted_dsts[0];
+ auto& splitted_dst1 = tcd.splitted_dsts[1];
+ ASSERT_TRUE(splitted_dst0.amount == 1400000000000);
+ ASSERT_TRUE(splitted_dst1.amount == 9631208773403);
+ ASSERT_TRUE(cryptonote::get_account_address_as_str(testnet, splitted_dst0.addr) == "9xnhrMczQkPeoGi6dyu6BgKAYX4tZsDs6KHCkyTStDBKL4M4pM1gfCR3utmTAcSaKHGa1R5o266FbdnubErmij3oMdLyYgA");
+ ASSERT_TRUE(cryptonote::get_account_address_as_str(testnet, splitted_dst1.addr) == "9svHk1wHPo3ULf2AZykghzcye6sitaRE4MaDjPC6uanTHCynHjJHZaiAb922PojE1GexhhRt1LVf5DC43feyrRZMLXQr3mk");
+ // ptx.construction_data.selected_transfers
+ ASSERT_TRUE(tcd.selected_transfers.size() == 1);
+ ASSERT_TRUE(tcd.selected_transfers.front() == 2);
+ // ptx.construction_data.extra
+ ASSERT_TRUE(tcd.extra.size() == 68);
+ // ptx.construction_data.{unlock_time, use_rct}
+ ASSERT_TRUE(tcd.unlock_time == 0);
+ ASSERT_TRUE(tcd.use_rct);
+ // ptx.construction_data.dests
+ ASSERT_TRUE(tcd.dests.size() == 1);
+ auto& dest = tcd.dests[0];
+ ASSERT_TRUE(dest.amount == 1400000000000);
+ ASSERT_TRUE(cryptonote::get_account_address_as_str(testnet, dest.addr) == "9xnhrMczQkPeoGi6dyu6BgKAYX4tZsDs6KHCkyTStDBKL4M4pM1gfCR3utmTAcSaKHGa1R5o266FbdnubErmij3oMdLyYgA");
+ // key_images
+ ASSERT_TRUE(exported_txs.key_images.size() == 3);
+ auto& ki0 = exported_txs.key_images[0];
+ auto& ki1 = exported_txs.key_images[1];
+ auto& ki2 = exported_txs.key_images[2];
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(ki0) == "c5680d3735b90871ca5e3d90cd82d6483eed1151b9ab75c2c8c3a7d89e00a5a8");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(ki1) == "d54cbd435a8d636ad9b01b8d4f3eb13bd0cf1ce98eddf53ab1617f9b763e66c0");
+ ASSERT_TRUE(epee::string_tools::pod_to_hex(ki2) == "6c3cd6af97c4070a7aef9b1344e7463e29c7cd245076fdb65da447a34da3ca76");
+}