Skip to content

Commit 07ff3d9

Browse files
committed
add mempool.get_info, update relayfee comments
Adds the `mempool.get_info` rpc to fetch mempoolminfee, minrelaytxfee and incrementalrelayfee from the daemons getmempoolinfo rpc. Updates the relayfee comments as the fee returned by `blockchain.relayfee` doesn't guarantee to get into the mempool as previously stated in the docstrings.
1 parent fb28dc2 commit 07ff3d9

4 files changed

Lines changed: 63 additions & 6 deletions

File tree

docs/rpc-interface.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ A typical result is as follows (with annotated comments)::
9898
"getinfo": 3,
9999
"groups": 1,
100100
"mempool.get_fee_histogram": 3194,
101+
"mempool.get_info": 121,
101102
"server.add_peer": 9,
102103
"server.banner": 740,
103104
"server.donation_address": 754,

src/electrumx/server/daemon.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ def __init__(
7979
self._networkinfo_cache = (None, 0)
8080
self._networkinfo_lock = asyncio.Lock()
8181

82+
self._mempoolinfo_cache = (None, 0)
83+
self._mempoolinfo_lock = asyncio.Lock()
84+
8285
async def __aenter__(self):
8386
self.session = aiohttp.ClientSession(connector=self.connector())
8487
return self
@@ -284,12 +287,38 @@ async def getnetworkinfo(self):
284287
self._networkinfo_cache = (val, time.time())
285288
return val
286289

290+
async def getmempoolinfo(self):
291+
"""Return the result of the 'getmempoolinfo' RPC call."""
292+
async with self._mempoolinfo_lock:
293+
cache_val, cache_time = self._mempoolinfo_cache
294+
if time.time() - cache_time < 60: # seconds
295+
return cache_val
296+
val = await self._send_single('getmempoolinfo')
297+
self._mempoolinfo_cache = (val, time.time())
298+
return val
299+
287300
async def relayfee(self):
288-
'''The minimum fee a low-priority tx must pay in order to be accepted
289-
to the daemon's memory pool.'''
301+
"""Same as getmempoolinfo['minrelaytxfee'].
302+
The minimum fee required for a transaction to be relayed on by the daemon to the
303+
bitcoin network. Doesn't guarantee mempool acceptance."""
290304
network_info = await self.getnetworkinfo()
291305
return network_info['relayfee']
292306

307+
async def mempool_info(self) -> dict[str, float]:
308+
"""
309+
returns: {
310+
"mempoolminfee": Minimum fee rate in BTC/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee
311+
"minrelaytxfee": Minimum relay fee for transactions in BTC/kvB, configured, static.
312+
"incrementalrelayfee": Minimum fee rate increment for mempool limiting or replacement in BTC/kvB, static, configured.
313+
}
314+
"""
315+
mempool_info = await self.getmempoolinfo()
316+
return {
317+
'mempoolminfee': mempool_info['mempoolminfee'],
318+
'minrelaytxfee': mempool_info['minrelaytxfee'],
319+
'incrementalrelayfee': mempool_info['incrementalrelayfee'],
320+
}
321+
293322
async def getrawtransaction(self, hex_hash, verbose=False):
294323
'''Return the serialized raw transaction with the given hash.'''
295324
# Cast to int because some coin daemons are old and require it
@@ -350,8 +379,8 @@ async def estimatefee(self, block_count):
350379
return self.coin.ESTIMATE_FEE
351380

352381
async def relayfee(self):
353-
'''The minimum fee a low-priority tx must pay in order to be accepted
354-
to the daemon's memory pool.'''
382+
"""The minimum fee required for a transaction to be relayed on by the server to the
383+
bitcoin network. Doesn't guarantee mempool acceptance."""
355384
return self.coin.RELAY_FEE
356385

357386

src/electrumx/server/session.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,11 +1396,22 @@ async def banner(self):
13961396
return banner
13971397

13981398
async def relayfee(self):
1399-
'''The minimum fee a low-priority tx must pay in order to be accepted
1400-
to the daemon's memory pool.'''
1399+
"""The minimum fee required for a transaction to be relayed on by the daemon to the
1400+
bitcoin network. Doesn't guarantee mempool acceptance."""
14011401
self.bump_cost(1.0)
14021402
return await self.daemon_request('relayfee')
14031403

1404+
async def mempool_info(self):
1405+
"""
1406+
returns: {
1407+
"mempoolminfee": Minimum fee rate in BTC/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee
1408+
"minrelaytxfee": Minimum relay fee for transactions in BTC/kvB, configured, static.
1409+
"incrementalrelayfee": Minimum fee rate increment for mempool limiting or replacement in BTC/kvB, static, configured.
1410+
}
1411+
"""
1412+
self.bump_cost(1.0)
1413+
return await self.daemon_request('mempool_info')
1414+
14041415
async def estimatefee(self, number, mode=None):
14051416
'''The estimated transaction fee per kilobyte to be paid for a
14061417
transaction to be included within a certain number of blocks.
@@ -1647,6 +1658,7 @@ def set_request_handlers(self, ptuple):
16471658
'blockchain.transaction.get_merkle': self.transaction_merkle,
16481659
'blockchain.transaction.id_from_pos': self.transaction_id_from_pos,
16491660
'mempool.get_fee_histogram': self.compact_fee_histogram,
1661+
'mempool.get_info': self.mempool_info,
16501662
'server.add_peer': self.add_peer,
16511663
'server.banner': self.banner,
16521664
'server.donation_address': self.donation_address,

tests/server/test_daemon.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,21 @@ async def test_relayfee(daemon):
255255
assert await daemon.relayfee() == sats
256256

257257

258+
@pytest.mark.asyncio
259+
async def test_mempool_info(daemon):
260+
bitcoin_per_kvb = 0.00002123
261+
response = {
262+
'mempoolminfee': bitcoin_per_kvb,
263+
'minrelaytxfee': bitcoin_per_kvb,
264+
'incrementalrelayfee': bitcoin_per_kvb,
265+
'other': 'cruft',
266+
}
267+
daemon.session = ClientSessionGood(('getmempoolinfo', [], response))
268+
expected_result = dict(response)
269+
del expected_result['other']
270+
assert await daemon.mempool_info() == expected_result
271+
272+
258273
@pytest.mark.asyncio
259274
async def test_mempool_hashes(daemon):
260275
hashes = ['hex_hash1', 'hex_hash2']

0 commit comments

Comments
 (0)