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_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,
which spends from a witness,
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):
# return serialize(segwit_signature_form(deserialize(txobj), i, script,
# amount, hashcode))
script = binascii.unhexlify(script)
script = decoder_func(script)
nVersion = encode(txobj["version"], 256, 4)[::-1]
#create hashPrevouts
if hashcode & SIGHASH_ANYONECANPAY:
@ -195,7 +196,7 @@ def segwit_signature_form(txobj, i, script, amount, hashcode=SIGHASH_ALL):
else:
pi = ""
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]
hashPrevouts = bin_dbl_sha256(pi)
#create hashSequence
@ -208,7 +209,7 @@ def segwit_signature_form(txobj, i, script, amount, hashcode=SIGHASH_ALL):
else:
hashSequence = "\x00"*32
#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]
scriptCode = num_to_var_int(len(script)) + script
amt = encode(amount, 256, 8)[::-1]
@ -218,13 +219,13 @@ def segwit_signature_form(txobj, i, script, amount, hashcode=SIGHASH_ALL):
pi = ""
for out in txobj["outs"]:
pi += encode(out["value"], 256, 8)[::-1]
pi += (num_to_var_int(len(binascii.unhexlify(out["script"]))) + \
binascii.unhexlify(out["script"]))
pi += (num_to_var_int(len(decoder_func(out["script"]))) + \
decoder_func(out["script"]))
hashOutputs = bin_dbl_sha256(pi)
elif hashcode & 0x1f == SIGHASH_SINGLE and i < len(txobj['outs']):
pi = encode(txobj["outs"][i]["value"], 256, 8)[::-1]
pi += (num_to_var_int(len(binascii.unhexlify(txobj["outs"][i]["script"]))) +
binascii.unhexlify(txobj["outs"][i]["script"]))
pi += (num_to_var_int(len(decoder_func(txobj["outs"][i]["script"]))) +
decoder_func(txobj["outs"][i]["script"]))
hashOutputs = bin_dbl_sha256(pi)
else:
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,
cheapest_order_choose, weighted_order_choose,
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 .old_mnemonic import mn_decode, mn_encode
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, get_wallet_cls)
from .wallet import (estimate_tx_fee, WalletError, BaseWallet, ImportWalletMixin,
BIP39WalletMixin, BIP32Wallet, BIP49Wallet, LegacyWallet,
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,
jm_single, get_network, validate_address, get_irc_mchannels,
get_blockchain_interface_instance, get_p2sh_vbyte, set_config)

5
jmclient/jmclient/client_protocol.py

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

13
jmclient/jmclient/support.py

@ -1,9 +1,5 @@
from __future__ import absolute_import, print_function
import sys
import logging
import pprint
import random
from jmbase.support import get_log
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):
# use normalvariate instead of gauss for thread safety
return [random.normalvariate(mu, sigma) for _ in range(n)]

11
jmclient/jmclient/taker_utils.py

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

41
scripts/sendpayment.py

@ -17,14 +17,12 @@ import time
import os
import pprint
from jmclient import (Taker, load_program_config, get_schedule,
JMClientProtocolFactory, start_reactor,
validate_address, jm_single, WalletError,
choose_orders, choose_sweep_orders,
cheapest_order_choose, weighted_order_choose,
sync_wallet, RegtestBitcoinCoreInterface,
estimate_tx_fee, direct_send, get_wallet_cls,
BitcoinCoreWallet)
from jmclient import (
Taker, load_program_config, get_schedule, JMClientProtocolFactory,
start_reactor, validate_address, jm_single, WalletError, choose_orders,
choose_sweep_orders, cheapest_order_choose, weighted_order_choose,
sync_wallet, RegtestBitcoinCoreInterface, estimate_tx_fee, direct_send,
open_test_wallet_maybe, get_wallet_path)
from twisted.python.log import startLogging
from jmbase.support import get_log, debug_dump_object, get_password
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);
#to ensure we have enough, must be at least (requested index+1)
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)
else:
while True:
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
wallet_path = get_wallet_path(wallet_name, None)
wallet = open_test_wallet_maybe(
wallet_path, wallet_name, max_mix_depth, gap_limit=options.gaplimit)
else:
wallet = BitcoinCoreWallet(fromaccount=wallet_name)
raise NotImplemented("Using non-joinmarket wallet is not supported.")
if jm_single().config.get("BLOCKCHAIN",
"blockchain_source") == "electrum-server" and options.makercount != 0:
jm_single().bc_interface.synctype = "with-script"
#wallet sync will now only occur on reactor start if we're joining.
sync_wallet(wallet, fast=options.fastsync)
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)
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):
orders, total_cj_fee = orders_fees
log.info("Chose these orders: " +pprint.pformat(orders))

Loading…
Cancel
Save