Skip to content

Commit

Permalink
Testing with cosigner id's, updated multisig single key unittests
Browse files Browse the repository at this point in the history
  • Loading branch information
Cryp Toon committed Jun 12, 2024
1 parent e48b4e1 commit b139c6f
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
12 changes: 9 additions & 3 deletions bitcoinlib/wallets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1305,7 +1305,7 @@ def create(cls, name, keys=None, owner='', network=None, account_id=0, purpose=0
:type multisig: bool
:param sigs_required: Number of signatures required for validation if using a multisignature wallet. For example 2 for 2-of-3 multisignature. Default is all keys must be signed
:type sigs_required: int
:param cosigner_id: Set this if wallet contains only public keys, more than one private key or if you would like to create keys for other cosigners. Note: provided keys of a multisig wallet are sorted if sort_keys = True (default) so if your provided key list is not sorted the cosigned_id may be different.
:param cosigner_id: Set this if wallet contains only public keys, more than one private key or if you would like to create keys for other cosigners. Note: provided keys of a multisig wallet are sorted if sort_keys = True (default) so if your provided key list is not sorted the wallet's cosigner_id may be different.
:type cosigner_id: int
:param key_path: Key path for multisig wallet, use to create your own non-standard key path. Key path must follow the following rules:
* Path start with masterkey (m) and end with change / address_index
Expand Down Expand Up @@ -1353,8 +1353,8 @@ def create(cls, name, keys=None, owner='', network=None, account_id=0, purpose=0
"locked up funds")

hdkey_list = []
if keys and isinstance(keys, list) and sort_keys:
keys.sort(key=lambda x: ('0' if isinstance(x, HDKey) else '1'))
# if keys and isinstance(keys, list) and sort_keys:
# keys.sort(key=lambda x: ('0' if isinstance(x, HDKey) else '1'))
for key in keys:
if isinstance(key, HDKey):
if network and network != key.network.name:
Expand Down Expand Up @@ -1417,7 +1417,13 @@ def create(cls, name, keys=None, owner='', network=None, account_id=0, purpose=0
main_key_path = key_path
if multisig:
if sort_keys:
# FIXME: Think of simple construction to distinct between key order and cosigner id, the solution below is a bit confusing
# cosigner_id_key = None if cosigner_id is None else hdkey_list[cosigner_id].public_byte
hdkey_list.sort(key=lambda x: x.public_byte)
# Update cosigner id if order of keys changed
# cosigner_id = cosigner_id if (cosigner_id is None or cosigner_id_key is None) else (
# hdkey_list.index([k for k in hdkey_list if k.public_byte == cosigner_id_key][0]))

cos_prv_lst = [hdkey_list.index(cw) for cw in hdkey_list if cw.is_private]
if cosigner_id is None:
if not cos_prv_lst:
Expand Down
10 changes: 7 additions & 3 deletions tests/test_wallets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1429,11 +1429,11 @@ def test_wallets_multisig_missing_private_and_cosigner(self):

def test_wallets_multisig_with_single_key_cosigner(self):
k0 = 'xprv9s21ZrQH143K459uwGGCU3Wj3v1LFFJ42tgyTsNnr6p2BS6FZ9jQ7fmZMMnqsWSi2BBgpX3hFbR4ode8Jx58ibSNeaBLFQ68Xs3' \
'jwg4QFLh'
'jwg4QFLh' # cosigner 2
k1 = 'xpub661MyMwAqRbcGcJB4UPQpR2mUQtdUVbjjNC84DEK9ptZ2XgAC54U1onrH6tEMueYbzGPCRRPoDx5npvCS4Xryz8toVVEQ4ZFfkU' \
'cJobNZfn'
'cJobNZfn' # cosigner 1
k2 = 'xpub661MyMwAqRbcFD9fBAsKxxRPgikEvig5KYT1CEnAp7FcfcFeu2ZxdNcj6DDUxNreWgftXody6NqDHmFmh8tRZ4UNAecucovtW4M' \
'bGjYRJFP'
'bGjYRJFP' # cosigner 0
hdkey0 = HDKey(k0).public_master_multisig()
hdkey1 = HDKey(k1, key_type='single')
hdkey2 = HDKey(k2, key_type='single')
Expand All @@ -1448,15 +1448,19 @@ def test_wallets_multisig_with_single_key_cosigner(self):
self.assertEqual(len(w.addresslist()), 3)
self.assertEqual(w.keys()[0].address, '39b2tosg9To6cQTrqnZLhuhW5auqCqXKsH')
self.assertEqual(w.keys()[1].address, '3K2eBv2hm3SjhVRaJJK8Dt7wMb8mRTWcMH')
self.assertEqual(w.keys()[2].address, '3PprnP2HcaivRGaUSBm9Z724NHvjibb4c7')

w2 = wallet_create_or_open('test_wallets_multisig_with_single_key_cosigner2', keys=[hdkey0, hdkey1, hdkey2],
cosigner_id=2, db_uri=self.database_uri)
w2.new_key()
w2.new_key()
w2.new_key(cosigner_id=0)
self.assertEqual(w2.keys()[0].address, '39b2tosg9To6cQTrqnZLhuhW5auqCqXKsH')
self.assertEqual(w2.keys()[1].address, '3K2eBv2hm3SjhVRaJJK8Dt7wMb8mRTWcMH')
self.assertEqual(w2.keys()[2].address, '3PprnP2HcaivRGaUSBm9Z724NHvjibb4c7')
self.assertEqual(w2.keys()[0].path, "M/2/0/0")
self.assertEqual(w2.keys()[1].path, "M/2/0/1")
self.assertEqual(w2.keys()[2].path, "M/0/0/0")

# Close wallet and reopen to test for database issues for example
del w
Expand Down

0 comments on commit b139c6f

Please sign in to comment.