* core/vm/runtime/tests: add more benchmarks * core/vm: initial work on improving alloc count for calls to precompiles name old time/op new time/op delta SimpleLoop/identity-precompile-10M-6 117ms ±75% 43ms ± 1% -63.09% (p=0.008 n=5+5) SimpleLoop/loop-10M-6 79.6ms ± 4% 70.5ms ± 1% -11.42% (p=0.008 n=5+5) name old alloc/op new alloc/op delta SimpleLoop/identity-precompile-10M-6 24.4MB ± 0% 4.9MB ± 0% -79.94% (p=0.008 n=5+5) SimpleLoop/loop-10M-6 13.2kB ± 0% 13.2kB ± 0% ~ (p=0.357 n=5+5) name old allocs/op new allocs/op delta SimpleLoop/identity-precompile-10M-6 382k ± 0% 153k ± 0% -59.99% (p=0.000 n=5+4) SimpleLoop/loop-10M-6 40.0 ± 0% 40.0 ± 0% ~ (all equal) * core/vm: don't allocate big.int for touch name old time/op new time/op delta SimpleLoop/identity-precompile-10M-6 43.3ms ± 1% 42.4ms ± 7% ~ (p=0.151 n=5+5) SimpleLoop/loop-10M-6 70.5ms ± 1% 76.7ms ± 1% +8.67% (p=0.008 n=5+5) name old alloc/op new alloc/op delta SimpleLoop/identity-precompile-10M-6 4.90MB ± 0% 2.46MB ± 0% -49.83% (p=0.008 n=5+5) SimpleLoop/loop-10M-6 13.2kB ± 0% 13.2kB ± 1% ~ (p=0.571 n=5+5) name old allocs/op new allocs/op delta SimpleLoop/identity-precompile-10M-6 153k ± 0% 76k ± 0% -49.98% (p=0.029 n=4+4) SimpleLoop/loop-10M-6 40.0 ± 0% 40.0 ± 0% ~ (all equal) * core/vm: reduce allocs in staticcall name old time/op new time/op delta SimpleLoop/identity-precompile-10M-6 42.4ms ± 7% 37.5ms ± 6% -11.68% (p=0.008 n=5+5) SimpleLoop/loop-10M-6 76.7ms ± 1% 69.1ms ± 1% -9.82% (p=0.008 n=5+5) name old alloc/op new alloc/op delta SimpleLoop/identity-precompile-10M-6 2.46MB ± 0% 0.02MB ± 0% -99.35% (p=0.008 n=5+5) SimpleLoop/loop-10M-6 13.2kB ± 1% 13.2kB ± 0% ~ (p=0.143 n=5+5) name old allocs/op new allocs/op delta SimpleLoop/identity-precompile-10M-6 76.4k ± 0% 0.1k ± 0% ~ (p=0.079 n=4+5) SimpleLoop/loop-10M-6 40.0 ± 0% 40.0 ± 0% ~ (all equal) * trie: better use of hasher keccakState * core/state/statedb: reduce allocations in getDeletedStateObject * core/vm: reduce allocations in all call derivates * core/vm: reduce allocations in call variants - Make returnstack `uint32` - Use a `sync.Pool` of `stack`s * core/vm: fix tests * core/vm: goimports * core/vm: tracer fix + staticcall gas fix * core/vm: add back snapshot to staticcall * core/vm: review concerns + make returnstack pooled + enable returndata in traces * core/vm: fix some test tracer method signatures * core/vm: run gencodec, minor comment polish Co-authored-by: Péter Szilágyi <peterke@gmail.com>
		
			
				
	
	
		
			363 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			363 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2017 The go-ethereum Authors
 | |
| // This file is part of the go-ethereum library.
 | |
| //
 | |
| // The go-ethereum library is free software: you can redistribute it and/or modify
 | |
| // it 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 go-ethereum library is distributed in the hope that it 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 <http://www.gnu.org/licenses/>.
 | |
| 
 | |
| package vm
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"encoding/json"
 | |
| 	"fmt"
 | |
| 	"io/ioutil"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/ethereum/go-ethereum/common"
 | |
| )
 | |
| 
 | |
| // precompiledTest defines the input/output pairs for precompiled contract tests.
 | |
| type precompiledTest struct {
 | |
| 	Input, Expected string
 | |
| 	Name            string
 | |
| 	NoBenchmark     bool // Benchmark primarily the worst-cases
 | |
| }
 | |
| 
 | |
| // precompiledFailureTest defines the input/error pairs for precompiled
 | |
| // contract failure tests.
 | |
| type precompiledFailureTest struct {
 | |
| 	Input         string
 | |
| 	ExpectedError string
 | |
| 	Name          string
 | |
| }
 | |
| 
 | |
| var allPrecompiles = PrecompiledContractsYoloV1
 | |
| 
 | |
| // EIP-152 test vectors
 | |
| var blake2FMalformedInputTests = []precompiledFailureTest{
 | |
| 	{
 | |
| 		Input:         "",
 | |
| 		ExpectedError: errBlake2FInvalidInputLength.Error(),
 | |
| 		Name:          "vector 0: empty input",
 | |
| 	},
 | |
| 	{
 | |
| 		Input:         "00000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
 | |
| 		ExpectedError: errBlake2FInvalidInputLength.Error(),
 | |
| 		Name:          "vector 1: less than 213 bytes input",
 | |
| 	},
 | |
| 	{
 | |
| 		Input:         "000000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
 | |
| 		ExpectedError: errBlake2FInvalidInputLength.Error(),
 | |
| 		Name:          "vector 2: more than 213 bytes input",
 | |
| 	},
 | |
| 	{
 | |
| 		Input:         "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002",
 | |
| 		ExpectedError: errBlake2FInvalidFinalFlag.Error(),
 | |
| 		Name:          "vector 3: malformed final block indicator flag",
 | |
| 	},
 | |
| }
 | |
| 
 | |
| func testPrecompiled(addr string, test precompiledTest, t *testing.T) {
 | |
| 	p := allPrecompiles[common.HexToAddress(addr)]
 | |
| 	in := common.Hex2Bytes(test.Input)
 | |
| 	gas := p.RequiredGas(in)
 | |
| 	t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) {
 | |
| 		if res, _, err := RunPrecompiledContract(p, in, gas); err != nil {
 | |
| 			t.Error(err)
 | |
| 		} else if common.Bytes2Hex(res) != test.Expected {
 | |
| 			t.Errorf("Expected %v, got %v", test.Expected, common.Bytes2Hex(res))
 | |
| 		}
 | |
| 		// Verify that the precompile did not touch the input buffer
 | |
| 		exp := common.Hex2Bytes(test.Input)
 | |
| 		if !bytes.Equal(in, exp) {
 | |
| 			t.Errorf("Precompiled %v modified input data", addr)
 | |
| 		}
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func testPrecompiledOOG(addr string, test precompiledTest, t *testing.T) {
 | |
| 	p := allPrecompiles[common.HexToAddress(addr)]
 | |
| 	in := common.Hex2Bytes(test.Input)
 | |
| 	gas := p.RequiredGas(in) - 1
 | |
| 
 | |
| 	t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) {
 | |
| 		_, _, err := RunPrecompiledContract(p, in, gas)
 | |
| 		if err.Error() != "out of gas" {
 | |
| 			t.Errorf("Expected error [out of gas], got [%v]", err)
 | |
| 		}
 | |
| 		// Verify that the precompile did not touch the input buffer
 | |
| 		exp := common.Hex2Bytes(test.Input)
 | |
| 		if !bytes.Equal(in, exp) {
 | |
| 			t.Errorf("Precompiled %v modified input data", addr)
 | |
| 		}
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func testPrecompiledFailure(addr string, test precompiledFailureTest, t *testing.T) {
 | |
| 	p := allPrecompiles[common.HexToAddress(addr)]
 | |
| 	in := common.Hex2Bytes(test.Input)
 | |
| 	gas := p.RequiredGas(in)
 | |
| 	t.Run(test.Name, func(t *testing.T) {
 | |
| 		_, _, err := RunPrecompiledContract(p, in, gas)
 | |
| 		if err.Error() != test.ExpectedError {
 | |
| 			t.Errorf("Expected error [%v], got [%v]", test.ExpectedError, err)
 | |
| 		}
 | |
| 		// Verify that the precompile did not touch the input buffer
 | |
| 		exp := common.Hex2Bytes(test.Input)
 | |
| 		if !bytes.Equal(in, exp) {
 | |
| 			t.Errorf("Precompiled %v modified input data", addr)
 | |
| 		}
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) {
 | |
| 	if test.NoBenchmark {
 | |
| 		return
 | |
| 	}
 | |
| 	p := allPrecompiles[common.HexToAddress(addr)]
 | |
| 	in := common.Hex2Bytes(test.Input)
 | |
| 	reqGas := p.RequiredGas(in)
 | |
| 
 | |
| 	var (
 | |
| 		res  []byte
 | |
| 		err  error
 | |
| 		data = make([]byte, len(in))
 | |
| 	)
 | |
| 
 | |
| 	bench.Run(fmt.Sprintf("%s-Gas=%d", test.Name, reqGas), func(bench *testing.B) {
 | |
| 		bench.ReportAllocs()
 | |
| 		start := time.Now().Nanosecond()
 | |
| 		bench.ResetTimer()
 | |
| 		for i := 0; i < bench.N; i++ {
 | |
| 			copy(data, in)
 | |
| 			res, _, err = RunPrecompiledContract(p, data, reqGas)
 | |
| 		}
 | |
| 		bench.StopTimer()
 | |
| 		elapsed := float64(time.Now().Nanosecond() - start)
 | |
| 		if elapsed < 1 {
 | |
| 			elapsed = 1
 | |
| 		}
 | |
| 		gasUsed := reqGas * uint64(bench.N)
 | |
| 		bench.ReportMetric(float64(reqGas), "gas/op")
 | |
| 		bench.ReportMetric(float64(gasUsed*1000)/elapsed, "mgas/s")
 | |
| 		//Check if it is correct
 | |
| 		if err != nil {
 | |
| 			bench.Error(err)
 | |
| 			return
 | |
| 		}
 | |
| 		if common.Bytes2Hex(res) != test.Expected {
 | |
| 			bench.Error(fmt.Sprintf("Expected %v, got %v", test.Expected, common.Bytes2Hex(res)))
 | |
| 			return
 | |
| 		}
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // Benchmarks the sample inputs from the ECRECOVER precompile.
 | |
| func BenchmarkPrecompiledEcrecover(bench *testing.B) {
 | |
| 	t := precompiledTest{
 | |
| 		Input:    "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",
 | |
| 		Expected: "000000000000000000000000ceaccac640adf55b2028469bd36ba501f28b699d",
 | |
| 		Name:     "",
 | |
| 	}
 | |
| 	benchmarkPrecompiled("01", t, bench)
 | |
| }
 | |
| 
 | |
| // Benchmarks the sample inputs from the SHA256 precompile.
 | |
| func BenchmarkPrecompiledSha256(bench *testing.B) {
 | |
| 	t := precompiledTest{
 | |
| 		Input:    "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",
 | |
| 		Expected: "811c7003375852fabd0d362e40e68607a12bdabae61a7d068fe5fdd1dbbf2a5d",
 | |
| 		Name:     "128",
 | |
| 	}
 | |
| 	benchmarkPrecompiled("02", t, bench)
 | |
| }
 | |
| 
 | |
| // Benchmarks the sample inputs from the RIPEMD precompile.
 | |
| func BenchmarkPrecompiledRipeMD(bench *testing.B) {
 | |
| 	t := precompiledTest{
 | |
| 		Input:    "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",
 | |
| 		Expected: "0000000000000000000000009215b8d9882ff46f0dfde6684d78e831467f65e6",
 | |
| 		Name:     "128",
 | |
| 	}
 | |
| 	benchmarkPrecompiled("03", t, bench)
 | |
| }
 | |
| 
 | |
| // Benchmarks the sample inputs from the identiy precompile.
 | |
| func BenchmarkPrecompiledIdentity(bench *testing.B) {
 | |
| 	t := precompiledTest{
 | |
| 		Input:    "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",
 | |
| 		Expected: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",
 | |
| 		Name:     "128",
 | |
| 	}
 | |
| 	benchmarkPrecompiled("04", t, bench)
 | |
| }
 | |
| 
 | |
| // Tests the sample inputs from the ModExp EIP 198.
 | |
| func TestPrecompiledModExp(t *testing.T)      { testJson("modexp", "05", t) }
 | |
| func BenchmarkPrecompiledModExp(b *testing.B) { benchJson("modexp", "05", b) }
 | |
| 
 | |
| // Tests the sample inputs from the elliptic curve addition EIP 213.
 | |
| func TestPrecompiledBn256Add(t *testing.T)      { testJson("bn256Add", "06", t) }
 | |
| func BenchmarkPrecompiledBn256Add(b *testing.B) { benchJson("bn256Add", "06", b) }
 | |
| 
 | |
| // Tests OOG
 | |
| func TestPrecompiledModExpOOG(t *testing.T) {
 | |
| 	modexpTests, err := loadJson("modexp")
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	for _, test := range modexpTests {
 | |
| 		testPrecompiledOOG("05", test, t)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Tests the sample inputs from the elliptic curve scalar multiplication EIP 213.
 | |
| func TestPrecompiledBn256ScalarMul(t *testing.T)      { testJson("bn256ScalarMul", "07", t) }
 | |
| func BenchmarkPrecompiledBn256ScalarMul(b *testing.B) { benchJson("bn256ScalarMul", "07", b) }
 | |
| 
 | |
| // Tests the sample inputs from the elliptic curve pairing check EIP 197.
 | |
| func TestPrecompiledBn256Pairing(t *testing.T)      { testJson("bn256Pairing", "08", t) }
 | |
| func BenchmarkPrecompiledBn256Pairing(b *testing.B) { benchJson("bn256Pairing", "08", b) }
 | |
| 
 | |
| func TestPrecompiledBlake2F(t *testing.T)      { testJson("blake2F", "09", t) }
 | |
| func BenchmarkPrecompiledBlake2F(b *testing.B) { benchJson("blake2F", "09", b) }
 | |
| 
 | |
| func TestPrecompileBlake2FMalformedInput(t *testing.T) {
 | |
| 	for _, test := range blake2FMalformedInputTests {
 | |
| 		testPrecompiledFailure("09", test, t)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestPrecompiledEcrecover(t *testing.T) { testJson("ecRecover", "01", t) }
 | |
| 
 | |
| func testJson(name, addr string, t *testing.T) {
 | |
| 	tests, err := loadJson(name)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	for _, test := range tests {
 | |
| 		testPrecompiled(addr, test, t)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func testJsonFail(name, addr string, t *testing.T) {
 | |
| 	tests, err := loadJsonFail(name)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	for _, test := range tests {
 | |
| 		testPrecompiledFailure(addr, test, t)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func benchJson(name, addr string, b *testing.B) {
 | |
| 	tests, err := loadJson(name)
 | |
| 	if err != nil {
 | |
| 		b.Fatal(err)
 | |
| 	}
 | |
| 	for _, test := range tests {
 | |
| 		benchmarkPrecompiled(addr, test, b)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestPrecompiledBLS12381G1Add(t *testing.T)      { testJson("blsG1Add", "0a", t) }
 | |
| func TestPrecompiledBLS12381G1Mul(t *testing.T)      { testJson("blsG1Mul", "0b", t) }
 | |
| func TestPrecompiledBLS12381G1MultiExp(t *testing.T) { testJson("blsG1MultiExp", "0c", t) }
 | |
| func TestPrecompiledBLS12381G2Add(t *testing.T)      { testJson("blsG2Add", "0d", t) }
 | |
| func TestPrecompiledBLS12381G2Mul(t *testing.T)      { testJson("blsG2Mul", "0e", t) }
 | |
| func TestPrecompiledBLS12381G2MultiExp(t *testing.T) { testJson("blsG2MultiExp", "0f", t) }
 | |
| func TestPrecompiledBLS12381Pairing(t *testing.T)    { testJson("blsPairing", "10", t) }
 | |
| func TestPrecompiledBLS12381MapG1(t *testing.T)      { testJson("blsMapG1", "11", t) }
 | |
| func TestPrecompiledBLS12381MapG2(t *testing.T)      { testJson("blsMapG2", "12", t) }
 | |
| 
 | |
| func BenchmarkPrecompiledBLS12381G1Add(b *testing.B)      { benchJson("blsG1Add", "0a", b) }
 | |
| func BenchmarkPrecompiledBLS12381G1Mul(b *testing.B)      { benchJson("blsG1Mul", "0b", b) }
 | |
| func BenchmarkPrecompiledBLS12381G1MultiExp(b *testing.B) { benchJson("blsG1MultiExp", "0c", b) }
 | |
| func BenchmarkPrecompiledBLS12381G2Add(b *testing.B)      { benchJson("blsG2Add", "0d", b) }
 | |
| func BenchmarkPrecompiledBLS12381G2Mul(b *testing.B)      { benchJson("blsG2Mul", "0e", b) }
 | |
| func BenchmarkPrecompiledBLS12381G2MultiExp(b *testing.B) { benchJson("blsG2MultiExp", "0f", b) }
 | |
| func BenchmarkPrecompiledBLS12381Pairing(b *testing.B)    { benchJson("blsPairing", "10", b) }
 | |
| func BenchmarkPrecompiledBLS12381MapG1(b *testing.B)      { benchJson("blsMapG1", "11", b) }
 | |
| func BenchmarkPrecompiledBLS12381MapG2(b *testing.B)      { benchJson("blsMapG2", "12", b) }
 | |
| 
 | |
| // Failure tests
 | |
| func TestPrecompiledBLS12381G1AddFail(t *testing.T)      { testJsonFail("blsG1Add", "0a", t) }
 | |
| func TestPrecompiledBLS12381G1MulFail(t *testing.T)      { testJsonFail("blsG1Mul", "0b", t) }
 | |
| func TestPrecompiledBLS12381G1MultiExpFail(t *testing.T) { testJsonFail("blsG1MultiExp", "0c", t) }
 | |
| func TestPrecompiledBLS12381G2AddFail(t *testing.T)      { testJsonFail("blsG2Add", "0d", t) }
 | |
| func TestPrecompiledBLS12381G2MulFail(t *testing.T)      { testJsonFail("blsG2Mul", "0e", t) }
 | |
| func TestPrecompiledBLS12381G2MultiExpFail(t *testing.T) { testJsonFail("blsG2MultiExp", "0f", t) }
 | |
| func TestPrecompiledBLS12381PairingFail(t *testing.T)    { testJsonFail("blsPairing", "10", t) }
 | |
| func TestPrecompiledBLS12381MapG1Fail(t *testing.T)      { testJsonFail("blsMapG1", "11", t) }
 | |
| func TestPrecompiledBLS12381MapG2Fail(t *testing.T)      { testJsonFail("blsMapG2", "12", t) }
 | |
| 
 | |
| func loadJson(name string) ([]precompiledTest, error) {
 | |
| 	data, err := ioutil.ReadFile(fmt.Sprintf("testdata/precompiles/%v.json", name))
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	var testcases []precompiledTest
 | |
| 	err = json.Unmarshal(data, &testcases)
 | |
| 	return testcases, err
 | |
| }
 | |
| 
 | |
| func loadJsonFail(name string) ([]precompiledFailureTest, error) {
 | |
| 	data, err := ioutil.ReadFile(fmt.Sprintf("testdata/precompiles/fail-%v.json", name))
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	var testcases []precompiledFailureTest
 | |
| 	err = json.Unmarshal(data, &testcases)
 | |
| 	return testcases, err
 | |
| }
 | |
| 
 | |
| // BenchmarkPrecompiledBLS12381G1MultiExpWorstCase benchmarks the worst case we could find that still fits a gaslimit of 10MGas.
 | |
| func BenchmarkPrecompiledBLS12381G1MultiExpWorstCase(b *testing.B) {
 | |
| 	task := "0000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be1" +
 | |
| 		"0000000000000000000000000000000011bc8afe71676e6730702a46ef817060249cd06cd82e6981085012ff6d013aa4470ba3a2c71e13ef653e1e223d1ccfe9" +
 | |
| 		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
 | |
| 	input := task
 | |
| 	for i := 0; i < 4787; i++ {
 | |
| 		input = input + task
 | |
| 	}
 | |
| 	testcase := precompiledTest{
 | |
| 		Input:       input,
 | |
| 		Expected:    "0000000000000000000000000000000005a6310ea6f2a598023ae48819afc292b4dfcb40aabad24a0c2cb6c19769465691859eeb2a764342a810c5038d700f18000000000000000000000000000000001268ac944437d15923dc0aec00daa9250252e43e4b35ec7a19d01f0d6cd27f6e139d80dae16ba1c79cc7f57055a93ff5",
 | |
| 		Name:        "WorstCaseG1",
 | |
| 		NoBenchmark: false,
 | |
| 	}
 | |
| 	benchmarkPrecompiled("0c", testcase, b)
 | |
| }
 | |
| 
 | |
| // BenchmarkPrecompiledBLS12381G2MultiExpWorstCase benchmarks the worst case we could find that still fits a gaslimit of 10MGas.
 | |
| func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) {
 | |
| 	task := "000000000000000000000000000000000d4f09acd5f362e0a516d4c13c5e2f504d9bd49fdfb6d8b7a7ab35a02c391c8112b03270d5d9eefe9b659dd27601d18f" +
 | |
| 		"000000000000000000000000000000000fd489cb75945f3b5ebb1c0e326d59602934c8f78fe9294a8877e7aeb95de5addde0cb7ab53674df8b2cfbb036b30b99" +
 | |
| 		"00000000000000000000000000000000055dbc4eca768714e098bbe9c71cf54b40f51c26e95808ee79225a87fb6fa1415178db47f02d856fea56a752d185f86b" +
 | |
| 		"000000000000000000000000000000001239b7640f416eb6e921fe47f7501d504fadc190d9cf4e89ae2b717276739a2f4ee9f637c35e23c480df029fd8d247c7" +
 | |
| 		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
 | |
| 	input := task
 | |
| 	for i := 0; i < 1040; i++ {
 | |
| 		input = input + task
 | |
| 	}
 | |
| 
 | |
| 	testcase := precompiledTest{
 | |
| 		Input:       input,
 | |
| 		Expected:    "0000000000000000000000000000000018f5ea0c8b086095cfe23f6bb1d90d45de929292006dba8cdedd6d3203af3c6bbfd592e93ecb2b2c81004961fdcbb46c00000000000000000000000000000000076873199175664f1b6493a43c02234f49dc66f077d3007823e0343ad92e30bd7dc209013435ca9f197aca44d88e9dac000000000000000000000000000000000e6f07f4b23b511eac1e2682a0fc224c15d80e122a3e222d00a41fab15eba645a700b9ae84f331ae4ed873678e2e6c9b000000000000000000000000000000000bcb4849e460612aaed79617255fd30c03f51cf03d2ed4163ca810c13e1954b1e8663157b957a601829bb272a4e6c7b8",
 | |
| 		Name:        "WorstCaseG2",
 | |
| 		NoBenchmark: false,
 | |
| 	}
 | |
| 	benchmarkPrecompiled("0f", testcase, b)
 | |
| }
 |