Skip to content

Commit f174ddb

Browse files
build, tests: add execution-spec-tests (#26985)
This makes it possible to run the execution-spec-tests (a.k.a. pyspec) in CI. --------- Co-authored-by: Felix Lange <[email protected]>
1 parent d4e345c commit f174ddb

File tree

7 files changed

+191
-88
lines changed

7 files changed

+191
-88
lines changed

build/checksums.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# This file contains sha256 checksums of optional build dependencies.
22

3+
# https://github.com/ethereum/execution-spec-tests/releases
4+
24bac679f3a2d8240d8e08e7f6a70b70c2dabf673317d924cf1d1887b9fe1f81 fixtures.tar.gz
5+
6+
# https://go.dev/dl/
37
818d46ede85682dd551ad378ef37a4d247006f12ec59b5b755601d2ce114369a go1.21.0.src.tar.gz
48
b314de9f704ab122c077d2ec8e67e3670affe8865479d1f01991e7ac55d65e70 go1.21.0.darwin-amd64.tar.gz
59
3aca44de55c5e098de2f406e98aba328898b05d509a2e2a356416faacf2c4566 go1.21.0.darwin-arm64.tar.gz
@@ -15,7 +19,7 @@ af920fbb74fc3d173118dc3cc35f02a709c1de642700e92a91a7d16981df3fec go1.21.0.windo
1519
732121e64e0ecb07c77fdf6cc1bc5ce7b242c2d40d4ac29021ad4c64a08731f6 go1.21.0.windows-amd64.zip
1620
41342f5a0f8c083b14c68bde738ddcd313a4f53a5854bfdfab47f0e88247de12 go1.21.0.windows-arm64.zip
1721

18-
22+
# https://github.com/golangci/golangci-lint/releases
1923
fba08acc4027f69f07cef48fbff70b8a7ecdfaa1c2aba9ad3fb31d60d9f5d4bc golangci-lint-1.51.1-darwin-amd64.tar.gz
2024
75b8f0ff3a4e68147156be4161a49d4576f1be37a0b506473f8c482140c1e7f2 golangci-lint-1.51.1-darwin-arm64.tar.gz
2125
e06b3459aaed356e1667580be00b05f41f3b2e29685d12cdee571c23e1edb414 golangci-lint-1.51.1-freebsd-386.tar.gz

build/ci.go

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,12 @@ var (
123123
// wily, yakkety, zesty, artful, cosmic, disco, eoan, groovy, hirsuite, impish,
124124
// kinetic
125125
debDistroGoBoots = map[string]string{
126-
"trusty": "golang-1.11", // EOL: 04/2024
127-
"xenial": "golang-go", // EOL: 04/2026
128-
"bionic": "golang-go", // EOL: 04/2028
129-
"focal": "golang-go", // EOL: 04/2030
130-
"jammy": "golang-go", // EOL: 04/2032
131-
"lunar": "golang-go", // EOL: 01/2024
126+
"trusty": "golang-1.11", // EOL: 04/2024
127+
"xenial": "golang-go", // EOL: 04/2026
128+
"bionic": "golang-go", // EOL: 04/2028
129+
"focal": "golang-go", // EOL: 04/2030
130+
"jammy": "golang-go", // EOL: 04/2032
131+
"lunar": "golang-go", // EOL: 01/2024
132132
}
133133

134134
debGoBootPaths = map[string]string{
@@ -148,6 +148,13 @@ var (
148148
// we need to switch over to a recursive builder to jumpt across supported
149149
// versions.
150150
gobootVersion = "1.19.6"
151+
152+
// This is the version of execution-spec-tests that we are using.
153+
// When updating, you must also update build/checksums.txt.
154+
executionSpecTestsVersion = "1.0.2"
155+
156+
// This is where the tests should be unpacked.
157+
executionSpecTestsDir = "tests/spec-tests"
151158
)
152159

153160
var GOBIN, _ = filepath.Abs(filepath.Join("build", "bin"))
@@ -294,13 +301,17 @@ func doTest(cmdline []string) {
294301
coverage = flag.Bool("coverage", false, "Whether to record code coverage")
295302
verbose = flag.Bool("v", false, "Whether to log verbosely")
296303
race = flag.Bool("race", false, "Execute the race detector")
304+
cachedir = flag.String("cachedir", "./build/cache", "directory for caching downloads")
297305
)
298306
flag.CommandLine.Parse(cmdline)
299307

308+
// Get test fixtures.
309+
csdb := build.MustLoadChecksums("build/checksums.txt")
310+
downloadSpecTestFixtures(csdb, *cachedir)
311+
300312
// Configure the toolchain.
301313
tc := build.GoToolchain{GOARCH: *arch, CC: *cc}
302314
if *dlgo {
303-
csdb := build.MustLoadChecksums("build/checksums.txt")
304315
tc.Root = build.DownloadGo(csdb, dlgoVersion)
305316
}
306317
gotest := tc.Go("test")
@@ -332,6 +343,21 @@ func doTest(cmdline []string) {
332343
build.MustRun(gotest)
333344
}
334345

346+
// downloadSpecTestFixtures downloads and extracts the execution-spec-tests fixtures.
347+
func downloadSpecTestFixtures(csdb *build.ChecksumDB, cachedir string) string {
348+
ext := ".tar.gz"
349+
base := "fixtures" // TODO(MariusVanDerWijden) rename once the version becomes part of the filename
350+
url := fmt.Sprintf("https://github.com/ethereum/execution-spec-tests/releases/download/v%s/%s%s", executionSpecTestsVersion, base, ext)
351+
archivePath := filepath.Join(cachedir, base+ext)
352+
if err := csdb.DownloadFile(url, archivePath); err != nil {
353+
log.Fatal(err)
354+
}
355+
if err := build.ExtractArchive(archivePath, executionSpecTestsDir); err != nil {
356+
log.Fatal(err)
357+
}
358+
return filepath.Join(cachedir, base)
359+
}
360+
335361
// doLint runs golangci-lint on requested packages.
336362
func doLint(cmdline []string) {
337363
var (

tests/block_test.go

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@ package tests
1919
import (
2020
"testing"
2121

22+
"github.com/ethereum/go-ethereum/common"
2223
"github.com/ethereum/go-ethereum/core/rawdb"
2324
)
2425

2526
func TestBlockchain(t *testing.T) {
26-
t.Parallel()
27-
2827
bt := new(testMatcher)
2928
// General state tests are 'exported' as blockchain tests, but we can run them natively.
3029
// For speedier CI-runs, the line below can be uncommented, so those are skipped.
@@ -50,20 +49,40 @@ func TestBlockchain(t *testing.T) {
5049
bt.skipLoad(`.*randomStatetest94.json.*`)
5150

5251
bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) {
53-
if err := bt.checkFailure(t, test.Run(false, rawdb.HashScheme, nil)); err != nil {
54-
t.Errorf("test in hash mode without snapshotter failed: %v", err)
55-
}
56-
if err := bt.checkFailure(t, test.Run(true, rawdb.HashScheme, nil)); err != nil {
57-
t.Errorf("test in hash mode with snapshotter failed: %v", err)
58-
}
59-
if err := bt.checkFailure(t, test.Run(false, rawdb.PathScheme, nil)); err != nil {
60-
t.Errorf("test in path mode without snapshotter failed: %v", err)
61-
}
62-
if err := bt.checkFailure(t, test.Run(true, rawdb.PathScheme, nil)); err != nil {
63-
t.Errorf("test in path mode with snapshotter failed: %v", err)
64-
}
52+
execBlockTest(t, bt, test)
6553
})
6654
// There is also a LegacyTests folder, containing blockchain tests generated
6755
// prior to Istanbul. However, they are all derived from GeneralStateTests,
6856
// which run natively, so there's no reason to run them here.
6957
}
58+
59+
// TestExecutionSpec runs the test fixtures from execution-spec-tests.
60+
func TestExecutionSpec(t *testing.T) {
61+
if !common.FileExist(executionSpecDir) {
62+
t.Skipf("directory %s does not exist", executionSpecDir)
63+
}
64+
bt := new(testMatcher)
65+
66+
// cancun tests are not complete yet
67+
bt.skipLoad(`^cancun/`)
68+
bt.skipLoad(`-fork=Cancun`)
69+
70+
bt.walk(t, executionSpecDir, func(t *testing.T, name string, test *BlockTest) {
71+
execBlockTest(t, bt, test)
72+
})
73+
}
74+
75+
func execBlockTest(t *testing.T, bt *testMatcher, test *BlockTest) {
76+
if err := bt.checkFailure(t, test.Run(false, rawdb.HashScheme, nil)); err != nil {
77+
t.Errorf("test in hash mode without snapshotter failed: %v", err)
78+
}
79+
if err := bt.checkFailure(t, test.Run(true, rawdb.HashScheme, nil)); err != nil {
80+
t.Errorf("test in hash mode with snapshotter failed: %v", err)
81+
}
82+
if err := bt.checkFailure(t, test.Run(false, rawdb.PathScheme, nil)); err != nil {
83+
t.Errorf("test in path mode without snapshotter failed: %v", err)
84+
}
85+
if err := bt.checkFailure(t, test.Run(true, rawdb.PathScheme, nil)); err != nil {
86+
t.Errorf("test in path mode with snapshotter failed: %v", err)
87+
}
88+
}

tests/block_test_util.go

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -73,24 +73,27 @@ type btBlock struct {
7373
//go:generate go run github.com/fjl/gencodec -type btHeader -field-override btHeaderMarshaling -out gen_btheader.go
7474

7575
type btHeader struct {
76-
Bloom types.Bloom
77-
Coinbase common.Address
78-
MixHash common.Hash
79-
Nonce types.BlockNonce
80-
Number *big.Int
81-
Hash common.Hash
82-
ParentHash common.Hash
83-
ReceiptTrie common.Hash
84-
StateRoot common.Hash
85-
TransactionsTrie common.Hash
86-
UncleHash common.Hash
87-
ExtraData []byte
88-
Difficulty *big.Int
89-
GasLimit uint64
90-
GasUsed uint64
91-
Timestamp uint64
92-
BaseFeePerGas *big.Int
93-
WithdrawalsRoot *common.Hash
76+
Bloom types.Bloom
77+
Coinbase common.Address
78+
MixHash common.Hash
79+
Nonce types.BlockNonce
80+
Number *big.Int
81+
Hash common.Hash
82+
ParentHash common.Hash
83+
ReceiptTrie common.Hash
84+
StateRoot common.Hash
85+
TransactionsTrie common.Hash
86+
UncleHash common.Hash
87+
ExtraData []byte
88+
Difficulty *big.Int
89+
GasLimit uint64
90+
GasUsed uint64
91+
Timestamp uint64
92+
BaseFeePerGas *big.Int
93+
WithdrawalsRoot *common.Hash
94+
BlobGasUsed *uint64
95+
ExcessBlobGas *uint64
96+
ParentBeaconBlockRoot *common.Hash
9497
}
9598

9699
type btHeaderMarshaling struct {
@@ -101,6 +104,8 @@ type btHeaderMarshaling struct {
101104
GasUsed math.HexOrDecimal64
102105
Timestamp math.HexOrDecimal64
103106
BaseFeePerGas *math.HexOrDecimal256
107+
BlobGasUsed *math.HexOrDecimal64
108+
ExcessBlobGas *math.HexOrDecimal64
104109
}
105110

106111
func (t *BlockTest) Run(snapshotter bool, scheme string, tracer vm.EVMLogger) error {
@@ -175,18 +180,20 @@ func (t *BlockTest) Run(snapshotter bool, scheme string, tracer vm.EVMLogger) er
175180

176181
func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis {
177182
return &core.Genesis{
178-
Config: config,
179-
Nonce: t.json.Genesis.Nonce.Uint64(),
180-
Timestamp: t.json.Genesis.Timestamp,
181-
ParentHash: t.json.Genesis.ParentHash,
182-
ExtraData: t.json.Genesis.ExtraData,
183-
GasLimit: t.json.Genesis.GasLimit,
184-
GasUsed: t.json.Genesis.GasUsed,
185-
Difficulty: t.json.Genesis.Difficulty,
186-
Mixhash: t.json.Genesis.MixHash,
187-
Coinbase: t.json.Genesis.Coinbase,
188-
Alloc: t.json.Pre,
189-
BaseFee: t.json.Genesis.BaseFeePerGas,
183+
Config: config,
184+
Nonce: t.json.Genesis.Nonce.Uint64(),
185+
Timestamp: t.json.Genesis.Timestamp,
186+
ParentHash: t.json.Genesis.ParentHash,
187+
ExtraData: t.json.Genesis.ExtraData,
188+
GasLimit: t.json.Genesis.GasLimit,
189+
GasUsed: t.json.Genesis.GasUsed,
190+
Difficulty: t.json.Genesis.Difficulty,
191+
Mixhash: t.json.Genesis.MixHash,
192+
Coinbase: t.json.Genesis.Coinbase,
193+
Alloc: t.json.Pre,
194+
BaseFee: t.json.Genesis.BaseFeePerGas,
195+
BlobGasUsed: t.json.Genesis.BlobGasUsed,
196+
ExcessBlobGas: t.json.Genesis.ExcessBlobGas,
190197
}
191198
}
192199

@@ -295,6 +302,15 @@ func validateHeader(h *btHeader, h2 *types.Header) error {
295302
if !reflect.DeepEqual(h.WithdrawalsRoot, h2.WithdrawalsHash) {
296303
return fmt.Errorf("withdrawalsRoot: want: %v have: %v", h.WithdrawalsRoot, h2.WithdrawalsHash)
297304
}
305+
if !reflect.DeepEqual(h.BlobGasUsed, h2.BlobGasUsed) {
306+
return fmt.Errorf("blobGasUsed: want: %v have: %v", h.BlobGasUsed, h2.BlobGasUsed)
307+
}
308+
if !reflect.DeepEqual(h.ExcessBlobGas, h2.ExcessBlobGas) {
309+
return fmt.Errorf("excessBlobGas: want: %v have: %v", h.ExcessBlobGas, h2.ExcessBlobGas)
310+
}
311+
if !reflect.DeepEqual(h.ParentBeaconBlockRoot, h2.ParentBeaconRoot) {
312+
return fmt.Errorf("parentBeaconBlockRoot: want: %v have: %v", h.ParentBeaconBlockRoot, h2.ParentBeaconRoot)
313+
}
298314
return nil
299315
}
300316

tests/gen_btheader.go

Lines changed: 54 additions & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)