qa: don't use a static dummy origin for descriptor xpubs
This commit is contained in:
parent
a81d39c81a
commit
b71bd693d6
@ -1,4 +1,5 @@
|
||||
from bip32 import BIP32
|
||||
from bip32.utils import _pubkey_to_fingerprint
|
||||
from bip380.descriptors import Descriptor
|
||||
from concurrent import futures
|
||||
from test_framework.bitcoind import Bitcoind
|
||||
@ -115,6 +116,10 @@ def bitcoind(directory):
|
||||
bitcoind.cleanup()
|
||||
|
||||
|
||||
def xpub_fingerprint(hd):
|
||||
return _pubkey_to_fingerprint(hd.pubkey).hex()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def lianad(bitcoind, directory):
|
||||
datadir = os.path.join(directory, "lianad")
|
||||
@ -122,13 +127,15 @@ def lianad(bitcoind, directory):
|
||||
bitcoind_cookie = os.path.join(bitcoind.bitcoin_dir, "regtest", ".cookie")
|
||||
|
||||
signer = SingleSigner()
|
||||
primary_xpub, recovery_xpub = (
|
||||
signer.primary_hd.get_xpub(),
|
||||
signer.recovery_hd.get_xpub(),
|
||||
(prim_fingerprint, primary_xpub), (reco_fingerprint, recovery_xpub) = (
|
||||
(xpub_fingerprint(signer.primary_hd), signer.primary_hd.get_xpub()),
|
||||
(xpub_fingerprint(signer.recovery_hd), signer.recovery_hd.get_xpub()),
|
||||
)
|
||||
csv_value = 10
|
||||
# NOTE: origins are the actual xpub themselves which is incorrect but make it
|
||||
# possible to differentiate them.
|
||||
main_desc = Descriptor.from_str(
|
||||
f"wsh(or_d(pk([aabbccdd]{primary_xpub}/<0;1>/*),and_v(v:pkh([aabbccdd]{recovery_xpub}/<0;1>/*),older({csv_value}))))"
|
||||
f"wsh(or_d(pk([{prim_fingerprint}]{primary_xpub}/<0;1>/*),and_v(v:pkh([{reco_fingerprint}]{recovery_xpub}/<0;1>/*),older({csv_value}))))"
|
||||
)
|
||||
|
||||
lianad = Lianad(
|
||||
@ -152,7 +159,10 @@ def lianad(bitcoind, directory):
|
||||
def multi_expression(thresh, keys):
|
||||
exp = f"multi({thresh},"
|
||||
for i, key in enumerate(keys):
|
||||
exp += f"[aabbccdd]{key.get_xpub()}/<0;1>/*"
|
||||
# NOTE: origins are the actual xpub themselves which is incorrect but make it
|
||||
# possible to differentiate them.
|
||||
fingerprint = xpub_fingerprint(key)
|
||||
exp += f"[{fingerprint}]{key.get_xpub()}/<0;1>/*"
|
||||
if i != len(keys) - 1:
|
||||
exp += ","
|
||||
return exp + ")"
|
||||
|
||||
@ -127,11 +127,16 @@ def test_multipath(lianad_multipath, bitcoind):
|
||||
reco_psbt = PSBT.from_base64(res["psbt"])
|
||||
txid = reco_psbt.tx.txid().hex()
|
||||
|
||||
# NOTE: this test was commented out due to the introduced restriction to not include
|
||||
# the BIP32 derivations for other spending paths in PSBT inputs to support the Bitbox2
|
||||
# signing device (and most likely others).
|
||||
# TODO: reintroduce these tests once we get rid of this restriction.
|
||||
|
||||
# Try to sign with the keys for the next recovery spending path, it'll fail.
|
||||
signed_psbt = lianad_multipath.signer.sign_psbt(reco_psbt, {20: range(3)})
|
||||
lianad_multipath.rpc.updatespend(signed_psbt.to_base64())
|
||||
with pytest.raises(RpcError, match="Failed to finalize"):
|
||||
lianad_multipath.rpc.broadcastspend(txid)
|
||||
# signed_psbt = lianad_multipath.signer.sign_psbt(reco_psbt, {20: range(3)})
|
||||
# lianad_multipath.rpc.updatespend(signed_psbt.to_base64())
|
||||
# with pytest.raises(RpcError, match="Failed to finalize"):
|
||||
# lianad_multipath.rpc.broadcastspend(txid)
|
||||
|
||||
# Try to sign with the right keys but only two of them, it'll fail.
|
||||
signed_psbt = lianad_multipath.signer.sign_psbt(reco_psbt, {10: range(2)})
|
||||
@ -144,52 +149,54 @@ def test_multipath(lianad_multipath, bitcoind):
|
||||
lianad_multipath.rpc.updatespend(signed_psbt.to_base64())
|
||||
lianad_multipath.rpc.broadcastspend(txid)
|
||||
|
||||
# NOTE: commented out for the same reason as above.
|
||||
|
||||
# Receive 3 more coins and make the second recovery path (20 blocks) available.
|
||||
txids = []
|
||||
for _ in range(3):
|
||||
addr = lianad_multipath.rpc.getnewaddress()["address"]
|
||||
txids.append(bitcoind.rpc.sendtoaddress(addr, 0.42))
|
||||
bitcoind.generate_block(20, wait_for_mempool=txids)
|
||||
wait_for(
|
||||
lambda: lianad_multipath.rpc.getinfo()["block_height"]
|
||||
== bitcoind.rpc.getblockcount()
|
||||
)
|
||||
# txids = []
|
||||
# for _ in range(3):
|
||||
# addr = lianad_multipath.rpc.getnewaddress()["address"]
|
||||
# txids.append(bitcoind.rpc.sendtoaddress(addr, 0.42))
|
||||
# bitcoind.generate_block(20, wait_for_mempool=txids)
|
||||
# wait_for(
|
||||
# lambda: lianad_multipath.rpc.getinfo()["block_height"]
|
||||
# == bitcoind.rpc.getblockcount()
|
||||
# )
|
||||
|
||||
# We can create a recovery transaction for an earlier timelock.
|
||||
lianad_multipath.rpc.createrecovery(bitcoind.rpc.getnewaddress(), 2)
|
||||
# lianad_multipath.rpc.createrecovery(bitcoind.rpc.getnewaddress(), 2)
|
||||
|
||||
# Sweep all coins through the second recovery path (that is available after 20 blocks).
|
||||
# It needs 3 signatures out of 5 keys.
|
||||
res = lianad_multipath.rpc.createrecovery(bitcoind.rpc.getnewaddress(), 2, 20)
|
||||
reco_psbt = PSBT.from_base64(res["psbt"])
|
||||
txid = reco_psbt.tx.txid().hex()
|
||||
# res = lianad_multipath.rpc.createrecovery(bitcoind.rpc.getnewaddress(), 2, 20)
|
||||
# reco_psbt = PSBT.from_base64(res["psbt"])
|
||||
# txid = reco_psbt.tx.txid().hex()
|
||||
|
||||
# We can sign with any keys for the second recovery path (we need only 1 out of 10)
|
||||
signed_psbt = lianad_multipath.signer.sign_psbt(reco_psbt, {20: [8]})
|
||||
lianad_multipath.rpc.updatespend(signed_psbt.to_base64())
|
||||
lianad_multipath.rpc.broadcastspend(txid)
|
||||
# signed_psbt = lianad_multipath.signer.sign_psbt(reco_psbt, {20: [8]})
|
||||
# lianad_multipath.rpc.updatespend(signed_psbt.to_base64())
|
||||
# lianad_multipath.rpc.broadcastspend(txid)
|
||||
|
||||
# Now do this again but with signing using keys for the first recovery path.
|
||||
# Receive 3 more coins and make the second recovery path (20 blocks) available. Note this
|
||||
# is possible since the CSV checks the nSequence is >= to the value, not ==.
|
||||
txids = []
|
||||
for _ in range(3):
|
||||
addr = lianad_multipath.rpc.getnewaddress()["address"]
|
||||
txids.append(bitcoind.rpc.sendtoaddress(addr, 0.398))
|
||||
bitcoind.generate_block(20, wait_for_mempool=txids)
|
||||
wait_for(
|
||||
lambda: lianad_multipath.rpc.getinfo()["block_height"]
|
||||
== bitcoind.rpc.getblockcount()
|
||||
)
|
||||
# txids = []
|
||||
# for _ in range(3):
|
||||
# addr = lianad_multipath.rpc.getnewaddress()["address"]
|
||||
# txids.append(bitcoind.rpc.sendtoaddress(addr, 0.398))
|
||||
# bitcoind.generate_block(20, wait_for_mempool=txids)
|
||||
# wait_for(
|
||||
# lambda: lianad_multipath.rpc.getinfo()["block_height"]
|
||||
# == bitcoind.rpc.getblockcount()
|
||||
# )
|
||||
# Sweep all coins through the second recovery path (that is available after 20 blocks).
|
||||
# It needs 3 signatures out of 5 keys.
|
||||
res = lianad_multipath.rpc.createrecovery(bitcoind.rpc.getnewaddress(), 2, 20)
|
||||
reco_psbt = PSBT.from_base64(res["psbt"])
|
||||
txid = reco_psbt.tx.txid().hex()
|
||||
# res = lianad_multipath.rpc.createrecovery(bitcoind.rpc.getnewaddress(), 2, 20)
|
||||
# reco_psbt = PSBT.from_base64(res["psbt"])
|
||||
# txid = reco_psbt.tx.txid().hex()
|
||||
# We can sign with keys for the first recovery path (we need 3 out of 5)
|
||||
signed_psbt = lianad_multipath.signer.sign_psbt(reco_psbt, {10: range(2, 5)})
|
||||
lianad_multipath.rpc.updatespend(signed_psbt.to_base64())
|
||||
lianad_multipath.rpc.broadcastspend(txid)
|
||||
# signed_psbt = lianad_multipath.signer.sign_psbt(reco_psbt, {10: range(2, 5)})
|
||||
# lianad_multipath.rpc.updatespend(signed_psbt.to_base64())
|
||||
# lianad_multipath.rpc.broadcastspend(txid)
|
||||
|
||||
|
||||
def test_coinbase_deposit(lianad, bitcoind):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user