Skip to content

sae: Add C-chain custom tx serialization#5307

Merged
StephenButtolph merged 17 commits intomasterfrom
StephenButtolph/atomic-tx-rewrite.1
Apr 30, 2026
Merged

sae: Add C-chain custom tx serialization#5307
StephenButtolph merged 17 commits intomasterfrom
StephenButtolph/atomic-tx-rewrite.1

Conversation

@StephenButtolph
Copy link
Copy Markdown
Contributor

@StephenButtolph StephenButtolph commented Apr 25, 2026

Why this should be merged

This PR factors out tx serialization from #5303.

How this works

The new tx package still relies on the avalanchego codec for serialization, however some changes were made to the transactions to provide a better QoL when interacting with the custom Txs.

  1. The codec is not exported, no package outside of tx should be manually marshaling or unmarshaling transactions.
  2. The existing codec registered some types which are currently unused: secp256k1fx.Input and secp256k1fx.OutputOwners. Those are removed.
  3. The existing tx definitions allow for the tx.Creds slice to be populated with types that are disallowed by later type-checks: secp256k1fx.Input, secp256k1fx.OutputOwners, secp256k1fx.TransferOutput, and secp256k1fx.TransferInput. The new transaction type disallows this within the codec.
  4. The prior pattern of using atomic.Metadata within the unsigned transaction implementations was removed. We may choose to add caching back in later, but if done, it should be done at the Tx level once, rather than in both Export and Import.

I'm marking myself as the only code-owner of this folder (at least until @ARR4N comes back from PTO)

How this was tested

  • Included both Import and Export txs from mainnet C-chain as known valid transactions.
  • Fuzzed canonical binary format
  • Fuzzed equality of canonical binary format
  • Fuzzed equality of json format

Need to be documented in RELEASES.md?

No

var (
tests = []struct {
name string
old *atomic.Tx
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This package includes both old and new in the tests to ensure compatibility with the prior code. Technically we could remove old and just treat the bytes as canonical... But it made me more confident in the change.

Comment on lines +363 to +376
func FuzzParseCompatibility(f *testing.F) {
for _, test := range tests {
f.Add(test.bytes)
}
f.Fuzz(func(t *testing.T, data []byte) {
_, oldErr := parseOldTx(data)
oldOk := oldErr == nil

_, newErr := Parse(data)
newOk := newErr == nil

assert.Equal(t, oldOk, newOk, "Parse(b) == parseOldTx(b)")
})
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The testdata included for this test did fail during development, so those are intentionally kept as regression tests. I actually wasn't aware prior to this that the old tx parsing logic could result in non-secp256k1fx.Credentials being parsed into the credential type.

It is safe, as we verify the types later during verification... But it caused this test to fail.

I have since verified that such type confusion can no longer happen with this package.

@StephenButtolph StephenButtolph changed the title Re-write C-chain atomic txs for SAE sae: Add C-chain atomic tx serialization Apr 25, 2026
@StephenButtolph StephenButtolph changed the title sae: Add C-chain atomic tx serialization sae: Add C-chain custom tx serialization Apr 25, 2026
@StephenButtolph StephenButtolph marked this pull request as ready for review April 25, 2026 18:04
@StephenButtolph StephenButtolph requested a review from ARR4N as a code owner April 25, 2026 18:04
Copilot AI review requested due to automatic review settings April 25, 2026 18:04
@StephenButtolph StephenButtolph requested review from a team as code owners April 25, 2026 18:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a dedicated vms/saevm/cchain/tx package to provide canonical (binary + JSON) serialization/parsing for C-Chain atomic import/export transactions, factoring out logic from the earlier work and tightening codec/type restrictions.

Changes:

  • Added a new C-Chain atomic tx package with its own unexported codec manager and helpers to marshal/parse single txs and tx slices.
  • Added unit + fuzz tests to ensure binary/JSON compatibility with the existing coreth atomic tx encoding and known mainnet tx fixtures.
  • Introduced small supporting API changes: secp256k1fx.Credential.Self(), ids.ShortFromStringOrPanic, and exported atomic.ErrMissingAtomicTxs.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
vms/saevm/cchain/tx/tx.go Defines the new signed tx type, ID/Bytes helpers, and slice marshal/parse helpers.
vms/saevm/cchain/tx/codec.go Creates an internal codec manager with explicit type registration order.
vms/saevm/cchain/tx/import.go Adds the unsigned Import tx definition and C-Chain Output type.
vms/saevm/cchain/tx/export.go Adds the unsigned Export tx definition and C-Chain Input type.
vms/saevm/cchain/tx/tx_test.go Adds known-vector tests plus fuzzers for compatibility and round-trips.
vms/saevm/cchain/tx/testdata/fuzz/** Adds fuzz corpora for regression and coverage.
vms/saevm/cchain/tx/BUILD.bazel Bazel build/test targets for the new package and its tests.
vms/secp256k1fx/credential.go Adds Self() to support restricting credential types in the new codec-facing interface.
ids/short.go Adds ShortFromStringOrPanic helper.
graft/coreth/plugin/evm/atomic/codec.go Exports the “missing atomic txs” error as ErrMissingAtomicTxs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread vms/saevm/cchain/tx/import.go
Comment thread vms/saevm/cchain/tx/export.go
Comment thread vms/saevm/cchain/tx/tx_test.go Outdated
Comment thread graft/coreth/plugin/evm/atomic/codec.go
Comment thread ids/short.go Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread vms/saevm/cchain/tx/tx_test.go
Comment thread vms/saevm/cchain/tx/tx_test.go
Comment thread vms/saevm/cchain/tx/tx_test.go
Comment thread vms/saevm/cchain/tx/tx.go
Comment thread vms/saevm/cchain/tx/tx_test.go
@StephenButtolph StephenButtolph force-pushed the StephenButtolph/atomic-tx-rewrite.1 branch from d3e8110 to eb8c0a0 Compare April 25, 2026 22:42
Comment thread vms/saevm/cchain/tx/tx.go Outdated
Comment thread vms/saevm/cchain/tx/tx_test.go Outdated
Comment thread vms/saevm/cchain/tx/tx_test.go Outdated
Comment thread ids/short.go
Copy link
Copy Markdown
Contributor

@alarso16 alarso16 left a comment

Choose a reason for hiding this comment

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

Having seen the final form of the atomic txs, I think this is fine. I don't love the test format, only because it would be really difficult to maintain. However, I'm approving with the hope that we will delete it all after the H upgrade.

Comment thread vms/saevm/cchain/tx/codec.go
Comment thread vms/saevm/cchain/tx/tx.go Outdated
@StephenButtolph
Copy link
Copy Markdown
Contributor Author

I don't love the test format, only because it would be really difficult to maintain. However, I'm approving with the hope that we will delete it all after the H upgrade.

I felt like using the prior code made these tests stronger... Once we remove coreth, the compatibility fuzzing will go away, but the test vectors will still exist.

Copy link
Copy Markdown
Contributor

@JonathanOppenheimer JonathanOppenheimer left a comment

Choose a reason for hiding this comment

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

I believe the bazel metadata has to be re-generated

Comment thread graft/coreth/BUILD.bazel
"//tests/reexecute/c",
"//tests/reexecute/chaos",
"//vms/evm/emulate",
"//vms/saevm/cchain/...",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@ARR4N is this an anti-pattern? I could just expose this to the packages as needed rather than for the whole sub-tree.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not an anti-pattern, just a question of what we believe the most appropriate scope to be. The others are only fine-grained because I had my agent (Maru) do it (with his agent). I think we could reasonably allow anything in //tests/... too but there's no need right now.

To me the more important thing is that the other //vms/saevm packages never import the //vms/saevm/cchain ones.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I updated the visibility logic to match graft/coreth.

@StephenButtolph StephenButtolph self-assigned this Apr 30, 2026
@StephenButtolph StephenButtolph moved this to In Progress 🏗️ in avalanchego Apr 30, 2026
Comment thread vms/saevm/cchain/tx/tx_test.go Outdated
Comment thread vms/saevm/cchain/tx/export.go
Comment thread graft/coreth/BUILD.bazel
"//tests/reexecute/c",
"//tests/reexecute/chaos",
"//vms/evm/emulate",
"//vms/saevm/cchain/...",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not an anti-pattern, just a question of what we believe the most appropriate scope to be. The others are only fine-grained because I had my agent (Maru) do it (with his agent). I think we could reasonably allow anything in //tests/... too but there's no need right now.

To me the more important thing is that the other //vms/saevm packages never import the //vms/saevm/cchain ones.

Comment thread vms/saevm/cchain/tx/BUILD.bazel Outdated
@StephenButtolph StephenButtolph merged commit e413347 into master Apr 30, 2026
60 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress 🏗️ to Done 🎉 in avalanchego Apr 30, 2026
@StephenButtolph StephenButtolph deleted the StephenButtolph/atomic-tx-rewrite.1 branch April 30, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done 🎉

Development

Successfully merging this pull request may close these issues.

5 participants