Implement get_headers as bounded selected-parent-chain traversal#993
Open
demisrael wants to merge 2 commits into
Open
Implement get_headers as bounded selected-parent-chain traversal#993demisrael wants to merge 2 commits into
demisrael wants to merge 2 commits into
Conversation
…versal Replace the NotImplemented stub with a bounded selected-parent-chain walk over existing consensus reads. The request shape (start_hash, limit, is_ascending) is preserved. GetHeadersResponseMessage gains an additive blockHeaders field carrying full header records; the legacy headers hash-string field is retained for wire compatibility. Closes kaspanet#806 Signed-off-by: Dmitry Perchanov <demisrael@gmail.com>
Wire the existing GetHeaders RPC into the interactive `kaspa-cli rpc` surface so operators can exercise the endpoint against a running node. The command takes a start hash, a limit, and an optional direction (ascending by default; descending alias accepted), and prints the returned header records. Add unit coverage for the direction parser: default, accepted aliases, and rejection of unknown values. Signed-off-by: Dmitry Perchanov <demisrael@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #806.
RpcApi::get_headers(gRPCgetHeaders, wRPCgetHeaders, WASMgetHeaders)previously returned
NotImplemented. The endpoint is now implemented as abounded selected-parent-chain traversal using existing consensus read APIs.
The endpoint shape (
start_hash,limit,is_ascending) is preserved, andno new external dependencies are introduced.
Behavior
is_ascending = true— walks the selected parent chain fromstart_hashtoward the current sink.
is_ascending = false— walks fromstart_hashtoward genesis.limitcounts returned headers and is inclusive ofstart_hashwhenlimit > 0.limit = 0returns an emptyheadersvector withouttouching consensus iterators beyond start-hash validation.
start_hashmust be on the selected parent chain. Unknown hashes andoff-chain hashes return typed RPC errors and the request is rejected
before any unbounded allocation.
u64limit cannot allocate an unbounded vector.Public API additions
Two new public consensus helpers carry the selected-parent-chain contract on
their doc comments and are reused by the RPC service:
ConsensusApi::get_virtual_selected_chain_fromConsensusSessionOwned::async_get_virtual_selected_chain_fromPublic Rust, proto, and WASM doc comments for
get_headers/getHeadersare updated to describe the selected-parent-chain direction and inclusive
limitsemantics.gRPC wire compatibility
GetHeadersResponseMessageadds an additiveblockHeaders = 2fieldcarrying full
RpcBlockHeaderrecords. The legacyheaders = 1hash-string field is preserved. The decoder:
blockHeadersset;full-header hash;
empty success response);
errorpayloads over both fields.wRPC and WASM require no transport-side wiring changes: both already
dispatch
GetHeadersthrough the coreRpcApitrait, so implementingRpcCoreService::get_headers_calland updating the gRPC converter issufficient to make all three transports functional. The WASM diff is
limited to doc-comment updates on the existing binding.
Interactive CLI (
kaspa-cli)The second commit (
b2b3c772) wires the existingGetHeadersRPC intothe interactive
kaspa-cli rpccommand surface so operators can drivethe endpoint against a running node:
ascendingwhen omitted.start_hashandlimituse the existingRpcHashandu64parsers.rpc.get_headers_call(...)request shapeand prints the returned
GetHeadersResponse(header records).cli/src/modules/rpc.rscover the direction parser:default behavior, accepted aliases, and rejection of unknown values.
No RPC wire fields, op IDs, or other CLI command surfaces were changed.
Tests
testing/integration::rpc_tests::sanity_test— theGetHeadersarm nowasserts a successful response instead of asserting
NotImplemented.testing/integration::rpc_tests::get_headers_selected_chain_test— new;exercises ascending, descending,
limit = 0,limit = 1, sink-rootedascending, genesis-rooted ascending, unknown
start_hash, and off-chainstart_hasherror paths against a mined simnet.rpc/grpc/core/src/convert/message.rs—new; cover empty payload acceptance, hash-only rejection, matching
mixed-payload success, length mismatch, hash mismatch, and error
precedence.
cli/src/modules/rpc.rs— direction parser default,alias acceptance, and unknown-value rejection.
Complexity
O(min(limit, selected-chain distance to endpoint))consensusreads. No broad DAG traversal.
O(returned headers). No allocation based directly on anunchecked
u64request limit.Verification
cargo nextest run --workspace— PASS (full workspace)cargo test --doc --workspace— PASS (doctests)cargo nextest run -p kaspa-testing-integration rpc_tests::sanity_test— PASScargo nextest run -p kaspa-testing-integration rpc_tests::get_headers_selected_chain_test— PASScargo test -p kaspa-grpc-core get_headers_response— PASS (focused gRPC converter tests)cargo check --tests --workspace --benches— PASScargo build --workspace --tests --benches— PASScargo fmt --all -- --check— PASScargo +1.93.0 clippy --workspace --tests --benches --examples -- -D warnings— PASSRUSTUP_TOOLCHAIN=1.93.0 ./check— PASSLive-node CLI smoke (interactive
kaspa-cli)Validated against a running testnet-10 node over wRPC:
rpc get-headers <genesis> 0 ascending— emptyheadersvector.rpc get-headers <genesis> 1 ascending— single header (genesis).rpc get-headers <genesis> 2 ascending— genesis + next selected-chain header.rpc get-headers <sink> N descending— sink first, walking selected parents.rpc get-headers <unknown-hash> N ascending— typed RPC error(
cannot find header ...), no panic.before any unbounded allocation.
Toolchain note
Clippy verification is on the project's pinned Rust 1.93.0 toolchain. Under
stable ≥ 1.95 there is an unrelated
clippy::explicit-counter-looplint incrypto/merkle/src/lib.rs:14, outside this diff; the pinned 1.93.0toolchain (the project's CI gate) is clean.
Out of scope
get_headers/getHeadersfrom public APIs.request (would require an API redesign).
GetHeadersRequestfields orRpcApiOps/KaspadPayloadOpsnumbering.
header-sync semantics.