Skip to content

Commit bd44839

Browse files
authored
test: lock in types.Header RLP encoding (#87)
## Why this should be merged We're making changes to very sensitive code that, if broken, can result in block hashes being different. ## How this works Change-detector test. ## How this was tested A randomly filled `types.Header` with expected RLP locked as a constant in the test.
1 parent aa183c5 commit bd44839

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright 2024 the libevm authors.
2+
//
3+
// The libevm additions to go-ethereum are free software: you can redistribute
4+
// them and/or modify them under the terms of the GNU Lesser General Public License
5+
// as published by the Free Software Foundation, either version 3 of the License,
6+
// or (at your option) any later version.
7+
//
8+
// The libevm additions are distributed in the hope that they will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11+
// General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU Lesser General Public License
14+
// along with the go-ethereum library. If not, see
15+
// <http://www.gnu.org/licenses/>.
16+
17+
package types_test
18+
19+
import (
20+
"encoding/hex"
21+
"testing"
22+
23+
"github.com/stretchr/testify/assert"
24+
"github.com/stretchr/testify/require"
25+
26+
. "github.com/ava-labs/libevm/core/types"
27+
"github.com/ava-labs/libevm/libevm/ethtest"
28+
"github.com/ava-labs/libevm/rlp"
29+
)
30+
31+
func TestHeaderRLPBackwardsCompatibility(t *testing.T) {
32+
// This is a deliberate change-detector test that locks in backwards
33+
// compatibility of RLP encoding.
34+
rng := ethtest.NewPseudoRand(42)
35+
36+
const numExtraBytes = 16
37+
hdr := &Header{
38+
ParentHash: rng.Hash(),
39+
UncleHash: rng.Hash(),
40+
Coinbase: rng.Address(),
41+
Root: rng.Hash(),
42+
TxHash: rng.Hash(),
43+
ReceiptHash: rng.Hash(),
44+
Bloom: rng.Bloom(),
45+
Difficulty: rng.Uint256().ToBig(),
46+
Number: rng.BigUint64(),
47+
GasLimit: rng.Uint64(),
48+
GasUsed: rng.Uint64(),
49+
Time: rng.Uint64(),
50+
Extra: rng.Bytes(numExtraBytes),
51+
MixDigest: rng.Hash(),
52+
Nonce: rng.BlockNonce(),
53+
54+
BaseFee: rng.BigUint64(),
55+
WithdrawalsHash: rng.HashPtr(),
56+
BlobGasUsed: rng.Uint64Ptr(),
57+
ExcessBlobGas: rng.Uint64Ptr(),
58+
ParentBeaconRoot: rng.HashPtr(),
59+
}
60+
t.Logf("%T:\n%+v", hdr, hdr)
61+
62+
// WARNING: changing this hex might break backwards compatibility of RLP
63+
// encoding (i.e. block hashes might change)!
64+
const wantHex = `f9029aa01a571e7e4d774caf46053201cfe0001b3c355ffcc93f510e671e8809741f0eeda0756095410506ec72a2c287fe83ebf68efb0be177e61acec1c985277e90e52087941bfc3bc193012ba58912c01fb35a3454831a8971a00bc9f064144eb5965c5e5d1020f9f90392e7e06ded9225966abc7c754b410e61a0d942eab201424f4320ec1e1ffa9390baf941629b9349977b5d48e0502dbb9386a035d9d550a9c113f78689b4c161c4605609bb57b83061914c42ad244daa7fc38eb901004b31d39ae246d689f23176d679a62ff328f530407cbafd0146f45b2ed635282e2812f2705bfffe52576a6fb31df817f29efac71fa56b8e133334079f8e2a8fd2055451571021506f27190adb52a1313f6d28c77d66ae1aa3d3d6757a762476f4c8a2b7b2a37079a4b6a15d1bc44161190c82d5e1c8b55e05c7354f1e5f6512924c941fb3d93667dc3a8c304a3c164e6525dfc99b5f474110c5059485732153e20300c3482832d07b65f97958360da414cb438ce252aec6c2718d155798390a6c6782181d1bac1dd64cd956332b008412ddc735f2994e297c8a088c6bb4c637542295ba3cbc3cd399c8127076f4d834d74d5b11a36b6d02e2fe3a583216aa4ccea0f052df9a96e7a454256bebabdfc38c429079f25913e0f1d7416b2f056c4a115f88b85f0e9fd6d25717881f03d9985060087c88a2c54269dfd07ca388eb8f974b42a412da90c757012bf5479896165caf573cf82fb3a0aa10f6ebf6b62bef8ed36b8ea3d4b1ddb80c99afafa37cb8f3393eb6d802f5bc886c8cd6bcd168a7e0886d5b1345d948b818a0061a7182ff228a4e66bade4717e6f4d318ac98fca12a053af6f98805a764fb5d8890ed9cab2c5229908891c7e2f71857c77ca0523cb6f654ef3fc7294c7768cddd9ccf4bcda3066d382675f37dd1a18507b5fb`
65+
want, err := hex.DecodeString(wantHex)
66+
require.NoError(t, err, "hex.DecodeString()")
67+
68+
got, err := rlp.EncodeToBytes(hdr)
69+
require.NoErrorf(t, err, "rlp.EncodeToBytes(%T)", hdr)
70+
assert.Equalf(t, want, got, "rlp.EncodeToBytes(%T)", hdr)
71+
}

libevm/ethtest/rand.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"golang.org/x/exp/rand"
2424

2525
"github.com/ava-labs/libevm/common"
26+
"github.com/ava-labs/libevm/core/types"
2627
)
2728

2829
// PseudoRand extends [rand.Rand] (*not* crypto/rand).
@@ -88,3 +89,15 @@ func (r *PseudoRand) Uint64Ptr() *uint64 {
8889
func (r *PseudoRand) Uint256() *uint256.Int {
8990
return new(uint256.Int).SetBytes(r.Bytes(32))
9091
}
92+
93+
// Bloom returns a pseudorandom Bloom.
94+
func (r *PseudoRand) Bloom() (b types.Bloom) {
95+
r.Read(b[:])
96+
return b
97+
}
98+
99+
// BlockNonce returns a pseudorandom BlockNonce.
100+
func (r *PseudoRand) BlockNonce() (n types.BlockNonce) {
101+
r.Read(n[:])
102+
return n
103+
}

0 commit comments

Comments
 (0)