Skip to content

Commit da9ab82

Browse files
Fix bug: transaction in mempool without witness
1 parent fbf6f6a commit da9ab82

File tree

6 files changed

+44
-10
lines changed

6 files changed

+44
-10
lines changed

btclib_node/interpreter.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from itertools import chain
33
from pathlib import Path
44
from typing import Tuple
5+
from copy import deepcopy
56

67
from btclib.script.engine import verify_input, verify_transaction
78

@@ -12,6 +13,10 @@ def get_flags(config, index) -> Tuple[str]:
1213

1314
def f(prevouts, tx, i, flags):
1415
try:
16+
# no need to deepcopy the values as
17+
# they are not reused
18+
# TODO: are we really sure this is safe?
19+
# To check and fix upstream
1520
verify_input(prevouts, tx, i, flags)
1621
except Exception as e:
1722
err_dir = Path("errors", tx.id.hex(), str(i))
@@ -48,5 +53,8 @@ def check_transactions(transaction_data, index, node):
4853

4954

5055
def check_transaction(prevouts, tx, index, node):
56+
# TODO: we need to deepcopy the transaction because
57+
# verify_transaction modifies it. To fix upstream
58+
tx = deepcopy(tx)
5159
flags = get_flags(node.config, index)
5260
verify_transaction(prevouts, tx, flags)

btclib_node/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def update_chain(node):
111111
node.mempool.add_tx(tx)
112112
for rev_block, block in zip(generated_rev_patches, to_add):
113113
for tx in block.transactions:
114-
node.mempool.remove_tx(tx.id)
114+
node.mempool.remove_tx(tx)
115115

116116
node.logger.debug("Finished main\n")
117117

btclib_node/mempool.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,22 @@ def get_tx(self, txid, wtxid=False):
3434
txid = self.txid_index.get(txid)
3535
return self.transactions.get(txid)
3636

37+
# Don't need lock because handled in same thread
3738
def add_tx(self, tx):
38-
if not self.is_full() and not tx.hash in self.transactions:
39-
self.transactions[tx.hash] = tx
40-
self.txid_index[tx.id] = tx.hash
39+
if self.is_full():
40+
return
41+
wtxid, txid = tx.hash, tx.id
42+
if txid not in self.txid_index:
43+
self.transactions[wtxid] = tx
44+
self.txid_index[tx.id] = wtxid
4145
self.size += 1
4246
self.bytesize += tx.vsize
4347

44-
def remove_tx(self, tx_id):
45-
if tx_id in self.transactions:
46-
tx = self.transactions.pop(tx_id)
47-
self.txid_index.pop(tx.id)
48+
def remove_tx(self, tx):
49+
txid = tx.id
50+
if txid in self.txid_index:
51+
wtxid = self.txid_index.pop(tx.id)
52+
tx = self.transactions.pop(wtxid)
4853
self.size -= 1
4954
self.bytesize -= tx.vsize
5055

btclib_node/p2p/manager.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,7 @@ def broadcast_raw_transaction(self, tx):
127127
def ping_all(self):
128128
for conn in self.connections.copy().values():
129129
conn.send_ping()
130+
131+
def stop_all(self):
132+
for conn in self.connections.copy().values():
133+
conn.stop()

btclib_node/rpc/callbacks.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ def get_block_hash(node, conn, params):
1515

1616

1717
def get_block_header(node, conn, params):
18-
1918
block_index = node.chainstate.block_index
2019
header_index = block_index.header_index
2120

@@ -81,6 +80,22 @@ def get_mempool_info(node, conn, _):
8180
return out
8281

8382

83+
def get_raw_mempool(node, conn, params):
84+
verbose = params[0] if params else False
85+
if verbose:
86+
return {
87+
tx.id.hex(): {
88+
"size": tx.size,
89+
"vsize": tx.vsize,
90+
"weigth": tx.weight,
91+
"wtxid": tx.hash.hex(),
92+
}
93+
for tx in node.mempool.transactions.values()
94+
}
95+
else:
96+
return {"txids": [txid.hex() for txid in node.mempool.txid_index]}
97+
98+
8499
def test_mempool_accept(node, conn, params):
85100
rawtxs = params[0]
86101
out = []
@@ -138,6 +153,7 @@ def stop(node, conn, _):
138153
"getpeerinfo": get_peer_info,
139154
"getconnectioncount": get_connection_count,
140155
"getmempoolinfo": get_mempool_info,
156+
"getrawmempool": get_raw_mempool,
141157
"testmempoolaccept": test_mempool_accept,
142158
"sendrawtransaction": send_raw_transaction,
143159
"ping": ping,

tests/unit/mempool.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ def test_workflow():
1616
assert mempool.size == 1
1717
assert mempool.bytesize == tx.vsize
1818
assert mempool.get_tx(tx.id) == tx
19+
assert mempool.get_tx(tx.hash, wtxid=True) == tx
1920

20-
mempool.remove_tx(tx.id)
21+
mempool.remove_tx(tx)
2122
assert mempool.size == 0
2223
assert mempool.bytesize == 0
2324

0 commit comments

Comments
 (0)