Continue building out the BCH interface

Adapt the swap flow to BCH specifics - txids change after funding and when signing inputs
BCH happy path (lock-spend) done
This commit is contained in:
mainnet-pat
2024-10-20 16:29:50 +00:00
committed by tecnovert
parent 3ea832bd03
commit b83f289013
6 changed files with 678 additions and 145 deletions

View File

@@ -1,11 +1,29 @@
import unittest
from basicswap.protocols.xmr_swap_1 import XmrBchSwapInterface
from basicswap.contrib.test_framework.script import CScript
from basicswap.interface.bch import BCHInterface
bch_lock_spend_tx = '0200000001bfc6bbb47851441c7827059ae337a06aa9064da7f9537eb9243e45766c3dd34c00000000d8473045022100a0161ea14d3b41ed41250c8474fc8ec6ce1cab8df7f401e69ecf77c2ab63d82102207a2a57ddf2ea400e09ea059f3b261da96f5098858b17239931f3cc2fb929bb2a4c8ec3519dc4519d02e80300c600cc949d00ce00d18800cf00d28800d000d39d00cb641976a91481ec21969399d15c26af089d5db437ead066c5ba88ac00cd788821024ffcc0481629866671d89f05f3da813a2aacec1b52e69b8c0c586b665f5d4574ba6752b27523aa20df65a90e9becc316ff5aca44d4e06dfaade56622f32bafa197aba706c5e589758700cd87680000000001251cde06000000001976a91481ec21969399d15c26af089d5db437ead066c5ba88ac00000000'
bch_lock_script = 'c3519dc4519d02e80300c600cc949d00ce00d18800cf00d28800d000d39d00cb641976a91481ec21969399d15c26af089d5db437ead066c5ba88ac00cd788821024ffcc0481629866671d89f05f3da813a2aacec1b52e69b8c0c586b665f5d4574ba6752b27523aa20df65a90e9becc316ff5aca44d4e06dfaade56622f32bafa197aba706c5e589758700cd8768'
bch_lock_spend_script = '473045022100a0161ea14d3b41ed41250c8474fc8ec6ce1cab8df7f401e69ecf77c2ab63d82102207a2a57ddf2ea400e09ea059f3b261da96f5098858b17239931f3cc2fb929bb2a4c8ec3519dc4519d02e80300c600cc949d00ce00d18800cf00d28800d000d39d00cb641976a91481ec21969399d15c26af089d5db437ead066c5ba88ac00cd788821024ffcc0481629866671d89f05f3da813a2aacec1b52e69b8c0c586b665f5d4574ba6752b27523aa20df65a90e9becc316ff5aca44d4e06dfaade56622f32bafa197aba706c5e589758700cd8768'
coin_settings = {'rpcport': 0, 'rpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1, 'use_segwit': False, 'connection_type': 'rpc'}
class TestXmrBchSwapInterface(unittest.TestCase):
def test_generate_script(self):
out_1 = bytes.fromhex('a9147171b53baf87efc9c78ffc0e37a78859cebaae4a87')
out_2 = bytes.fromhex('a9147171b53baf87efc9c78ffc0e37a78859cebaae4a87')
public_key = bytes.fromhex('03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556')
print(XmrBchSwapInterface().genScriptLockTxScript(None, 1000, out_1, out_2, public_key, 2).hex())
# def test_generate_script(self):
# out_1 = bytes.fromhex('a9147171b53baf87efc9c78ffc0e37a78859cebaae4a87')
# out_2 = bytes.fromhex('a9147171b53baf87efc9c78ffc0e37a78859cebaae4a87')
# public_key = bytes.fromhex('03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556')
# ci = BCHInterface(coin_settings, "regtest")
# print(ci.genScriptLockTxScript(None, 1000, out_1, out_2, public_key, 2).hex())
def test_extractScriptLockScriptValues(self):
ci = BCHInterface(coin_settings, "regtest")
script_bytes = CScript(bytes.fromhex(bch_lock_script))
ci.extractScriptLockScriptValues(script_bytes)
script_bytes = CScript(bytes.fromhex(bch_lock_spend_script))
signature, mining_fee, out_1, out_2, public_key, timelock = ci.extractScriptLockScriptValuesFromScriptSig(script_bytes)
print(timelock)

View File

@@ -90,7 +90,7 @@ class TestFunctions(BaseTest):
swap_clients = self.swap_clients
ci = swap_clients[0].ci(Coins.BCH)
pi = swap_clients[0].pi(SwapTypes.XMR_BCH_SWAP)
pi = swap_clients[0].pi(SwapTypes.XMR_SWAP)
amount: int = ci.make_int(random.uniform(0.1, 2.0), r=1)
@@ -108,17 +108,36 @@ class TestFunctions(BaseTest):
mining_fee = 1000
timelock = 2
a_receive = ci.getNewAddress()
b_refund = ci.getNewAddress()
refund_lock_tx_script = pi.genScriptLockTxScript(mining_fee=mining_fee, out_1=ci.addressToLockingBytecode(b_refund), out_2=ci.addressToLockingBytecode(a_receive), public_key=A, timelock=timelock)
addr_out = ci.getNewAddress()
b_receive = ci.getNewAddress()
a_refund = ci.getNewAddress()
lock_tx_script = pi.genScriptLockTxScript(mining_fee=mining_fee, out_1=ci.addressToLockingBytecode(a_receive), out_2=ci.scriptToP2SH32LockingBytecode(refund_lock_tx_script), public_key=B, timelock=timelock)
refundExtraArgs = dict()
lockExtraArgs = dict()
refundExtraArgs['mining_fee'] = 1000
refundExtraArgs['out_1'] = ci.addressToLockingBytecode(a_refund)
refundExtraArgs['out_2'] = ci.addressToLockingBytecode(b_receive)
refundExtraArgs['public_key'] = B
refundExtraArgs['timelock'] = 5
refund_lock_tx_script = pi.genScriptLockTxScript(ci, A, B, **refundExtraArgs)
# will make use of this in `createSCLockRefundTx`
refundExtraArgs['refund_lock_tx_script'] = refund_lock_tx_script
# lock script
lockExtraArgs['mining_fee'] = 1000
lockExtraArgs['out_1'] = ci.addressToLockingBytecode(b_receive)
lockExtraArgs['out_2'] = ci.scriptToP2SH32LockingBytecode(refund_lock_tx_script)
lockExtraArgs['public_key'] = A
lockExtraArgs['timelock'] = 2
lock_tx_script = pi.genScriptLockTxScript(ci, A, B, **lockExtraArgs)
lock_tx = ci.createSCLockTx(amount, lock_tx_script)
lock_tx = ci.fundSCLockTx(lock_tx, fee_rate)
lock_tx = ci.signTxWithWallet(lock_tx)
print(lock_tx.hex())
return
unspents_after = ci.rpc('listunspent')
assert (len(unspents) > len(unspents_after))
@@ -151,25 +170,25 @@ class TestFunctions(BaseTest):
assert (wallet_tx_fee == fee_value)
assert (wallet_tx_fee == expect_fee_int)
pkh_out = ci.decodeAddress(a_receive)
pkh_out = ci.decodeAddress(b_receive)
msg = sha256(ci.addressToLockingBytecode(a_receive))
msg = sha256(ci.addressToLockingBytecode(b_receive))
# bob creates an adaptor signature for alice and transmits it to her
bAdaptorSig = ecdsaotves_enc_sign(b, A, msg)
# leader creates an adaptor signature for follower and transmits it to the follower
aAdaptorSig = ecdsaotves_enc_sign(a, B, msg)
# alice verifies the adaptor signature
assert (ecdsaotves_enc_verify(B, A, msg, bAdaptorSig))
assert (ecdsaotves_enc_verify(A, B, msg, aAdaptorSig))
# alice decrypts the adaptor signature
bAdaptorSig_dec = ecdsaotves_dec_sig(a, bAdaptorSig)
aAdaptorSig_dec = ecdsaotves_dec_sig(b, aAdaptorSig)
fee_info = {}
lock_spend_tx = ci.createSCLockSpendTx(lock_tx, lock_tx_script, pkh_out, mining_fee, ves=bAdaptorSig_dec, fee_info=fee_info)
lock_spend_tx = ci.createSCLockSpendTx(lock_tx, lock_tx_script, pkh_out, mining_fee, fee_info=fee_info, ves=aAdaptorSig_dec)
vsize_estimated: int = fee_info['vsize']
tx_decoded = ci.rpc('decoderawtransaction', [lock_spend_tx.hex()])
print(tx_decoded)
print('lock_spend_tx', lock_spend_tx.hex(), '\n', 'tx_decoded', tx_decoded)
txid = tx_decoded['txid']
tx_decoded = ci.rpc('decoderawtransaction', [lock_spend_tx.hex()])

View File

@@ -98,11 +98,11 @@ from basicswap.bin.run import startDaemon, startXmrDaemon, startXmrWalletDaemon
logger = logging.getLogger()
NUM_NODES = 2
NUM_XMR_NODES = 2
NUM_BTC_NODES = 2
NUM_BCH_NODES = 2
NUM_LTC_NODES = 2
NUM_NODES = 3
NUM_XMR_NODES = 3
NUM_BTC_NODES = 3
NUM_BCH_NODES = 3
NUM_LTC_NODES = 3
TEST_DIR = cfg.TEST_DATADIRS
XMR_BASE_P2P_PORT = 17792
@@ -692,7 +692,7 @@ class BaseTest(unittest.TestCase):
if cls.btc_addr is not None:
btcCli('generatetoaddress 1 {}'.format(cls.btc_addr))
if cls.bch_addr is not None:
ltcCli('generatetoaddress 1 {}'.format(cls.bch_addr))
bchCli('generatetoaddress 1 {}'.format(cls.bch_addr))
if cls.ltc_addr is not None:
ltcCli('generatetoaddress 1 {}'.format(cls.ltc_addr))
if cls.xmr_addr is not None: