From 72e932f6e88ee429069fad9447f1914b9edf76f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Fri, 1 Mar 2024 08:03:09 +0100 Subject: [PATCH 01/13] Add evm-benchmarks git submodule --- .gitmodules | 3 +++ tests/evm-benchmarks | 1 + 2 files changed, 4 insertions(+) create mode 160000 tests/evm-benchmarks diff --git a/.gitmodules b/.gitmodules index 083c521ccc..086c671948 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ [submodule "blade-contracts"] path = blade-contracts url = https://github.com/Ethernal-Tech/blade-contracts +[submodule "tests/evm-benchmarks"] + path = tests/evm-benchmarks + url = https://github.com/ipsilon/evm-benchmarks diff --git a/tests/evm-benchmarks b/tests/evm-benchmarks new file mode 160000 index 0000000000..d8b88f4046 --- /dev/null +++ b/tests/evm-benchmarks @@ -0,0 +1 @@ +Subproject commit d8b88f4046a87d6b902378cef752591f95427b43 From 711324943d1e3af340f04a8b2862e1c310b5055e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Sun, 3 Mar 2024 10:16:56 +0100 Subject: [PATCH 02/13] Benchmark tests support --- tests/evm_benchmark.go | 57 ++++++++++++++++++++++++++++++++++++++++ tests/state_test.go | 10 +------ tests/state_test_util.go | 12 +++++++++ 3 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 tests/evm_benchmark.go diff --git a/tests/evm_benchmark.go b/tests/evm_benchmark.go new file mode 100644 index 0000000000..cab647e820 --- /dev/null +++ b/tests/evm_benchmark.go @@ -0,0 +1,57 @@ +package tests + +import ( + "encoding/json" + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +const ( + benchmarksDir = "tests/evm-benchmarks/benchmarks" +) + +func BenchmarkEVM(b *testing.B) { + folders, err := listFolders([]string{benchmarksDir}) + require.NoError(b, err) + + for _, folder := range folders { + files, err := listFiles(folder, ".json") + require.NoError(b, err) + + for _, file := range files { + name := getTestName(file) + + b.Run(name, func(b *testing.B) { + data, err := os.ReadFile(file) + require.NoError(b, err) + + var testCases map[string]testCase + if err = json.Unmarshal(data, &testCases); err != nil { + b.Fatalf("failed to unmarshal %s: %v", file, err) + } + + for _, tc := range testCases { + for fork, postState := range tc.Post { + forks, exists := Forks[fork] + if !exists { + b.Logf("%s fork is not supported, skipping test case.", fork) + continue + } + + fc := &forkConfig{name: fork, forks: forks} + + for idx, postStateEntry := range postState { + runBenchmarkTest(b, file, tc, fc, idx, postStateEntry) + } + } + } + }) + } + } +} + +func runBenchmarkTest(b *testing.B, file string, c testCase, fc *forkConfig, index int, p postEntry) { + +} diff --git a/tests/state_test.go b/tests/state_test.go index 8b32b71c49..00f4f9fb5f 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -6,8 +6,6 @@ import ( "fmt" "math/big" "os" - "path/filepath" - "strings" "testing" "time" @@ -116,8 +114,7 @@ func TestState(t *testing.T) { func runSpecificTestCase(t *testing.T, file string, c testCase, fc *forkConfig, index int, p postEntry) error { t.Helper() - testName := filepath.Base(file) - testName = strings.TrimSuffix(testName, ".json") + testName := getTestName(file) env := c.Env.ToEnv(t) forks := fc.forks @@ -231,8 +228,3 @@ func runSpecificTestCase(t *testing.T, file string, c testCase, fc *forkConfig, return nil } - -type forkConfig struct { - name string - forks *chain.Forks -} diff --git a/tests/state_test_util.go b/tests/state_test_util.go index bf105245fd..5acafbc5ba 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -689,3 +689,15 @@ func rlpHashLogs(logs []*types.Log) (res types.Hash) { func vmTestBlockHash(n uint64) types.Hash { return types.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String()))) } + +// getTestName extracts test name from the test file path +func getTestName(testFile string) string { + testName := filepath.Base(testFile) + + return strings.TrimSuffix(testName, ".json") +} + +type forkConfig struct { + name string + forks *chain.Forks +} From c138f0859f6a6a79bc83b7143edee24a2ab1d4ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Mon, 4 Mar 2024 10:25:14 +0100 Subject: [PATCH 03/13] Benchmark tests support (part 2) --- state/executor.go | 19 ++++++- tests/evm_benchmark.go | 120 ++++++++++++++++++++++++++++++++++++++- tests/state_test.go | 2 - tests/state_test_util.go | 39 ++++++------- 4 files changed, 153 insertions(+), 27 deletions(-) diff --git a/state/executor.go b/state/executor.go index 6331204d6a..54b5ace14f 100644 --- a/state/executor.go +++ b/state/executor.go @@ -649,7 +649,8 @@ func (t *Transition) apply(msg *types.Transaction) (*runtime.ExecutionResult, er // set up initial access list initialAccessList := runtime.NewAccessList() - if t.config.Berlin { // check if berlin fork is activated or not + if t.config.Berlin { + // populate access list in case Berlin fork is active initialAccessList.PrepareAccessList(msg.From(), msg.To(), t.precompiles.Addrs, msg.AccessList()) } @@ -1183,6 +1184,11 @@ func (t *Transition) GetRefund() uint64 { return t.state.GetRefund() } +// ActivePrecompiles returns addresses of precompile contracts +func (t *Transition) ActivePrecompiles() []types.Address { + return t.precompiles.Addrs +} + func TransactionGasCost(msg *types.Transaction, isHomestead, isIstanbul bool) (uint64, error) { cost := uint64(0) @@ -1354,6 +1360,17 @@ func (t *Transition) RevertToSnapshot(snapshot int) error { return nil } +// PopulateAccessList populates access list based on the provided access list +func (t *Transition) PopulateAccessList(acl types.TxAccessList) { + for _, accessInfo := range acl { + t.AddAddressToAccessList(accessInfo.Address) + + for _, storageKey := range accessInfo.StorageKeys { + t.AddSlotToAccessList(accessInfo.Address, storageKey) + } + } +} + func (t *Transition) AddSlotToAccessList(addr types.Address, slot types.Hash) { t.journal.Append(&runtime.AccessListAddSlotChange{Address: addr, Slot: slot}) t.accessList.AddSlot(addr, slot) diff --git a/tests/evm_benchmark.go b/tests/evm_benchmark.go index cab647e820..71daa61f2f 100644 --- a/tests/evm_benchmark.go +++ b/tests/evm_benchmark.go @@ -2,14 +2,24 @@ package tests import ( "encoding/json" + "fmt" + "math/big" "os" "testing" + "time" + "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/require" + + "github.com/0xPolygon/polygon-edge/chain" + "github.com/0xPolygon/polygon-edge/crypto" + "github.com/0xPolygon/polygon-edge/state" + "github.com/0xPolygon/polygon-edge/types" ) const ( benchmarksDir = "tests/evm-benchmarks/benchmarks" + chainID = 10 ) func BenchmarkEVM(b *testing.B) { @@ -43,7 +53,8 @@ func BenchmarkEVM(b *testing.B) { fc := &forkConfig{name: fork, forks: forks} for idx, postStateEntry := range postState { - runBenchmarkTest(b, file, tc, fc, idx, postStateEntry) + err := runBenchmarkTest(b, tc, fc, postStateEntry) + require.NoError(b, err, fmt.Sprintf("test %s (case#%d) execution failed", getTestName(file), idx)) } } } @@ -52,6 +63,111 @@ func BenchmarkEVM(b *testing.B) { } } -func runBenchmarkTest(b *testing.B, file string, c testCase, fc *forkConfig, index int, p postEntry) { +func runBenchmarkTest(b *testing.B, c testCase, fc *forkConfig, p postEntry) error { + env := c.Env.ToEnv(b) + forks := fc.forks + + var baseFee *big.Int + + if forks.IsActive(chain.London, 0) { + if c.Env.BaseFee != "" { + baseFee = stringToBigIntT(b, c.Env.BaseFee) + } else { + // Retesteth uses `10` for genesis baseFee. Therefore, it defaults to + // parent - 2 : 0xa as the basefee for 'this' context. + baseFee = big.NewInt(testGenesisBaseFee) + } + } + + msg, err := c.Transaction.At(p.Indexes, baseFee) + if err != nil { + return err + } + + s, _, parentRoot, err := buildState(c.Pre) + if err != nil { + return err + } + + currentForks := forks.At(uint64(env.Number)) + + // try to recover tx with current signer + if len(p.TxBytes) != 0 { + tx := &types.Transaction{} + err := tx.UnmarshalRLP(p.TxBytes) + if err != nil { + return err + } + + signer := crypto.NewSigner(currentForks, chainID) + + _, err = signer.Sender(tx) + if err != nil { + return err + } + } + + executor := state.NewExecutor(&chain.Params{ + Forks: forks, + ChainID: chainID, + BurnContract: map[uint64]types.Address{ + 0: types.ZeroAddress, + }, + }, s, hclog.NewNullLogger()) + + executor.GetHash = func(*types.Header) func(i uint64) types.Hash { + return vmTestBlockHash + } + + transition, err := executor.BeginTxn(parentRoot, c.Env.ToHeader(b), env.Coinbase) + if err != nil { + return err + } + + var ( + gasUsed uint64 + elapsed uint64 + refund uint64 + ) + + b.ResetTimer() + for n := 0; n < b.N; n++ { + snapshotID := transition.Snapshot() + if currentForks.Berlin { + transition.PopulateAccessList(msg.AccessList()) + transition.AddAddressToAccessList(msg.From()) + if msg.To() != nil { + transition.AddAddressToAccessList(*msg.To()) + } + } + + b.StartTimer() + start := time.Now() + + // execute the message + result := transition.Call2(msg.From(), *msg.To(), msg.Input(), msg.Value(), msg.Gas()) + if result.Err != nil { + return result.Err + } + + b.StopTimer() + elapsed += uint64(time.Since(start)) + refund += transition.GetRefund() + gasUsed += msg.Gas() - result.GasLeft + + err = transition.RevertToSnapshot(snapshotID) + if err != nil { + return err + } + } + + if elapsed < 1 { + elapsed = 1 + } + + // Keep it as uint64, multiply 100 to get two digit float later + mgasps := (100 * 1000 * (gasUsed - refund)) / elapsed + b.ReportMetric(float64(mgasps)/100, "mgas/s") + return nil } diff --git a/tests/state_test.go b/tests/state_test.go index 00f4f9fb5f..e4fe770177 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -23,8 +23,6 @@ import ( const ( stateTestsDir = "tests/GeneralStateTests" - - testGenesisBaseFee = 0xa ) var ( diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 5acafbc5ba..ef7dc99e1e 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -11,6 +11,7 @@ import ( "strings" "testing" + "github.com/stretchr/testify/require" "github.com/umbracle/fastrlp" "github.com/0xPolygon/polygon-edge/chain" @@ -24,6 +25,10 @@ import ( "github.com/0xPolygon/polygon-edge/types" ) +const ( + testGenesisBaseFee = 0xa +) + type testCase struct { Env *env `json:"env"` Pre map[types.Address]*chain.GenesisAccount `json:"pre"` @@ -57,7 +62,7 @@ type env struct { Timestamp string `json:"currentTimestamp"` } -func (e *env) ToHeader(t *testing.T) *types.Header { +func (e *env) ToHeader(t testing.TB) *types.Header { t.Helper() baseFee := uint64(0) @@ -75,7 +80,7 @@ func (e *env) ToHeader(t *testing.T) *types.Header { } } -func (e *env) ToEnv(t *testing.T) runtime.TxContext { +func (e *env) ToEnv(t testing.TB) runtime.TxContext { t.Helper() baseFee := new(big.Int) @@ -129,35 +134,29 @@ func stringToBigInt(str string) (*big.Int, error) { return n, nil } -func stringToBigIntT(t *testing.T, str string) *big.Int { +func stringToBigIntT(t testing.TB, str string) *big.Int { t.Helper() number, err := stringToBigInt(str) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return number } -func stringToAddressT(t *testing.T, str string) types.Address { +func stringToAddressT(t testing.TB, str string) types.Address { t.Helper() address, err := stringToAddress(str) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return address } -func stringToHashT(t *testing.T, str string) types.Hash { +func stringToHashT(t testing.TB, str string) types.Hash { t.Helper() address, err := stringToHash(str) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return address } @@ -171,24 +170,20 @@ func stringToUint64(str string) (uint64, error) { return n.Uint64(), nil } -func stringToUint64T(t *testing.T, str string) uint64 { +func stringToUint64T(t testing.TB, str string) uint64 { t.Helper() n, err := stringToUint64(str) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return n } -func stringToInt64T(t *testing.T, str string) int64 { +func stringToInt64T(t testing.TB, str string) int64 { t.Helper() n, err := stringToUint64(str) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return int64(n) } From d379f1a592f3a36e58bcfb34d937fec2fde46057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Mon, 4 Mar 2024 12:36:50 +0100 Subject: [PATCH 04/13] Rename and fix tests path --- tests/{evm_benchmark.go => evm_benchmark_test.go} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/{evm_benchmark.go => evm_benchmark_test.go} (98%) diff --git a/tests/evm_benchmark.go b/tests/evm_benchmark_test.go similarity index 98% rename from tests/evm_benchmark.go rename to tests/evm_benchmark_test.go index 71daa61f2f..d7540fc9db 100644 --- a/tests/evm_benchmark.go +++ b/tests/evm_benchmark_test.go @@ -18,7 +18,7 @@ import ( ) const ( - benchmarksDir = "tests/evm-benchmarks/benchmarks" + benchmarksDir = "evm-benchmarks/benchmarks" chainID = 10 ) From 4fd703255e311e2e93ced9ad3586a0bf113145a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Mon, 4 Mar 2024 13:13:14 +0100 Subject: [PATCH 05/13] WIP (introduce make benchmark-test) --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9a8c5de0af..4ae9219153 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,11 @@ generate-bsd-licenses: check-git .PHONY: unit-test unit-test: check-go - go test -race -shuffle=on -coverprofile coverage.out -timeout 20m `go list ./... | grep -v e2e` + go test -race -shuffle=on -coverprofile coverage.out -v -timeout 20m `go list ./... | grep -v e2e` + +.PHONY: benchmark-test +benchmark-test: check-go + go test -v -run=^$ -bench=^Benchmark -timeout 20m `go list ./... | grep -v e2e` .PHONY: fuzz-test fuzz-test: check-go From 292f40d5ac74dc8ac47a4cf6049d09c309157b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Mon, 4 Mar 2024 14:49:33 +0100 Subject: [PATCH 06/13] Benchmark tests GH workflow --- .github/workflows/benchmark-test.yml | 32 ++++++++++++++++++++++ .github/workflows/ci.yml | 19 +++++++++++++ .github/workflows/nightly.yml | 2 ++ .github/workflows/notification-nightly.yml | 10 +++++-- 4 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/benchmark-test.yml diff --git a/.github/workflows/benchmark-test.yml b/.github/workflows/benchmark-test.yml new file mode 100644 index 0000000000..7187054b88 --- /dev/null +++ b/.github/workflows/benchmark-test.yml @@ -0,0 +1,32 @@ +--- +name: Benchmark Tests +on: # yamllint disable-line rule:truthy + workflow_call: + outputs: + workflow_output: + description: "Benchmark Tests output" + value: ${{ jobs.benchmark_test.outputs.test_output_failure }} + +jobs: + benchmark_test: + name: Run Benchmark Tests + runs-on: ubuntu-latest + outputs: + test_output_failure: ${{ steps.run_tests_failure.outputs.test_output }} + steps: + - name: Checkout Code + uses: actions/checkout@v4.1.1 + with: + submodules: recursive + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Setup Go + uses: actions/setup-go@v5.0.0 + with: + go-version: 1.20.x + - name: Run Go Test + run: make benchmark-test + - name: Run Go Test Failed + if: failure() + id: run_tests_failure + run: echo "test_output=false" >> $GITHUB_OUTPUT + \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6df137d078..152bbb7199 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,6 +36,10 @@ on: # yamllint disable-line rule:truthy description: Fuzz Tests type: boolean default: true + benchmark-test: + description: Benchmark Tests + type: boolean + default: true workflow_call: inputs: build-blade: @@ -65,6 +69,10 @@ on: # yamllint disable-line rule:truthy description: Fuzz Tests type: boolean required: true + benchmark-test: + description: Benchmark Tests + type: boolean + default: true outputs: build-blade: description: Build Blade output @@ -87,6 +95,9 @@ on: # yamllint disable-line rule:truthy fuzz-test: description: Fuzz Tests output value: ${{ jobs.fuzz-test.outputs.workflow_output }} + benchmark-test: + description: Benchmark Tests output + value: ${{ jobs.benchmark-test.outputs.workflow_output }} jobs: build-blade: @@ -144,3 +155,11 @@ jobs: inputs.fuzz-test || github.event_name == 'pull_request' || (github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop')) + benchmark-test: + name: Benchmark Tests + uses: ./.github/workflows/benchmark-test.yml + needs: build-blade + if: | + inputs.benchmark-test || + github.event_name == 'pull_request' || + (github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop')) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index eac54f51d8..d4bf6a6e75 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -30,6 +30,7 @@ jobs: e2e-legacy-test: true property-polybft-test: true fuzz-test: true + benchmark-test: true deploy_network: name: Deploy Network uses: ./.github/workflows/deploy-network.yml @@ -120,6 +121,7 @@ jobs: e2e_legacy_test_output: ${{ needs.ci.outputs.e2e-legacy-test }} property_polybft_test_output: ${{ needs.ci.outputs.property-polybft-test }} fuzz_test_output: ${{ needs.ci.outputs.fuzz-test }} + benchmark_test_output: ${{ needs.ci.outputs.benchmark-test }} deploy_network_terraform_output: ${{ needs.deploy_network.outputs.terraform_output }} deploy_network_ansible_output: ${{ needs.deploy_network.outputs.ansible_output }} load_test_multiple_eoa_output: ${{ needs.load_test_multiple_eoa.outputs.load_test_output }} diff --git a/.github/workflows/notification-nightly.yml b/.github/workflows/notification-nightly.yml index df39660a01..8bdf8967be 100644 --- a/.github/workflows/notification-nightly.yml +++ b/.github/workflows/notification-nightly.yml @@ -39,6 +39,10 @@ on: # yamllint disable-line rule:truthy description: Fuzz Tests output type: string required: true + benchmark_test_output: + description: Benchmark Tests output + type: string + required: true deploy_network_terraform_output: description: Deploy Network - Terraform output type: string @@ -91,7 +95,7 @@ jobs: { "attachments": [ { - "color": "${{ inputs.build_blade_output == '' && inputs.lint_output == '' && inputs.unit_test_output == '' && inputs.e2e_polybft_test_output == '' && inputs.e2e_legacy_test_output == '' && inputs.property_polybft_test_output == '' && inputs.fuzz_test_output == '' && inputs.deploy_network_terraform_output == '' && inputs.deploy_network_ansible_output == '' && inputs.load_test_multiple_eoa_output == 'true' && inputs.load_test_multiple_erc20_output == 'true' && inputs.destroy_network_logs_output == '' && inputs.destroy_network_terraform_output == '' && env.green_color || env.red_color }}", + "color": "${{ inputs.build_blade_output == '' && inputs.lint_output == '' && inputs.unit_test_output == '' && inputs.e2e_polybft_test_output == '' && inputs.e2e_legacy_test_output == '' && inputs.property_polybft_test_output == '' && inputs.fuzz_test_output == '' && inputs.benchmark_test_output == '' && inputs.deploy_network_terraform_output == '' && inputs.deploy_network_ansible_output == '' && inputs.load_test_multiple_eoa_output == 'true' && inputs.load_test_multiple_erc20_output == 'true' && inputs.destroy_network_logs_output == '' && inputs.destroy_network_terraform_output == '' && env.green_color || env.red_color }}", "blocks": [ { "type": "header", @@ -152,13 +156,13 @@ jobs: ] }, { - "color": "${{ inputs.build_blade_output == '' && inputs.lint_output == '' && inputs.unit_test_output == '' && inputs.fuzz_test_output == '' && inputs.e2e_legacy_test_output == '' && inputs.e2e_polybft_test_output == '' && inputs.property_polybft_test_output == '' && env.green_color || env.red_color }}", + "color": "${{ inputs.build_blade_output == '' && inputs.lint_output == '' && inputs.unit_test_output == '' && inputs.fuzz_test_output == '' && inputs.benchmark_test_output == '' && inputs.e2e_legacy_test_output == '' && inputs.e2e_polybft_test_output == '' && inputs.property_polybft_test_output == '' && env.green_color || env.red_color }}", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", - "text": "*CI*\n${{ inputs.build_blade_output == '' && 'Build Blade' || '~Build Blade~' }}, ${{ inputs.lint_output == '' && 'Lint' || '~Lint~' }}, ${{ inputs.unit_test_output == '' && 'Unit Tests' || '~Unit Tests~' }},\n${{ inputs.fuzz_test_output == '' && 'Fuzz Tests' || '~Fuzz Tests~' }}, ${{ inputs.e2e_legacy_test_output == '' && 'E2E Legacy Tests' || '~E2E Legacy Tests~' }},\n${{ inputs.e2e_polybft_test_output == '' && 'E2E PolyBFT Tests' || '~E2E PolyBFT Tests~' }}, ${{ inputs.property_polybft_test_output == '' && 'Property PolyBFT Tests' || '~Property PolyBFT Tests~' }}" + "text": "*CI*\n${{ inputs.build_blade_output == '' && 'Build' || '~Build~' }}, ${{ inputs.lint_output == '' && 'Lint' || '~Lint~' }}, ${{ inputs.unit_test_output == '' && 'Unit Tests' || '~Unit Tests~' }},\n${{ inputs.fuzz_test_output == '' && 'Fuzz Tests' || '~Fuzz Tests~' }}, ${{ inputs.e2e_legacy_test_output == '' && 'E2E Legacy Tests' || '~E2E Legacy Tests~' }},\n${{ inputs.e2e_polybft_test_output == '' && 'E2E PolyBFT Tests' || '~E2E PolyBFT Tests~' }}, ${{ inputs.property_polybft_test_output == '' && 'Property PolyBFT Tests' || '~Property PolyBFT Tests~' }},\n${{ inputs.benchmark_test_output == '' && 'Benchmark Tests' || '~Benchmark Tests~' }}" } } ] From 8eff4d65ba1ae8ef4d94f14cce7dc66a47d640bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Mon, 4 Mar 2024 15:21:01 +0100 Subject: [PATCH 07/13] Fix make benchmark-test --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4ae9219153..733cf21273 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,7 @@ unit-test: check-go .PHONY: benchmark-test benchmark-test: check-go - go test -v -run=^$ -bench=^Benchmark -timeout 20m `go list ./... | grep -v e2e` + go test -bench=. -run=^$ `go list ./... | grep -v /e2e` .PHONY: fuzz-test fuzz-test: check-go From eb05482b7bc362af0827266794d05a6b9b04d53a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Mon, 4 Mar 2024 16:07:32 +0100 Subject: [PATCH 08/13] Manual trigger for the nigtly --- .github/workflows/nightly.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index d4bf6a6e75..aaa6617fd4 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,6 +1,7 @@ --- name: Nightly Build on: # yamllint disable-line rule:truthy + workflow_dispatch: schedule: # * is a special character in YAML so you have to quote this string - cron: '0 0 * * *' From 1199b7f5d0521dfda3323fda279633f1f0090772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Mon, 4 Mar 2024 17:04:55 +0100 Subject: [PATCH 09/13] Indentation fixes --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 152bbb7199..71d06339fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,9 +37,9 @@ on: # yamllint disable-line rule:truthy type: boolean default: true benchmark-test: - description: Benchmark Tests - type: boolean - default: true + description: Benchmark Tests + type: boolean + default: true workflow_call: inputs: build-blade: @@ -70,9 +70,9 @@ on: # yamllint disable-line rule:truthy type: boolean required: true benchmark-test: - description: Benchmark Tests - type: boolean - default: true + description: Benchmark Tests + type: boolean + default: true outputs: build-blade: description: Build Blade output From 9ce9de8acf163a012d2171e600ee2afcc3708b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Tue, 5 Mar 2024 08:38:59 +0100 Subject: [PATCH 10/13] Remove v flag --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 733cf21273..d4276c28aa 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ generate-bsd-licenses: check-git .PHONY: unit-test unit-test: check-go - go test -race -shuffle=on -coverprofile coverage.out -v -timeout 20m `go list ./... | grep -v e2e` + go test -race -shuffle=on -coverprofile coverage.out -timeout 20m `go list ./... | grep -v e2e` .PHONY: benchmark-test benchmark-test: check-go From 5b101bd385611d8fad3564f60ba67bb6df0f1dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Tue, 5 Mar 2024 08:55:00 +0100 Subject: [PATCH 11/13] Remove workflow_dispatch on nightly --- .github/workflows/nightly.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index aaa6617fd4..d4bf6a6e75 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,7 +1,6 @@ --- name: Nightly Build on: # yamllint disable-line rule:truthy - workflow_dispatch: schedule: # * is a special character in YAML so you have to quote this string - cron: '0 0 * * *' From 4afb72d4f5c5fc9143047560e9acb6881e881b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Tue, 5 Mar 2024 10:29:40 +0100 Subject: [PATCH 12/13] Address comments (part 1) --- state/executor.go | 8 +++++++- tests/evm_benchmark_test.go | 8 ++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/state/executor.go b/state/executor.go index 54b5ace14f..4de1b28a5d 100644 --- a/state/executor.go +++ b/state/executor.go @@ -1361,7 +1361,13 @@ func (t *Transition) RevertToSnapshot(snapshot int) error { } // PopulateAccessList populates access list based on the provided access list -func (t *Transition) PopulateAccessList(acl types.TxAccessList) { +func (t *Transition) PopulateAccessList(from types.Address, to *types.Address, acl types.TxAccessList) { + t.AddAddressToAccessList(from) + + if to != nil { + t.AddAddressToAccessList(*to) + } + for _, accessInfo := range acl { t.AddAddressToAccessList(accessInfo.Address) diff --git a/tests/evm_benchmark_test.go b/tests/evm_benchmark_test.go index d7540fc9db..bb07e74dd8 100644 --- a/tests/evm_benchmark_test.go +++ b/tests/evm_benchmark_test.go @@ -54,7 +54,7 @@ func BenchmarkEVM(b *testing.B) { for idx, postStateEntry := range postState { err := runBenchmarkTest(b, tc, fc, postStateEntry) - require.NoError(b, err, fmt.Sprintf("test %s (case#%d) execution failed", getTestName(file), idx)) + require.NoError(b, err, fmt.Sprintf("test %s (case#%d) execution failed", name, idx)) } } } @@ -134,11 +134,7 @@ func runBenchmarkTest(b *testing.B, c testCase, fc *forkConfig, p postEntry) err for n := 0; n < b.N; n++ { snapshotID := transition.Snapshot() if currentForks.Berlin { - transition.PopulateAccessList(msg.AccessList()) - transition.AddAddressToAccessList(msg.From()) - if msg.To() != nil { - transition.AddAddressToAccessList(*msg.To()) - } + transition.PopulateAccessList(msg.From(), msg.To(), msg.AccessList()) } b.StartTimer() From fc7c0a0bde5c6aee10c7c51ce7da01ecc02165e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Tue, 5 Mar 2024 15:22:01 +0100 Subject: [PATCH 13/13] Populate access list in the transition in advance --- state/executor.go | 19 +------------------ tests/evm_benchmark_test.go | 7 ++++--- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/state/executor.go b/state/executor.go index 4de1b28a5d..4f094c0c86 100644 --- a/state/executor.go +++ b/state/executor.go @@ -1184,11 +1184,6 @@ func (t *Transition) GetRefund() uint64 { return t.state.GetRefund() } -// ActivePrecompiles returns addresses of precompile contracts -func (t *Transition) ActivePrecompiles() []types.Address { - return t.precompiles.Addrs -} - func TransactionGasCost(msg *types.Transaction, isHomestead, isIstanbul bool) (uint64, error) { cost := uint64(0) @@ -1362,19 +1357,7 @@ func (t *Transition) RevertToSnapshot(snapshot int) error { // PopulateAccessList populates access list based on the provided access list func (t *Transition) PopulateAccessList(from types.Address, to *types.Address, acl types.TxAccessList) { - t.AddAddressToAccessList(from) - - if to != nil { - t.AddAddressToAccessList(*to) - } - - for _, accessInfo := range acl { - t.AddAddressToAccessList(accessInfo.Address) - - for _, storageKey := range accessInfo.StorageKeys { - t.AddSlotToAccessList(accessInfo.Address, storageKey) - } - } + t.accessList.PrepareAccessList(from, to, t.precompiles.Addrs, acl) } func (t *Transition) AddSlotToAccessList(addr types.Address, slot types.Hash) { diff --git a/tests/evm_benchmark_test.go b/tests/evm_benchmark_test.go index bb07e74dd8..01e94bd90d 100644 --- a/tests/evm_benchmark_test.go +++ b/tests/evm_benchmark_test.go @@ -124,6 +124,10 @@ func runBenchmarkTest(b *testing.B, c testCase, fc *forkConfig, p postEntry) err return err } + if currentForks.Berlin { + transition.PopulateAccessList(msg.From(), msg.To(), msg.AccessList()) + } + var ( gasUsed uint64 elapsed uint64 @@ -133,9 +137,6 @@ func runBenchmarkTest(b *testing.B, c testCase, fc *forkConfig, p postEntry) err b.ResetTimer() for n := 0; n < b.N; n++ { snapshotID := transition.Snapshot() - if currentForks.Berlin { - transition.PopulateAccessList(msg.From(), msg.To(), msg.AccessList()) - } b.StartTimer() start := time.Now()