From 6b2c138f0965e02c81224abdf73257fbe44b6170 Mon Sep 17 00:00:00 2001 From: MMGen Date: Tue, 2 Apr 2019 13:41:04 +0000 Subject: [PATCH] implement BIP69 (lexicographical indexing of tx inputs and outputs) --- mmgen/main_txbump.py | 3 +++ mmgen/tx.py | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/mmgen/main_txbump.py b/mmgen/main_txbump.py index 8436e334..a10e6ea3 100755 --- a/mmgen/main_txbump.py +++ b/mmgen/main_txbump.py @@ -129,6 +129,9 @@ tx.update_fee(op_idx,fee) d = tx.get_fee_from_tx() assert d == fee and d <= g.proto.max_tx_fee +if g.proto.base_proto == 'Bitcoin': + tx.outputs.sort_bip69() # output amts have changed, so re-sort + if not opt.yes: tx.add_comment() # edits an existing comment tx.create_raw() # creates tx.hex, tx.txid diff --git a/mmgen/tx.py b/mmgen/tx.py index 49c0a1d0..f3eeea67 100755 --- a/mmgen/tx.py +++ b/mmgen/tx.py @@ -267,11 +267,21 @@ class MMGenTxInputList(list,MMGenObject): if type(i.amt) != g.proto.coin_amt: die(2,'Coin mismatch in transaction: amount {} not of type {}!'.format(i.amt,g.proto.coin_amt)) + # Lexicographical Indexing of Transaction Inputs and Outputs + # https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki + def sort_bip69(self): + from struct import pack + self.sort(key=lambda a: bytes.fromhex(a.txid) + pack('>i',a.vout)) + class MMGenTxOutputList(MMGenTxInputList): desc = 'transaction outputs' member_type = 'MMGenTxOutput' + def sort_bip69(self): + from struct import pack + self.sort(key=lambda a: pack('>q',a.amt.toSatoshi()) + bytes.fromhex(addr2scriptPubKey(a.addr))) + class MMGenTX(MMGenObject): def __new__(cls,*args,**kwargs): @@ -1430,6 +1440,9 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam self.update_send_amt(change_amt) if g.proto.base_proto == 'Bitcoin': + self.inputs.sort_bip69() + self.outputs.sort_bip69() + # do this only after inputs are sorted if opt.rbf: self.inputs[0].sequence = g.max_int - 2 # handles the locktime case too elif locktime: self.inputs[0].sequence = g.max_int - 1