Skip to content

Conversation

@agaffney
Copy link
Contributor

@agaffney agaffney commented Nov 29, 2025

Fixes #449


Summary by cubic

Added decoding support for additional Handshake covenant types to fully parse transactions across the name lifecycle. Fixes #449.

  • New Features
    • Support for None, Claim, Open, Bid, Reveal, Redeem, Renew, Transfer, Finalize, and Revoke, with conversions from GenericCovenant.
    • Fail-fast on unknown types and add item-length checks; decode heights, flags, names, and hashes for each type.

Written for commit 7daedf1. Summary will update automatically on new commits.

Summary by CodeRabbit

Refactor

  • Expanded covenant handling with distinct covenant variants (None, Claim, Open, Bid, Reveal, Redeem, Renew, Transfer, Finalize, Revoke), adding explicit parsing, stricter validation and length checks, explicit field population, deep-copying of binary fields, and improved error reporting for mismatches to ensure safer, clearer processing of covenant data.

✏️ Tip: You can customize this high-level summary in your review settings.

@agaffney agaffney requested a review from a team as a code owner November 29, 2025 20:08
@coderabbitai
Copy link

coderabbitai bot commented Nov 29, 2025

📝 Walkthrough

Walkthrough

This PR adds explicit concrete covenant types and conversion constructors for many Handshake covenant variants. It introduces NoneCovenant, ClaimCovenant, OpenCovenant, BidCovenant, RevealCovenant, RedeemCovenant, RenewCovenant, TransferCovenant, FinalizeCovenant, and RevokeCovenant, each with an isCovenant() marker and NewFromGeneric(gc *GenericCovenant) constructors. Each constructor validates covenant type and item counts, enforces per-item length checks, decodes little-endian numeric fields (uint32/uint8), deep-copies hash fields, and populates RawName/NameHash where applicable. Covenant() dispatching was extended to route to these constructors and panics on conversion errors or unknown types.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify per-constructor item count and length validations against the Handshake spec.
  • Check all binary.LittleEndian decodes for Height/Claimed/Renewals and uint8 Flags/AddrVersion.
  • Review deep-copy logic for hash slices to avoid aliasing.
  • Confirm Covenant() routing covers all CovenantTypeX values and that panic behavior is intentional.

Files/areas needing extra attention:

  • internal/handshake/covenant.go (new constructors, type declarations, and Covenant() dispatcher)
  • NewFinalizeCovenantFromGeneric and NewClaimCovenantFromGeneric (multiple numeric fields decoded)
  • Any previously existing constructors updated with tightened length checks (e.g., Register/Update variants)

Possibly related PRs

  • feat: initial Handshake indexer support #447 — Modifies internal/handshake/covenant.go with overlapping covenant parsing changes (e.g., UpdateCovenant item count and BlockHash handling), indicating a strong code-level relationship.

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: decode support for additional Handshake covenants' accurately summarizes the main change: adding decoding support for multiple new covenant types beyond existing REGISTER/UPDATE support.
Linked Issues check ✅ Passed The PR successfully implements the objective from issue #449 by adding comprehensive decoding support for None, Claim, Open, Bid, Reveal, Redeem, Renew, Transfer, Finalize, and Revoke covenants, including robust parsing with item-length checks and fail-fast on unknown types.
Out of Scope Changes check ✅ Passed All changes are directly related to the covenant decoding objective; no out-of-scope modifications were introduced beyond the required new covenant type constructors and supporting infrastructure.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/handshake-additional-covenants

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (2)
internal/handshake/covenant.go (2)

65-142: Consider returning errors instead of panicking in the Covenant() method.

Panicking in library code can crash caller applications unexpectedly. While the current pattern is consistent with the existing Register/Update handling, consider changing the signature to Covenant() (Covenant, error) to give callers control over error handling.


172-196: Consider extracting a helper for safe uint32 decoding.

The pattern of decoding uint32 from items is repeated across many constructors. A small helper could centralize the bounds check and reduce duplication.

func decodeUint32(data []byte) (uint32, error) {
	if len(data) < 4 {
		return 0, errors.New("insufficient bytes for uint32")
	}
	return binary.LittleEndian.Uint32(data), nil
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 206e4df and 8363e66.

📒 Files selected for processing (1)
  • internal/handshake/covenant.go (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Analyze (go)
🔇 Additional comments (2)
internal/handshake/covenant.go (2)

144-159: LGTM!

The NoneCovenant implementation correctly validates that items are empty and returns an appropriate error otherwise.


198-223: LGTM!

The OpenCovenant implementation safely copies hashes and converts the raw name. The comment on line 219 about ignoring index 1 is helpful documentation.

Fixes #449

Signed-off-by: Aurora Gaffney <aurora@blinklabs.io>
@agaffney agaffney force-pushed the feat/handshake-additional-covenants branch from 8363e66 to 7daedf1 Compare November 29, 2025 20:22
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
internal/handshake/covenant.go (2)

65-142: Consider returning errors instead of panicking.

The method panics on conversion errors and unknown covenant types, which will crash the application. If this code processes untrusted or externally-sourced data, consider returning (Covenant, error) to allow graceful error handling upstream.


211-229: Consider validating that item[1] is zero.

The comment on line 225 notes that index 1 "always contains 0". For additional robustness against malformed input, you could add a check to verify this assumption.

 	// Copy hash
 	copy(ret.NameHash, gc.Items[0])
-	// NOTE: purposely ignoring index 1, which always contains 0
+	// Validate that item[1] is zero as expected
+	if len(gc.Items[1]) != 1 || gc.Items[1][0] != 0 {
+		return nil, errors.New("item[1] must be zero")
+	}
 	// Raw name
 	ret.RawName = string(gc.Items[2])
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8363e66 and 7daedf1.

📒 Files selected for processing (1)
  • internal/handshake/covenant.go (5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Analyze (go)
🔇 Additional comments (11)
internal/handshake/covenant.go (11)

144-159: LGTM!

The NoneCovenant implementation correctly validates the covenant type and ensures no items are present.


172-202: LGTM! Bounds checks properly added.

The constructor now includes proper length validation for all items before accessing them (lines 181-186), addressing the previous review concern about missing bounds checks.


240-264: LGTM! Bounds check properly added.

The constructor now validates the height item length (line 249-251) before decoding, addressing the previous review concern.


274-296: LGTM! Bounds check properly added.

The constructor now validates the height item length (line 283-285) before decoding, addressing the previous review concern.


305-325: LGTM! Bounds check properly added.

The constructor now validates the height item length (line 314-316) before decoding, addressing the previous review concern.


336-364: LGTM! Bounds check added.

The constructor properly validates the height item length (line 345-347) before decoding, following the same safe pattern as other covenant constructors.


374-400: LGTM! Bounds check added.

The constructor properly validates the height item length (line 383-385) before decoding, following the same safe pattern as other covenant constructors.


410-432: LGTM! Bounds check properly added.

The constructor now validates the height item length (line 419-421) before decoding, addressing the previous review concern.


443-470: LGTM! Bounds checks properly added.

The constructor now validates both the height item length (line 452-454) and address version item length (line 455-457) before accessing them, addressing the previous review concern.


484-515: LGTM! Bounds checks properly added.

The constructor now validates all item lengths before accessing them (lines 493-498), including all uint32 fields and the uint8 flags field, addressing the previous review concern.


524-544: LGTM! Bounds check properly added.

The constructor now validates the height item length (line 533-535) before decoding, addressing the previous review concern.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 1 file

@agaffney agaffney merged commit 2e8f3b5 into main Nov 29, 2025
12 checks passed
@agaffney agaffney deleted the feat/handshake-additional-covenants branch November 29, 2025 20:42
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.

Decode additional Handshake covenant types

3 participants