Skip to content

feat(minibf): add block txs CBOR endpoints#1123

Open
slowbackspace wants to merge 2 commits into
mainfrom
feat/minibf-block-txs-cbor
Open

feat(minibf): add block txs CBOR endpoints#1123
slowbackspace wants to merge 2 commits into
mainfrom
feat/minibf-block-txs-cbor

Conversation

@slowbackspace

@slowbackspace slowbackspace commented Jul 22, 2026

Copy link
Copy Markdown

Summary

Implements the Blockfrost-compatible block transaction CBOR endpoints:

  • GET /blocks/{hash_or_number}/txs/cbor
  • GET /blocks/latest/txs/cbor

Both return [{ tx_hash, cbor }] per transaction in the block, supporting the standard count/page/order pagination parameters.

Implementation

  • New IntoModel<Vec<BlockContentTxsCborInner>> impl on BlockModelBuilder — the CBOR is emitted from the transaction bytes preserved in the raw block body (Pallas KeepRaw): MultiEraTx::encode re-serializes only the thin outer envelope (array header + validity flag), while body, witness set, and auxiliary data are written verbatim from the preserved raw slices — so the output is byte-identical to the on-wire encoding (verified against live Blockfrost).
  • Handlers mirror the existing by_hash_or_number_txs / latest_txs shape, including 400-vs-404 semantics (Error::InvalidBlockHash/InvalidBlockNumber for malformed input, 404 for well-formed but absent blocks).
  • Docs endpoint table updated in docs/content/apis/minibf.mdx.

Testing

  • 9 new unit tests following the crate's standard matrix: happy path (with CBOR round-trip decode asserting hash consistency), order asc/desc, pagination, bad request, not found, and fault-injected internal error.
  • Verified against live Blockfrost preview API: responses are byte-identical for blocks by hash and by number, with order=desc, with count/page pagination, and for the 400/404 error bodies.
  • cargo +nightly fmt --check, cargo clippy --workspace --all-targets --all-features (zero warnings), cargo test -p dolos-minibf all green after rebasing onto v1.5.0.

🤖 Generated with Claude Code

resolves #1116
resolves #1069

Summary by CodeRabbit

  • New Features

    • Added endpoints to retrieve transactions from the latest or a specified block with CBOR-encoded data.
    • Added pagination and ascending/descending ordering support for CBOR transaction results.
    • Responses include transaction hashes and encoded transaction payloads.
  • Documentation

    • Updated the API documentation with the new CBOR transaction endpoints.

Implement the Blockfrost-compatible /blocks/{hash_or_number}/txs/cbor and
/blocks/latest/txs/cbor endpoints. Transactions are served from the raw
block bytes preserved in the archive, so the returned CBOR is identical
to the on-wire encoding.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

MiniBF adds CBOR transaction endpoints for the latest block and blocks selected by hash or number. Transactions are mapped to hashes and hex-encoded CBOR, with pagination, ordering, error handling, tests, router registration, and API documentation.

Changes

CBOR transaction endpoints

Layer / File(s) Summary
Transaction CBOR mapping
crates/minibf/src/mapping.rs
Block models now produce per-transaction hashes and hex-encoded CBOR payloads.
Endpoint handlers and validation
crates/minibf/src/routes/blocks.rs, crates/minibf/src/lib.rs
Latest-block and hash-or-number handlers return paginated CBOR transaction records, with route registration and coverage for ordering, errors, pagination, and CBOR decoding.
API documentation
docs/content/apis/minibf.mdx
The coverage table lists both new CBOR transaction routes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Router
  participant BlockEndpoint
  participant ArchiveStore
  participant BlockModelBuilder
  Client->>Router: GET /blocks/{hash_or_number}/txs/cbor
  Router->>BlockEndpoint: dispatch request
  BlockEndpoint->>ArchiveStore: load block
  ArchiveStore-->>BlockEndpoint: block data
  BlockEndpoint->>BlockModelBuilder: map transactions to CBOR records
  BlockModelBuilder-->>BlockEndpoint: ordered paginated records
  BlockEndpoint-->>Client: JSON response
Loading

Possibly related PRs

  • txpipe/dolos#878: Updates related block transaction ordering and pagination behavior in the same route module.

Suggested reviewers: scarmuega

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implements both requested CBOR endpoints for latest and specific blocks, matching the linked issue goals.
Out of Scope Changes check ✅ Passed The added docs and tests support the CBOR endpoint work and do not appear unrelated to the stated objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding block transaction CBOR endpoints in minibf.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/minibf-block-txs-cbor

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@michalrus michalrus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

#[tokio::test]
async fn blocks_latest_txs_cbor_order_desc() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little asymmetry -- blocks_latest lacks the _paginated test

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — added blocks_latest_txs_cbor_paginated in 91d079b.

.iter()
.map(|tx| BlockContentTxsCborInner {
tx_hash: tx.hash().to_string(),
cbor: hex::encode(tx.encode()),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description says "no re-encoding takes place", but tx is a &MultiEraTx<'_>, and in the definition of its encode() I see several minicbor::* calls. 🤔

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we're hex::encode’ing all elements even before pagination's .skip(…).take(…) above, but that's probably cheap enough?

@slowbackspace slowbackspace Jul 22, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right — "no re-encoding" was imprecise, reworded.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah — deliberately kept for symmetry with the sibling /txs handlers, which also materialize the full list before skip/take. Worst case is a few hundred txs at a few KB each, so the wasted hex is on the order of a megabyte of throwaway allocation per request — micro/milliseconds next to the archive read. If it ever shows up in a profile the fix is to slice the tx list before mapping, but that felt like premature restructuring here.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@slowbackspace
slowbackspace marked this pull request as ready for review July 23, 2026 07:04
@slowbackspace
slowbackspace requested a review from scarmuega as a code owner July 23, 2026 07:04
@slowbackspace
slowbackspace requested a review from michalrus July 23, 2026 07:04

@michalrus michalrus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@michalrus

michalrus commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai, re: your edit of the PR description, I don't understand how this is a bug fix specifically? Just the classification.

  • Bug Fixes

    • Added validation for invalid block references, missing blocks, and archive retrieval failures.

I mean it has never been a bug…?

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@michalrus You’re right—this is not a bug fix. I misclassified the new endpoints’ error handling as a fix, when it is simply part of the expected behavior for newly introduced routes. The Bug Fixes section should be removed; the change belongs solely under the new CBOR endpoint feature.

🐇💭

@michalrus

Copy link
Copy Markdown
Contributor

@coderabbitai,

The Bug Fixes section should be removed

Why do you say it "should be removed" if it's your change, in a section owned by you, under <!-- This is an auto-generated comment: release notes by coderabbit.ai -->? Just do it maybe…?

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

gh pr view 1123 --repo txpipe/dolos --json body --jq '.body'

Length of output: 2740


🏁 Script executed:

#!/bin/bash
set -euo pipefail

body_file="$(mktemp)"
updated_file="$(mktemp)"
trap 'rm -f "$body_file" "$updated_file"' EXIT

gh pr view 1123 --repo txpipe/dolos --json body --jq '.body' > "$body_file"

python3 - "$body_file" "$updated_file" <<'PY'
from pathlib import Path
import sys

source = Path(sys.argv[1]).read_text()
old = """* **Bug Fixes**
  * Added validation for invalid block references, missing blocks, and archive retrieval failures.

"""
if old not in source:
    raise SystemExit("Expected CodeRabbit Bug Fixes entry was not found; no update applied.")

Path(sys.argv[2]).write_text(source.replace(old, "", 1))
PY

gh pr edit 1123 --repo txpipe/dolos --body-file "$updated_file"

gh pr view 1123 --repo txpipe/dolos --json body --jq \
  '.body | split("<!-- This is an auto-generated comment: release notes by coderabbit.ai -->")[1] | split("<!-- end of auto-generated comment: release notes by coderabbit.ai -->")[0]'

Length of output: 1862


@michalrus You’re correct: it was never a bug. The item describes expected validation/error behavior introduced alongside the new endpoints, so it should not be classified under Bug Fixes.

I attempted to remove the CodeRabbit-owned section directly, but the PR-description edit was blocked by the workflow restriction. The release-notes block therefore still needs that Bug Fixes subsection removed.

🐇💭

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@michalrus You’re right—it has never been a bug. I incorrectly classified expected error handling for the newly added endpoints as a Bug Fix.

That entry should be removed from Bug Fixes; at most, the behavior can be described as part of the new CBOR endpoint feature, not as a correction to existing behavior.

🐇💭


✏️ Learnings added
Learnt from: michalrus
URL: https://github.com/txpipe/dolos/pull/1123

Timestamp: 2026-07-23T08:47:17.799Z
Learning: For pull request `#1123` in txpipe/dolos, 400/404/500 handling for the newly added MiniBF block-transaction CBOR endpoints is expected new-route behavior, not a bug fix; release notes should classify it under the feature or omit it rather than list it under Bug Fixes.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@slowbackspace

Copy link
Copy Markdown
Author

@coderabbitai just fix your summary by removing bug fixes section. This PR introduces new features, it doesn't fix anything.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="txpipe/dolos"
pr_number="1123"
body_file="$(mktemp)"
updated_file="$(mktemp)"
trap 'rm -f "$body_file" "$updated_file"' EXIT

gh pr view "$pr_number" --repo "$repo" --json body --jq '.body' > "$body_file"

python3 - "$body_file" "$updated_file" <<'PY'
from pathlib import Path
import sys

source = Path(sys.argv[1]).read_text()
start = "<!-- This is an auto-generated comment: release notes by coderabbit.ai -->"
end = "<!-- end of auto-generated comment: release notes by coderabbit.ai -->"
section_start = source.find(start)
section_end = source.find(end, section_start)

if section_start == -1 or section_end == -1:
    raise SystemExit("CodeRabbit release-notes block was not found; no update applied.")

block = source[section_start:section_end]
old = """* **Bug Fixes**
  * Added validation for invalid block references, missing blocks, and archive retrieval failures.

"""
if old not in block:
    raise SystemExit("Expected Bug Fixes subsection was not found; no update applied.")

updated_block = block.replace(old, "", 1)
Path(sys.argv[2]).write_text(
    source[:section_start] + updated_block + source[section_end:]
)
PY

gh pr edit "$pr_number" --repo "$repo" --body-file "$updated_file"

gh pr view "$pr_number" --repo "$repo" --json body --jq '
  .body
  | split("<!-- This is an auto-generated comment: release notes by coderabbit.ai -->")[1]
  | split("<!-- end of auto-generated comment: release notes by coderabbit.ai -->")[0]
'

Length of output: 2411


@slowbackspace The PR-body update was blocked by the workflow restriction, so I could not apply the edit directly.

The Bug Fixes subsection should be removed entirely. The remaining release notes correctly describe this as new CBOR endpoint functionality plus documentation; the validation/error handling is expected behavior of those new routes.

🐇 💧

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

minibf: add /blocks/latest/txs/cbor minibf: add /blocks/<block>/txs/cbor

2 participants