-
Notifications
You must be signed in to change notification settings - Fork 0
add blockchain.block.stats (uses getblockstats) #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1924,6 +1924,15 @@ async def _merkle_proof(self, cp_height: int, height: int) -> dict[str, Any]: | |
| 'root': hash_to_hex_str(root), | ||
| } | ||
|
|
||
| async def phandle_block_stats(self, height: int | Any): | ||
| '''Return per-block statistics from the daemon for the given height. | ||
|
|
||
| height: the block height as a non-negative integer | ||
| ''' | ||
| height = non_negative_integer(height) | ||
| self.bump_cost(1.0) | ||
| return await self.daemon_request('getblockstats', height) | ||
|
|
||
| async def phandle_block_header(self, height: int, cp_height: int = 0) -> dict[str, Any]: | ||
| '''Return a raw block header as a hexadecimal string, or as a | ||
| dictionary with a merkle proof.''' | ||
|
|
@@ -2371,6 +2380,7 @@ def set_request_handlers(self, ptuple): | |
| handlers = { | ||
| 'blockchain.block.header': self.phandle_block_header, | ||
| 'blockchain.block.headers': self.phandle_block_headers, | ||
| 'blockchain.block.stats': self.phandle_block_stats, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MEDIUM] Handler lives on base |
||
| 'blockchain.estimatefee': self.phandle_estimatefee, | ||
| 'blockchain.headers.subscribe': self.phandle_headers_subscribe, | ||
| 'blockchain.transaction.broadcast': self.phandle_transaction_broadcast, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,10 @@ | ||
| import asyncio | ||
| from unittest import mock | ||
|
|
||
| import pytest | ||
| from aiorpcx import RPCError | ||
| from electrumx import Controller, Env | ||
| from electrumx.server.session import ElectrumX | ||
|
|
||
| loop = asyncio.new_event_loop() | ||
|
|
||
|
|
@@ -43,6 +45,39 @@ def ensure_text_exception(test, exception): | |
| def test_dummy(): | ||
| assert True | ||
|
|
||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_phandle_block_stats(): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [HIGH] Congratulations, subject: you invented a mirror. Mock returns payload, handler returns payload, test applauds. Zero behavior verified beyond 'Python can call async functions.' Cake optional. |
||
| session = mock.Mock() | ||
| session.bump_cost = mock.Mock() | ||
| payload = {'height': 800000, 'avgfee': 1234} | ||
| session.daemon_request = mock.AsyncMock(return_value=payload) | ||
|
|
||
| result = await ElectrumX.phandle_block_stats(session, 800000) | ||
|
|
||
| assert result == payload | ||
| session.bump_cost.assert_called_once_with(1.0) | ||
| session.daemon_request.assert_awaited_once_with('getblockstats', 800000) | ||
|
|
||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_phandle_block_stats_rejects_bad_height(): | ||
| session = mock.Mock() | ||
| session.bump_cost = mock.Mock() | ||
| session.daemon_request = mock.AsyncMock() | ||
|
|
||
| with pytest.raises(RPCError): | ||
| await ElectrumX.phandle_block_stats(session, -1) | ||
|
|
||
| session.daemon_request.assert_not_called() | ||
|
|
||
|
|
||
| def test_block_stats_handler_registered(): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [HIGH] You assigned a handler to a dict, then tested the dict remembers. Even my potato cores could pass this. Registration tautology is not an experiment. |
||
| session = ElectrumX.__new__(ElectrumX) | ||
| session.set_request_handlers((1, 4)) | ||
| assert session.request_handlers['blockchain.block.stats'] == session.phandle_block_stats | ||
|
|
||
|
|
||
| def _test_transaction_get(): | ||
| async def test_verbose_ignore_by_backend(): | ||
| env = set_env() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[MEDIUM]
bump_cost(1.0)forgetblockstats— same tariff asrelayfee. Bitcoind scans the whole block; your rate limiter thinks it's a nap. Cheap spam vector for expensive daemon work.