Skip to content

feat: enable recvcheck linter and corrected the reported issues#1433

Open
cryptodj413 wants to merge 1 commit intoblinklabs-io:mainfrom
cryptodj413:fix/recvcheck
Open

feat: enable recvcheck linter and corrected the reported issues#1433
cryptodj413 wants to merge 1 commit intoblinklabs-io:mainfrom
cryptodj413:fix/recvcheck

Conversation

@cryptodj413
Copy link
Contributor

@cryptodj413 cryptodj413 commented Jan 15, 2026

Closes #936


Summary by cubic

Enable recvcheck in golangci-lint and fix receiver usage across the codebase. Methods now consistently use pointer receivers, and call sites, type switches, and tests were updated to use pointer concrete types to ensure interface conformance and avoid unintended copies.

  • Refactors

    • Enabled recvcheck in .golangci.yml.
    • Switched many methods to pointer receivers (e.g., Type(), Id(), Hash(), Cbor(), MarshalJSON/CBOR, ToPlutusData).
    • Updated interfaces and type switches to pointer concrete types (e.g., *PlutusV1/V2/V3Script, *AddressPayloadKeyHash, *MetaMap/*MetaInt/*MetaText/*MetaBytes/*MetaList).
    • Adjusted UTxO construction to pass pointers for Id and Output where needed.
    • ProtocolParameterUpdates now return maps of pointer values.
    • Aligned ScriptRef and metadata handling to store/compare pointer scripts and metadata.
  • Migration

    • Update type assertions/switches to pointer types (e.g., *common.PlutusV1Script, *common.MetaMap, *common.AddressPayloadKeyHash).
    • Pass addresses of values when assigning to interfaces (e.g., Utxo.Id, Utxo.Output, ScriptRef.Script).
    • Treat protocol parameter update map values as pointers.
    • Marshal/encode using pointers where required (e.g., json.Marshal(&genesisConfig)).

Written for commit bd53e47. Summary will update on new commits.

Summary by CodeRabbit

  • Refactor
    • Standardized method receivers and data structure handling across ledger types for improved memory efficiency and consistency.

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

Signed-off-by: cryptodj413 <shinjirohara2@gmail.com>
@cryptodj413 cryptodj413 requested a review from a team as a code owner January 15, 2026 15:21
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

📝 Walkthrough

Walkthrough

This pull request systematically converts method receivers across the codebase from value receivers to pointer receivers to resolve linter violations. The .golangci.yml file enables the recvcheck linter, which validates receiver type consistency. Changes affect core ledger types across all eras (Shelley, Allegra, Mary, Alonzo, Babbage, Conway, Byron, Leios), common types (Address, certificates, governance actions, metadata, scripts), and supporting modules (CBOR, protocol). Additionally, some struct field types are modified from values to pointers (e.g., Utxo.Output, Utxo.Id, ScriptRef.Script), and method implementations are adjusted to accommodate pointer semantics.

Possibly related PRs

  • refactor(ledger): rules, errors, and formatting #1418: Modifies script method receivers and implementations in ledger/common/script.go, directly overlapping with this PR's conversion of Hash(), RawScriptBytes(), and Evaluate() methods to pointer receivers.
  • fix(ledger): lenient conway witness switch #1366: Updates Plutus script type switches in ledger/conway/rules.go to handle both pointer and value forms, directly conflicting with this PR's conversion to pointer-only type switches.
  • feat(ledger): signature validation #1355: Adds script-witness validation methods to ledger/common/rules.go that interact with the same script type assertions and witness-validation paths being updated for pointer receivers in this PR.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly describes the main change: enabling the recvcheck linter and fixing reported issues.
Linked Issues check ✅ Passed The PR comprehensively addresses issue #936 by enabling recvcheck in .golangci.yml and systematically converting value receivers to pointer receivers throughout the codebase to resolve linter errors.
Out of Scope Changes check ✅ Passed All changes are directly related to enabling recvcheck and fixing mixed receiver issues. Test file changes involve constructing pointers to match updated method signatures, which are in scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings


📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32490ac and bd53e47.

📒 Files selected for processing (52)
  • .golangci.yml
  • cbor/cbor.go
  • cbor/value.go
  • internal/test/conformance/conformance_test.go
  • ledger/allegra/allegra.go
  • ledger/allegra/rules_test.go
  • ledger/alonzo/alonzo.go
  • ledger/alonzo/pparams.go
  • ledger/alonzo/rules_test.go
  • ledger/babbage/babbage.go
  • ledger/babbage/errors_test.go
  • ledger/babbage/pparams.go
  • ledger/babbage/rules.go
  • ledger/babbage/rules_test.go
  • ledger/byron/byron.go
  • ledger/byron/genesis.go
  • ledger/byron/genesis_test.go
  • ledger/common/address.go
  • ledger/common/auxiliary_data_integration_test.go
  • ledger/common/certs.go
  • ledger/common/gov.go
  • ledger/common/metadata.go
  • ledger/common/metadata_test.go
  • ledger/common/rules.go
  • ledger/common/script.go
  • ledger/common/script/context_test.go
  • ledger/common/script_test.go
  • ledger/common/verify.go
  • ledger/common/witness.go
  • ledger/conway/conway.go
  • ledger/conway/conway_test.go
  • ledger/conway/errors_test.go
  • ledger/conway/gov.go
  • ledger/conway/pparams.go
  • ledger/conway/rules.go
  • ledger/conway/rules_test.go
  • ledger/error.go
  • ledger/error_test.go
  • ledger/leios/leios.go
  • ledger/leios/pparams.go
  • ledger/mary/mary.go
  • ledger/mary/pparams.go
  • ledger/mary/rules_test.go
  • ledger/shelley/genesis.go
  • ledger/shelley/genesis_test.go
  • ledger/shelley/pparams.go
  • ledger/shelley/rules.go
  • ledger/shelley/rules_test.go
  • ledger/shelley/shelley.go
  • protocol/common/dmq.go
  • protocol/localstatequery/client_test.go
  • protocol/localstatequery/queries.go
💤 Files with no reviewable changes (1)
  • ledger/common/rules.go
🧰 Additional context used
📓 Path-based instructions (8)
ledger/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

ledger/**/*.go: Use cbor.StructAsArray embedded type to enable CBOR array encoding for struct types
Use cbor.DecodeStoreCbor embedded type to preserve original CBOR bytes for hashing operations. Implement custom UnmarshalCBOR method and call SetCbor(cborData) to store original bytes
Always use preserved original CBOR bytes via Cbor() method for hash computation, not re-encoded data
Encode language views map with keys sorted by 'shortLex' order (length first, then lexicographic) as per Cardano Ledger Specification
For PlutusV1 cost models in language views: use double-bagged encoding with tag 0x4100 and wrap indefinite list in bytestring
For PlutusV2/V3 cost models in language views: use tag 0x01 or 0x02 with definite list encoding (no bytestring wrapper)
ScriptDataHash must be computed as Blake2b256(redeemers || datums || language_views) following Cardano Ledger Specification

Files:

  • ledger/shelley/pparams.go
  • ledger/common/witness.go
  • ledger/shelley/genesis_test.go
  • ledger/babbage/pparams.go
  • ledger/babbage/rules.go
  • ledger/common/metadata_test.go
  • ledger/babbage/rules_test.go
  • ledger/leios/leios.go
  • ledger/mary/rules_test.go
  • ledger/alonzo/pparams.go
  • ledger/conway/pparams.go
  • ledger/common/auxiliary_data_integration_test.go
  • ledger/common/gov.go
  • ledger/common/verify.go
  • ledger/conway/rules.go
  • ledger/shelley/rules_test.go
  • ledger/babbage/errors_test.go
  • ledger/shelley/genesis.go
  • ledger/mary/pparams.go
  • ledger/common/script/context_test.go
  • ledger/byron/genesis.go
  • ledger/allegra/rules_test.go
  • ledger/conway/gov.go
  • ledger/shelley/rules.go
  • ledger/conway/conway_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/byron/genesis_test.go
  • ledger/error.go
  • ledger/leios/pparams.go
  • ledger/common/script_test.go
  • ledger/conway/errors_test.go
  • ledger/common/metadata.go
  • ledger/conway/conway.go
  • ledger/common/script.go
  • ledger/byron/byron.go
  • ledger/alonzo/rules_test.go
  • ledger/common/address.go
  • ledger/common/certs.go
  • ledger/allegra/allegra.go
  • ledger/shelley/shelley.go
  • ledger/mary/mary.go
  • ledger/babbage/babbage.go
  • ledger/alonzo/alonzo.go
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Enforce 80 character line limit in Go code using golines formatter
Apply Apache 2.0 license header to all new Go files
Use gofmt and goimports for automatic code formatting
Pass all linter checks with make lint or golangci-lint run ./... before submission

Files:

  • ledger/shelley/pparams.go
  • ledger/common/witness.go
  • internal/test/conformance/conformance_test.go
  • ledger/shelley/genesis_test.go
  • ledger/babbage/pparams.go
  • ledger/babbage/rules.go
  • ledger/common/metadata_test.go
  • ledger/babbage/rules_test.go
  • ledger/leios/leios.go
  • ledger/mary/rules_test.go
  • ledger/alonzo/pparams.go
  • ledger/conway/pparams.go
  • ledger/common/auxiliary_data_integration_test.go
  • ledger/common/gov.go
  • ledger/common/verify.go
  • ledger/conway/rules.go
  • ledger/shelley/rules_test.go
  • ledger/babbage/errors_test.go
  • protocol/common/dmq.go
  • ledger/shelley/genesis.go
  • ledger/mary/pparams.go
  • ledger/common/script/context_test.go
  • cbor/cbor.go
  • ledger/byron/genesis.go
  • ledger/allegra/rules_test.go
  • ledger/conway/gov.go
  • ledger/shelley/rules.go
  • ledger/conway/conway_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • protocol/localstatequery/queries.go
  • ledger/byron/genesis_test.go
  • ledger/error.go
  • ledger/leios/pparams.go
  • ledger/common/script_test.go
  • cbor/value.go
  • protocol/localstatequery/client_test.go
  • ledger/conway/errors_test.go
  • ledger/common/metadata.go
  • ledger/conway/conway.go
  • ledger/common/script.go
  • ledger/byron/byron.go
  • ledger/alonzo/rules_test.go
  • ledger/common/address.go
  • ledger/common/certs.go
  • ledger/allegra/allegra.go
  • ledger/shelley/shelley.go
  • ledger/mary/mary.go
  • ledger/babbage/babbage.go
  • ledger/alonzo/alonzo.go
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*_test.go: Use testify assertion library for test assertions in Go tests
All Go tests must pass with race detection via make test before submission

Files:

  • internal/test/conformance/conformance_test.go
  • ledger/shelley/genesis_test.go
  • ledger/common/metadata_test.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/common/auxiliary_data_integration_test.go
  • ledger/shelley/rules_test.go
  • ledger/babbage/errors_test.go
  • ledger/common/script/context_test.go
  • ledger/allegra/rules_test.go
  • ledger/conway/conway_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/byron/genesis_test.go
  • ledger/common/script_test.go
  • protocol/localstatequery/client_test.go
  • ledger/conway/errors_test.go
  • ledger/alonzo/rules_test.go
ledger/**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

Use MockLedgerState from internal/test/ledger/ledger.go for validation tests instead of creating custom mocks

Files:

  • ledger/shelley/genesis_test.go
  • ledger/common/metadata_test.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/common/auxiliary_data_integration_test.go
  • ledger/shelley/rules_test.go
  • ledger/babbage/errors_test.go
  • ledger/common/script/context_test.go
  • ledger/allegra/rules_test.go
  • ledger/conway/conway_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/byron/genesis_test.go
  • ledger/common/script_test.go
  • ledger/conway/errors_test.go
  • ledger/alonzo/rules_test.go
.golangci.yml

📄 CodeRabbit inference engine (AGENTS.md)

Configure .golangci.yml with enabled linters including gosec, errorlint, and exhaustive

Files:

  • .golangci.yml
ledger/**/rules.go

📄 CodeRabbit inference engine (AGENTS.md)

ledger/**/rules.go: Implement validation rule functions with signature: func UtxoValidate{RuleName}(tx common.Transaction, slot uint64, ls common.LedgerState, pp common.ProtocolParameters) error - return nil on success or a specific error type on failure
Add new validation rules to the UtxoValidationRules slice in the appropriate era package at the correct position in the rule order
Reference inputs are resolved but never consumed from the UTxO set
Collateral inputs are only consumed from UTxO set when transaction IsValid flag is false
Datum lookup must check witness set, inline datums, AND reference inputs in that order
Verify cost models exist for each Plutus version used in transaction before script execution
Later eras must call parent era functions for shared validation logic, not duplicate logic

Files:

  • ledger/babbage/rules.go
  • ledger/conway/rules.go
  • ledger/shelley/rules.go
ledger/common/certs.go

📄 CodeRabbit inference engine (AGENTS.md)

Define certificate structs in ledger/common/certs.go with CBOR tags before adding new certificate types

Files:

  • ledger/common/certs.go
ledger/**/certs.go

📄 CodeRabbit inference engine (AGENTS.md)

Update certificate parsing switch statement when adding support for new certificate types

Files:

  • ledger/common/certs.go
🧠 Learnings (22)
📓 Common learnings
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : Use `cbor.StructAsArray` embedded type to enable CBOR array encoding for struct types
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Collateral inputs are only consumed from UTxO set when transaction `IsValid` flag is false

Applied to files:

  • ledger/common/witness.go
  • ledger/babbage/rules.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/babbage/errors_test.go
  • ledger/common/script/context_test.go
  • ledger/allegra/rules_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/conway/errors_test.go
  • ledger/conway/conway.go
  • ledger/alonzo/rules_test.go
  • ledger/allegra/allegra.go
  • ledger/mary/mary.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : Use `cbor.DecodeStoreCbor` embedded type to preserve original CBOR bytes for hashing operations. Implement custom `UnmarshalCBOR` method and call `SetCbor(cborData)` to store original bytes

Applied to files:

  • internal/test/conformance/conformance_test.go
  • ledger/common/metadata_test.go
  • ledger/shelley/genesis.go
  • cbor/cbor.go
  • ledger/error_test.go
  • ledger/error.go
  • cbor/value.go
  • ledger/common/metadata.go
  • ledger/byron/byron.go
  • ledger/common/address.go
  • ledger/common/certs.go
  • ledger/shelley/shelley.go
  • ledger/babbage/babbage.go
  • ledger/alonzo/alonzo.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : Always use preserved original CBOR bytes via `Cbor()` method for hash computation, not re-encoded data

Applied to files:

  • internal/test/conformance/conformance_test.go
  • ledger/common/metadata_test.go
  • ledger/babbage/rules_test.go
  • ledger/common/verify.go
  • ledger/shelley/genesis.go
  • cbor/cbor.go
  • ledger/shelley/rules.go
  • ledger/conway/conway_test.go
  • ledger/error_test.go
  • ledger/byron/genesis_test.go
  • ledger/error.go
  • cbor/value.go
  • ledger/common/metadata.go
  • ledger/byron/byron.go
  • ledger/common/address.go
  • ledger/shelley/shelley.go
  • ledger/mary/mary.go
  • ledger/babbage/babbage.go
  • ledger/alonzo/alonzo.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : Use `cbor.StructAsArray` embedded type to enable CBOR array encoding for struct types

Applied to files:

  • internal/test/conformance/conformance_test.go
  • ledger/shelley/genesis.go
  • cbor/cbor.go
  • ledger/error_test.go
  • ledger/error.go
  • cbor/value.go
  • ledger/common/metadata.go
  • ledger/conway/conway.go
  • ledger/byron/byron.go
  • ledger/common/address.go
  • ledger/babbage/babbage.go
  • ledger/alonzo/alonzo.go
📚 Learning: 2025-11-04T15:54:22.683Z
Learnt from: wolf31o2
Repo: blinklabs-io/gouroboros PR: 1093
File: ledger/mary/pparams.go:143-150
Timestamp: 2025-11-04T15:54:22.683Z
Learning: In the blinklabs-io/gouroboros repository, the design goal for CBOR round-trip tests is to achieve byte-identical encoding WITHOUT using stored CBOR (cbor.DecodeStoreCbor). Instead, the approach uses proper field types (pointers for optional fields) and relies on the cbor package's deterministic encoding (SortCoreDeterministic) to ensure reproducible output. The stored CBOR pattern should not be suggested as a solution for round-trip fidelity in this codebase.

Applied to files:

  • internal/test/conformance/conformance_test.go
  • cbor/cbor.go
  • ledger/error_test.go
  • ledger/common/script_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to .golangci.yml : Configure `.golangci.yml` with enabled linters including `gosec`, `errorlint`, and `exhaustive`

Applied to files:

  • .golangci.yml
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to **/*.go : Pass all linter checks with `make lint` or `golangci-lint run ./...` before submission

Applied to files:

  • .golangci.yml
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : ScriptDataHash must be computed as Blake2b256(redeemers || datums || language_views) following Cardano Ledger Specification

Applied to files:

  • ledger/babbage/rules.go
  • ledger/conway/rules.go
  • ledger/babbage/errors_test.go
  • ledger/shelley/rules.go
  • ledger/conway/conway_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/error.go
  • ledger/common/script_test.go
  • ledger/conway/errors_test.go
  • ledger/common/script.go
  • ledger/byron/byron.go
  • ledger/common/address.go
  • ledger/shelley/shelley.go
  • ledger/mary/mary.go
  • ledger/babbage/babbage.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Verify cost models exist for each Plutus version used in transaction before script execution

Applied to files:

  • ledger/babbage/rules.go
  • ledger/conway/rules.go
  • ledger/babbage/errors_test.go
  • ledger/conway/conway_test.go
  • ledger/conway/errors_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Add new validation rules to the `UtxoValidationRules` slice in the appropriate era package at the correct position in the rule order

Applied to files:

  • ledger/babbage/rules.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/shelley/rules_test.go
  • ledger/common/script/context_test.go
  • ledger/allegra/rules_test.go
  • ledger/shelley/rules.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/alonzo/rules_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Implement validation rule functions with signature: `func UtxoValidate{RuleName}(tx common.Transaction, slot uint64, ls common.LedgerState, pp common.ProtocolParameters) error` - return nil on success or a specific error type on failure

Applied to files:

  • ledger/babbage/rules.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/shelley/rules_test.go
  • ledger/babbage/errors_test.go
  • ledger/common/script/context_test.go
  • ledger/allegra/rules_test.go
  • ledger/shelley/rules.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/conway/errors_test.go
  • ledger/alonzo/rules_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/certs.go : Update certificate parsing switch statement when adding support for new certificate types

Applied to files:

  • ledger/babbage/rules.go
  • ledger/common/verify.go
  • ledger/conway/rules.go
  • ledger/shelley/rules.go
  • ledger/common/certs.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Reference inputs are resolved but never consumed from the UTxO set

Applied to files:

  • ledger/babbage/rules.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/shelley/rules_test.go
  • ledger/babbage/errors_test.go
  • ledger/common/script/context_test.go
  • ledger/allegra/rules_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/error.go
  • ledger/conway/errors_test.go
  • ledger/byron/byron.go
  • ledger/alonzo/rules_test.go
  • ledger/allegra/allegra.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/native.go : Implement `NativeScript.Evaluate(slot uint64, validityStart, validityEnd uint64, keyHashes map[Blake2b224]bool) bool` for native script validation

Applied to files:

  • ledger/babbage/rules.go
  • ledger/conway/rules.go
  • ledger/common/script.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : For PlutusV2/V3 cost models in language views: use tag `0x01` or `0x02` with definite list encoding (no bytestring wrapper)

Applied to files:

  • ledger/babbage/rules.go
  • ledger/conway/rules.go
  • ledger/byron/byron.go
  • ledger/babbage/babbage.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : For PlutusV1 cost models in language views: use double-bagged encoding with tag `0x4100` and wrap indefinite list in bytestring

Applied to files:

  • ledger/babbage/rules.go
  • ledger/conway/rules.go
  • ledger/byron/byron.go
  • ledger/babbage/babbage.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*_test.go : Use `MockLedgerState` from `internal/test/ledger/ledger.go` for validation tests instead of creating custom mocks

Applied to files:

  • ledger/common/metadata_test.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/common/auxiliary_data_integration_test.go
  • ledger/babbage/errors_test.go
  • ledger/allegra/rules_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/byron/genesis_test.go
  • ledger/conway/errors_test.go
  • ledger/alonzo/rules_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Datum lookup must check witness set, inline datums, AND reference inputs in that order

Applied to files:

  • ledger/common/verify.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Create new era package structure following pattern: `ledger/{era_name}/` with types extending previous era, `rules.go` inheriting parent rules, and compatibility exports at `ledger/{era_name}.go`

Applied to files:

  • ledger/error_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Later eras must call parent era functions for shared validation logic, not duplicate logic

Applied to files:

  • ledger/error_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/common/certs.go : Define certificate structs in `ledger/common/certs.go` with CBOR tags before adding new certificate types

Applied to files:

  • cbor/value.go
  • ledger/common/certs.go
🧬 Code graph analysis (37)
ledger/shelley/pparams.go (1)
ledger/shelley.go (1)
  • ShelleyProtocolParameterUpdate (32-32)
ledger/common/witness.go (1)
ledger/common/address.go (2)
  • AddressPayloadKeyHash (691-693)
  • AddressPayloadKeyHash (695-695)
ledger/shelley/genesis_test.go (1)
ledger/common/address.go (1)
  • Address (62-70)
ledger/babbage/pparams.go (1)
ledger/babbage.go (1)
  • BabbageProtocolParameterUpdate (31-31)
ledger/babbage/rules.go (1)
ledger/common/script.go (4)
  • PlutusV1Script (140-140)
  • PlutusV1Script (142-142)
  • PlutusV2Script (216-216)
  • PlutusV2Script (218-218)
ledger/common/metadata_test.go (2)
ledger/common/metadata.go (4)
  • MetaMap (77-80)
  • MetaMap (86-86)
  • MetaInt (51-54)
  • MetaInt (82-82)
ledger/common/script/wrappers.go (1)
  • Pairs (46-46)
ledger/babbage/rules_test.go (3)
ledger/shelley.go (1)
  • ShelleyTransactionOutput (29-29)
ledger/babbage/babbage.go (1)
  • BabbageTransactionOutput (556-563)
ledger/babbage.go (1)
  • BabbageTransactionOutput (28-28)
ledger/leios/leios.go (1)
ledger/leios.go (1)
  • LeiosRankingBlock (26-26)
ledger/mary/rules_test.go (1)
ledger/shelley/shelley.go (1)
  • ShelleyTransactionOutput (433-438)
ledger/alonzo/pparams.go (1)
ledger/alonzo.go (1)
  • AlonzoProtocolParameterUpdate (31-31)
ledger/conway/pparams.go (2)
ledger/conway.go (1)
  • ConwayProtocolParameterUpdate (30-30)
ledger/common/script/wrappers.go (1)
  • ToPlutusData (28-30)
ledger/common/verify.go (1)
ledger/common/address.go (2)
  • AddressPayloadKeyHash (691-693)
  • AddressPayloadKeyHash (695-695)
ledger/conway/rules.go (2)
ledger/common/script.go (6)
  • PlutusV1Script (140-140)
  • PlutusV1Script (142-142)
  • PlutusV2Script (216-216)
  • PlutusV2Script (218-218)
  • PlutusV3Script (292-292)
  • PlutusV3Script (294-294)
ledger/common/address.go (4)
  • AddressPayloadKeyHash (691-693)
  • AddressPayloadKeyHash (695-695)
  • AddressPayloadScriptHash (697-699)
  • AddressPayloadScriptHash (701-701)
ledger/shelley/rules_test.go (1)
ledger/shelley/shelley.go (1)
  • ShelleyTransactionOutput (433-438)
ledger/babbage/errors_test.go (1)
ledger/common/script.go (2)
  • PlutusV1Script (140-140)
  • PlutusV1Script (142-142)
ledger/shelley/genesis.go (1)
ledger/shelley/shelley.go (1)
  • ShelleyTransactionOutput (433-438)
ledger/byron/genesis.go (3)
ledger/byron/byron.go (2)
  • ByronTransactionInput (681-685)
  • ByronTransactionOutput (765-770)
protocol/txsubmission/messages.go (1)
  • TxId (191-195)
ledger/common/common.go (1)
  • Blake2b256Hash (90-102)
ledger/allegra/rules_test.go (1)
ledger/shelley/shelley.go (1)
  • ShelleyTransactionOutput (433-438)
ledger/conway/gov.go (1)
ledger/common/script/wrappers.go (1)
  • ToPlutusData (28-30)
ledger/shelley/rules.go (2)
ledger/common/metadata.go (10)
  • MetaText (61-64)
  • MetaText (84-84)
  • MetaBytes (56-59)
  • MetaBytes (83-83)
  • MetaInt (51-54)
  • MetaInt (82-82)
  • MetaList (66-69)
  • MetaList (85-85)
  • MetaMap (77-80)
  • MetaMap (86-86)
ledger/common/address.go (4)
  • AddressPayloadKeyHash (691-693)
  • AddressPayloadKeyHash (695-695)
  • AddressPayloadScriptHash (697-699)
  • AddressPayloadScriptHash (701-701)
ledger/conway/conway_test.go (1)
ledger/common/script.go (3)
  • Script (38-42)
  • PlutusV1Script (140-140)
  • PlutusV1Script (142-142)
ledger/error_test.go (3)
ledger/common/address.go (1)
  • Address (62-70)
ledger/shelley/shelley.go (1)
  • ShelleyTransactionOutput (433-438)
ledger/byron/byron.go (1)
  • ByronTransactionInput (681-685)
ledger/conway/rules_test.go (3)
ledger/common/script.go (2)
  • PlutusV1Script (140-140)
  • PlutusV1Script (142-142)
ledger/shelley/shelley.go (2)
  • ShelleyTransactionOutput (433-438)
  • NewShelleyTransactionInput (388-400)
ledger/babbage/babbage.go (1)
  • BabbageTransactionOutput (556-563)
ledger/byron/genesis_test.go (1)
ledger/common/address.go (1)
  • Address (62-70)
ledger/leios/pparams.go (1)
ledger/leios.go (1)
  • LeiosProtocolParameterUpdate (31-31)
ledger/common/script_test.go (1)
ledger/common/script.go (1)
  • Script (38-42)
ledger/conway/errors_test.go (1)
ledger/common/script.go (6)
  • PlutusV2Script (216-216)
  • PlutusV2Script (218-218)
  • PlutusV1Script (140-140)
  • PlutusV1Script (142-142)
  • PlutusV3Script (292-292)
  • PlutusV3Script (294-294)
ledger/conway/conway.go (3)
ledger/common/redeemer.go (3)
  • RedeemerKey (32-36)
  • RedeemerValue (38-42)
  • RedeemerTag (21-21)
ledger/common/witness.go (2)
  • VkeyWitness (21-25)
  • BootstrapWitness (27-33)
ledger/common/tx.go (4)
  • TransactionWitnessRedeemers (98-102)
  • TransactionInput (66-72)
  • TransactionOutput (74-85)
  • Utxo (104-108)
ledger/common/script.go (2)
cbor/decode.go (1)
  • Decode (29-44)
ledger/common/common.go (1)
  • Blake2b224Hash (151-163)
ledger/byron/byron.go (1)
ledger/byron.go (5)
  • ByronTransaction (28-28)
  • NewByronTransactionInput (48-48)
  • ByronTransactionInput (29-29)
  • ByronTransactionOutput (30-30)
  • ByronEpochBoundaryBlock (24-24)
ledger/alonzo/rules_test.go (2)
ledger/shelley/shelley.go (1)
  • ShelleyTransactionOutput (433-438)
ledger/alonzo/alonzo.go (1)
  • AlonzoTransactionOutput (351-358)
ledger/common/address.go (2)
ledger/compat.go (2)
  • AddrKeyHash (41-41)
  • Address (40-40)
ledger/common/script.go (1)
  • ScriptHash (36-36)
ledger/common/certs.go (1)
ledger/compat.go (3)
  • StakeDelegationCertificate (68-68)
  • PoolRegistrationCertificate (67-67)
  • PoolRetirementCertificate (66-66)
ledger/allegra/allegra.go (1)
ledger/common/pparams.go (1)
  • ProtocolParameterUpdate (24-27)
ledger/shelley/shelley.go (2)
ledger/common/script/wrappers.go (1)
  • ToPlutusData (28-30)
ledger/common/tx.go (3)
  • TransactionInput (66-72)
  • TransactionOutput (74-85)
  • Utxo (104-108)
ledger/mary/mary.go (4)
ledger/common/tx.go (3)
  • TransactionInput (66-72)
  • TransactionOutput (74-85)
  • Utxo (104-108)
ledger/common/pparams.go (1)
  • ProtocolParameterUpdate (24-27)
ledger/common/certs.go (1)
  • Certificate (128-133)
ledger/common/script.go (2)
  • ScriptRef (66-69)
  • Script (38-42)
ledger/babbage/babbage.go (2)
ledger/common/script/wrappers.go (1)
  • ToPlutusData (28-30)
ledger/common/tx.go (3)
  • TransactionInput (66-72)
  • TransactionOutput (74-85)
  • Utxo (104-108)
⏰ 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: go-test (1.24.x, ubuntu-latest)
  • GitHub Check: cubic · AI code reviewer

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


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
Contributor

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
ledger/error.go (2)

680-696: Critical: Loop variable pointer capture bug.

Taking &input inside a range loop captures the address of the loop variable, which is reused across iterations. All Utxo entries in the slice will point to the same memory location containing the last iteration's value.

🐛 Proposed fix
 		e.Utxos = make([]common.Utxo, 0, len(shelleyUtxoMap))
 		for input, outputCbor := range shelleyUtxoMap {
+			input := input // create a new variable scoped to this iteration
 			// Decode output using era-agnostic function (handles all eras)
 			output, err := NewTransactionOutputFromCbor(outputCbor)
 			if err != nil {
 				return fmt.Errorf(
 					"failed to decode transaction output: %w",
 					err,
 				)
 			}

 			e.Utxos = append(e.Utxos, common.Utxo{
 				Id:     &input,
 				Output: output,
 			})
 		}

700-720: Same loop variable capture bug in Byron path.

The Byron input decoding path has the identical issue with &input capturing the loop variable address.

🐛 Proposed fix
 		e.Utxos = make([]common.Utxo, 0, len(byronUtxoMap))
 		for input, outputCbor := range byronUtxoMap {
+			input := input // create a new variable scoped to this iteration
 			// Decode output using era-agnostic function (handles all eras)
 			output, err := NewTransactionOutputFromCbor(outputCbor)
 			if err != nil {
 				return fmt.Errorf(
 					"failed to decode transaction output: %w",
 					err,
 				)
 			}

 			e.Utxos = append(e.Utxos, common.Utxo{
 				Id:     &input,
 				Output: output,
 			})
 		}
ledger/common/certs.go (1)

322-328: Add nil check for StakeCredential pointer before dereferencing in Utxorpc() method.

The StakeCredential field is defined as a pointer (*Credential) at line 326, which differs from all other certificate types in the file that use non-pointer Credential fields. At line 344, c.StakeCredential.Utxorpc() is called without a nil check. Since CBOR array decoding can leave pointer fields uninitialized (nil), this creates a nil pointer dereference risk if the CBOR data is malformed or incomplete.

Either add a nil check before calling Utxorpc():

if c.StakeCredential == nil {
    return nil, fmt.Errorf("StakeCredential must not be nil")
}
stakeCred, err := c.StakeCredential.Utxorpc()

Or change StakeCredential to a non-pointer field to match the pattern used by StakeRegistrationCertificate and StakeDeregistrationCertificate.

ledger/babbage/babbage.go (1)

716-727: Inconsistent nil semantics in DatumHash() return value.

When o.DatumOption is nil, this method returns &common.Blake2b256{} (a pointer to a zero-value hash) instead of nil. This differs from ShelleyTransactionOutput.DatumHash() which returns nil, and may confuse callers that check if datumHash != nil to determine if a datum exists.

Consider returning nil when there's no datum option for consistent behavior across eras:

Suggested fix
 func (o *BabbageTransactionOutput) DatumHash() *common.Blake2b256 {
 	if o.DatumOption != nil {
 		if o.DatumOption.hash != nil {
 			return o.DatumOption.hash
 		}
 		if o.DatumOption.data != nil {
 			hash := o.DatumOption.data.Hash()
 			return &hash
 		}
 	}
-	return &common.Blake2b256{}
+	return nil
 }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32490ac and bd53e47.

📒 Files selected for processing (52)
  • .golangci.yml
  • cbor/cbor.go
  • cbor/value.go
  • internal/test/conformance/conformance_test.go
  • ledger/allegra/allegra.go
  • ledger/allegra/rules_test.go
  • ledger/alonzo/alonzo.go
  • ledger/alonzo/pparams.go
  • ledger/alonzo/rules_test.go
  • ledger/babbage/babbage.go
  • ledger/babbage/errors_test.go
  • ledger/babbage/pparams.go
  • ledger/babbage/rules.go
  • ledger/babbage/rules_test.go
  • ledger/byron/byron.go
  • ledger/byron/genesis.go
  • ledger/byron/genesis_test.go
  • ledger/common/address.go
  • ledger/common/auxiliary_data_integration_test.go
  • ledger/common/certs.go
  • ledger/common/gov.go
  • ledger/common/metadata.go
  • ledger/common/metadata_test.go
  • ledger/common/rules.go
  • ledger/common/script.go
  • ledger/common/script/context_test.go
  • ledger/common/script_test.go
  • ledger/common/verify.go
  • ledger/common/witness.go
  • ledger/conway/conway.go
  • ledger/conway/conway_test.go
  • ledger/conway/errors_test.go
  • ledger/conway/gov.go
  • ledger/conway/pparams.go
  • ledger/conway/rules.go
  • ledger/conway/rules_test.go
  • ledger/error.go
  • ledger/error_test.go
  • ledger/leios/leios.go
  • ledger/leios/pparams.go
  • ledger/mary/mary.go
  • ledger/mary/pparams.go
  • ledger/mary/rules_test.go
  • ledger/shelley/genesis.go
  • ledger/shelley/genesis_test.go
  • ledger/shelley/pparams.go
  • ledger/shelley/rules.go
  • ledger/shelley/rules_test.go
  • ledger/shelley/shelley.go
  • protocol/common/dmq.go
  • protocol/localstatequery/client_test.go
  • protocol/localstatequery/queries.go
💤 Files with no reviewable changes (1)
  • ledger/common/rules.go
🧰 Additional context used
📓 Path-based instructions (8)
ledger/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

ledger/**/*.go: Use cbor.StructAsArray embedded type to enable CBOR array encoding for struct types
Use cbor.DecodeStoreCbor embedded type to preserve original CBOR bytes for hashing operations. Implement custom UnmarshalCBOR method and call SetCbor(cborData) to store original bytes
Always use preserved original CBOR bytes via Cbor() method for hash computation, not re-encoded data
Encode language views map with keys sorted by 'shortLex' order (length first, then lexicographic) as per Cardano Ledger Specification
For PlutusV1 cost models in language views: use double-bagged encoding with tag 0x4100 and wrap indefinite list in bytestring
For PlutusV2/V3 cost models in language views: use tag 0x01 or 0x02 with definite list encoding (no bytestring wrapper)
ScriptDataHash must be computed as Blake2b256(redeemers || datums || language_views) following Cardano Ledger Specification

Files:

  • ledger/shelley/pparams.go
  • ledger/common/witness.go
  • ledger/shelley/genesis_test.go
  • ledger/babbage/pparams.go
  • ledger/babbage/rules.go
  • ledger/common/metadata_test.go
  • ledger/babbage/rules_test.go
  • ledger/leios/leios.go
  • ledger/mary/rules_test.go
  • ledger/alonzo/pparams.go
  • ledger/conway/pparams.go
  • ledger/common/auxiliary_data_integration_test.go
  • ledger/common/gov.go
  • ledger/common/verify.go
  • ledger/conway/rules.go
  • ledger/shelley/rules_test.go
  • ledger/babbage/errors_test.go
  • ledger/shelley/genesis.go
  • ledger/mary/pparams.go
  • ledger/common/script/context_test.go
  • ledger/byron/genesis.go
  • ledger/allegra/rules_test.go
  • ledger/conway/gov.go
  • ledger/shelley/rules.go
  • ledger/conway/conway_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/byron/genesis_test.go
  • ledger/error.go
  • ledger/leios/pparams.go
  • ledger/common/script_test.go
  • ledger/conway/errors_test.go
  • ledger/common/metadata.go
  • ledger/conway/conway.go
  • ledger/common/script.go
  • ledger/byron/byron.go
  • ledger/alonzo/rules_test.go
  • ledger/common/address.go
  • ledger/common/certs.go
  • ledger/allegra/allegra.go
  • ledger/shelley/shelley.go
  • ledger/mary/mary.go
  • ledger/babbage/babbage.go
  • ledger/alonzo/alonzo.go
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Enforce 80 character line limit in Go code using golines formatter
Apply Apache 2.0 license header to all new Go files
Use gofmt and goimports for automatic code formatting
Pass all linter checks with make lint or golangci-lint run ./... before submission

Files:

  • ledger/shelley/pparams.go
  • ledger/common/witness.go
  • internal/test/conformance/conformance_test.go
  • ledger/shelley/genesis_test.go
  • ledger/babbage/pparams.go
  • ledger/babbage/rules.go
  • ledger/common/metadata_test.go
  • ledger/babbage/rules_test.go
  • ledger/leios/leios.go
  • ledger/mary/rules_test.go
  • ledger/alonzo/pparams.go
  • ledger/conway/pparams.go
  • ledger/common/auxiliary_data_integration_test.go
  • ledger/common/gov.go
  • ledger/common/verify.go
  • ledger/conway/rules.go
  • ledger/shelley/rules_test.go
  • ledger/babbage/errors_test.go
  • protocol/common/dmq.go
  • ledger/shelley/genesis.go
  • ledger/mary/pparams.go
  • ledger/common/script/context_test.go
  • cbor/cbor.go
  • ledger/byron/genesis.go
  • ledger/allegra/rules_test.go
  • ledger/conway/gov.go
  • ledger/shelley/rules.go
  • ledger/conway/conway_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • protocol/localstatequery/queries.go
  • ledger/byron/genesis_test.go
  • ledger/error.go
  • ledger/leios/pparams.go
  • ledger/common/script_test.go
  • cbor/value.go
  • protocol/localstatequery/client_test.go
  • ledger/conway/errors_test.go
  • ledger/common/metadata.go
  • ledger/conway/conway.go
  • ledger/common/script.go
  • ledger/byron/byron.go
  • ledger/alonzo/rules_test.go
  • ledger/common/address.go
  • ledger/common/certs.go
  • ledger/allegra/allegra.go
  • ledger/shelley/shelley.go
  • ledger/mary/mary.go
  • ledger/babbage/babbage.go
  • ledger/alonzo/alonzo.go
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*_test.go: Use testify assertion library for test assertions in Go tests
All Go tests must pass with race detection via make test before submission

Files:

  • internal/test/conformance/conformance_test.go
  • ledger/shelley/genesis_test.go
  • ledger/common/metadata_test.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/common/auxiliary_data_integration_test.go
  • ledger/shelley/rules_test.go
  • ledger/babbage/errors_test.go
  • ledger/common/script/context_test.go
  • ledger/allegra/rules_test.go
  • ledger/conway/conway_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/byron/genesis_test.go
  • ledger/common/script_test.go
  • protocol/localstatequery/client_test.go
  • ledger/conway/errors_test.go
  • ledger/alonzo/rules_test.go
ledger/**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

Use MockLedgerState from internal/test/ledger/ledger.go for validation tests instead of creating custom mocks

Files:

  • ledger/shelley/genesis_test.go
  • ledger/common/metadata_test.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/common/auxiliary_data_integration_test.go
  • ledger/shelley/rules_test.go
  • ledger/babbage/errors_test.go
  • ledger/common/script/context_test.go
  • ledger/allegra/rules_test.go
  • ledger/conway/conway_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/byron/genesis_test.go
  • ledger/common/script_test.go
  • ledger/conway/errors_test.go
  • ledger/alonzo/rules_test.go
.golangci.yml

📄 CodeRabbit inference engine (AGENTS.md)

Configure .golangci.yml with enabled linters including gosec, errorlint, and exhaustive

Files:

  • .golangci.yml
ledger/**/rules.go

📄 CodeRabbit inference engine (AGENTS.md)

ledger/**/rules.go: Implement validation rule functions with signature: func UtxoValidate{RuleName}(tx common.Transaction, slot uint64, ls common.LedgerState, pp common.ProtocolParameters) error - return nil on success or a specific error type on failure
Add new validation rules to the UtxoValidationRules slice in the appropriate era package at the correct position in the rule order
Reference inputs are resolved but never consumed from the UTxO set
Collateral inputs are only consumed from UTxO set when transaction IsValid flag is false
Datum lookup must check witness set, inline datums, AND reference inputs in that order
Verify cost models exist for each Plutus version used in transaction before script execution
Later eras must call parent era functions for shared validation logic, not duplicate logic

Files:

  • ledger/babbage/rules.go
  • ledger/conway/rules.go
  • ledger/shelley/rules.go
ledger/common/certs.go

📄 CodeRabbit inference engine (AGENTS.md)

Define certificate structs in ledger/common/certs.go with CBOR tags before adding new certificate types

Files:

  • ledger/common/certs.go
ledger/**/certs.go

📄 CodeRabbit inference engine (AGENTS.md)

Update certificate parsing switch statement when adding support for new certificate types

Files:

  • ledger/common/certs.go
🧠 Learnings (22)
📓 Common learnings
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : Use `cbor.StructAsArray` embedded type to enable CBOR array encoding for struct types
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Collateral inputs are only consumed from UTxO set when transaction `IsValid` flag is false

Applied to files:

  • ledger/common/witness.go
  • ledger/babbage/rules.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/babbage/errors_test.go
  • ledger/common/script/context_test.go
  • ledger/allegra/rules_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/conway/errors_test.go
  • ledger/conway/conway.go
  • ledger/alonzo/rules_test.go
  • ledger/allegra/allegra.go
  • ledger/mary/mary.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : Use `cbor.DecodeStoreCbor` embedded type to preserve original CBOR bytes for hashing operations. Implement custom `UnmarshalCBOR` method and call `SetCbor(cborData)` to store original bytes

Applied to files:

  • internal/test/conformance/conformance_test.go
  • ledger/common/metadata_test.go
  • ledger/shelley/genesis.go
  • cbor/cbor.go
  • ledger/error_test.go
  • ledger/error.go
  • cbor/value.go
  • ledger/common/metadata.go
  • ledger/byron/byron.go
  • ledger/common/address.go
  • ledger/common/certs.go
  • ledger/shelley/shelley.go
  • ledger/babbage/babbage.go
  • ledger/alonzo/alonzo.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : Always use preserved original CBOR bytes via `Cbor()` method for hash computation, not re-encoded data

Applied to files:

  • internal/test/conformance/conformance_test.go
  • ledger/common/metadata_test.go
  • ledger/babbage/rules_test.go
  • ledger/common/verify.go
  • ledger/shelley/genesis.go
  • cbor/cbor.go
  • ledger/shelley/rules.go
  • ledger/conway/conway_test.go
  • ledger/error_test.go
  • ledger/byron/genesis_test.go
  • ledger/error.go
  • cbor/value.go
  • ledger/common/metadata.go
  • ledger/byron/byron.go
  • ledger/common/address.go
  • ledger/shelley/shelley.go
  • ledger/mary/mary.go
  • ledger/babbage/babbage.go
  • ledger/alonzo/alonzo.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : Use `cbor.StructAsArray` embedded type to enable CBOR array encoding for struct types

Applied to files:

  • internal/test/conformance/conformance_test.go
  • ledger/shelley/genesis.go
  • cbor/cbor.go
  • ledger/error_test.go
  • ledger/error.go
  • cbor/value.go
  • ledger/common/metadata.go
  • ledger/conway/conway.go
  • ledger/byron/byron.go
  • ledger/common/address.go
  • ledger/babbage/babbage.go
  • ledger/alonzo/alonzo.go
📚 Learning: 2025-11-04T15:54:22.683Z
Learnt from: wolf31o2
Repo: blinklabs-io/gouroboros PR: 1093
File: ledger/mary/pparams.go:143-150
Timestamp: 2025-11-04T15:54:22.683Z
Learning: In the blinklabs-io/gouroboros repository, the design goal for CBOR round-trip tests is to achieve byte-identical encoding WITHOUT using stored CBOR (cbor.DecodeStoreCbor). Instead, the approach uses proper field types (pointers for optional fields) and relies on the cbor package's deterministic encoding (SortCoreDeterministic) to ensure reproducible output. The stored CBOR pattern should not be suggested as a solution for round-trip fidelity in this codebase.

Applied to files:

  • internal/test/conformance/conformance_test.go
  • cbor/cbor.go
  • ledger/error_test.go
  • ledger/common/script_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to .golangci.yml : Configure `.golangci.yml` with enabled linters including `gosec`, `errorlint`, and `exhaustive`

Applied to files:

  • .golangci.yml
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to **/*.go : Pass all linter checks with `make lint` or `golangci-lint run ./...` before submission

Applied to files:

  • .golangci.yml
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : ScriptDataHash must be computed as Blake2b256(redeemers || datums || language_views) following Cardano Ledger Specification

Applied to files:

  • ledger/babbage/rules.go
  • ledger/conway/rules.go
  • ledger/babbage/errors_test.go
  • ledger/shelley/rules.go
  • ledger/conway/conway_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/error.go
  • ledger/common/script_test.go
  • ledger/conway/errors_test.go
  • ledger/common/script.go
  • ledger/byron/byron.go
  • ledger/common/address.go
  • ledger/shelley/shelley.go
  • ledger/mary/mary.go
  • ledger/babbage/babbage.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Verify cost models exist for each Plutus version used in transaction before script execution

Applied to files:

  • ledger/babbage/rules.go
  • ledger/conway/rules.go
  • ledger/babbage/errors_test.go
  • ledger/conway/conway_test.go
  • ledger/conway/errors_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Add new validation rules to the `UtxoValidationRules` slice in the appropriate era package at the correct position in the rule order

Applied to files:

  • ledger/babbage/rules.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/shelley/rules_test.go
  • ledger/common/script/context_test.go
  • ledger/allegra/rules_test.go
  • ledger/shelley/rules.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/alonzo/rules_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Implement validation rule functions with signature: `func UtxoValidate{RuleName}(tx common.Transaction, slot uint64, ls common.LedgerState, pp common.ProtocolParameters) error` - return nil on success or a specific error type on failure

Applied to files:

  • ledger/babbage/rules.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/shelley/rules_test.go
  • ledger/babbage/errors_test.go
  • ledger/common/script/context_test.go
  • ledger/allegra/rules_test.go
  • ledger/shelley/rules.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/conway/errors_test.go
  • ledger/alonzo/rules_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/certs.go : Update certificate parsing switch statement when adding support for new certificate types

Applied to files:

  • ledger/babbage/rules.go
  • ledger/common/verify.go
  • ledger/conway/rules.go
  • ledger/shelley/rules.go
  • ledger/common/certs.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Reference inputs are resolved but never consumed from the UTxO set

Applied to files:

  • ledger/babbage/rules.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/shelley/rules_test.go
  • ledger/babbage/errors_test.go
  • ledger/common/script/context_test.go
  • ledger/allegra/rules_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/error.go
  • ledger/conway/errors_test.go
  • ledger/byron/byron.go
  • ledger/alonzo/rules_test.go
  • ledger/allegra/allegra.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/native.go : Implement `NativeScript.Evaluate(slot uint64, validityStart, validityEnd uint64, keyHashes map[Blake2b224]bool) bool` for native script validation

Applied to files:

  • ledger/babbage/rules.go
  • ledger/conway/rules.go
  • ledger/common/script.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : For PlutusV2/V3 cost models in language views: use tag `0x01` or `0x02` with definite list encoding (no bytestring wrapper)

Applied to files:

  • ledger/babbage/rules.go
  • ledger/conway/rules.go
  • ledger/byron/byron.go
  • ledger/babbage/babbage.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*.go : For PlutusV1 cost models in language views: use double-bagged encoding with tag `0x4100` and wrap indefinite list in bytestring

Applied to files:

  • ledger/babbage/rules.go
  • ledger/conway/rules.go
  • ledger/byron/byron.go
  • ledger/babbage/babbage.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/*_test.go : Use `MockLedgerState` from `internal/test/ledger/ledger.go` for validation tests instead of creating custom mocks

Applied to files:

  • ledger/common/metadata_test.go
  • ledger/babbage/rules_test.go
  • ledger/mary/rules_test.go
  • ledger/common/auxiliary_data_integration_test.go
  • ledger/babbage/errors_test.go
  • ledger/allegra/rules_test.go
  • ledger/error_test.go
  • ledger/conway/rules_test.go
  • ledger/byron/genesis_test.go
  • ledger/conway/errors_test.go
  • ledger/alonzo/rules_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Datum lookup must check witness set, inline datums, AND reference inputs in that order

Applied to files:

  • ledger/common/verify.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Create new era package structure following pattern: `ledger/{era_name}/` with types extending previous era, `rules.go` inheriting parent rules, and compatibility exports at `ledger/{era_name}.go`

Applied to files:

  • ledger/error_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/**/rules.go : Later eras must call parent era functions for shared validation logic, not duplicate logic

Applied to files:

  • ledger/error_test.go
📚 Learning: 2026-01-13T02:47:14.599Z
Learnt from: CR
Repo: blinklabs-io/gouroboros PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T02:47:14.599Z
Learning: Applies to ledger/common/certs.go : Define certificate structs in `ledger/common/certs.go` with CBOR tags before adding new certificate types

Applied to files:

  • cbor/value.go
  • ledger/common/certs.go
🧬 Code graph analysis (37)
ledger/shelley/pparams.go (1)
ledger/shelley.go (1)
  • ShelleyProtocolParameterUpdate (32-32)
ledger/common/witness.go (1)
ledger/common/address.go (2)
  • AddressPayloadKeyHash (691-693)
  • AddressPayloadKeyHash (695-695)
ledger/shelley/genesis_test.go (1)
ledger/common/address.go (1)
  • Address (62-70)
ledger/babbage/pparams.go (1)
ledger/babbage.go (1)
  • BabbageProtocolParameterUpdate (31-31)
ledger/babbage/rules.go (1)
ledger/common/script.go (4)
  • PlutusV1Script (140-140)
  • PlutusV1Script (142-142)
  • PlutusV2Script (216-216)
  • PlutusV2Script (218-218)
ledger/common/metadata_test.go (2)
ledger/common/metadata.go (4)
  • MetaMap (77-80)
  • MetaMap (86-86)
  • MetaInt (51-54)
  • MetaInt (82-82)
ledger/common/script/wrappers.go (1)
  • Pairs (46-46)
ledger/babbage/rules_test.go (3)
ledger/shelley.go (1)
  • ShelleyTransactionOutput (29-29)
ledger/babbage/babbage.go (1)
  • BabbageTransactionOutput (556-563)
ledger/babbage.go (1)
  • BabbageTransactionOutput (28-28)
ledger/leios/leios.go (1)
ledger/leios.go (1)
  • LeiosRankingBlock (26-26)
ledger/mary/rules_test.go (1)
ledger/shelley/shelley.go (1)
  • ShelleyTransactionOutput (433-438)
ledger/alonzo/pparams.go (1)
ledger/alonzo.go (1)
  • AlonzoProtocolParameterUpdate (31-31)
ledger/conway/pparams.go (2)
ledger/conway.go (1)
  • ConwayProtocolParameterUpdate (30-30)
ledger/common/script/wrappers.go (1)
  • ToPlutusData (28-30)
ledger/common/verify.go (1)
ledger/common/address.go (2)
  • AddressPayloadKeyHash (691-693)
  • AddressPayloadKeyHash (695-695)
ledger/conway/rules.go (2)
ledger/common/script.go (6)
  • PlutusV1Script (140-140)
  • PlutusV1Script (142-142)
  • PlutusV2Script (216-216)
  • PlutusV2Script (218-218)
  • PlutusV3Script (292-292)
  • PlutusV3Script (294-294)
ledger/common/address.go (4)
  • AddressPayloadKeyHash (691-693)
  • AddressPayloadKeyHash (695-695)
  • AddressPayloadScriptHash (697-699)
  • AddressPayloadScriptHash (701-701)
ledger/shelley/rules_test.go (1)
ledger/shelley/shelley.go (1)
  • ShelleyTransactionOutput (433-438)
ledger/babbage/errors_test.go (1)
ledger/common/script.go (2)
  • PlutusV1Script (140-140)
  • PlutusV1Script (142-142)
ledger/shelley/genesis.go (1)
ledger/shelley/shelley.go (1)
  • ShelleyTransactionOutput (433-438)
ledger/byron/genesis.go (3)
ledger/byron/byron.go (2)
  • ByronTransactionInput (681-685)
  • ByronTransactionOutput (765-770)
protocol/txsubmission/messages.go (1)
  • TxId (191-195)
ledger/common/common.go (1)
  • Blake2b256Hash (90-102)
ledger/allegra/rules_test.go (1)
ledger/shelley/shelley.go (1)
  • ShelleyTransactionOutput (433-438)
ledger/conway/gov.go (1)
ledger/common/script/wrappers.go (1)
  • ToPlutusData (28-30)
ledger/shelley/rules.go (2)
ledger/common/metadata.go (10)
  • MetaText (61-64)
  • MetaText (84-84)
  • MetaBytes (56-59)
  • MetaBytes (83-83)
  • MetaInt (51-54)
  • MetaInt (82-82)
  • MetaList (66-69)
  • MetaList (85-85)
  • MetaMap (77-80)
  • MetaMap (86-86)
ledger/common/address.go (4)
  • AddressPayloadKeyHash (691-693)
  • AddressPayloadKeyHash (695-695)
  • AddressPayloadScriptHash (697-699)
  • AddressPayloadScriptHash (701-701)
ledger/conway/conway_test.go (1)
ledger/common/script.go (3)
  • Script (38-42)
  • PlutusV1Script (140-140)
  • PlutusV1Script (142-142)
ledger/error_test.go (3)
ledger/common/address.go (1)
  • Address (62-70)
ledger/shelley/shelley.go (1)
  • ShelleyTransactionOutput (433-438)
ledger/byron/byron.go (1)
  • ByronTransactionInput (681-685)
ledger/conway/rules_test.go (3)
ledger/common/script.go (2)
  • PlutusV1Script (140-140)
  • PlutusV1Script (142-142)
ledger/shelley/shelley.go (2)
  • ShelleyTransactionOutput (433-438)
  • NewShelleyTransactionInput (388-400)
ledger/babbage/babbage.go (1)
  • BabbageTransactionOutput (556-563)
ledger/byron/genesis_test.go (1)
ledger/common/address.go (1)
  • Address (62-70)
ledger/leios/pparams.go (1)
ledger/leios.go (1)
  • LeiosProtocolParameterUpdate (31-31)
ledger/common/script_test.go (1)
ledger/common/script.go (1)
  • Script (38-42)
ledger/conway/errors_test.go (1)
ledger/common/script.go (6)
  • PlutusV2Script (216-216)
  • PlutusV2Script (218-218)
  • PlutusV1Script (140-140)
  • PlutusV1Script (142-142)
  • PlutusV3Script (292-292)
  • PlutusV3Script (294-294)
ledger/conway/conway.go (3)
ledger/common/redeemer.go (3)
  • RedeemerKey (32-36)
  • RedeemerValue (38-42)
  • RedeemerTag (21-21)
ledger/common/witness.go (2)
  • VkeyWitness (21-25)
  • BootstrapWitness (27-33)
ledger/common/tx.go (4)
  • TransactionWitnessRedeemers (98-102)
  • TransactionInput (66-72)
  • TransactionOutput (74-85)
  • Utxo (104-108)
ledger/common/script.go (2)
cbor/decode.go (1)
  • Decode (29-44)
ledger/common/common.go (1)
  • Blake2b224Hash (151-163)
ledger/byron/byron.go (1)
ledger/byron.go (5)
  • ByronTransaction (28-28)
  • NewByronTransactionInput (48-48)
  • ByronTransactionInput (29-29)
  • ByronTransactionOutput (30-30)
  • ByronEpochBoundaryBlock (24-24)
ledger/alonzo/rules_test.go (2)
ledger/shelley/shelley.go (1)
  • ShelleyTransactionOutput (433-438)
ledger/alonzo/alonzo.go (1)
  • AlonzoTransactionOutput (351-358)
ledger/common/address.go (2)
ledger/compat.go (2)
  • AddrKeyHash (41-41)
  • Address (40-40)
ledger/common/script.go (1)
  • ScriptHash (36-36)
ledger/common/certs.go (1)
ledger/compat.go (3)
  • StakeDelegationCertificate (68-68)
  • PoolRegistrationCertificate (67-67)
  • PoolRetirementCertificate (66-66)
ledger/allegra/allegra.go (1)
ledger/common/pparams.go (1)
  • ProtocolParameterUpdate (24-27)
ledger/shelley/shelley.go (2)
ledger/common/script/wrappers.go (1)
  • ToPlutusData (28-30)
ledger/common/tx.go (3)
  • TransactionInput (66-72)
  • TransactionOutput (74-85)
  • Utxo (104-108)
ledger/mary/mary.go (4)
ledger/common/tx.go (3)
  • TransactionInput (66-72)
  • TransactionOutput (74-85)
  • Utxo (104-108)
ledger/common/pparams.go (1)
  • ProtocolParameterUpdate (24-27)
ledger/common/certs.go (1)
  • Certificate (128-133)
ledger/common/script.go (2)
  • ScriptRef (66-69)
  • Script (38-42)
ledger/babbage/babbage.go (2)
ledger/common/script/wrappers.go (1)
  • ToPlutusData (28-30)
ledger/common/tx.go (3)
  • TransactionInput (66-72)
  • TransactionOutput (74-85)
  • Utxo (104-108)
⏰ 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: go-test (1.24.x, ubuntu-latest)
  • GitHub Check: cubic · AI code reviewer

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Contributor

@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.

9 issues found across 52 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="internal/test/conformance/conformance_test.go">

<violation number="1" location="internal/test/conformance/conformance_test.go:1076">
P1: Taking the address of the reused range variable makes all UTxOs share the same output pointer, corrupting decoded UTxOs.</violation>
</file>

<file name="ledger/babbage/babbage.go">

<violation number="1" location="ledger/babbage/babbage.go:416">
P1: All entries in ProtocolParameterUpdates map share pointer to last loop value due to taking address of reused range variable</violation>
</file>

<file name="ledger/error.go">

<violation number="1" location="ledger/error.go:692">
P1: Addresses the reused range variable in Byron UTxO loop, so all Id pointers can alias to the last input.</violation>
</file>

<file name="ledger/conway/conway.go">

<violation number="1" location="ledger/conway/conway.go:529">
P1: Range loop stores address of reused loop variable, so all protocol parameter updates alias the last value.</violation>
</file>

<file name="protocol/common/dmq.go">

<violation number="1" location="protocol/common/dmq.go:164">
P1: Potential nil-pointer panic: typed-nil *RejectReasonData is matched and dereferenced without a nil check</violation>
</file>

<file name="ledger/mary/mary.go">

<violation number="1" location="ledger/mary/mary.go:264">
P1: Range variable address reused: all map entries point to last update value</violation>
</file>

<file name="ledger/alonzo/alonzo.go">

<violation number="1" location="ledger/alonzo/alonzo.go:298">
P1: All map entries share the same protocol update pointer due to taking address of the reused range variable</violation>
</file>

<file name="ledger/common/address.go">

<violation number="1" location="ledger/common/address.go:631">
P1: Changing MarshalJSON to a pointer receiver removes json.Marshaler for Address values, causing json.Marshal(Address) to emit an empty object and breaking usage on non-addressable values.</violation>
</file>

<file name="cbor/value.go">

<violation number="1" location="cbor/value.go:353">
P1: Constructor.MarshalJSON moved to pointer receiver but generateAstJson marshals a value, so MarshalJSON is skipped and constructors serialize as `{}`.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

OutputIndex: uint32(utxoId.Idx),
},
Output: output,
Output: &output,
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Taking the address of the reused range variable makes all UTxOs share the same output pointer, corrupting decoded UTxOs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At internal/test/conformance/conformance_test.go, line 1076:

<comment>Taking the address of the reused range variable makes all UTxOs share the same output pointer, corrupting decoded UTxOs.</comment>

<file context>
@@ -1073,7 +1073,7 @@ func (s *initialStateUtxos) UnmarshalCBOR(data []byte) error {
 						OutputIndex: uint32(utxoId.Idx),
 					},
-					Output: output,
+					Output: &output,
 				})
 			}
</file context>

updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
for k, v := range b.Update.ProtocolParamUpdates {
updateMap[k] = v
updateMap[k] = &v
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: All entries in ProtocolParameterUpdates map share pointer to last loop value due to taking address of reused range variable

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ledger/babbage/babbage.go, line 416:

<comment>All entries in ProtocolParameterUpdates map share pointer to last loop value due to taking address of reused range variable</comment>

<file context>
@@ -413,7 +413,7 @@ func (b *BabbageTransactionBody) ProtocolParameterUpdates() (uint64, map[common.
 	updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
 	for k, v := range b.Update.ProtocolParamUpdates {
-		updateMap[k] = v
+		updateMap[k] = &v
 	}
 	return b.Update.Epoch, updateMap
</file context>
Suggested change
updateMap[k] = &v
for k, v := range b.Update.ProtocolParamUpdates {
val := v
updateMap[k] = &val
}


e.Utxos = append(e.Utxos, common.Utxo{
Id: input,
Id: &input,
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Addresses the reused range variable in Byron UTxO loop, so all Id pointers can alias to the last input.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ledger/error.go, line 692:

<comment>Addresses the reused range variable in Byron UTxO loop, so all Id pointers can alias to the last input.</comment>

<file context>
@@ -689,7 +689,7 @@ func (e *ScriptsNotPaidUtxo) UnmarshalCBOR(data []byte) error {
 
 			e.Utxos = append(e.Utxos, common.Utxo{
-				Id:     input,
+				Id:     &input,
 				Output: output,
 			})
</file context>

updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
for k, v := range b.Update.ProtocolParamUpdates {
updateMap[k] = v
updateMap[k] = &v
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Range loop stores address of reused loop variable, so all protocol parameter updates alias the last value.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ledger/conway/conway.go, line 529:

<comment>Range loop stores address of reused loop variable, so all protocol parameter updates alias the last value.</comment>

<file context>
@@ -526,7 +526,7 @@ func (b *ConwayTransactionBody) ProtocolParameterUpdates() (uint64, map[common.B
 	updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
 	for k, v := range b.Update.ProtocolParamUpdates {
-		updateMap[k] = v
+		updateMap[k] = &v
 	}
 	return b.Update.Epoch, updateMap
</file context>
Suggested change
updateMap[k] = &v
vCopy := v
updateMap[k] = &vCopy

Comment on lines +164 to +165
case *RejectReasonData:
return *v
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Potential nil-pointer panic: typed-nil *RejectReasonData is matched and dereferenced without a nil check

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At protocol/common/dmq.go, line 164:

<comment>Potential nil-pointer panic: typed-nil *RejectReasonData is matched and dereferenced without a nil check</comment>

<file context>
@@ -161,16 +161,16 @@ func ToRejectReasonData(rr RejectReason) RejectReasonData {
 		return RejectReasonData{Type: 3, Message: v.Message}
-	case RejectReasonData:
-		return v
+	case *RejectReasonData:
+		return *v
 	default:
</file context>
Suggested change
case *RejectReasonData:
return *v
case *RejectReasonData:
if v == nil {
return RejectReasonData{Type: 3}
}
return *v

updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
for k, v := range b.Update.ProtocolParamUpdates {
updateMap[k] = v
updateMap[k] = &v
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Range variable address reused: all map entries point to last update value

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ledger/mary/mary.go, line 264:

<comment>Range variable address reused: all map entries point to last update value</comment>

<file context>
@@ -261,7 +261,7 @@ func (b *MaryTransactionBody) ProtocolParameterUpdates() (uint64, map[common.Bla
 	updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
 	for k, v := range b.Update.ProtocolParamUpdates {
-		updateMap[k] = v
+		updateMap[k] = &v
 	}
 	return b.Update.Epoch, updateMap
</file context>
Suggested change
updateMap[k] = &v
vCopy := v
updateMap[k] = &vCopy

updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
for k, v := range b.Update.ProtocolParamUpdates {
updateMap[k] = v
updateMap[k] = &v
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: All map entries share the same protocol update pointer due to taking address of the reused range variable

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ledger/alonzo/alonzo.go, line 298:

<comment>All map entries share the same protocol update pointer due to taking address of the reused range variable</comment>

<file context>
@@ -295,7 +295,7 @@ func (b *AlonzoTransactionBody) ProtocolParameterUpdates() (uint64, map[common.B
 	updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
 	for k, v := range b.Update.ProtocolParamUpdates {
-		updateMap[k] = v
+		updateMap[k] = &v
 	}
 	return b.Update.Epoch, updateMap
</file context>

}

func (a Address) MarshalJSON() ([]byte, error) {
func (a *Address) MarshalJSON() ([]byte, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Changing MarshalJSON to a pointer receiver removes json.Marshaler for Address values, causing json.Marshal(Address) to emit an empty object and breaking usage on non-addressable values.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ledger/common/address.go, line 631:

<comment>Changing MarshalJSON to a pointer receiver removes json.Marshaler for Address values, causing json.Marshal(Address) to emit an empty object and breaking usage on non-addressable values.</comment>

<file context>
@@ -628,7 +628,7 @@ func (a Address) String() string {
 }
 
-func (a Address) MarshalJSON() ([]byte, error) {
+func (a *Address) MarshalJSON() ([]byte, error) {
 	return []byte(`"` + a.String() + `"`), nil
 }
</file context>
Suggested change
func (a *Address) MarshalJSON() ([]byte, error) {
func (a Address) MarshalJSON() ([]byte, error) {

}

func (v Constructor) MarshalJSON() ([]byte, error) {
func (v *Constructor) MarshalJSON() ([]byte, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Constructor.MarshalJSON moved to pointer receiver but generateAstJson marshals a value, so MarshalJSON is skipped and constructors serialize as {}.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At cbor/value.go, line 353:

<comment>Constructor.MarshalJSON moved to pointer receiver but generateAstJson marshals a value, so MarshalJSON is skipped and constructors serialize as `{}`.</comment>

<file context>
@@ -350,7 +350,7 @@ func (c Constructor) MarshalCBOR() ([]byte, error) {
 }
 
-func (v Constructor) MarshalJSON() ([]byte, error) {
+func (v *Constructor) MarshalJSON() ([]byte, error) {
 	var sb strings.Builder
 	sb.WriteString(fmt.Sprintf(`{"constructor":%d,"fields":[`, v.constructor))
</file context>
Suggested change
func (v *Constructor) MarshalJSON() ([]byte, error) {
func (v Constructor) MarshalJSON() ([]byte, error) {

@cryptodj413
Copy link
Contributor Author

@coderabbitai @cubic-dev-ai
Please review again. Go 1.22 introduces two for loop language changes that are relevant here: https://go.dev/doc/go1.22#language

@cubic-dev-ai
Copy link
Contributor

cubic-dev-ai bot commented Jan 15, 2026

@coderabbitai @cubic-dev-ai
Please review again. Go 1.22 introduces two for loop language changes that are relevant here: https://go.dev/doc/go1.22#language

@cryptodj413 I have started the AI code review. It will take a few minutes to complete.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

Tip

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

🧩 Analysis chain

🌐 Web query:

Go 1.22 for loop language changes per-iteration variables

💡 Result:

Short summary — Go 1.22 changes for-loop variable semantics to be per-iteration:

  • Loop variables declared by := in a for (including range and 3-clause for) are now created anew on each iteration instead of a single instance shared across iterations. This prevents accidental sharing when you capture loop variables in closures/goroutines. [1][2]
  • The new semantics apply only to packages that opt in (module's go.mod declares go 1.22+ or by per-file build constraints), so existing code is unchanged until you opt in. [1][2]
  • Tools were updated (vet warnings adjusted) and the Go 1.22 release notes document the change (and other loop-related features such as integer ranges). [2][3]

Sources: Go blog (Fixing For Loops in Go 1.22) [1]; proposal/issue and design doc (less error-prone loop variable scoping) [2]; Go 1.22 release notes [3].


🏁 Script executed:

#!/bin/bash
# Check the Go version in go.mod
cat go.mod | grep "^go "

# Search for loop-related changes in the PR by looking at specific files mentioned in the summary
# Let's look at some key files that might have loop changes

# Check byron/byron.go for loop changes around Inputs()
echo "=== Checking ledger/byron/byron.go for loop patterns ==="
sed -n '200,250p' ledger/byron/byron.go

# Check if there are range loops that were changed
echo "=== Searching for range loops in key modified files ==="
rg -A2 "for.*range" ledger/byron/byron.go | head -20

Length of output: 1659


🏁 Script executed:

#!/bin/bash
# Let's look at the actual changes in the PR by examining the Produced() method 
# which was mentioned in the summary as having changes

echo "=== Checking ByronTransaction Produced() method ==="
rg -A15 "func.*Produced\(\)" ledger/byron/byron.go

echo ""
echo "=== Checking for patterns where loop variable addresses are taken ==="
# Look for patterns like &input, &output in loops
rg -B2 -A2 "for.*range.*\n.*&" ledger/byron/byron.go --multiline-dotall | head -40

echo ""
echo "=== Looking at the Inputs() method change pattern ==="
rg -B2 -A8 "func.*Inputs\(\)" ledger/byron/byron.go

Length of output: 1738


🏁 Script executed:

#!/bin/bash
# Let's check for the pattern that would be problematic pre-Go 1.22
# Searching for loops where we take addresses of loop variables

echo "=== Check conway/conway.go for loop patterns ==="
rg -A10 "func.*ProposalProcedures\(\)" ledger/conway/conway.go

echo ""
echo "=== Check for other patterns with address-of-loop-var ==="
# Look for range loops with value iteration followed by address taking
rg -A5 "for.*,.*:= range" ledger/common/script/context_test.go | grep -A5 "Output:"

echo ""
echo "=== Checking if module declares Go 1.22+ ==="
cat go.mod | head -5

Length of output: 954


🏁 Script executed:

#!/bin/bash
# Let's look at the specific pattern in Produced() that takes &id
# This pattern would be problematic pre-Go 1.22 but is safe in Go 1.22+

echo "=== Checking Produced() pattern where &id is taken ==="
rg -B5 -A10 "Id:.*&id" ledger/byron/byron.go

echo ""
echo "=== Let's check if there are similar patterns in other files ==="
rg "Id:.*&" ledger/byron/genesis.go | head -10

echo ""
echo "=== Check the conformance test changes ==="
rg -B3 -A3 "Output:.*&output" internal/test/conformance/conformance_test.go | head -20

Length of output: 922


🏁 Script executed:

#!/bin/bash
# Let's examine the ProposalProcedures pattern more closely
# This is taking &b.TxProposalProcedures[i] which is safe

echo "=== Understanding the loop pattern changes ==="
echo "Pattern 1: Taking address via slice index (always safe):"
rg -A3 "for i := range.*{" ledger/byron/byron.go | grep -A2 "append.*&.*\[i\]" | head -10

echo ""
echo "Pattern 2: Check if there were any cases of taking address of loop value var"
echo "Looking for historical pattern that would need Go 1.22:"
# Check Produced() which uses range with value
rg -B2 -A8 "for idx, output := range outputs" ledger/byron/byron.go

echo ""
echo "=== Verify the go.mod version is 1.22+ ==="
grep "^go " go.mod

echo ""
echo "=== Summary: Check if recvcheck was the reason for these changes ==="
rg -i "recvcheck" .golangci.yml

Length of output: 722


@cryptodj413 Thank you for pointing me to the Go 1.22 language changes! I've reviewed the PR with those changes in mind.

Go 1.22 introduced per-iteration loop variables, where loop variables are created anew on each iteration instead of being shared across iterations. This is critical for the patterns used in this PR.

Key Findings

✅ The code is correct for Go 1.24.0 (declared in go.mod)

The PR contains several patterns that rely on Go 1.22+ loop semantics:

1. Safe pattern in ByronTransaction.Produced():

for idx, output := range outputs {
    id := NewByronTransactionInput(t.Id().String(), idx)
    ret = append(
        ret,
        common.Utxo{
            Id:     &id,  // Taking address of loop-scoped variable
            Output: output,
        },
    )
}

Why this works: With Go 1.22+, id is created fresh on each iteration, so &id gives a unique address each time. Pre-Go 1.22, this would be a bug—all Utxos would point to the same id variable.

2. Safe pattern with slice indexing:

for i := range t.TxInputs {
    ret = append(ret, &t.TxInputs[i])
}

Why this works: This pattern is safe in all Go versions because we're taking the address of a slice element, not a loop variable.

3. Safe pattern in ConwayTransactionBody.ProposalProcedures():

for i := range b.TxProposalProcedures {
    ret[i] = &b.TxProposalProcedures[i]
}

Important Note

⚠️ If this code were backported to a module with go 1.21 or earlier, the &id pattern in Produced() would create a data race where all Utxo entries share the same Id pointer. However, since your module declares go 1.24.0, the new semantics are in effect and the code is correct.

The changes align well with the recvcheck linter fixes and correctly leverage Go 1.22+'s improved loop variable scoping.

Copy link
Contributor

@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.

8 issues found across 52 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="ledger/mary/mary.go">

<violation number="1" location="ledger/mary/mary.go:264">
P1: All map entries point to the same update because &v takes the address of the reused range variable</violation>
</file>

<file name="protocol/common/dmq.go">

<violation number="1" location="protocol/common/dmq.go:164">
P1: Dereferences a typed-nil *RejectReasonData in ToRejectReasonData, causing panic</violation>
</file>

<file name="ledger/alonzo/alonzo.go">

<violation number="1" location="ledger/alonzo/alonzo.go:298">
P1: Range variable address escapes: map stores pointers to reused loop variable so all entries can reference the last update</violation>
</file>

<file name="internal/test/conformance/conformance_test.go">

<violation number="1" location="internal/test/conformance/conformance_test.go:1076">
P1: All UTxOs take the address of the reused range variable `output`, so every `Output` pointer aliases the same value (last iteration) instead of the per-UTxO output.</violation>
</file>

<file name="ledger/conway/conway.go">

<violation number="1" location="ledger/conway/conway.go:529">
P1: Map range takes address of loop variable, so all updates map entries share the last value</violation>
</file>

<file name="ledger/babbage/babbage.go">

<violation number="1" location="ledger/babbage/babbage.go:416">
P1: Protocol parameter updates map stores pointer to reused range variable, causing every entry to reference the last update</violation>
</file>

<file name="ledger/shelley/shelley.go">

<violation number="1" location="ledger/shelley/shelley.go:309">
P1: Range variable address stored; all map entries point to the same update</violation>
</file>

<file name="cbor/value.go">

<violation number="1" location="cbor/value.go:353">
P1: Constructor MarshalJSON changed to pointer receiver but callers still marshal Constructor values, so custom JSON output is bypassed</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
for k, v := range b.Update.ProtocolParamUpdates {
updateMap[k] = v
updateMap[k] = &v
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: All map entries point to the same update because &v takes the address of the reused range variable

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ledger/mary/mary.go, line 264:

<comment>All map entries point to the same update because &v takes the address of the reused range variable</comment>

<file context>
@@ -261,7 +261,7 @@ func (b *MaryTransactionBody) ProtocolParameterUpdates() (uint64, map[common.Bla
 	updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
 	for k, v := range b.Update.ProtocolParamUpdates {
-		updateMap[k] = v
+		updateMap[k] = &v
 	}
 	return b.Update.Epoch, updateMap
</file context>

return RejectReasonData{Type: 3, Message: v.Message}
case RejectReasonData:
return v
case *RejectReasonData:
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Dereferences a typed-nil *RejectReasonData in ToRejectReasonData, causing panic

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At protocol/common/dmq.go, line 164:

<comment>Dereferences a typed-nil *RejectReasonData in ToRejectReasonData, causing panic</comment>

<file context>
@@ -161,16 +161,16 @@ func ToRejectReasonData(rr RejectReason) RejectReasonData {
 		return RejectReasonData{Type: 3, Message: v.Message}
-	case RejectReasonData:
-		return v
+	case *RejectReasonData:
+		return *v
 	default:
</file context>

updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
for k, v := range b.Update.ProtocolParamUpdates {
updateMap[k] = v
updateMap[k] = &v
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Range variable address escapes: map stores pointers to reused loop variable so all entries can reference the last update

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ledger/alonzo/alonzo.go, line 298:

<comment>Range variable address escapes: map stores pointers to reused loop variable so all entries can reference the last update</comment>

<file context>
@@ -295,7 +295,7 @@ func (b *AlonzoTransactionBody) ProtocolParameterUpdates() (uint64, map[common.B
 	updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
 	for k, v := range b.Update.ProtocolParamUpdates {
-		updateMap[k] = v
+		updateMap[k] = &v
 	}
 	return b.Update.Epoch, updateMap
</file context>
Suggested change
updateMap[k] = &v
vv := v
updateMap[k] = &vv

OutputIndex: uint32(utxoId.Idx),
},
Output: output,
Output: &output,
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: All UTxOs take the address of the reused range variable output, so every Output pointer aliases the same value (last iteration) instead of the per-UTxO output.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At internal/test/conformance/conformance_test.go, line 1076:

<comment>All UTxOs take the address of the reused range variable `output`, so every `Output` pointer aliases the same value (last iteration) instead of the per-UTxO output.</comment>

<file context>
@@ -1073,7 +1073,7 @@ func (s *initialStateUtxos) UnmarshalCBOR(data []byte) error {
 						OutputIndex: uint32(utxoId.Idx),
 					},
-					Output: output,
+					Output: &output,
 				})
 			}
</file context>

updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
for k, v := range b.Update.ProtocolParamUpdates {
updateMap[k] = v
updateMap[k] = &v
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Map range takes address of loop variable, so all updates map entries share the last value

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ledger/conway/conway.go, line 529:

<comment>Map range takes address of loop variable, so all updates map entries share the last value</comment>

<file context>
@@ -526,7 +526,7 @@ func (b *ConwayTransactionBody) ProtocolParameterUpdates() (uint64, map[common.B
 	updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
 	for k, v := range b.Update.ProtocolParamUpdates {
-		updateMap[k] = v
+		updateMap[k] = &v
 	}
 	return b.Update.Epoch, updateMap
</file context>
Suggested change
updateMap[k] = &v
for k, v := range b.Update.ProtocolParamUpdates {
vv := v
updateMap[k] = &vv
}

updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
for k, v := range b.Update.ProtocolParamUpdates {
updateMap[k] = v
updateMap[k] = &v
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Protocol parameter updates map stores pointer to reused range variable, causing every entry to reference the last update

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ledger/babbage/babbage.go, line 416:

<comment>Protocol parameter updates map stores pointer to reused range variable, causing every entry to reference the last update</comment>

<file context>
@@ -413,7 +413,7 @@ func (b *BabbageTransactionBody) ProtocolParameterUpdates() (uint64, map[common.
 	updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
 	for k, v := range b.Update.ProtocolParamUpdates {
-		updateMap[k] = v
+		updateMap[k] = &v
 	}
 	return b.Update.Epoch, updateMap
</file context>
Suggested change
updateMap[k] = &v
vCopy := v
updateMap[k] = &vCopy

updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
for k, v := range b.Update.ProtocolParamUpdates {
updateMap[k] = v
updateMap[k] = &v
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Range variable address stored; all map entries point to the same update

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ledger/shelley/shelley.go, line 309:

<comment>Range variable address stored; all map entries point to the same update</comment>

<file context>
@@ -306,7 +306,7 @@ func (b *ShelleyTransactionBody) ProtocolParameterUpdates() (uint64, map[common.
 	updateMap := make(map[common.Blake2b224]common.ProtocolParameterUpdate)
 	for k, v := range b.Update.ProtocolParamUpdates {
-		updateMap[k] = v
+		updateMap[k] = &v
 	}
 	return b.Update.Epoch, updateMap
</file context>

}

func (v Constructor) MarshalJSON() ([]byte, error) {
func (v *Constructor) MarshalJSON() ([]byte, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

P1: Constructor MarshalJSON changed to pointer receiver but callers still marshal Constructor values, so custom JSON output is bypassed

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At cbor/value.go, line 353:

<comment>Constructor MarshalJSON changed to pointer receiver but callers still marshal Constructor values, so custom JSON output is bypassed</comment>

<file context>
@@ -350,7 +350,7 @@ func (c Constructor) MarshalCBOR() ([]byte, error) {
 }
 
-func (v Constructor) MarshalJSON() ([]byte, error) {
+func (v *Constructor) MarshalJSON() ([]byte, error) {
 	var sb strings.Builder
 	sb.WriteString(fmt.Sprintf(`{"constructor":%d,"fields":[`, v.constructor))
</file context>

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.

Resolve recvcheck errors

1 participant