1
0

wizard: enable_keystore: fix for multisig

regression from 66c0fec1ea
This commit is contained in:
SomberNight
2025-08-15 20:52:49 +00:00
parent 14494c13dc
commit dc999aa948
4 changed files with 69 additions and 14 deletions

View File

@@ -6,7 +6,9 @@ from typing import Sequence
import asyncio
import copy
from electrum import storage, bitcoin, keystore, bip32, slip39, wallet
from electrum import bitcoin, keystore, bip32, slip39, wallet
from electrum.wallet_db import WalletDB
from electrum.storage import WalletStorage
from electrum import SimpleConfig
from electrum import util
from electrum.address_synchronizer import TX_HEIGHT_UNCONFIRMED, TX_HEIGHT_UNCONF_PARENT, TX_HEIGHT_LOCAL, TX_HEIGHT_FUTURE
@@ -35,7 +37,6 @@ class WalletIntegrityHelper:
gap_limit = 1 # make tests run faster
gap_limit_for_change = 1 # make tests run faster
# TODO also use short gap limit for change addrs, for performance
@classmethod
def check_seeded_keystore_sanity(cls, test_obj, ks):
@@ -53,7 +54,7 @@ class WalletIntegrityHelper:
@classmethod
def create_standard_wallet(cls, ks, *, config: SimpleConfig, gap_limit=None, gap_limit_for_change=None):
db = storage.WalletDB('', storage=None, upgrade=True)
db = WalletDB('', storage=None, upgrade=True)
db.put('keystore', ks.dump())
db.put('gap_limit', gap_limit or cls.gap_limit)
db.put('gap_limit_for_change', gap_limit_for_change or cls.gap_limit_for_change)
@@ -63,7 +64,7 @@ class WalletIntegrityHelper:
@classmethod
def create_imported_wallet(cls, *, config: SimpleConfig, privkeys: bool):
db = storage.WalletDB('', storage=None, upgrade=True)
db = WalletDB('', storage=None, upgrade=True)
if privkeys:
k = keystore.Imported_KeyStore({})
db.put('keystore', k.dump())
@@ -71,10 +72,18 @@ class WalletIntegrityHelper:
return w
@classmethod
def create_multisig_wallet(cls, keystores: Sequence, multisig_type: str, *,
config: SimpleConfig, gap_limit=None, gap_limit_for_change=None):
def create_multisig_wallet(
cls,
keystores: Sequence,
multisig_type: str,
*,
config: SimpleConfig,
storage: WalletStorage | None = None,
gap_limit=None,
gap_limit_for_change=None,
):
"""Creates a multisig wallet."""
db = storage.WalletDB('', storage=None, upgrade=False)
db = WalletDB('', storage=storage, upgrade=False)
for i, ks in enumerate(keystores):
cosigner_index = i + 1
db.put('x%d' % cosigner_index, ks.dump())

View File

@@ -11,9 +11,11 @@ from electrum.wallet import Abstract_Wallet
from electrum import util
from electrum import slip39
from electrum.bip32 import KeyOriginInfo
from electrum import keystore
from electrum.storage import WalletStorage
from . import ElectrumTestCase
from .test_wallet_vertical import UNICODE_HORROR
from .test_wallet_vertical import UNICODE_HORROR, WalletIntegrityHelper
class NetworkMock:
@@ -125,8 +127,6 @@ class ServerConnectWizardTestCase(WizardTestCase):
class KeystoreWizardTestCase(WizardTestCase):
# TODO add test cases for:
# - multisig
class TKeystoreWizard(KeystoreWizard):
def is_single_password(self):
@@ -390,6 +390,46 @@ class KeystoreWizardTestCase(WizardTestCase):
wallet.disable_keystore(wallet.get_keystore())
self._sanity_checks_after_disabling_keystore(ks=wallet.get_keystore(), xpub=myxpub, key_origin_info=my_keyorigininfo)
async def test_multisig(self):
seed1 = "bitter grass shiver impose acquire brush forget axis eager alone wine silver"
xpub1 = "Zpub6ymNkfdyhypEoqQNNGAUz9gXeiWJsW8AWx8Aa6PnDdeL76UC9b1UPGmEvwWzzkVVghVQuDBry7CK7wCBBdysRQgFFmdDSqi5kWoZ3A4cBuA"
seed2 = "snow nest raise royal more walk demise rotate smooth spirit canyon gun"
xpub2 = "Zpub6xwgqLvc42wXB1wEELTdALD9iXwStMUkGqBgxkJFYumaL2dWgNvUkjEDWyDFZD3fZuDWDzd1KQJ4NwVHS7hs6H6QkpNYSShfNiUZsgMdtNg"
wallet = WalletIntegrityHelper.create_multisig_wallet(
[
keystore.from_seed(seed1, passphrase='', for_multisig=True),
keystore.from_xpub(xpub2),
],
'2of2',
config=self.config,
storage=WalletStorage(self.wallet_path),
)
w, v = self._wizard_for(wallet_type=wallet.wallet_type)
d = v.wizard_data
d.update({
'seed': seed2, 'seed_type': 'segwit', 'seed_extend': False, 'seed_variant': 'electrum',
})
self.assertTrue(w.is_last_view(v.view, d))
w.resolve_next(v.view, d)
ks, ishww = w._result
self.assertFalse(ishww)
self.assertEqual(ks.xpub, xpub2)
self.assertFalse(wallet.get_keystores()[0].is_watching_only())
self.assertTrue(wallet.get_keystores()[1].is_watching_only())
self.assertTrue(wallet.can_enable_disable_keystore(ks))
wallet.enable_keystore(ks, ishww, None)
self.assertFalse(wallet.get_keystores()[0].is_watching_only())
self.assertFalse(wallet.get_keystores()[1].is_watching_only())
self.assertEqual(seed1, wallet.get_keystores()[0].get_seed(None))
self.assertEqual(seed2, wallet.get_keystores()[1].get_seed(None))
keyorigininfo1 = wallet.get_keystores()[0].get_key_origin_info()
wallet.disable_keystore(wallet.get_keystores()[0])
self._sanity_checks_after_disabling_keystore(ks=wallet.get_keystores()[0], xpub=xpub1, key_origin_info=keyorigininfo1)
class WalletWizardTestCase(WizardTestCase):