mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-29 16:31:29 +00:00
Merge pull request #5494 from SomberNight/tx_signing_perf_20190708
transaction: segwit input signing was doing quadratic hashing
This commit is contained in:
commit
261c492c37
1 changed files with 28 additions and 7 deletions
|
@ -86,6 +86,12 @@ class TxOutputHwInfo(NamedTuple):
|
||||||
script_type: str
|
script_type: str
|
||||||
|
|
||||||
|
|
||||||
|
class BIP143SharedTxDigestFields(NamedTuple):
|
||||||
|
hashPrevouts: str
|
||||||
|
hashSequence: str
|
||||||
|
hashOutputs: str
|
||||||
|
|
||||||
|
|
||||||
class BCDataStream(object):
|
class BCDataStream(object):
|
||||||
"""Workalike python implementation of Bitcoin's CDataStream class."""
|
"""Workalike python implementation of Bitcoin's CDataStream class."""
|
||||||
|
|
||||||
|
@ -958,7 +964,18 @@ class Transaction:
|
||||||
s += script
|
s += script
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def serialize_preimage(self, txin_index: int) -> str:
|
def _calc_bip143_shared_txdigest_fields(self) -> BIP143SharedTxDigestFields:
|
||||||
|
inputs = self.inputs()
|
||||||
|
outputs = self.outputs()
|
||||||
|
hashPrevouts = bh2u(sha256d(bfh(''.join(self.serialize_outpoint(txin) for txin in inputs))))
|
||||||
|
hashSequence = bh2u(sha256d(bfh(''.join(int_to_hex(txin.get('sequence', 0xffffffff - 1), 4) for txin in inputs))))
|
||||||
|
hashOutputs = bh2u(sha256d(bfh(''.join(self.serialize_output(o) for o in outputs))))
|
||||||
|
return BIP143SharedTxDigestFields(hashPrevouts=hashPrevouts,
|
||||||
|
hashSequence=hashSequence,
|
||||||
|
hashOutputs=hashOutputs)
|
||||||
|
|
||||||
|
def serialize_preimage(self, txin_index: int, *,
|
||||||
|
bip143_shared_txdigest_fields: BIP143SharedTxDigestFields = None) -> str:
|
||||||
nVersion = int_to_hex(self.version, 4)
|
nVersion = int_to_hex(self.version, 4)
|
||||||
nHashType = int_to_hex(1, 4) # SIGHASH_ALL
|
nHashType = int_to_hex(1, 4) # SIGHASH_ALL
|
||||||
nLocktime = int_to_hex(self.locktime, 4)
|
nLocktime = int_to_hex(self.locktime, 4)
|
||||||
|
@ -966,9 +983,11 @@ class Transaction:
|
||||||
outputs = self.outputs()
|
outputs = self.outputs()
|
||||||
txin = inputs[txin_index]
|
txin = inputs[txin_index]
|
||||||
if self.is_segwit_input(txin):
|
if self.is_segwit_input(txin):
|
||||||
hashPrevouts = bh2u(sha256d(bfh(''.join(self.serialize_outpoint(txin) for txin in inputs))))
|
if bip143_shared_txdigest_fields is None:
|
||||||
hashSequence = bh2u(sha256d(bfh(''.join(int_to_hex(txin.get('sequence', 0xffffffff - 1), 4) for txin in inputs))))
|
bip143_shared_txdigest_fields = self._calc_bip143_shared_txdigest_fields()
|
||||||
hashOutputs = bh2u(sha256d(bfh(''.join(self.serialize_output(o) for o in outputs))))
|
hashPrevouts = bip143_shared_txdigest_fields.hashPrevouts
|
||||||
|
hashSequence = bip143_shared_txdigest_fields.hashSequence
|
||||||
|
hashOutputs = bip143_shared_txdigest_fields.hashOutputs
|
||||||
outpoint = self.serialize_outpoint(txin)
|
outpoint = self.serialize_outpoint(txin)
|
||||||
preimage_script = self.get_preimage_script(txin)
|
preimage_script = self.get_preimage_script(txin)
|
||||||
scriptCode = var_int(len(preimage_script) // 2) + preimage_script
|
scriptCode = var_int(len(preimage_script) // 2) + preimage_script
|
||||||
|
@ -1129,6 +1148,7 @@ class Transaction:
|
||||||
|
|
||||||
def sign(self, keypairs) -> None:
|
def sign(self, keypairs) -> None:
|
||||||
# keypairs: (x_)pubkey -> secret_bytes
|
# keypairs: (x_)pubkey -> secret_bytes
|
||||||
|
bip143_shared_txdigest_fields = self._calc_bip143_shared_txdigest_fields()
|
||||||
for i, txin in enumerate(self.inputs()):
|
for i, txin in enumerate(self.inputs()):
|
||||||
pubkeys, x_pubkeys = self.get_sorted_pubkeys(txin)
|
pubkeys, x_pubkeys = self.get_sorted_pubkeys(txin)
|
||||||
for j, (pubkey, x_pubkey) in enumerate(zip(pubkeys, x_pubkeys)):
|
for j, (pubkey, x_pubkey) in enumerate(zip(pubkeys, x_pubkeys)):
|
||||||
|
@ -1142,14 +1162,15 @@ class Transaction:
|
||||||
continue
|
continue
|
||||||
_logger.info(f"adding signature for {_pubkey}")
|
_logger.info(f"adding signature for {_pubkey}")
|
||||||
sec, compressed = keypairs.get(_pubkey)
|
sec, compressed = keypairs.get(_pubkey)
|
||||||
sig = self.sign_txin(i, sec)
|
sig = self.sign_txin(i, sec, bip143_shared_txdigest_fields=bip143_shared_txdigest_fields)
|
||||||
self.add_signature_to_txin(i, j, sig)
|
self.add_signature_to_txin(i, j, sig)
|
||||||
|
|
||||||
_logger.info(f"is_complete {self.is_complete()}")
|
_logger.info(f"is_complete {self.is_complete()}")
|
||||||
self.raw = self.serialize()
|
self.raw = self.serialize()
|
||||||
|
|
||||||
def sign_txin(self, txin_index, privkey_bytes) -> str:
|
def sign_txin(self, txin_index, privkey_bytes, *, bip143_shared_txdigest_fields=None) -> str:
|
||||||
pre_hash = sha256d(bfh(self.serialize_preimage(txin_index)))
|
pre_hash = sha256d(bfh(self.serialize_preimage(txin_index,
|
||||||
|
bip143_shared_txdigest_fields=bip143_shared_txdigest_fields)))
|
||||||
privkey = ecc.ECPrivkey(privkey_bytes)
|
privkey = ecc.ECPrivkey(privkey_bytes)
|
||||||
sig = privkey.sign_transaction(pre_hash)
|
sig = privkey.sign_transaction(pre_hash)
|
||||||
sig = bh2u(sig) + '01'
|
sig = bh2u(sig) + '01'
|
||||||
|
|
Loading…
Add table
Reference in a new issue