Skip to content

test(tbtc): add reservation proposal marshaling coverage - #4277

Draft
piotr-roslaniec wants to merge 2 commits into
m1/reservation-readiness-fixesfrom
m1/reservation-protobuf-marshaling
Draft

test(tbtc): add reservation proposal marshaling coverage#4277
piotr-roslaniec wants to merge 2 commits into
m1/reservation-readiness-fixesfrom
m1/reservation-protobuf-marshaling

Conversation

@piotr-roslaniec

@piotr-roslaniec piotr-roslaniec commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds test coverage for the reservation CoordinationProposal protobuf
marshaling (ReservationAnchorProposal, ReservationReanchorProposal) that
switched from a JSON placeholder to real protobuf via #4276 (stacked base
m1/reservation-readiness-fixes), matching every other proposal type in
pkg/tbtc (Heartbeat, DepositSweep, Redemption, MovingFunds,
MovedFundsSweep). The protobuf message definitions, generated bindings, and
Marshal/Unmarshal implementations (including required-field validation)
already exist on the base branch; this PR does not change that production
code.

Stacked on m1/reservation-readiness-fixes per the delivery plan's
follow-up-PR sequencing.

Change

  • pkg/tbtc/marshaling_test.go: extended the existing table-driven
    TestCoordinationMessage_MarshalingRoundtrip with both reservation
    proposal types (exact field-for-field equality through the wire), plus two
    new TestFuzzCoordinationMessage_MarshalingRoundtrip_With<X>Proposal
    crash-safety tests, one per type, matching the existing
    one-per-sibling-type convention.
  • pkg/tbtc/reservation_test.go: renamed
    TestReservationProposals_UnmarshalRejectsMissingIntegers to
    TestReservationProposals_UnmarshalRejectsInvalidFields, matching the
    base branch's already-broader field-validation coverage. Added three new
    cases proving that a legitimately-constructed proposal with a zero
    *big.Int fee/key value is rejected as missing on unmarshal (the
    documented .Bytes() empty-slice equivalence), exercised through each
    proposal's real Marshal() method rather than a hand-built protobuf
    payload.

Testing

  • go test ./pkg/tbtc/...: full package suite passes (362/362), zero
    failures.
  • gofmt -l / go vet: clean on all changed files.

Not in this PR

  • Wiring reservation actions into the coordination checklist so these
    proposals are actually reachable in production - tracked separately.
  • Milestone 2 test-coverage backfill and the M3 multi-signer integration
    test - both tracked as separate follow-up PRs per the implementation plan.
  • The substantive protobuf switch (message definitions, generated bindings,
    Marshal/Unmarshal implementations, and their required-field
    validation) lives on the base branch via fix(spv): re-verify reservation action generation before SPV proof submission #4276, not in this PR's diff;
    the milestone row should be closed against that PR, not this one.

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

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.

Closes gap-analysis Major row 1 and implementation-plan.md M1 row 3.

ReservationAnchorProposal, ReservedRedemptionProposal,
ReservationReanchorProposal, and ReservationDissolutionProposal
previously used a JSON Marshal/Unmarshal placeholder, unlike every
other CoordinationProposal type in this package (Heartbeat,
DepositSweep, Redemption, MovingFunds, MovedFundsSweep), which all
marshal via pkg/tbtc/gen/pb.

Added the four missing message types to message.proto and
regenerated message.pb.go (protoc 3.21.12 installed for this).
Moved the four proposals' Marshal/Unmarshal from reservation.go's
JSON stubs into marshaling.go, matching the existing proto-based
implementations' structure and field-encoding conventions (big.Int
fees via .Bytes()/SetBytes(), fixed-size hashes/pubkey-hashes via
byte-slice copy with a length check).

Preserved the original JSON stubs' validation intent under proto3's
zero-value-is-absence semantics: a request nonce of 0, or empty
fee/reservation-key/hash bytes, are rejected the same way an
explicitly-missing JSON field was. The original '== nil' checks on
*big.Int fields don't carry over as-is - SetBytes never returns nil -
so they're now byte-length checks on the wire field instead, which is
the pattern every other proto-based proposal in this file already
uses.

Testing: extended the existing table-driven
TestCoordinationMessage_MarshalingRoundtrip with the four new types
(exact field-for-field equality through the wire, matching the
existing test's own precision, not just the fuzz-style tests already
covering every sibling type) plus four new
TestFuzzCoordinationMessage_MarshalingRoundtrip_With<X>Proposal
crash-safety tests, matching the one-per-type convention. Rewrote
the pre-existing TestReservationProposals_UnmarshalRejectsMissingIntegers
(now TestReservationProposals_UnmarshalRejectsInvalidFields) to
construct real protobuf payloads instead of JSON string literals,
porting every original missing-field case plus two new structural
cases (invalid hash/pubkey-hash length) that fall out of the new
wire format.

go test ./pkg/tbtc/...: 15/15 new/changed tests pass, full package
suite passes (146s), -race clean (156s). gofmt/vet clean on all 6
changed files.
…g coverage

- rename TestReservationProposals_UnmarshalRejectsMissingIntegers to
  ...RejectsInvalidFields, matching what the PR description already claimed
- add rejection cases proving a zero *big.Int fee/key marshals to the same
  empty-bytes wire representation as an omitted field, exercised through
  each proposal's real Marshal() method
- fix reservation fuzz test loops to match the sibling for-i convention
@piotr-roslaniec
piotr-roslaniec force-pushed the m1/reservation-protobuf-marshaling branch from 5c1f8f5 to 87c6a68 Compare September 2, 2026 18:13
@piotr-roslaniec piotr-roslaniec changed the title feat(tbtc): switch reservation proposal marshaling to protobuf test(tbtc): add reservation proposal marshaling coverage Sep 2, 2026
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.

1 participant