Browse Source

replace old wallet implementation with new one

master
undeath 8 years ago
parent
commit
995c123eec
  1. 17
      jmbitcoin/jmbitcoin/secp256k1_transaction.py
  2. 12
      jmclient/jmclient/__init__.py
  3. 5
      jmclient/jmclient/client_protocol.py
  4. 13
      jmclient/jmclient/support.py
  5. 11
      jmclient/jmclient/taker_utils.py
  6. 41
      scripts/sendpayment.py

17
jmbitcoin/jmbitcoin/secp256k1_transaction.py

@ -178,7 +178,8 @@ SIGHASH_NONE = 2
SIGHASH_SINGLE = 3 SIGHASH_SINGLE = 3
SIGHASH_ANYONECANPAY = 0x80 SIGHASH_ANYONECANPAY = 0x80
def segwit_signature_form(txobj, i, script, amount, hashcode=SIGHASH_ALL): def segwit_signature_form(txobj, i, script, amount, hashcode=SIGHASH_ALL,
decoder_func=binascii.unhexlify):
"""Given a deserialized transaction txobj, an input index i, """Given a deserialized transaction txobj, an input index i,
which spends from a witness, which spends from a witness,
a script for redemption and an amount in satoshis, prepare a script for redemption and an amount in satoshis, prepare
@ -187,7 +188,7 @@ def segwit_signature_form(txobj, i, script, amount, hashcode=SIGHASH_ALL):
#if isinstance(txobj, string_or_bytes_types): #if isinstance(txobj, string_or_bytes_types):
# return serialize(segwit_signature_form(deserialize(txobj), i, script, # return serialize(segwit_signature_form(deserialize(txobj), i, script,
# amount, hashcode)) # amount, hashcode))
script = binascii.unhexlify(script) script = decoder_func(script)
nVersion = encode(txobj["version"], 256, 4)[::-1] nVersion = encode(txobj["version"], 256, 4)[::-1]
#create hashPrevouts #create hashPrevouts
if hashcode & SIGHASH_ANYONECANPAY: if hashcode & SIGHASH_ANYONECANPAY:
@ -195,7 +196,7 @@ def segwit_signature_form(txobj, i, script, amount, hashcode=SIGHASH_ALL):
else: else:
pi = "" pi = ""
for inp in txobj["ins"]: for inp in txobj["ins"]:
pi += binascii.unhexlify(inp["outpoint"]["hash"])[::-1] pi += decoder_func(inp["outpoint"]["hash"])[::-1]
pi += encode(inp["outpoint"]["index"], 256, 4)[::-1] pi += encode(inp["outpoint"]["index"], 256, 4)[::-1]
hashPrevouts = bin_dbl_sha256(pi) hashPrevouts = bin_dbl_sha256(pi)
#create hashSequence #create hashSequence
@ -208,7 +209,7 @@ def segwit_signature_form(txobj, i, script, amount, hashcode=SIGHASH_ALL):
else: else:
hashSequence = "\x00"*32 hashSequence = "\x00"*32
#add this input's outpoint #add this input's outpoint
thisOut = binascii.unhexlify(txobj["ins"][i]["outpoint"]["hash"])[::-1] thisOut = decoder_func(txobj["ins"][i]["outpoint"]["hash"])[::-1]
thisOut += encode(txobj["ins"][i]["outpoint"]["index"], 256, 4)[::-1] thisOut += encode(txobj["ins"][i]["outpoint"]["index"], 256, 4)[::-1]
scriptCode = num_to_var_int(len(script)) + script scriptCode = num_to_var_int(len(script)) + script
amt = encode(amount, 256, 8)[::-1] amt = encode(amount, 256, 8)[::-1]
@ -218,13 +219,13 @@ def segwit_signature_form(txobj, i, script, amount, hashcode=SIGHASH_ALL):
pi = "" pi = ""
for out in txobj["outs"]: for out in txobj["outs"]:
pi += encode(out["value"], 256, 8)[::-1] pi += encode(out["value"], 256, 8)[::-1]
pi += (num_to_var_int(len(binascii.unhexlify(out["script"]))) + \ pi += (num_to_var_int(len(decoder_func(out["script"]))) + \
binascii.unhexlify(out["script"])) decoder_func(out["script"]))
hashOutputs = bin_dbl_sha256(pi) hashOutputs = bin_dbl_sha256(pi)
elif hashcode & 0x1f == SIGHASH_SINGLE and i < len(txobj['outs']): elif hashcode & 0x1f == SIGHASH_SINGLE and i < len(txobj['outs']):
pi = encode(txobj["outs"][i]["value"], 256, 8)[::-1] pi = encode(txobj["outs"][i]["value"], 256, 8)[::-1]
pi += (num_to_var_int(len(binascii.unhexlify(txobj["outs"][i]["script"]))) + pi += (num_to_var_int(len(decoder_func(txobj["outs"][i]["script"]))) +
binascii.unhexlify(txobj["outs"][i]["script"])) decoder_func(txobj["outs"][i]["script"]))
hashOutputs = bin_dbl_sha256(pi) hashOutputs = bin_dbl_sha256(pi)
else: else:
hashOutputs = "\x00"*32 hashOutputs = "\x00"*32

12
jmclient/jmclient/__init__.py

@ -11,14 +11,18 @@ from btc import *
from .support import (calc_cj_fee, choose_sweep_orders, choose_orders, from .support import (calc_cj_fee, choose_sweep_orders, choose_orders,
cheapest_order_choose, weighted_order_choose, cheapest_order_choose, weighted_order_choose,
rand_norm_array, rand_pow_array, rand_exp_array, select, rand_norm_array, rand_pow_array, rand_exp_array, select,
select_gradual, select_greedy, select_greediest) select_gradual, select_greedy, select_greediest,
get_random_bytes)
from .jsonrpc import JsonRpcError, JsonRpcConnectionError, JsonRpc from .jsonrpc import JsonRpcError, JsonRpcConnectionError, JsonRpc
from .old_mnemonic import mn_decode, mn_encode from .old_mnemonic import mn_decode, mn_encode
from .slowaes import decryptData, encryptData from .slowaes import decryptData, encryptData
from .taker import Taker from .taker import Taker
from .wallet import (AbstractWallet, BitcoinCoreInterface, Wallet, from .wallet import (estimate_tx_fee, WalletError, BaseWallet, ImportWalletMixin,
BitcoinCoreWallet, estimate_tx_fee, WalletError, BIP39WalletMixin, BIP32Wallet, BIP49Wallet, LegacyWallet,
create_wallet_file, SegwitWallet, Bip39Wallet, get_wallet_cls) SegwitLegacyWallet, UTXOManager, WALLET_IMPLEMENTATIONS)
from .storage import (Argon2Hash, Storage, StorageError,
StoragePasswordError, VolatileStorage)
from .cryptoengine import BTCEngine, BTC_P2PKH, BTC_P2SH_P2WPKH, EngineError
from .configure import (load_program_config, get_p2pk_vbyte, from .configure import (load_program_config, get_p2pk_vbyte,
jm_single, get_network, validate_address, get_irc_mchannels, jm_single, get_network, validate_address, get_irc_mchannels,
get_blockchain_interface_instance, get_p2sh_vbyte, set_config) get_blockchain_interface_instance, get_p2sh_vbyte, set_config)

5
jmclient/jmclient/client_protocol.py

@ -16,9 +16,8 @@ import hashlib
import os import os
import sys import sys
import pprint import pprint
from jmclient import (Taker, Wallet, jm_single, get_irc_mchannels, from jmclient import (jm_single, get_irc_mchannels, get_log, get_p2sh_vbyte,
load_program_config, get_log, get_p2sh_vbyte, RegtestBitcoinCoreInterface)
RegtestBitcoinCoreInterface)
from jmbase import _byteify from jmbase import _byteify
import btc import btc

13
jmclient/jmclient/support.py

@ -1,9 +1,5 @@
from __future__ import absolute_import, print_function from __future__ import absolute_import, print_function
import sys
import logging
import pprint
import random import random
from jmbase.support import get_log from jmbase.support import get_log
from decimal import Decimal from decimal import Decimal
@ -23,6 +19,15 @@ Only for sampling purposes
""" """
def get_random_bytes(num_bytes, cryptographically_secure=False):
if cryptographically_secure:
# uses os.urandom if available
generator = random.SystemRandom()
else:
generator = random
return bytes(bytearray((generator.randrange(256) for b in xrange(num_bytes))))
def rand_norm_array(mu, sigma, n): def rand_norm_array(mu, sigma, n):
# use normalvariate instead of gauss for thread safety # use normalvariate instead of gauss for thread safety
return [random.normalvariate(mu, sigma) for _ in range(n)] return [random.normalvariate(mu, sigma) for _ in range(n)]

11
jmclient/jmclient/taker_utils.py

@ -7,7 +7,7 @@ import time
import numbers import numbers
from .configure import get_log, jm_single, validate_address from .configure import get_log, jm_single, validate_address
from .schedule import human_readable_schedule_entry, tweak_tumble_schedule from .schedule import human_readable_schedule_entry, tweak_tumble_schedule
from .wallet import Wallet, SegwitWallet, estimate_tx_fee from .wallet import BaseWallet, estimate_tx_fee
from jmclient import mktx, deserialize, sign, txhash from jmclient import mktx, deserialize, sign, txhash
log = get_log() log = get_log()
@ -42,10 +42,10 @@ def direct_send(wallet, amount, mixdepth, destaddr, answeryes=False,
assert mixdepth >= 0 assert mixdepth >= 0
assert isinstance(amount, numbers.Integral) assert isinstance(amount, numbers.Integral)
assert amount >=0 assert amount >=0
assert isinstance(wallet, Wallet) or isinstance(wallet, SegwitWallet) assert isinstance(wallet, BaseWallet)
from pprint import pformat from pprint import pformat
txtype = 'p2sh-p2wpkh' if isinstance(wallet, SegwitWallet) else 'p2pkh' txtype = wallet.get_txtype()
if amount == 0: if amount == 0:
utxos = wallet.get_utxos_by_mixdepth()[mixdepth] utxos = wallet.get_utxos_by_mixdepth()[mixdepth]
if utxos == {}: if utxos == {}:
@ -79,9 +79,8 @@ def direct_send(wallet, amount, mixdepth, destaddr, answeryes=False,
utxo = ins['outpoint']['hash'] + ':' + str( utxo = ins['outpoint']['hash'] + ':' + str(
ins['outpoint']['index']) ins['outpoint']['index'])
addr = utxos[utxo]['address'] addr = utxos[utxo]['address']
signing_amount = utxos[utxo]['value'] amount = utxos[utxo]['value']
amt = signing_amount if isinstance(wallet, SegwitWallet) else None tx = sign(tx, index, wallet.get_key_from_addr(addr), amount=amount)
tx = sign(tx, index, wallet.get_key_from_addr(addr), amount=amt)
txsigned = deserialize(tx) txsigned = deserialize(tx)
log.info("Got signed transaction:\n") log.info("Got signed transaction:\n")
log.info(tx + "\n") log.info(tx + "\n")

41
scripts/sendpayment.py

@ -17,14 +17,12 @@ import time
import os import os
import pprint import pprint
from jmclient import (Taker, load_program_config, get_schedule, from jmclient import (
JMClientProtocolFactory, start_reactor, Taker, load_program_config, get_schedule, JMClientProtocolFactory,
validate_address, jm_single, WalletError, start_reactor, validate_address, jm_single, WalletError, choose_orders,
choose_orders, choose_sweep_orders, choose_sweep_orders, cheapest_order_choose, weighted_order_choose,
cheapest_order_choose, weighted_order_choose, sync_wallet, RegtestBitcoinCoreInterface, estimate_tx_fee, direct_send,
sync_wallet, RegtestBitcoinCoreInterface, open_test_wallet_maybe, get_wallet_path)
estimate_tx_fee, direct_send, get_wallet_cls,
BitcoinCoreWallet)
from twisted.python.log import startLogging from twisted.python.log import startLogging
from jmbase.support import get_log, debug_dump_object, get_password from jmbase.support import get_log, debug_dump_object, get_password
from cli_options import get_sendpayment_parser from cli_options import get_sendpayment_parser
@ -126,33 +124,26 @@ def main():
#maxmixdepth in the wallet is actually the *number* of mixdepths (so misnamed); #maxmixdepth in the wallet is actually the *number* of mixdepths (so misnamed);
#to ensure we have enough, must be at least (requested index+1) #to ensure we have enough, must be at least (requested index+1)
max_mix_depth = max([mixdepth+1, options.amtmixdepths]) max_mix_depth = max([mixdepth+1, options.amtmixdepths])
if not os.path.exists(os.path.join('wallets', wallet_name)):
wallet = get_wallet_cls()(wallet_name, None, max_mix_depth, options.gaplimit) wallet_path = get_wallet_path(wallet_name, None)
else: wallet = open_test_wallet_maybe(
while True: wallet_path, wallet_name, max_mix_depth, gap_limit=options.gaplimit)
try:
pwd = get_password("Enter wallet decryption passphrase: ")
wallet = get_wallet_cls()(wallet_name, pwd, max_mix_depth, options.gaplimit)
except WalletError:
print("Wrong password, try again.")
continue
except Exception as e:
print("Failed to load wallet, error message: " + repr(e))
sys.exit(0)
break
else: else:
wallet = BitcoinCoreWallet(fromaccount=wallet_name) raise NotImplemented("Using non-joinmarket wallet is not supported.")
if jm_single().config.get("BLOCKCHAIN", if jm_single().config.get("BLOCKCHAIN",
"blockchain_source") == "electrum-server" and options.makercount != 0: "blockchain_source") == "electrum-server" and options.makercount != 0:
jm_single().bc_interface.synctype = "with-script" jm_single().bc_interface.synctype = "with-script"
#wallet sync will now only occur on reactor start if we're joining. #wallet sync will now only occur on reactor start if we're joining.
sync_wallet(wallet, fast=options.fastsync) sync_wallet(wallet, fast=options.fastsync)
if options.makercount == 0: if options.makercount == 0:
if isinstance(wallet, BitcoinCoreWallet):
raise NotImplementedError("Direct send only supported for JM wallets")
direct_send(wallet, amount, mixdepth, destaddr, options.answeryes) direct_send(wallet, amount, mixdepth, destaddr, options.answeryes)
return return
if wallet.get_txtype() == 'p2pkh':
print("Only direct sends (use -N 0) are supported for "
"legacy (non-segwit) wallets.")
return
def filter_orders_callback(orders_fees, cjamount): def filter_orders_callback(orders_fees, cjamount):
orders, total_cj_fee = orders_fees orders, total_cj_fee = orders_fees
log.info("Chose these orders: " +pprint.pformat(orders)) log.info("Chose these orders: " +pprint.pformat(orders))

Loading…
Cancel
Save