Browse Source

Make fidelity bond wallets be native segwit

Previously fidelity bond wallets were always p2sh-p2wpkh wallet, but
now joinmarket has moved over to native segwit.
master
chris-belcher 5 years ago
parent
commit
a3b3cd4054
No known key found for this signature in database
GPG Key ID: EF734EA677F31129
  1. 2
      jmclient/jmclient/__init__.py
  2. 10
      jmclient/jmclient/cryptoengine.py
  3. 20
      jmclient/jmclient/wallet.py
  4. 6
      jmclient/jmclient/wallet_utils.py
  5. 44
      jmclient/test/test_wallet.py

2
jmclient/jmclient/__init__.py

@ -14,7 +14,7 @@ from .taker import Taker
from .wallet import (Mnemonic, estimate_tx_fee, WalletError, BaseWallet, ImportWalletMixin,
BIP39WalletMixin, BIP32Wallet, BIP49Wallet, LegacyWallet,
SegwitWallet, SegwitLegacyWallet, FidelityBondMixin,
FidelityBondWatchonlyWallet, SegwitLegacyWalletFidelityBonds,
FidelityBondWatchonlyWallet, SegwitWalletFidelityBonds,
UTXOManager, WALLET_IMPLEMENTATIONS, compute_tx_locktime)
from .storage import (Argon2Hash, Storage, StorageError, RetryableStorageError,
StoragePasswordError, VolatileStorage)

10
jmclient/jmclient/cryptoengine.py

@ -12,8 +12,8 @@ from .configure import get_network, jm_single
#with fidelity bond wallets and watchonly fidelity bond wallet, the wallet class
# can have two engines, one for single-sig addresses and the other for timelocked addresses
TYPE_P2PKH, TYPE_P2SH_P2WPKH, TYPE_P2WPKH, TYPE_P2SH_M_N, TYPE_TIMELOCK_P2WSH, \
TYPE_SEGWIT_LEGACY_WALLET_FIDELITY_BONDS, TYPE_WATCHONLY_FIDELITY_BONDS, \
TYPE_WATCHONLY_TIMELOCK_P2WSH, TYPE_WATCHONLY_P2SH_P2WPKH = range(9)
TYPE_SEGWIT_WALLET_FIDELITY_BONDS, TYPE_WATCHONLY_FIDELITY_BONDS, \
TYPE_WATCHONLY_TIMELOCK_P2WSH, TYPE_WATCHONLY_P2WPKH = range(9)
NET_MAINNET, NET_TESTNET, NET_SIGNET = range(3)
NET_MAP = {'mainnet': NET_MAINNET, 'testnet': NET_TESTNET,
'signet': NET_SIGNET}
@ -407,7 +407,7 @@ class BTC_Watchonly_Timelocked_P2WSH(BTC_Timelocked_P2WSH):
hashcode=btc.SIGHASH_ALL, **kwargs):
raise RuntimeError("Cannot spend from watch-only wallets")
class BTC_Watchonly_P2SH_P2WPKH(BTC_P2SH_P2WPKH):
class BTC_Watchonly_P2WPKH(BTC_P2WPKH):
@classmethod
def derive_bip32_privkey(cls, master_key, path):
@ -426,7 +426,7 @@ class BTC_Watchonly_P2SH_P2WPKH(BTC_P2SH_P2WPKH):
@classmethod
def derive_bip32_pub_export(cls, master_key, path):
return super(BTC_Watchonly_P2SH_P2WPKH, cls).derive_bip32_pub_export(
return super(BTC_Watchonly_P2WPKH, cls).derive_bip32_pub_export(
master_key, BTC_Watchonly_Timelocked_P2WSH.get_watchonly_path(path))
@classmethod
@ -440,5 +440,5 @@ ENGINES = {
TYPE_P2WPKH: BTC_P2WPKH,
TYPE_TIMELOCK_P2WSH: BTC_Timelocked_P2WSH,
TYPE_WATCHONLY_TIMELOCK_P2WSH: BTC_Watchonly_Timelocked_P2WSH,
TYPE_WATCHONLY_P2SH_P2WPKH: BTC_Watchonly_P2SH_P2WPKH
TYPE_WATCHONLY_P2WPKH: BTC_Watchonly_P2WPKH
}

20
jmclient/jmclient/wallet.py

@ -25,8 +25,8 @@ from .blockchaininterface import INF_HEIGHT
from .support import select_gradual, select_greedy, select_greediest, \
select
from .cryptoengine import TYPE_P2PKH, TYPE_P2SH_P2WPKH,\
TYPE_P2WPKH, TYPE_TIMELOCK_P2WSH, TYPE_SEGWIT_LEGACY_WALLET_FIDELITY_BONDS,\
TYPE_WATCHONLY_FIDELITY_BONDS, TYPE_WATCHONLY_TIMELOCK_P2WSH, TYPE_WATCHONLY_P2SH_P2WPKH,\
TYPE_P2WPKH, TYPE_TIMELOCK_P2WSH, TYPE_SEGWIT_WALLET_FIDELITY_BONDS,\
TYPE_WATCHONLY_FIDELITY_BONDS, TYPE_WATCHONLY_TIMELOCK_P2WSH, TYPE_WATCHONLY_P2WPKH,\
ENGINES
from .support import get_random_bytes
from . import mn_encode, mn_decode
@ -405,10 +405,10 @@ class BaseWallet(object):
"""
if self.TYPE == TYPE_P2PKH:
return 'p2pkh'
elif self.TYPE in (TYPE_P2SH_P2WPKH,
TYPE_SEGWIT_LEGACY_WALLET_FIDELITY_BONDS):
elif self.TYPE == TYPE_P2SH_P2WPKH:
return 'p2sh-p2wpkh'
elif self.TYPE == TYPE_P2WPKH:
elif self.TYPE in (TYPE_P2WPKH,
TYPE_SEGWIT_WALLET_FIDELITY_BONDS):
return 'p2wpkh'
assert False
@ -2414,13 +2414,13 @@ class SegwitLegacyWallet(ImportWalletMixin, BIP39WalletMixin, PSBTWalletMixin, S
class SegwitWallet(ImportWalletMixin, BIP39WalletMixin, PSBTWalletMixin, SNICKERWalletMixin, BIP84Wallet):
TYPE = TYPE_P2WPKH
class SegwitLegacyWalletFidelityBonds(FidelityBondMixin, SegwitLegacyWallet):
TYPE = TYPE_SEGWIT_LEGACY_WALLET_FIDELITY_BONDS
class SegwitWalletFidelityBonds(FidelityBondMixin, SegwitWallet):
TYPE = TYPE_SEGWIT_WALLET_FIDELITY_BONDS
class FidelityBondWatchonlyWallet(FidelityBondMixin, BIP49Wallet):
class FidelityBondWatchonlyWallet(FidelityBondMixin, BIP84Wallet):
TYPE = TYPE_WATCHONLY_FIDELITY_BONDS
_ENGINE = ENGINES[TYPE_WATCHONLY_P2SH_P2WPKH]
_ENGINE = ENGINES[TYPE_WATCHONLY_P2WPKH]
_TIMELOCK_ENGINE = ENGINES[TYPE_WATCHONLY_TIMELOCK_P2WSH]
@classmethod
@ -2440,6 +2440,6 @@ WALLET_IMPLEMENTATIONS = {
LegacyWallet.TYPE: LegacyWallet,
SegwitLegacyWallet.TYPE: SegwitLegacyWallet,
SegwitWallet.TYPE: SegwitWallet,
SegwitLegacyWalletFidelityBonds.TYPE: SegwitLegacyWalletFidelityBonds,
SegwitWalletFidelityBonds.TYPE: SegwitWalletFidelityBonds,
FidelityBondWatchonlyWallet.TYPE: FidelityBondWatchonlyWallet
}

6
jmclient/jmclient/wallet_utils.py

@ -21,7 +21,7 @@ from jmbase.support import (get_password, jmprint, EXIT_FAILURE,
IndentedHelpFormatterWithNL)
from .cryptoengine import TYPE_P2PKH, TYPE_P2SH_P2WPKH, TYPE_P2WPKH, \
TYPE_SEGWIT_LEGACY_WALLET_FIDELITY_BONDS
TYPE_SEGWIT_WALLET_FIDELITY_BONDS
from .output import fmt_utxo
import jmbitcoin as btc
@ -1296,8 +1296,8 @@ def get_configured_wallet_type(support_fidelity_bonds):
if not support_fidelity_bonds:
return configured_type
if configured_type == TYPE_P2SH_P2WPKH:
return TYPE_SEGWIT_LEGACY_WALLET_FIDELITY_BONDS
if configured_type == TYPE_P2WPKH:
return TYPE_SEGWIT_WALLET_FIDELITY_BONDS
else:
raise ValueError("Fidelity bonds not supported with the configured "
"options of segwit and native. Edit joinmarket.cfg")

44
jmclient/test/test_wallet.py

@ -11,7 +11,7 @@ from jmbase import get_log, hextobin
from jmclient import load_test_config, jm_single, BaseWallet, \
SegwitLegacyWallet,BIP32Wallet, BIP49Wallet, LegacyWallet,\
VolatileStorage, get_network, cryptoengine, WalletError,\
SegwitWallet, WalletService, SegwitLegacyWalletFidelityBonds,\
SegwitWallet, WalletService, SegwitWalletFidelityBonds,\
create_wallet, open_test_wallet_maybe, \
FidelityBondMixin, FidelityBondWatchonlyWallet, wallet_gettimelockaddress
from test_blockchaininterface import sync_test_wallet
@ -243,19 +243,19 @@ def test_bip32_addresses_p2sh_p2wpkh(setup_wallet, mixdepth, internal, index, ad
assert address == wallet.get_addr(mixdepth, internal, index)
@pytest.mark.parametrize('index,timenumber,address,wif', [
[0, 0, 'bcrt1qndcqwedwa4lu77ryqpvp738d6p034a2fv8mufw3pw5smfcn39sgqpesn76', 'cST4g5R3mKp44K4J8PRVyys4XJu6EFavZyssq67PJKCnbhjdEdBY'],
[0, 50, 'bcrt1q73zhrfcu0ttkk4er9esrmvnpl6wpzhny5aly97jj9nw52agf8ncqjv8rda', 'cST4g5R3mKp44K4J8PRVyys4XJu6EFavZyssq67PJKCnbhjdEdBY'],
[5, 0, 'bcrt1qz5208jdm6399ja309ra28d0a34qlt0859u77uxc94v5mgk7auhtssau4pw', 'cRnUaBYTmyZURPe72YCrtvgxpBMvLKPZaCoXvKuWRPMryeJeAZx2'],
[9, 1, 'bcrt1qa7pd6qnadpmlm29vtvqnykalc34tr33eclaz7eeqal59n4gwr28qwnka2r', 'cQCxEPCWMwXVB16zCikDBTXMUccx6ioHQipPhYEp1euihkJUafyD']
[0, 0, 'bcrt1qgysu2eynn6klarz200ctgev7gqhhp7hwsdaaec3c7h0ltmc3r68q87c2d3', 'cVASAS6bpC5yctGmnsKaDz7D8CxEwccUtpjSNBQzeV2fw8ox8RR9'],
[0, 50, 'bcrt1qyrdhyqzj87vq20e853x7gzhx9lp8ta6cd8mwp8haqex8r4vrg2wsf7rcxm', 'cVASAS6bpC5yctGmnsKaDz7D8CxEwccUtpjSNBQzeV2fw8ox8RR9'],
[5, 0, 'bcrt1quunmmsudhpsuksa2ke8m6aj7757mst966mqq50nckx9wdrs4y6fs9gjuww', 'cUgT5jRjYi6i8Fc7TirJrrvhbs7ceSqJ6USKboVrLYghJKDzEQHQ'],
[9, 1, 'bcrt1qvpgmrn5a7yc0h2j6fp8jhtwzd8eetlt7hsu3cn098qftzp4t2h6sp5p35p', 'cW7H2pv6Rr5NWaTAnDC6r7bviHwDsAwyqh4XdZTE4xf2H2DB2hmb']
])
def test_bip32_timelocked_addresses(setup_wallet, index, timenumber, address, wif):
jm_single().config.set('BLOCKCHAIN', 'network', 'testnet')
entropy = unhexlify('2e0339ba89b4a1272cdf78b27ee62669ee01992a59e836e2807051be128ca817')
storage = VolatileStorage()
SegwitLegacyWalletFidelityBonds.initialize(
SegwitWalletFidelityBonds.initialize(
storage, get_network(), entropy=entropy, max_mixdepth=1)
wallet = SegwitLegacyWalletFidelityBonds(storage)
wallet = SegwitWalletFidelityBonds(storage)
mixdepth = FidelityBondMixin.FIDELITY_BOND_MIXDEPTH
address_type = FidelityBondMixin.BIP32_TIMELOCK_ID
@ -274,8 +274,8 @@ def test_bip32_timelocked_addresses(setup_wallet, index, timenumber, address, wi
])
def test_gettimelockaddress_method(setup_wallet, timenumber, locktime_string):
storage = VolatileStorage()
SegwitLegacyWalletFidelityBonds.initialize(storage, get_network())
wallet = SegwitLegacyWalletFidelityBonds(storage)
SegwitWalletFidelityBonds.initialize(storage, get_network())
wallet = SegwitWalletFidelityBonds(storage)
m = FidelityBondMixin.FIDELITY_BOND_MIXDEPTH
address_type = FidelityBondMixin.BIP32_TIMELOCK_ID
@ -289,18 +289,18 @@ def test_gettimelockaddress_method(setup_wallet, timenumber, locktime_string):
assert addr == addr_from_method
@pytest.mark.parametrize('index,wif', [
[0, 'cMg9eH3fW2JDSyggvXucjmECRwiheCMDo2Qik8y1keeYaxynzrYa'],
[9, 'cURA1Qgxhd7QnhhwxCnCHD4pZddVrJdu2BkTdzNaTp9owRSkUvPy'],
[50, 'cRTaHZ1eezb8s6xsT2V7EAevYToQMi7cxQD9vgFZzaJZDfhMhf3c']
[0, 'cVQbz7DB5JQ1TGsg9Dbm32VtJbXBHaj39Yc9QLkaGpRgXcibHTDH'],
[9, 'cULqe2sYZ4z8jZTGybr2Bzf4EyiT5Ts6wAE3mvCUofRuTVsofR8N'],
[50, 'cQNp7cQbrwjWuxmbkZF8ax9ogmTuWp3Ykb9LEpainhRTJXYc8Deu']
])
def test_bip32_burn_keys(setup_wallet, index, wif):
jm_single().config.set('BLOCKCHAIN', 'network', 'testnet')
entropy = unhexlify('2e0339ba89b4a1272cdf78b27ee62669ee01992a59e836e2807051be128ca817')
storage = VolatileStorage()
SegwitLegacyWalletFidelityBonds.initialize(
SegwitWalletFidelityBonds.initialize(
storage, get_network(), entropy=entropy, max_mixdepth=1)
wallet = SegwitLegacyWalletFidelityBonds(storage)
wallet = SegwitWalletFidelityBonds(storage)
mixdepth = FidelityBondMixin.FIDELITY_BOND_MIXDEPTH
address_type = FidelityBondMixin.BIP32_BURN_ID
@ -402,8 +402,8 @@ def test_timelocked_output_signing(setup_wallet):
jm_single().config.set('BLOCKCHAIN', 'network', 'testnet')
ensure_bip65_activated()
storage = VolatileStorage()
SegwitLegacyWalletFidelityBonds.initialize(storage, get_network())
wallet = SegwitLegacyWalletFidelityBonds(storage)
SegwitWalletFidelityBonds.initialize(storage, get_network())
wallet = SegwitWalletFidelityBonds(storage)
index = 0
timenumber = 0
@ -787,14 +787,14 @@ def test_wallet_mixdepth_decrease(setup_wallet):
def test_watchonly_wallet(setup_wallet):
jm_single().config.set('BLOCKCHAIN', 'network', 'testnet')
storage = VolatileStorage()
SegwitLegacyWalletFidelityBonds.initialize(storage, get_network())
wallet = SegwitLegacyWalletFidelityBonds(storage)
SegwitWalletFidelityBonds.initialize(storage, get_network())
wallet = SegwitWalletFidelityBonds(storage)
paths = [
"m/49'/1'/0'/0/0",
"m/49'/1'/0'/1/0",
"m/49'/1'/0'/2/0:1577836800",
"m/49'/1'/0'/2/0:2314051200"
"m/84'/1'/0'/0/0",
"m/84'/1'/0'/1/0",
"m/84'/1'/0'/2/0:1577836800",
"m/84'/1'/0'/2/0:2314051200"
]
burn_path = "m/49'/1'/0'/3/0"

Loading…
Cancel
Save