Skip to content

Commit 7f7e301

Browse files
committed
protocol change: define order of mempool txs in status of scripthash
Note that this is a soft fork: the server can apply it even for past protocol versions. Previously, with the order being undefined, if an address had multiple mempool transactions touching it, switching between different servers could result in a change in address status simply as a result of these servers ordering mempool txs differently. This would result in the client re-requesting the whole history of the address. ----- D/i | interface.[electrum.blockstream.info:60002] | <-- ('blockchain.scripthash.subscribe', ['660b44502503064f9d5feee48726287c0973e25bc531b4b8a072f57f143d5cd0']) {} (id: 12) D/i | interface.[electrum.blockstream.info:60002] | --> 9da27f9df91e3f860212f65b736fa20a539ba6e3d509f6370367ee7f10a4d5b0 (id: 12) D/i | interface.[electrum.blockstream.info:60002] | <-- ('blockchain.scripthash.get_history', ['660b44502503064f9d5feee48726287c0973e25bc531b4b8a072f57f143d5cd0']) {} (id: 13) D/i | interface.[electrum.blockstream.info:60002] | --> [ {'fee': 200, 'height': 0, 'tx_hash': '3ee6d6e26291ce360127fe039b816470fce6eeea19b5c9d10829a1e4efc2d0c7'}, {'fee': 239, 'height': 0, 'tx_hash': '9e050f09b676b9b0ee26aa02ccee623fae585a85d6a5e24ecedd6f8d6d2d3b1d'}, {'fee': 178, 'height': 0, 'tx_hash': 'fb80adbf8274190418cb3fb0385d82fe9d47a844d9913684fa5fb3d48094b35a'}, {'fee': 200, 'height': 0, 'tx_hash': '713933c50b7c43f606dad5749ea46e3bc6622657e9b13ace9d639697da266e8b'} ] (id: 13) D/i | interface.[testnet.hsmiths.com:53012] | <-- ('blockchain.scripthash.subscribe', ['660b44502503064f9d5feee48726287c0973e25bc531b4b8a072f57f143d5cd0']) {} (id: 12) D/i | interface.[testnet.hsmiths.com:53012] | --> f7ef7237d2d62a3280acae05616200b96ad9dd85fd0473c29152a4a41e05686c (id: 12) D/i | interface.[testnet.hsmiths.com:53012] | <-- ('blockchain.scripthash.get_history', ['660b44502503064f9d5feee48726287c0973e25bc531b4b8a072f57f143d5cd0']) {} (id: 13) D/i | interface.[testnet.hsmiths.com:53012] | --> [ {'tx_hash': '9e050f09b676b9b0ee26aa02ccee623fae585a85d6a5e24ecedd6f8d6d2d3b1d', 'height': 0, 'fee': 239}, {'tx_hash': 'fb80adbf8274190418cb3fb0385d82fe9d47a844d9913684fa5fb3d48094b35a', 'height': 0, 'fee': 178}, {'tx_hash': '3ee6d6e26291ce360127fe039b816470fce6eeea19b5c9d10829a1e4efc2d0c7', 'height': 0, 'fee': 200}, {'tx_hash': '713933c50b7c43f606dad5749ea46e3bc6622657e9b13ace9d639697da266e8b', 'height': 0, 'fee': 200} ] (id: 13)
1 parent 6eafd6c commit 7f7e301

File tree

2 files changed

+7
-4
lines changed

2 files changed

+7
-4
lines changed

src/electrumx/server/mempool.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,12 +416,15 @@ async def potential_spends(self, hashX):
416416
return result
417417

418418
async def transaction_summaries(self, hashX):
419-
'''Return a list of MemPoolTxSummary objects for the hashX.'''
419+
'''Return a list of MemPoolTxSummary objects for the hashX,
420+
sorted as expected by protocol methods.
421+
'''
420422
result = []
421423
for tx_hash in self.hashXs.get(hashX, ()):
422424
tx = self.txs[tx_hash]
423425
has_ui = any(hash in self.txs for hash, idx in tx.prevouts)
424426
result.append(MemPoolTxSummary(tx_hash, tx.fee, has_ui))
427+
result.sort(key=lambda x: (x.has_unconfirmed_inputs, x.hash))
425428
return result
426429

427430
async def unordered_UTXOs(self, hashX):

src/electrumx/server/session.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ async def address_status(self, hashX):
11971197
11981198
Status is a hex string, but must be None if there is no history.
11991199
'''
1200-
# Note history is ordered and mempool unordered in electrum-server
1200+
# Note both confirmed history and mempool history are ordered
12011201
# For mempool, height is -1 if it has unconfirmed inputs, otherwise 0
12021202
db_history, cost = await self.session_mgr.limited_history(hashX)
12031203
mempool = await self.mempool.transaction_summaries(hashX)
@@ -1267,7 +1267,7 @@ async def scripthash_get_balance(self, scripthash):
12671267
return await self.get_balance(hashX)
12681268

12691269
async def unconfirmed_history(self, hashX):
1270-
# Note unconfirmed history is unordered in electrum-server
1270+
# Note both confirmed history and mempool history are ordered
12711271
# height is -1 if it has unconfirmed inputs, otherwise 0
12721272
result = [{'tx_hash': hash_to_hex_str(tx.hash),
12731273
'height': -tx.has_unconfirmed_inputs,
@@ -1277,7 +1277,7 @@ async def unconfirmed_history(self, hashX):
12771277
return result
12781278

12791279
async def confirmed_and_unconfirmed_history(self, hashX):
1280-
# Note history is ordered but unconfirmed is unordered in e-s
1280+
# Note both confirmed history and mempool history are ordered
12811281
history, cost = await self.session_mgr.limited_history(hashX)
12821282
self.bump_cost(cost)
12831283
conf = [{'tx_hash': hash_to_hex_str(tx_hash), 'height': height}

0 commit comments

Comments
 (0)