aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/data/fuzz/cold-outputs/out-all-6bin2607 -> 394 bytes
-rwxr-xr-xtests/functional_tests/cold_signing.py116
-rwxr-xr-xtests/functional_tests/functional_tests_rpc.py6
-rw-r--r--tests/fuzz/cold-outputs.cpp2
4 files changed, 104 insertions, 20 deletions
diff --git a/tests/data/fuzz/cold-outputs/out-all-6 b/tests/data/fuzz/cold-outputs/out-all-6
index d24fc604f..8016928e3 100644
--- a/tests/data/fuzz/cold-outputs/out-all-6
+++ b/tests/data/fuzz/cold-outputs/out-all-6
Binary files differ
diff --git a/tests/functional_tests/cold_signing.py b/tests/functional_tests/cold_signing.py
index 31d5780bb..bd48671a2 100755
--- a/tests/functional_tests/cold_signing.py
+++ b/tests/functional_tests/cold_signing.py
@@ -34,13 +34,22 @@
from __future__ import print_function
from framework.daemon import Daemon
from framework.wallet import Wallet
+import random
+
+SEED = 'velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted'
+STANDARD_ADDRESS = '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
+SUBADDRESS = '84QRUYawRNrU3NN1VpFRndSukeyEb3Xpv8qZjjsoJZnTYpDYceuUTpog13D7qPxpviS7J29bSgSkR11hFFoXWk2yNdsR9WF'
class ColdSigningTest():
def run_test(self):
self.reset()
self.create(0)
self.mine()
- self.transfer()
+ for piecemeal_output_export in [False, True]:
+ self.transfer(piecemeal_output_export)
+ for piecemeal_output_export in [False, True]:
+ self.self_transfer_to_subaddress(piecemeal_output_export)
+ self.transfer_after_empty_export_import()
def reset(self):
print('Resetting blockchain')
@@ -57,17 +66,15 @@ class ColdSigningTest():
try: self.hot_wallet.close_wallet()
except: pass
- self.cold_wallet = Wallet(idx = 1)
+ self.cold_wallet = Wallet(idx = 5)
# close the wallet if any, will throw if none is loaded
try: self.cold_wallet.close_wallet()
except: pass
- seed = 'velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted'
- res = self.cold_wallet.restore_deterministic_wallet(seed = seed)
- self.cold_wallet.set_daemon('127.0.0.1:11111', ssl_support = "disabled")
+ res = self.cold_wallet.restore_deterministic_wallet(seed = SEED)
spend_key = self.cold_wallet.query_key("spend_key").key
view_key = self.cold_wallet.query_key("view_key").key
- res = self.hot_wallet.generate_from_keys(viewkey = view_key, address = '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm')
+ res = self.hot_wallet.generate_from_keys(viewkey = view_key, address = STANDARD_ADDRESS)
ok = False
try: res = self.hot_wallet.query_key("spend_key")
@@ -79,28 +86,62 @@ class ColdSigningTest():
assert ok
assert self.cold_wallet.query_key("view_key").key == view_key
assert self.cold_wallet.get_address().address == self.hot_wallet.get_address().address
+ assert self.cold_wallet.get_address().address == STANDARD_ADDRESS
def mine(self):
print("Mining some blocks")
daemon = Daemon()
wallet = Wallet()
- daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80)
+ daemon.generateblocks(STANDARD_ADDRESS, 80)
wallet.refresh()
- def transfer(self):
- daemon = Daemon()
+ def export_import(self, piecemeal_output_export):
+ self.hot_wallet.refresh()
- print("Creating transaction in hot wallet")
+ if piecemeal_output_export:
+ res = self.hot_wallet.incoming_transfers()
+ num_outputs = len(res.transfers)
+ done = [False] * num_outputs
+ while len([x for x in done if not done[x]]) > 0:
+ start = int(random.random() * num_outputs)
+ if start == num_outputs:
+ num_outputs -= 1
+ count = 1 + int(random.random() * 5)
+ res = self.hot_wallet.export_outputs(all = True, start = start, count = count)
- dst = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
+ # the hot wallet cannot import outputs
+ ok = False
+ try:
+ self.hot_wallet.import_outputs(res.outputs_data_hex)
+ except:
+ ok = True
+ assert ok
+
+ try:
+ self.cold_wallet.import_outputs(res.outputs_data_hex)
+ except Exception as e:
+ # this just means we selected later outputs first, without filling
+ # new outputs first
+ if 'Imported outputs omit more outputs that we know of' not in str(e):
+ raise
+ for i in range(start, start + count):
+ if i < len(done):
+ done[i] = True
+ else:
+ res = self.hot_wallet.export_outputs()
+ self.cold_wallet.import_outputs(res.outputs_data_hex)
- self.hot_wallet.refresh()
- res = self.hot_wallet.export_outputs()
- self.cold_wallet.import_outputs(res.outputs_data_hex)
res = self.cold_wallet.export_key_images(True)
self.hot_wallet.import_key_images(res.signed_key_images, offset = res.offset)
+ def create_tx(self, destination_addr, piecemeal_output_export):
+ daemon = Daemon()
+
+ dst = {'address': destination_addr, 'amount': 1000000000000}
+
+ self.export_import(piecemeal_output_export)
+
res = self.hot_wallet.transfer([dst], ring_size = 16, get_tx_key = False)
assert len(res.tx_hash) == 32*2
txid = res.tx_hash
@@ -125,11 +166,11 @@ class ColdSigningTest():
assert desc.unlock_time == 0
assert desc.payment_id in ['', '0000000000000000']
assert desc.change_amount == desc.amount_in - 1000000000000 - fee
- assert desc.change_address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
+ assert desc.change_address == STANDARD_ADDRESS
assert desc.fee == fee
assert len(desc.recipients) == 1
rec = desc.recipients[0]
- assert rec.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
+ assert rec.address == destination_addr
assert rec.amount == 1000000000000
res = self.cold_wallet.sign_transfer(unsigned_txset)
@@ -148,7 +189,7 @@ class ColdSigningTest():
assert len([x for x in (res['pending'] if 'pending' in res else []) if x.txid == txid]) == 1
assert len([x for x in (res['out'] if 'out' in res else []) if x.txid == txid]) == 0
- daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
+ daemon.generateblocks(STANDARD_ADDRESS, 1)
self.hot_wallet.refresh()
res = self.hot_wallet.get_transfers()
@@ -160,6 +201,47 @@ class ColdSigningTest():
res = self.cold_wallet.get_tx_key(txid)
assert len(res.tx_key) == 64
+ self.export_import(piecemeal_output_export)
+
+ def transfer(self, piecemeal_output_export):
+ print("Creating transaction in hot wallet")
+ self.create_tx(STANDARD_ADDRESS, piecemeal_output_export)
+
+ res = self.cold_wallet.get_address()
+ assert len(res['addresses']) == 1
+ assert res['addresses'][0].address == STANDARD_ADDRESS
+ assert res['addresses'][0].used
+
+ res = self.hot_wallet.get_address()
+ assert len(res['addresses']) == 1
+ assert res['addresses'][0].address == STANDARD_ADDRESS
+ assert res['addresses'][0].used
+
+ def self_transfer_to_subaddress(self, piecemeal_output_export):
+ print("Self-spending to subaddress in hot wallet")
+ self.create_tx(SUBADDRESS, piecemeal_output_export)
+
+ res = self.cold_wallet.get_address()
+ assert len(res['addresses']) == 2
+ assert res['addresses'][0].address == STANDARD_ADDRESS
+ assert res['addresses'][0].used
+ assert res['addresses'][1].address == SUBADDRESS
+ assert res['addresses'][1].used
+
+ res = self.hot_wallet.get_address()
+ assert len(res['addresses']) == 2
+ assert res['addresses'][0].address == STANDARD_ADDRESS
+ assert res['addresses'][0].used
+ assert res['addresses'][1].address == SUBADDRESS
+ assert res['addresses'][1].used
+
+ def transfer_after_empty_export_import(self):
+ print("Creating transaction in hot wallet after empty export & import")
+ start_len = len(self.hot_wallet.get_transfers()['in'])
+ self.export_import(False)
+ assert start_len == len(self.hot_wallet.get_transfers()['in'])
+ self.create_tx(STANDARD_ADDRESS, False)
+ assert start_len == len(self.hot_wallet.get_transfers()['in']) - 1
class Guard:
def __enter__(self):
diff --git a/tests/functional_tests/functional_tests_rpc.py b/tests/functional_tests/functional_tests_rpc.py
index eb8d51f08..d020bf2f6 100755
--- a/tests/functional_tests/functional_tests_rpc.py
+++ b/tests/functional_tests/functional_tests_rpc.py
@@ -40,8 +40,9 @@ except:
N_MONERODS = 4
# 4 wallets connected to the main offline monerod
-# a wallet connected to the first local online monerod
-N_WALLETS = 5
+# 1 wallet connected to the first local online monerod
+# 1 offline wallet
+N_WALLETS = 6
WALLET_DIRECTORY = builddir + "/functional-tests-directory"
FUNCTIONAL_TESTS_DIRECTORY = builddir + "/tests/functional_tests"
@@ -61,6 +62,7 @@ wallet_extra = [
["--daemon-port", "18180"],
["--daemon-port", "18180"],
["--daemon-port", "18182"],
+ ["--offline"],
]
command_lines = []
diff --git a/tests/fuzz/cold-outputs.cpp b/tests/fuzz/cold-outputs.cpp
index a7e8a6530..fddd5359b 100644
--- a/tests/fuzz/cold-outputs.cpp
+++ b/tests/fuzz/cold-outputs.cpp
@@ -50,7 +50,7 @@ BEGIN_INIT_SIMPLE_FUZZER()
END_INIT_SIMPLE_FUZZER()
BEGIN_SIMPLE_FUZZER()
- std::pair<uint64_t, std::vector<tools::wallet2::transfer_details>> outputs;
+ std::tuple<uint64_t, uint64_t, std::vector<tools::wallet2::transfer_details>> outputs;
binary_archive<false> ar{{buf, len}};
::serialization::serialize(ar, outputs);
size_t n_outputs = wallet->import_outputs(outputs);