diff --git a/jmclient/jmclient/__init__.py b/jmclient/jmclient/__init__.py index 8e980c6..e285696 100644 --- a/jmclient/jmclient/__init__.py +++ b/jmclient/jmclient/__init__.py @@ -18,7 +18,7 @@ from .slowaes import decryptData, encryptData from .taker import Taker from .wallet import (AbstractWallet, BitcoinCoreInterface, Wallet, BitcoinCoreWallet, estimate_tx_fee, WalletError, - create_wallet_file, SegwitWallet, Bip39Wallet) + create_wallet_file, SegwitWallet, Bip39Wallet, get_wallet_cls) from .configure import (load_program_config, get_p2pk_vbyte, jm_single, get_network, validate_address, get_irc_mchannels, get_blockchain_interface_instance, get_p2sh_vbyte, set_config) diff --git a/jmclient/jmclient/maker.py b/jmclient/jmclient/maker.py index 773675c..38543d0 100644 --- a/jmclient/jmclient/maker.py +++ b/jmclient/jmclient/maker.py @@ -69,8 +69,7 @@ class Maker(object): if res[0]['value'] < reqd_amt: reason = "commitment utxo too small: " + str(res[0]['value']) return reject(reason) - if res[0]['address'] != btc.pubkey_to_p2sh_p2wpkh_address(cr_dict['P'], - self.wallet.get_vbyte()): + if res[0]['address'] != self.wallet.pubkey_to_address(cr_dict['P']): reason = "Invalid podle pubkey: " + str(cr_dict['P']) return reject(reason) @@ -147,7 +146,8 @@ class Maker(object): times_seen_cj_addr = 0 times_seen_change_addr = 0 for outs in txd['outs']: - addr = btc.script_to_address(outs['script'], get_p2sh_vbyte()) + #FIXME: the type of address should be detected from the script (p2pkh/p2sh) + addr = self.wallet.script_to_address(outs['script']) if addr == cjaddr: times_seen_cj_addr += 1 if outs['value'] != amount: diff --git a/jmclient/jmclient/wallet.py b/jmclient/jmclient/wallet.py index a48d6af..cb220d8 100644 --- a/jmclient/jmclient/wallet.py +++ b/jmclient/jmclient/wallet.py @@ -101,6 +101,10 @@ class AbstractWallet(object): """ return None + @classmethod + def pubkey_to_address(cls, pubkey): + return None + def update_cache_index(self): pass @@ -214,12 +218,17 @@ class Wallet(AbstractWallet): """ return btc.sign(tx, i, priv) - def script_to_address(self, script): + @classmethod + def script_to_address(cls, script): """Return the address for a given output script, which will be p2pkh for the default Wallet object, and reading the correct network byte from the config. """ - return btc.script_to_address(script, get_p2pk_vbyte()) + return btc.script_to_address(script, cls.get_vbyte()) + + @classmethod + def pubkey_to_address(cls, pubkey): + return btc.pubkey_to_address(pubkey, cls.get_vbyte()) def read_wallet_file_data(self, filename, pwd=None, wallet_dir=None): self.path = None @@ -385,8 +394,8 @@ class Wallet(AbstractWallet): self.spent_utxos += removed_utxos.keys() return removed_utxos - - def get_vbyte(self): + @staticmethod + def get_vbyte(): return get_p2pk_vbyte() def add_new_utxos(self, tx, txid): @@ -467,7 +476,8 @@ class SegwitWallet(Bip39Wallet): root = btc.bip32_ckd(pre_root, testnet_flag + 2**31) return [btc.bip32_ckd(root, c + 2**31) for c in range(self.max_mix_depth)] - def get_vbyte(self): + @staticmethod + def get_vbyte(): return get_p2sh_vbyte() def get_txtype(self): @@ -484,13 +494,18 @@ class SegwitWallet(Bip39Wallet): pub = btc.privtopub(self.get_key(mixing_depth, forchange, i)) return btc.pubkey_to_p2sh_p2wpkh_address(pub, magicbyte=self.get_vbyte()) - def script_to_address(self, script): + @classmethod + def script_to_address(cls, script): """Return the address for a given output script, which will be p2sh-p2wpkh for the segwit (currently). The underlying witness is however invisible at this layer; so it's just a p2sh address. """ - return btc.script_to_address(script, get_p2sh_vbyte()) + return btc.script_to_address(script, cls.get_vbyte()) + + @classmethod + def pubkey_to_address(cls, pubkey): + return btc.pubkey_to_p2sh_p2wpkh_address(pubkey, cls.get_vbyte()) def sign(self, tx, i, priv, amount): """Sign a transaction; the amount field @@ -551,3 +566,8 @@ class BitcoinCoreWallet(AbstractWallet): #pragma: no cover if exc.code != -14: raise exc # Wrong passphrase, try again. + +def get_wallet_cls(): + if jm_single().config.get("POLICY", "segwit") == "true": + return SegwitWallet + return Wallet diff --git a/jmclient/jmclient/wallet_utils.py b/jmclient/jmclient/wallet_utils.py index cb16f3e..de24ce7 100644 --- a/jmclient/jmclient/wallet_utils.py +++ b/jmclient/jmclient/wallet_utils.py @@ -9,10 +9,10 @@ from datetime import datetime from mnemonic import Mnemonic from optparse import OptionParser import getpass -from jmclient import (get_network, Wallet, Bip39Wallet, podle, +from jmclient import (get_network, get_wallet_cls, Bip39Wallet, podle, encryptData, get_p2sh_vbyte, get_p2pk_vbyte, jm_single, mn_decode, mn_encode, BitcoinCoreInterface, - JsonRpcError, sync_wallet, WalletError, SegwitWallet) + JsonRpcError, sync_wallet, WalletError) from jmbase.support import get_password import jmclient.btc as btc @@ -815,8 +815,6 @@ def wallet_tool_main(wallet_root_path): """ parser = get_wallettool_parser() (options, args) = parser.parse_args() - walletclass = SegwitWallet if jm_single().config.get( - "POLICY", "segwit") == "true" else Wallet # if the index_cache stored in wallet.json is longer than the default # then set maxmixdepth to the length of index_cache maxmixdepth_configured = True @@ -840,15 +838,15 @@ def wallet_tool_main(wallet_root_path): seed = args[0] method = ('display' if len(args) == 1 else args[1].lower()) if not os.path.exists(os.path.join(wallet_root_path, seed)): - wallet = walletclass(seed, None, options.maxmixdepth, - options.gaplimit, extend_mixdepth= not maxmixdepth_configured, - storepassword=(method == 'importprivkey'), - wallet_dir=wallet_root_path) + wallet = get_wallet_cls()(seed, None, options.maxmixdepth, + options.gaplimit, extend_mixdepth= not maxmixdepth_configured, + storepassword=(method == 'importprivkey'), + wallet_dir=wallet_root_path) else: while True: try: pwd = get_password("Enter wallet decryption passphrase: ") - wallet = walletclass(seed, pwd, + wallet = get_wallet_cls()(seed, pwd, options.maxmixdepth, options.gaplimit, extend_mixdepth=not maxmixdepth_configured, diff --git a/jmclient/jmclient/yieldgenerator.py b/jmclient/jmclient/yieldgenerator.py index df08851..72dc585 100644 --- a/jmclient/jmclient/yieldgenerator.py +++ b/jmclient/jmclient/yieldgenerator.py @@ -9,7 +9,7 @@ from twisted.python.log import startLogging from optparse import OptionParser from jmbase import get_password from jmclient import (Maker, jm_single, get_network, load_program_config, get_log, - SegwitWallet, sync_wallet, JMClientProtocolFactory, + get_wallet_cls, sync_wallet, JMClientProtocolFactory, start_reactor, calc_cj_fee, WalletError) jlog = get_log() @@ -87,13 +87,13 @@ class YieldGeneratorBasic(YieldGenerator): # print mix_balance max_mix = max(mix_balance, key=mix_balance.get) f = '0' - if self.ordertype == 'swreloffer': + if self.ordertype in ('reloffer', 'swreloffer'): f = self.cjfee_r #minimum size bumped if necessary such that you always profit #least 50% of the miner fee self.minsize = max(int(1.5 * self.txfee / float(self.cjfee_r)), self.minsize) - elif self.ordertype == 'swabsoffer': + elif self.ordertype in ('absoffer', 'swabsoffer'): f = str(self.txfee + self.cjfee_a) order = {'oid': 0, 'ordertype': self.ordertype, @@ -215,13 +215,13 @@ def ygmain(ygclass, txfee=1000, cjfee_a=200, cjfee_r=0.002, ordertype='swreloffe wallet_name = args[0] ordertype = options.ordertype txfee = options.txfee - if ordertype == 'swreloffer': + if ordertype in ('reloffer', 'swreloffer'): if options.cjfee != '': cjfee_r = options.cjfee # minimum size is such that you always net profit at least 20% #of the miner fee minsize = max(int(1.2 * txfee / float(cjfee_r)), options.minsize) - elif ordertype == 'swabsoffer': + elif ordertype in ('absoffer', 'swabsoffer'): if options.cjfee != '': cjfee_a = int(options.cjfee) minsize = options.minsize @@ -233,15 +233,15 @@ def ygmain(ygclass, txfee=1000, cjfee_a=200, cjfee_r=0.002, ordertype='swreloffe load_program_config() if not os.path.exists(os.path.join('wallets', wallet_name)): - wallet = SegwitWallet(wallet_name, None, max_mix_depth=MAX_MIX_DEPTH, - gaplimit=options.gaplimit) + wallet = get_wallet_cls()(wallet_name, None, max_mix_depth=MAX_MIX_DEPTH, + gaplimit=options.gaplimit) else: while True: try: pwd = get_password("Enter wallet decryption passphrase: ") - wallet = SegwitWallet(wallet_name, pwd, - max_mix_depth=MAX_MIX_DEPTH, - gaplimit=options.gaplimit) + wallet = get_wallet_cls()(wallet_name, pwd, + max_mix_depth=MAX_MIX_DEPTH, + gaplimit=options.gaplimit) except WalletError: print("Wrong password, try again.") continue