Use gettxout where scantxoutset is not available.

This commit is contained in:
tecnovert
2023-11-24 21:44:48 +02:00
parent 22cd3cf9f1
commit 7053d7ee4b
23 changed files with 4985 additions and 124 deletions

View File

@@ -44,7 +44,7 @@ from tests.basicswap.common import (
wait_for_in_progress,
wait_for_bid_tx_state,
)
from basicswap.contrib.test_framework.messages import (
from basicswap.interface.contrib.firo_test_framework.mininode import (
FromHex,
CTransaction,
)
@@ -168,7 +168,8 @@ class Test(BaseTest):
# Set future block rewards to nowhere (a random address), so wallet amounts stay constant
void_block_rewards_pubkey = cls.getRandomPubkey()
cls.firo_addr = cls.swap_clients[0].ci(Coins.FIRO).pubkey_to_address(void_block_rewards_pubkey)
num_blocks = 100
chain_height = callnoderpc(0, 'getblockcount', base_rpc_port=FIRO_BASE_RPC_PORT)
num_blocks = 1352 - chain_height # Activate CTLV (bip65)
logging.info('Mining %d Firo blocks to %s', num_blocks, cls.firo_addr)
callnoderpc(0, 'generatetoaddress', [num_blocks, cls.firo_addr], base_rpc_port=FIRO_BASE_RPC_PORT)
@@ -189,7 +190,7 @@ class Test(BaseTest):
'rpcpassword': 'test_pass' + str(node_id),
'datadir': os.path.join(datadir, 'firo_' + str(node_id)),
'bindir': FIRO_BINDIR,
'use_csv': True,
'use_csv': False,
'use_segwit': False,
}
@@ -207,6 +208,9 @@ class Test(BaseTest):
def callnoderpc(self, method, params=[], wallet=None, node_id=0):
return callnoderpc(node_id, method, params, wallet, base_rpc_port=FIRO_BASE_RPC_PORT)
def mineBlock(self, num_blocks: int = 1):
self.callnoderpc('generatetoaddress', [num_blocks, self.firo_addr])
def test_001_firo(self):
logging.info('---------- Test {} segwit'.format(self.test_coin_from.name))
@@ -251,7 +255,8 @@ class Test(BaseTest):
decoded_tx = CTransaction()
decoded_tx = FromHex(decoded_tx, tx_funded)
decoded_tx.vin[0].scriptSig = bytes.fromhex('16' + addr_witness_info['hex'])
txid_with_scriptsig = decoded_tx.rehash()
decoded_tx.rehash()
txid_with_scriptsig = decoded_tx.hash
tx_funded_decoded = firoCli(f'decoderawtransaction {tx_funded}')
tx_signed_decoded = firoCli(f'decoderawtransaction {tx_signed}')
@@ -268,6 +273,55 @@ class Test(BaseTest):
assert ('490ba1e2c3894d5534c467141ee3cdf77292c362' == ci.getWalletSeedID())
assert swap_client.checkWalletSeed(self.test_coin_from) is True
def test_008_gettxout(self):
logging.info('---------- Test {} gettxout'.format(self.test_coin_from.name))
swap_client = self.swap_clients[0]
addr_plain = self.callnoderpc('getnewaddress', ['gettxout test',])
addr_plain1 = self.callnoderpc('getnewaddress', ['gettxout test 1',])
addr_witness = self.callnoderpc('addwitnessaddress', [addr_plain1,])
txid = self.callnoderpc('sendtoaddress', [addr_witness, 1.0])
assert len(txid) == 64
self.callnoderpc('generatetoaddress', [1, self.firo_addr])
unspents = self.callnoderpc('listunspent')
for u in unspents:
if u['spendable'] is not True:
continue
if u['address'] == addr_witness:
print(u)
unspents = self.callnoderpc('listunspent', [0, 999999999, [addr_witness,]])
assert (len(unspents) == 1)
utxo = unspents[0]
txout = self.callnoderpc('gettxout', [utxo['txid'], utxo['vout']])
assert (addr_witness in txout['scriptPubKey']['addresses'])
# Spend
addr_plain2 = self.callnoderpc('getnewaddress', ['gettxout test 2',])
addr_witness2 = self.callnoderpc('addwitnessaddress', [addr_plain2,])
tx_funded = self.callnoderpc('createrawtransaction', [[{'txid': utxo['txid'], 'vout': utxo['vout']}], {addr_witness2: 0.99}])
tx_signed = self.callnoderpc('signrawtransaction', [tx_funded,])['hex']
self.callnoderpc('sendrawtransaction', [tx_signed,])
# utxo should be unavailable when spent in the mempool
txout = self.callnoderpc('gettxout', [utxo['txid'], utxo['vout']])
assert (txout is None)
self.callnoderpc('generatetoaddress', [1, self.firo_addr])
ci = swap_client.ci(Coins.FIRO)
require_amount: int = ci.make_int(1)
funds_proof = ci.getProofOfFunds(require_amount, 'test'.encode('utf-8'))
amount_proved = ci.verifyProofOfFunds(funds_proof[0], funds_proof[1], funds_proof[2], 'test'.encode('utf-8'))
assert (amount_proved >= require_amount)
def test_02_part_coin(self):
logging.info('---------- Test PART to {}'.format(self.test_coin_from.name))
if not self.test_atomic:
@@ -275,7 +329,7 @@ class Test(BaseTest):
return
swap_clients = self.swap_clients
offer_id = swap_clients[0].postOffer(Coins.PART, self.test_coin_from, 100 * COIN, 0.1 * COIN, 100 * COIN, SwapTypes.SELLER_FIRST)
offer_id = swap_clients[0].postOffer(Coins.PART, self.test_coin_from, 100 * COIN, 0.1 * COIN, 100 * COIN, SwapTypes.SELLER_FIRST, TxLockTypes.ABS_LOCK_TIME)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offer = swap_clients[1].getOffer(offer_id)
@@ -297,7 +351,7 @@ class Test(BaseTest):
logging.info('---------- Test {} to PART'.format(self.test_coin_from.name))
swap_clients = self.swap_clients
offer_id = swap_clients[1].postOffer(self.test_coin_from, Coins.PART, 10 * COIN, 9.0 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST)
offer_id = swap_clients[1].postOffer(self.test_coin_from, Coins.PART, 10 * COIN, 9.0 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST, TxLockTypes.ABS_LOCK_TIME)
wait_for_offer(test_delay_event, swap_clients[0], offer_id)
offer = swap_clients[0].getOffer(offer_id)
@@ -320,7 +374,7 @@ class Test(BaseTest):
logging.info('---------- Test {} to BTC'.format(self.test_coin_from.name))
swap_clients = self.swap_clients
offer_id = swap_clients[0].postOffer(self.test_coin_from, Coins.BTC, 10 * COIN, 0.1 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST)
offer_id = swap_clients[0].postOffer(self.test_coin_from, Coins.BTC, 10 * COIN, 0.1 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST, TxLockTypes.ABS_LOCK_TIME)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offer = swap_clients[1].getOffer(offer_id)
@@ -348,7 +402,7 @@ class Test(BaseTest):
swap_clients = self.swap_clients
offer_id = swap_clients[0].postOffer(self.test_coin_from, Coins.BTC, 10 * COIN, 0.1 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST,
TxLockTypes.SEQUENCE_LOCK_BLOCKS, 10)
TxLockTypes.ABS_LOCK_BLOCKS, 10)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offer = swap_clients[1].getOffer(offer_id)
@@ -372,7 +426,7 @@ class Test(BaseTest):
js_0_before = read_json_api(1800)
offer_id = swap_clients[0].postOffer(self.test_coin_from, Coins.BTC, 10 * COIN, 10 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST)
offer_id = swap_clients[0].postOffer(self.test_coin_from, Coins.BTC, 10 * COIN, 10 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST, TxLockTypes.ABS_LOCK_TIME)
wait_for_offer(test_delay_event, swap_clients[0], offer_id)
offer = swap_clients[0].getOffer(offer_id)
@@ -394,7 +448,7 @@ class Test(BaseTest):
js_0_before = read_json_api(1800)
offer_id = swap_clients[0].postOffer(self.test_coin_from, Coins.BTC, 0.001 * COIN, 1.0 * COIN, 0.001 * COIN, SwapTypes.SELLER_FIRST)
offer_id = swap_clients[0].postOffer(self.test_coin_from, Coins.BTC, 0.001 * COIN, 1.0 * COIN, 0.001 * COIN, SwapTypes.SELLER_FIRST, TxLockTypes.ABS_LOCK_TIME)
wait_for_offer(test_delay_event, swap_clients[0], offer_id)
offer = swap_clients[0].getOffer(offer_id)
@@ -491,7 +545,7 @@ class Test(BaseTest):
extra_options = {'prefunded_itx': itx}
rate_swap = ci_to.make_int(random.uniform(0.2, 10.0), r=1)
offer_id = swap_clients[2].postOffer(coin_from, coin_to, swap_value, rate_swap, swap_value, swap_type, extra_options=extra_options)
offer_id = swap_clients[2].postOffer(coin_from, coin_to, swap_value, rate_swap, swap_value, swap_type, TxLockTypes.ABS_LOCK_TIME, extra_options=extra_options)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offer = swap_clients[1].getOffer(offer_id)

View File

@@ -505,6 +505,10 @@ class BasicSwapTest(TestFunctions):
logging.info('---------- Test {} cltv'.format(self.test_coin_from.name))
ci = self.swap_clients[0].ci(self.test_coin_from)
deploymentinfo = self.callnoderpc('getdeploymentinfo')
bip65_active = deploymentinfo['deployments']['bip65']['active']
assert (bip65_active)
chain_height = self.callnoderpc('getblockcount')
script = CScript([chain_height + 3, OP_CHECKLOCKTIMEVERIFY, ])
@@ -518,7 +522,7 @@ class BasicSwapTest(TestFunctions):
tx_signed = self.callnoderpc('signrawtransactionwithwallet', [tx_funded['hex'], ])['hex']
txid = self.callnoderpc('sendrawtransaction', [tx_signed, ])
addr_out = self.callnoderpc('getnewaddress', ['csv test', 'bech32'])
addr_out = self.callnoderpc('getnewaddress', ['cltv test', 'bech32'])
pkh = ci.decodeSegwitAddress(addr_out)
script_out = ci.getScriptForPubkeyHash(pkh)
@@ -530,14 +534,26 @@ class BasicSwapTest(TestFunctions):
tx_spend.wit.vtxinwit.append(CTxInWitness())
tx_spend.wit.vtxinwit[0].scriptWitness.stack = [script, ]
tx_spend_hex = ToHex(tx_spend)
tx_spend.nLockTime = chain_height + 2
tx_spend_invalid_hex = ToHex(tx_spend)
for tx_hex in [tx_spend_invalid_hex, tx_spend_hex]:
try:
txid = self.callnoderpc('sendrawtransaction', [tx_hex, ])
except Exception as e:
assert ('non-final' in str(e))
else:
assert False, 'Should fail'
self.mineBlock(5)
try:
txid = self.callnoderpc('sendrawtransaction', [tx_spend_hex, ])
txid = self.callnoderpc('sendrawtransaction', [tx_spend_invalid_hex, ])
except Exception as e:
assert ('non-final' in str(e))
assert ('Locktime requirement not satisfied' in str(e))
else:
assert False, 'Should fail'
self.mineBlock(5)
txid = self.callnoderpc('sendrawtransaction', [tx_spend_hex, ])
self.mineBlock()
ro = self.callnoderpc('listreceivedbyaddress', [0, ])
@@ -547,6 +563,10 @@ class BasicSwapTest(TestFunctions):
sum_addr += entry['amount']
assert (sum_addr == 1.0999)
# Ensure tx was mined
tx_wallet = self.callnoderpc('gettransaction', [txid, ])
assert (len(tx_wallet['blockhash']) == 64)
def test_004_csv(self):
logging.info('---------- Test {} csv'.format(self.test_coin_from.name))
swap_clients = self.swap_clients

View File

@@ -36,6 +36,11 @@ from basicswap.util import (
DeserialiseNum,
validate_amount)
from basicswap.messages_pb2 import (
BidMessage,
BidMessage_v1Deprecated,
)
class Test(unittest.TestCase):
REQUIRED_SETTINGS = {'blocks_confirmed': 1, 'conf_target': 1, 'use_segwit': True, 'connection_type': 'rpc'}
@@ -312,6 +317,18 @@ class Test(unittest.TestCase):
input_data = b'hash this'
assert (ripemd160(input_data).hex() == 'd5443a154f167e2c1332f6de72cfb4c6ab9c8c17')
def test_protobuf(self):
# Ensure old protobuf templates can be read
msg_buf = BidMessage_v1Deprecated()
msg_buf.protocol_version = 2
serialised_msg = msg_buf.SerializeToString()
msg_buf_v2 = BidMessage()
msg_buf_v2.ParseFromString(serialised_msg)
assert (msg_buf_v2.protocol_version == 2)
if __name__ == '__main__':
unittest.main()

View File

@@ -52,6 +52,17 @@ from tests.basicswap.common import (
compare_bid_states,
extract_states_from_xu_file,
)
from basicswap.contrib.test_framework.messages import (
ToHex,
CTxIn,
COutPoint,
CTransaction,
CTxInWitness,
)
from basicswap.contrib.test_framework.script import (
CScript,
OP_CHECKLOCKTIMEVERIFY,
)
from .test_xmr import BaseTest, test_delay_event, callnoderpc
@@ -196,6 +207,77 @@ class Test(BaseTest):
for case in should_fail:
self.assertRaises(ValueError, sc.validateSwapType, case[0], case[1], case[2])
def test_003_cltv(self):
test_coin_from = Coins.PART
logging.info('---------- Test {} cltv'.format(test_coin_from.name))
ci = self.swap_clients[0].ci(test_coin_from)
deploymentinfo = callnoderpc(0, 'getdeploymentinfo')
bip65_active = deploymentinfo['deployments']['bip65']['active']
assert (bip65_active)
chain_height = callnoderpc(0, 'getblockcount')
script = CScript([chain_height + 3, OP_CHECKLOCKTIMEVERIFY, ])
script_dest = ci.getScriptDest(script)
tx = CTransaction()
tx.nVersion = ci.txVersion()
tx.vout.append(ci.txoType()(ci.make_int(1.1), script_dest))
tx_hex = ToHex(tx)
tx_funded = callnoderpc(0, 'fundrawtransaction', [tx_hex])
utxo_pos = 0 if tx_funded['changepos'] == 1 else 1
tx_signed = callnoderpc(0, 'signrawtransactionwithwallet', [tx_funded['hex'], ])['hex']
txid = callnoderpc(0, 'sendrawtransaction', [tx_signed, ])
addr_out = callnoderpc(0, 'getnewaddress', ['cltv test', ])
pkh = ci.decodeAddress(addr_out)
script_out = ci.getScriptForPubkeyHash(pkh)
tx_spend = CTransaction()
tx_spend.nVersion = ci.txVersion()
tx_spend.nLockTime = chain_height + 3
tx_spend.vin.append(CTxIn(COutPoint(int(txid, 16), utxo_pos)))
tx_spend.vout.append(ci.txoType()(ci.make_int(1.0999), script_out))
tx_spend.wit.vtxinwit.append(CTxInWitness())
tx_spend.wit.vtxinwit[0].scriptWitness.stack = [script, ]
tx_spend_hex = ToHex(tx_spend)
tx_spend.nLockTime = chain_height + 2
tx_spend_invalid_hex = ToHex(tx_spend)
for tx_hex in [tx_spend_invalid_hex, tx_spend_hex]:
try:
txid = callnoderpc(0, 'sendrawtransaction', [tx_hex, ])
except Exception as e:
assert ('non-final' in str(e))
else:
assert False, 'Should fail'
self.waitForParticlHeight(chain_height + 3)
try:
txid = callnoderpc(0, 'sendrawtransaction', [tx_spend_invalid_hex, ])
except Exception as e:
assert ('Locktime requirement not satisfied' in str(e))
else:
assert False, 'Should fail'
chain_height = callnoderpc(0, 'getblockcount')
txid = callnoderpc(0, 'sendrawtransaction', [tx_spend_hex, ])
ro = callnoderpc(0, 'listreceivedbyaddress', [0, ])
sum_addr = 0
for entry in ro:
if entry['address'] == addr_out:
sum_addr += entry['amount']
assert (sum_addr == 1.0999)
# Ensure tx was mined
for i in range(5):
self.waitForParticlHeight(chain_height + i)
tx_wallet = callnoderpc(0, 'gettransaction', [txid, ])
if 'blockhash' in tx_wallet:
break
assert (len(tx_wallet['blockhash']) == 64)
def test_01_verifyrawtransaction(self):
txn = '0200000001eb6e5c4ebba4efa32f40c7314cad456a64008e91ee30b2dd0235ab9bb67fbdbb01000000ee47304402200956933242dde94f6cf8f195a470f8d02aef21ec5c9b66c5d3871594bdb74c9d02201d7e1b440de8f4da672d689f9e37e98815fb63dbc1706353290887eb6e8f7235012103dc1b24feb32841bc2f4375da91fa97834e5983668c2a39a6b7eadb60e7033f9d205a803b28fe2f86c17db91fa99d7ed2598f79b5677ffe869de2e478c0d1c02cc7514c606382012088a8201fe90717abb84b481c2a59112414ae56ec8acc72273642ca26cc7a5812fdc8f68876a914225fbfa4cb725b75e511810ac4d6f74069bdded26703520140b27576a914207eb66b2fd6ed9924d6217efc7fa7b38dfabe666888acffffffff01e0167118020000001976a9140044e188928710cecba8311f1cf412135b98145c88ac00000000'
prevout = {