electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 0438bbc2c26d32ec17c76a0c8f1beb69255142f2
parent 05e5ef16eb0b11f580ded5ad5501316888f97d26
Author: SomberNight <somber.night@protonmail.com>
Date:   Thu, 14 Jun 2018 20:13:04 +0200

transaction.py: change update_signatures API. fix trezor segwit signing.

Traceback (most recent call last):
  File "...\electrum\lib\transaction.py", line 498, in parse_witness
    if txin['witness_version'] != 0:
KeyError: 'witness_version'

Diffstat:
Mlib/tests/test_transaction.py | 5+++--
Mlib/transaction.py | 16++++++----------
Mplugins/keepkey/keepkey.py | 6+++---
Mplugins/trezor/trezor.py | 6+++---
4 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/lib/tests/test_transaction.py b/lib/tests/test_transaction.py @@ -13,6 +13,7 @@ signed_blob = '01000000012a5c9a94fcde98f5581cd00162c60a13936ceb75389ea65bf38633b v2_blob = "0200000001191601a44a81e061502b7bfbc6eaa1cef6d1e6af5308ef96c9342f71dbf4b9b5000000006b483045022100a6d44d0a651790a477e75334adfb8aae94d6612d01187b2c02526e340a7fd6c8022028bdf7a64a54906b13b145cd5dab21a26bd4b85d6044e9b97bceab5be44c2a9201210253e8e0254b0c95776786e40984c1aa32a7d03efa6bdacdea5f421b774917d346feffffff026b20fa04000000001976a914024db2e87dd7cfd0e5f266c5f212e21a31d805a588aca0860100000000001976a91421919b94ae5cefcdf0271191459157cdb41c4cbf88aca6240700" signed_segwit_blob = "01000000000101b66d722484f2db63e827ebf41d02684fed0c6550e85015a6c9d41ef216a8a6f00000000000fdffffff0280c3c90100000000160014b65ce60857f7e7892b983851c2a8e3526d09e4ab64bac30400000000160014c478ebbc0ab2097706a98e10db7cf101839931c4024730440220789c7d47f876638c58d98733c30ae9821c8fa82b470285dcdf6db5994210bf9f02204163418bbc44af701212ad42d884cc613f3d3d831d2d0cc886f767cca6e0235e012103083a6dc250816d771faa60737bfe78b23ad619f6b458e0a1f1688e3a0605e79c00000000" +signed_blob_signatures = ['3046022100a82bbc57a0136751e5433f41cf000b3f1a99c6744775e76ec764fb78c54ee100022100f9e80b7de89de861dc6fb0c1429d5da72c2b6b2ee2406bc9bfb1beedd729d98501', ] class TestBCDataStream(SequentialTestCase): @@ -96,7 +97,7 @@ class TestTransaction(SequentialTestCase): self.assertEqual(tx.serialize(), unsigned_blob) - tx.update_signatures(signed_blob) + tx.update_signatures(signed_blob_signatures) self.assertEqual(tx.raw, signed_blob) tx.update(unsigned_blob) @@ -132,7 +133,7 @@ class TestTransaction(SequentialTestCase): self.assertEqual(tx.serialize(), signed_blob) - tx.update_signatures(signed_blob) + tx.update_signatures(signed_blob_signatures) self.assertEqual(tx.estimated_total_size(), 193) self.assertEqual(tx.estimated_base_size(), 193) diff --git a/lib/transaction.py b/lib/transaction.py @@ -545,7 +545,7 @@ def parse_output(vds, i): return d -def deserialize(raw: str, force_full_parse=False) -> dict: +def deserialize(raw: str) -> dict: raw_bytes = bfh(raw) d = {} if raw_bytes[:5] == PARTIAL_TXN_HEADER_MAGIC: @@ -557,7 +557,6 @@ def deserialize(raw: str, force_full_parse=False) -> dict: raw_bytes = raw_bytes[6:] else: d['partial'] = is_partial = False - full_parse = force_full_parse or is_partial vds = BCDataStream() vds.write(raw_bytes) d['version'] = vds.read_int32() @@ -569,13 +568,13 @@ def deserialize(raw: str, force_full_parse=False) -> dict: raise ValueError('invalid txn marker byte: {}'.format(marker)) n_vin = vds.read_compact_size() d['segwit_ser'] = is_segwit - d['inputs'] = [parse_input(vds, full_parse=full_parse) for i in range(n_vin)] + d['inputs'] = [parse_input(vds, full_parse=is_partial) for i in range(n_vin)] n_vout = vds.read_compact_size() d['outputs'] = [parse_output(vds, i) for i in range(n_vout)] if is_segwit: for i in range(n_vin): txin = d['inputs'][i] - parse_witness(vds, txin, full_parse=full_parse) + parse_witness(vds, txin, full_parse=is_partial) d['lockTime'] = vds.read_uint32() if vds.can_read_more(): raise SerializationError('extra junk at the end') @@ -652,17 +651,14 @@ class Transaction: txin['x_pubkeys'] = x_pubkeys = list(x_pubkeys) return pubkeys, x_pubkeys - def update_signatures(self, raw): + def update_signatures(self, signatures: Sequence[str]): """Add new signatures to a transaction""" if self.is_complete(): return - d = deserialize(raw, force_full_parse=True) for i, txin in enumerate(self.inputs()): pubkeys, x_pubkeys = self.get_sorted_pubkeys(txin) - sigs1 = txin.get('signatures') - sigs2 = d['inputs'][i].get('signatures') - for sig in sigs2: - if sig in sigs1: + for sig in signatures: + if sig in txin.get('signatures'): continue pre_hash = Hash(bfh(self.serialize_preimage(i))) sig_string = ecc.sig_string_from_der_sig(bfh(sig[:-2])) diff --git a/plugins/keepkey/keepkey.py b/plugins/keepkey/keepkey.py @@ -258,9 +258,9 @@ class KeepKeyPlugin(HW_PluginBase): client = self.get_client(keystore) inputs = self.tx_inputs(tx, True, keystore.is_segwit()) outputs = self.tx_outputs(keystore.get_derivation(), tx, keystore.is_segwit()) - signed_tx = client.sign_tx(self.get_coin_name(), inputs, outputs, lock_time=tx.locktime)[1] - raw = bh2u(signed_tx) - tx.update_signatures(raw) + signatures = client.sign_tx(self.get_coin_name(), inputs, outputs, lock_time=tx.locktime)[0] + signatures = [(bh2u(x) + '01') for x in signatures] + tx.update_signatures(signatures) def show_address(self, wallet, address, keystore=None): if keystore is None: diff --git a/plugins/trezor/trezor.py b/plugins/trezor/trezor.py @@ -318,9 +318,9 @@ class TrezorPlugin(HW_PluginBase): client = self.get_client(keystore) inputs = self.tx_inputs(tx, True, keystore.get_script_gen()) outputs = self.tx_outputs(keystore.get_derivation(), tx, keystore.get_script_gen()) - signed_tx = client.sign_tx(self.get_coin_name(), inputs, outputs, lock_time=tx.locktime)[1] - raw = bh2u(signed_tx) - tx.update_signatures(raw) + signatures = client.sign_tx(self.get_coin_name(), inputs, outputs, lock_time=tx.locktime)[0] + signatures = [(bh2u(x) + '01') for x in signatures] + tx.update_signatures(signatures) def show_address(self, wallet, address, keystore=None): if keystore is None: