diff --git a/core/types/rlp_backwards_compat.libevm_test.go b/core/types/backwards_compat.libevm_test.go
similarity index 64%
rename from core/types/rlp_backwards_compat.libevm_test.go
rename to core/types/backwards_compat.libevm_test.go
index 673bf548c39..81b287177c4 100644
--- a/core/types/rlp_backwards_compat.libevm_test.go
+++ b/core/types/backwards_compat.libevm_test.go
@@ -14,7 +14,7 @@
// along with the go-ethereum library. If not, see
// .
-package types_test
+package types
import (
"encoding/hex"
@@ -26,91 +26,9 @@ import (
"github.com/stretchr/testify/require"
"github.com/ava-labs/libevm/common"
- . "github.com/ava-labs/libevm/core/types"
- "github.com/ava-labs/libevm/libevm/cmpeth"
- "github.com/ava-labs/libevm/libevm/ethtest"
"github.com/ava-labs/libevm/rlp"
)
-func TestHeaderRLPBackwardsCompatibility(t *testing.T) {
- tests := []struct {
- name string
- register func()
- }{
- {
- name: "no registered extras",
- register: func() {},
- },
- {
- name: "no-op header hooks",
- register: func() {
- RegisterExtras[NOOPHeaderHooks, *NOOPHeaderHooks, struct{}]()
- },
- },
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- TestOnlyClearRegisteredExtras()
- defer TestOnlyClearRegisteredExtras()
- tt.register()
- testHeaderRLPBackwardsCompatibility(t)
- })
- }
-}
-
-//nolint:thelper
-func testHeaderRLPBackwardsCompatibility(t *testing.T) {
- // This is a deliberate change-detector test that locks in backwards
- // compatibility of RLP encoding.
- rng := ethtest.NewPseudoRand(42)
-
- const numExtraBytes = 16
- hdr := &Header{
- ParentHash: rng.Hash(),
- UncleHash: rng.Hash(),
- Coinbase: rng.Address(),
- Root: rng.Hash(),
- TxHash: rng.Hash(),
- ReceiptHash: rng.Hash(),
- Bloom: rng.Bloom(),
- Difficulty: rng.Uint256().ToBig(),
- Number: rng.BigUint64(),
- GasLimit: rng.Uint64(),
- GasUsed: rng.Uint64(),
- Time: rng.Uint64(),
- Extra: rng.Bytes(numExtraBytes),
- MixDigest: rng.Hash(),
- Nonce: rng.BlockNonce(),
-
- BaseFee: rng.BigUint64(),
- WithdrawalsHash: rng.HashPtr(),
- BlobGasUsed: rng.Uint64Ptr(),
- ExcessBlobGas: rng.Uint64Ptr(),
- ParentBeaconRoot: rng.HashPtr(),
- }
- t.Logf("%T:\n%+v", hdr, hdr)
-
- // WARNING: changing this hex might break backwards compatibility of RLP
- // encoding (i.e. block hashes might change)!
- const wantHex = `f9029aa01a571e7e4d774caf46053201cfe0001b3c355ffcc93f510e671e8809741f0eeda0756095410506ec72a2c287fe83ebf68efb0be177e61acec1c985277e90e52087941bfc3bc193012ba58912c01fb35a3454831a8971a00bc9f064144eb5965c5e5d1020f9f90392e7e06ded9225966abc7c754b410e61a0d942eab201424f4320ec1e1ffa9390baf941629b9349977b5d48e0502dbb9386a035d9d550a9c113f78689b4c161c4605609bb57b83061914c42ad244daa7fc38eb901004b31d39ae246d689f23176d679a62ff328f530407cbafd0146f45b2ed635282e2812f2705bfffe52576a6fb31df817f29efac71fa56b8e133334079f8e2a8fd2055451571021506f27190adb52a1313f6d28c77d66ae1aa3d3d6757a762476f4c8a2b7b2a37079a4b6a15d1bc44161190c82d5e1c8b55e05c7354f1e5f6512924c941fb3d93667dc3a8c304a3c164e6525dfc99b5f474110c5059485732153e20300c3482832d07b65f97958360da414cb438ce252aec6c2718d155798390a6c6782181d1bac1dd64cd956332b008412ddc735f2994e297c8a088c6bb4c637542295ba3cbc3cd399c8127076f4d834d74d5b11a36b6d02e2fe3a583216aa4ccea0f052df9a96e7a454256bebabdfc38c429079f25913e0f1d7416b2f056c4a115f88b85f0e9fd6d25717881f03d9985060087c88a2c54269dfd07ca388eb8f974b42a412da90c757012bf5479896165caf573cf82fb3a0aa10f6ebf6b62bef8ed36b8ea3d4b1ddb80c99afafa37cb8f3393eb6d802f5bc886c8cd6bcd168a7e0886d5b1345d948b818a0061a7182ff228a4e66bade4717e6f4d318ac98fca12a053af6f98805a764fb5d8890ed9cab2c5229908891c7e2f71857c77ca0523cb6f654ef3fc7294c7768cddd9ccf4bcda3066d382675f37dd1a18507b5fb`
- wantRLP, err := hex.DecodeString(wantHex)
- require.NoError(t, err, "hex.DecodeString()")
-
- t.Run("Encode", func(t *testing.T) {
- got, err := rlp.EncodeToBytes(hdr)
- require.NoErrorf(t, err, "rlp.EncodeToBytes(%T)", hdr)
- assert.Equalf(t, wantRLP, got, "rlp.EncodeToBytes(%T)", hdr)
- })
-
- t.Run("Decode", func(t *testing.T) {
- got := new(Header)
- err := rlp.DecodeBytes(wantRLP, got)
- require.NoErrorf(t, err, "rlp.DecodeBytes(..., %T)", hdr)
- assert.Equal(t, hdr, got)
- })
-}
-
func TestBodyRLPBackwardsCompatibility(t *testing.T) {
newTx := func(nonce uint64) *Transaction { return NewTx(&LegacyTx{Nonce: nonce}) }
newHdr := func(hashLow byte) *Header { return &Header{ParentHash: common.Hash{hashLow}} }
@@ -176,8 +94,8 @@ func TestBodyRLPBackwardsCompatibility(t *testing.T) {
}
opts := cmp.Options{
- cmpeth.CompareHeadersByHash(),
- cmpeth.CompareTransactionsByBinary(t),
+ cmp.Comparer((*Header).equalHash),
+ cmp.Comparer((*Transaction).equalHash),
}
if diff := cmp.Diff(body, got, opts); diff != "" {
t.Errorf("rlp.DecodeBytes(rlp.EncodeToBytes(%#v)) diff (-want +got):\n%s", body, diff)
@@ -292,8 +210,8 @@ func TestBodyRLPCChainCompat(t *testing.T) {
assert.Equal(t, tt.extra, &extra, "rlp.DecodeBytes(%#x, [%T as registered extra in %T carrier])", wantRLP, &extra, got)
opts := cmp.Options{
- cmpeth.CompareHeadersByHash(),
- cmpeth.CompareTransactionsByBinary(t),
+ cmp.Comparer((*Header).equalHash),
+ cmp.Comparer((*Transaction).equalHash),
}
if diff := cmp.Diff(body, got, opts); diff != "" {
t.Errorf("rlp.DecodeBytes(%#x, [%T while carrying registered %T extra payload]) diff (-want +got):\n%s", wantRLP, got, &extra, diff)
@@ -302,3 +220,24 @@ func TestBodyRLPCChainCompat(t *testing.T) {
})
}
}
+
+// equalHash reports whether `a` and `b` have equal hashes. It allows for nil
+// arguments, returning `true` if both are nil, `false` if only one is nil,
+// otherwise `a.Hash() == b.Hash()`.
+func equalHash[
+ T any, P interface {
+ Hash() common.Hash
+ *T
+ },
+](a, b P) bool {
+ if a == nil && b == nil {
+ return true
+ }
+ if a == nil || b == nil {
+ return false
+ }
+ return a.Hash() == b.Hash()
+}
+
+func (h *Header) equalHash(hh *Header) bool { return equalHash(h, hh) }
+func (tx *Transaction) equalHash(u *Transaction) bool { return equalHash(tx, u) }
diff --git a/core/types/backwards_compat_diffpkg.libevm_test.go b/core/types/backwards_compat_diffpkg.libevm_test.go
new file mode 100644
index 00000000000..47c704c44c7
--- /dev/null
+++ b/core/types/backwards_compat_diffpkg.libevm_test.go
@@ -0,0 +1,108 @@
+// Copyright 2024-2025 the libevm authors.
+//
+// The libevm additions to go-ethereum are free software: you can redistribute
+// them and/or modify them under the terms of the GNU Lesser General Public License
+// as published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The libevm additions are distributed in the hope that they will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see
+// .
+
+package types_test
+
+import (
+ "encoding/hex"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ . "github.com/ava-labs/libevm/core/types"
+ "github.com/ava-labs/libevm/libevm/ethtest"
+ "github.com/ava-labs/libevm/rlp"
+)
+
+func TestHeaderRLPBackwardsCompatibility(t *testing.T) {
+ tests := []struct {
+ name string
+ register func()
+ }{
+ {
+ name: "no registered extras",
+ register: func() {},
+ },
+ {
+ name: "no-op header hooks",
+ register: func() {
+ RegisterExtras[NOOPHeaderHooks, *NOOPHeaderHooks, struct{}]()
+ },
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ TestOnlyClearRegisteredExtras()
+ defer TestOnlyClearRegisteredExtras()
+ tt.register()
+ testHeaderRLPBackwardsCompatibility(t)
+ })
+ }
+}
+
+//nolint:thelper
+func testHeaderRLPBackwardsCompatibility(t *testing.T) {
+ // This is a deliberate change-detector test that locks in backwards
+ // compatibility of RLP encoding.
+ rng := ethtest.NewPseudoRand(42)
+
+ const numExtraBytes = 16
+ hdr := &Header{
+ ParentHash: rng.Hash(),
+ UncleHash: rng.Hash(),
+ Coinbase: rng.Address(),
+ Root: rng.Hash(),
+ TxHash: rng.Hash(),
+ ReceiptHash: rng.Hash(),
+ Bloom: rng.Bloom(),
+ Difficulty: rng.Uint256().ToBig(),
+ Number: rng.BigUint64(),
+ GasLimit: rng.Uint64(),
+ GasUsed: rng.Uint64(),
+ Time: rng.Uint64(),
+ Extra: rng.Bytes(numExtraBytes),
+ MixDigest: rng.Hash(),
+ Nonce: rng.BlockNonce(),
+
+ BaseFee: rng.BigUint64(),
+ WithdrawalsHash: rng.HashPtr(),
+ BlobGasUsed: rng.Uint64Ptr(),
+ ExcessBlobGas: rng.Uint64Ptr(),
+ ParentBeaconRoot: rng.HashPtr(),
+ }
+ t.Logf("%T:\n%+v", hdr, hdr)
+
+ // WARNING: changing this hex might break backwards compatibility of RLP
+ // encoding (i.e. block hashes might change)!
+ const wantHex = `f9029aa01a571e7e4d774caf46053201cfe0001b3c355ffcc93f510e671e8809741f0eeda0756095410506ec72a2c287fe83ebf68efb0be177e61acec1c985277e90e52087941bfc3bc193012ba58912c01fb35a3454831a8971a00bc9f064144eb5965c5e5d1020f9f90392e7e06ded9225966abc7c754b410e61a0d942eab201424f4320ec1e1ffa9390baf941629b9349977b5d48e0502dbb9386a035d9d550a9c113f78689b4c161c4605609bb57b83061914c42ad244daa7fc38eb901004b31d39ae246d689f23176d679a62ff328f530407cbafd0146f45b2ed635282e2812f2705bfffe52576a6fb31df817f29efac71fa56b8e133334079f8e2a8fd2055451571021506f27190adb52a1313f6d28c77d66ae1aa3d3d6757a762476f4c8a2b7b2a37079a4b6a15d1bc44161190c82d5e1c8b55e05c7354f1e5f6512924c941fb3d93667dc3a8c304a3c164e6525dfc99b5f474110c5059485732153e20300c3482832d07b65f97958360da414cb438ce252aec6c2718d155798390a6c6782181d1bac1dd64cd956332b008412ddc735f2994e297c8a088c6bb4c637542295ba3cbc3cd399c8127076f4d834d74d5b11a36b6d02e2fe3a583216aa4ccea0f052df9a96e7a454256bebabdfc38c429079f25913e0f1d7416b2f056c4a115f88b85f0e9fd6d25717881f03d9985060087c88a2c54269dfd07ca388eb8f974b42a412da90c757012bf5479896165caf573cf82fb3a0aa10f6ebf6b62bef8ed36b8ea3d4b1ddb80c99afafa37cb8f3393eb6d802f5bc886c8cd6bcd168a7e0886d5b1345d948b818a0061a7182ff228a4e66bade4717e6f4d318ac98fca12a053af6f98805a764fb5d8890ed9cab2c5229908891c7e2f71857c77ca0523cb6f654ef3fc7294c7768cddd9ccf4bcda3066d382675f37dd1a18507b5fb`
+ wantRLP, err := hex.DecodeString(wantHex)
+ require.NoError(t, err, "hex.DecodeString()")
+
+ t.Run("Encode", func(t *testing.T) {
+ got, err := rlp.EncodeToBytes(hdr)
+ require.NoErrorf(t, err, "rlp.EncodeToBytes(%T)", hdr)
+ assert.Equalf(t, wantRLP, got, "rlp.EncodeToBytes(%T)", hdr)
+ })
+
+ t.Run("Decode", func(t *testing.T) {
+ got := new(Header)
+ err := rlp.DecodeBytes(wantRLP, got)
+ require.NoErrorf(t, err, "rlp.DecodeBytes(..., %T)", hdr)
+ assert.Equal(t, hdr, got)
+ })
+}
diff --git a/libevm/cmpeth/cmpeth.go b/libevm/cmpeth/cmpeth.go
deleted file mode 100644
index 8d17e3e5192..00000000000
--- a/libevm/cmpeth/cmpeth.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2025 the libevm authors.
-//
-// The libevm additions to go-ethereum are free software: you can redistribute
-// them and/or modify them under the terms of the GNU Lesser General Public License
-// as published by the Free Software Foundation, either version 3 of the License,
-// or (at your option) any later version.
-//
-// The libevm additions are distributed in the hope that they will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-// General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see
-// .
-
-// Package cmpeth provides ETH-specific options for the cmp package.
-package cmpeth
-
-import (
- "bytes"
- "testing"
-
- "github.com/google/go-cmp/cmp"
-
- "github.com/ava-labs/libevm/core/types"
-)
-
-// CompareHeadersByHash returns an option to compare Headers based on
-// [types.Header.Hash] equality.
-func CompareHeadersByHash() cmp.Option {
- return cmp.Comparer(func(a, b *types.Header) bool {
- return a.Hash() == b.Hash()
- })
-}
-
-// CompareTransactionsByBinary returns an option to compare Transactions based
-// on [types.Transaction.MarshalBinary] equality. Two nil pointers are
-// considered equal.
-//
-// If MarshalBinary() returns an error, it will be reported with
-// [testing.TB.Fatal].
-func CompareTransactionsByBinary(tb testing.TB) cmp.Option {
- tb.Helper()
- return cmp.Comparer(func(a, b *types.Transaction) bool {
- tb.Helper()
-
- if a == nil && b == nil {
- return true
- }
- if a == nil || b == nil {
- return false
- }
-
- return bytes.Equal(marshalTxBinary(tb, a), marshalTxBinary(tb, b))
- })
-}
-
-func marshalTxBinary(tb testing.TB, tx *types.Transaction) []byte {
- tb.Helper()
- buf, err := tx.MarshalBinary()
- if err != nil {
- tb.Fatalf("%T.MarshalBinary() error %v", tx, err)
- }
- return buf
-}