op-geth

diff: ignored:
+7850
-510
+9329
-196

This is an overview of the changes in op-geth, a fork of go-ethereum, part of the OP-stack.

The OP-stack architecture is modular, following the Consensus/Execution split of post-Merge Ethereum L1:

  • op-node implements most rollup-specific functionality as Consensus-Layer, similar to a L1 beacon-node.
  • op-geth implements the Execution-Layer, with minimal changes for a secure Ethereum-equivalent application environment.

Related op-stack specifications:

The Bedrock upgrade introduces a Deposit transaction-type (0x7E) to enable both users and the rollup system itself to change the L2 state based on L1 events and system rules as specified.

diff --git go-ethereum/core/types/deposit_tx.go op-geth/core/types/deposit_tx.go new file mode 100644 index 0000000000000000000000000000000000000000..4131ee7af037275dcacd795baab4e0d55a1acb07 --- /dev/null +++ op-geth/core/types/deposit_tx.go @@ -0,0 +1,103 @@ +// Copyright 2021 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 types + +import ( + "bytes" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rlp" +) + +const DepositTxType = 0x7E + +type DepositTx struct { + // SourceHash uniquely identifies the source of the deposit + SourceHash common.Hash + // From is exposed through the types.Signer, not through TxData + From common.Address + // nil means contract creation + To *common.Address `rlp:"nil"` + // Mint is minted on L2, locked on L1, nil if no minting. + Mint *big.Int `rlp:"nil"` + // Value is transferred from L2 balance, executed after Mint (if any) + Value *big.Int + // gas limit + Gas uint64 + // Field indicating if this transaction is exempt from the L2 gas limit. + IsSystemTransaction bool + // Normal Tx data + Data []byte +} + +// copy creates a deep copy of the transaction data and initializes all fields. +func (tx *DepositTx) copy() TxData { + cpy := &DepositTx{ + SourceHash: tx.SourceHash, + From: tx.From, + To: copyAddressPtr(tx.To), + Mint: nil, + Value: new(big.Int), + Gas: tx.Gas, + IsSystemTransaction: tx.IsSystemTransaction, + Data: common.CopyBytes(tx.Data), + } + if tx.Mint != nil { + cpy.Mint = new(big.Int).Set(tx.Mint) + } + if tx.Value != nil { + cpy.Value.Set(tx.Value) + } + return cpy +} + +// accessors for innerTx. +func (tx *DepositTx) txType() byte { return DepositTxType } +func (tx *DepositTx) chainID() *big.Int { return common.Big0 } +func (tx *DepositTx) accessList() AccessList { return nil } +func (tx *DepositTx) data() []byte { return tx.Data } +func (tx *DepositTx) gas() uint64 { return tx.Gas } +func (tx *DepositTx) gasFeeCap() *big.Int { return new(big.Int) } +func (tx *DepositTx) gasTipCap() *big.Int { return new(big.Int) } +func (tx *DepositTx) gasPrice() *big.Int { return new(big.Int) } +func (tx *DepositTx) value() *big.Int { return tx.Value } +func (tx *DepositTx) nonce() uint64 { return 0 } +func (tx *DepositTx) to() *common.Address { return tx.To } +func (tx *DepositTx) isSystemTx() bool { return tx.IsSystemTransaction } + +func (tx *DepositTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { + return dst.Set(new(big.Int)) +} + +func (tx *DepositTx) effectiveNonce() *uint64 { return nil } + +func (tx *DepositTx) rawSignatureValues() (v, r, s *big.Int) { + return common.Big0, common.Big0, common.Big0 +} + +func (tx *DepositTx) setSignatureValues(chainID, v, r, s *big.Int) { + // this is a noop for deposit transactions +} + +func (tx *DepositTx) encode(b *bytes.Buffer) error { + return rlp.Encode(b, tx) +} + +func (tx *DepositTx) decode(input []byte) error { + return rlp.DecodeBytes(input, tx) +}
diff --git go-ethereum/core/types/transaction_marshalling.go op-geth/core/types/transaction_marshalling.go index 1bbb97a3ec0462deb7655c1341afaefc0d197a55..7d48bbcd5b7eb6af8af11d8276208b952922a3e1 100644 --- go-ethereum/core/types/transaction_marshalling.go +++ op-geth/core/types/transaction_marshalling.go @@ -19,11 +19,13 @@ import ( "encoding/json" "errors" + "io" "math/big"   "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/ethereum/go-ethereum/rlp" "github.com/holiman/uint256" )   @@ -48,6 +50,12 @@ V *hexutil.Big `json:"v"` R *hexutil.Big `json:"r"` S *hexutil.Big `json:"s"` YParity *hexutil.Uint64 `json:"yParity,omitempty"` + + // Deposit transaction fields + SourceHash *common.Hash `json:"sourceHash,omitempty"` + From *common.Address `json:"from,omitempty"` + Mint *hexutil.Big `json:"mint,omitempty"` + IsSystemTx *bool `json:"isSystemTx,omitempty"`   // Blob transaction sidecar encoding: Blobs []kzg4844.Blob `json:"blobs,omitempty"` @@ -170,6 +178,33 @@ enc.R = (*hexutil.Big)(itx.R.ToBig()) enc.S = (*hexutil.Big)(itx.S.ToBig()) yparity := itx.V.Uint64() enc.YParity = (*hexutil.Uint64)(&yparity) + + case *DepositTx: + enc.Gas = (*hexutil.Uint64)(&itx.Gas) + enc.Value = (*hexutil.Big)(itx.Value) + enc.Input = (*hexutil.Bytes)(&itx.Data) + enc.To = tx.To() + enc.SourceHash = &itx.SourceHash + enc.From = &itx.From + if itx.Mint != nil { + enc.Mint = (*hexutil.Big)(itx.Mint) + } + enc.IsSystemTx = &itx.IsSystemTransaction + // other fields will show up as null. + + case *depositTxWithNonce: + enc.Gas = (*hexutil.Uint64)(&itx.Gas) + enc.Value = (*hexutil.Big)(itx.Value) + enc.Input = (*hexutil.Bytes)(&itx.Data) + enc.To = tx.To() + enc.SourceHash = &itx.SourceHash + enc.From = &itx.From + if itx.Mint != nil { + enc.Mint = (*hexutil.Big)(itx.Mint) + } + enc.IsSystemTx = &itx.IsSystemTransaction + enc.Nonce = (*hexutil.Uint64)(&itx.EffectiveNonce) + // other fields will show up as null. } return json.Marshal(&enc) } @@ -507,6 +542,54 @@ return err } }   + case DepositTxType: + if dec.AccessList != nil || dec.MaxFeePerGas != nil || + dec.MaxPriorityFeePerGas != nil { + return errors.New("unexpected field(s) in deposit transaction") + } + if dec.GasPrice != nil && dec.GasPrice.ToInt().Cmp(common.Big0) != 0 { + return errors.New("deposit transaction GasPrice must be 0") + } + if (dec.V != nil && dec.V.ToInt().Cmp(common.Big0) != 0) || + (dec.R != nil && dec.R.ToInt().Cmp(common.Big0) != 0) || + (dec.S != nil && dec.S.ToInt().Cmp(common.Big0) != 0) { + return errors.New("deposit transaction signature must be 0 or unset") + } + var itx DepositTx + inner = &itx + if dec.To != nil { + itx.To = dec.To + } + if dec.Gas == nil { + return errors.New("missing required field 'gas' for txdata") + } + itx.Gas = uint64(*dec.Gas) + if dec.Value == nil { + return errors.New("missing required field 'value' in transaction") + } + itx.Value = (*big.Int)(dec.Value) + // mint may be omitted or nil if there is nothing to mint. + itx.Mint = (*big.Int)(dec.Mint) + if dec.Input == nil { + return errors.New("missing required field 'input' in transaction") + } + itx.Data = *dec.Input + if dec.From == nil { + return errors.New("missing required field 'from' in transaction") + } + itx.From = *dec.From + if dec.SourceHash == nil { + return errors.New("missing required field 'sourceHash' in transaction") + } + itx.SourceHash = *dec.SourceHash + // IsSystemTx may be omitted. Defaults to false. + if dec.IsSystemTx != nil { + itx.IsSystemTransaction = *dec.IsSystemTx + } + + if dec.Nonce != nil { + inner = &depositTxWithNonce{DepositTx: itx, EffectiveNonce: uint64(*dec.Nonce)} + } default: return ErrTxTypeNotSupported } @@ -517,3 +600,15 @@ // TODO: check hash here? return nil } + +type depositTxWithNonce struct { + DepositTx + EffectiveNonce uint64 +} + +// EncodeRLP ensures that RLP encoding this transaction excludes the nonce. Otherwise, the tx Hash would change +func (tx *depositTxWithNonce) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, tx.DepositTx) +} + +func (tx *depositTxWithNonce) effectiveNonce() *uint64 { return &tx.EffectiveNonce }
diff --git go-ethereum/core/types/transaction_signing.go op-geth/core/types/transaction_signing.go index 030fc472a00a79b39b3b9ad01a077c06db8a1b6b..bfbea8df1421cbbe7aeda4059a039b742f3bf963 100644 --- go-ethereum/core/types/transaction_signing.go +++ op-geth/core/types/transaction_signing.go @@ -40,9 +40,9 @@ // MakeSigner returns a Signer based on the given chain config and block number. func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer { var signer Signer switch { - case config.IsPrague(blockNumber, blockTime): + case config.IsPrague(blockNumber, blockTime) && !config.IsOptimism(): signer = NewPragueSigner(config.ChainID) - case config.IsCancun(blockNumber, blockTime): + case config.IsCancun(blockNumber, blockTime) && !config.IsOptimism(): signer = NewCancunSigner(config.ChainID) case config.IsLondon(blockNumber): signer = NewLondonSigner(config.ChainID) @@ -69,9 +69,9 @@ func LatestSigner(config *params.ChainConfig) Signer { var signer Signer if config.ChainID != nil { switch { - case config.PragueTime != nil: + case config.PragueTime != nil && !config.IsOptimism(): signer = NewPragueSigner(config.ChainID) - case config.CancunTime != nil: + case config.CancunTime != nil && !config.IsOptimism(): signer = NewCancunSigner(config.ChainID) case config.LondonBlock != nil: signer = NewLondonSigner(config.ChainID) @@ -330,6 +330,14 @@ return londonSigner{eip2930Signer{NewEIP155Signer(chainId)}} }   func (s londonSigner) Sender(tx *Transaction) (common.Address, error) { + if tx.Type() == DepositTxType { + switch tx.inner.(type) { + case *DepositTx: + return tx.inner.(*DepositTx).From, nil + case *depositTxWithNonce: + return tx.inner.(*depositTxWithNonce).From, nil + } + } if tx.Type() != DynamicFeeTxType { return s.eip2930Signer.Sender(tx) } @@ -349,6 +357,9 @@ return ok && x.chainId.Cmp(s.chainId) == 0 }   func (s londonSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { + if tx.Type() == DepositTxType { + return nil, nil, nil, fmt.Errorf("deposits do not have a signature") + } txdata, ok := tx.inner.(*DynamicFeeTx) if !ok { return s.eip2930Signer.SignatureValues(tx, sig) @@ -366,6 +377,9 @@ // Hash returns the hash to be signed by the sender. // It does not uniquely identify the transaction. func (s londonSigner) Hash(tx *Transaction) common.Hash { + if tx.Type() == DepositTxType { + panic("deposits cannot be signed and do not have a signing hash") + } if tx.Type() != DynamicFeeTxType { return s.eip2930Signer.Hash(tx) }

The Transaction type now exposes the deposit-transaction and L1-cost properties required for the rollup.

diff --git go-ethereum/core/types/transaction.go op-geth/core/types/transaction.go index 35dc1ea3f90be388e2700155191799311a424b52..4ff771d255f8d1cf765877de2929c130554c71fc 100644 --- go-ethereum/core/types/transaction.go +++ op-geth/core/types/transaction.go @@ -27,6 +27,7 @@ "time"   "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" )   @@ -60,6 +61,15 @@ // caches hash atomic.Pointer[common.Hash] size atomic.Uint64 from atomic.Pointer[sigCache] + + // cache of details to compute the data availability fee + rollupCostData atomic.Value + + // optional preconditions for inclusion + conditional atomic.Pointer[TransactionConditional] + + // an indicator if this transaction is rejected during block building + rejected atomic.Bool }   // NewTx creates a new transaction. @@ -86,6 +96,7 @@ gasFeeCap() *big.Int value() *big.Int nonce() uint64 to() *common.Address + isSystemTx() bool   rawSignatureValues() (v, r, s *big.Int) setSignatureValues(chainID, v, r, s *big.Int) @@ -208,6 +219,8 @@ case BlobTxType: inner = new(BlobTx) case SetCodeTxType: inner = new(SetCodeTx) + case DepositTxType: + inner = new(DepositTx) default: return nil, ErrTxTypeNotSupported } @@ -305,12 +318,62 @@ // Nonce returns the sender account nonce of the transaction. func (tx *Transaction) Nonce() uint64 { return tx.inner.nonce() }   +// EffectiveNonce returns the nonce that was actually used as part of transaction execution +// Returns nil if the effective nonce is not known +func (tx *Transaction) EffectiveNonce() *uint64 { + type txWithEffectiveNonce interface { + effectiveNonce() *uint64 + } + + if itx, ok := tx.inner.(txWithEffectiveNonce); ok { + return itx.effectiveNonce() + } + nonce := tx.inner.nonce() + return &nonce +} + // To returns the recipient address of the transaction. // For contract-creation transactions, To returns nil. func (tx *Transaction) To() *common.Address { return copyAddressPtr(tx.inner.to()) }   +// SourceHash returns the hash that uniquely identifies the source of the deposit tx, +// e.g. a user deposit event, or a L1 info deposit included in a specific L2 block height. +// Non-deposit transactions return a zeroed hash. +func (tx *Transaction) SourceHash() common.Hash { + switch tx.inner.(type) { + case *DepositTx: + return tx.inner.(*DepositTx).SourceHash + case *depositTxWithNonce: + return tx.inner.(*depositTxWithNonce).SourceHash + } + return common.Hash{} +} + +// Mint returns the ETH to mint in the deposit tx. +// This returns nil if there is nothing to mint, or if this is not a deposit tx. +func (tx *Transaction) Mint() *big.Int { + switch tx.inner.(type) { + case *DepositTx: + return tx.inner.(*DepositTx).Mint + case *depositTxWithNonce: + return tx.inner.(*depositTxWithNonce).Mint + } + return nil +} + +// IsDepositTx returns true if the transaction is a deposit tx type. +func (tx *Transaction) IsDepositTx() bool { + return tx.Type() == DepositTxType +} + +// IsSystemTx returns true for deposits that are system transactions. These transactions +// are executed in an unmetered environment & do not contribute to the block gas limit. +func (tx *Transaction) IsSystemTx() bool { + return tx.inner.isSystemTx() +} + // Cost returns (gas * gasPrice) + (blobGas * blobGasPrice) + value. func (tx *Transaction) Cost() *big.Int { total := new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas())) @@ -321,6 +384,43 @@ total.Add(total, tx.Value()) return total }   +// RollupCostData caches the information needed to efficiently compute the data availability fee +func (tx *Transaction) RollupCostData() RollupCostData { + if tx.Type() == DepositTxType { + return RollupCostData{} + } + if v := tx.rollupCostData.Load(); v != nil { + return v.(RollupCostData) + } + data, err := tx.MarshalBinary() + if err != nil { // Silent error, invalid txs will not be marshalled/unmarshalled for batch submission anyway. + log.Error("failed to encode tx for L1 cost computation", "err", err) + } + out := NewRollupCostData(data) + tx.rollupCostData.Store(out) + return out +} + +// Conditional returns the conditional attached to the transaction +func (tx *Transaction) Conditional() *TransactionConditional { + return tx.conditional.Load() +} + +// SetConditional attaches a conditional to the transaction +func (tx *Transaction) SetConditional(cond *TransactionConditional) { + tx.conditional.Store(cond) +} + +// Rejected will mark this transaction as rejected. +func (tx *Transaction) SetRejected() { + tx.rejected.Store(true) +} + +// Rejected returns the rejected status of this tx +func (tx *Transaction) Rejected() bool { + return tx.rejected.Load() +} + // RawSignatureValues returns the V, R, S signature values of the transaction. // The return values should not be modified by the caller. // The return values may be nil or zero, if the transaction is unsigned. @@ -352,6 +452,9 @@ // EffectiveGasTip returns the effective miner gasTipCap for the given base fee. // Note: if the effective gasTipCap is negative, this method returns both error // the actual negative value, _and_ ErrGasFeeCapTooLow func (tx *Transaction) EffectiveGasTip(baseFee *big.Int) (*big.Int, error) { + if tx.Type() == DepositTxType { + return new(big.Int), nil + } if baseFee == nil { return tx.GasTipCap(), nil } @@ -424,6 +527,18 @@ } return nil }   +// SetBlobTxSidecar sets the sidecar of a transaction. +// The sidecar should match the blob-tx versioned hashes, or the transaction will be invalid. +// This allows tools to easily re-attach blob sidecars to signed transactions that omit the sidecar. +func (tx *Transaction) SetBlobTxSidecar(sidecar *BlobTxSidecar) error { + blobtx, ok := tx.inner.(*BlobTx) + if !ok { + return fmt.Errorf("not a blob tx, type = %d", tx.Type()) + } + blobtx.Sidecar = sidecar + return nil +} + // BlobGasFeeCapCmp compares the blob fee cap of two transactions. func (tx *Transaction) BlobGasFeeCapCmp(other *Transaction) int { return tx.BlobGasFeeCap().Cmp(other.BlobGasFeeCap()) @@ -483,9 +598,9 @@ } return setcodetx.AuthList }   -// SetTime sets the decoding time of a transaction. This is used by tests to set -// arbitrary times and by persistent transaction pools when loading old txs from -// disk. +// SetTime sets the decoding time of a transaction. Used by the sequencer API to +// determine mempool time spent by conditional txs and by tests to set arbitrary +// times and by persistent transaction pools when loading old txs from disk. func (tx *Transaction) SetTime(t time.Time) { tx.time = t }
diff --git go-ethereum/core/types/tx_access_list.go op-geth/core/types/tx_access_list.go index 730a77b752866afb5e6ba3d7ea8f4a5af6456d00..59880b0eabb182cd889a27b58d6c449187f4701a 100644 --- go-ethereum/core/types/tx_access_list.go +++ op-geth/core/types/tx_access_list.go @@ -107,6 +107,7 @@ func (tx *AccessListTx) gasFeeCap() *big.Int { return tx.GasPrice } func (tx *AccessListTx) value() *big.Int { return tx.Value } func (tx *AccessListTx) nonce() uint64 { return tx.Nonce } func (tx *AccessListTx) to() *common.Address { return tx.To } +func (tx *AccessListTx) isSystemTx() bool { return false }   func (tx *AccessListTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { return dst.Set(tx.GasPrice)
diff --git go-ethereum/core/types/tx_blob.go op-geth/core/types/tx_blob.go index 88251ab95729f39002497a1ca62e32ff4443dc5a..7ab2d68cbdc8c0bbf7dfd92fda83f42b278df47a 100644 --- go-ethereum/core/types/tx_blob.go +++ op-geth/core/types/tx_blob.go @@ -162,6 +162,7 @@ func (tx *BlobTx) value() *big.Int { return tx.Value.ToBig() } func (tx *BlobTx) nonce() uint64 { return tx.Nonce } func (tx *BlobTx) to() *common.Address { tmp := tx.To; return &tmp } func (tx *BlobTx) blobGas() uint64 { return params.BlobTxBlobGasPerBlob * uint64(len(tx.BlobHashes)) } +func (tx *BlobTx) isSystemTx() bool { return false }   func (tx *BlobTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { if baseFee == nil {
diff --git go-ethereum/core/types/tx_dynamic_fee.go op-geth/core/types/tx_dynamic_fee.go index 981755cf7007882a6c5703e7a2d728bb25310d45..273d9452ba2b54fa605af5cc5313e1a5d462e7d5 100644 --- go-ethereum/core/types/tx_dynamic_fee.go +++ op-geth/core/types/tx_dynamic_fee.go @@ -96,6 +96,7 @@ func (tx *DynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap } func (tx *DynamicFeeTx) value() *big.Int { return tx.Value } func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce } func (tx *DynamicFeeTx) to() *common.Address { return tx.To } +func (tx *DynamicFeeTx) isSystemTx() bool { return false }   func (tx *DynamicFeeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { if baseFee == nil {
diff --git go-ethereum/core/types/tx_legacy.go op-geth/core/types/tx_legacy.go index 71025b78fc060692c1d034f84b59b4cdc8e6cf65..bcb65c39349a3a1bef78948af48a30a1e14c71ba 100644 --- go-ethereum/core/types/tx_legacy.go +++ op-geth/core/types/tx_legacy.go @@ -103,6 +103,7 @@ func (tx *LegacyTx) gasFeeCap() *big.Int { return tx.GasPrice } func (tx *LegacyTx) value() *big.Int { return tx.Value } func (tx *LegacyTx) nonce() uint64 { return tx.Nonce } func (tx *LegacyTx) to() *common.Address { return tx.To } +func (tx *LegacyTx) isSystemTx() bool { return false }   func (tx *LegacyTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { return dst.Set(tx.GasPrice)

Apply L1 cost computation, and add EVM configuration for tooling and more: - Disable bytecode size-limits (for large test/script contracts). - Prank (solidity test terminology) the EVM-call message-sender. - Override precompiles, to insert tooling precompiles and optimize precompile proving.

diff --git go-ethereum/core/vm/evm.go op-geth/core/vm/evm.go index 1e52215b7e46b425bc2d43d7f025e225f83ac9b3..c987aa61c1b10b61848e37df9ba74d455c797ab1 100644 --- go-ethereum/core/vm/evm.go +++ op-geth/core/vm/evm.go @@ -42,6 +42,10 @@ )   func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { p, ok := evm.precompiles[addr] + if evm.Config.PrecompileOverrides != nil { + override := evm.Config.PrecompileOverrides(evm.chainRules, p, addr) + return override, override != nil + } return p, ok }   @@ -55,6 +59,8 @@ // Transfer transfers ether from one account to the other Transfer TransferFunc // GetHash returns the hash corresponding to n GetHash GetHashFunc + // L1CostFunc returns the L1 cost of the rollup message, the function may be nil, or return nil + L1CostFunc types.L1CostFunc   // Block information Coinbase common.Address // Provides information for COINBASE @@ -163,6 +169,13 @@ // Interpreter returns the current interpreter func (evm *EVM) Interpreter() *EVMInterpreter { return evm.interpreter +} + +func (evm *EVM) maybeOverrideCaller(caller ContractRef) ContractRef { + if evm.Config.CallerOverride != nil { + return evm.Config.CallerOverride(caller) + } + return caller }   // Call executes the contract associated with the addr with the given input as @@ -170,6 +183,7 @@ // parameters. It also handles any necessary value transfer required and takes // the necessary steps to create accounts and reverses the state in case of an // execution error or failed value transfer. func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) { + caller = evm.maybeOverrideCaller(caller) // Capture the tracer start/end events in debug mode if evm.Config.Tracer != nil { evm.captureBegin(evm.depth, CALL, caller.Address(), addr, input, gas, value.ToBig()) @@ -252,6 +266,7 @@ // // CallCode differs from Call in the sense that it executes the given address' // code with the caller as context. func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) { + caller = evm.maybeOverrideCaller(caller) // Invoke tracer hooks that signal entering/exiting a call frame if evm.Config.Tracer != nil { evm.captureBegin(evm.depth, CALLCODE, caller.Address(), addr, input, gas, value.ToBig()) @@ -303,13 +318,14 @@ // // DelegateCall differs from CallCode in the sense that it executes the given address' // code with the caller as context and the caller is set to the caller of the caller. func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { + caller = evm.maybeOverrideCaller(caller) // Invoke tracer hooks that signal entering/exiting a call frame if evm.Config.Tracer != nil { // NOTE: caller must, at all times be a contract. It should never happen // that caller is something other than a Contract. - parent := caller.(*Contract) + parent := caller.(interface{ Value() *uint256.Int }) // DELEGATECALL inherits value from parent call - evm.captureBegin(evm.depth, DELEGATECALL, caller.Address(), addr, input, gas, parent.value.ToBig()) + evm.captureBegin(evm.depth, DELEGATECALL, caller.Address(), addr, input, gas, parent.Value().ToBig()) defer func(startGas uint64) { evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err) }(gas) @@ -348,6 +364,7 @@ // as parameters while disallowing any modifications to the state during the call. // Opcodes that attempt to perform such modifications will result in exceptions // instead of performing the modifications. func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { + caller = evm.maybeOverrideCaller(caller) // Invoke tracer hooks that signal entering/exiting a call frame if evm.Config.Tracer != nil { evm.captureBegin(evm.depth, STATICCALL, caller.Address(), addr, input, gas, nil) @@ -522,7 +539,7 @@ return ret, err }   // Check whether the max code size has been exceeded, assign err if the case. - if evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize { + if evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize && !evm.Config.NoMaxCodeSize { return ret, ErrMaxCodeSizeExceeded }   @@ -548,6 +565,7 @@ }   // Create creates a new contract using code as deployment code. func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { + caller = evm.maybeOverrideCaller(caller) contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address())) return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE) } @@ -557,6 +575,7 @@ // // The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:] // instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { + caller = evm.maybeOverrideCaller(caller) codeAndHash := &codeAndHash{code: code} contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes()) return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2)
diff --git go-ethereum/core/vm/gas_table.go op-geth/core/vm/gas_table.go index f3a9808251d5e7b1442d1643deb6c33e3b87ac7a..ed7d464dded6b9a970111a550046e06b87c361ae 100644 --- go-ethereum/core/vm/gas_table.go +++ op-geth/core/vm/gas_table.go @@ -314,7 +314,7 @@ size, overflow := stack.Back(2).Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow } - if size > params.MaxInitCodeSize { + if size > params.MaxInitCodeSize && !evm.Config.NoMaxCodeSize { return 0, fmt.Errorf("%w: size %d", ErrMaxInitCodeSizeExceeded, size) } // Since size <= params.MaxInitCodeSize, these multiplication cannot overflow @@ -333,7 +333,7 @@ size, overflow := stack.Back(2).Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow } - if size > params.MaxInitCodeSize { + if size > params.MaxInitCodeSize && !evm.Config.NoMaxCodeSize { return 0, fmt.Errorf("%w: size %d", ErrMaxInitCodeSizeExceeded, size) } // Since size <= params.MaxInitCodeSize, these multiplication cannot overflow
diff --git go-ethereum/core/vm/interpreter.go op-geth/core/vm/interpreter.go index 996ed6e56afef04992459cb374967f69e7990381..c90344da294d6eaa55794e9decbe112f9a801b5c 100644 --- go-ethereum/core/vm/interpreter.go +++ op-geth/core/vm/interpreter.go @@ -24,8 +24,13 @@ "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" ) + +// PrecompileOverrides is a function that can be used to override the default precompiled contracts +// Nil is returned when there is no precompile. The original is returned if the existing precompile should run. +type PrecompileOverrides func(rules params.Rules, original PrecompiledContract, addr common.Address) PrecompiledContract   // Config are the configuration options for the Interpreter type Config struct { @@ -35,6 +40,10 @@ EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages ExtraEips []int // Additional EIPS that are to be enabled   StatelessSelfValidation bool // Generate execution witnesses and self-check against them (testing purpose) + + PrecompileOverrides PrecompileOverrides // Precompiles can be swapped / changed / wrapped as needed + NoMaxCodeSize bool // Ignore Max code size and max init code size limits + CallerOverride func(v ContractRef) ContractRef // Swap the caller as needed, for VM prank functionality. }   // ScopeContext contains the things that are per-call, such as stack and memory,

Transactions must pay an additional L1 cost based on the amount of rollup-data-gas they consume, estimated based on gas-price-oracle information and encoded tx size.”

diff --git go-ethereum/core/evm.go op-geth/core/evm.go index 5d3c454d7c472839edd8b84c7a20a8a9a3f1fd02..e8016fbb782145ac28fdf78e02e59f0e2b9784be 100644 --- go-ethereum/core/evm.go +++ op-geth/core/evm.go @@ -25,6 +25,7 @@ "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" )   @@ -39,7 +40,7 @@ GetHeader(common.Hash, uint64) *types.Header }   // NewEVMBlockContext creates a new context for use in the EVM. -func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address) vm.BlockContext { +func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address, config *params.ChainConfig, statedb types.StateGetter) vm.BlockContext { var ( beneficiary common.Address baseFee *big.Int @@ -74,6 +75,7 @@ BaseFee: baseFee, BlobBaseFee: blobBaseFee, GasLimit: header.GasLimit, Random: random, + L1CostFunc: types.NewL1CostFunc(config, statedb), } }
diff --git go-ethereum/core/state_prefetcher.go op-geth/core/state_prefetcher.go index 805df5ef622e5bed3f1f158f006bc88417e4520c..e0d1bee344fdf48d22904ba5cf067f7dad10fa4b 100644 --- go-ethereum/core/state_prefetcher.go +++ op-geth/core/state_prefetcher.go @@ -48,7 +48,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, cfg vm.Config, interrupt *atomic.Bool) { var ( header = block.Header() gaspool = new(GasPool).AddGas(block.GasLimit()) - blockContext = NewEVMBlockContext(header, p.chain, nil) + blockContext = NewEVMBlockContext(header, p.chain, nil, p.config, statedb) evm = vm.NewEVM(blockContext, statedb, p.config, cfg) signer = types.MakeSigner(p.config, header.Number, header.Time) )
diff --git go-ethereum/core/state_processor.go op-geth/core/state_processor.go index 3eb83a673a968d0e8282829cc6e0e4d667e6432b..4fda5938a92fcbb6fe7dc6a823f611b7e57ebf63 100644 --- go-ethereum/core/state_processor.go +++ op-geth/core/state_processor.go @@ -69,17 +69,17 @@ // Mutate the block and state according to any hard-fork specs if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(statedb) } + misc.EnsureCreate2Deployer(p.config, block.Time(), statedb) var ( context vm.BlockContext signer = types.MakeSigner(p.config, header.Number, header.Time) ) - // Apply pre-execution system calls. - var tracingStateDB = vm.StateDB(statedb) + tracingStateDB := vm.StateDB(statedb) if hooks := cfg.Tracer; hooks != nil { tracingStateDB = state.NewHookedState(statedb, hooks) } - context = NewEVMBlockContext(header, p.chain, nil) + context = NewEVMBlockContext(header, p.chain, nil, p.config, statedb) evm := vm.NewEVM(context, tracingStateDB, p.config, cfg)   if beaconRoot := block.BeaconRoot(); beaconRoot != nil { @@ -118,6 +118,10 @@ // EIP-7251 ProcessConsolidationQueue(&requests, evm) }   + if p.config.IsIsthmus(block.Time()) { + requests = [][]byte{} + } + // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) p.chain.engine.Finalize(p.chain, header, tracingStateDB, block.Body())   @@ -141,6 +145,12 @@ if hooks.OnTxEnd != nil { defer func() { hooks.OnTxEnd(receipt, err) }() } } + + nonce := tx.Nonce() + if msg.IsDepositTx && evm.ChainConfig().IsOptimismRegolith(evm.Context.Time) { + nonce = statedb.GetNonce(msg.From) + } + // Apply the transaction to the current state (included in the env). result, err := ApplyMessage(evm, msg, gp) if err != nil { @@ -155,11 +165,11 @@ root = statedb.IntermediateRoot(evm.ChainConfig().IsEIP158(blockNumber)).Bytes() } *usedGas += result.UsedGas   - return MakeReceipt(evm, result, statedb, blockNumber, blockHash, tx, *usedGas, root), nil + return MakeReceipt(evm, result, statedb, blockNumber, blockHash, tx, *usedGas, root, evm.ChainConfig(), nonce), nil }   // MakeReceipt generates the receipt object for a transaction given its execution result. -func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas uint64, root []byte) *types.Receipt { +func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas uint64, root []byte, config *params.ChainConfig, nonce uint64) *types.Receipt { // Create a new receipt for the transaction, storing the intermediate root and gas used // by the tx. receipt := &types.Receipt{Type: tx.Type(), PostState: root, CumulativeGasUsed: usedGas} @@ -171,6 +181,17 @@ } receipt.TxHash = tx.Hash() receipt.GasUsed = result.UsedGas   + if tx.IsDepositTx() && config.IsOptimismRegolith(evm.Context.Time) { + // The actual nonce for deposit transactions is only recorded from Regolith onwards and + // otherwise must be nil. + receipt.DepositNonce = &nonce + // The DepositReceiptVersion for deposit transactions is only recorded from Canyon onwards + // and otherwise must be nil. + if config.IsOptimismCanyon(evm.Context.Time) { + receipt.DepositReceiptVersion = new(uint64) + *receipt.DepositReceiptVersion = types.CanyonDepositReceiptVersion + } + } if tx.Type() == types.BlobTxType { receipt.BlobGasUsed = uint64(len(tx.BlobHashes()) * params.BlobTxBlobGasPerBlob) receipt.BlobGasPrice = evm.Context.BlobBaseFee @@ -178,7 +199,7 @@ }   // If the transaction created a contract, store the creation address in the receipt. if tx.To() == nil { - receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce()) + receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, nonce) }   // Merge the tx-local access event into the "block-local" one, in order to collect @@ -201,9 +222,20 @@ // and uses the input parameters for its environment. It returns the receipt // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. func ApplyTransaction(evm *vm.EVM, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64) (*types.Receipt, error) { + return ApplyTransactionExtended(evm, gp, statedb, header, tx, usedGas, nil) +} + +type ApplyTransactionOpts struct { + PostValidation func(evm *vm.EVM, result *ExecutionResult) error +} + +func ApplyTransactionExtended(evm *vm.EVM, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, extraOpts *ApplyTransactionOpts) (*types.Receipt, error) { msg, err := TransactionToMessage(tx, types.MakeSigner(evm.ChainConfig(), header.Number, header.Time), header.BaseFee) if err != nil { return nil, err + } + if extraOpts != nil { + msg.PostValidation = extraOpts.PostValidation } // Create a new context to be used in the EVM environment return ApplyTransactionWithEVM(msg, gp, statedb, header.Number, header.Hash(), tx, usedGas, evm)
diff --git go-ethereum/core/types/rollup_cost.go op-geth/core/types/rollup_cost.go new file mode 100644 index 0000000000000000000000000000000000000000..f398c43af1e460aa4f24e7c464ddeb7d2ab6e2e5 --- /dev/null +++ op-geth/core/types/rollup_cost.go @@ -0,0 +1,485 @@ +// Copyright 2022 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 types + +import ( + "bytes" + "encoding/binary" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" +) + +const ( + // The two 4-byte Ecotone fee scalar values are packed into the same storage slot as the 8-byte + // sequence number and have the following Solidity offsets within the slot. Note that Solidity + // offsets correspond to the last byte of the value in the slot, counting backwards from the + // end of the slot. For example, The 8-byte sequence number has offset 0, and is therefore + // stored as big-endian format in bytes [24:32) of the slot. + BaseFeeScalarSlotOffset = 12 // bytes [16:20) of the slot + BlobBaseFeeScalarSlotOffset = 8 // bytes [20:24) of the slot + + // scalarSectionStart is the beginning of the scalar values segment in the slot + // array. baseFeeScalar is in the first four bytes of the segment, blobBaseFeeScalar the next + // four. + scalarSectionStart = 32 - BaseFeeScalarSlotOffset - 4 +) + +func init() { + if BlobBaseFeeScalarSlotOffset != BaseFeeScalarSlotOffset-4 { + panic("this code assumes the scalars are at adjacent positions in the scalars slot") + } +} + +var ( + // BedrockL1AttributesSelector is the function selector indicating Bedrock style L1 gas + // attributes. + BedrockL1AttributesSelector = []byte{0x01, 0x5d, 0x8e, 0xb9} + // EcotoneL1AttributesSelector is the selector indicating Ecotone style L1 gas attributes. + EcotoneL1AttributesSelector = []byte{0x44, 0x0a, 0x5e, 0x20} + + // L1BlockAddr is the address of the L1Block contract which stores the L1 gas attributes. + L1BlockAddr = common.HexToAddress("0x4200000000000000000000000000000000000015") + + L1BaseFeeSlot = common.BigToHash(big.NewInt(1)) + OverheadSlot = common.BigToHash(big.NewInt(5)) + ScalarSlot = common.BigToHash(big.NewInt(6)) + + // L1BlobBaseFeeSlot was added with the Ecotone upgrade and stores the blobBaseFee L1 gas + // attribute. + L1BlobBaseFeeSlot = common.BigToHash(big.NewInt(7)) + // L1FeeScalarsSlot as of the Ecotone upgrade stores the 32-bit basefeeScalar and + // blobBaseFeeScalar L1 gas attributes at offsets `BaseFeeScalarSlotOffset` and + // `BlobBaseFeeScalarSlotOffset` respectively. + L1FeeScalarsSlot = common.BigToHash(big.NewInt(3)) + + oneMillion = big.NewInt(1_000_000) + ecotoneDivisor = big.NewInt(1_000_000 * 16) + fjordDivisor = big.NewInt(1_000_000_000_000) + sixteen = big.NewInt(16) + + L1CostIntercept = big.NewInt(-42_585_600) + L1CostFastlzCoef = big.NewInt(836_500) + + MinTransactionSize = big.NewInt(100) + MinTransactionSizeScaled = new(big.Int).Mul(MinTransactionSize, big.NewInt(1e6)) + + emptyScalars = make([]byte, 8) +) + +// RollupCostData is a transaction structure that caches data for quickly computing the data +// availability costs for the transaction. +type RollupCostData struct { + Zeroes, Ones uint64 + FastLzSize uint64 +} + +type StateGetter interface { + GetState(common.Address, common.Hash) common.Hash +} + +// L1CostFunc is used in the state transition to determine the data availability fee charged to the +// sender of non-Deposit transactions. It returns nil if no data availability fee is charged. +type L1CostFunc func(rcd RollupCostData, blockTime uint64) *big.Int + +// l1CostFunc is an internal version of L1CostFunc that also returns the gasUsed for use in +// receipts. +type l1CostFunc func(rcd RollupCostData) (fee, gasUsed *big.Int) + +func NewRollupCostData(data []byte) (out RollupCostData) { + for _, b := range data { + if b == 0 { + out.Zeroes++ + } else { + out.Ones++ + } + } + out.FastLzSize = uint64(FlzCompressLen(data)) + return out +} + +// NewL1CostFunc returns a function used for calculating data availability fees, or nil if this is +// not an op-stack chain. +func NewL1CostFunc(config *params.ChainConfig, statedb StateGetter) L1CostFunc { + if config.Optimism == nil { + return nil + } + forBlock := ^uint64(0) + var cachedFunc l1CostFunc + selectFunc := func(blockTime uint64) l1CostFunc { + if !config.IsOptimismEcotone(blockTime) { + return newL1CostFuncBedrock(config, statedb, blockTime) + } + + // Note: the various state variables below are not initialized from the DB until this + // point to allow deposit transactions from the block to be processed first by state + // transition. This behavior is consensus critical! + l1FeeScalars := statedb.GetState(L1BlockAddr, L1FeeScalarsSlot).Bytes() + l1BlobBaseFee := statedb.GetState(L1BlockAddr, L1BlobBaseFeeSlot).Big() + l1BaseFee := statedb.GetState(L1BlockAddr, L1BaseFeeSlot).Big() + + // Edge case: the very first Ecotone block requires we use the Bedrock cost + // function. We detect this scenario by checking if the Ecotone parameters are + // unset. Note here we rely on assumption that the scalar parameters are adjacent + // in the buffer and l1BaseFeeScalar comes first. We need to check this prior to + // other forks, as the first block of Fjord and Ecotone could be the same block. + firstEcotoneBlock := l1BlobBaseFee.BitLen() == 0 && + bytes.Equal(emptyScalars, l1FeeScalars[scalarSectionStart:scalarSectionStart+8]) + if firstEcotoneBlock { + log.Info("using bedrock l1 cost func for first Ecotone block", "time", blockTime) + return newL1CostFuncBedrock(config, statedb, blockTime) + } + + l1BaseFeeScalar, l1BlobBaseFeeScalar := extractEcotoneFeeParams(l1FeeScalars) + + if config.IsOptimismFjord(blockTime) { + return NewL1CostFuncFjord( + l1BaseFee, + l1BlobBaseFee, + l1BaseFeeScalar, + l1BlobBaseFeeScalar, + ) + } else { + return newL1CostFuncEcotone(l1BaseFee, l1BlobBaseFee, l1BaseFeeScalar, l1BlobBaseFeeScalar) + } + } + + return func(rollupCostData RollupCostData, blockTime uint64) *big.Int { + if rollupCostData == (RollupCostData{}) { + return nil // Do not charge if there is no rollup cost-data (e.g. RPC call or deposit). + } + if forBlock != blockTime { + if forBlock != ^uint64(0) { + // best practice is not to re-use l1 cost funcs across different blocks, but we + // make it work just in case. + log.Info("l1 cost func re-used for different L1 block", "oldTime", forBlock, "newTime", blockTime) + } + forBlock = blockTime + cachedFunc = selectFunc(blockTime) + } + fee, _ := cachedFunc(rollupCostData) + return fee + } +} + +// newL1CostFuncBedrock returns an L1 cost function suitable for Bedrock, Regolith, and the first +// block only of the Ecotone upgrade. +func newL1CostFuncBedrock(config *params.ChainConfig, statedb StateGetter, blockTime uint64) l1CostFunc { + l1BaseFee := statedb.GetState(L1BlockAddr, L1BaseFeeSlot).Big() + overhead := statedb.GetState(L1BlockAddr, OverheadSlot).Big() + scalar := statedb.GetState(L1BlockAddr, ScalarSlot).Big() + isRegolith := config.IsRegolith(blockTime) + return newL1CostFuncBedrockHelper(l1BaseFee, overhead, scalar, isRegolith) +} + +// newL1CostFuncBedrockHelper is lower level version of newL1CostFuncBedrock that expects already +// extracted parameters +func newL1CostFuncBedrockHelper(l1BaseFee, overhead, scalar *big.Int, isRegolith bool) l1CostFunc { + return func(rollupCostData RollupCostData) (fee, gasUsed *big.Int) { + if rollupCostData == (RollupCostData{}) { + return nil, nil // Do not charge if there is no rollup cost-data (e.g. RPC call or deposit) + } + gas := rollupCostData.Zeroes * params.TxDataZeroGas + if isRegolith { + gas += rollupCostData.Ones * params.TxDataNonZeroGasEIP2028 + } else { + gas += (rollupCostData.Ones + 68) * params.TxDataNonZeroGasEIP2028 + } + gasWithOverhead := new(big.Int).SetUint64(gas) + gasWithOverhead.Add(gasWithOverhead, overhead) + l1Cost := l1CostHelper(gasWithOverhead, l1BaseFee, scalar) + return l1Cost, gasWithOverhead + } +} + +// newL1CostFuncEcotone returns an l1 cost function suitable for the Ecotone upgrade except for the +// very first block of the upgrade. +func newL1CostFuncEcotone(l1BaseFee, l1BlobBaseFee, l1BaseFeeScalar, l1BlobBaseFeeScalar *big.Int) l1CostFunc { + return func(costData RollupCostData) (fee, calldataGasUsed *big.Int) { + calldataGasUsed = bedrockCalldataGasUsed(costData) + + // Ecotone L1 cost function: + // + // (calldataGas/16)*(l1BaseFee*16*l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar)/1e6 + // + // We divide "calldataGas" by 16 to change from units of calldata gas to "estimated # of bytes when + // compressed". Known as "compressedTxSize" in the spec. + // + // Function is actually computed as follows for better precision under integer arithmetic: + // + // calldataGas*(l1BaseFee*16*l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar)/16e6 + + calldataCostPerByte := new(big.Int).Set(l1BaseFee) + calldataCostPerByte = calldataCostPerByte.Mul(calldataCostPerByte, sixteen) + calldataCostPerByte = calldataCostPerByte.Mul(calldataCostPerByte, l1BaseFeeScalar) + + blobCostPerByte := new(big.Int).Set(l1BlobBaseFee) + blobCostPerByte = blobCostPerByte.Mul(blobCostPerByte, l1BlobBaseFeeScalar) + + fee = new(big.Int).Add(calldataCostPerByte, blobCostPerByte) + fee = fee.Mul(fee, calldataGasUsed) + fee = fee.Div(fee, ecotoneDivisor) + + return fee, calldataGasUsed + } +} + +type gasParams struct { + l1BaseFee *big.Int + l1BlobBaseFee *big.Int + costFunc l1CostFunc + feeScalar *big.Float // pre-ecotone + l1BaseFeeScalar *uint32 // post-ecotone + l1BlobBaseFeeScalar *uint32 // post-ecotone +} + +// intToScaledFloat returns scalar/10e6 as a float +func intToScaledFloat(scalar *big.Int) *big.Float { + fscalar := new(big.Float).SetInt(scalar) + fdivisor := new(big.Float).SetUint64(1_000_000) // 10**6, i.e. 6 decimals + return new(big.Float).Quo(fscalar, fdivisor) +} + +// extractL1GasParams extracts the gas parameters necessary to compute gas costs from L1 block info +func extractL1GasParams(config *params.ChainConfig, time uint64, data []byte) (gasParams, error) { + // edge case: for the very first Ecotone block we still need to use the Bedrock + // function. We detect this edge case by seeing if the function selector is the old one + // If so, fall through to the pre-ecotone format + // Both Ecotone and Fjord use the same function selector + if config.IsEcotone(time) && len(data) >= 4 && !bytes.Equal(data[0:4], BedrockL1AttributesSelector) { + p, err := extractL1GasParamsPostEcotone(data) + if err != nil { + return gasParams{}, err + } + + if config.IsFjord(time) { + p.costFunc = NewL1CostFuncFjord( + p.l1BaseFee, + p.l1BlobBaseFee, + big.NewInt(int64(*p.l1BaseFeeScalar)), + big.NewInt(int64(*p.l1BlobBaseFeeScalar)), + ) + } else { + p.costFunc = newL1CostFuncEcotone( + p.l1BaseFee, + p.l1BlobBaseFee, + big.NewInt(int64(*p.l1BaseFeeScalar)), + big.NewInt(int64(*p.l1BlobBaseFeeScalar)), + ) + } + + return p, nil + } + return extractL1GasParamsPreEcotone(config, time, data) +} + +func extractL1GasParamsPreEcotone(config *params.ChainConfig, time uint64, data []byte) (gasParams, error) { + // data consists of func selector followed by 7 ABI-encoded parameters (32 bytes each) + if len(data) < 4+32*8 { + return gasParams{}, fmt.Errorf("expected at least %d L1 info bytes, got %d", 4+32*8, len(data)) + } + data = data[4:] // trim function selector + l1BaseFee := new(big.Int).SetBytes(data[32*2 : 32*3]) // arg index 2 + overhead := new(big.Int).SetBytes(data[32*6 : 32*7]) // arg index 6 + scalar := new(big.Int).SetBytes(data[32*7 : 32*8]) // arg index 7 + feeScalar := intToScaledFloat(scalar) // legacy: format fee scalar as big Float + costFunc := newL1CostFuncBedrockHelper(l1BaseFee, overhead, scalar, config.IsRegolith(time)) + return gasParams{ + l1BaseFee: l1BaseFee, + costFunc: costFunc, + feeScalar: feeScalar, + }, nil +} + +// extractL1GasParamsPostEcotone extracts the gas parameters necessary to compute gas from L1 attribute +// info calldata after the Ecotone upgrade, but not for the very first Ecotone block. +func extractL1GasParamsPostEcotone(data []byte) (gasParams, error) { + if len(data) != 164 { + return gasParams{}, fmt.Errorf("expected 164 L1 info bytes, got %d", len(data)) + } + // data layout assumed for Ecotone: + // offset type varname + // 0 <selector> + // 4 uint32 _basefeeScalar + // 8 uint32 _blobBaseFeeScalar + // 12 uint64 _sequenceNumber, + // 20 uint64 _timestamp, + // 28 uint64 _l1BlockNumber + // 36 uint256 _basefee, + // 68 uint256 _blobBaseFee, + // 100 bytes32 _hash, + // 132 bytes32 _batcherHash, + l1BaseFee := new(big.Int).SetBytes(data[36:68]) + l1BlobBaseFee := new(big.Int).SetBytes(data[68:100]) + l1BaseFeeScalar := binary.BigEndian.Uint32(data[4:8]) + l1BlobBaseFeeScalar := binary.BigEndian.Uint32(data[8:12]) + return gasParams{ + l1BaseFee: l1BaseFee, + l1BlobBaseFee: l1BlobBaseFee, + l1BaseFeeScalar: &l1BaseFeeScalar, + l1BlobBaseFeeScalar: &l1BlobBaseFeeScalar, + }, nil +} + +// L1Cost computes the the data availability fee for transactions in blocks prior to the Ecotone +// upgrade. It is used by e2e tests so must remain exported. +func L1Cost(rollupDataGas uint64, l1BaseFee, overhead, scalar *big.Int) *big.Int { + l1GasUsed := new(big.Int).SetUint64(rollupDataGas) + l1GasUsed.Add(l1GasUsed, overhead) + return l1CostHelper(l1GasUsed, l1BaseFee, scalar) +} + +func l1CostHelper(gasWithOverhead, l1BaseFee, scalar *big.Int) *big.Int { + fee := new(big.Int).Set(gasWithOverhead) + fee.Mul(fee, l1BaseFee).Mul(fee, scalar).Div(fee, oneMillion) + return fee +} + +// NewL1CostFuncFjord returns an l1 cost function suitable for the Fjord upgrade +func NewL1CostFuncFjord(l1BaseFee, l1BlobBaseFee, baseFeeScalar, blobFeeScalar *big.Int) l1CostFunc { + return func(costData RollupCostData) (fee, calldataGasUsed *big.Int) { + // Fjord L1 cost function: + //l1FeeScaled = baseFeeScalar*l1BaseFee*16 + blobFeeScalar*l1BlobBaseFee + //estimatedSize = max(minTransactionSize, intercept + fastlzCoef*fastlzSize) + //l1Cost = estimatedSize * l1FeeScaled / 1e12 + + scaledL1BaseFee := new(big.Int).Mul(baseFeeScalar, l1BaseFee) + calldataCostPerByte := new(big.Int).Mul(scaledL1BaseFee, sixteen) + blobCostPerByte := new(big.Int).Mul(blobFeeScalar, l1BlobBaseFee) + l1FeeScaled := new(big.Int).Add(calldataCostPerByte, blobCostPerByte) + estimatedSize := costData.estimatedDASizeScaled() + l1CostScaled := new(big.Int).Mul(estimatedSize, l1FeeScaled) + l1Cost := new(big.Int).Div(l1CostScaled, fjordDivisor) + + calldataGasUsed = new(big.Int).Mul(estimatedSize, new(big.Int).SetUint64(params.TxDataNonZeroGasEIP2028)) + calldataGasUsed.Div(calldataGasUsed, big.NewInt(1e6)) + + return l1Cost, calldataGasUsed + } +} + +// estimatedDASizeScaled estimates the number of bytes the transaction will occupy in the DA batch using the Fjord +// linear regression model, and returns this value scaled up by 1e6. +func (cd RollupCostData) estimatedDASizeScaled() *big.Int { + fastLzSize := new(big.Int).SetUint64(cd.FastLzSize) + estimatedSize := new(big.Int).Add(L1CostIntercept, new(big.Int).Mul(L1CostFastlzCoef, fastLzSize)) + + if estimatedSize.Cmp(MinTransactionSizeScaled) < 0 { + estimatedSize.Set(MinTransactionSizeScaled) + } + return estimatedSize +} + +// EstimatedDASize estimates the number of bytes the transaction will occupy in its DA batch using the Fjord linear +// regression model. +func (cd RollupCostData) EstimatedDASize() *big.Int { + b := cd.estimatedDASizeScaled() + return b.Div(b, big.NewInt(1e6)) +} + +func extractEcotoneFeeParams(l1FeeParams []byte) (l1BaseFeeScalar, l1BlobBaseFeeScalar *big.Int) { + offset := scalarSectionStart + l1BaseFeeScalar = new(big.Int).SetBytes(l1FeeParams[offset : offset+4]) + l1BlobBaseFeeScalar = new(big.Int).SetBytes(l1FeeParams[offset+4 : offset+8]) + return +} + +func bedrockCalldataGasUsed(costData RollupCostData) (calldataGasUsed *big.Int) { + calldataGas := (costData.Zeroes * params.TxDataZeroGas) + (costData.Ones * params.TxDataNonZeroGasEIP2028) + return new(big.Int).SetUint64(calldataGas) +} + +// FlzCompressLen returns the length of the data after compression through FastLZ, based on +// https://github.com/Vectorized/solady/blob/5315d937d79b335c668896d7533ac603adac5315/js/solady.js +func FlzCompressLen(ib []byte) uint32 { + n := uint32(0) + ht := make([]uint32, 8192) + u24 := func(i uint32) uint32 { + return uint32(ib[i]) | (uint32(ib[i+1]) << 8) | (uint32(ib[i+2]) << 16) + } + cmp := func(p uint32, q uint32, e uint32) uint32 { + l := uint32(0) + for e -= q; l < e; l++ { + if ib[p+l] != ib[q+l] { + e = 0 + } + } + return l + } + literals := func(r uint32) { + n += 0x21 * (r / 0x20) + r %= 0x20 + if r != 0 { + n += r + 1 + } + } + match := func(l uint32) { + l-- + n += 3 * (l / 262) + if l%262 >= 6 { + n += 3 + } else { + n += 2 + } + } + hash := func(v uint32) uint32 { + return ((2654435769 * v) >> 19) & 0x1fff + } + setNextHash := func(ip uint32) uint32 { + ht[hash(u24(ip))] = ip + return ip + 1 + } + a := uint32(0) + ipLimit := uint32(len(ib)) - 13 + if len(ib) < 13 { + ipLimit = 0 + } + for ip := a + 2; ip < ipLimit; { + r := uint32(0) + d := uint32(0) + for { + s := u24(ip) + h := hash(s) + r = ht[h] + ht[h] = ip + d = ip - r + if ip >= ipLimit { + break + } + ip++ + if d <= 0x1fff && s == u24(r) { + break + } + } + if ip >= ipLimit { + break + } + ip-- + if ip > a { + literals(ip - a) + } + l := cmp(r+3, ip+3, ipLimit+9) + match(l) + ip = setNextHash(setNextHash(ip + l)) + a = ip + } + literals(uint32(len(ib)) - a) + return n +}

Deposit transactions have special processing rules: gas is pre-paid on L1, and deposits with EVM-failure are included with rolled back changes (except mint). For regular transactions, at the end of the transition, the 1559 burn and L1 cost are routed to vaults.

diff --git go-ethereum/core/state_transition.go op-geth/core/state_transition.go index b6203e6aae0dc5e5ce8fdb5a8a78e399c73ae2e8..895ca93a8b7368d60bbdca5517518185da2add61 100644 --- go-ethereum/core/state_transition.go +++ op-geth/core/state_transition.go @@ -152,6 +152,15 @@ SkipNonceChecks bool   // When SkipFromEOACheck is true, the message sender is not checked to be an EOA. SkipFromEOACheck bool + + IsSystemTx bool // IsSystemTx indicates the message, if also a deposit, does not emit gas usage. + IsDepositTx bool // IsDepositTx indicates the message is force-included and can persist a mint. + Mint *big.Int // Mint is the amount to mint before EVM processing, or nil if there is no minting. + RollupCostData types.RollupCostData // RollupCostData caches data to compute the fee we charge for data availability + + // PostValidation is an optional check of the resulting post-state, if and when the message is + // applied fully to the EVM. This function may return an error to deny inclusion of the message. + PostValidation func(evm *vm.EVM, result *ExecutionResult) error }   // TransactionToMessage converts a transaction into a Message. @@ -171,6 +180,11 @@ SkipNonceChecks: false, SkipFromEOACheck: false, BlobHashes: tx.BlobHashes(), BlobGasFeeCap: tx.BlobGasFeeCap(), + + IsSystemTx: tx.IsSystemTx(), + IsDepositTx: tx.IsDepositTx(), + Mint: tx.Mint(), + RollupCostData: tx.RollupCostData(), } // If baseFee provided, set gasPrice to effectiveGasPrice. if baseFee != nil { @@ -248,10 +262,20 @@ func (st *stateTransition) buyGas() error { mgval := new(big.Int).SetUint64(st.msg.GasLimit) mgval.Mul(mgval, st.msg.GasPrice) + var l1Cost *big.Int + if st.evm.Context.L1CostFunc != nil && !st.msg.SkipNonceChecks && !st.msg.SkipFromEOACheck { + l1Cost = st.evm.Context.L1CostFunc(st.msg.RollupCostData, st.evm.Context.Time) + if l1Cost != nil { + mgval = mgval.Add(mgval, l1Cost) + } + } balanceCheck := new(big.Int).Set(mgval) if st.msg.GasFeeCap != nil { balanceCheck.SetUint64(st.msg.GasLimit) balanceCheck = balanceCheck.Mul(balanceCheck, st.msg.GasFeeCap) + if l1Cost != nil { + balanceCheck.Add(balanceCheck, l1Cost) + } } balanceCheck.Add(balanceCheck, st.msg.Value)   @@ -290,6 +314,21 @@ return nil }   func (st *stateTransition) preCheck() error { + if st.msg.IsDepositTx { + // No fee fields to check, no nonce to check, and no need to check if EOA (L1 already verified it for us) + // Gas is free, but no refunds! + st.initialGas = st.msg.GasLimit + st.gasRemaining += st.msg.GasLimit // Add gas here in order to be able to execute calls. + // Don't touch the gas pool for system transactions + if st.msg.IsSystemTx { + if st.evm.ChainConfig().IsOptimismRegolith(st.evm.Context.Time) { + return fmt.Errorf("%w: address %v", ErrSystemTxNotSupported, + st.msg.From.Hex()) + } + return nil + } + return st.gp.SubGas(st.msg.GasLimit) // gas used by deposits may not be used by other txs + } // Only check transactions that are not fake msg := st.msg if !msg.SkipNonceChecks { @@ -394,6 +433,52 @@ // // However if any consensus issue encountered, return the error directly with // nil evm execution result. func (st *stateTransition) execute() (*ExecutionResult, error) { + if mint := st.msg.Mint; mint != nil { + mintU256, overflow := uint256.FromBig(mint) + if overflow { + return nil, fmt.Errorf("mint value exceeds uint256: %d", mintU256) + } + st.state.AddBalance(st.msg.From, mintU256, tracing.BalanceMint) + } + snap := st.state.Snapshot() + + result, err := st.innerExecute() + // Failed deposits must still be included. Unless we cannot produce the block at all due to the gas limit. + // On deposit failure, we rewind any state changes from after the minting, and increment the nonce. + if err != nil && err != ErrGasLimitReached && st.msg.IsDepositTx { + if st.evm.Config.Tracer != nil && st.evm.Config.Tracer.OnEnter != nil { + st.evm.Config.Tracer.OnEnter(0, byte(vm.STOP), common.Address{}, common.Address{}, nil, 0, nil) + } + + st.state.RevertToSnapshot(snap) + // Even though we revert the state changes, always increment the nonce for the next deposit transaction + st.state.SetNonce(st.msg.From, st.state.GetNonce(st.msg.From)+1) + // Record deposits as using all their gas (matches the gas pool) + // System Transactions are special & are not recorded as using any gas (anywhere) + // Regolith changes this behaviour so the actual gas used is reported. + // In this case the tx is invalid so is recorded as using all gas. + gasUsed := st.msg.GasLimit + if st.msg.IsSystemTx && !st.evm.ChainConfig().IsRegolith(st.evm.Context.Time) { + gasUsed = 0 + } + result = &ExecutionResult{ + UsedGas: gasUsed, + Err: fmt.Errorf("failed deposit: %w", err), + ReturnData: nil, + } + err = nil + } + + if err == nil && st.msg.PostValidation != nil { + if err := st.msg.PostValidation(st.evm, result); err != nil { + return nil, err + } + } + + return result, err +} + +func (st *stateTransition) innerExecute() (*ExecutionResult, error) { // First check this message satisfies all consensus rules before // applying the message. The rules include these clauses // @@ -425,7 +510,11 @@ if st.gasRemaining < gas { return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining, gas) } if t := st.evm.Config.Tracer; t != nil && t.OnGasChange != nil { - t.OnGasChange(st.gasRemaining, st.gasRemaining-gas, tracing.GasChangeTxIntrinsicGas) + if st.msg.IsDepositTx { + t.OnGasChange(st.gasRemaining, 0, tracing.GasChangeTxIntrinsicGas) + } else { + t.OnGasChange(st.gasRemaining, st.gasRemaining-gas, tracing.GasChangeTxIntrinsicGas) + } } st.gasRemaining -= gas   @@ -487,6 +576,24 @@ // Execute the transaction's call. ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, value) }   + // if deposit: skip refunds, skip tipping coinbase + // Regolith changes this behaviour to report the actual gasUsed instead of always reporting all gas used. + if st.msg.IsDepositTx && !rules.IsOptimismRegolith { + // Record deposits as using all their gas (matches the gas pool) + // System Transactions are special & are not recorded as using any gas (anywhere) + gasUsed := st.msg.GasLimit + if st.msg.IsSystemTx { + gasUsed = 0 + } + return &ExecutionResult{ + UsedGas: gasUsed, + Err: vmerr, + ReturnData: ret, + }, nil + } + // Note for deposit tx there is no ETH refunded for unused gas, but that's taken care of by the fact that gasPrice + // is always 0 for deposit tx. So calling refundGas will ensure the gasUsed accounting is correct without actually + // changing the sender's balance var gasRefund uint64 if !rules.IsLondon { // Before EIP-3529: refunds were capped to gasUsed / 2 @@ -495,6 +602,15 @@ } else { // After EIP-3529: refunds are capped to gasUsed / 5 gasRefund = st.refundGas(params.RefundQuotientEIP3529) } + if st.msg.IsDepositTx && rules.IsOptimismRegolith { + // Skip coinbase payments for deposit tx in Regolith + return &ExecutionResult{ + UsedGas: st.gasUsed(), + RefundedGas: gasRefund, + Err: vmerr, + ReturnData: ret, + }, nil + } effectiveTip := msg.GasPrice if rules.IsLondon { effectiveTip = new(big.Int).Sub(msg.GasFeeCap, st.evm.Context.BaseFee) @@ -516,6 +632,24 @@ // add the coinbase to the witness iff the fee is greater than 0 if rules.IsEIP4762 && fee.Sign() != 0 { st.evm.AccessEvents.AddAccount(st.evm.Context.Coinbase, true) + } + + // Check that we are post bedrock to enable op-geth to be able to create pseudo pre-bedrock blocks (these are pre-bedrock, but don't follow l2 geth rules) + // Note optimismConfig will not be nil if rules.IsOptimismBedrock is true + if optimismConfig := st.evm.ChainConfig().Optimism; optimismConfig != nil && rules.IsOptimismBedrock && !st.msg.IsDepositTx { + gasCost := new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.evm.Context.BaseFee) + amtU256, overflow := uint256.FromBig(gasCost) + if overflow { + return nil, fmt.Errorf("optimism gas cost overflows U256: %d", gasCost) + } + st.state.AddBalance(params.OptimismBaseFeeRecipient, amtU256, tracing.BalanceIncreaseRewardTransactionFee) + if l1Cost := st.evm.Context.L1CostFunc(st.msg.RollupCostData, st.evm.Context.Time); l1Cost != nil { + amtU256, overflow = uint256.FromBig(l1Cost) + if overflow { + return nil, fmt.Errorf("optimism l1 cost overflows U256: %d", l1Cost) + } + st.state.AddBalance(params.OptimismL1FeeRecipient, amtU256, tracing.BalanceIncreaseRewardTransactionFee) + } } }
diff --git go-ethereum/core/error.go op-geth/core/error.go index 82f7ddcf5d048cb53d8b28d6284f77e7a5136ff0..a33a0f471b499ab5732950b4b7024f31e5a6b496 100644 --- go-ethereum/core/error.go +++ op-geth/core/error.go @@ -131,3 +131,13 @@ ErrAuthorizationInvalidSignature = errors.New("EIP-7702 authorization has invalid signature") ErrAuthorizationDestinationHasCode = errors.New("EIP-7702 authorization destination is a contract") ErrAuthorizationNonceMismatch = errors.New("EIP-7702 authorization nonce does not match current account nonce") ) + +// OP-Stack errors. +var ( + // ErrTxFilteredOut indicates an ingress filter has rejected the transaction from + // being included in the pool. + ErrTxFilteredOut = errors.New("transaction filtered out") + + // ErrSystemTxNotSupported is returned for any deposit tx with IsSystemTx=true after the Regolith fork + ErrSystemTxNotSupported = errors.New("system tx not supported") +)

The gaslimit is free to be set by the Engine API caller, instead of enforcing adjustments of the gaslimit in increments of 11024 of the previous gaslimit. The elasticity-multiplier and base-fee-max-change-denominator EIP-1559 parameters can also be set by the Engine API caller through the ExtraData field. The gaslimit and EIP-1559 parameters are changed (and limited) through the SystemConfig contract.

diff --git go-ethereum/consensus/misc/eip1559/eip1559.go op-geth/consensus/misc/eip1559/eip1559.go index a90bd744b2757b5ad167622038f6ebdc48f8ba6b..1a405d6121979e45df4fffa48b4232c931667379 100644 --- go-ethereum/consensus/misc/eip1559/eip1559.go +++ op-geth/consensus/misc/eip1559/eip1559.go @@ -17,8 +17,10 @@ package eip1559   import ( + "encoding/binary" "errors" "fmt" + gomath "math" "math/big"   "github.com/ethereum/go-ethereum/common" @@ -36,15 +38,17 @@ parentGasLimit := parent.GasLimit if !config.IsLondon(parent.Number) { parentGasLimit = parent.GasLimit * config.ElasticityMultiplier() } - if err := misc.VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil { - return err + if config.Optimism == nil { // gasLimit can adjust instantly in optimism + if err := misc.VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil { + return err + } } // Verify the header is not malformed if header.BaseFee == nil { return errors.New("header is missing baseFee") } // Verify the baseFee is correct based on the parent header. - expectedBaseFee := CalcBaseFee(config, parent) + expectedBaseFee := CalcBaseFee(config, parent, header.Time) if header.BaseFee.Cmp(expectedBaseFee) != 0 { return fmt.Errorf("invalid baseFee: have %s, want %s, parentBaseFee %s, parentGasUsed %d", header.BaseFee, expectedBaseFee, parent.BaseFee, parent.GasUsed) @@ -52,14 +56,99 @@ } return nil }   +// DecodeHolocene1559Params extracts the Holcene 1599 parameters from the encoded form defined here: +// https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/holocene/exec-engine.md#eip-1559-parameters-in-payloadattributesv3 +// +// Returns 0,0 if the format is invalid, though ValidateHolocene1559Params should be used instead of this function for +// validity checking. +func DecodeHolocene1559Params(params []byte) (uint64, uint64) { + if len(params) != 8 { + return 0, 0 + } + denominator := binary.BigEndian.Uint32(params[:4]) + elasticity := binary.BigEndian.Uint32(params[4:]) + return uint64(denominator), uint64(elasticity) +} + +// DecodeHoloceneExtraData decodes the Holocene 1559 parameters from the encoded form defined here: +// https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/holocene/exec-engine.md#eip-1559-parameters-in-block-header +// +// Returns 0,0 if the format is invalid, though ValidateHoloceneExtraData should be used instead of this function for +// validity checking. +func DecodeHoloceneExtraData(extra []byte) (uint64, uint64) { + if len(extra) != 9 { + return 0, 0 + } + return DecodeHolocene1559Params(extra[1:]) +} + +// EncodeHolocene1559Params encodes the eip-1559 parameters into 'PayloadAttributes.EIP1559Params' format. Will panic if +// either value is outside uint32 range. +func EncodeHolocene1559Params(denom, elasticity uint64) []byte { + r := make([]byte, 8) + if denom > gomath.MaxUint32 || elasticity > gomath.MaxUint32 { + panic("eip-1559 parameters out of uint32 range") + } + binary.BigEndian.PutUint32(r[:4], uint32(denom)) + binary.BigEndian.PutUint32(r[4:], uint32(elasticity)) + return r +} + +// EncodeHoloceneExtraData encodes the eip-1559 parameters into the header 'ExtraData' format. Will panic if either +// value is outside uint32 range. +func EncodeHoloceneExtraData(denom, elasticity uint64) []byte { + r := make([]byte, 9) + if denom > gomath.MaxUint32 || elasticity > gomath.MaxUint32 { + panic("eip-1559 parameters out of uint32 range") + } + // leave version byte 0 + binary.BigEndian.PutUint32(r[1:5], uint32(denom)) + binary.BigEndian.PutUint32(r[5:], uint32(elasticity)) + return r +} + +// ValidateHolocene1559Params checks if the encoded parameters are valid according to the Holocene +// upgrade. +func ValidateHolocene1559Params(params []byte) error { + if len(params) != 8 { + return fmt.Errorf("holocene eip-1559 params should be 8 bytes, got %d", len(params)) + } + d, e := DecodeHolocene1559Params(params) + if e != 0 && d == 0 { + return errors.New("holocene params cannot have a 0 denominator unless elasticity is also 0") + } + return nil +} + +// ValidateHoloceneExtraData checks if the header extraData is valid according to the Holocene +// upgrade. +func ValidateHoloceneExtraData(extra []byte) error { + if len(extra) != 9 { + return fmt.Errorf("holocene extraData should be 9 bytes, got %d", len(extra)) + } + if extra[0] != 0 { + return fmt.Errorf("holocene extraData should have 0 version byte, got %d", extra[0]) + } + return ValidateHolocene1559Params(extra[1:]) +} + // CalcBaseFee calculates the basefee of the header. -func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int { +// The time belongs to the new block to check which upgrades are active. +func CalcBaseFee(config *params.ChainConfig, parent *types.Header, time uint64) *big.Int { // If the current block is the first EIP-1559 block, return the InitialBaseFee. if !config.IsLondon(parent.Number) { return new(big.Int).SetUint64(params.InitialBaseFee) } - - parentGasTarget := parent.GasLimit / config.ElasticityMultiplier() + elasticity := config.ElasticityMultiplier() + denominator := config.BaseFeeChangeDenominator(time) + if config.IsHolocene(parent.Time) { + denominator, elasticity = DecodeHoloceneExtraData(parent.Extra) + if denominator == 0 { + // this shouldn't happen as the ExtraData should have been validated prior + panic("invalid eip-1559 params in extradata") + } + } + parentGasTarget := parent.GasLimit / elasticity // If the parent gasUsed is the same as the target, the baseFee remains unchanged. if parent.GasUsed == parentGasTarget { return new(big.Int).Set(parent.BaseFee) @@ -76,7 +165,7 @@ // max(1, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator) num.SetUint64(parent.GasUsed - parentGasTarget) num.Mul(num, parent.BaseFee) num.Div(num, denom.SetUint64(parentGasTarget)) - num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator())) + num.Div(num, denom.SetUint64(denominator)) if num.Cmp(common.Big1) < 0 { return num.Add(parent.BaseFee, common.Big1) } @@ -87,7 +176,7 @@ // max(0, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator) num.SetUint64(parentGasTarget - parent.GasUsed) num.Mul(num, parent.BaseFee) num.Div(num, denom.SetUint64(parentGasTarget)) - num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator())) + num.Div(num, denom.SetUint64(denominator))   baseFee := num.Sub(parent.BaseFee, num) if baseFee.Cmp(common.Big0) < 0 {
diff --git go-ethereum/consensus/misc/eip1559/eip1559_test.go op-geth/consensus/misc/eip1559/eip1559_test.go index b5afdf0fe5e56ca6ced6031be233c6aafb17dcdd..c48b540b74e62a1146b616f3aa5c4e22b11160a1 100644 --- go-ethereum/consensus/misc/eip1559/eip1559_test.go +++ op-geth/consensus/misc/eip1559/eip1559_test.go @@ -55,6 +55,22 @@ config.LondonBlock = big.NewInt(5) return config }   +func opConfig() *params.ChainConfig { + config := copyConfig(params.TestChainConfig) + config.LondonBlock = big.NewInt(5) + ct := uint64(10) + eip1559DenominatorCanyon := uint64(250) + config.CanyonTime = &ct + ht := uint64(12) + config.HoloceneTime = &ht + config.Optimism = &params.OptimismConfig{ + EIP1559Elasticity: 6, + EIP1559Denominator: 50, + EIP1559DenominatorCanyon: &eip1559DenominatorCanyon, + } + return config +} + // TestBlockGasLimits tests the gasLimit checks for blocks both across // the EIP-1559 boundary and post-1559 blocks func TestBlockGasLimits(t *testing.T) { @@ -124,7 +140,80 @@ GasLimit: test.parentGasLimit, GasUsed: test.parentGasUsed, BaseFee: big.NewInt(test.parentBaseFee), } - if have, want := CalcBaseFee(config(), parent), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 { + if have, want := CalcBaseFee(config(), parent, 0), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 { + t.Errorf("test %d: have %d want %d, ", i, have, want) + } + } +} + +// TestCalcBaseFeeOptimism assumes all blocks are 1559-blocks but tests the Canyon activation +func TestCalcBaseFeeOptimism(t *testing.T) { + tests := []struct { + parentBaseFee int64 + parentGasLimit uint64 + parentGasUsed uint64 + expectedBaseFee int64 + postCanyon bool + }{ + {params.InitialBaseFee, 30_000_000, 5_000_000, params.InitialBaseFee, false}, // usage == target + {params.InitialBaseFee, 30_000_000, 4_000_000, 996000000, false}, // usage below target + {params.InitialBaseFee, 30_000_000, 10_000_000, 1020000000, false}, // usage above target + {params.InitialBaseFee, 30_000_000, 5_000_000, params.InitialBaseFee, true}, // usage == target + {params.InitialBaseFee, 30_000_000, 4_000_000, 999200000, true}, // usage below target + {params.InitialBaseFee, 30_000_000, 10_000_000, 1004000000, true}, // usage above target + } + for i, test := range tests { + parent := &types.Header{ + Number: common.Big32, + GasLimit: test.parentGasLimit, + GasUsed: test.parentGasUsed, + BaseFee: big.NewInt(test.parentBaseFee), + Time: 6, + } + if test.postCanyon { + parent.Time = 8 + } + if have, want := CalcBaseFee(opConfig(), parent, parent.Time+2), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 { + t.Errorf("test %d: have %d want %d, ", i, have, want) + } + if test.postCanyon { + // make sure Holocene activation doesn't change the outcome; since these tests have empty eip1559 params, + // they should be handled using the Canyon config. + parent.Time = 10 + if have, want := CalcBaseFee(opConfig(), parent, parent.Time+2), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 { + t.Errorf("test %d: have %d want %d, ", i, have, want) + } + } + } +} + +// TestCalcBaseFeeOptimismHolocene assumes all blocks are Optimism blocks post-Holocene upgrade +func TestCalcBaseFeeOptimismHolocene(t *testing.T) { + parentBaseFee := int64(10_000_000) + parentGasLimit := uint64(30_000_000) + + tests := []struct { + parentGasUsed uint64 + expectedBaseFee int64 + denom, elasticity uint64 + }{ + {parentGasLimit / 2, parentBaseFee, 10, 2}, // target + {10_000_000, 9_666_667, 10, 2}, // below + {20_000_000, 10_333_333, 10, 2}, // above + {parentGasLimit / 10, parentBaseFee, 2, 10}, // target + {1_000_000, 6_666_667, 2, 10}, // below + {30_000_000, 55_000_000, 2, 10}, // above + } + for i, test := range tests { + parent := &types.Header{ + Number: common.Big32, + GasLimit: parentGasLimit, + GasUsed: test.parentGasUsed, + BaseFee: big.NewInt(parentBaseFee), + Time: 12, + Extra: EncodeHoloceneExtraData(test.denom, test.elasticity), + } + if have, want := CalcBaseFee(opConfig(), parent, parent.Time+2), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 { t.Errorf("test %d: have %d want %d, ", i, have, want) } }

The Engine API is activated at the Merge transition, with a Total Terminal Difficulty (TTD). The rollup starts post-merge, and thus sets the TTD to 0. The TTD is always “reached” starting at the bedrock block.

diff --git go-ethereum/consensus/beacon/consensus.go op-geth/consensus/beacon/consensus.go index cdacf354a5e6c3d613a88061516ebcc770e442c3..399b09cb535533eb9ff3e93a37ebf88eaae44ffc 100644 --- go-ethereum/consensus/beacon/consensus.go +++ op-geth/consensus/beacon/consensus.go @@ -61,6 +61,7 @@ // The beacon here is a half-functional consensus engine with partial functions which // is only used for necessary consensus checks. The legacy consensus engine can be any // engine implements the consensus interface (except the beacon itself). type Beacon struct { + // For migrated OP chains (OP mainnet, OP Goerli), ethone is a dummy legacy pre-Bedrock consensus ethone consensus.Engine // Original consensus engine used in eth1, e.g. ethash or clique }   @@ -108,12 +109,27 @@ } return errs }   +// OP-Stack Bedrock variant of splitHeaders: the total-terminal difficulty is terminated at bedrock transition, but also reset to 0. +// So just use the bedrock fork check to split the headers, to simplify the splitting. +// The returned slices are slices over the input. The input must be sorted. +func (beacon *Beacon) splitBedrockHeaders(chain consensus.ChainHeaderReader, headers []*types.Header) ([]*types.Header, []*types.Header, error) { + for i, h := range headers { + if chain.Config().IsBedrock(h.Number) { + return headers[:i], headers[i:], nil + } + } + return headers, nil, nil +} + // splitHeaders splits the provided header batch into two parts according to // the configured ttd. It requires the parent of header batch along with its // td are stored correctly in chain. If ttd is not configured yet, all headers // will be treated legacy PoW headers. // Note, this function will not verify the header validity but just split them. func (beacon *Beacon) splitHeaders(chain consensus.ChainHeaderReader, headers []*types.Header) ([]*types.Header, []*types.Header, error) { + if chain.Config().Optimism != nil { + return beacon.splitBedrockHeaders(chain, headers) + } // TTD is not defined yet, all headers should be in legacy format. ttd := chain.Config().TerminalTotalDifficulty ptd := chain.GetTd(headers[0].ParentHash, headers[0].Number.Uint64()-1) @@ -385,8 +401,21 @@ // Assign the final state root to header. header.Root = state.IntermediateRoot(true)   + if chain.Config().IsOptimismIsthmus(header.Time) { + if body.Withdrawals == nil || len(body.Withdrawals) > 0 { // We verify nil/empty withdrawals in the CL pre-Isthmus + return nil, fmt.Errorf("expected non-nil empty withdrawals operation list in Isthmus, but got: %v", body.Withdrawals) + } + // State-root has just been computed, we can get an accurate storage-root now. + h := state.GetStorageRoot(params.OptimismL2ToL1MessagePasser) + header.WithdrawalsHash = &h + sa := state.AccessEvents() + if sa != nil { + sa.AddAccount(params.OptimismL2ToL1MessagePasser, false) // include in execution witness + } + } + // Assemble the final block. - block := types.NewBlock(header, body, receipts, trie.NewStackTrie(nil)) + block := types.NewBlock(header, body, receipts, trie.NewStackTrie(nil), chain.Config())   // Create the block witness and attach to block. // This step needs to happen as late as possible to catch all access events. @@ -481,6 +510,10 @@ func (beacon *Beacon) InnerEngine() consensus.Engine { return beacon.ethone }   +func (beacon *Beacon) SwapInner(inner consensus.Engine) { + beacon.ethone = inner +} + // SetThreads updates the mining threads. Delegate the call // to the eth1 engine if it's threaded. func (beacon *Beacon) SetThreads(threads int) { @@ -496,6 +529,17 @@ // IsTTDReached checks if the TotalTerminalDifficulty has been surpassed on the `parentHash` block. // It depends on the parentHash already being stored in the database. // If the parentHash is not stored in the database a UnknownAncestor error is returned. func IsTTDReached(chain consensus.ChainHeaderReader, parentHash common.Hash, parentNumber uint64) (bool, error) { + if cfg := chain.Config(); cfg.Optimism != nil { + // If OP-Stack then bedrock activation number determines when TTD (eth Merge) has been reached. + // Note: some tests/utils will set parentNumber == max_uint64 as "parent" of the genesis block, this is fine. + return cfg.IsBedrock(new(big.Int).SetUint64(parentNumber + 1)), nil + } + if chain.Config().TerminalTotalDifficulty == nil { + return false, nil + } + if common.Big0.Cmp(chain.Config().TerminalTotalDifficulty) == 0 { // in case TTD is reached at genesis. + return true, nil + } td := chain.GetTd(parentHash, parentNumber) if td == nil { return false, consensus.ErrUnknownAncestor

Pre-Bedrock OP-mainnet and OP-Goerli had differently formatted block-headers, loosely compatible with the geth types (since it was based on Clique). However, due to differences like the extra-data length (97+ bytes), these legacy block-headers need special verification. The pre-merge “consensus” fallback is set to this custom but basic verifier, to accept these headers when syncing a pre-bedrock part of the chain, independent of any clique code or configuration (which may be removed from geth at a later point). All the custom verifier has to do is accept the headers, as the headers are already verified by block-hash through the reverse-header-sync.

diff --git go-ethereum/consensus/beacon/oplegacy.go op-geth/consensus/beacon/oplegacy.go new file mode 100644 index 0000000000000000000000000000000000000000..5b313e08529daf92fe7fddbe9e319a417055fc72 --- /dev/null +++ op-geth/consensus/beacon/oplegacy.go @@ -0,0 +1,92 @@ +package beacon + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/rpc" +) + +type OpLegacy struct{} + +func (o *OpLegacy) Author(header *types.Header) (common.Address, error) { + return header.Coinbase, nil +} + +func (o *OpLegacy) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header) error { + // Short circuit if the header is known, or its parent not + number := header.Number.Uint64() + if chain.GetHeader(header.Hash(), number) != nil { + return nil + } + parent := chain.GetHeader(header.ParentHash, number-1) + if parent == nil { + return consensus.ErrUnknownAncestor + } + // legacy chain is verified by block-hash reverse sync otherwise + return nil +} + +func (o *OpLegacy) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header) (chan<- struct{}, <-chan error) { + abort := make(chan struct{}) + results := make(chan error, len(headers)) + + for i := range headers { + // legacy chain is verified by block-hash reverse sync + var parent *types.Header + if i == 0 { + parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1) + } else if headers[i-1].Hash() == headers[i].ParentHash { + parent = headers[i-1] + } + var err error + if parent == nil { + err = consensus.ErrUnknownAncestor + } + results <- err + } + return abort, results +} + +func (o *OpLegacy) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { + return nil +} + +func (o *OpLegacy) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error { + return fmt.Errorf("cannot prepare for legacy block header: %s (num %d)", header.Hash(), header.Number) +} + +func (o *OpLegacy) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state vm.StateDB, body *types.Body) { + panic(fmt.Errorf("cannot finalize legacy block header: %s (num %d)", header.Hash(), header.Number)) +} + +func (o *OpLegacy) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, body *types.Body, receipts []*types.Receipt) (*types.Block, error) { + return nil, fmt.Errorf("cannot finalize and assemble for legacy block header: %s (num %d)", header.Hash(), header.Number) +} + +func (o *OpLegacy) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { + return fmt.Errorf("cannot seal legacy block header: %s (num %d)", block.Hash(), block.Number()) +} + +func (o *OpLegacy) SealHash(header *types.Header) common.Hash { + panic(fmt.Errorf("cannot compute pow/poa seal-hash for legacy block header: %s (num %d)", header.Hash(), header.Number)) +} + +func (o *OpLegacy) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int { + return big.NewInt(0) +} + +func (o *OpLegacy) APIs(chain consensus.ChainHeaderReader) []rpc.API { + return nil +} + +func (o *OpLegacy) Close() error { + return nil +} + +var _ consensus.Engine = (*OpLegacy)(nil)

The Engine API is extended to insert transactions into the block and optionally exclude the tx-pool, to reproduce the exact block of the sequencer from just the inputs, as derived from L1 by the rollup-node. See L2 execution engine specs. It is also extended to support dynamic EIP-1559 parameters. See Holocene execution engine specs.

diff --git go-ethereum/beacon/engine/gen_blockparams.go op-geth/beacon/engine/gen_blockparams.go index b1f01b50ff8e3b1adf0454ff989356a6f612a337..1a9a45fba586f76cb73c359b8151da4ead09389a 100644 --- go-ethereum/beacon/engine/gen_blockparams.go +++ op-geth/beacon/engine/gen_blockparams.go @@ -21,6 +21,10 @@ Random common.Hash `json:"prevRandao" gencodec:"required"` SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"` Withdrawals []*types.Withdrawal `json:"withdrawals"` BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"` + Transactions []hexutil.Bytes `json:"transactions,omitempty" gencodec:"optional"` + NoTxPool bool `json:"noTxPool,omitempty" gencodec:"optional"` + GasLimit *hexutil.Uint64 `json:"gasLimit,omitempty" gencodec:"optional"` + EIP1559Params hexutil.Bytes `json:"eip1559Params,omitempty" gencodec:"optional"` } var enc PayloadAttributes enc.Timestamp = hexutil.Uint64(p.Timestamp) @@ -28,6 +32,15 @@ enc.Random = p.Random enc.SuggestedFeeRecipient = p.SuggestedFeeRecipient enc.Withdrawals = p.Withdrawals enc.BeaconRoot = p.BeaconRoot + if p.Transactions != nil { + enc.Transactions = make([]hexutil.Bytes, len(p.Transactions)) + for k, v := range p.Transactions { + enc.Transactions[k] = v + } + } + enc.NoTxPool = p.NoTxPool + enc.GasLimit = (*hexutil.Uint64)(p.GasLimit) + enc.EIP1559Params = p.EIP1559Params return json.Marshal(&enc) }   @@ -39,6 +52,10 @@ Random *common.Hash `json:"prevRandao" gencodec:"required"` SuggestedFeeRecipient *common.Address `json:"suggestedFeeRecipient" gencodec:"required"` Withdrawals []*types.Withdrawal `json:"withdrawals"` BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"` + Transactions []hexutil.Bytes `json:"transactions,omitempty" gencodec:"optional"` + NoTxPool *bool `json:"noTxPool,omitempty" gencodec:"optional"` + GasLimit *hexutil.Uint64 `json:"gasLimit,omitempty" gencodec:"optional"` + EIP1559Params *hexutil.Bytes `json:"eip1559Params,omitempty" gencodec:"optional"` } var dec PayloadAttributes if err := json.Unmarshal(input, &dec); err != nil { @@ -61,6 +78,21 @@ p.Withdrawals = dec.Withdrawals } if dec.BeaconRoot != nil { p.BeaconRoot = dec.BeaconRoot + } + if dec.Transactions != nil { + p.Transactions = make([][]byte, len(dec.Transactions)) + for k, v := range dec.Transactions { + p.Transactions[k] = v + } + } + if dec.NoTxPool != nil { + p.NoTxPool = *dec.NoTxPool + } + if dec.GasLimit != nil { + p.GasLimit = (*uint64)(dec.GasLimit) + } + if dec.EIP1559Params != nil { + p.EIP1559Params = *dec.EIP1559Params } return nil }
diff --git go-ethereum/beacon/engine/types.go op-geth/beacon/engine/types.go index 984090ef89b1a342994737980722ea95bdb08b6e..4067988e52ebfebee47682a341bbd3a5b63bfc47 100644 --- go-ethereum/beacon/engine/types.go +++ op-geth/beacon/engine/types.go @@ -48,11 +48,27 @@ Random common.Hash `json:"prevRandao" gencodec:"required"` SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"` Withdrawals []*types.Withdrawal `json:"withdrawals"` BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"` + + // Transactions is a field for rollups: the transactions list is forced into the block + Transactions [][]byte `json:"transactions,omitempty" gencodec:"optional"` + // NoTxPool is a field for rollups: if true, the no transactions are taken out of the tx-pool, + // only transactions from the above Transactions list will be included. + NoTxPool bool `json:"noTxPool,omitempty" gencodec:"optional"` + // GasLimit is a field for rollups: if set, this sets the exact gas limit the block produced with. + GasLimit *uint64 `json:"gasLimit,omitempty" gencodec:"optional"` + // EIP1559Params is a field for rollups implementing the Holocene upgrade, + // and contains encoded EIP-1559 parameters. See: + // https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/holocene/exec-engine.md#eip1559params-encoding + EIP1559Params []byte `json:"eip1559Params,omitempty" gencodec:"optional"` }   // JSON type overrides for PayloadAttributes. type payloadAttributesMarshaling struct { Timestamp hexutil.Uint64 + + Transactions []hexutil.Bytes + GasLimit *hexutil.Uint64 + EIP1559Params hexutil.Bytes }   //go:generate go run github.com/fjl/gencodec -type ExecutableData -field-override executableDataMarshaling -out gen_ed.go @@ -77,6 +93,11 @@ Withdrawals []*types.Withdrawal `json:"withdrawals"` BlobGasUsed *uint64 `json:"blobGasUsed"` ExcessBlobGas *uint64 `json:"excessBlobGas"` ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"` + + // OP-Stack Isthmus specific field: + // instead of computing the root from a withdrawals list, set it directly. + // The "withdrawals" list attribute must be non-nil but empty. + WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"` }   // JSON type overrides for executableData. @@ -110,6 +131,8 @@ BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` Requests [][]byte `json:"executionRequests"` Override bool `json:"shouldOverrideBuilder"` Witness *hexutil.Bytes `json:"witness,omitempty"` + // OP-Stack: Ecotone specific fields + ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot,omitempty"` }   type BlobsBundleV1 struct { @@ -213,8 +236,8 @@ // // and that the blockhash of the constructed block matches the parameters. Nil // Withdrawals value will propagate through the returned block. Empty // Withdrawals value must be passed via non-nil, length 0 value in data. -func ExecutableDataToBlock(data ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte) (*types.Block, error) { - block, err := ExecutableDataToBlockNoHash(data, versionedHashes, beaconRoot, requests) +func ExecutableDataToBlock(data ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte, bType types.BlockType) (*types.Block, error) { + block, err := ExecutableDataToBlockNoHash(data, versionedHashes, beaconRoot, requests, bType) if err != nil { return nil, err } @@ -227,7 +250,7 @@ // ExecutableDataToBlockNoHash is analogous to ExecutableDataToBlock, but is used // for stateless execution, so it skips checking if the executable data hashes to // the requested hash (stateless has to *compute* the root hash, it's not given). -func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte) (*types.Block, error) { +func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte, bType types.BlockType) (*types.Block, error) { txs, err := decodeTransactions(data.Transactions) if err != nil { return nil, err @@ -258,15 +281,32 @@ // Only set withdrawalsRoot if it is non-nil. This allows CLs to use // ExecutableData before withdrawals are enabled by marshaling // Withdrawals as the json null value. var withdrawalsRoot *common.Hash - if data.Withdrawals != nil { + if bType.HasOptimismWithdrawalsRoot(data.Timestamp) { + if data.WithdrawalsRoot == nil { + return nil, fmt.Errorf("attribute WithdrawalsRoot is required for Isthmus blocks") + } + if data.Withdrawals == nil || len(data.Withdrawals) > 0 { + return nil, fmt.Errorf("expected non-nil empty withdrawals operation list in Isthmus, but got: %v", data.Withdrawals) + } + } + if data.WithdrawalsRoot != nil { + h := *data.WithdrawalsRoot // copy, avoid any sharing of memory + withdrawalsRoot = &h + } else if data.Withdrawals != nil { h := types.DeriveSha(types.Withdrawals(data.Withdrawals), trie.NewStackTrie(nil)) withdrawalsRoot = &h }   + isthmusEnabled := bType.IsIsthmus(data.Timestamp) var requestsHash *common.Hash if requests != nil { + if isthmusEnabled && len(requests) > 0 { + return nil, fmt.Errorf("requests should be empty for Isthmus blocks") + } h := types.CalcRequestsHash(requests) requestsHash = &h + } else if isthmusEnabled { + return nil, fmt.Errorf("requests must be an empty array for Isthmus blocks") }   header := &types.Header{ @@ -319,6 +359,8 @@ Withdrawals: block.Withdrawals(), BlobGasUsed: block.BlobGasUsed(), ExcessBlobGas: block.ExcessBlobGas(), ExecutionWitness: block.ExecutionWitness(), + // OP-Stack addition: withdrawals list alone does not express the withdrawals storage-root. + WithdrawalsRoot: block.WithdrawalsRoot(), }   // Add blobs. @@ -341,6 +383,9 @@ BlockValue: fees, BlobsBundle: &bundle, Requests: requests, Override: false, + + // OP-Stack addition + ParentBeaconBlockRoot: block.BeaconRoot(), } }
diff --git go-ethereum/eth/catalyst/api.go op-geth/eth/catalyst/api.go index 37d962d070e0b25bd914b5d8f732bca3d149f35b..728240f217fa90c644a8f63de417a57249f48848 100644 --- go-ethereum/eth/catalyst/api.go +++ op-geth/eth/catalyst/api.go @@ -18,6 +18,7 @@ // Package catalyst implements the temporary eth1/eth2 RPC integration. package catalyst   import ( + "bytes" "errors" "fmt" "strconv" @@ -27,6 +28,7 @@ "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/stateless" @@ -395,7 +397,7 @@ } else if api.eth.BlockChain().CurrentBlock().Hash() == update.HeadBlockHash { // If the specified head matches with our local head, do nothing and keep // generating the payload. It's a special corner case that a few slots are // missing and we are requested to generate the payload in slot. - } else { + } else if api.eth.BlockChain().Config().Optimism == nil { // minor Engine API divergence: allow proposers to reorg their own chain // If the head block is already in our canonical chain, the beacon client is // probably resyncing. Ignore the update. log.Info("Ignoring beacon update to old head", "number", block.NumberU64(), "hash", update.HeadBlockHash, "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)), "have", api.eth.BlockChain().CurrentBlock().Number) @@ -435,15 +437,43 @@ } // If payload generation was requested, create a new block to be potentially // sealed by the beacon client. The payload will be requested later, and we // will replace it arbitrarily many times in between. + if payloadAttributes != nil { + var eip1559Params []byte + if api.eth.BlockChain().Config().Optimism != nil { + if payloadAttributes.GasLimit == nil { + return engine.STATUS_INVALID, engine.InvalidPayloadAttributes.With(errors.New("gasLimit parameter is required")) + } + if api.eth.BlockChain().Config().IsHolocene(payloadAttributes.Timestamp) { + if err := eip1559.ValidateHolocene1559Params(payloadAttributes.EIP1559Params); err != nil { + return engine.STATUS_INVALID, engine.InvalidPayloadAttributes.With(err) + } + eip1559Params = bytes.Clone(payloadAttributes.EIP1559Params) + } else if len(payloadAttributes.EIP1559Params) != 0 { + return engine.STATUS_INVALID, + engine.InvalidPayloadAttributes.With(errors.New("eip155Params not supported prior to Holocene upgrade")) + } + } + transactions := make(types.Transactions, 0, len(payloadAttributes.Transactions)) + for i, otx := range payloadAttributes.Transactions { + var tx types.Transaction + if err := tx.UnmarshalBinary(otx); err != nil { + return engine.STATUS_INVALID, fmt.Errorf("transaction %d is not valid: %v", i, err) + } + transactions = append(transactions, &tx) + } args := &miner.BuildPayloadArgs{ - Parent: update.HeadBlockHash, - Timestamp: payloadAttributes.Timestamp, - FeeRecipient: payloadAttributes.SuggestedFeeRecipient, - Random: payloadAttributes.Random, - Withdrawals: payloadAttributes.Withdrawals, - BeaconRoot: payloadAttributes.BeaconRoot, - Version: payloadVersion, + Parent: update.HeadBlockHash, + Timestamp: payloadAttributes.Timestamp, + FeeRecipient: payloadAttributes.SuggestedFeeRecipient, + Random: payloadAttributes.Random, + Withdrawals: payloadAttributes.Withdrawals, + BeaconRoot: payloadAttributes.BeaconRoot, + NoTxPool: payloadAttributes.NoTxPool, + Transactions: transactions, + GasLimit: payloadAttributes.GasLimit, + Version: payloadVersion, + EIP1559Params: eip1559Params, } id := args.Id() // If we already are busy generating this work, then we do not need @@ -609,6 +639,7 @@ if api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Cancun { return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadV3 must only be called for cancun payloads")) } + return api.newPayload(params, versionedHashes, beaconRoot, nil, false) }   @@ -839,11 +870,23 @@ // 3. When the db compaction ends, then N calls inserting the same payload are processed // sequentially. // Hence, we use a lock here, to be sure that the previous call has finished before we // check whether we already have the block locally. + + // OP-Stack diff: payload must have empty extraData before Holocene and hold eip-1559 params after Holocene. + if cfg := api.eth.BlockChain().Config(); cfg.IsHolocene(params.Timestamp) { + if err := eip1559.ValidateHoloceneExtraData(params.ExtraData); err != nil { + return api.invalid(err, nil), nil + } + } else if cfg.IsOptimism() { + if len(params.ExtraData) > 0 { + return api.invalid(errors.New("extraData must be empty before Holocene"), nil), nil + } + } + api.newPayloadLock.Lock() defer api.newPayloadLock.Unlock()   log.Trace("Engine API request received", "method", "NewPayload", "number", params.Number, "hash", params.BlockHash) - block, err := engine.ExecutableDataToBlock(params, versionedHashes, beaconRoot, requests) + block, err := engine.ExecutableDataToBlock(params, versionedHashes, beaconRoot, requests, api.eth.BlockChain().Config()) if err != nil { bgu := "nil" if params.BlobGasUsed != nil { @@ -870,6 +913,7 @@ "params.BlobGasUsed", bgu, "params.ExcessBlobGas", ebg, "len(params.Transactions)", len(params.Transactions), "len(params.Withdrawals)", len(params.Withdrawals), + "params.WithdrawalsRoot", params.WithdrawalsRoot, "beaconRoot", beaconRoot, "len(requests)", len(requests), "error", err) @@ -957,7 +1001,7 @@ }   func (api *ConsensusAPI) executeStatelessPayload(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte, opaqueWitness hexutil.Bytes) (engine.StatelessPayloadStatusV1, error) { log.Trace("Engine API request received", "method", "ExecuteStatelessPayload", "number", params.Number, "hash", params.BlockHash) - block, err := engine.ExecutableDataToBlockNoHash(params, versionedHashes, beaconRoot, requests) + block, err := engine.ExecutableDataToBlockNoHash(params, versionedHashes, beaconRoot, requests, api.eth.BlockChain().Config()) if err != nil { bgu := "nil" if params.BlobGasUsed != nil { @@ -984,6 +1028,7 @@ "params.BlobGasUsed", bgu, "params.ExcessBlobGas", ebg, "len(params.Transactions)", len(params.Transactions), "len(params.Withdrawals)", len(params.Withdrawals), + "params.WithdrawalsRoot", params.WithdrawalsRoot, "beaconRoot", beaconRoot, "len(requests)", len(requests), "error", err) @@ -1135,6 +1180,9 @@ // user that something might be off with their consensus node. // // TODO(karalabe): Spin this goroutine down somehow func (api *ConsensusAPI) heartbeat() { + if api.eth.BlockChain().Config().Optimism != nil { // don't start the api heartbeat, there is no transition + return + } // Sleep a bit on startup since there's obviously no beacon client yet // attached, so no need to print scary warnings to the user. time.Sleep(beaconUpdateStartupTimeout)

The block-building code (in the “miner” package because of Proof-Of-Work legacy of ethereum) implements the changes to support the transaction-inclusion, tx-pool toggle, gaslimit, and EIP-1559 parameters of the Engine API. This also includes experimental support for interop executing-messages to be verified through an RPC.

diff --git go-ethereum/miner/miner.go op-geth/miner/miner.go index 9892c08ed6e5e0cca83348bb3979df3c1a5e9216..447cf4ccbd2f59fac1c9c1f7d391f2d74c726d01 100644 --- go-ethereum/miner/miner.go +++ op-geth/miner/miner.go @@ -18,6 +18,7 @@ // Package miner implements Ethereum block creation and mining. package miner   import ( + "context" "fmt" "math/big" "sync" @@ -30,6 +31,8 @@ "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/types/interoptypes" + "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/params" )   @@ -40,6 +43,14 @@ BlockChain() *core.BlockChain TxPool() *txpool.TxPool }   +type BackendWithHistoricalState interface { + StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, tracers.StateReleaseFunc, error) +} + +type BackendWithInterop interface { + CheckMessages(ctx context.Context, messages []interoptypes.Message, minSafety interoptypes.SafetyLevel) error +} + // Config is the configuration parameters of mining. type Config struct { Etherbase common.Address `toml:"-"` // Deprecated @@ -48,12 +59,19 @@ ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner GasCeil uint64 // Target gas ceiling for mined blocks. GasPrice *big.Int // Minimum gas price for mining a transaction Recommit time.Duration // The time interval for miner to re-create mining work. + + RollupComputePendingBlock bool // Compute the pending block from tx-pool, instead of copying the latest-block + RollupTransactionConditionalRateLimit int // Total number of conditional cost units allowed in a second + + EffectiveGasCeil uint64 // if non-zero, a gas ceiling to apply independent of the header's gaslimit value + MaxDATxSize *big.Int `toml:",omitempty"` // if non-nil, don't include any txs with data availability size larger than this in any built block + MaxDABlockSize *big.Int `toml:",omitempty"` // if non-nil, then don't build a block requiring more than this amount of total data availability }   // DefaultConfig contains default settings for miner. var DefaultConfig = Config{ GasCeil: 30_000_000, - GasPrice: big.NewInt(params.GWei / 1000), + GasPrice: big.NewInt(params.Wei),   // The default recommit time is chosen as two seconds since // consensus-layer usually will wait a half slot of time(6s) @@ -73,17 +91,27 @@ txpool *txpool.TxPool chain *core.BlockChain pending *pending pendingMu sync.Mutex // Lock protects the pending block + + backend Backend + + lifeCtxCancel context.CancelFunc + lifeCtx context.Context }   // New creates a new miner with provided config. func New(eth Backend, config Config, engine consensus.Engine) *Miner { + ctx, cancel := context.WithCancel(context.Background()) return &Miner{ + backend: eth, config: &config, chainConfig: eth.BlockChain().Config(), engine: engine, txpool: eth.TxPool(), chain: eth.BlockChain(), pending: &pending{}, + // To interrupt background tasks that may be attached to external processes + lifeCtxCancel: cancel, + lifeCtx: ctx, } }   @@ -91,6 +119,19 @@ // Pending returns the currently pending block and associated receipts, logs // and statedb. The returned values can be nil in case the pending block is // not initialized. func (miner *Miner) Pending() (*types.Block, types.Receipts, *state.StateDB) { + if miner.chainConfig.Optimism != nil && !miner.config.RollupComputePendingBlock { + // For compatibility when not computing a pending block, we serve the latest block as "pending" + headHeader := miner.chain.CurrentHeader() + headBlock := miner.chain.GetBlock(headHeader.Hash(), headHeader.Number.Uint64()) + headReceipts := miner.chain.GetReceiptsByHash(headHeader.Hash()) + stateDB, err := miner.chain.StateAt(headHeader.Root) + if err != nil { + return nil, nil, nil + } + + return headBlock, headReceipts, stateDB.Copy() + } + pending := miner.getPending() if pending == nil { return nil, nil, nil @@ -125,6 +166,22 @@ miner.confMu.Unlock() return nil }   +// SetMaxDASize sets the maximum data availability size currently allowed for inclusion. 0 means no maximum. +func (miner *Miner) SetMaxDASize(maxTxSize, maxBlockSize *big.Int) { + miner.confMu.Lock() + if maxTxSize == nil || maxTxSize.BitLen() == 0 { + miner.config.MaxDATxSize = nil + } else { + miner.config.MaxDATxSize = new(big.Int).Set(maxTxSize) + } + if maxBlockSize == nil || maxBlockSize.BitLen() == 0 { + miner.config.MaxDABlockSize = nil + } else { + miner.config.MaxDABlockSize = new(big.Int).Set(maxBlockSize) + } + miner.confMu.Unlock() +} + // BuildPayload builds the payload according to the provided parameters. func (miner *Miner) BuildPayload(args *BuildPayloadArgs, witness bool) (*Payload, error) { return miner.buildPayload(args, witness) @@ -163,3 +220,7 @@ } miner.pending.update(header.Hash(), ret) return ret } + +func (miner *Miner) Close() { + miner.lifeCtxCancel() +}
diff --git go-ethereum/miner/miner_test.go op-geth/miner/miner_test.go index 04d84e2e1dc2a6c33dc5c269ad254c8d337d08c5..7df5a642b601e197964b161c6eccfaf16ce26a98 100644 --- go-ethereum/miner/miner_test.go +++ op-geth/miner/miner_test.go @@ -21,6 +21,7 @@ import ( "math/big" "sync" "testing" + "time"   "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/clique" @@ -74,11 +75,12 @@ func (bc *testBlockChain) CurrentBlock() *types.Header { return &types.Header{ Number: new(big.Int), GasLimit: bc.gasLimit, + BaseFee: big.NewInt(params.InitialBaseFee), } }   func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { - return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil)) + return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil), types.DefaultBlockConfig) }   func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { @@ -139,12 +141,13 @@ func createMiner(t *testing.T) *Miner { // Create Ethash config config := Config{ - PendingFeeRecipient: common.HexToAddress("123456789"), + PendingFeeRecipient: common.HexToAddress("123456789"), + RollupTransactionConditionalRateLimit: params.TransactionConditionalMaxCost, } // Create chainConfig chainDB := rawdb.NewMemoryDatabase() triedb := triedb.NewDatabase(chainDB, nil) - genesis := minerTestGenesisBlock(15, 11_500_000, common.HexToAddress("12345")) + genesis := minerTestGenesisBlock(15, 11_500_000, testBankAddress) chainConfig, _, _, err := core.SetupGenesisBlock(chainDB, triedb, genesis) if err != nil { t.Fatalf("can't create new chain config: %v", err) @@ -160,10 +163,57 @@ statedb, _ := state.New(bc.Genesis().Root(), bc.StateCache()) blockchain := &testBlockChain{bc.Genesis().Root(), chainConfig, statedb, 10000000, new(event.Feed)}   pool := legacypool.New(testTxPoolConfig, blockchain) - txpool, _ := txpool.New(testTxPoolConfig.PriceLimit, blockchain, []txpool.SubPool{pool}) + txpool, _ := txpool.New(testTxPoolConfig.PriceLimit, blockchain, []txpool.SubPool{pool}, nil)   // Create Miner backend := NewMockBackend(bc, txpool) miner := New(backend, config, engine) return miner } + +func TestRejectedConditionalTx(t *testing.T) { + miner := createMiner(t) + timestamp := uint64(time.Now().Unix()) + uint64Ptr := func(num uint64) *uint64 { return &num } + + // add a conditional transaction to be rejected + signer := types.LatestSigner(miner.chainConfig) + tx := types.MustSignNewTx(testBankKey, signer, &types.LegacyTx{ + Nonce: 0, + To: &testUserAddress, + Value: big.NewInt(1000), + Gas: params.TxGas, + GasPrice: big.NewInt(params.InitialBaseFee), + }) + tx.SetConditional(&types.TransactionConditional{TimestampMax: uint64Ptr(timestamp - 1)}) + + // 1 pending tx (synchronously, it has to be there before it can be rejected) + miner.txpool.Add(types.Transactions{tx}, true, true) + if !miner.txpool.Has(tx.Hash()) { + t.Fatalf("conditional tx is not in the mempool") + } + + // request block + r := miner.generateWork(&generateParams{ + parentHash: miner.chain.CurrentBlock().Hash(), + timestamp: timestamp, + random: common.HexToHash("0xcafebabe"), + noTxs: false, + forceTime: true, + }, false) + + if len(r.block.Transactions()) != 0 { + t.Fatalf("block should be empty") + } + + // tx is rejected + if !tx.Rejected() { + t.Fatalf("conditional tx is not marked as rejected") + } + + // rejected conditional is evicted from the txpool + miner.txpool.Sync() + if miner.txpool.Has(tx.Hash()) { + t.Fatalf("conditional tx is still in the mempool") + } +}
diff --git go-ethereum/miner/payload_building.go op-geth/miner/payload_building.go index 3090de5d4b1fc9ec5769de860c05ee5a168be33f..11fe9e21c75c7f668d88c7fd6a7993253d1b43fb 100644 --- go-ethereum/miner/payload_building.go +++ op-geth/miner/payload_building.go @@ -17,10 +17,13 @@ package miner   import ( + "context" "crypto/sha256" "encoding/binary" + "errors" "math/big" "sync" + "sync/atomic" "time"   "github.com/ethereum/go-ethereum/beacon/engine" @@ -44,6 +47,11 @@ Random common.Hash // The provided randomness value Withdrawals types.Withdrawals // The provided withdrawals BeaconRoot *common.Hash // The provided beaconRoot (Cancun) Version engine.PayloadVersion // Versioning byte for payload id calculation. + + NoTxPool bool // Optimism addition: option to disable tx pool contents from being included + Transactions []*types.Transaction // Optimism addition: txs forced into the block via engine API + GasLimit *uint64 // Optimism addition: override gas limit of the block to build + EIP1559Params []byte // Optimism addition: encodes Holocene EIP-1559 params }   // Id computes an 8-byte identifier by hashing the components of the payload arguments. @@ -57,6 +65,22 @@ rlp.Encode(hasher, args.Withdrawals) if args.BeaconRoot != nil { hasher.Write(args.BeaconRoot[:]) } + + if args.NoTxPool || len(args.Transactions) > 0 { // extend if extra payload attributes are used + binary.Write(hasher, binary.BigEndian, args.NoTxPool) + binary.Write(hasher, binary.BigEndian, uint64(len(args.Transactions))) + for _, tx := range args.Transactions { + h := tx.Hash() + hasher.Write(h[:]) + } + } + if args.GasLimit != nil { + binary.Write(hasher, binary.BigEndian, *args.GasLimit) + } + if len(args.EIP1559Params) != 0 { + hasher.Write(args.EIP1559Params[:]) + } + var out engine.PayloadID copy(out[:], hasher.Sum(nil)[:8]) out[0] = byte(args.Version) @@ -81,21 +105,36 @@ fullFees *big.Int stop chan struct{} lock sync.Mutex cond *sync.Cond + + err error + stopOnce sync.Once + interrupt *atomic.Int32 // interrupt signal shared with worker + + rpcCtx context.Context // context to limit RPC-coupled payload checks + rpcCancel context.CancelFunc }   // newPayload initializes the payload object. -func newPayload(empty *types.Block, emptyRequests [][]byte, witness *stateless.Witness, id engine.PayloadID) *Payload { +func newPayload(lifeCtx context.Context, empty *types.Block, emptyRequests [][]byte, witness *stateless.Witness, id engine.PayloadID) *Payload { + rpcCtx, rpcCancel := context.WithCancel(lifeCtx) payload := &Payload{ id: id, empty: empty, emptyRequests: emptyRequests, emptyWitness: witness, stop: make(chan struct{}), + + interrupt: new(atomic.Int32), + + rpcCtx: rpcCtx, + rpcCancel: rpcCancel, } log.Info("Starting work on payload", "id", payload.id) payload.cond = sync.NewCond(&payload.lock) return payload } + +var errInterruptedUpdate = errors.New("interrupted payload update")   // update updates the full-block with latest built version. func (payload *Payload) update(r *newPayloadResult, elapsed time.Duration) { @@ -107,6 +146,19 @@ case <-payload.stop: return // reject stale update default: } + + defer payload.cond.Broadcast() // fire signal for notifying any full block result + + if errors.Is(r.err, errInterruptedUpdate) { + log.Debug("Ignoring interrupted payload update", "id", payload.id) + return + } else if r.err != nil { + log.Warn("Error building payload update", "id", payload.id, "err", r.err) + payload.err = r.err // record latest error + return + } + log.Debug("New payload update", "id", payload.id, "elapsed", common.PrettyDuration(elapsed)) + // Ensure the newly provided full block has a higher transaction fee. // In post-merge stage, there is no uncle reward anymore and transaction // fee(apart from the mev revenue) is the only indicator for comparison. @@ -130,34 +182,12 @@ "root", r.block.Root(), "elapsed", common.PrettyDuration(elapsed), ) } - payload.cond.Broadcast() // fire signal for notifying full block }   // Resolve returns the latest built payload and also terminates the background // thread for updating payload. It's safe to be called multiple times. func (payload *Payload) Resolve() *engine.ExecutionPayloadEnvelope { - payload.lock.Lock() - defer payload.lock.Unlock() - - select { - case <-payload.stop: - default: - close(payload.stop) - } - if payload.full != nil { - envelope := engine.BlockToExecutableData(payload.full, payload.fullFees, payload.sidecars, payload.requests) - if payload.fullWitness != nil { - envelope.Witness = new(hexutil.Bytes) - *envelope.Witness, _ = rlp.EncodeToBytes(payload.fullWitness) // cannot fail - } - return envelope - } - envelope := engine.BlockToExecutableData(payload.empty, big.NewInt(0), nil, payload.emptyRequests) - if payload.emptyWitness != nil { - envelope.Witness = new(hexutil.Bytes) - *envelope.Witness, _ = rlp.EncodeToBytes(payload.emptyWitness) // cannot fail - } - return envelope + return payload.resolve(false) }   // ResolveEmpty is basically identical to Resolve, but it expects empty block only. @@ -177,10 +207,24 @@ // ResolveFull is basically identical to Resolve, but it expects full block only. // Don't call Resolve until ResolveFull returns, otherwise it might block forever. func (payload *Payload) ResolveFull() *engine.ExecutionPayloadEnvelope { + return payload.resolve(true) +} + +func (payload *Payload) WaitFull() { + payload.lock.Lock() + defer payload.lock.Unlock() + payload.cond.Wait() +} + +func (payload *Payload) resolve(onlyFull bool) *engine.ExecutionPayloadEnvelope { payload.lock.Lock() defer payload.lock.Unlock()   - if payload.full == nil { + // We interrupt any active building block to prevent it from adding more transactions, + // and if it is an update, don't attempt to seal the block. + payload.interruptBuilding() + + if payload.full == nil && (onlyFull || payload.empty == nil) { select { case <-payload.stop: return nil @@ -191,41 +235,120 @@ // forever if Resolve is called in the meantime which // terminates the background construction process. payload.cond.Wait() } - // Terminate the background payload construction - select { - case <-payload.stop: - default: - close(payload.stop) + + // Now we can signal the building routine to stop. + payload.stopBuilding() + + if payload.full != nil { + envelope := engine.BlockToExecutableData(payload.full, payload.fullFees, payload.sidecars, payload.requests) + if payload.fullWitness != nil { + envelope.Witness = new(hexutil.Bytes) + *envelope.Witness, _ = rlp.EncodeToBytes(payload.fullWitness) // cannot fail + } + return envelope + } else if !onlyFull && payload.empty != nil { + envelope := engine.BlockToExecutableData(payload.empty, big.NewInt(0), nil, payload.emptyRequests) + if payload.emptyWitness != nil { + envelope.Witness = new(hexutil.Bytes) + *envelope.Witness, _ = rlp.EncodeToBytes(payload.emptyWitness) // cannot fail + } + } else if err := payload.err; err != nil { + log.Error("Error building any payload", "id", payload.id, "err", err) } - envelope := engine.BlockToExecutableData(payload.full, payload.fullFees, payload.sidecars, payload.requests) - if payload.fullWitness != nil { - envelope.Witness = new(hexutil.Bytes) - *envelope.Witness, _ = rlp.EncodeToBytes(payload.fullWitness) // cannot fail + return nil +} + +// interruptBuilding sets an interrupt for a potentially ongoing +// block building process. +// This will prevent it from adding new transactions to the block, and if it is +// building an update, the block will also not be sealed, as we would discard +// the update anyways. +// interruptBuilding is safe to be called concurrently. +func (payload *Payload) interruptBuilding() { + payload.rpcCancel() + // Set the interrupt if not interrupted already. + // It's ok if it has either already been interrupted by payload resolution earlier, + // or by the timeout timer set to commitInterruptTimeout. + if payload.interrupt.CompareAndSwap(commitInterruptNone, commitInterruptResolve) { + log.Debug("Interrupted payload building.", "id", payload.id) + } else { + log.Debug("Payload building already interrupted.", + "id", payload.id, "interrupt", payload.interrupt.Load()) } - return envelope +} + +// stopBuilding signals to the block updating routine to stop. An ongoing payload +// building job will still complete. It can be interrupted to stop filling new +// transactions with interruptBuilding. +// stopBuilding is safe to be called concurrently. +func (payload *Payload) stopBuilding() { + payload.rpcCancel() + // Concurrent Resolve calls should only stop once. + payload.stopOnce.Do(func() { + log.Debug("Stop payload building.", "id", payload.id) + close(payload.stop) + }) }   // buildPayload builds the payload according to the provided parameters. func (miner *Miner) buildPayload(args *BuildPayloadArgs, witness bool) (*Payload, error) { - // Build the initial version with no transaction included. It should be fast - // enough to run. The empty payload can at least make sure there is something - // to deliver for not missing slot. - emptyParams := &generateParams{ - timestamp: args.Timestamp, - forceTime: true, - parentHash: args.Parent, - coinbase: args.FeeRecipient, - random: args.Random, - withdrawals: args.Withdrawals, - beaconRoot: args.BeaconRoot, - noTxs: true, + if args.NoTxPool { // don't start the background payload updating job if there is no tx pool to pull from + // Build the initial version with no transaction included. It should be fast + // enough to run. The empty payload can at least make sure there is something + // to deliver for not missing slot. + // In OP-Stack, the "empty" block is constructed from provided txs only, i.e. no tx-pool usage. + emptyParams := &generateParams{ + timestamp: args.Timestamp, + forceTime: true, + parentHash: args.Parent, + coinbase: args.FeeRecipient, + random: args.Random, + withdrawals: args.Withdrawals, + beaconRoot: args.BeaconRoot, + noTxs: true, + txs: args.Transactions, + gasLimit: args.GasLimit, + eip1559Params: args.EIP1559Params, + // No RPC requests allowed. + rpcCtx: nil, + } + empty := miner.generateWork(emptyParams, witness) + if empty.err != nil { + return nil, empty.err + } + payload := newPayload(miner.lifeCtx, empty.block, empty.requests, empty.witness, args.Id()) + // make sure to make it appear as full, otherwise it will wait indefinitely for payload building to complete. + payload.full = empty.block + payload.fullFees = empty.fees + payload.cond.Broadcast() // unblocks Resolve + return payload, nil } - empty := miner.generateWork(emptyParams, witness) - if empty.err != nil { - return nil, empty.err + + fullParams := &generateParams{ + timestamp: args.Timestamp, + forceTime: true, + parentHash: args.Parent, + coinbase: args.FeeRecipient, + random: args.Random, + withdrawals: args.Withdrawals, + beaconRoot: args.BeaconRoot, + noTxs: false, + txs: args.Transactions, + gasLimit: args.GasLimit, + eip1559Params: args.EIP1559Params, } - // Construct a payload object for return. - payload := newPayload(empty.block, empty.requests, empty.witness, args.Id()) + + // Since we skip building the empty block when using the tx pool, we need to explicitly + // validate the BuildPayloadArgs here. + blockTime, err := miner.validateParams(fullParams) + if err != nil { + return nil, err + } + + payload := newPayload(miner.lifeCtx, nil, nil, nil, args.Id()) + // set shared interrupt + fullParams.interrupt = payload.interrupt + fullParams.rpcCtx = payload.rpcCtx   // Spin up a routine for updating the payload in background. This strategy // can maximum the revenue for including transactions with highest fee. @@ -235,38 +358,61 @@ // for triggering process immediately. timer := time.NewTimer(0) defer timer.Stop()   - // Setup the timer for terminating the process if SECONDS_PER_SLOT (12s in - // the Mainnet configuration) have passed since the point in time identified - // by the timestamp parameter. - endTimer := time.NewTimer(time.Second * 12) + start := time.Now() + // Setup the timer for terminating the payload building process as determined + // by validateParams. + endTimer := time.NewTimer(blockTime) + defer endTimer.Stop() + + timeout := time.Now().Add(blockTime) + + stopReason := "delivery" + defer func() { + log.Info("Stopping work on payload", + "id", payload.id, + "reason", stopReason, + "elapsed", common.PrettyDuration(time.Since(start))) + }()   - fullParams := &generateParams{ - timestamp: args.Timestamp, - forceTime: true, - parentHash: args.Parent, - coinbase: args.FeeRecipient, - random: args.Random, - withdrawals: args.Withdrawals, - beaconRoot: args.BeaconRoot, - noTxs: false, + updatePayload := func() time.Duration { + start := time.Now() + // getSealingBlock is interrupted by shared interrupt + r := miner.generateWork(fullParams, witness) + dur := time.Since(start) + // update handles error case + payload.update(r, dur) + if r.err == nil { + // after first successful pass, we're updating + fullParams.isUpdate = true + } + timer.Reset(miner.config.Recommit) + return dur }   + var lastDuration time.Duration for { select { + case <-miner.lifeCtx.Done(): + stopReason = "miner-shutdown" case <-timer.C: - start := time.Now() - r := miner.generateWork(fullParams, witness) - if r.err == nil { - payload.update(r, time.Since(start)) - } else { - log.Info("Error while generating work", "id", payload.id, "err", r.err) + // We have to prioritize the stop signal because the recommit timer + // might have fired while stop also got closed. + select { + case <-payload.stop: + return + default: } - timer.Reset(miner.config.Recommit) + // Assuming last payload building duration as lower bound for next one, + // skip new update if we're too close to the timeout anyways. + if lastDuration > 0 && time.Now().Add(lastDuration).After(timeout) { + stopReason = "near-timeout" + return + } + lastDuration = updatePayload() case <-payload.stop: - log.Info("Stopping work on payload", "id", payload.id, "reason", "delivery") return case <-endTimer.C: - log.Info("Stopping work on payload", "id", payload.id, "reason", "timeout") + stopReason = "timeout" return } }
diff --git go-ethereum/miner/payload_building_test.go op-geth/miner/payload_building_test.go index e5eb0297a155d810b4ae1ff12e21f83aaadf5577..549debdff22ddfa6b9bbaeb73658d26e4779fe09 100644 --- go-ethereum/miner/payload_building_test.go +++ op-geth/miner/payload_building_test.go @@ -17,6 +17,8 @@ package miner   import ( + "bytes" + "crypto/rand" "math/big" "reflect" "testing" @@ -27,6 +29,7 @@ "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/txpool" @@ -52,6 +55,9 @@ testUserKey, _ = crypto.GenerateKey() testUserAddress = crypto.PubkeyToAddress(testUserKey.PublicKey)   + testRecipient = common.HexToAddress("0xdeadbeef") + testTimestamp = uint64(time.Now().Unix()) + // Test transactions pendingTxs []*types.Transaction newTxs []*types.Transaction @@ -59,10 +65,14 @@ testConfig = Config{ PendingFeeRecipient: testBankAddress, Recommit: time.Second, - GasCeil: params.GenesisGasLimit, + GasCeil: 50_000_000, } )   +const ( + numDAFilterTxs = 256 +) + func init() { testTxPoolConfig = legacypool.DefaultConfig testTxPoolConfig.Journal = "" @@ -117,13 +127,17 @@ e.Authorize(testBankAddress) case *ethash.Ethash: default: t.Fatalf("unexpected consensus engine type: %T", engine) + } + if chainConfig.HoloceneTime != nil { + // genesis block extraData needs to be correct format + gspec.ExtraData = []byte{0, 0, 1, 2, 3, 4, 5, 6, 7} } chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieDirtyDisabled: true}, gspec, nil, engine, vm.Config{}, nil) if err != nil { t.Fatalf("core.NewBlockChain failed: %v", err) } pool := legacypool.New(testTxPoolConfig, chain) - txpool, _ := txpool.New(testTxPoolConfig.PriceLimit, chain, []txpool.SubPool{pool}) + txpool, _ := txpool.New(testTxPoolConfig.PriceLimit, chain, []txpool.SubPool{pool}, nil)   return &testWorkerBackend{ db: db, @@ -138,30 +152,109 @@ func (b *testWorkerBackend) TxPool() *txpool.TxPool { return b.txPool }   func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, blocks int) (*Miner, *testWorkerBackend) { backend := newTestWorkerBackend(t, chainConfig, engine, db, blocks) - backend.txPool.Add(pendingTxs, true, true) + backend.txPool.Add(pendingTxs, false, true) w := New(backend, testConfig, engine) return w, backend }   func TestBuildPayload(t *testing.T) { - var ( - db = rawdb.NewMemoryDatabase() - recipient = common.HexToAddress("0xdeadbeef") - ) - w, b := newTestWorker(t, params.TestChainConfig, ethash.NewFaker(), db, 0) + t.Run("no-tx-pool", func(t *testing.T) { testBuildPayload(t, true, false, nil) }) + // no-tx-pool case with interrupt not interesting because no-tx-pool doesn't run + // the builder routine + t.Run("with-tx-pool", func(t *testing.T) { testBuildPayload(t, false, false, nil) }) + t.Run("with-tx-pool-interrupt", func(t *testing.T) { testBuildPayload(t, false, true, nil) }) + params1559 := []byte{0, 1, 2, 3, 4, 5, 6, 7} + t.Run("with-params", func(t *testing.T) { testBuildPayload(t, false, false, params1559) }) + t.Run("with-params-no-tx-pool", func(t *testing.T) { testBuildPayload(t, true, false, params1559) }) + t.Run("with-params-interrupt", func(t *testing.T) { testBuildPayload(t, false, true, params1559) }) + + t.Run("wrong-config-no-params", func(t *testing.T) { testBuildPayloadWrongConfig(t, nil) }) + t.Run("wrong-config-params", func(t *testing.T) { testBuildPayloadWrongConfig(t, params1559) }) + + zeroParams := make([]byte, 8) + t.Run("with-zero-params", func(t *testing.T) { testBuildPayload(t, true, false, zeroParams) }) +} + +func TestDAFilters(t *testing.T) { + // Each test case inserts one pending small (DA cost 100) transaction followed by + // numDAFilterTxs transactions that have random calldata (min DA size >> 100) + totalTxs := numDAFilterTxs + 1 + + // Very low max should filter all transactions. + t.Run("with-tx-filter-max-filters-all", func(t *testing.T) { testDAFilters(t, big.NewInt(1), nil, 0) }) + t.Run("with-block-filter-max-filters-all", func(t *testing.T) { testDAFilters(t, nil, big.NewInt(1), 0) }) + // Very high max should filter nothing. + t.Run("with-tx-filter-max-too-high", func(t *testing.T) { testDAFilters(t, big.NewInt(1000000), nil, totalTxs) }) + t.Run("with-block-filter-max-too-high", func(t *testing.T) { testDAFilters(t, nil, big.NewInt(1000000), totalTxs) }) + // The first transaction has size 100, all other DA test txs are bigger due to random Data, so should get filtered. + t.Run("with-tx-filter-all-but-first", func(t *testing.T) { testDAFilters(t, big.NewInt(100), nil, 1) }) + t.Run("with-block-filter-all-but-first", func(t *testing.T) { testDAFilters(t, nil, big.NewInt(100), 1) }) + // Zero/nil values for these parameters means we should never filter + t.Run("with-zero-tx-filters", func(t *testing.T) { testDAFilters(t, big.NewInt(0), big.NewInt(0), totalTxs) }) + t.Run("with-nil-tx-filters", func(t *testing.T) { testDAFilters(t, nil, nil, totalTxs) }) +} + +func holoceneConfig() *params.ChainConfig { + config := *params.TestChainConfig + config.LondonBlock = big.NewInt(0) + t := uint64(0) + config.CanyonTime = &t + config.HoloceneTime = &t + canyonDenom := uint64(250) + config.Optimism = &params.OptimismConfig{ + EIP1559Elasticity: 6, + EIP1559Denominator: 50, + EIP1559DenominatorCanyon: &canyonDenom, + } + return &config +}   - timestamp := uint64(time.Now().Unix()) - args := &BuildPayloadArgs{ - Parent: b.chain.CurrentBlock().Hash(), - Timestamp: timestamp, - Random: common.Hash{}, - FeeRecipient: recipient, +// newPayloadArgs returns a BuildPaylooadArgs with the given parentHash and eip-1559 params, +// testTimestamp for Timestamp, and testRecipient for recipient. NoTxPool is set to true. +func newPayloadArgs(parentHash common.Hash, params1559 []byte) *BuildPayloadArgs { + return &BuildPayloadArgs{ + Parent: parentHash, + Timestamp: testTimestamp, + Random: common.Hash{}, + FeeRecipient: testRecipient, + NoTxPool: true, + EIP1559Params: params1559, } +} + +func testBuildPayload(t *testing.T, noTxPool, interrupt bool, params1559 []byte) { + t.Parallel() + db := rawdb.NewMemoryDatabase() + + config := params.TestChainConfig + if len(params1559) != 0 { + config = holoceneConfig() + } + w, b := newTestWorker(t, config, ethash.NewFaker(), db, 0) + + const numInterruptTxs = 256 + + if interrupt { + // when doing interrupt testing, create a large pool so interruption will + // definitely be visible. + txs := genTxs(1, numInterruptTxs) + b.txPool.Add(txs, false, false) + } + + args := newPayloadArgs(b.chain.CurrentBlock().Hash(), params1559) + args.NoTxPool = noTxPool + + // payload resolution now interrupts block building, so we have to + // wait for the payloading building process to build its first block payload, err := w.buildPayload(args, false) if err != nil { t.Fatalf("Failed to build payload %v", err) } verify := func(outer *engine.ExecutionPayloadEnvelope, txs int) { + t.Helper() + if outer == nil { + t.Fatal("ExecutionPayloadEnvelope is nil") + } payload := outer.ExecutionPayload if payload.ParentHash != b.chain.CurrentBlock().Hash() { t.Fatal("Unexpected parent hash") @@ -169,21 +262,51 @@ } if payload.Random != (common.Hash{}) { t.Fatal("Unexpected random value") } - if payload.Timestamp != timestamp { + if payload.Timestamp != testTimestamp { t.Fatal("Unexpected timestamp") } - if payload.FeeRecipient != recipient { + if payload.FeeRecipient != testRecipient { t.Fatal("Unexpected fee recipient") } - if len(payload.Transactions) != txs { - t.Fatal("Unexpected transaction set") + if !interrupt && len(payload.Transactions) != txs { + t.Fatalf("Unexpect transaction set: got %d, expected %d", len(payload.Transactions), txs) + } else if interrupt && len(payload.Transactions) >= txs { + t.Fatalf("Unexpect transaction set: got %d, expected less than %d", len(payload.Transactions), txs) } } - empty := payload.ResolveEmpty() - verify(empty, 0)   - full := payload.ResolveFull() - verify(full, len(pendingTxs)) + // make sure the 1559 params we've specied (if any) ends up in both the full and empty block headers + var expected []byte + if len(params1559) != 0 { + expected = []byte{0} + d, _ := eip1559.DecodeHolocene1559Params(params1559) + if d == 0 { + expected = append(expected, eip1559.EncodeHolocene1559Params(250, 6)...) // canyon defaults + } else { + expected = append(expected, params1559...) + } + } + if payload.full != nil && !bytes.Equal(payload.full.Header().Extra, expected) { + t.Fatalf("ExtraData doesn't match. want: %x, got %x", expected, payload.full.Header().Extra) + } + if payload.empty != nil && !bytes.Equal(payload.empty.Header().Extra, expected) { + t.Fatalf("ExtraData doesn't match on empty block. want: %x, got %x", expected, payload.empty.Header().Extra) + } + + if noTxPool { + // we only build the empty block when ignoring the tx pool + empty := payload.ResolveEmpty() + verify(empty, 0) + full := payload.ResolveFull() + verify(full, 0) + } else if interrupt { + full := payload.ResolveFull() + verify(full, len(pendingTxs)+numInterruptTxs) + } else { // tx-pool and no interrupt + payload.WaitFull() + full := payload.ResolveFull() + verify(full, len(pendingTxs)) + }   // Ensure resolve can be called multiple times and the // result should be unchanged @@ -192,6 +315,88 @@ dataTwo := payload.Resolve() if !reflect.DeepEqual(dataOne, dataTwo) { t.Fatal("Unexpected payload data") } +} + +func testDAFilters(t *testing.T, maxDATxSize, maxDABlockSize *big.Int, expectedTxCount int) { + t.Parallel() + db := rawdb.NewMemoryDatabase() + config := holoceneConfig() + w, b := newTestWorker(t, config, ethash.NewFaker(), db, 0) + w.SetMaxDASize(maxDATxSize, maxDABlockSize) + txs := genTxs(1, numDAFilterTxs) + b.txPool.Add(txs, false, false) + + params1559 := []byte{0, 1, 2, 3, 4, 5, 6, 7} + args := newPayloadArgs(b.chain.CurrentBlock().Hash(), params1559) + args.NoTxPool = false + + payload, err := w.buildPayload(args, false) + if err != nil { + t.Fatalf("Failed to build payload %v", err) + } + payload.WaitFull() + result := payload.ResolveFull().ExecutionPayload + if len(result.Transactions) != expectedTxCount { + t.Fatalf("Unexpected transaction set: got %d, expected %d", len(result.Transactions), expectedTxCount) + } +} + +func testBuildPayloadWrongConfig(t *testing.T, params1559 []byte) { + t.Parallel() + db := rawdb.NewMemoryDatabase() + config := holoceneConfig() + if len(params1559) != 0 { + // deactivate holocene and make sure non-empty params get rejected + config.HoloceneTime = nil + } + w, b := newTestWorker(t, config, ethash.NewFaker(), db, 0) + + args := newPayloadArgs(b.chain.CurrentBlock().Hash(), params1559) + payload, err := w.buildPayload(args, false) + if err == nil && (payload == nil || payload.err == nil) { + t.Fatalf("expected error, got none") + } +} + +func TestBuildPayloadInvalidHoloceneParams(t *testing.T) { + t.Parallel() + db := rawdb.NewMemoryDatabase() + config := holoceneConfig() + w, b := newTestWorker(t, config, ethash.NewFaker(), db, 0) + + // 0 denominators shouldn't be allowed + badParams := eip1559.EncodeHolocene1559Params(0, 6) + + args := newPayloadArgs(b.chain.CurrentBlock().Hash(), badParams) + payload, err := w.buildPayload(args, false) + if err == nil && (payload == nil || payload.err == nil) { + t.Fatalf("expected error, got none") + } +} + +func genTxs(startNonce, count uint64) types.Transactions { + txs := make(types.Transactions, 0, count) + signer := types.LatestSigner(params.TestChainConfig) + for nonce := startNonce; nonce < startNonce+count; nonce++ { + // generate incompressible data to put in the tx for DA filter testing. each of these + // txs will be bigger than the 100 minimum. + randomBytes := make([]byte, 100) + _, err := rand.Read(randomBytes) + if err != nil { + panic(err) + } + tx := types.MustSignNewTx(testBankKey, signer, &types.AccessListTx{ + ChainID: params.TestChainConfig.ChainID, + Nonce: nonce, + To: &testUserAddress, + Value: big.NewInt(1000), + Gas: params.TxGas + uint64(len(randomBytes))*16, + GasPrice: big.NewInt(params.InitialBaseFee), + Data: randomBytes, + }) + txs = append(txs, tx) + } + return txs }   func TestPayloadId(t *testing.T) {
diff --git go-ethereum/miner/worker.go op-geth/miner/worker.go index b5aa0800259123083ef7e42f65e95ea79d1c935d..cf9c1c1a7ac29e610b26a31db01170f51bc00528 100644 --- go-ethereum/miner/worker.go +++ op-geth/miner/worker.go @@ -17,6 +17,7 @@ package miner   import ( + "context" "errors" "fmt" "math/big" @@ -24,6 +25,7 @@ "sync/atomic" "time"   "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" @@ -31,16 +33,33 @@ "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/stateless" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/types/interoptypes" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" )   +const ( + // minRecommitInterruptInterval is the minimum time interval used to interrupt filling a + // sealing block with pending transactions from the mempool + minRecommitInterruptInterval = 2 * time.Second +) + var ( + errTxConditionalInvalid = errors.New("transaction conditional failed") + errBlockInterruptedByNewHead = errors.New("new head arrived while building block") errBlockInterruptedByRecommit = errors.New("recommit interrupt while building block") errBlockInterruptedByTimeout = errors.New("timeout while building block") + errBlockInterruptedByResolve = errors.New("payload resolution while building block") + + txConditionalRejectedCounter = metrics.NewRegisteredCounter("miner/transactionConditional/rejected", nil) + txConditionalMinedTimer = metrics.NewRegisteredTimer("miner/transactionConditional/elapsedtime", nil) + + txInteropRejectedCounter = metrics.NewRegisteredCounter("miner/transactionInterop/rejected", nil) )   // environment is the worker's current environment and holds all @@ -60,6 +79,9 @@ sidecars []*types.BlobTxSidecar blobs int   witness *stateless.Witness + + noTxs bool // true if we are reproducing a block, and do not have to check interop txs + rpcCtx context.Context // context to control block-building RPC work. No RPC allowed if nil. }   const ( @@ -67,6 +89,7 @@ commitInterruptNone int32 = iota commitInterruptNewHead commitInterruptResubmit commitInterruptTimeout + commitInterruptResolve )   // newPayloadResult is the result of payload generation. @@ -91,6 +114,14 @@ random common.Hash // The randomness generated by beacon chain, empty before the merge withdrawals types.Withdrawals // List of withdrawals to include in block (shanghai field) beaconRoot *common.Hash // The beacon root (cancun field). noTxs bool // Flag whether an empty block without any transaction is expected + + txs types.Transactions // Deposit transactions to include at the start of the block + gasLimit *uint64 // Optional gas limit override + eip1559Params []byte // Optional EIP-1559 parameters + interrupt *atomic.Int32 // Optional interruption signal to pass down to worker.generateWork + isUpdate bool // Optional flag indicating that this is building a discardable update + + rpcCtx context.Context // context to control block-building RPC work. No RPC allowed if nil. }   // generateWork generates a sealing block based on the given parameters. @@ -99,18 +130,52 @@ work, err := miner.prepareWork(params, witness) if err != nil { return &newPayloadResult{err: err} } + if work.gasPool == nil { + gasLimit := work.header.GasLimit + + // If we're building blocks with mempool transactions, we need to ensure that the + // gas limit is not higher than the effective gas limit. We must still accept any + // explicitly selected transactions with gas usage up to the block header's limit. + if !params.noTxs { + effectiveGasLimit := miner.config.EffectiveGasCeil + if effectiveGasLimit != 0 && effectiveGasLimit < gasLimit { + gasLimit = effectiveGasLimit + } + } + work.gasPool = new(core.GasPool).AddGas(gasLimit) + } + + misc.EnsureCreate2Deployer(miner.chainConfig, work.header.Time, work.state) + + for _, tx := range params.txs { + from, _ := types.Sender(work.signer, tx) + work.state.SetTxContext(tx.Hash(), work.tcount) + err = miner.commitTransaction(work, tx) + if err != nil { + return &newPayloadResult{err: fmt.Errorf("failed to force-include tx: %s type: %d sender: %s nonce: %d, err: %w", tx.Hash(), tx.Type(), from, tx.Nonce(), err)} + } + } if !params.noTxs { - interrupt := new(atomic.Int32) - timer := time.AfterFunc(miner.config.Recommit, func() { + // use shared interrupt if present + interrupt := params.interrupt + if interrupt == nil { + interrupt = new(atomic.Int32) + } + timer := time.AfterFunc(max(minRecommitInterruptInterval, miner.config.Recommit), func() { interrupt.Store(commitInterruptTimeout) }) - defer timer.Stop()   err := miner.fillTransactions(interrupt, work) + timer.Stop() // don't need timeout interruption any more if errors.Is(err, errBlockInterruptedByTimeout) { log.Warn("Block building is interrupted", "allowance", common.PrettyDuration(miner.config.Recommit)) + } else if errors.Is(err, errBlockInterruptedByResolve) { + log.Info("Block building got interrupted by payload resolution") } } + if intr := params.interrupt; intr != nil && params.isUpdate && intr.Load() != commitInterruptNone { + return &newPayloadResult{err: errInterruptedUpdate} + }   body := types.Body{Transactions: work.txs, Withdrawals: params.withdrawals} allLogs := make([]*types.Log, 0) @@ -131,6 +196,11 @@ core.ProcessWithdrawalQueue(&requests, work.evm) // EIP-7251 consolidations core.ProcessConsolidationQueue(&requests, work.evm) } + + if miner.chainConfig.IsIsthmus(work.header.Time) { + requests = [][]byte{} + } + if requests != nil { reqHash := types.CalcRequestsHash(requests) work.header.RequestsHash = &reqHash @@ -185,7 +255,8 @@ Time: timestamp, Coinbase: genParams.coinbase, } // Set the extra field. - if len(miner.config.ExtraData) != 0 { + if len(miner.config.ExtraData) != 0 && miner.chainConfig.Optimism == nil { + // Optimism chains have their own ExtraData handling rules header.Extra = miner.config.ExtraData } // Set the randomness field from the beacon chain if it's available. @@ -194,11 +265,32 @@ header.MixDigest = genParams.random } // Set baseFee and GasLimit if we are on an EIP-1559 chain if miner.chainConfig.IsLondon(header.Number) { - header.BaseFee = eip1559.CalcBaseFee(miner.chainConfig, parent) + header.BaseFee = eip1559.CalcBaseFee(miner.chainConfig, parent, header.Time) if !miner.chainConfig.IsLondon(parent.Number) { parentGasLimit := parent.GasLimit * miner.chainConfig.ElasticityMultiplier() header.GasLimit = core.CalcGasLimit(parentGasLimit, miner.config.GasCeil) } + } + if genParams.gasLimit != nil { // override gas limit if specified + header.GasLimit = *genParams.gasLimit + } else if miner.chain.Config().Optimism != nil && miner.config.GasCeil != 0 { + // configure the gas limit of pending blocks with the miner gas limit config when using optimism + header.GasLimit = miner.config.GasCeil + } + if miner.chainConfig.IsHolocene(header.Time) { + if err := eip1559.ValidateHolocene1559Params(genParams.eip1559Params); err != nil { + return nil, err + } + // If this is a holocene block and the params are 0, we must convert them to their previous + // constants in the header. + d, e := eip1559.DecodeHolocene1559Params(genParams.eip1559Params) + if d == 0 { + d = miner.chainConfig.BaseFeeChangeDenominator(header.Time) + e = miner.chainConfig.ElasticityMultiplier() + } + header.Extra = eip1559.EncodeHoloceneExtraData(d, e) + } else if genParams.eip1559Params != nil { + return nil, errors.New("got eip1559 params, expected none") } // Run the consensus preparation with the default or customized consensus engine. // Note that the `header.Time` may be changed. @@ -222,11 +314,12 @@ } // Could potentially happen if starting to mine in an odd state. // Note genParams.coinbase can be different with header.Coinbase // since clique algorithm can modify the coinbase field in header. - env, err := miner.makeEnv(parent, header, genParams.coinbase, witness) + env, err := miner.makeEnv(parent, header, genParams.coinbase, witness, genParams.rpcCtx) if err != nil { log.Error("Failed to create sealing context", "err", err) return nil, err } + env.noTxs = genParams.noTxs if header.ParentBeaconRoot != nil { core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, env.evm) } @@ -237,12 +330,25 @@ return env, nil }   // makeEnv creates a new environment for the sealing block. -func (miner *Miner) makeEnv(parent *types.Header, header *types.Header, coinbase common.Address, witness bool) (*environment, error) { +func (miner *Miner) makeEnv(parent *types.Header, header *types.Header, coinbase common.Address, witness bool, rpcCtx context.Context) (*environment, error) { // Retrieve the parent state to execute on top. state, err := miner.chain.StateAt(parent.Root) if err != nil { return nil, err } + if miner.chainConfig.Optimism != nil { // Allow the miner to reorg its own chain arbitrarily deep + if historicalBackend, ok := miner.backend.(BackendWithHistoricalState); ok { + var release tracers.StateReleaseFunc + parentBlock := miner.backend.BlockChain().GetBlockByHash(parent.Hash()) + state, release, err = historicalBackend.StateAtBlock(context.Background(), parentBlock, ^uint64(0), nil, false, false) + if err != nil { + return nil, err + } + state = state.Copy() + release() + } + } + if witness { bundle, err := stateless.NewWitness(header, miner.chain) if err != nil { @@ -257,7 +363,8 @@ state: state, coinbase: coinbase, header: header, witness: state.Witness(), - evm: vm.NewEVM(core.NewEVMBlockContext(header, miner.chain, &coinbase), state, miner.chainConfig, vm.Config{}), + evm: vm.NewEVM(core.NewEVMBlockContext(header, miner.chain, &coinbase, miner.chainConfig, state), state, miner.chainConfig, vm.Config{}), + rpcCtx: rpcCtx, }, nil }   @@ -265,6 +372,20 @@ func (miner *Miner) commitTransaction(env *environment, tx *types.Transaction) error { if tx.Type() == types.BlobTxType { return miner.commitBlobTransaction(env, tx) } + + // If a conditional is set, check prior to applying + if conditional := tx.Conditional(); conditional != nil { + txConditionalMinedTimer.UpdateSince(tx.Time()) + + // check the conditional + if err := env.header.CheckTransactionConditional(conditional); err != nil { + return fmt.Errorf("failed header check: %s: %w", err, errTxConditionalInvalid) + } + if err := env.state.CheckTransactionConditional(conditional); err != nil { + return fmt.Errorf("failed state check: %s: %w", err, errTxConditionalInvalid) + } + } + receipt, err := miner.applyTransaction(env, tx) if err != nil { return err @@ -300,13 +421,37 @@ env.tcount++ return nil }   +type LogInspector interface { + GetLogs(hash common.Hash, blockNumber uint64, blockHash common.Hash) []*types.Log +} + // applyTransaction runs the transaction. If execution fails, state and gas pool are reverted. func (miner *Miner) applyTransaction(env *environment, tx *types.Transaction) (*types.Receipt, error) { var ( snap = env.state.Snapshot() gp = env.gasPool.Gas() ) - receipt, err := core.ApplyTransaction(env.evm, env.gasPool, env.state, env.header, tx, &env.header.GasUsed) + var extraOpts *core.ApplyTransactionOpts + // If not just reproducing the block, check the interop executing messages. + if !env.noTxs && miner.chain.Config().IsInterop(env.header.Time) { + // Whenever there are `noTxs` it means we are building a block from pre-determined txs. There are two cases: + // (1) it's derived from L1, and will be verified asynchronously by the op-node. + // (2) it is a deposits-only empty-block by the sequencer, in which case there are no interop-txs to verify (as deposits do not emit any). + + // We have to insert as call-back, since we cannot revert the snapshot + // after the tx is deemed successful and the journal has been cleared already. + extraOpts = &core.ApplyTransactionOpts{ + PostValidation: func(evm *vm.EVM, result *core.ExecutionResult) error { + logInspector, ok := evm.StateDB.(LogInspector) + if !ok { + return fmt.Errorf("cannot get logs from StateDB type %T", evm.StateDB) + } + logs := logInspector.GetLogs(tx.Hash(), env.header.Number.Uint64(), common.Hash{}) + return miner.checkInterop(env.rpcCtx, tx, result.Failed(), logs) + }, + } + } + receipt, err := core.ApplyTransactionExtended(env.evm, env.gasPool, env.state, env.header, tx, &env.header.GasUsed, extraOpts) if err != nil { env.state.RevertToSnapshot(snap) env.gasPool.SetGas(gp) @@ -314,11 +459,48 @@ } return receipt, err }   +func (miner *Miner) checkInterop(ctx context.Context, tx *types.Transaction, failed bool, logs []*types.Log) error { + if tx.Type() == types.DepositTxType { + return nil // deposit-txs are always safe + } + if failed { + return nil // failed txs don't persist any logs + } + if tx.Rejected() { + return errors.New("transaction was previously rejected") + } + b, ok := miner.backend.(BackendWithInterop) + if !ok { + return fmt.Errorf("cannot mine interop txs without interop backend, got backend type %T", miner.backend) + } + if ctx == nil { // check if the miner was set up correctly to interact with an RPC + return errors.New("need RPC context to check executing messages") + } + executingMessages, err := interoptypes.ExecutingMessagesFromLogs(logs) + if err != nil { + return fmt.Errorf("cannot parse interop messages from receipt of %s: %w", tx.Hash(), err) + } + if len(executingMessages) == 0 { + return nil // avoid an RPC check if there are no executing messages to verify. + } + if err := b.CheckMessages(ctx, executingMessages, interoptypes.CrossUnsafe); err != nil { + if ctx.Err() != nil { // don't reject transactions permanently on RPC timeouts etc. + log.Debug("CheckMessages timed out", "err", ctx.Err()) + return err + } + txInteropRejectedCounter.Inc(1) + tx.SetRejected() // Mark the tx as rejected: it will not be welcome in the tx-pool anymore. + return err + } + return nil +} + func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *transactionsByPriceAndNonce, interrupt *atomic.Int32) error { gasLimit := env.header.GasLimit if env.gasPool == nil { env.gasPool = new(core.GasPool).AddGas(gasLimit) } + blockDABytes := new(big.Int) for { // Check interruption signal and abort building if it's fired. if interrupt != nil { @@ -372,6 +554,22 @@ log.Trace("Not enough blob gas left for transaction", "hash", ltx.Hash, "left", left, "needed", ltx.BlobGas) txs.Pop() continue } + daBytesAfter := new(big.Int) + if ltx.DABytes != nil && miner.config.MaxDABlockSize != nil { + daBytesAfter.Add(blockDABytes, ltx.DABytes) + if daBytesAfter.Cmp(miner.config.MaxDABlockSize) > 0 { + log.Debug("adding tx would exceed block DA size limit", + "hash", ltx.Hash, "txda", ltx.DABytes, "blockda", blockDABytes, "dalimit", miner.config.MaxDABlockSize) + txs.Pop() + // If the number of remaining bytes is too few to hold even the minimum possible transaction size, + // then we can stop early. + daBytesRemaining := new(big.Int).Sub(miner.config.MaxDABlockSize, daBytesAfter) + if daBytesRemaining.Cmp(types.MinTransactionSize) < 0 { + break + } + continue + } + } // Transaction seems to fit, pull it up from the pool tx := ltx.Resolve() if tx == nil { @@ -400,8 +598,26 @@ // New head notification data race between the transaction pool and miner, shift log.Trace("Skipping transaction with low nonce", "hash", ltx.Hash, "sender", from, "nonce", tx.Nonce()) txs.Shift()   + case errors.Is(err, errTxConditionalInvalid): + // err contains contextual info on the failed conditional. + txConditionalRejectedCounter.Inc(1) + + // mark as rejected so that it can be ejected from the mempool + tx.SetRejected() + log.Warn("Skipping account, transaction with failed conditional", "sender", from, "hash", ltx.Hash, "err", err) + txs.Pop() + + case env.rpcCtx != nil && env.rpcCtx.Err() != nil && errors.Is(err, env.rpcCtx.Err()): + log.Warn("Transaction processing aborted due to RPC context error", "err", err) + txs.Pop() // RPC timeout. Tx could not be checked, and thus not included, but not rejected yet. + + case err != nil && tx.Rejected(): + log.Warn("Transaction was rejected during block-building", "hash", ltx.Hash, "err", err) + txs.Pop() + case errors.Is(err, nil): // Everything ok, collect the logs and shift in the next transaction from the same account + blockDABytes = daBytesAfter txs.Shift()   default: @@ -424,7 +640,8 @@ miner.confMu.RUnlock()   // Retrieve the pending transactions pre-filtered by the 1559/4844 dynamic fees filter := txpool.PendingFilter{ - MinTip: uint256.MustFromBig(tip), + MinTip: uint256.MustFromBig(tip), + MaxDATxSize: miner.config.MaxDATxSize, } if env.header.BaseFee != nil { filter.BaseFee = uint256.MustFromBig(env.header.BaseFee) @@ -492,7 +709,41 @@ case commitInterruptResubmit: return errBlockInterruptedByRecommit case commitInterruptTimeout: return errBlockInterruptedByTimeout + case commitInterruptResolve: + return errBlockInterruptedByResolve default: panic(fmt.Errorf("undefined signal %d", signal)) } } + +// validateParams validates the given parameters. +// It currently checks that the parent block is known and that the timestamp is valid, +// i.e., after the parent block's timestamp. +// It returns an upper bound of the payload building duration as computed +// by the difference in block timestamps between the parent and genParams. +func (miner *Miner) validateParams(genParams *generateParams) (time.Duration, error) { + miner.confMu.RLock() + defer miner.confMu.RUnlock() + + // Find the parent block for sealing task + parent := miner.chain.CurrentBlock() + if genParams.parentHash != (common.Hash{}) { + block := miner.chain.GetBlockByHash(genParams.parentHash) + if block == nil { + return 0, fmt.Errorf("missing parent %v", genParams.parentHash) + } + parent = block.Header() + } + + // Sanity check the timestamp correctness + blockTime := int64(genParams.timestamp) - int64(parent.Time) + if blockTime <= 0 && genParams.forceTime { + return 0, fmt.Errorf("invalid timestamp, parent %d given %d", parent.Time, genParams.timestamp) + } + + // minimum payload build time of 2s + if blockTime < 2 { + blockTime = 2 + } + return time.Duration(blockTime) * time.Second, nil +}

Transaction queueing and inclusion needs to account for the L1 cost component.

diff --git go-ethereum/core/txpool/blobpool/blobpool.go op-geth/core/txpool/blobpool/blobpool.go index 4ab14bbcc09b66c0961ece017afd4b74b850e86d..1017c966cbce077062cb4541f7799b16607bd5ab 100644 --- go-ethereum/core/txpool/blobpool/blobpool.go +++ op-geth/core/txpool/blobpool/blobpool.go @@ -410,7 +410,7 @@ for addr := range p.index { p.recheck(addr, nil) } var ( - basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head)) + basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head, p.head.Time+1)) blobfee = uint256.NewInt(params.BlobTxMinBlobGasprice) ) if p.head.ExcessBlobGas != nil { @@ -830,7 +830,7 @@ p.limbo.finalize(p.chain.CurrentFinalBlock()) } // Reset the price heap for the new set of basefee/blobfee pairs var ( - basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), newHead)) + basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), newHead, newHead.Time+1)) blobfee = uint256.MustFromBig(big.NewInt(params.BlobTxMinBlobGasprice)) ) if newHead.ExcessBlobGas != nil { @@ -1759,7 +1759,7 @@ p.index = make(map[common.Address][]*blobTxMeta) p.spent = make(map[common.Address]*uint256.Int)   var ( - basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head)) + basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head, p.head.Time)) blobfee = uint256.NewInt(params.BlobTxMinBlobGasprice) ) p.evict = newPriceHeap(basefee, blobfee, p.index)
diff --git go-ethereum/core/txpool/blobpool/blobpool_test.go op-geth/core/txpool/blobpool/blobpool_test.go index 3d90ec44126996fb62d0087562866229a1be92c1..cb553f3b894aa7c043323aa4beeffc6e96eb2c2d 100644 --- go-ethereum/core/txpool/blobpool/blobpool_test.go +++ op-geth/core/txpool/blobpool/blobpool_test.go @@ -104,7 +104,7 @@ Number: blockNumber, GasLimit: gasLimit, GasUsed: 0, BaseFee: mid, - }).Cmp(bc.basefee.ToBig()) > 0 { + }, blockTime).Cmp(bc.basefee.ToBig()) > 0 { hi = mid } else { lo = mid
diff --git go-ethereum/core/txpool/ingress_filters.go op-geth/core/txpool/ingress_filters.go new file mode 100644 index 0000000000000000000000000000000000000000..d911b6975897eb62f9f522182c59d9d3b3ea3399 --- /dev/null +++ op-geth/core/txpool/ingress_filters.go @@ -0,0 +1,59 @@ +package txpool + +import ( + "context" + "time" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/types/interoptypes" + "github.com/ethereum/go-ethereum/log" +) + +// IngressFilter is an interface that allows filtering of transactions before they are added to the transaction pool. +// Implementations of this interface can be used to filter transactions based on various criteria. +// FilterTx will return true if the transaction should be allowed, and false if it should be rejected. +type IngressFilter interface { + FilterTx(ctx context.Context, tx *types.Transaction) bool +} + +type interopFilter struct { + logsFn func(tx *types.Transaction) ([]*types.Log, error) + checkFn func(ctx context.Context, ems []interoptypes.Message, safety interoptypes.SafetyLevel) error +} + +func NewInteropFilter( + logsFn func(tx *types.Transaction) ([]*types.Log, error), + checkFn func(ctx context.Context, ems []interoptypes.Message, safety interoptypes.SafetyLevel) error) IngressFilter { + return &interopFilter{ + logsFn: logsFn, + checkFn: checkFn, + } +} + +// FilterTx implements IngressFilter.FilterTx +// it gets logs checks for message safety based on the function provided +func (f *interopFilter) FilterTx(ctx context.Context, tx *types.Transaction) bool { + logs, err := f.logsFn(tx) + if err != nil { + log.Debug("Failed to retrieve logs of tx", "txHash", tx.Hash(), "err", err) + return false // default to deny if logs cannot be retrieved + } + if len(logs) == 0 { + return true // default to allow if there are no logs + } + ems, err := interoptypes.ExecutingMessagesFromLogs(logs) + if err != nil { + log.Debug("Failed to parse executing messages of tx", "txHash", tx.Hash(), "err", err) + return false // default to deny if logs cannot be parsed + } + if len(ems) == 0 { + return true // default to allow if there are no executing messages + } + + ctx, cancel := context.WithTimeout(ctx, time.Second*2) + defer cancel() + // check with the supervisor if the transaction should be allowed given the executing messages + // the message can be unsafe (discovered only via P2P unsafe blocks), but it must be cross-valid + // so CrossUnsafe is used here + return f.checkFn(ctx, ems, interoptypes.CrossUnsafe) == nil +}
diff --git go-ethereum/core/txpool/ingress_filters_test.go op-geth/core/txpool/ingress_filters_test.go new file mode 100644 index 0000000000000000000000000000000000000000..b2fcfd9018768560d3469c4421f4ccd4298a36a1 --- /dev/null +++ op-geth/core/txpool/ingress_filters_test.go @@ -0,0 +1,188 @@ +package txpool + +import ( + "context" + "errors" + "math/big" + "net" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/types/interoptypes" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/require" +) + +func TestInteropFilter(t *testing.T) { + // some placeholder transaction to test with + tx := types.NewTx(&types.DynamicFeeTx{ + ChainID: big.NewInt(1), + Nonce: 1, + To: &common.Address{}, + Value: big.NewInt(1), + Data: []byte{}, + }) + t.Run("Tx has no logs", func(t *testing.T) { + logFn := func(tx *types.Transaction) ([]*types.Log, error) { + return []*types.Log{}, nil + } + checkFn := func(ctx context.Context, ems []interoptypes.Message, safety interoptypes.SafetyLevel) error { + // make this return error, but it won't be called because logs are empty + return errors.New("error") + } + // when there are no logs to process, the transaction should be allowed + filter := NewInteropFilter(logFn, checkFn) + require.True(t, filter.FilterTx(context.Background(), tx)) + }) + t.Run("Tx errored when getting logs", func(t *testing.T) { + logFn := func(tx *types.Transaction) ([]*types.Log, error) { + return []*types.Log{}, errors.New("error") + } + checkFn := func(ctx context.Context, ems []interoptypes.Message, safety interoptypes.SafetyLevel) error { + // make this return error, but it won't be called because logs retrieval errored + return errors.New("error") + } + // when log retrieval errors, the transaction should be denied + filter := NewInteropFilter(logFn, checkFn) + require.False(t, filter.FilterTx(context.Background(), tx)) + }) + t.Run("Tx has no executing messages", func(t *testing.T) { + logFn := func(tx *types.Transaction) ([]*types.Log, error) { + l1 := &types.Log{ + Topics: []common.Hash{common.BytesToHash([]byte("topic1"))}, + } + return []*types.Log{l1}, nil + } + checkFn := func(ctx context.Context, ems []interoptypes.Message, safety interoptypes.SafetyLevel) error { + // make this return error, but it won't be called because logs retrieval doesn't have executing messages + return errors.New("error") + } + // when no executing messages are included, the transaction should be allowed + filter := NewInteropFilter(logFn, checkFn) + require.True(t, filter.FilterTx(context.Background(), tx)) + }) + t.Run("Tx has valid executing message", func(t *testing.T) { + // build a basic executing message + // the executing message must pass basic decode validation, + // but the validity check is done by the checkFn + l1 := &types.Log{ + Address: params.InteropCrossL2InboxAddress, + Topics: []common.Hash{ + common.BytesToHash(interoptypes.ExecutingMessageEventTopic[:]), + common.BytesToHash([]byte("payloadHash")), + }, + Data: []byte{}, + } + // using all 0s for data allows all takeZeros to pass + for i := 0; i < 32*5; i++ { + l1.Data = append(l1.Data, 0) + } + logFn := func(tx *types.Transaction) ([]*types.Log, error) { + return []*types.Log{l1}, nil + } + var spyEMs []interoptypes.Message + checkFn := func(ctx context.Context, ems []interoptypes.Message, safety interoptypes.SafetyLevel) error { + spyEMs = ems + return nil + } + // when there is one executing message, the transaction should be allowed + // if the checkFn returns nil + filter := NewInteropFilter(logFn, checkFn) + require.True(t, filter.FilterTx(context.Background(), tx)) + // confirm that one executing message was passed to the checkFn + require.Equal(t, 1, len(spyEMs)) + }) + t.Run("Tx has invalid executing message", func(t *testing.T) { + // build a basic executing message + // the executing message must pass basic decode validation, + // but the validity check is done by the checkFn + l1 := &types.Log{ + Address: params.InteropCrossL2InboxAddress, + Topics: []common.Hash{ + common.BytesToHash(interoptypes.ExecutingMessageEventTopic[:]), + common.BytesToHash([]byte("payloadHash")), + }, + Data: []byte{}, + } + // using all 0s for data allows all takeZeros to pass + for i := 0; i < 32*5; i++ { + l1.Data = append(l1.Data, 0) + } + logFn := func(tx *types.Transaction) ([]*types.Log, error) { + return []*types.Log{l1}, nil + } + var spyEMs []interoptypes.Message + checkFn := func(ctx context.Context, ems []interoptypes.Message, safety interoptypes.SafetyLevel) error { + spyEMs = ems + return errors.New("error") + } + // when there is one executing message, and the checkFn returns an error, + // (ie the supervisor rejects the transaction) the transaction should be denied + filter := NewInteropFilter(logFn, checkFn) + require.False(t, filter.FilterTx(context.Background(), tx)) + // confirm that one executing message was passed to the checkFn + require.Equal(t, 1, len(spyEMs)) + }) +} + +func TestInteropFilterRPCFailures(t *testing.T) { + tests := []struct { + name string + networkErr bool + timeout bool + invalidResp bool + }{ + { + name: "Network Error", + networkErr: true, + }, + { + name: "Timeout", + timeout: true, + }, + { + name: "Invalid Response", + invalidResp: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create mock log function that always returns our test log + logFn := func(tx *types.Transaction) ([]*types.Log, error) { + log := &types.Log{ + Address: params.InteropCrossL2InboxAddress, + Topics: []common.Hash{ + common.BytesToHash(interoptypes.ExecutingMessageEventTopic[:]), + common.BytesToHash([]byte("payloadHash")), + }, + Data: make([]byte, 32*5), + } + return []*types.Log{log}, nil + } + + // Create mock check function that simulates RPC failures + checkFn := func(ctx context.Context, ems []interoptypes.Message, safety interoptypes.SafetyLevel) error { + if tt.networkErr { + return &net.OpError{Op: "dial", Err: errors.New("connection refused")} + } + + if tt.timeout { + return context.DeadlineExceeded + } + + if tt.invalidResp { + return errors.New("invalid response format") + } + + return nil + } + + // Create and test filter + filter := NewInteropFilter(logFn, checkFn) + result := filter.FilterTx(context.Background(), &types.Transaction{}) + require.Equal(t, false, result, "FilterTx result mismatch") + }) + } +}
diff --git go-ethereum/core/txpool/legacypool/legacypool.go op-geth/core/txpool/legacypool/legacypool.go index 3d780ad3739c3d14aaf2bae7de7063bc56b2fc5c..efbd6a49c84e431dabf02cef7a447dda94b6aca5 100644 --- go-ethereum/core/txpool/legacypool/legacypool.go +++ op-geth/core/txpool/legacypool/legacypool.go @@ -128,6 +128,10 @@ NoLocals bool // Whether local transaction handling should be disabled Journal string // Journal of local transactions to survive node restarts Rejournal time.Duration // Time interval to regenerate the local transaction journal   + // JournalRemote controls whether journaling includes remote transactions or not. + // When true, all transactions loaded from the journal are treated as remote. + JournalRemote bool + PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool PriceBump uint64 // Minimum price bump percentage to replace an already existing transaction (nonce)   @@ -137,6 +141,8 @@ AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts   Lifetime time.Duration // Maximum amount of time non-executable transaction are queued + + EffectiveGasCeil uint64 // if non-zero, a gas ceiling to enforce independent of the header's gaslimit value }   // DefaultConfig contains the default configurations for the transaction pool. @@ -233,6 +239,8 @@ wg sync.WaitGroup // tracks loop, scheduleReorgLoop initDoneCh chan struct{} // is closed once the pool is initialized (for tests)   changesSinceReorg int // A counter for how many drops we've performed in-between reorg. + + l1CostFn txpool.L1CostFunc // To apply L1 costs as rollup, optional field, may be nil. }   type txpoolResetRequest struct { @@ -269,7 +277,7 @@ pool.locals.add(addr) } pool.priced = newPricedList(pool.all)   - if !config.NoLocals && config.Journal != "" { + if (!config.NoLocals || config.JournalRemote) && config.Journal != "" { pool.journal = newTxJournal(config.Journal) } return pool @@ -318,10 +326,14 @@ go pool.scheduleReorgLoop()   // If local transactions and journaling is enabled, load from disk if pool.journal != nil { - if err := pool.journal.load(pool.addLocals); err != nil { + add := pool.addLocals + if pool.config.JournalRemote { + add = pool.addRemotesSync // Use sync version to match pool.AddLocals + } + if err := pool.journal.load(add); err != nil { log.Warn("Failed to load transaction journal", "err", err) } - if err := pool.journal.rotate(pool.local()); err != nil { + if err := pool.journal.rotate(pool.toJournal()); err != nil { log.Warn("Failed to rotate transaction journal", "err", err) } } @@ -391,7 +403,7 @@ // Handle local transaction journal rotation case <-journal.C: if pool.journal != nil { pool.mu.Lock() - if err := pool.journal.rotate(pool.local()); err != nil { + if err := pool.journal.rotate(pool.toJournal()); err != nil { log.Warn("Failed to rotate local tx journal", "err", err) } pool.mu.Unlock() @@ -552,6 +564,17 @@ // If the miner requests tip enforcement, cap the lists now if minTipBig != nil && !pool.locals.contains(addr) { for i, tx := range txs { if tx.EffectiveGasTipIntCmp(minTipBig, baseFeeBig) < 0 { + txs = txs[:i] + break + } + } + } + if filter.MaxDATxSize != nil && !pool.locals.contains(addr) { + for i, tx := range txs { + estimate := tx.RollupCostData().EstimatedDASize() + if estimate.Cmp(filter.MaxDATxSize) > 0 { + log.Debug("filtering tx that exceeds max da tx size", + "hash", tx.Hash(), "txda", estimate, "dalimit", filter.MaxDATxSize) txs = txs[:i] break } @@ -560,6 +583,7 @@ } if len(txs) > 0 { lazies := make([]*txpool.LazyTransaction, len(txs)) for i := 0; i < len(txs); i++ { + daBytes := txs[i].RollupCostData().EstimatedDASize() lazies[i] = &txpool.LazyTransaction{ Pool: pool, Hash: txs[i].Hash(), @@ -569,6 +593,7 @@ GasFeeCap: uint256.MustFromBig(txs[i].GasFeeCap()), GasTipCap: uint256.MustFromBig(txs[i].GasTipCap()), Gas: txs[i].Gas(), BlobGas: txs[i].BlobGas(), + DABytes: daBytes, } } pending[addr] = lazies @@ -585,6 +610,23 @@ return pool.locals.flatten() }   +// toJournal retrieves all transactions that should be included in the journal, +// grouped by origin account and sorted by nonce. +// The returned transaction set is a copy and can be freely modified by calling code. +func (pool *LegacyPool) toJournal() map[common.Address]types.Transactions { + if !pool.config.JournalRemote { + return pool.local() + } + txs := make(map[common.Address]types.Transactions) + for addr, pending := range pool.pending { + txs[addr] = append(txs[addr], pending.Flatten()...) + } + for addr, queued := range pool.queue { + txs[addr] = append(txs[addr], queued.Flatten()...) + } + return txs +} + // local retrieves all currently known local transactions, grouped by origin // account and sorted by nonce. The returned transaction set is a copy and can be // freely modified by calling code. @@ -612,8 +654,9 @@ Accept: 0 | 1<<types.LegacyTxType | 1<<types.AccessListTxType | 1<<types.DynamicFeeTxType, - MaxSize: txMaxSize, - MinTip: pool.gasTip.Load().ToBig(), + MaxSize: txMaxSize, + MinTip: pool.gasTip.Load().ToBig(), + EffectiveGasCeil: pool.config.EffectiveGasCeil, } if local { opts.MinTip = new(big.Int) @@ -650,11 +693,18 @@ }, ExistingCost: func(addr common.Address, nonce uint64) *big.Int { if list := pool.pending[addr]; list != nil { if tx := list.txs.Get(nonce); tx != nil { - return tx.Cost() + cost := tx.Cost() + if pool.l1CostFn != nil { + if l1Cost := pool.l1CostFn(tx.RollupCostData()); l1Cost != nil { // add rollup cost + cost = cost.Add(cost, l1Cost) + } + } + return cost } } return nil }, + L1CostFn: pool.l1CostFn, } if err := txpool.ValidateTransactionWithState(tx, pool.signer, opts); err != nil { return err @@ -777,7 +827,7 @@ // Try to replace an existing transaction in the pending pool if list := pool.pending[from]; list != nil && list.Contains(tx.Nonce()) { // Nonce already pending, check if required price bump is met - inserted, old := list.Add(tx, pool.config.PriceBump) + inserted, old := list.Add(tx, pool.config.PriceBump, pool.l1CostFn) if !inserted { pendingDiscardMeter.Mark(1) return false, txpool.ErrReplaceUnderpriced @@ -851,7 +901,7 @@ from, _ := types.Sender(pool.signer, tx) // already validated if pool.queue[from] == nil { pool.queue[from] = newList(false) } - inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump) + inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump, pool.l1CostFn) if !inserted { // An older transaction was better, discard this queuedDiscardMeter.Mark(1) @@ -886,7 +936,7 @@ // journalTx adds the specified transaction to the local disk journal if it is // deemed to have been sent from a local account. func (pool *LegacyPool) journalTx(from common.Address, tx *types.Transaction) { // Only journal if it's enabled and the transaction is local - if pool.journal == nil || !pool.locals.contains(from) { + if pool.journal == nil || (!pool.config.JournalRemote && !pool.locals.contains(from)) { return } if err := pool.journal.insert(tx); err != nil { @@ -905,7 +955,7 @@ pool.pending[addr] = newList(true) } list := pool.pending[addr]   - inserted, old := list.Add(tx, pool.config.PriceBump) + inserted, old := list.Add(tx, pool.config.PriceBump, pool.l1CostFn) if !inserted { // An older transaction was better, discard this pool.all.Remove(hash) @@ -1306,7 +1356,7 @@ if reset != nil { pool.demoteUnexecutables() if reset.newHead != nil { if pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) { - pendingBaseFee := eip1559.CalcBaseFee(pool.chainconfig, reset.newHead) + pendingBaseFee := eip1559.CalcBaseFee(pool.chainconfig, reset.newHead, reset.newHead.Time+1) pool.priced.SetBaseFee(pendingBaseFee) } else { pool.priced.Reheap() @@ -1438,12 +1488,36 @@ pool.currentHead.Store(newHead) pool.currentState = statedb pool.pendingNonces = newNoncer(statedb)   + if costFn := types.NewL1CostFunc(pool.chainconfig, statedb); costFn != nil { + pool.l1CostFn = func(rollupCostData types.RollupCostData) *big.Int { + return costFn(rollupCostData, newHead.Time) + } + } + // Inject any transactions discarded due to reorgs log.Debug("Reinjecting stale transactions", "count", len(reinject)) core.SenderCacher().Recover(pool.signer, reinject) pool.addTxsLocked(reinject, false) }   +// reduceBalanceByL1Cost returns the given balance, reduced by the L1Cost of the first transaction in list if applicable +// Other txs will get filtered out necessary. +func (pool *LegacyPool) reduceBalanceByL1Cost(list *list, balance *uint256.Int) *uint256.Int { + if !list.Empty() && pool.l1CostFn != nil { + el := list.txs.FirstElement() + if l1Cost := pool.l1CostFn(el.RollupCostData()); l1Cost != nil { + l1Cost256 := uint256.MustFromBig(l1Cost) + if l1Cost256.Cmp(balance) >= 0 { + // Avoid underflow + balance = uint256.NewInt(0) + } else { + balance = new(uint256.Int).Sub(balance, l1Cost256) + } + } + } + return balance +} + // promoteExecutables moves transactions that have become processable from the // future queue to the set of pending transactions. During this process, all // invalidated transactions (low nonce, low balance) are deleted. @@ -1452,7 +1526,7 @@ // Track the promoted transactions to broadcast them at once var promoted []*types.Transaction   // Iterate over all accounts and promote any executable transactions - gasLimit := pool.currentHead.Load().GasLimit + gasLimit := txpool.EffectiveGasLimit(pool.chainconfig, pool.currentHead.Load().GasLimit, pool.config.EffectiveGasCeil) for _, addr := range accounts { list := pool.queue[addr] if list == nil { @@ -1465,8 +1539,10 @@ hash := tx.Hash() pool.all.Remove(hash) } log.Trace("Removed old queued transactions", "count", len(forwards)) + balance := pool.currentState.GetBalance(addr) + balance = pool.reduceBalanceByL1Cost(list, balance) // Drop all transactions that are too costly (low balance or out of gas) - drops, _ := list.Filter(pool.currentState.GetBalance(addr), gasLimit) + drops, _ := list.Filter(balance, gasLimit) for _, tx := range drops { hash := tx.Hash() pool.all.Remove(hash) @@ -1655,7 +1731,7 @@ // is always explicitly triggered by SetBaseFee and it would be unnecessary and wasteful // to trigger a re-heap is this function func (pool *LegacyPool) demoteUnexecutables() { // Iterate over all accounts and demote any non-executable transactions - gasLimit := pool.currentHead.Load().GasLimit + gasLimit := txpool.EffectiveGasLimit(pool.chainconfig, pool.currentHead.Load().GasLimit, pool.config.EffectiveGasCeil) for addr, list := range pool.pending { nonce := pool.currentState.GetNonce(addr)   @@ -1666,8 +1742,10 @@ hash := tx.Hash() pool.all.Remove(hash) log.Trace("Removed old pending transaction", "hash", hash) } + balance := pool.currentState.GetBalance(addr) + balance = pool.reduceBalanceByL1Cost(list, balance) // Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later - drops, invalids := list.Filter(pool.currentState.GetBalance(addr), gasLimit) + drops, invalids := list.Filter(balance, gasLimit) for _, tx := range drops { hash := tx.Hash() log.Trace("Removed unpayable pending transaction", "hash", hash) @@ -1675,6 +1753,16 @@ pool.all.Remove(hash) } pendingNofundsMeter.Mark(int64(len(drops)))   + // Drop all transactions that were rejected by the miner + rejectedDrops := list.txs.Filter(func(tx *types.Transaction) bool { + return tx.Rejected() + }) + for _, tx := range rejectedDrops { + hash := tx.Hash() + pool.all.Remove(hash) + log.Trace("Removed rejected transaction", "hash", hash) + } + for _, tx := range invalids { hash := tx.Hash() log.Trace("Demoting pending transaction", "hash", hash) @@ -1682,9 +1770,9 @@ // Internal shuffle shouldn't touch the lookup set. pool.enqueueTx(hash, tx, false, false) } - pendingGauge.Dec(int64(len(olds) + len(drops) + len(invalids))) + pendingGauge.Dec(int64(len(olds) + len(drops) + len(invalids) + len(rejectedDrops))) if pool.locals.contains(addr) { - localGauge.Dec(int64(len(olds) + len(drops) + len(invalids))) + localGauge.Dec(int64(len(olds) + len(drops) + len(invalids) + len(rejectedDrops))) } // If there's a gap in front, alert (should never happen) and postpone all transactions if list.Len() > 0 && list.txs.Get(nonce) == nil {
diff --git go-ethereum/core/txpool/legacypool/legacypool_test.go op-geth/core/txpool/legacypool/legacypool_test.go index abbde8cae3fb323fa8fd22cff8659dcd261e2e11..be04b5c94cf9eef0420d2c59d04ce7c225ae59ef 100644 --- go-ethereum/core/txpool/legacypool/legacypool_test.go +++ op-geth/core/txpool/legacypool/legacypool_test.go @@ -86,7 +86,7 @@ } }   func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { - return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil)) + return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil), bc.config) }   func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { @@ -686,6 +686,39 @@ t.Errorf("over-gased queued transaction present: %v", tx11) } if pool.all.Count() != 2 { t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 2) + } +} + +// Tests that transactions marked as reject (by the miner in practice) +// are removed from the pool +func TestRejectedDropping(t *testing.T) { + t.Parallel() + + pool, key := setupPool() + defer pool.Close() + + account := crypto.PubkeyToAddress(key.PublicKey) + testAddBalance(pool, account, big.NewInt(1000)) + + // create some txs. tx0 has a conditional + tx0, tx1 := transaction(0, 100, key), transaction(1, 200, key) + + pool.all.Add(tx0, false) + pool.all.Add(tx1, false) + pool.promoteTx(account, tx0.Hash(), tx0) + pool.promoteTx(account, tx1.Hash(), tx1) + + // pool state is unchanged + <-pool.requestReset(nil, nil) + if pool.all.Count() != 2 { + t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 2) + } + + // tx0 conditional is marked as rejected and should be removed + tx0.SetRejected() + <-pool.requestReset(nil, nil) + if pool.all.Count() != 1 { + t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 1) } }   @@ -2338,10 +2371,13 @@ }   // Tests that local transactions are journaled to disk, but remote transactions // get discarded between restarts. -func TestJournaling(t *testing.T) { testJournaling(t, false) } -func TestJournalingNoLocals(t *testing.T) { testJournaling(t, true) } +func TestJournaling(t *testing.T) { testJournaling(t, false, false) } +func TestJournalingNoLocals(t *testing.T) { testJournaling(t, true, false) } + +func TestJournalingRemotes(t *testing.T) { testJournaling(t, false, true) } +func TestJournalingRemotesNoLocals(t *testing.T) { testJournaling(t, true, true) }   -func testJournaling(t *testing.T, nolocals bool) { +func testJournaling(t *testing.T, nolocals bool, journalRemotes bool) { t.Parallel()   // Create a temporary file for the journal @@ -2362,6 +2398,7 @@ blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))   config := testTxPoolConfig config.NoLocals = nolocals + config.JournalRemote = journalRemotes config.Journal = journal config.Rejournal = time.Second   @@ -2410,10 +2447,14 @@ pending, queued = pool.Stats() if queued != 0 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) } - if nolocals { + if nolocals && !journalRemotes { if pending != 0 { t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) } + } else if journalRemotes { + if pending != 3 { + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) + } } else { if pending != 2 { t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) @@ -2434,10 +2475,16 @@ pool = New(config, blockchain) pool.Init(config.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver())   pending, queued = pool.Stats() - if pending != 0 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) + if journalRemotes { + if pending != 1 { // Remove the 2 replaced local transactions, but preserve the remote + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 1) + } + } else { + if pending != 0 { + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) + } } - if nolocals { + if nolocals && !journalRemotes { if queued != 0 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) }
diff --git go-ethereum/core/txpool/legacypool/list.go op-geth/core/txpool/legacypool/list.go index b749db44d45e74b389f671e69dd5c9e3df3a6123..24b18d2273252af4115825c94aaf6f9d8904dd1f 100644 --- go-ethereum/core/txpool/legacypool/list.go +++ op-geth/core/txpool/legacypool/list.go @@ -27,6 +27,7 @@ "sync/atomic" "time"   "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/holiman/uint256" ) @@ -265,6 +266,15 @@ cache := m.flatten() return cache[len(cache)-1] }   +// FirstElement returns the first element from the heap (guaranteed to be lowest), thus, the +// transaction with the lowest nonce. Returns nil if there are no elements. +func (m *sortedMap) FirstElement() *types.Transaction { + if m.Len() == 0 { + return nil + } + return m.Get((*m.index)[0]) +} + // list is a "list" of transactions belonging to an account, sorted by account // nonce. The same type can be used both for storing contiguous transactions for // the executable/pending queue; and for storing gapped transactions for the non- @@ -300,7 +310,7 @@ // transaction was accepted, and if yes, any previous transaction it replaced. // // If the new transaction is accepted into the list, the lists' cost and gas // thresholds are also potentially updated. -func (l *list) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transaction) { +func (l *list) Add(tx *types.Transaction, priceBump uint64, l1CostFn txpool.L1CostFunc) (bool, *types.Transaction) { // If there's an older better transaction, abort old := l.txs.Get(tx.Nonce()) if old != nil { @@ -332,7 +342,11 @@ if overflow { return false, nil } l.totalcost.Add(l.totalcost, cost) - + if l1CostFn != nil { + if l1Cost := l1CostFn(tx.RollupCostData()); l1Cost != nil { // add rollup cost + l.totalcost.Add(l.totalcost, cost) + } + } // Otherwise overwrite the old transaction with the current one l.txs.Put(tx) if l.costcap.Cmp(cost) < 0 {
diff --git go-ethereum/core/txpool/legacypool/list_test.go op-geth/core/txpool/legacypool/list_test.go index 8587c66f7d22a07f5776d7e25f90499eddc239cc..9f341a7f2026a9ef79944f542fbde08d558c21e2 100644 --- go-ethereum/core/txpool/legacypool/list_test.go +++ op-geth/core/txpool/legacypool/list_test.go @@ -40,7 +40,7 @@ } // Insert the transactions in a random order list := newList(true) for _, v := range rand.Perm(len(txs)) { - list.Add(txs[v], DefaultConfig.PriceBump) + list.Add(txs[v], DefaultConfig.PriceBump, nil) } // Verify internal state if len(list.txs.items) != len(txs) { @@ -64,7 +64,7 @@ gasprice, _ := new(big.Int).SetString("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 0) gaslimit := uint64(i) tx, _ := types.SignTx(types.NewTransaction(uint64(i), common.Address{}, value, gaslimit, gasprice, nil), types.HomesteadSigner{}, key) t.Logf("cost: %x bitlen: %d\n", tx.Cost(), tx.Cost().BitLen()) - list.Add(tx, DefaultConfig.PriceBump) + list.Add(tx, DefaultConfig.PriceBump, nil) } }   @@ -82,7 +82,7 @@ b.ResetTimer() for i := 0; i < b.N; i++ { list := newList(true) for _, v := range rand.Perm(len(txs)) { - list.Add(txs[v], DefaultConfig.PriceBump) + list.Add(txs[v], DefaultConfig.PriceBump, nil) list.Filter(priceLimit, DefaultConfig.PriceBump) } } @@ -102,7 +102,7 @@ for i := 0; i < b.N; i++ { list := newList(true) // Insert the transactions in a random order for _, v := range rand.Perm(len(txs)) { - list.Add(txs[v], DefaultConfig.PriceBump) + list.Add(txs[v], DefaultConfig.PriceBump, nil) } b.StartTimer() list.Cap(list.Len() - 1)
diff --git go-ethereum/core/txpool/subpool.go op-geth/core/txpool/subpool.go index 9ee0a69c0be9b994615d6258186ab72cfa32c438..e44052856fd9c61fe5b15da6d80f42808f841b3e 100644 --- go-ethereum/core/txpool/subpool.go +++ op-geth/core/txpool/subpool.go @@ -42,6 +42,8 @@ GasTipCap *uint256.Int // Maximum miner tip per gas the transaction can pay   Gas uint64 // Amount of gas required by the transaction BlobGas uint64 // Amount of blob gas required by the transaction + + DABytes *big.Int // Amount of data availability bytes this transaction may require if this is a rollup }   // Resolve retrieves the full transaction belonging to a lazy handle if it is still @@ -84,6 +86,10 @@ BlobFee *uint256.Int // Minimum 4844 blobfee needed to include a blob transaction   OnlyPlainTxs bool // Return only plain EVM transactions (peer-join announces, block space filling) OnlyBlobTxs bool // Return only blob transactions (block blob-space filling) + + // OP stack addition: Maximum l1 data size allowed for an included transaction (for throttling + // when batcher is backlogged). Ignored if nil. + MaxDATxSize *big.Int }   // SubPool represents a specialized transaction pool that lives on its own (e.g.
diff --git go-ethereum/core/txpool/txpool.go op-geth/core/txpool/txpool.go index 182706d63cfb96ad3474392d64b633058434911b..e7790c904214398fe134ddd7957d87b636e67bb9 100644 --- go-ethereum/core/txpool/txpool.go +++ op-geth/core/txpool/txpool.go @@ -17,6 +17,7 @@ package txpool   import ( + "context" "errors" "fmt" "math/big" @@ -30,6 +31,8 @@ "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" ) + +type L1CostFunc func(dataGas types.RollupCostData) *big.Int   // TxStatus is the current status of a transaction as seen by the pool. type TxStatus uint @@ -76,22 +79,32 @@ quit chan chan error // Quit channel to tear down the head updater term chan struct{} // Termination channel to detect a closed pool   sync chan chan error // Testing / simulator channel to block until internal reset is done + + ingressFilters []IngressFilter // List of filters to apply to incoming transactions + + filterCtx context.Context // Filters may use external resources + filterCancel context.CancelFunc // Filter calls are cancelled on shutdown }   // New creates a new transaction pool to gather, sort and filter inbound // transactions from the network. -func New(gasTip uint64, chain BlockChain, subpools []SubPool) (*TxPool, error) { +func New(gasTip uint64, chain BlockChain, subpools []SubPool, poolFilters []IngressFilter) (*TxPool, error) { // Retrieve the current head so that all subpools and this main coordinator // pool will have the same starting state, even if the chain moves forward // during initialization. head := chain.CurrentBlock()   + filterCtx, filterCancel := context.WithCancel(context.Background()) + pool := &TxPool{ - subpools: subpools, - reservations: make(map[common.Address]SubPool), - quit: make(chan chan error), - term: make(chan struct{}), - sync: make(chan chan error), + subpools: subpools, + reservations: make(map[common.Address]SubPool), + quit: make(chan chan error), + term: make(chan struct{}), + sync: make(chan chan error), + ingressFilters: poolFilters, + filterCtx: filterCtx, + filterCancel: filterCancel, } for i, subpool := range subpools { if err := subpool.Init(gasTip, head, pool.reserver(i, subpool)); err != nil { @@ -154,6 +167,8 @@ // Close terminates the transaction pool and all its subpools. func (p *TxPool) Close() error { var errs []error + + p.filterCancel() // Cancel filter work, these in-flight txs will be not be allowed through before shutdown   // Terminate the reset loop and wait for it to finish errc := make(chan error) @@ -337,11 +352,23 @@ // We also need to track how the transactions were split across the subpools, // so we can piece back the returned errors into the original order. txsets := make([][]*types.Transaction, len(p.subpools)) splits := make([]int, len(txs)) + filtered_out := make([]bool, len(txs))   for i, tx := range txs { // Mark this transaction belonging to no-subpool splits[i] = -1   + // Filter the transaction through the ingress filters + for _, f := range p.ingressFilters { + if !f.FilterTx(p.filterCtx, tx) { + filtered_out[i] = true + } + } + // if the transaction is filtered out, don't add it to any subpool + if filtered_out[i] { + continue + } + // Try to find a subpool that accepts the transaction for j, subpool := range p.subpools { if subpool.Filter(tx) { @@ -359,6 +386,11 @@ errsets[i] = p.subpools[i].Add(txsets[i], local, sync) } errs := make([]error, len(txs)) for i, split := range splits { + // If the transaction was filtered out, mark it as such + if filtered_out[i] { + errs[i] = core.ErrTxFilteredOut + continue + } // If the transaction was rejected by all subpools, mark it unsupported if split == -1 { errs[i] = fmt.Errorf("%w: received type %d", core.ErrTxTypeNotSupported, txs[i].Type())
diff --git go-ethereum/core/txpool/validation.go op-geth/core/txpool/validation.go index 412418dcc9367965cd3c578f6150433cd76fbf45..c76adfaac568165f060796b66d8e5df486c57f35 100644 --- go-ethereum/core/txpool/validation.go +++ op-geth/core/txpool/validation.go @@ -31,12 +31,31 @@ "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" )   +// L1 Info Gas Overhead is the amount of gas the the L1 info deposit consumes. +// It is removed from the tx pool max gas to better indicate that L2 transactions +// are not able to consume all of the gas in a L2 block as the L1 info deposit is always present. +const l1InfoGasOverhead = uint64(70_000) + var ( // blobTxMinBlobGasPrice is the big.Int version of the configured protocol // parameter to avoid constructing a new big integer for every transaction. blobTxMinBlobGasPrice = big.NewInt(params.BlobTxMinBlobGasprice) )   +func EffectiveGasLimit(chainConfig *params.ChainConfig, gasLimit uint64, effectiveLimit uint64) uint64 { + if effectiveLimit != 0 && effectiveLimit < gasLimit { + gasLimit = effectiveLimit + } + if chainConfig.Optimism != nil { + if l1InfoGasOverhead < gasLimit { + gasLimit -= l1InfoGasOverhead + } else { + gasLimit = 0 + } + } + return gasLimit +} + // ValidationOptions define certain differences between transaction validation // across the different pools without having to duplicate those checks. type ValidationOptions struct { @@ -45,6 +64,8 @@ Accept uint8 // Bitmap of transaction types that should be accepted for the calling pool MaxSize uint64 // Maximum size of a transaction that the caller can meaningfully handle MinTip *big.Int // Minimum gas tip needed to allow a transaction into the caller pool + + EffectiveGasCeil uint64 // if non-zero, a gas ceiling to enforce independent of the header's gaslimit value }   // ValidationFunction is an method type which the pools use to perform the tx-validations which do not @@ -59,6 +80,15 @@ // // This check is public to allow different transaction pools to check the basic // rules without duplicating code and running the risk of missed updates. func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types.Signer, opts *ValidationOptions) error { + // No unauthenticated deposits allowed in the transaction pool. + // This is for spam protection, not consensus, + // as the external engine-API user authenticates deposits. + if tx.Type() == types.DepositTxType { + return core.ErrTxTypeNotSupported + } + if opts.Config.IsOptimism() && tx.Type() == types.BlobTxType { + return core.ErrTxTypeNotSupported + } // Ensure transactions not implemented by the calling pool are rejected if opts.Accept&(1<<tx.Type()) == 0 { return fmt.Errorf("%w: tx type %v not supported by this pool", core.ErrTxTypeNotSupported, tx.Type()) @@ -88,7 +118,7 @@ if tx.Value().Sign() < 0 { return ErrNegativeValue } // Ensure the transaction doesn't exceed the current block limit gas - if head.GasLimit < tx.Gas() { + if EffectiveGasLimit(opts.Config, head.GasLimit, opts.EffectiveGasCeil) < tx.Gas() { return ErrGasLimit } // Sanity check for extremely large numbers (supported by RLP or RPC) @@ -197,6 +227,9 @@ // ExistingCost is a mandatory callback to retrieve an already pooled // transaction's cost with the given nonce to check for overdrafts. ExistingCost func(addr common.Address, nonce uint64) *big.Int + + // L1CostFn is an optional extension, to validate L1 rollup costs of a tx + L1CostFn L1CostFunc }   // ValidateTransactionWithState is a helper method to check whether a transaction @@ -227,6 +260,11 @@ var ( balance = opts.State.GetBalance(from).ToBig() cost = tx.Cost() ) + if opts.L1CostFn != nil { + if l1Cost := opts.L1CostFn(tx.RollupCostData()); l1Cost != nil { // add rollup cost + cost = cost.Add(cost, l1Cost) + } + } if balance.Cmp(cost) < 0 { return fmt.Errorf("%w: balance %v, tx cost %v, overshot %v", core.ErrInsufficientFunds, balance, cost, new(big.Int).Sub(cost, balance)) }
diff --git go-ethereum/core/vm/contracts.go op-geth/core/vm/contracts.go index 06849e65ade3ba4edbc4c39bae7ceb6d1694ebe4..0daa8f1645ddd639b375e5db212a6aa4788ae06e 100644 --- go-ethereum/core/vm/contracts.go +++ op-geth/core/vm/contracts.go @@ -35,6 +35,7 @@ "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/blake2b" "github.com/ethereum/go-ethereum/crypto/bn256" "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/ethereum/go-ethereum/crypto/secp256r1" "github.com/ethereum/go-ethereum/params" "golang.org/x/crypto/ripemd160" ) @@ -129,10 +130,10 @@ common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{}, common.BytesToAddress([]byte{0x09}): &blake2F{}, common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{}, - common.BytesToAddress([]byte{0x0c}): &bls12381G1MultiExp{}, + common.BytesToAddress([]byte{0x0c}): &bls12381G1MultiExpPrague{}, common.BytesToAddress([]byte{0x0d}): &bls12381G2Add{}, - common.BytesToAddress([]byte{0x0e}): &bls12381G2MultiExp{}, - common.BytesToAddress([]byte{0x0f}): &bls12381Pairing{}, + common.BytesToAddress([]byte{0x0e}): &bls12381G2MultiExpPrague{}, + common.BytesToAddress([]byte{0x0f}): &bls12381PairingPrague{}, common.BytesToAddress([]byte{0x10}): &bls12381MapG1{}, common.BytesToAddress([]byte{0x11}): &bls12381MapG2{}, } @@ -141,7 +142,63 @@ var PrecompiledContractsBLS = PrecompiledContractsPrague   var PrecompiledContractsVerkle = PrecompiledContractsPrague   +// PrecompiledContractsFjord contains the default set of pre-compiled Ethereum +// contracts used in the Fjord release. +var PrecompiledContractsFjord = map[common.Address]PrecompiledContract{ + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{4}): &dataCopy{}, + common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, + common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + common.BytesToAddress([]byte{9}): &blake2F{}, + common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, + common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{}, +} + +// PrecompiledContractsGranite contains the default set of pre-compiled Ethereum +// contracts used in the Granite release. +var PrecompiledContractsGranite = map[common.Address]PrecompiledContract{ + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{4}): &dataCopy{}, + common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, + common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + common.BytesToAddress([]byte{8}): &bn256PairingGranite{}, + common.BytesToAddress([]byte{9}): &blake2F{}, + common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, + common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{}, +} + +var PrecompiledContractsIsthmus = map[common.Address]PrecompiledContract{ + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{4}): &dataCopy{}, + common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, + common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + common.BytesToAddress([]byte{8}): &bn256PairingGranite{}, + common.BytesToAddress([]byte{9}): &blake2F{}, + common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, + common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{}, + common.BytesToAddress([]byte{0x0c}): &bls12381G1MultiExpIsthmus{}, + common.BytesToAddress([]byte{0x0d}): &bls12381G2Add{}, + common.BytesToAddress([]byte{0x0e}): &bls12381G2MultiExpIsthmus{}, + common.BytesToAddress([]byte{0x0f}): &bls12381PairingIsthmus{}, + common.BytesToAddress([]byte{0x10}): &bls12381MapG1{}, + common.BytesToAddress([]byte{0x11}): &bls12381MapG2{}, + common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{}, +} + var ( + PrecompiledAddressesIsthmus []common.Address + PrecompiledAddressesGranite []common.Address + PrecompiledAddressesFjord []common.Address PrecompiledAddressesPrague []common.Address PrecompiledAddressesCancun []common.Address PrecompiledAddressesBerlin []common.Address @@ -169,10 +226,26 @@ } for k := range PrecompiledContractsPrague { PrecompiledAddressesPrague = append(PrecompiledAddressesPrague, k) } + for k := range PrecompiledContractsFjord { + PrecompiledAddressesFjord = append(PrecompiledAddressesFjord, k) + } + for k := range PrecompiledContractsGranite { + PrecompiledAddressesGranite = append(PrecompiledAddressesGranite, k) + } + for k := range PrecompiledContractsIsthmus { + PrecompiledAddressesIsthmus = append(PrecompiledAddressesIsthmus, k) + } }   func activePrecompiledContracts(rules params.Rules) PrecompiledContracts { + // note: the order of these switch cases is important switch { + case rules.IsOptimismIsthmus: + return PrecompiledContractsIsthmus + case rules.IsOptimismGranite: + return PrecompiledContractsGranite + case rules.IsOptimismFjord: + return PrecompiledContractsFjord case rules.IsVerkle: return PrecompiledContractsVerkle case rules.IsPrague: @@ -198,6 +271,12 @@ // ActivePrecompiles returns the precompile addresses enabled with the current configuration. func ActivePrecompiles(rules params.Rules) []common.Address { switch { + case rules.IsOptimismIsthmus: + return PrecompiledAddressesIsthmus + case rules.IsOptimismGranite: + return PrecompiledAddressesGranite + case rules.IsOptimismFjord: + return PrecompiledAddressesFjord case rules.IsPrague: return PrecompiledAddressesPrague case rules.IsCancun: @@ -585,6 +664,9 @@ false32Byte = make([]byte, 32)   // errBadPairingInput is returned if the bn256 pairing input is invalid. errBadPairingInput = errors.New("bad elliptic curve pairing size") + + // errBadPairingInputSize is returned if the bn256 pairing input size is invalid. + errBadPairingInputSize = errors.New("bad elliptic curve pairing input size") )   // runBn256Pairing implements the Bn256Pairing precompile, referenced by both @@ -616,6 +698,22 @@ if bn256.PairingCheck(cs, ts) { return true32Byte, nil } return false32Byte, nil +} + +// bn256PairingGranite implements a pairing pre-compile for the bn256 curve +// conforming to Granite consensus rules. +type bn256PairingGranite struct{} + +// RequiredGas returns the gas required to execute the pre-compiled contract. +func (c *bn256PairingGranite) RequiredGas(input []byte) uint64 { + return new(bn256PairingIstanbul).RequiredGas(input) +} + +func (c *bn256PairingGranite) Run(input []byte) ([]byte, error) { + if len(input) > int(params.Bn256PairingMaxInputSizeGranite) { + return nil, errBadPairingInputSize + } + return runBn256Pairing(input) }   // bn256PairingIstanbul implements a pairing pre-compile for the bn256 curve @@ -710,6 +808,9 @@ errBLS12381InvalidInputLength = errors.New("invalid input length") errBLS12381InvalidFieldElementTopBytes = errors.New("invalid field element top bytes") errBLS12381G1PointSubgroup = errors.New("g1 point is not on correct subgroup") errBLS12381G2PointSubgroup = errors.New("g2 point is not on correct subgroup") + errBLS12381MaxG1Size = errors.New("g1 msm input size exceeds maximum") + errBLS12381MaxG2Size = errors.New("g2 msm input size exceeds maximum") + errBLS12381MaxPairingSize = errors.New("pairing input size exceeds maximum") )   // bls12381G1Add implements EIP-2537 G1Add precompile. @@ -748,11 +849,26 @@ // Encode the G1 point result into 128 bytes return encodePointG1(p0), nil }   -// bls12381G1MultiExp implements EIP-2537 G1MultiExp precompile. -type bls12381G1MultiExp struct{} +type bls12381G1MultiExpIsthmus struct { +} + +func (c *bls12381G1MultiExpIsthmus) RequiredGas(input []byte) uint64 { + return new(bls12381G1MultiExpPrague).RequiredGas(input) +} + +func (c *bls12381G1MultiExpIsthmus) Run(input []byte) ([]byte, error) { + if len(input) > int(params.Bls12381G1MulMaxInputSizeIsthmus) { + return nil, errBLS12381MaxG1Size + } + + return new(bls12381G1MultiExpPrague).Run(input) +} + +// bls12381G1MultiExpPrague implements EIP-2537 G1MultiExp precompile for Prague (no size limits). +type bls12381G1MultiExpPrague struct{}   // RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381G1MultiExp) RequiredGas(input []byte) uint64 { +func (c *bls12381G1MultiExpPrague) RequiredGas(input []byte) uint64 { // Calculate G1 point, scalar value pair length k := len(input) / 160 if k == 0 { @@ -770,7 +886,7 @@ // Calculate gas and return the result return (uint64(k) * params.Bls12381G1MulGas * discount) / 1000 }   -func (c *bls12381G1MultiExp) Run(input []byte) ([]byte, error) { +func (c *bls12381G1MultiExpPrague) Run(input []byte) ([]byte, error) { // Implements EIP-2537 G1MultiExp precompile. // G1 multiplication call expects `160*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` bytes). // Output is an encoding of multiexponentiation operation result - single G1 point (`128` bytes). @@ -845,11 +961,26 @@ // Encode the G2 point into 256 bytes return encodePointG2(r), nil }   -// bls12381G2MultiExp implements EIP-2537 G2MultiExp precompile. -type bls12381G2MultiExp struct{} +type bls12381G2MultiExpIsthmus struct { +} + +func (c *bls12381G2MultiExpIsthmus) RequiredGas(input []byte) uint64 { + return new(bls12381G2MultiExpPrague).RequiredGas(input) +} + +func (c *bls12381G2MultiExpIsthmus) Run(input []byte) ([]byte, error) { + if len(input) > int(params.Bls12381G2MulMaxInputSizeIsthmus) { + return nil, errBLS12381MaxG2Size + } + + return new(bls12381G2MultiExpPrague).Run(input) +} + +// bls12381G2MultiExpPrague implements EIP-2537 G2MultiExp precompile. +type bls12381G2MultiExpPrague struct{}   // RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381G2MultiExp) RequiredGas(input []byte) uint64 { +func (c *bls12381G2MultiExpPrague) RequiredGas(input []byte) uint64 { // Calculate G2 point, scalar value pair length k := len(input) / 288 if k == 0 { @@ -867,7 +998,7 @@ // Calculate gas and return the result return (uint64(k) * params.Bls12381G2MulGas * discount) / 1000 }   -func (c *bls12381G2MultiExp) Run(input []byte) ([]byte, error) { +func (c *bls12381G2MultiExpPrague) Run(input []byte) ([]byte, error) { // Implements EIP-2537 G2MultiExp precompile logic // > G2 multiplication call expects `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes). // > Output is an encoding of multiexponentiation operation result - single G2 point (`256` bytes). @@ -905,15 +1036,30 @@ // Encode the G2 point to 256 bytes. return encodePointG2(r), nil }   -// bls12381Pairing implements EIP-2537 Pairing precompile. -type bls12381Pairing struct{} +type bls12381PairingIsthmus struct { +} + +func (c *bls12381PairingIsthmus) RequiredGas(input []byte) uint64 { + return new(bls12381PairingPrague).RequiredGas(input) +} + +func (c *bls12381PairingIsthmus) Run(input []byte) ([]byte, error) { + if len(input) > int(params.Bls12381PairingMaxInputSizeIsthmus) { + return nil, errBLS12381MaxPairingSize + } + + return new(bls12381PairingPrague).Run(input) +} + +// bls12381PairingPrague implements EIP-2537 Pairing precompile. +type bls12381PairingPrague struct{}   // RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381Pairing) RequiredGas(input []byte) uint64 { +func (c *bls12381PairingPrague) RequiredGas(input []byte) uint64 { return params.Bls12381PairingBaseGas + uint64(len(input)/384)*params.Bls12381PairingPerPairGas }   -func (c *bls12381Pairing) Run(input []byte) ([]byte, error) { +func (c *bls12381PairingPrague) Run(input []byte) ([]byte, error) { // Implements EIP-2537 Pairing precompile logic. // > Pairing call expects `384*k` bytes as an inputs that is interpreted as byte concatenation of `k` slices. Each slice has the following structure: // > - `128` bytes of G1 point encoding @@ -1182,3 +1328,37 @@ h[0] = blobCommitmentVersionKZG   return h } + +// P256VERIFY (secp256r1 signature verification) +// implemented as a native contract +type p256Verify struct{} + +// RequiredGas returns the gas required to execute the precompiled contract +func (c *p256Verify) RequiredGas(input []byte) uint64 { + return params.P256VerifyGas +} + +// Run executes the precompiled contract with given 160 bytes of param, returning the output and the used gas +func (c *p256Verify) Run(input []byte) ([]byte, error) { + // Required input length is 160 bytes + const p256VerifyInputLength = 160 + // Check the input length + if len(input) != p256VerifyInputLength { + // Input length is invalid + return nil, nil + } + + // Extract the hash, r, s, x, y from the input + hash := input[0:32] + r, s := new(big.Int).SetBytes(input[32:64]), new(big.Int).SetBytes(input[64:96]) + x, y := new(big.Int).SetBytes(input[96:128]), new(big.Int).SetBytes(input[128:160]) + + // Verify the secp256r1 signature + if secp256r1.Verify(hash, r, s, x, y) { + // Signature is valid + return common.LeftPadBytes([]byte{1}, 32), nil + } else { + // Signature is invalid + return nil, nil + } +}
diff --git go-ethereum/crypto/secp256r1/publickey.go op-geth/crypto/secp256r1/publickey.go new file mode 100644 index 0000000000000000000000000000000000000000..885a3e1a624b85310225913c44d294e402a50fcd --- /dev/null +++ op-geth/crypto/secp256r1/publickey.go @@ -0,0 +1,21 @@ +package secp256r1 + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "math/big" +) + +// Generates appropriate public key format from given coordinates +func newPublicKey(x, y *big.Int) *ecdsa.PublicKey { + // Check if the given coordinates are valid + if x == nil || y == nil || !elliptic.P256().IsOnCurve(x, y) { + return nil + } + + return &ecdsa.PublicKey{ + Curve: elliptic.P256(), + X: x, + Y: y, + } +}
diff --git go-ethereum/crypto/secp256r1/verifier.go op-geth/crypto/secp256r1/verifier.go new file mode 100644 index 0000000000000000000000000000000000000000..ffb4839d8d560a5892175c737bff136d73ee6e12 --- /dev/null +++ op-geth/crypto/secp256r1/verifier.go @@ -0,0 +1,22 @@ +package secp256r1 + +import ( + "crypto/ecdsa" + "math/big" +) + +// Verify verifies the given signature (r, s) for the given hash and public key (x, y). +// It returns true if the signature is valid, false otherwise. +func Verify(hash []byte, r, s, x, y *big.Int) bool { + // Create the public key format + publicKey := newPublicKey(x, y) + + // Check if they are invalid public key coordinates + if publicKey == nil { + return false + } + + // Verify the signature with the public key, + // then return true if it's valid, false otherwise + return ecdsa.Verify(publicKey, hash, r, s) +}

The rollup functionality is enabled with the optimism field in the chain config. The EIP-1559 parameters are configurable to adjust for faster more frequent and smaller blocks. The parameters can be overriden for testing.

diff --git go-ethereum/core/genesis.go op-geth/core/genesis.go index 68d945e37ee122af7e7f0c9b2db76a452f719134..6586db3c42833a1ea5624c736174f3ed383a4c38 100644 --- go-ethereum/core/genesis.go +++ op-geth/core/genesis.go @@ -36,6 +36,7 @@ "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/superchain" "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb/pathdb" @@ -73,6 +74,11 @@ ParentHash common.Hash `json:"parentHash"` BaseFee *big.Int `json:"baseFeePerGas"` // EIP-1559 ExcessBlobGas *uint64 `json:"excessBlobGas"` // EIP-4844 BlobGasUsed *uint64 `json:"blobGasUsed"` // EIP-4844 + + // StateHash represents the genesis state, to allow instantiation of a chain with missing initial state. + // Chains with history pruning, or extraordinarily large genesis allocation (e.g. after a regenesis event) + // may utilize this to get started, and then state-sync the latest state, while still verifying the header chain. + StateHash *common.Hash `json:"stateHash,omitempty"` }   func ReadGenesis(db ethdb.Database) (*Genesis, error) { @@ -109,12 +115,21 @@ genesis.Coinbase = genesisHeader.Coinbase genesis.BaseFee = genesisHeader.BaseFee genesis.ExcessBlobGas = genesisHeader.ExcessBlobGas genesis.BlobGasUsed = genesisHeader.BlobGasUsed + // A nil or empty alloc, with a non-matching state-root in the block header, intents to override the state-root. + if genesis.Alloc == nil || (len(genesis.Alloc) == 0 && genesisHeader.Root != types.EmptyRootHash) { + h := genesisHeader.Root // the genesis block is encoded as RLP in the DB and will contain the state-root + genesis.StateHash = &h + genesis.Alloc = nil + }   return &genesis, nil }   -// hashAlloc computes the state root according to the genesis specification. -func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { +// hashAlloc returns the following: +// * computed state root according to the genesis specification. +// * storage root of the L2ToL1MessagePasser contract. +// * error if any, when committing the genesis state (if so, state root and storage root will be empty). +func hashAlloc(ga *types.GenesisAlloc, isVerkle, isIsthmus bool) (common.Hash, common.Hash, error) { // If a genesis-time verkle trie is requested, create a trie config // with the verkle trie enabled so that the tree can be initialized // as such. @@ -134,7 +149,7 @@ } db := rawdb.NewMemoryDatabase() statedb, err := state.New(emptyRoot, state.NewDatabase(triedb.NewDatabase(db, config), nil)) if err != nil { - return common.Hash{}, err + return common.Hash{}, common.Hash{}, err } for addr, account := range *ga { if account.Balance != nil { @@ -146,19 +161,31 @@ for key, value := range account.Storage { statedb.SetState(addr, key, value) } } - return statedb.Commit(0, false, false) + + stateRoot, err := statedb.Commit(0, false, false) + if err != nil { + return common.Hash{}, common.Hash{}, err + } + // get the storage root of the L2ToL1MessagePasser contract + var storageRootMessagePasser common.Hash + if isIsthmus { + storageRootMessagePasser = statedb.GetStorageRoot(params.OptimismL2ToL1MessagePasser) + } + + return stateRoot, storageRootMessagePasser, nil }   // flushAlloc is very similar with hash, but the main difference is all the -// generated states will be persisted into the given database. -func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, error) { +// generated states will be persisted into the given database. Returns the +// same values as hashAlloc. +func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database, isIsthmus bool) (common.Hash, common.Hash, error) { emptyRoot := types.EmptyRootHash if triedb.IsVerkle() { emptyRoot = types.EmptyVerkleHash } statedb, err := state.New(emptyRoot, state.NewDatabase(triedb, nil)) if err != nil { - return common.Hash{}, err + return common.Hash{}, common.Hash{}, err } for addr, account := range *ga { if account.Balance != nil { @@ -174,15 +201,20 @@ } } root, err := statedb.Commit(0, false, false) if err != nil { - return common.Hash{}, err + return common.Hash{}, common.Hash{}, err + } + // get the storage root of the L2ToL1MessagePasser contract + var storageRootMessagePasser common.Hash + if isIsthmus { + storageRootMessagePasser = statedb.GetStorageRoot(params.OptimismL2ToL1MessagePasser) } // Commit newly generated states into disk if it's not empty. if root != types.EmptyRootHash { if err := triedb.Commit(root, true); err != nil { - return common.Hash{}, err + return common.Hash{}, common.Hash{}, err } } - return root, nil + return root, storageRootMessagePasser, nil }   func getGenesisState(db ethdb.Database, blockhash common.Hash) (alloc types.GenesisAlloc, err error) { @@ -245,6 +277,17 @@ // ChainOverrides contains the changes to chain config. type ChainOverrides struct { OverrideCancun *uint64 OverrideVerkle *uint64 + + // OP-Stack additions + OverrideOptimismCanyon *uint64 + OverrideOptimismEcotone *uint64 + OverrideOptimismFjord *uint64 + OverrideOptimismGranite *uint64 + OverrideOptimismHolocene *uint64 + OverrideOptimismIsthmus *uint64 + OverrideOptimismJovian *uint64 + OverrideOptimismInterop *uint64 + ApplySuperchainUpgrades bool }   // apply applies the chain overrides on the supplied chain config. @@ -253,12 +296,73 @@ if o == nil || cfg == nil { return cfg, nil } cpy := *cfg + + // OP-Stack: If applying the superchain-registry to a known OP-Stack chain, + // then override the local chain-config with that from the registry. + if o.ApplySuperchainUpgrades && cfg.IsOptimism() && cfg.ChainID != nil && cfg.ChainID.IsUint64() { + getChainConfig := func() (*params.ChainConfig, error) { + chain, err := superchain.GetChain(cfg.ChainID.Uint64()) + if err != nil { + return nil, err + } + chainConf, err := chain.Config() + if err != nil { + return nil, err + } + genConf, err := params.LoadOPStackChainConfig(chainConf) + if err != nil { + return nil, err + } + return genConf, err + } + + if genConf, err := getChainConfig(); err == nil { + cpy = *genConf + } else { + log.Warn("failed to load chain config from superchain-registry, skipping override", "err", err, "chain_id", cfg.ChainID) + } + } + if o.OverrideCancun != nil { cpy.CancunTime = o.OverrideCancun } if o.OverrideVerkle != nil { cpy.VerkleTime = o.OverrideVerkle } + + // OP-Stack overrides + if o.OverrideOptimismCanyon != nil { + cpy.CanyonTime = o.OverrideOptimismCanyon + cpy.ShanghaiTime = o.OverrideOptimismCanyon + if cfg.Optimism != nil && (cfg.Optimism.EIP1559DenominatorCanyon == nil || *cfg.Optimism.EIP1559DenominatorCanyon == 0) { + eip1559DenominatorCanyon := uint64(250) + cpy.Optimism.EIP1559DenominatorCanyon = &eip1559DenominatorCanyon + } + } + if o.OverrideOptimismEcotone != nil { + cpy.EcotoneTime = o.OverrideOptimismEcotone + cpy.CancunTime = o.OverrideOptimismEcotone + } + if o.OverrideOptimismFjord != nil { + cpy.FjordTime = o.OverrideOptimismFjord + } + if o.OverrideOptimismGranite != nil { + cpy.GraniteTime = o.OverrideOptimismGranite + } + if o.OverrideOptimismHolocene != nil { + cpy.HoloceneTime = o.OverrideOptimismHolocene + } + if o.OverrideOptimismIsthmus != nil { + cpy.IsthmusTime = o.OverrideOptimismIsthmus + cpy.PragueTime = o.OverrideOptimismIsthmus + } + if o.OverrideOptimismJovian != nil { + cpy.JovianTime = o.OverrideOptimismJovian + } + if o.OverrideOptimismInterop != nil { + cpy.InteropTime = o.OverrideOptimismInterop + } + if err := cpy.CheckConfigForkOrder(); err != nil { return nil, err } @@ -307,12 +411,18 @@ return nil, common.Hash{}, nil, err } return chainCfg, block.Hash(), nil, nil } + log.Info("Genesis hash", "hash", ghash) + // OP-Stack note: the OP-Mainnet bedrock-migration snapshot has a genesis hash, header and storedCfg. + // The only thing to do to it is to apply the overrides, to apply later superchain-upgrades. + // Commit the genesis if the genesis block exists in the ancient database // but the key-value database is empty without initializing the genesis // fields. This scenario can occur when the node is created from scratch // with an existing ancient store. storedCfg := rawdb.ReadChainConfig(db, ghash) if storedCfg == nil { + // OP-Stack note: a new chain, initialized with op-network CLI flag, hits this case. + // Ensure the stored genesis block matches with the given genesis. Private // networks must explicitly specify the genesis in the config file, mainnet // genesis will be used as default and the initialization will always fail. @@ -351,25 +461,49 @@ if hash := genesis.ToBlock().Hash(); hash != ghash { return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash} } } + // Check config compatibility and write the config. Compatibility errors // are returned to the caller unless we're already at block zero. head := rawdb.ReadHeadHeader(db) if head == nil { return nil, common.Hash{}, nil, errors.New("missing head header") } + + // OP-Stack warning: tricky upstream code: method with nil-receiver case. + // Returns genesis.Config if genesis is not nil. Falls back to storedCfg otherwise. And some special L1 cases. newCfg := genesis.chainConfigOrDefault(ghash, storedCfg)   + // OP-Stack note: Always apply overrides. + // The genesis function arg may be nil, and stored-config may be non-nil at the same time. + // This is important to apply superchain-upgrades to existing DBs, where the network CLI flag is not used. + chainCfg, err := overrides.apply(newCfg) + if err != nil { + return nil, common.Hash{}, nil, err + } + newCfg = chainCfg + + var genesisTimestamp *uint64 + if genesis != nil { + genesisTimestamp = &genesis.Timestamp + } + // OP-Stack diff: provide genesis timestamp (may be nil), to check bedrock-migration compat with config. // TODO(rjl493456442) better to define the comparator of chain config // and short circuit if the chain config is not changed. - compatErr := storedCfg.CheckCompatible(newCfg, head.Number.Uint64(), head.Time) + compatErr := storedCfg.CheckCompatible(newCfg, head.Number.Uint64(), head.Time, genesisTimestamp) if compatErr != nil && ((head.Number.Uint64() != 0 && compatErr.RewindToBlock != 0) || (head.Time != 0 && compatErr.RewindToTime != 0)) { return newCfg, ghash, compatErr, nil } + // Don't overwrite if the old is identical to the new. It's useful // for the scenarios that database is opened in the read-only mode. storedData, _ := json.Marshal(storedCfg) if newData, _ := json.Marshal(newCfg); !bytes.Equal(storedData, newData) { + log.Info("Chain configs differ, overwriting stored config with new config.") + log.Info("Previously stored chain config", "json", string(storedData)) + log.Info("New chain config", "json", string(newData), "genesis-nil", genesis == nil) rawdb.WriteChainConfig(db, ghash, newCfg) + } else { + log.Info("Configured chain config matches existing chain config in storage.") } return newCfg, ghash, nil, nil } @@ -433,15 +567,27 @@ }   // ToBlock returns the genesis block according to genesis specification. func (g *Genesis) ToBlock() *types.Block { - root, err := hashAlloc(&g.Alloc, g.IsVerkle()) - if err != nil { + var stateRoot, storageRootMessagePasser common.Hash + var err error + if g.StateHash != nil { + if len(g.Alloc) > 0 { + panic(fmt.Errorf("cannot both have genesis hash %s "+ + "and non-empty state-allocation", *g.StateHash)) + } + // g.StateHash is only relevant for pre-bedrock (and hence pre-isthmus) chains. + // we bail here since this is not a valid usage of StateHash + if g.Config.IsOptimismIsthmus(g.Timestamp) { + panic(fmt.Errorf("stateHash usage disallowed in chain with isthmus active at genesis")) + } + stateRoot = *g.StateHash + } else if stateRoot, storageRootMessagePasser, err = hashAlloc(&g.Alloc, g.IsVerkle(), g.Config.IsOptimismIsthmus(g.Timestamp)); err != nil { panic(err) } - return g.toBlockWithRoot(root) + return g.toBlockWithRoot(stateRoot, storageRootMessagePasser) }   // toBlockWithRoot constructs the genesis block with the given genesis state root. -func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block { +func (g *Genesis) toBlockWithRoot(stateRoot, storageRootMessagePasser common.Hash) *types.Block { head := &types.Header{ Number: new(big.Int).SetUint64(g.Number), Nonce: types.EncodeNonce(g.Nonce), @@ -454,7 +600,7 @@ BaseFee: g.BaseFee, Difficulty: g.Difficulty, MixDigest: g.Mixhash, Coinbase: g.Coinbase, - Root: root, + Root: stateRoot, } if g.GasLimit == 0 { head.GasLimit = params.GenesisGasLimit @@ -469,9 +615,7 @@ } else { head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee) } } - var ( - withdrawals []*types.Withdrawal - ) + var withdrawals []*types.Withdrawal if conf := g.Config; conf != nil { num := big.NewInt(int64(g.Number)) if conf.IsShanghai(num, g.Timestamp) { @@ -496,8 +640,16 @@ } if conf.IsPrague(num, g.Timestamp) { head.RequestsHash = &types.EmptyRequestsHash } + // If Isthmus is active at genesis, set the WithdrawalRoot to the storage root of the L2ToL1MessagePasser contract. + if g.Config.IsOptimismIsthmus(g.Timestamp) { + if storageRootMessagePasser == (common.Hash{}) { + // if there was no MessagePasser contract storage, set the WithdrawalsHash to the empty hash + storageRootMessagePasser = types.EmptyWithdrawalsHash + } + head.WithdrawalsHash = &storageRootMessagePasser + } } - return types.NewBlock(head, &types.Body{Withdrawals: withdrawals}, nil, trie.NewStackTrie(nil)) + return types.NewBlock(head, &types.Body{Withdrawals: withdrawals}, nil, trie.NewStackTrie(nil), g.Config) }   // Commit writes the block and state of a genesis specification to the database. @@ -516,12 +668,22 @@ } if config.Clique != nil && len(g.ExtraData) < 32+crypto.SignatureLength { return nil, errors.New("can't start clique chain without signers") } - // flush the data to disk and compute the state root - root, err := flushAlloc(&g.Alloc, triedb) - if err != nil { - return nil, err + var stateRoot, storageRootMessagePasser common.Hash + var err error + if len(g.Alloc) == 0 { + if g.StateHash == nil { + stateRoot = types.EmptyRootHash // default to the hash of the empty state. Some unit-tests rely on this. + } else { + stateRoot = *g.StateHash + } + } else { + // flush the data to disk and compute the state root + stateRoot, storageRootMessagePasser, err = flushAlloc(&g.Alloc, triedb, g.Config.IsIsthmus(g.Timestamp)) + if err != nil { + return nil, err + } } - block := g.toBlockWithRoot(root) + block := g.toBlockWithRoot(stateRoot, storageRootMessagePasser)   // Marshal the genesis state specification and persist. blob, err := json.Marshal(g.Alloc)
diff --git go-ethereum/params/config.go op-geth/params/config.go index f1e139608c7bdc51bf678e279940d9c9c7ed7682..0fa5c1a2163305e26b68db60b235dbbbeb4a8c59 100644 --- go-ethereum/params/config.go +++ op-geth/params/config.go @@ -22,6 +22,7 @@ "math" "math/big"   "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params/forks" )   @@ -30,6 +31,12 @@ var ( MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") HoleskyGenesisHash = common.HexToHash("0xb5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4") SepoliaGenesisHash = common.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9") +) + +const ( + OPMainnetChainID = 10 + BaseMainnetChainID = 8453 + baseSepoliaChainID = 84532 )   func newUint64(val uint64) *uint64 { return &val } @@ -275,6 +282,15 @@ Ethash: new(EthashConfig), Clique: nil, } TestRules = TestChainConfig.Rules(new(big.Int), false, 0) + + // This is an Optimism chain config with bedrock starting a block 5, introduced for historical endpoint testing, largely based on the clique config + OptimismTestConfig = func() *ChainConfig { + conf := *AllCliqueProtocolChanges // copy the config + conf.Clique = nil + conf.BedrockBlock = big.NewInt(5) + conf.Optimism = &OptimismConfig{EIP1559Elasticity: 50, EIP1559Denominator: 10} + return &conf + }() )   // NetworkNames are user friendly names to use in the chain spec banner. @@ -320,6 +336,19 @@ CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun) PragueTime *uint64 `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague) VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle)   + BedrockBlock *big.Int `json:"bedrockBlock,omitempty"` // Bedrock switch block (nil = no fork, 0 = already on optimism bedrock) + RegolithTime *uint64 `json:"regolithTime,omitempty"` // Regolith switch time (nil = no fork, 0 = already on optimism regolith) + CanyonTime *uint64 `json:"canyonTime,omitempty"` // Canyon switch time (nil = no fork, 0 = already on optimism canyon) + // Delta: the Delta upgrade does not affect the execution-layer, and is thus not configurable in the chain config. + EcotoneTime *uint64 `json:"ecotoneTime,omitempty"` // Ecotone switch time (nil = no fork, 0 = already on optimism ecotone) + FjordTime *uint64 `json:"fjordTime,omitempty"` // Fjord switch time (nil = no fork, 0 = already on Optimism Fjord) + GraniteTime *uint64 `json:"graniteTime,omitempty"` // Granite switch time (nil = no fork, 0 = already on Optimism Granite) + HoloceneTime *uint64 `json:"holoceneTime,omitempty"` // Holocene switch time (nil = no fork, 0 = already on Optimism Holocene) + IsthmusTime *uint64 `json:"isthmusTime,omitempty"` // Isthmus switch time (nil = no fork, 0 = already on Optimism Isthmus) + JovianTime *uint64 `json:"jovianTime,omitempty"` // Jovian switch time (nil = no fork, 0 = already on Optimism Jovian) + + InteropTime *uint64 `json:"interopTime,omitempty"` // Interop switch time (nil = no fork, 0 = already on optimism interop) + // TerminalTotalDifficulty is the amount of total difficulty reached by // the network that triggers the consensus upgrade. TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"` @@ -342,6 +371,9 @@ // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` Clique *CliqueConfig `json:"clique,omitempty"` + + // Optimism config, nil if not active + Optimism *OptimismConfig `json:"optimism,omitempty"` }   // EthashConfig is the consensus engine configs for proof-of-work based sealing. @@ -363,6 +395,18 @@ func (c CliqueConfig) String() string { return fmt.Sprintf("clique(period: %d, epoch: %d)", c.Period, c.Epoch) }   +// OptimismConfig is the optimism config. +type OptimismConfig struct { + EIP1559Elasticity uint64 `json:"eip1559Elasticity"` + EIP1559Denominator uint64 `json:"eip1559Denominator"` + EIP1559DenominatorCanyon *uint64 `json:"eip1559DenominatorCanyon,omitempty"` +} + +// String implements the stringer interface, returning the optimism fee config details. +func (o *OptimismConfig) String() string { + return "optimism" +} + // Description returns a human-readable description of ChainConfig. func (c *ChainConfig) Description() string { var banner string @@ -374,6 +418,8 @@ network = "unknown" } banner += fmt.Sprintf("Chain ID: %v (%s)\n", c.ChainID, network) switch { + case c.Optimism != nil: + banner += "Consensus: Optimism\n" case c.Ethash != nil: banner += "Consensus: Beacon (proof-of-stake), merged from Ethash (proof-of-work)\n" case c.Clique != nil: @@ -435,6 +481,33 @@ } if c.VerkleTime != nil { banner += fmt.Sprintf(" - Verkle: @%-10v\n", *c.VerkleTime) } + if c.RegolithTime != nil { + banner += fmt.Sprintf(" - Regolith: @%-10v\n", *c.RegolithTime) + } + if c.CanyonTime != nil { + banner += fmt.Sprintf(" - Canyon: @%-10v\n", *c.CanyonTime) + } + if c.EcotoneTime != nil { + banner += fmt.Sprintf(" - Ecotone: @%-10v\n", *c.EcotoneTime) + } + if c.FjordTime != nil { + banner += fmt.Sprintf(" - Fjord: @%-10v\n", *c.FjordTime) + } + if c.GraniteTime != nil { + banner += fmt.Sprintf(" - Granite: @%-10v\n", *c.GraniteTime) + } + if c.HoloceneTime != nil { + banner += fmt.Sprintf(" - Holocene: @%-10v\n", *c.HoloceneTime) + } + if c.IsthmusTime != nil { + banner += fmt.Sprintf(" - Isthmus: @%-10v\n", *c.IsthmusTime) + } + if c.JovianTime != nil { + banner += fmt.Sprintf(" - Jovian: @%-10v\n", *c.JovianTime) + } + if c.InteropTime != nil { + banner += fmt.Sprintf(" - Interop: @%-10v\n", *c.InteropTime) + } return banner }   @@ -557,9 +630,97 @@ func (c *ChainConfig) IsEIP4762(num *big.Int, time uint64) bool { return c.IsVerkle(num, time) }   +// IsBedrock returns whether num is either equal to the Bedrock fork block or greater. +func (c *ChainConfig) IsBedrock(num *big.Int) bool { + return isBlockForked(c.BedrockBlock, num) +} + +func (c *ChainConfig) IsRegolith(time uint64) bool { + return isTimestampForked(c.RegolithTime, time) +} + +func (c *ChainConfig) IsCanyon(time uint64) bool { + return isTimestampForked(c.CanyonTime, time) +} + +func (c *ChainConfig) IsEcotone(time uint64) bool { + return isTimestampForked(c.EcotoneTime, time) +} + +func (c *ChainConfig) IsFjord(time uint64) bool { + return isTimestampForked(c.FjordTime, time) +} + +func (c *ChainConfig) IsGranite(time uint64) bool { + return isTimestampForked(c.GraniteTime, time) +} + +func (c *ChainConfig) IsHolocene(time uint64) bool { + return isTimestampForked(c.HoloceneTime, time) +} + +func (c *ChainConfig) IsIsthmus(time uint64) bool { + return isTimestampForked(c.IsthmusTime, time) +} + +func (c *ChainConfig) IsJovian(time uint64) bool { + return isTimestampForked(c.JovianTime, time) +} + +func (c *ChainConfig) IsInterop(time uint64) bool { + return isTimestampForked(c.InteropTime, time) +} + +// IsOptimism returns whether the node is an optimism node or not. +func (c *ChainConfig) IsOptimism() bool { + return c.Optimism != nil +} + +// IsOptimismBedrock returns true iff this is an optimism node & bedrock is active +func (c *ChainConfig) IsOptimismBedrock(num *big.Int) bool { + return c.IsOptimism() && c.IsBedrock(num) +} + +func (c *ChainConfig) IsOptimismRegolith(time uint64) bool { + return c.IsOptimism() && c.IsRegolith(time) +} + +func (c *ChainConfig) IsOptimismCanyon(time uint64) bool { + return c.IsOptimism() && c.IsCanyon(time) +} + +func (c *ChainConfig) IsOptimismEcotone(time uint64) bool { + return c.IsOptimism() && c.IsEcotone(time) +} + +func (c *ChainConfig) IsOptimismFjord(time uint64) bool { + return c.IsOptimism() && c.IsFjord(time) +} + +func (c *ChainConfig) IsOptimismGranite(time uint64) bool { + return c.IsOptimism() && c.IsGranite(time) +} + +func (c *ChainConfig) IsOptimismHolocene(time uint64) bool { + return c.IsOptimism() && c.IsHolocene(time) +} + +func (c *ChainConfig) IsOptimismIsthmus(time uint64) bool { + return c.IsOptimism() && c.IsIsthmus(time) +} + +func (c *ChainConfig) IsOptimismJovian(time uint64) bool { + return c.IsOptimism() && c.IsJovian(time) +} + +// IsOptimismPreBedrock returns true iff this is an optimism node & bedrock is not yet active +func (c *ChainConfig) IsOptimismPreBedrock(num *big.Int) bool { + return c.IsOptimism() && !c.IsBedrock(num) +} + // CheckCompatible checks whether scheduled fork transitions have been imported // with a mismatching chain configuration. -func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError { +func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height, time uint64, genesisTimestamp *uint64) *ConfigCompatError { var ( bhead = new(big.Int).SetUint64(height) btime = time @@ -567,7 +728,8 @@ ) // Iterate checkCompatible to find the lowest conflict. var lasterr *ConfigCompatError for { - err := c.checkCompatible(newcfg, bhead, btime) + err := c.checkCompatible(newcfg, bhead, btime, genesisTimestamp) + log.Info("Checking compatibility", "height", bhead, "time", btime, "error", err) if err == nil || (lasterr != nil && err.RewindToBlock == lasterr.RewindToBlock && err.RewindToTime == lasterr.RewindToTime) { break } @@ -650,7 +812,7 @@ } return nil }   -func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int, headTimestamp uint64) *ConfigCompatError { +func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int, headTimestamp uint64, genesisTimestamp *uint64) *ConfigCompatError { if isForkBlockIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, headNumber) { return newBlockCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) } @@ -706,28 +868,71 @@ } if isForkBlockIncompatible(c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock, headNumber) { return newBlockCompatError("Merge netsplit fork block", c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock) } - if isForkTimestampIncompatible(c.ShanghaiTime, newcfg.ShanghaiTime, headTimestamp) { + if isForkTimestampIncompatible(c.ShanghaiTime, newcfg.ShanghaiTime, headTimestamp, genesisTimestamp) { return newTimestampCompatError("Shanghai fork timestamp", c.ShanghaiTime, newcfg.ShanghaiTime) } - if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, headTimestamp) { + if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, headTimestamp, genesisTimestamp) { return newTimestampCompatError("Cancun fork timestamp", c.CancunTime, newcfg.CancunTime) } - if isForkTimestampIncompatible(c.PragueTime, newcfg.PragueTime, headTimestamp) { + if isForkTimestampIncompatible(c.PragueTime, newcfg.PragueTime, headTimestamp, genesisTimestamp) { return newTimestampCompatError("Prague fork timestamp", c.PragueTime, newcfg.PragueTime) } - if isForkTimestampIncompatible(c.VerkleTime, newcfg.VerkleTime, headTimestamp) { + if isForkTimestampIncompatible(c.VerkleTime, newcfg.VerkleTime, headTimestamp, genesisTimestamp) { return newTimestampCompatError("Verkle fork timestamp", c.VerkleTime, newcfg.VerkleTime) } + if isForkBlockIncompatible(c.BedrockBlock, newcfg.BedrockBlock, headNumber) { + return newBlockCompatError("Bedrock fork block", c.BedrockBlock, newcfg.BedrockBlock) + } + if isForkTimestampIncompatible(c.RegolithTime, newcfg.RegolithTime, headTimestamp, genesisTimestamp) { + return newTimestampCompatError("Regolith fork timestamp", c.RegolithTime, newcfg.RegolithTime) + } + if isForkTimestampIncompatible(c.CanyonTime, newcfg.CanyonTime, headTimestamp, genesisTimestamp) { + return newTimestampCompatError("Canyon fork timestamp", c.CanyonTime, newcfg.CanyonTime) + } + if isForkTimestampIncompatible(c.EcotoneTime, newcfg.EcotoneTime, headTimestamp, genesisTimestamp) { + return newTimestampCompatError("Ecotone fork timestamp", c.EcotoneTime, newcfg.EcotoneTime) + } + if isForkTimestampIncompatible(c.FjordTime, newcfg.FjordTime, headTimestamp, genesisTimestamp) { + return newTimestampCompatError("Fjord fork timestamp", c.FjordTime, newcfg.FjordTime) + } + if isForkTimestampIncompatible(c.GraniteTime, newcfg.GraniteTime, headTimestamp, genesisTimestamp) { + return newTimestampCompatError("Granite fork timestamp", c.GraniteTime, newcfg.GraniteTime) + } + if isForkTimestampIncompatible(c.HoloceneTime, newcfg.HoloceneTime, headTimestamp, genesisTimestamp) { + return newTimestampCompatError("Holocene fork timestamp", c.HoloceneTime, newcfg.HoloceneTime) + } + if isForkTimestampIncompatible(c.IsthmusTime, newcfg.IsthmusTime, headTimestamp, genesisTimestamp) { + return newTimestampCompatError("Isthmus fork timestamp", c.IsthmusTime, newcfg.IsthmusTime) + } + if isForkTimestampIncompatible(c.JovianTime, newcfg.JovianTime, headTimestamp, genesisTimestamp) { + return newTimestampCompatError("Jovian fork timestamp", c.JovianTime, newcfg.JovianTime) + } + if isForkTimestampIncompatible(c.InteropTime, newcfg.InteropTime, headTimestamp, genesisTimestamp) { + return newTimestampCompatError("Interop fork timestamp", c.InteropTime, newcfg.InteropTime) + } return nil }   // BaseFeeChangeDenominator bounds the amount the base fee can change between blocks. -func (c *ChainConfig) BaseFeeChangeDenominator() uint64 { +// The time parameters is the timestamp of the block to determine if Canyon is active or not +func (c *ChainConfig) BaseFeeChangeDenominator(time uint64) uint64 { + if c.Optimism != nil { + if c.IsCanyon(time) { + if c.Optimism.EIP1559DenominatorCanyon == nil || *c.Optimism.EIP1559DenominatorCanyon == 0 { + panic("invalid ChainConfig.Optimism.EIP1559DenominatorCanyon value: '0' or 'nil'") + } + return *c.Optimism.EIP1559DenominatorCanyon + } + return c.Optimism.EIP1559Denominator + } return DefaultBaseFeeChangeDenominator }   // ElasticityMultiplier bounds the maximum gas limit an EIP-1559 block may have. func (c *ChainConfig) ElasticityMultiplier() uint64 { + if c.Optimism != nil { + return c.Optimism.EIP1559Elasticity + } return DefaultElasticityMultiplier }   @@ -749,7 +954,7 @@ } }   // isForkBlockIncompatible returns true if a fork scheduled at block s1 cannot be -// rescheduled to block s2 because head is already past the fork. +// rescheduled to block s2 because head is already past the fork and the fork was scheduled after genesis func isForkBlockIncompatible(s1, s2, head *big.Int) bool { return (isBlockForked(s1, head) || isBlockForked(s2, head)) && !configBlockEqual(s1, s2) } @@ -776,8 +981,15 @@ }   // isForkTimestampIncompatible returns true if a fork scheduled at timestamp s1 // cannot be rescheduled to timestamp s2 because head is already past the fork. -func isForkTimestampIncompatible(s1, s2 *uint64, head uint64) bool { - return (isTimestampForked(s1, head) || isTimestampForked(s2, head)) && !configTimestampEqual(s1, s2) +func isForkTimestampIncompatible(s1, s2 *uint64, head uint64, genesis *uint64) bool { + return (isTimestampForked(s1, head) || isTimestampForked(s2, head)) && !configTimestampEqual(s1, s2) && !(isTimestampPreGenesis(s1, genesis) && isTimestampPreGenesis(s2, genesis)) +} + +func isTimestampPreGenesis(s, genesis *uint64) bool { + if s == nil || genesis == nil { + return false + } + return *s < *genesis }   // isTimestampForked returns whether a fork scheduled at timestamp s is active @@ -890,6 +1102,10 @@ IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsBerlin, IsLondon bool IsMerge, IsShanghai, IsCancun, IsPrague bool IsVerkle bool + IsOptimismBedrock, IsOptimismRegolith bool + IsOptimismCanyon, IsOptimismFjord bool + IsOptimismGranite, IsOptimismHolocene bool + IsOptimismIsthmus bool }   // Rules ensures c's ChainID is not nil. @@ -920,5 +1136,17 @@ IsCancun: isMerge && c.IsCancun(num, timestamp), IsPrague: isMerge && c.IsPrague(num, timestamp), IsVerkle: isVerkle, IsEIP4762: isVerkle, + // Optimism + IsOptimismBedrock: isMerge && c.IsOptimismBedrock(num), + IsOptimismRegolith: isMerge && c.IsOptimismRegolith(timestamp), + IsOptimismCanyon: isMerge && c.IsOptimismCanyon(timestamp), + IsOptimismFjord: isMerge && c.IsOptimismFjord(timestamp), + IsOptimismGranite: isMerge && c.IsOptimismGranite(timestamp), + IsOptimismHolocene: isMerge && c.IsOptimismHolocene(timestamp), + IsOptimismIsthmus: isMerge && c.IsOptimismIsthmus(timestamp), } } + +func (c *ChainConfig) HasOptimismWithdrawalsRoot(blockTime uint64) bool { + return c.IsOptimismIsthmus(blockTime) +}
diff --git go-ethereum/params/protocol_params.go op-geth/params/protocol_params.go index f06346db844894f90c45d4caab220de313b29ba9..e78f63b6598284372b62e9255c8b4174f58a09ee 100644 --- go-ethereum/params/protocol_params.go +++ op-geth/params/protocol_params.go @@ -22,6 +22,15 @@ "github.com/ethereum/go-ethereum/common" )   +var ( + // The base fee portion of the transaction fee accumulates at this predeploy + OptimismBaseFeeRecipient = common.HexToAddress("0x4200000000000000000000000000000000000019") + // The L1 portion of the transaction fee accumulates at this predeploy + OptimismL1FeeRecipient = common.HexToAddress("0x420000000000000000000000000000000000001A") + // The L2 withdrawals contract predeploy address + OptimismL2ToL1MessagePasser = common.HexToAddress("0x4200000000000000000000000000000000000016") +) + const ( GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations. MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be. @@ -152,6 +161,8 @@ Bn256PairingBaseGasIstanbul uint64 = 45000 // Base price for an elliptic curve pairing check Bn256PairingPerPointGasByzantium uint64 = 80000 // Byzantium per-point price for an elliptic curve pairing check Bn256PairingPerPointGasIstanbul uint64 = 34000 // Per-point price for an elliptic curve pairing check   + Bn256PairingMaxInputSizeGranite uint64 = 112687 // Maximum input size for an elliptic curve pairing check + Bls12381G1AddGas uint64 = 375 // Price for BLS12-381 elliptic curve G1 point addition Bls12381G1MulGas uint64 = 12000 // Price for BLS12-381 elliptic curve G1 point scalar multiplication Bls12381G2AddGas uint64 = 600 // Price for BLS12-381 elliptic curve G2 point addition @@ -160,6 +171,12 @@ Bls12381PairingBaseGas uint64 = 37700 // Base gas price for BLS12-381 elliptic curve pairing check Bls12381PairingPerPairGas uint64 = 32600 // Per-point pair gas price for BLS12-381 elliptic curve pairing check Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation Bls12381MapG2Gas uint64 = 23800 // Gas price for BLS12-381 mapping field element to G2 operation + + Bls12381G1MulMaxInputSizeIsthmus uint64 = 513760 // Maximum input size for BLS12-381 G1 multiple-scalar-multiply operation + Bls12381G2MulMaxInputSizeIsthmus uint64 = 488448 // Maximum input size for BLS12-381 G2 multiple-scalar-multiply operation + Bls12381PairingMaxInputSizeIsthmus uint64 = 235008 // Maximum input size for BLS12-381 pairing check + + P256VerifyGas uint64 = 3450 // secp256r1 elliptic curve signature verifier gas price   // The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529, // up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529

The optimism Goerli testnet used clique-config data to make geth internals accept blocks. Post-bedrock the beacon-consensus (i.e. follow Engine API) is now used, and the clique config is removed.

diff --git go-ethereum/core/rawdb/accessors_metadata.go op-geth/core/rawdb/accessors_metadata.go index 859566f722f5960b0ce417514d6f20ff35a5cbe9..7dae87a98f2f5383b3b14f0d04012eb64c98a91b 100644 --- go-ethereum/core/rawdb/accessors_metadata.go +++ op-geth/core/rawdb/accessors_metadata.go @@ -64,6 +64,9 @@ if err := json.Unmarshal(data, &config); err != nil { log.Error("Invalid chain config JSON", "hash", hash, "err", err) return nil } + if config.Optimism != nil { + config.Clique = nil // get rid of legacy clique data in chain config (optimism goerli issue) + } return &config }
diff --git go-ethereum/core/gen_genesis.go op-geth/core/gen_genesis.go index 2028f98edc0691b4dce10bbe0a8019f7931637f2..64840dec2d95080f15212107b7cb673ca1477489 100644 --- go-ethereum/core/gen_genesis.go +++ op-geth/core/gen_genesis.go @@ -34,6 +34,7 @@ ParentHash common.Hash `json:"parentHash"` BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"` BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"` + StateHash *common.Hash `json:"stateHash,omitempty"` } var enc Genesis enc.Config = g.Config @@ -56,6 +57,7 @@ enc.ParentHash = g.ParentHash enc.BaseFee = (*math.HexOrDecimal256)(g.BaseFee) enc.ExcessBlobGas = (*math.HexOrDecimal64)(g.ExcessBlobGas) enc.BlobGasUsed = (*math.HexOrDecimal64)(g.BlobGasUsed) + enc.StateHash = g.StateHash return json.Marshal(&enc) }   @@ -77,6 +79,7 @@ ParentHash *common.Hash `json:"parentHash"` BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"` BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"` + StateHash *common.Hash `json:"stateHash,omitempty"` } var dec Genesis if err := json.Unmarshal(input, &dec); err != nil { @@ -132,6 +135,9 @@ g.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas) } if dec.BlobGasUsed != nil { g.BlobGasUsed = (*uint64)(dec.BlobGasUsed) + } + if dec.StateHash != nil { + g.StateHash = dec.StateHash } return nil }

Testing of the superchain configuration

diff --git go-ethereum/core/superchain.go op-geth/core/superchain.go new file mode 100644 index 0000000000000000000000000000000000000000..bdc715718361ba0c0389b59fb6120fd14367df96 --- /dev/null +++ op-geth/core/superchain.go @@ -0,0 +1,91 @@ +package core + +import ( + _ "embed" + "encoding/json" + "fmt" + + "github.com/ethereum/go-ethereum/superchain" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/params" +) + +func LoadOPStackGenesis(chainID uint64) (*Genesis, error) { + chain, err := superchain.GetChain(chainID) + if err != nil { + return nil, fmt.Errorf("error getting superchain: %w", err) + } + + chConfig, err := chain.Config() + if err != nil { + return nil, fmt.Errorf("error getting chain config from superchain: %w", err) + } + + cfg, err := params.LoadOPStackChainConfig(chConfig) + if err != nil { + return nil, fmt.Errorf("failed to load params.ChainConfig for chain %d: %w", chainID, err) + } + + gen, err := readSuperchainGenesis(chain) + if err != nil { + return nil, fmt.Errorf("failed to load genesis definition for chain %d: %w", chainID, err) + } + + genesis := &Genesis{ + Config: cfg, + Nonce: gen.Nonce, + Timestamp: gen.Timestamp, + ExtraData: gen.ExtraData, + GasLimit: gen.GasLimit, + Difficulty: gen.Difficulty, + Mixhash: gen.Mixhash, + Coinbase: gen.Coinbase, + Alloc: gen.Alloc, + Number: gen.Number, + GasUsed: gen.GasUsed, + ParentHash: gen.ParentHash, + BaseFee: gen.BaseFee, + ExcessBlobGas: gen.ExcessBlobGas, + BlobGasUsed: gen.BlobGasUsed, + } + + if gen.StateHash != nil { + if len(gen.Alloc) > 0 { + return nil, fmt.Errorf("chain definition unexpectedly contains both allocation (%d) and state-hash %s", len(gen.Alloc), *gen.StateHash) + } + genesis.StateHash = gen.StateHash + genesis.Alloc = nil + } + + genesisBlock := genesis.ToBlock() + genesisBlockHash := genesisBlock.Hash() + expectedHash := chConfig.Genesis.L2.Hash + + // Verify we correctly produced the genesis config by recomputing the genesis-block-hash, + // and check the genesis matches the chain genesis definition. + if chConfig.Genesis.L2.Number != genesisBlock.NumberU64() { + switch chainID { + case params.OPMainnetChainID: + expectedHash = common.HexToHash("0x7ca38a1916c42007829c55e69d3e9a73265554b586a499015373241b8a3fa48b") + default: + return nil, fmt.Errorf("unknown stateless genesis definition for chain %d", chainID) + } + } + if expectedHash != genesisBlockHash { + return nil, fmt.Errorf("chainID=%d: produced genesis with hash %s but expected %s", chainID, genesisBlockHash, expectedHash) + } + return genesis, nil +} + +func readSuperchainGenesis(chain *superchain.Chain) (*Genesis, error) { + genData, err := chain.GenesisData() + if err != nil { + return nil, fmt.Errorf("error getting genesis data from superchain: %w", err) + } + gen := new(Genesis) + if err := json.Unmarshal(genData, gen); err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis data: %w", err) + } + return gen, nil +}
diff --git go-ethereum/params/superchain.go op-geth/params/superchain.go new file mode 100644 index 0000000000000000000000000000000000000000..2bfcef031b60f43e0cbc4e7e906cc5a0edbc9ec6 --- /dev/null +++ op-geth/params/superchain.go @@ -0,0 +1,245 @@ +package params + +import ( + "encoding/binary" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/superchain" +) + +var OPStackSupport = ProtocolVersionV0{Build: [8]byte{}, Major: 9, Minor: 0, Patch: 0, PreRelease: 0}.Encode() + +func init() { + for id, ch := range superchain.Chains { + NetworkNames[fmt.Sprintf("%d", id)] = ch.Name + } +} + +// uint64ptr is a weird helper to allow 1-line constant pointer creation. +func uint64ptr(n uint64) *uint64 { + return &n +} + +func LoadOPStackChainConfig(chConfig *superchain.ChainConfig) (*ChainConfig, error) { + hardforks := chConfig.Hardforks + genesisActivation := uint64(0) + out := &ChainConfig{ + ChainID: new(big.Int).SetUint64(chConfig.ChainID), + HomesteadBlock: common.Big0, + DAOForkBlock: nil, + DAOForkSupport: false, + EIP150Block: common.Big0, + EIP155Block: common.Big0, + EIP158Block: common.Big0, + ByzantiumBlock: common.Big0, + ConstantinopleBlock: common.Big0, + PetersburgBlock: common.Big0, + IstanbulBlock: common.Big0, + MuirGlacierBlock: common.Big0, + BerlinBlock: common.Big0, + LondonBlock: common.Big0, + ArrowGlacierBlock: common.Big0, + GrayGlacierBlock: common.Big0, + MergeNetsplitBlock: common.Big0, + ShanghaiTime: hardforks.CanyonTime, // Shanghai activates with Canyon + CancunTime: hardforks.EcotoneTime, // Cancun activates with Ecotone + PragueTime: hardforks.IsthmusTime, // Prague activates with Isthmus + BedrockBlock: common.Big0, + RegolithTime: &genesisActivation, + CanyonTime: hardforks.CanyonTime, + EcotoneTime: hardforks.EcotoneTime, + FjordTime: hardforks.FjordTime, + GraniteTime: hardforks.GraniteTime, + HoloceneTime: hardforks.HoloceneTime, + IsthmusTime: hardforks.IsthmusTime, + JovianTime: hardforks.JovianTime, + TerminalTotalDifficulty: common.Big0, + Ethash: nil, + Clique: nil, + } + + if chConfig.Optimism != nil { + out.Optimism = &OptimismConfig{ + EIP1559Elasticity: chConfig.Optimism.EIP1559Elasticity, + EIP1559Denominator: chConfig.Optimism.EIP1559Denominator, + } + if chConfig.Optimism.EIP1559DenominatorCanyon != nil { + out.Optimism.EIP1559DenominatorCanyon = uint64ptr(*chConfig.Optimism.EIP1559DenominatorCanyon) + } + } + + // special overrides for OP-Stack chains with pre-Regolith upgrade history + switch chConfig.ChainID { + case OPMainnetChainID: + out.BerlinBlock = big.NewInt(3950000) + out.LondonBlock = big.NewInt(105235063) + out.ArrowGlacierBlock = big.NewInt(105235063) + out.GrayGlacierBlock = big.NewInt(105235063) + out.MergeNetsplitBlock = big.NewInt(105235063) + out.BedrockBlock = big.NewInt(105235063) + } + + return out, nil +} + +// ProtocolVersion encodes the OP-Stack protocol version. See OP-Stack superchain-upgrade specification. +type ProtocolVersion [32]byte + +func (p ProtocolVersion) MarshalText() ([]byte, error) { + return common.Hash(p).MarshalText() +} + +func (p *ProtocolVersion) UnmarshalText(input []byte) error { + return (*common.Hash)(p).UnmarshalText(input) +} + +func (p ProtocolVersion) Parse() (versionType uint8, build [8]byte, major, minor, patch, preRelease uint32) { + versionType = p[0] + if versionType != 0 { + return + } + // bytes 1:8 reserved for future use + copy(build[:], p[8:16]) // differentiates forks and custom-builds of standard protocol + major = binary.BigEndian.Uint32(p[16:20]) // incompatible API changes + minor = binary.BigEndian.Uint32(p[20:24]) // identifies additional functionality in backwards compatible manner + patch = binary.BigEndian.Uint32(p[24:28]) // identifies backward-compatible bug-fixes + preRelease = binary.BigEndian.Uint32(p[28:32]) // identifies unstable versions that may not satisfy the above + return +} + +func (p ProtocolVersion) String() string { + versionType, build, major, minor, patch, preRelease := p.Parse() + if versionType != 0 { + return "v0.0.0-unknown." + common.Hash(p).String() + } + ver := fmt.Sprintf("v%d.%d.%d", major, minor, patch) + if preRelease != 0 { + ver += fmt.Sprintf("-%d", preRelease) + } + if build != ([8]byte{}) { + if humanBuildTag(build) { + ver += fmt.Sprintf("+%s", strings.TrimRight(string(build[:]), "\x00")) + } else { + ver += fmt.Sprintf("+0x%x", build) + } + } + return ver +} + +// humanBuildTag identifies which build tag we can stringify for human-readable versions +func humanBuildTag(v [8]byte) bool { + for i, c := range v { // following semver.org advertised regex, alphanumeric with '-' and '.', except leading '.'. + if c == 0 { // trailing zeroed are allowed + for _, d := range v[i:] { + if d != 0 { + return false + } + } + return true + } + if !((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || (c == '.' && i > 0)) { + return false + } + } + return true +} + +// ProtocolVersionComparison is used to identify how far ahead/outdated a protocol version is relative to another. +// This value is used in metrics and switch comparisons, to easily identify each type of version difference. +// Negative values mean the version is outdated. +// Positive values mean the version is up-to-date. +// Matching versions have a 0. +type ProtocolVersionComparison int + +const ( + AheadMajor ProtocolVersionComparison = 4 + OutdatedMajor ProtocolVersionComparison = -4 + AheadMinor ProtocolVersionComparison = 3 + OutdatedMinor ProtocolVersionComparison = -3 + AheadPatch ProtocolVersionComparison = 2 + OutdatedPatch ProtocolVersionComparison = -2 + AheadPrerelease ProtocolVersionComparison = 1 + OutdatedPrerelease ProtocolVersionComparison = -1 + Matching ProtocolVersionComparison = 0 + DiffVersionType ProtocolVersionComparison = 100 + DiffBuild ProtocolVersionComparison = 101 + EmptyVersion ProtocolVersionComparison = 102 + InvalidVersion ProtocolVersionComparison = 103 +) + +func (p ProtocolVersion) Compare(other ProtocolVersion) (cmp ProtocolVersionComparison) { + if p == (ProtocolVersion{}) || (other == (ProtocolVersion{})) { + return EmptyVersion + } + aVersionType, aBuild, aMajor, aMinor, aPatch, aPreRelease := p.Parse() + bVersionType, bBuild, bMajor, bMinor, bPatch, bPreRelease := other.Parse() + if aVersionType != bVersionType { + return DiffVersionType + } + if aBuild != bBuild { + return DiffBuild + } + // max values are reserved, consider versions with these values invalid + if aMajor == ^uint32(0) || aMinor == ^uint32(0) || aPatch == ^uint32(0) || aPreRelease == ^uint32(0) || + bMajor == ^uint32(0) || bMinor == ^uint32(0) || bPatch == ^uint32(0) || bPreRelease == ^uint32(0) { + return InvalidVersion + } + fn := func(a, b uint32, ahead, outdated ProtocolVersionComparison) ProtocolVersionComparison { + if a == b { + return Matching + } + if a > b { + return ahead + } + return outdated + } + if aPreRelease != 0 { // if A is a pre-release, then decrement the version before comparison + if aPatch != 0 { + aPatch -= 1 + } else if aMinor != 0 { + aMinor -= 1 + aPatch = ^uint32(0) // max value + } else if aMajor != 0 { + aMajor -= 1 + aMinor = ^uint32(0) // max value + } + } + if bPreRelease != 0 { // if B is a pre-release, then decrement the version before comparison + if bPatch != 0 { + bPatch -= 1 + } else if bMinor != 0 { + bMinor -= 1 + bPatch = ^uint32(0) // max value + } else if bMajor != 0 { + bMajor -= 1 + bMinor = ^uint32(0) // max value + } + } + if c := fn(aMajor, bMajor, AheadMajor, OutdatedMajor); c != Matching { + return c + } + if c := fn(aMinor, bMinor, AheadMinor, OutdatedMinor); c != Matching { + return c + } + if c := fn(aPatch, bPatch, AheadPatch, OutdatedPatch); c != Matching { + return c + } + return fn(aPreRelease, bPreRelease, AheadPrerelease, OutdatedPrerelease) +} + +type ProtocolVersionV0 struct { + Build [8]byte + Major, Minor, Patch, PreRelease uint32 +} + +func (v ProtocolVersionV0) Encode() (out ProtocolVersion) { + copy(out[8:16], v.Build[:]) + binary.BigEndian.PutUint32(out[16:20], v.Major) + binary.BigEndian.PutUint32(out[20:24], v.Minor) + binary.BigEndian.PutUint32(out[24:28], v.Patch) + binary.BigEndian.PutUint32(out[28:32], v.PreRelease) + return +}

Changes to the node configuration and services.

Flag changes: - Transactions can be forwarded to an RPC for sequencing. - Historical calls can be forwarded to a legacy node. - The tx pool propagation can be enabled/disabled. - The Optimism bedrock fork activation can be changed for testing.

diff --git go-ethereum/cmd/geth/config.go op-geth/cmd/geth/config.go index ecee2bfd805be9ab217a8b1dbf4c9e189660836f..837b38777b76d2890ffd7d157d7d7f63d8018b89 100644 --- go-ethereum/cmd/geth/config.go +++ op-geth/cmd/geth/config.go @@ -187,6 +187,47 @@ if ctx.IsSet(utils.OverrideCancun.Name) { v := ctx.Uint64(utils.OverrideCancun.Name) cfg.Eth.OverrideCancun = &v } + + if ctx.IsSet(utils.OverrideOptimismCanyon.Name) { + v := ctx.Uint64(utils.OverrideOptimismCanyon.Name) + cfg.Eth.OverrideOptimismCanyon = &v + } + + if ctx.IsSet(utils.OverrideOptimismEcotone.Name) { + v := ctx.Uint64(utils.OverrideOptimismEcotone.Name) + cfg.Eth.OverrideOptimismEcotone = &v + } + + if ctx.IsSet(utils.OverrideOptimismFjord.Name) { + v := ctx.Uint64(utils.OverrideOptimismFjord.Name) + cfg.Eth.OverrideOptimismFjord = &v + } + + if ctx.IsSet(utils.OverrideOptimismGranite.Name) { + v := ctx.Uint64(utils.OverrideOptimismGranite.Name) + cfg.Eth.OverrideOptimismGranite = &v + } + + if ctx.IsSet(utils.OverrideOptimismHolocene.Name) { + v := ctx.Uint64(utils.OverrideOptimismHolocene.Name) + cfg.Eth.OverrideOptimismHolocene = &v + } + + if ctx.IsSet(utils.OverrideOptimismIsthmus.Name) { + v := ctx.Uint64(utils.OverrideOptimismIsthmus.Name) + cfg.Eth.OverrideOptimismIsthmus = &v + } + + if ctx.IsSet(utils.OverrideOptimismJovian.Name) { + v := ctx.Uint64(utils.OverrideOptimismJovian.Name) + cfg.Eth.OverrideOptimismJovian = &v + } + + if ctx.IsSet(utils.OverrideOptimismInterop.Name) { + v := ctx.Uint64(utils.OverrideOptimismInterop.Name) + cfg.Eth.OverrideOptimismInterop = &v + } + if ctx.IsSet(utils.OverrideVerkle.Name) { v := ctx.Uint64(utils.OverrideVerkle.Name) cfg.Eth.OverrideVerkle = &v
diff --git go-ethereum/cmd/geth/main.go op-geth/cmd/geth/main.go index 9d9256862b632b1a4d0371024a2ca7ddb4391e1e..0f1974901648d77ecf2dffbc0b37965ed2e7d844 100644 --- go-ethereum/cmd/geth/main.go +++ op-geth/cmd/geth/main.go @@ -23,6 +23,7 @@ "os" "slices" "sort" "strconv" + "strings" "time"   "github.com/ethereum/go-ethereum/accounts" @@ -64,10 +65,19 @@ utils.USBFlag, utils.SmartCardDaemonPathFlag, utils.OverrideCancun, utils.OverrideVerkle, + utils.OverrideOptimismCanyon, + utils.OverrideOptimismEcotone, + utils.OverrideOptimismFjord, + utils.OverrideOptimismGranite, + utils.OverrideOptimismHolocene, + utils.OverrideOptimismIsthmus, + utils.OverrideOptimismJovian, + utils.OverrideOptimismInterop, utils.EnablePersonal, // deprecated utils.TxPoolLocalsFlag, utils.TxPoolNoLocalsFlag, utils.TxPoolJournalFlag, + utils.TxPoolJournalRemotesFlag, utils.TxPoolRejournalFlag, utils.TxPoolPriceLimitFlag, utils.TxPoolPriceBumpFlag, @@ -115,6 +125,7 @@ utils.MaxPeersFlag, utils.MaxPendingPeersFlag, utils.MiningEnabledFlag, // deprecated utils.MinerGasLimitFlag, + utils.MinerEffectiveGasLimitFlag, utils.MinerGasPriceFlag, utils.MinerEtherbaseFlag, // deprecated utils.MinerExtraDataFlag, @@ -143,6 +154,19 @@ utils.GpoBlocksFlag, utils.GpoPercentileFlag, utils.GpoMaxGasPriceFlag, utils.GpoIgnoreGasPriceFlag, + utils.GpoMinSuggestedPriorityFeeFlag, + utils.RollupSequencerHTTPFlag, + utils.RollupSequencerTxConditionalEnabledFlag, + utils.RollupSequencerTxConditionalCostRateLimitFlag, + utils.RollupHistoricalRPCFlag, + utils.RollupHistoricalRPCTimeoutFlag, + utils.RollupInteropRPCFlag, + utils.RollupInteropMempoolFilteringFlag, + utils.RollupDisableTxPoolGossipFlag, + utils.RollupEnableTxPoolAdmissionFlag, + utils.RollupComputePendingBlock, + utils.RollupHaltOnIncompatibleProtocolVersionFlag, + utils.RollupSuperchainUpgradesFlag, configFileFlag, utils.LogDebugFlag, utils.LogBacktraceAtFlag, @@ -310,6 +334,9 @@ 5. Networking is disabled; there is no listen-address, the maximum number of peers is set to 0, and discovery is disabled. `)   + case ctx.IsSet(utils.OPNetworkFlag.Name): + log.Info("Starting geth on an OP network...", "network", ctx.String(utils.OPNetworkFlag.Name)) + case !ctx.IsSet(utils.NetworkIdFlag.Name): log.Info("Starting Geth on Ethereum mainnet...") } @@ -320,7 +347,14 @@ if !ctx.IsSet(utils.HoleskyFlag.Name) && !ctx.IsSet(utils.SepoliaFlag.Name) && !ctx.IsSet(utils.DeveloperFlag.Name) { // Nope, we're really on mainnet. Bump that cache up! + // Note: If we don't set the OPNetworkFlag and have already initialized the database, we may hit this case. log.Info("Bumping default cache on mainnet", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 4096) + ctx.Set(utils.CacheFlag.Name, strconv.Itoa(4096)) + } + } else if ctx.String(utils.SyncModeFlag.Name) != "light" && !ctx.IsSet(utils.CacheFlag.Name) && ctx.IsSet(utils.OPNetworkFlag.Name) { + // We haven't set the cache, but may used the OP network flag we may be on an OP stack mainnet. + if strings.Contains(ctx.String(utils.OPNetworkFlag.Name), "mainnet") { + log.Info("Bumping default cache on mainnet", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 4096, "network", ctx.String(utils.OPNetworkFlag.Name)) ctx.Set(utils.CacheFlag.Name, strconv.Itoa(4096)) } }
diff --git go-ethereum/cmd/utils/flags.go op-geth/cmd/utils/flags.go index f079df83b9daad5b96ad6bf48b4e9412ca4aef48..4f8cbc9b26894e1ba6776ddffcb05aaff6fdcc68 100644 --- go-ethereum/cmd/utils/flags.go +++ op-geth/cmd/utils/flags.go @@ -72,6 +72,7 @@ "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/p2p/netutil" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/superchain" "github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb/hashdb" "github.com/ethereum/go-ethereum/triedb/pathdb" @@ -153,6 +154,15 @@ Name: "holesky", Usage: "Holesky network: pre-configured proof-of-stake test network", Category: flags.EthCategory, } + + OPNetworkFlag = &cli.StringFlag{ + Name: "op-network", + Aliases: []string{"beta.op-network"}, + Usage: "Select a pre-configured OP-Stack network (warning: op-mainnet and op-goerli require special sync," + + " datadir is recommended), options: " + strings.Join(superchain.ChainNames(), ", "), + Category: flags.EthCategory, + } + // Dev mode DeveloperFlag = &cli.BoolFlag{ Name: "dev", @@ -243,6 +253,46 @@ Name: "override.verkle", Usage: "Manually specify the Verkle fork timestamp, overriding the bundled setting", Category: flags.EthCategory, } + OverrideOptimismCanyon = &cli.Uint64Flag{ + Name: "override.canyon", + Usage: "Manually specify the Optimism Canyon fork timestamp, overriding the bundled setting", + Category: flags.EthCategory, + } + OverrideOptimismEcotone = &cli.Uint64Flag{ + Name: "override.ecotone", + Usage: "Manually specify the Optimism Ecotone fork timestamp, overriding the bundled setting", + Category: flags.EthCategory, + } + OverrideOptimismFjord = &cli.Uint64Flag{ + Name: "override.fjord", + Usage: "Manually specify the Optimism Fjord fork timestamp, overriding the bundled setting", + Category: flags.EthCategory, + } + OverrideOptimismGranite = &cli.Uint64Flag{ + Name: "override.granite", + Usage: "Manually specify the Optimism Granite fork timestamp, overriding the bundled setting", + Category: flags.EthCategory, + } + OverrideOptimismHolocene = &cli.Uint64Flag{ + Name: "override.holocene", + Usage: "Manually specify the Optimism Holocene fork timestamp, overriding the bundled setting", + Category: flags.EthCategory, + } + OverrideOptimismIsthmus = &cli.Uint64Flag{ + Name: "override.isthmus", + Usage: "Manually specify the Optimism Isthmus fork timestamp, overriding the bundled setting", + Category: flags.EthCategory, + } + OverrideOptimismJovian = &cli.Uint64Flag{ + Name: "override.jovian", + Usage: "Manually specify the Optimism Jovian fork timestamp, overriding the bundled setting", + Category: flags.EthCategory, + } + OverrideOptimismInterop = &cli.Uint64Flag{ + Name: "override.interop", + Usage: "Manually specify the Optimsim Interop feature-set fork timestamp, overriding the bundled setting", + Category: flags.EthCategory, + } SyncModeFlag = &cli.StringFlag{ Name: "syncmode", Usage: `Blockchain sync mode ("snap" or "full")`, @@ -339,6 +389,11 @@ TxPoolJournalFlag = &cli.StringFlag{ Name: "txpool.journal", Usage: "Disk journal for local transaction to survive node restarts", Value: ethconfig.Defaults.TxPool.Journal, + Category: flags.TxPoolCategory, + } + TxPoolJournalRemotesFlag = &cli.BoolFlag{ + Name: "txpool.journalremotes", + Usage: "Includes remote transactions in the journal", Category: flags.TxPoolCategory, } TxPoolRejournalFlag = &cli.DurationFlag{ @@ -474,6 +529,12 @@ Usage: "Target gas ceiling for mined blocks", Value: ethconfig.Defaults.Miner.GasCeil, Category: flags.MinerCategory, } + MinerEffectiveGasLimitFlag = &cli.Uint64Flag{ + Name: "miner.effectivegaslimit", + Usage: "If non-zero, an effective gas limit to apply in addition to the block header gaslimit.", + Value: 0, + Category: flags.MinerCategory, + } MinerGasPriceFlag = &flags.BigFlag{ Name: "miner.gasprice", Usage: "Minimum gas price for mining a transaction", @@ -774,7 +835,7 @@ Name: "discovery.v4", Aliases: []string{"discv4"}, Usage: "Enables the V4 discovery mechanism", Category: flags.NetworkingCategory, - Value: true, + Value: false, } DiscoveryV5Flag = &cli.BoolFlag{ Name: "discovery.v5", @@ -839,6 +900,84 @@ Usage: "Gas price below which gpo will ignore transactions", Value: ethconfig.Defaults.GPO.IgnorePrice.Int64(), Category: flags.GasPriceCategory, } + GpoMinSuggestedPriorityFeeFlag = &cli.Int64Flag{ + Name: "gpo.minsuggestedpriorityfee", + Usage: "Minimum transaction priority fee to suggest. Used on OP chains when blocks are not full.", + Value: ethconfig.Defaults.GPO.MinSuggestedPriorityFee.Int64(), + Category: flags.GasPriceCategory, + } + + // Rollup Flags + RollupSequencerHTTPFlag = &cli.StringFlag{ + Name: "rollup.sequencerhttp", + Usage: "HTTP endpoint for the sequencer mempool", + Category: flags.RollupCategory, + } + + RollupHistoricalRPCFlag = &cli.StringFlag{ + Name: "rollup.historicalrpc", + Usage: "RPC endpoint for historical data.", + Category: flags.RollupCategory, + } + + RollupHistoricalRPCTimeoutFlag = &cli.StringFlag{ + Name: "rollup.historicalrpctimeout", + Usage: "Timeout for historical RPC requests.", + Value: "5s", + Category: flags.RollupCategory, + } + + RollupInteropRPCFlag = &cli.StringFlag{ + Name: "rollup.interoprpc", + Usage: "RPC endpoint for interop message verification (experimental).", + Category: flags.RollupCategory, + } + + RollupInteropMempoolFilteringFlag = &cli.BoolFlag{ + Name: "rollup.interopmempoolfiltering", + Usage: "If using interop, transactions are checked for interop validity before being added to the mempool (experimental).", + Category: flags.RollupCategory, + } + + RollupDisableTxPoolGossipFlag = &cli.BoolFlag{ + Name: "rollup.disabletxpoolgossip", + Usage: "Disable transaction pool gossip.", + Category: flags.RollupCategory, + } + RollupEnableTxPoolAdmissionFlag = &cli.BoolFlag{ + Name: "rollup.enabletxpooladmission", + Usage: "Add RPC-submitted transactions to the txpool (on by default if --rollup.sequencerhttp is not set).", + Category: flags.RollupCategory, + } + RollupComputePendingBlock = &cli.BoolFlag{ + Name: "rollup.computependingblock", + Usage: "By default the pending block equals the latest block to save resources and not leak txs from the tx-pool, this flag enables computing of the pending block from the tx-pool instead.", + Category: flags.RollupCategory, + } + RollupHaltOnIncompatibleProtocolVersionFlag = &cli.StringFlag{ + Name: "rollup.halt", + Usage: "Opt-in option to halt on incompatible protocol version requirements of the given level (major/minor/patch/none), as signaled through the Engine API by the rollup node", + Category: flags.RollupCategory, + } + RollupSuperchainUpgradesFlag = &cli.BoolFlag{ + Name: "rollup.superchain-upgrades", + Aliases: []string{"beta.rollup.superchain-upgrades"}, + Usage: "Apply superchain-registry config changes to the local chain-configuration", + Category: flags.RollupCategory, + Value: true, + } + RollupSequencerTxConditionalEnabledFlag = &cli.BoolFlag{ + Name: "rollup.sequencertxconditionalenabled", + Usage: "Serve the eth_sendRawTransactionConditional endpoint and apply the conditional constraints on mempool inclusion & block building", + Category: flags.RollupCategory, + Value: false, + } + RollupSequencerTxConditionalCostRateLimitFlag = &cli.IntFlag{ + Name: "rollup.sequencertxconditionalcostratelimit", + Usage: "Maximum cost -- storage lookups -- allowed for conditional transactions in a given second", + Category: flags.RollupCategory, + Value: 5000, + }   // Metrics flags MetricsEnabledFlag = &cli.BoolFlag{ @@ -937,7 +1076,7 @@ SepoliaFlag, HoleskyFlag, } // NetworkFlags is the flag group of all built-in supported networks. - NetworkFlags = append([]cli.Flag{MainnetFlag}, TestnetFlags...) + NetworkFlags = append([]cli.Flag{MainnetFlag, OPNetworkFlag}, TestnetFlags...)   // DatabaseFlags is the flag group of all database flags. DatabaseFlags = []cli.Flag{ @@ -961,6 +1100,9 @@ } if ctx.Bool(HoleskyFlag.Name) { return filepath.Join(path, "holesky") } + if ctx.IsSet(OPNetworkFlag.Name) { + return filepath.Join(path, ctx.String(OPNetworkFlag.Name)) + } return path } Fatalf("Cannot determine default data directory, please set manually (--datadir)") @@ -1050,6 +1192,13 @@ case ctx.IsSet(BootnodesFlag.Name): urls = SplitAndTrim(ctx.String(BootnodesFlag.Name)) case cfg.BootstrapNodesV5 != nil: return // already set, don't apply defaults. + case ctx.IsSet(OPNetworkFlag.Name): + network := ctx.String(OPNetworkFlag.Name) + if strings.Contains(strings.ToLower(network), "mainnet") { + urls = params.V5OPBootnodes + } else { + urls = params.V5OPTestnetBootnodes + } }   cfg.BootstrapNodesV5 = make([]*enode.Node, 0, len(urls)) @@ -1405,6 +1554,8 @@ case ctx.Bool(SepoliaFlag.Name) && cfg.DataDir == node.DefaultDataDir(): cfg.DataDir = filepath.Join(node.DefaultDataDir(), "sepolia") case ctx.Bool(HoleskyFlag.Name) && cfg.DataDir == node.DefaultDataDir(): cfg.DataDir = filepath.Join(node.DefaultDataDir(), "holesky") + case ctx.IsSet(OPNetworkFlag.Name) && cfg.DataDir == node.DefaultDataDir(): + cfg.DataDir = filepath.Join(node.DefaultDataDir(), ctx.String(OPNetworkFlag.Name)) } }   @@ -1421,6 +1572,9 @@ } if ctx.IsSet(GpoIgnoreGasPriceFlag.Name) { cfg.IgnorePrice = big.NewInt(ctx.Int64(GpoIgnoreGasPriceFlag.Name)) } + if ctx.IsSet(GpoMinSuggestedPriorityFeeFlag.Name) { + cfg.MinSuggestedPriorityFee = big.NewInt(ctx.Int64(GpoMinSuggestedPriorityFeeFlag.Name)) + } }   func setTxPool(ctx *cli.Context, cfg *legacypool.Config) { @@ -1440,6 +1594,9 @@ } if ctx.IsSet(TxPoolJournalFlag.Name) { cfg.Journal = ctx.String(TxPoolJournalFlag.Name) } + if ctx.IsSet(TxPoolJournalRemotesFlag.Name) { + cfg.JournalRemote = ctx.Bool(TxPoolJournalRemotesFlag.Name) + } if ctx.IsSet(TxPoolRejournalFlag.Name) { cfg.Rejournal = ctx.Duration(TxPoolRejournalFlag.Name) } @@ -1464,6 +1621,11 @@ } if ctx.IsSet(TxPoolLifetimeFlag.Name) { cfg.Lifetime = ctx.Duration(TxPoolLifetimeFlag.Name) } + if ctx.IsSet(MinerEffectiveGasLimitFlag.Name) { + // While technically this is a miner config parameter, we also want the txpool to enforce + // it to avoid accepting transactions that can never be included in a block. + cfg.EffectiveGasCeil = ctx.Uint64(MinerEffectiveGasLimitFlag.Name) + } }   func setBlobPool(ctx *cli.Context, cfg *blobpool.Config) { @@ -1488,6 +1650,9 @@ } if ctx.IsSet(MinerGasLimitFlag.Name) { cfg.GasCeil = ctx.Uint64(MinerGasLimitFlag.Name) } + if ctx.IsSet(MinerEffectiveGasLimitFlag.Name) { + cfg.EffectiveGasCeil = ctx.Uint64(MinerEffectiveGasLimitFlag.Name) + } if ctx.IsSet(MinerGasPriceFlag.Name) { cfg.GasPrice = flags.GlobalBig(ctx, MinerGasPriceFlag.Name) } @@ -1497,6 +1662,9 @@ } if ctx.IsSet(MinerNewPayloadTimeoutFlag.Name) { log.Warn("The flag --miner.newpayload-timeout is deprecated and will be removed, please use --miner.recommit") cfg.Recommit = ctx.Duration(MinerNewPayloadTimeoutFlag.Name) + } + if ctx.IsSet(RollupComputePendingBlock.Name) { + cfg.RollupComputePendingBlock = ctx.Bool(RollupComputePendingBlock.Name) } }   @@ -1572,7 +1740,7 @@ // SetEthConfig applies eth-related command line flags to the config. func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { // Avoid conflicting network flags - CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag) + CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag, OPNetworkFlag) CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer   // Set configurations from CLI flags @@ -1718,6 +1886,29 @@ } else { cfg.EthDiscoveryURLs = SplitAndTrim(urls) } } + // Only configure sequencer http flag if we're running in verifier mode i.e. --mine is disabled. + if ctx.IsSet(RollupSequencerHTTPFlag.Name) && !ctx.IsSet(MiningEnabledFlag.Name) { + cfg.RollupSequencerHTTP = ctx.String(RollupSequencerHTTPFlag.Name) + } + if ctx.IsSet(RollupHistoricalRPCFlag.Name) { + cfg.RollupHistoricalRPC = ctx.String(RollupHistoricalRPCFlag.Name) + } + if ctx.IsSet(RollupHistoricalRPCTimeoutFlag.Name) { + cfg.RollupHistoricalRPCTimeout = ctx.Duration(RollupHistoricalRPCTimeoutFlag.Name) + } + if ctx.IsSet(RollupInteropRPCFlag.Name) { + cfg.InteropMessageRPC = ctx.String(RollupInteropRPCFlag.Name) + } + if ctx.IsSet(RollupInteropMempoolFilteringFlag.Name) { + cfg.InteropMempoolFiltering = ctx.Bool(RollupInteropMempoolFilteringFlag.Name) + } + cfg.RollupDisableTxPoolGossip = ctx.Bool(RollupDisableTxPoolGossipFlag.Name) + cfg.RollupDisableTxPoolAdmission = cfg.RollupSequencerHTTP != "" && !ctx.Bool(RollupEnableTxPoolAdmissionFlag.Name) + cfg.RollupHaltOnIncompatibleProtocolVersion = ctx.String(RollupHaltOnIncompatibleProtocolVersionFlag.Name) + cfg.ApplySuperchainUpgrades = ctx.Bool(RollupSuperchainUpgradesFlag.Name) + cfg.RollupSequencerTxConditionalEnabled = ctx.Bool(RollupSequencerTxConditionalEnabledFlag.Name) + cfg.RollupSequencerTxConditionalCostRateLimit = ctx.Int(RollupSequencerTxConditionalCostRateLimitFlag.Name) + // Override any default configs for hard coded networks. switch { case ctx.Bool(MainnetFlag.Name): @@ -1795,7 +1986,7 @@ chaindb := tryMakeReadOnlyDatabase(ctx, stack) if rawdb.ReadCanonicalHash(chaindb, 0) != (common.Hash{}) { cfg.Genesis = nil // fallback to db content   - //validate genesis has PoS enabled in block 0 + // validate genesis has PoS enabled in block 0 genesis, err := core.ReadGenesis(chaindb) if err != nil { Fatalf("Could not read genesis from database: %v", err) @@ -1814,6 +2005,12 @@ } if !ctx.IsSet(MinerGasPriceFlag.Name) { cfg.Miner.GasPrice = big.NewInt(1) } + case ctx.IsSet(OPNetworkFlag.Name): + genesis := MakeGenesis(ctx) + if !ctx.IsSet(NetworkIdFlag.Name) { + cfg.NetworkId = genesis.Config.ChainID.Uint64() + } + cfg.Genesis = genesis default: if cfg.NetworkId == 1 { SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash) @@ -2074,8 +2271,7 @@ }   func IsNetworkPreset(ctx *cli.Context) bool { for _, flag := range NetworkFlags { - bFlag, _ := flag.(*cli.BoolFlag) - if ctx.IsSet(bFlag.Name) { + if ctx.IsSet(flag.Names()[0]) { return true } } @@ -2115,6 +2311,17 @@ case ctx.Bool(HoleskyFlag.Name): genesis = core.DefaultHoleskyGenesisBlock() case ctx.Bool(SepoliaFlag.Name): genesis = core.DefaultSepoliaGenesisBlock() + case ctx.IsSet(OPNetworkFlag.Name): + name := ctx.String(OPNetworkFlag.Name) + ch, err := superchain.ChainIDByName(name) + if err != nil { + Fatalf("failed to load OP-Stack chain %q: %v", name, err) + } + genesis, err := core.LoadOPStackGenesis(ch) + if err != nil { + Fatalf("failed to load genesis for OP-Stack chain %q (%d): %v", name, ch, err) + } + return genesis case ctx.Bool(DeveloperFlag.Name): Fatalf("Developer chains are ephemeral") }
diff --git go-ethereum/internal/flags/categories.go op-geth/internal/flags/categories.go index d426add55b10b62cc75ba4f294f9f2fd1b4ae06a..d9c2d9894afae2099988e8b2729454d77509ae11 100644 --- go-ethereum/internal/flags/categories.go +++ op-geth/internal/flags/categories.go @@ -32,6 +32,7 @@ NetworkingCategory = "NETWORKING" MinerCategory = "MINER" GasPriceCategory = "GAS PRICE ORACLE" VMCategory = "VIRTUAL MACHINE" + RollupCategory = "ROLLUP NODE" LoggingCategory = "LOGGING AND DEBUGGING" MetricsCategory = "METRICS AND STATS" MiscCategory = "MISC"

List the op-geth and upstream go-ethereum versions.

diff --git go-ethereum/build/ci.go op-geth/build/ci.go index fd51b90d17a14dadcedca1f96d089644ce3a53cc..632d6c3835db512ff1add8ddd99dce3ec6225493 100644 --- go-ethereum/build/ci.go +++ op-geth/build/ci.go @@ -240,6 +240,9 @@ if env.Commit != "" { ld = append(ld, "-X", "github.com/ethereum/go-ethereum/internal/version.gitCommit="+env.Commit) ld = append(ld, "-X", "github.com/ethereum/go-ethereum/internal/version.gitDate="+env.Date) } + if env.Tag != "" { + ld = append(ld, "-X", "github.com/ethereum/go-ethereum/version.gitTag="+env.Tag) + } // Strip DWARF on darwin. This used to be required for certain things, // and there is no downside to this, so we just keep doing it. if runtime.GOOS == "darwin" { @@ -912,10 +915,10 @@ return wdflag }   func isUnstableBuild(env build.Environment) bool { - if env.Tag != "" { - return false + if env.Tag == "untagged" || env.Tag == "" { + return true } - return true + return false }   type debPackage struct {
diff --git go-ethereum/cmd/geth/misccmd.go op-geth/cmd/geth/misccmd.go index 2d31f3abe7b28ff290860b8720bd782873474077..033f715b57099bc7b220349d08e419f5f771f141 100644 --- go-ethereum/cmd/geth/misccmd.go +++ op-geth/cmd/geth/misccmd.go @@ -79,6 +79,7 @@ } if git.Date != "" { fmt.Println("Git Commit Date:", git.Date) } + fmt.Println("Upstream Version:", version.UpstreamGethWithMeta) fmt.Println("Architecture:", runtime.GOARCH) fmt.Println("Go Version:", runtime.Version()) fmt.Println("Operating System:", runtime.GOOS)
diff --git go-ethereum/eth/ethconfig/config.go op-geth/eth/ethconfig/config.go index 6b75ab816fa6fcf3ae817e389200b4260751b7c6..7668ee28f5fbf54bcc7dd3373ecd1092e1ce9a9a 100644 --- go-ethereum/eth/ethconfig/config.go +++ op-geth/eth/ethconfig/config.go @@ -38,12 +38,13 @@ )   // FullNodeGPO contains default gasprice oracle settings for full node. var FullNodeGPO = gasprice.Config{ - Blocks: 20, - Percentile: 60, - MaxHeaderHistory: 1024, - MaxBlockHistory: 1024, - MaxPrice: gasprice.DefaultMaxPrice, - IgnorePrice: gasprice.DefaultIgnorePrice, + Blocks: 20, + Percentile: 60, + MaxHeaderHistory: 1024, + MaxBlockHistory: 1024, + MaxPrice: gasprice.DefaultMaxPrice, + IgnorePrice: gasprice.DefaultIgnorePrice, + MinSuggestedPriorityFee: gasprice.DefaultMinSuggestedPriorityFee, }   // Defaults contains default settings for use on the Ethereum main net. @@ -153,12 +154,46 @@ OverrideCancun *uint64 `toml:",omitempty"`   // OverrideVerkle (TODO: remove after the fork) OverrideVerkle *uint64 `toml:",omitempty"` + + OverrideOptimismCanyon *uint64 `toml:",omitempty"` + + OverrideOptimismEcotone *uint64 `toml:",omitempty"` + + OverrideOptimismFjord *uint64 `toml:",omitempty"` + + OverrideOptimismGranite *uint64 `toml:",omitempty"` + + OverrideOptimismHolocene *uint64 `toml:",omitempty"` + + OverrideOptimismIsthmus *uint64 `toml:",omitempty"` + + OverrideOptimismJovian *uint64 `toml:",omitempty"` + + OverrideOptimismInterop *uint64 `toml:",omitempty"` + + // ApplySuperchainUpgrades requests the node to load chain-configuration from the superchain-registry. + ApplySuperchainUpgrades bool `toml:",omitempty"` + + RollupSequencerHTTP string + RollupSequencerTxConditionalEnabled bool + RollupSequencerTxConditionalCostRateLimit int + RollupHistoricalRPC string + RollupHistoricalRPCTimeout time.Duration + RollupDisableTxPoolGossip bool + RollupDisableTxPoolAdmission bool + RollupHaltOnIncompatibleProtocolVersion string + + InteropMessageRPC string `toml:",omitempty"` + InteropMempoolFiltering bool `toml:",omitempty"` }   // CreateConsensusEngine creates a consensus engine for the given chain config. // Clique is allowed for now to live standalone, but ethash is forbidden and can // only exist on already merged networks. func CreateConsensusEngine(config *params.ChainConfig, db ethdb.Database) (consensus.Engine, error) { + if config.Optimism != nil { + return beacon.New(&beacon.OpLegacy{}), nil + } if config.TerminalTotalDifficulty == nil { log.Error("Geth only supports PoS networks. Please transition legacy networks using Geth v1.13.x.") return nil, fmt.Errorf("'terminalTotalDifficulty' is not set in genesis block")
diff --git go-ethereum/eth/handler.go op-geth/eth/handler.go index 9820118173c38f38e10934dfe07ae69be1cc0f3f..01c6dc314aade018534c55f0ad7498a318cce00e 100644 --- go-ethereum/eth/handler.go +++ op-geth/eth/handler.go @@ -92,6 +92,7 @@ Sync ethconfig.SyncMode // Whether to snap or full sync BloomCache uint64 // Megabytes to alloc for snap sync bloom EventMux *event.TypeMux // Legacy event mux, deprecate for `feed` RequiredBlocks map[uint64]common.Hash // Hard coded map of required block hashes for sync challenges + NoTxGossip bool // Disable P2P transaction gossip }   type handler struct { @@ -106,6 +107,8 @@ database ethdb.Database txpool txPool chain *core.BlockChain maxPeers int + + noTxGossip bool   downloader *downloader.Downloader txFetcher *fetcher.TxFetcher @@ -139,6 +142,7 @@ forkFilter: forkid.NewFilter(config.Chain), eventMux: config.EventMux, database: config.Database, txpool: config.TxPool, + noTxGossip: config.NoTxGossip, chain: config.Chain, peers: newPeerSet(), requiredBlocks: config.RequiredBlocks, @@ -165,9 +169,10 @@ log.Warn("Switch sync mode from full sync to snap sync", "reason", "head state missing") } } else { head := h.chain.CurrentBlock() - if head.Number.Uint64() > 0 && h.chain.HasState(head.Root) { + if head.Number.Uint64() > 0 && h.chain.HasState(head.Root) && (!config.Chain.Config().IsOptimism() || head.Number.Cmp(config.Chain.Config().BedrockBlock) != 0) { // Print warning log if database is not empty to run snap sync. - log.Warn("Switch sync mode from snap sync to full sync", "reason", "snap sync complete") + // For OP chains, snap sync from bedrock block is allowed. + log.Warn("Switch sync mode from snap sync to full sync") } else { // If snap sync was requested and our database is empty, grant it h.snapSync.Store(true) @@ -178,8 +183,14 @@ // If snap sync is requested but snapshots are disabled, fail loudly if h.snapSync.Load() && config.Chain.Snapshots() == nil { return nil, errors.New("snap sync not supported with snapshots disabled") } + // if the chainID is set, pass it to the downloader for use in sync + // this might not be set in tests + var chainID uint64 + if cid := h.chain.Config().ChainID; cid != nil { + chainID = cid.Uint64() + } // Construct the downloader (long sync) - h.downloader = downloader.New(config.Database, h.eventMux, h.chain, h.removePeer, h.enableSyncedFeatures) + h.downloader = downloader.New(config.Database, h.eventMux, h.chain, h.removePeer, h.enableSyncedFeatures, chainID)   fetchTx := func(peer string, hashes []common.Hash) error { p := h.peers.peer(peer)
diff --git go-ethereum/eth/handler_eth.go op-geth/eth/handler_eth.go index b2cd52a22105ac700782008678229d33853e4004..be0abc1b60855ad2c941f829515ebf8e6b28390f 100644 --- go-ethereum/eth/handler_eth.go +++ op-geth/eth/handler_eth.go @@ -20,6 +20,7 @@ import ( "errors" "fmt"   + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/protocols/eth" @@ -31,7 +32,20 @@ // packets that are sent as replies or broadcasts. type ethHandler handler   func (h *ethHandler) Chain() *core.BlockChain { return h.chain } -func (h *ethHandler) TxPool() eth.TxPool { return h.txpool } + +// NilPool satisfies the TxPool interface but does not return any tx in the +// pool. It is used to disable transaction gossip. +type NilPool struct{} + +// NilPool Get always returns nil +func (n NilPool) Get(hash common.Hash) *types.Transaction { return nil } + +func (h *ethHandler) TxPool() eth.TxPool { + if h.noTxGossip { + return &NilPool{} + } + return h.txpool +}   // RunPeer is invoked when a peer joins on the `eth` protocol. func (h *ethHandler) RunPeer(peer *eth.Peer, hand eth.Handler) error { @@ -49,6 +63,9 @@ // AcceptTxs retrieves whether transaction processing is enabled on the node // or if inbound transactions should simply be dropped. func (h *ethHandler) AcceptTxs() bool { + if h.noTxGossip { + return false + } return h.synced.Load() }
diff --git go-ethereum/core/blockchain.go op-geth/core/blockchain.go index 6aac541ba01e44e79967b29d1eb66ab166c6d942..61d41ce7ac06ad035da3ffb2b7f66a8d8b9479ec 100644 --- go-ethereum/core/blockchain.go +++ op-geth/core/blockchain.go @@ -291,6 +291,10 @@ } log.Info(strings.Repeat("-", 153)) log.Info("")   + if chainConfig.IsOptimism() && chainConfig.RegolithTime == nil { + log.Warn("Optimism RegolithTime has not been set") + } + bc := &BlockChain{ chainConfig: chainConfig, cacheConfig: cacheConfig, @@ -410,10 +414,6 @@ return nil, err } } } - // The first thing the node will do is reconstruct the verification data for - // the head block (ethash cache or clique voting snapshot). Might as well do - // it in advance. - bc.engine.VerifyHeader(bc, bc.CurrentHeader())   if bc.logger != nil && bc.logger.OnBlockchainInit != nil { bc.logger.OnBlockchainInit(chainConfig) @@ -466,6 +466,13 @@ bc.SetHead(compatErr.RewindToBlock) } rawdb.WriteChainConfig(db, genesisHash, chainConfig) } + + // OP-Stack diff: deliberately only check header after reorg handling, to get un-stuck of degenerate reorg cases. + // The first thing the node will do is reconstruct the verification data for + // the head block (ethash cache or clique voting snapshot). Might as well do + // it in advance. + bc.engine.VerifyHeader(bc, bc.CurrentHeader()) + // Start tx indexer if it's enabled. if txLookupLimit != nil { bc.txIndexer = newTxIndexer(*txLookupLimit, bc)
diff --git go-ethereum/eth/catalyst/superchain.go op-geth/eth/catalyst/superchain.go new file mode 100644 index 0000000000000000000000000000000000000000..503519889f4f050ad0aa739525022044fa842bc6 --- /dev/null +++ op-geth/eth/catalyst/superchain.go @@ -0,0 +1,66 @@ +package catalyst + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" +) + +var ( + requiredProtocolDeltaGauge = metrics.NewRegisteredGauge("superchain/required/delta", nil) + recommendedProtocolDeltaGauge = metrics.NewRegisteredGauge("superchain/recommended/delta", nil) +) + +type SuperchainSignal struct { + Recommended params.ProtocolVersion `json:"recommended"` + Required params.ProtocolVersion `json:"required"` +} + +func (api *ConsensusAPI) SignalSuperchainV1(signal *SuperchainSignal) (params.ProtocolVersion, error) { + if signal == nil { + log.Info("Received empty superchain version signal", "local", params.OPStackSupport) + return params.OPStackSupport, nil + } + // update metrics and log any warnings/info + requiredProtocolDeltaGauge.Update(int64(params.OPStackSupport.Compare(signal.Required))) + recommendedProtocolDeltaGauge.Update(int64(params.OPStackSupport.Compare(signal.Recommended))) + logger := log.New("local", params.OPStackSupport, "required", signal.Required, "recommended", signal.Recommended) + LogProtocolVersionSupport(logger, params.OPStackSupport, signal.Recommended, "recommended") + LogProtocolVersionSupport(logger, params.OPStackSupport, signal.Required, "required") + + if err := api.eth.HandleRequiredProtocolVersion(signal.Required); err != nil { + log.Error("Failed to handle required protocol version", "err", err, "required", signal.Required) + return params.OPStackSupport, err + } + + return params.OPStackSupport, nil +} + +func LogProtocolVersionSupport(logger log.Logger, local, other params.ProtocolVersion, name string) { + switch local.Compare(other) { + case params.AheadMajor: + logger.Info(fmt.Sprintf("Ahead with major %s protocol version change", name)) + case params.AheadMinor, params.AheadPatch, params.AheadPrerelease: + logger.Debug(fmt.Sprintf("Ahead with compatible %s protocol version change", name)) + case params.Matching: + logger.Debug(fmt.Sprintf("Latest %s protocol version is supported", name)) + case params.OutdatedMajor: + logger.Error(fmt.Sprintf("Outdated with major %s protocol change", name)) + case params.OutdatedMinor: + logger.Warn(fmt.Sprintf("Outdated with minor backward-compatible %s protocol change", name)) + case params.OutdatedPatch: + logger.Info(fmt.Sprintf("Outdated with support backward-compatible %s protocol change", name)) + case params.OutdatedPrerelease: + logger.Debug(fmt.Sprintf("New %s protocol pre-release is available", name)) + case params.DiffBuild: + logger.Debug(fmt.Sprintf("Ignoring %s protocolversion signal, local build is different", name)) + case params.DiffVersionType: + logger.Warn(fmt.Sprintf("Failed to recognize %s protocol version signal version-type", name)) + case params.EmptyVersion: + logger.Debug(fmt.Sprintf("No %s protocol version available to check", name)) + case params.InvalidVersion: + logger.Warn(fmt.Sprintf("Invalid protocol version comparison with %s", name)) + } +}

Snap-sync does not serve unprefixed code by default.

diff --git go-ethereum/core/blockchain_reader.go op-geth/core/blockchain_reader.go index cf72e98cb280effaf787ee3b3128d332b83c1497..65b85417c1d237bb767245bcd35073d0eae4519f 100644 --- go-ethereum/core/blockchain_reader.go +++ op-geth/core/blockchain_reader.go @@ -350,6 +350,16 @@ // in Verkle scheme. Fix it once snap-sync is supported for Verkle. return bc.statedb.ContractCodeWithPrefix(common.Address{}, hash) }   +// ContractCode retrieves a blob of data associated with a contract hash +// either from ephemeral in-memory cache, or from persistent storage. +// OP-Stack diff: this is a legacy-method, replaced by ContractCodeWithPrefix in upstream, +// but required for old databases to serve snap-sync. +// It tries prefix-style contract-code retrieval first, then falls back to legacy code storage. +// Returns nil if not found. +func (bc *BlockChain) ContractCode(hash common.Hash) []byte { + return bc.statedb.ContractCode(common.Address{}, hash) +} + // State returns a new mutable state based on the current HEAD block. func (bc *BlockChain) State() (*state.StateDB, error) { return bc.StateAt(bc.CurrentBlock().Root)
diff --git go-ethereum/eth/protocols/snap/handler.go op-geth/eth/protocols/snap/handler.go index 924aff7ac9a6063faa52c79585f9c47eece026fa..ab469b4ce990584c439f7179ae57af35e7fa9629 100644 --- go-ethereum/eth/protocols/snap/handler.go +++ op-geth/eth/protocols/snap/handler.go @@ -454,7 +454,8 @@ if hash == types.EmptyCodeHash { // Peers should not request the empty code, but if they do, at // least sent them back a correct response without db lookups codes = append(codes, []byte{}) - } else if blob := chain.ContractCodeWithPrefix(hash); len(blob) > 0 { + } else if blob := chain.ContractCode(hash); len(blob) > 0 { + // OP-Stack diff: above contract-code is fetched with support for legacy DB. codes = append(codes, blob) bytes += uint64(len(blob)) }

Snap-sync has access to trusted Deposit Transaction Nonce Data.

diff --git go-ethereum/eth/downloader/downloader.go op-geth/eth/downloader/downloader.go index 8ac5d2eb3159ab2eb8fa68f61c64f3a49e1982b2..50c070b871d4a29ea146461e51421616476496f4 100644 --- go-ethereum/eth/downloader/downloader.go +++ op-geth/eth/downloader/downloader.go @@ -151,10 +151,18 @@ // Progress reporting metrics syncStartBlock uint64 // Head snap block when Geth was started syncStartTime time.Time // Time instance when chain sync started syncLogTime time.Time // Time instance when status was last reported + + // Chain ID for downloaders to reference + chainID uint64 }   // BlockChain encapsulates functions required to sync a (full or snap) blockchain. type BlockChain interface { + // Config returns the chain configuration. + // OP-Stack diff, to adjust withdrawal-hash verification. + // Usage of ths in the Downloader is discouraged. + Config() *params.ChainConfig + // HasHeader verifies a header's presence in the local chain. HasHeader(common.Hash, uint64) bool   @@ -206,11 +214,11 @@ TrieDB() *triedb.Database }   // New creates a new downloader to fetch hashes and blocks from remote peers. -func New(stateDb ethdb.Database, mux *event.TypeMux, chain BlockChain, dropPeer peerDropFn, success func()) *Downloader { +func New(stateDb ethdb.Database, mux *event.TypeMux, chain BlockChain, dropPeer peerDropFn, success func(), chainID uint64) *Downloader { dl := &Downloader{ stateDB: stateDb, mux: mux, - queue: newQueue(blockCacheMaxItems, blockCacheInitialItems), + queue: newQueue(chain.Config(), blockCacheMaxItems, blockCacheInitialItems), peers: newPeerSet(), blockchain: chain, dropPeer: dropPeer, @@ -219,6 +227,7 @@ quitCh: make(chan struct{}), SnapSyncer: snap.NewSyncer(stateDb, chain.TrieDB().Scheme()), stateSyncStart: make(chan *stateSync), syncStartBlock: chain.CurrentSnapBlock().Number.Uint64(), + chainID: chainID, } // Create the post-merge skeleton syncer and start the process dl.skeleton = newSkeleton(stateDb, dl.peers, dropPeer, newBeaconBackfiller(dl, success)) @@ -993,7 +1002,7 @@ blocks := make([]*types.Block, len(results)) receipts := make([]types.Receipts, len(results)) for i, result := range results { blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.body()) - receipts[i] = result.Receipts + receipts[i] = correctReceipts(result.Receipts, result.Transactions, blocks[i].NumberU64(), d.chainID) } if index, err := d.blockchain.InsertReceiptChain(blocks, receipts, d.ancientLimit); err != nil { log.Debug("Downloaded item processing failed", "number", results[index].Header.Number, "hash", results[index].Header.Hash(), "err", err)
diff --git go-ethereum/eth/downloader/receiptreference.go op-geth/eth/downloader/receiptreference.go new file mode 100644 index 0000000000000000000000000000000000000000..b4c5623ddc9033ac6c03e48710f44e5c00cf1d94 --- /dev/null +++ op-geth/eth/downloader/receiptreference.go @@ -0,0 +1,144 @@ +package downloader + +import ( + "bytes" + "embed" + "encoding/gob" + "fmt" + "path" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +// userDepositNonces is a struct to hold the reference data for user deposits +// The reference data is used to correct the deposit nonce in the receipts +type userDepositNonces struct { + ChainID uint64 + First uint64 + Last uint64 // non inclusive + Results map[uint64][]uint64 +} + +var ( + systemAddress = common.HexToAddress("0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001") + receiptReferencePath = "userDepositData" + //go:embed userDepositData/*.gob + receiptReference embed.FS + userDepositNoncesAlreadySearched = map[uint64]bool{} + userDepositNoncesReference = map[uint64]userDepositNonces{} +) + +// lazy load the reference data for the requested chain +// if this chain data was already requested, returns early +func initReceiptReferences(chainID uint64) { + // if already loaded, return + if userDepositNoncesAlreadySearched[chainID] { + return + } + // look for a file prefixed by the chainID + fPrefix := fmt.Sprintf("%d.", chainID) + files, err := receiptReference.ReadDir(receiptReferencePath) + if err != nil { + log.Warn("Receipt Correction: Failed to read reference directory", "err", err) + return + } + // mark as loaded so we don't try again, even if no files match + userDepositNoncesAlreadySearched[chainID] = true + for _, file := range files { + // skip files which don't match the prefix + if !strings.HasPrefix(file.Name(), fPrefix) { + continue + } + fpath := path.Join(receiptReferencePath, file.Name()) + bs, err := receiptReference.ReadFile(fpath) + if err != nil { + log.Warn("Receipt Correction: Failed to read reference data", "err", err) + continue + } + udns := userDepositNonces{} + err = gob.NewDecoder(bytes.NewReader(bs)).Decode(&udns) + if err != nil { + log.Warn("Receipt Correction: Failed to decode reference data", "err", err) + continue + } + userDepositNoncesReference[udns.ChainID] = udns + return + } +} + +// correctReceipts corrects the deposit nonce in the receipts using the reference data +// prior to Canyon Hard Fork, DepositNonces were not cryptographically verifiable. +// As a consequence, the deposit nonces found during Snap Sync may be incorrect. +// This function inspects transaction data for user deposits, and if it is found to be incorrect, it is corrected. +// The data used to correct the deposit nonce is stored in the userDepositData directory, +// and was generated with the receipt reference tool in the optimism monorepo. +func correctReceipts(receipts types.Receipts, transactions types.Transactions, blockNumber uint64, chainID uint64) types.Receipts { + initReceiptReferences(chainID) + // if there is no data even after initialization, return the receipts as is + depositNoncesForChain, ok := userDepositNoncesReference[chainID] + if !ok { + log.Trace("Receipt Correction: No data source for chain", "chainID", chainID) + return receipts + } + + // check that the block number being examined is within the range of the reference data + if blockNumber < depositNoncesForChain.First || blockNumber > depositNoncesForChain.Last { + log.Trace("Receipt Correction: Block is out of range for receipt reference", + "blockNumber", blockNumber, + "start", depositNoncesForChain.First, + "end", depositNoncesForChain.Last) + return receipts + } + + // get the block nonces + blockNonces, ok := depositNoncesForChain.Results[blockNumber] + if !ok { + log.Trace("Receipt Correction: Block does not contain user deposits", "blockNumber", blockNumber) + return receipts + } + + // iterate through the receipts and transactions to correct the deposit nonce + // user deposits should always be at the front of the block, but we will check all transactions to be sure + udCount := 0 + for i := 0; i < len(receipts); i++ { + r := receipts[i] + tx := transactions[i] + from, err := types.Sender(types.LatestSignerForChainID(tx.ChainId()), tx) + if err != nil { + log.Warn("Receipt Correction: Failed to determine sender", "err", err) + continue + } + // break as soon as a non deposit is found + if r.Type != types.DepositTxType { + break + } + // ignore any transactions from the system address + if from != systemAddress { + // prevent index out of range (indicates a problem with the reference data or the block data) + if udCount >= len(blockNonces) { + log.Warn("Receipt Correction: More user deposits in block than included in reference data", "in_reference", len(blockNonces)) + break + } + nonce := blockNonces[udCount] + udCount++ + log.Trace("Receipt Correction: User Deposit detected", "address", from, "nonce", nonce) + if nonce != *r.DepositNonce { + // correct the deposit nonce + // warn because this should not happen unless the data was modified by corruption or a malicious peer + // by correcting the nonce, the entire block is still valid for use + log.Warn("Receipt Correction: Corrected deposit nonce", "nonce", *r.DepositNonce, "corrected", nonce) + r.DepositNonce = &nonce + } + } + } + // check for unused reference data (indicates a problem with the reference data or the block data) + if udCount < len(blockNonces) { + log.Warn("Receipt Correction: More user deposits in reference data than found in block", "in_reference", len(blockNonces), "in_block", udCount) + } + + log.Trace("Receipt Correction: Completed", "blockNumber", blockNumber, "userDeposits", udCount, "receipts", len(receipts), "transactions", len(transactions)) + return receipts +}

Prevent the write-buffer to grow too large, to keep the journal optional, and not restart on top of unavailable state.

diff --git go-ethereum/triedb/pathdb/buffer.go op-geth/triedb/pathdb/buffer.go index dea8875bda5dfb327ab4c5cdff46a02328a82184..fdef77dce375b5d5de68ef2146bc5212738d51af 100644 --- go-ethereum/triedb/pathdb/buffer.go +++ op-geth/triedb/pathdb/buffer.go @@ -114,7 +114,10 @@ // full returns an indicator if the size of accumulated content exceeds the // configured threshold. func (b *buffer) full() bool { - return b.size() > b.limit + // Limit not just by data size, but also the number of layers: + // if we allow the write-buffer to become larger, + // the journal becomes critical to not roll back to an unavailable state. + return b.size() > b.limit || b.layers >= uint64(maxDiffLayers) }   // size returns the approximate memory size of the held content.

Fix discv5 option to allow discv5 to be an active source for node-discovery.

diff --git go-ethereum/p2p/server.go op-geth/p2p/server.go index c1564352e5d1523b6a506818dfc939e55ed03539..77d2f94becf2e599f71e1dc19ae0ac8bc10fc24a 100644 --- go-ethereum/p2p/server.go +++ op-geth/p2p/server.go @@ -492,6 +492,7 @@ srv.discv5, err = discover.ListenV5(sconn, srv.localnode, cfg) if err != nil { return err } + srv.discmix.AddSource(srv.discv5.RandomNodes()) }   // Add protocol-specific discovery sources.

Discovery bootnode addresses.

diff --git go-ethereum/params/bootnodes.go op-geth/params/bootnodes.go index 124765313a81cc6df296e117af346f85dcf3114f..dc2abe59c74f1d2d6c7d06bea47d0d14af25d83d 100644 --- go-ethereum/params/bootnodes.go +++ op-geth/params/bootnodes.go @@ -70,6 +70,37 @@ "enr:-LK4QA8FfhaAjlb_BXsXxSfiysR7R52Nhi9JBt4F8SPssu8hdE1BXQQEtVDC3qStCW60LSO7hEsVHv5zm8_6Vnjhcn0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAN4aBKJc2VjcDI1NmsxoQJerDhsJ-KxZ8sHySMOCmTO6sHM3iCFQ6VMvLTe948MyYN0Y3CCI4yDdWRwgiOM", // 3.120.104.18 | aws-eu-central-1-frankfurt "enr:-LK4QKWrXTpV9T78hNG6s8AM6IO4XH9kFT91uZtFg1GcsJ6dKovDOr1jtAAFPnS2lvNltkOGA9k29BUN7lFh_sjuc9QBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhANAdd-Jc2VjcDI1NmsxoQLQa6ai7y9PMN5hpLe5HmiJSlYzMuzP7ZhwRiwHvqNXdoN0Y3CCI4yDdWRwgiOM", // 3.64.117.223 | aws-eu-central-1-frankfurt} }   +var V5OPBootnodes = []string{ + // OP Labs + "enode://ca2774c3c401325850b2477fd7d0f27911efbf79b1e8b335066516e2bd8c4c9e0ba9696a94b1cb030a88eac582305ff55e905e64fb77fe0edcd70a4e5296d3ec@34.65.175.185:30305", + "enode://dd751a9ef8912be1bfa7a5e34e2c3785cc5253110bd929f385e07ba7ac19929fb0e0c5d93f77827291f4da02b2232240fbc47ea7ce04c46e333e452f8656b667@34.65.107.0:30305", + "enode://c5d289b56a77b6a2342ca29956dfd07aadf45364dde8ab20d1dc4efd4d1bc6b4655d902501daea308f4d8950737a4e93a4dfedd17b49cd5760ffd127837ca965@34.65.202.239:30305", + // Base + "enode://87a32fd13bd596b2ffca97020e31aef4ddcc1bbd4b95bb633d16c1329f654f34049ed240a36b449fda5e5225d70fe40bc667f53c304b71f8e68fc9d448690b51@3.231.138.188:30301", + "enode://ca21ea8f176adb2e229ce2d700830c844af0ea941a1d8152a9513b966fe525e809c3a6c73a2c18a12b74ed6ec4380edf91662778fe0b79f6a591236e49e176f9@184.72.129.189:30301", + "enode://acf4507a211ba7c1e52cdf4eef62cdc3c32e7c9c47998954f7ba024026f9a6b2150cd3f0b734d9c78e507ab70d59ba61dfe5c45e1078c7ad0775fb251d7735a2@3.220.145.177:30301", + "enode://8a5a5006159bf079d06a04e5eceab2a1ce6e0f721875b2a9c96905336219dbe14203d38f70f3754686a6324f786c2f9852d8c0dd3adac2d080f4db35efc678c5@3.231.11.52:30301", + "enode://cdadbe835308ad3557f9a1de8db411da1a260a98f8421d62da90e71da66e55e98aaa8e90aa7ce01b408a54e4bd2253d701218081ded3dbe5efbbc7b41d7cef79@54.198.153.150:30301", + // Uniswap Labs + "enode://b1a743328188dba3b2ed8c06abbb2688fabe64a3251e43bd77d4e5265bbd5cf03eca8ace4cde8ddb0c49c409b90bf941ebf556094638c6203edd6baa5ef0091b@3.134.214.169:30303", + "enode://ea9eaaf695facbe53090beb7a5b0411a81459bbf6e6caac151e587ee77120a1b07f3b9f3a9550f797d73d69840a643b775fd1e40344dea11e7660b6a483fe80e@52.14.30.39:30303", + "enode://77b6b1e72984d5d50e00ae934ffea982902226fe92fa50da42334c2750d8e405b55a5baabeb988c88125368142a64eda5096d0d4522d3b6eef75d166c7d303a9@3.148.100.173:30303", +} + +var V5OPTestnetBootnodes = []string{ + // OP Labs + "enode://2bd2e657bb3c8efffb8ff6db9071d9eb7be70d7c6d7d980ff80fc93b2629675c5f750bc0a5ef27cd788c2e491b8795a7e9a4a6e72178c14acc6753c0e5d77ae4@34.65.205.244:30305", + "enode://db8e1cab24624cc62fc35dbb9e481b88a9ef0116114cd6e41034c55b5b4f18755983819252333509bd8e25f6b12aadd6465710cd2e956558faf17672cce7551f@34.65.173.88:30305", + "enode://bfda2e0110cfd0f4c9f7aa5bf5ec66e6bd18f71a2db028d36b8bf8b0d6fdb03125c1606a6017b31311d96a36f5ef7e1ad11604d7a166745e6075a715dfa67f8a@34.65.229.245:30305", + // Base + "enode://548f715f3fc388a7c917ba644a2f16270f1ede48a5d88a4d14ea287cc916068363f3092e39936f1a3e7885198bef0e5af951f1d7b1041ce8ba4010917777e71f@18.210.176.114:30301", + "enode://6f10052847a966a725c9f4adf6716f9141155b99a0fb487fea3f51498f4c2a2cb8d534e680ee678f9447db85b93ff7c74562762c3714783a7233ac448603b25f@107.21.251.55:30301", + // Uniswap Labs + "enode://9e138a8ec4291c4f2fe5851aaee44fc73ae67da87fb26b75e3b94183c7ffc15b2795afc816b0aa084151b95b3a3553f1cd0d1e9dd134dcf059a84d4e0b429afc@3.146.117.118:30303", + "enode://34d87d649e5c58a17a43c1d59900a2020bd82d5b12ea39467c3366bee2946aaa9c759c77ede61089624691291fb2129eeb2a47687b50e2463188c78e1f738cf2@52.15.54.8:30303", + "enode://c2405194166fe2c0e6c61ee469745fed1a6802f51c8fc39e1c78c21c9a6a15a7c55304f09ee37e430da9a1ce8117ca085263c6b0f474f6946811e398347611ef@3.146.213.65:30303", +} + const dnsPrefix = "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@"   // KnownDNSNetwork returns the address of a public DNS-based node list for the given
diff --git go-ethereum/eth/ethconfig/gen_config.go op-geth/eth/ethconfig/gen_config.go index 8e954eaefb19a9262cf2f7c8d623af91f07dffa7..bbe6b4baa7815d197ca4aa33fe34c645ab26748b 100644 --- go-ethereum/eth/ethconfig/gen_config.go +++ op-geth/eth/ethconfig/gen_config.go @@ -16,40 +16,59 @@ // MarshalTOML marshals as TOML. func (c Config) MarshalTOML() (interface{}, error) { type Config struct { - Genesis *core.Genesis `toml:",omitempty"` - NetworkId uint64 - SyncMode SyncMode - EthDiscoveryURLs []string - SnapDiscoveryURLs []string - NoPruning bool - NoPrefetch bool - TxLookupLimit uint64 `toml:",omitempty"` - TransactionHistory uint64 `toml:",omitempty"` - StateHistory uint64 `toml:",omitempty"` - StateScheme string `toml:",omitempty"` - RequiredBlocks map[uint64]common.Hash `toml:"-"` - SkipBcVersionCheck bool `toml:"-"` - DatabaseHandles int `toml:"-"` - DatabaseCache int - DatabaseFreezer string - TrieCleanCache int - TrieDirtyCache int - TrieTimeout time.Duration - SnapshotCache int - Preimages bool - FilterLogCacheSize int - Miner miner.Config - TxPool legacypool.Config - BlobPool blobpool.Config - GPO gasprice.Config - EnablePreimageRecording bool - VMTrace string - VMTraceJsonConfig string - RPCGasCap uint64 - RPCEVMTimeout time.Duration - RPCTxFeeCap float64 - OverrideCancun *uint64 `toml:",omitempty"` - OverrideVerkle *uint64 `toml:",omitempty"` + Genesis *core.Genesis `toml:",omitempty"` + NetworkId uint64 + SyncMode SyncMode + EthDiscoveryURLs []string + SnapDiscoveryURLs []string + NoPruning bool + NoPrefetch bool + TxLookupLimit uint64 `toml:",omitempty"` + TransactionHistory uint64 `toml:",omitempty"` + StateHistory uint64 `toml:",omitempty"` + StateScheme string `toml:",omitempty"` + RequiredBlocks map[uint64]common.Hash `toml:"-"` + SkipBcVersionCheck bool `toml:"-"` + DatabaseHandles int `toml:"-"` + DatabaseCache int + DatabaseFreezer string + TrieCleanCache int + TrieDirtyCache int + TrieTimeout time.Duration + SnapshotCache int + Preimages bool + FilterLogCacheSize int + Miner miner.Config + TxPool legacypool.Config + BlobPool blobpool.Config + GPO gasprice.Config + EnablePreimageRecording bool + VMTrace string + VMTraceJsonConfig string + RPCGasCap uint64 + RPCEVMTimeout time.Duration + RPCTxFeeCap float64 + OverrideCancun *uint64 `toml:",omitempty"` + OverrideVerkle *uint64 `toml:",omitempty"` + OverrideOptimismCanyon *uint64 `toml:",omitempty"` + OverrideOptimismEcotone *uint64 `toml:",omitempty"` + OverrideOptimismFjord *uint64 `toml:",omitempty"` + OverrideOptimismGranite *uint64 `toml:",omitempty"` + OverrideOptimismHolocene *uint64 `toml:",omitempty"` + OverrideOptimismIsthmus *uint64 `toml:",omitempty"` + OverrideOptimismJovian *uint64 `toml:",omitempty"` + OverrideOptimismInterop *uint64 `toml:",omitempty"` + ApplySuperchainUpgrades bool `toml:",omitempty"` + RollupSequencerHTTP string + RollupSequencerTxConditionalEnabled bool + RollupSequencerTxConditionalCostRateLimit int + RollupHistoricalRPC string + RollupHistoricalRPCTimeout time.Duration + RollupDisableTxPoolGossip bool + RollupDisableTxPoolAdmission bool + RollupHaltOnIncompatibleProtocolVersion string + InteropMessageRPC string `toml:",omitempty"` + InteropMempoolFiltering bool `toml:",omitempty"` } var enc Config enc.Genesis = c.Genesis @@ -86,46 +105,84 @@ enc.RPCEVMTimeout = c.RPCEVMTimeout enc.RPCTxFeeCap = c.RPCTxFeeCap enc.OverrideCancun = c.OverrideCancun enc.OverrideVerkle = c.OverrideVerkle + enc.OverrideOptimismCanyon = c.OverrideOptimismCanyon + enc.OverrideOptimismEcotone = c.OverrideOptimismEcotone + enc.OverrideOptimismFjord = c.OverrideOptimismFjord + enc.OverrideOptimismGranite = c.OverrideOptimismGranite + enc.OverrideOptimismHolocene = c.OverrideOptimismHolocene + enc.OverrideOptimismIsthmus = c.OverrideOptimismIsthmus + enc.OverrideOptimismJovian = c.OverrideOptimismJovian + enc.OverrideOptimismInterop = c.OverrideOptimismInterop + enc.ApplySuperchainUpgrades = c.ApplySuperchainUpgrades + enc.RollupSequencerHTTP = c.RollupSequencerHTTP + enc.RollupSequencerTxConditionalEnabled = c.RollupSequencerTxConditionalEnabled + enc.RollupSequencerTxConditionalCostRateLimit = c.RollupSequencerTxConditionalCostRateLimit + enc.RollupHistoricalRPC = c.RollupHistoricalRPC + enc.RollupHistoricalRPCTimeout = c.RollupHistoricalRPCTimeout + enc.RollupDisableTxPoolGossip = c.RollupDisableTxPoolGossip + enc.RollupDisableTxPoolAdmission = c.RollupDisableTxPoolAdmission + enc.RollupHaltOnIncompatibleProtocolVersion = c.RollupHaltOnIncompatibleProtocolVersion + enc.InteropMessageRPC = c.InteropMessageRPC + enc.InteropMempoolFiltering = c.InteropMempoolFiltering return &enc, nil }   // UnmarshalTOML unmarshals from TOML. func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { type Config struct { - Genesis *core.Genesis `toml:",omitempty"` - NetworkId *uint64 - SyncMode *SyncMode - EthDiscoveryURLs []string - SnapDiscoveryURLs []string - NoPruning *bool - NoPrefetch *bool - TxLookupLimit *uint64 `toml:",omitempty"` - TransactionHistory *uint64 `toml:",omitempty"` - StateHistory *uint64 `toml:",omitempty"` - StateScheme *string `toml:",omitempty"` - RequiredBlocks map[uint64]common.Hash `toml:"-"` - SkipBcVersionCheck *bool `toml:"-"` - DatabaseHandles *int `toml:"-"` - DatabaseCache *int - DatabaseFreezer *string - TrieCleanCache *int - TrieDirtyCache *int - TrieTimeout *time.Duration - SnapshotCache *int - Preimages *bool - FilterLogCacheSize *int - Miner *miner.Config - TxPool *legacypool.Config - BlobPool *blobpool.Config - GPO *gasprice.Config - EnablePreimageRecording *bool - VMTrace *string - VMTraceJsonConfig *string - RPCGasCap *uint64 - RPCEVMTimeout *time.Duration - RPCTxFeeCap *float64 - OverrideCancun *uint64 `toml:",omitempty"` - OverrideVerkle *uint64 `toml:",omitempty"` + Genesis *core.Genesis `toml:",omitempty"` + NetworkId *uint64 + SyncMode *SyncMode + EthDiscoveryURLs []string + SnapDiscoveryURLs []string + NoPruning *bool + NoPrefetch *bool + TxLookupLimit *uint64 `toml:",omitempty"` + TransactionHistory *uint64 `toml:",omitempty"` + StateHistory *uint64 `toml:",omitempty"` + StateScheme *string `toml:",omitempty"` + RequiredBlocks map[uint64]common.Hash `toml:"-"` + SkipBcVersionCheck *bool `toml:"-"` + DatabaseHandles *int `toml:"-"` + DatabaseCache *int + DatabaseFreezer *string + TrieCleanCache *int + TrieDirtyCache *int + TrieTimeout *time.Duration + SnapshotCache *int + Preimages *bool + FilterLogCacheSize *int + Miner *miner.Config + TxPool *legacypool.Config + BlobPool *blobpool.Config + GPO *gasprice.Config + EnablePreimageRecording *bool + VMTrace *string + VMTraceJsonConfig *string + RPCGasCap *uint64 + RPCEVMTimeout *time.Duration + RPCTxFeeCap *float64 + OverrideCancun *uint64 `toml:",omitempty"` + OverrideVerkle *uint64 `toml:",omitempty"` + OverrideOptimismCanyon *uint64 `toml:",omitempty"` + OverrideOptimismEcotone *uint64 `toml:",omitempty"` + OverrideOptimismFjord *uint64 `toml:",omitempty"` + OverrideOptimismGranite *uint64 `toml:",omitempty"` + OverrideOptimismHolocene *uint64 `toml:",omitempty"` + OverrideOptimismIsthmus *uint64 `toml:",omitempty"` + OverrideOptimismJovian *uint64 `toml:",omitempty"` + OverrideOptimismInterop *uint64 `toml:",omitempty"` + ApplySuperchainUpgrades *bool `toml:",omitempty"` + RollupSequencerHTTP *string + RollupSequencerTxConditionalEnabled *bool + RollupSequencerTxConditionalCostRateLimit *int + RollupHistoricalRPC *string + RollupHistoricalRPCTimeout *time.Duration + RollupDisableTxPoolGossip *bool + RollupDisableTxPoolAdmission *bool + RollupHaltOnIncompatibleProtocolVersion *string + InteropMessageRPC *string `toml:",omitempty"` + InteropMempoolFiltering *bool `toml:",omitempty"` } var dec Config if err := unmarshal(&dec); err != nil { @@ -232,6 +289,63 @@ c.OverrideCancun = dec.OverrideCancun } if dec.OverrideVerkle != nil { c.OverrideVerkle = dec.OverrideVerkle + } + if dec.OverrideOptimismCanyon != nil { + c.OverrideOptimismCanyon = dec.OverrideOptimismCanyon + } + if dec.OverrideOptimismEcotone != nil { + c.OverrideOptimismEcotone = dec.OverrideOptimismEcotone + } + if dec.OverrideOptimismFjord != nil { + c.OverrideOptimismFjord = dec.OverrideOptimismFjord + } + if dec.OverrideOptimismGranite != nil { + c.OverrideOptimismGranite = dec.OverrideOptimismGranite + } + if dec.OverrideOptimismHolocene != nil { + c.OverrideOptimismHolocene = dec.OverrideOptimismHolocene + } + if dec.OverrideOptimismIsthmus != nil { + c.OverrideOptimismIsthmus = dec.OverrideOptimismIsthmus + } + if dec.OverrideOptimismJovian != nil { + c.OverrideOptimismJovian = dec.OverrideOptimismJovian + } + if dec.OverrideOptimismInterop != nil { + c.OverrideOptimismInterop = dec.OverrideOptimismInterop + } + if dec.ApplySuperchainUpgrades != nil { + c.ApplySuperchainUpgrades = *dec.ApplySuperchainUpgrades + } + if dec.RollupSequencerHTTP != nil { + c.RollupSequencerHTTP = *dec.RollupSequencerHTTP + } + if dec.RollupSequencerTxConditionalEnabled != nil { + c.RollupSequencerTxConditionalEnabled = *dec.RollupSequencerTxConditionalEnabled + } + if dec.RollupSequencerTxConditionalCostRateLimit != nil { + c.RollupSequencerTxConditionalCostRateLimit = *dec.RollupSequencerTxConditionalCostRateLimit + } + if dec.RollupHistoricalRPC != nil { + c.RollupHistoricalRPC = *dec.RollupHistoricalRPC + } + if dec.RollupHistoricalRPCTimeout != nil { + c.RollupHistoricalRPCTimeout = *dec.RollupHistoricalRPCTimeout + } + if dec.RollupDisableTxPoolGossip != nil { + c.RollupDisableTxPoolGossip = *dec.RollupDisableTxPoolGossip + } + if dec.RollupDisableTxPoolAdmission != nil { + c.RollupDisableTxPoolAdmission = *dec.RollupDisableTxPoolAdmission + } + if dec.RollupHaltOnIncompatibleProtocolVersion != nil { + c.RollupHaltOnIncompatibleProtocolVersion = *dec.RollupHaltOnIncompatibleProtocolVersion + } + if dec.InteropMessageRPC != nil { + c.InteropMessageRPC = *dec.InteropMessageRPC + } + if dec.InteropMempoolFiltering != nil { + c.InteropMempoolFiltering = *dec.InteropMempoolFiltering } return nil }

The cannon fault proofs virtual machine does not support the creation of threads. To ensure compatibility, thread creation is avoided when only a single CPU is available.

diff --git go-ethereum/core/state/workers.go op-geth/core/state/workers.go new file mode 100644 index 0000000000000000000000000000000000000000..72b93cd7ad0a3e3ea7566f98cc86090c72dab9e6 --- /dev/null +++ op-geth/core/state/workers.go @@ -0,0 +1,37 @@ +package state + +import ( + "errors" + + "golang.org/x/sync/errgroup" +) + +type workerGroup interface { + Go(func() error) + SetLimit(int) + Wait() error +} + +func newWorkerGroup(singlethreaded bool) workerGroup { + if singlethreaded { + return &inlineWorkerGroup{} + } else { + var grp errgroup.Group + return &grp + } +} + +type inlineWorkerGroup struct { + err error +} + +func (i *inlineWorkerGroup) Go(action func() error) { + i.err = errors.Join(i.err, action()) +} + +func (i *inlineWorkerGroup) SetLimit(_ int) { +} + +func (i *inlineWorkerGroup) Wait() error { + return i.err +}
diff --git go-ethereum/trie/hasher.go op-geth/trie/hasher.go index 28f7f3d0c387100680483b2e864d1405a232fffd..3ef30c46a1a2b1c6c55ab74a987242349ce4489c 100644 --- go-ethereum/trie/hasher.go +++ op-geth/trie/hasher.go @@ -17,6 +17,7 @@ package trie   import ( + "runtime" "sync"   "github.com/ethereum/go-ethereum/crypto" @@ -45,7 +46,7 @@ }   func newHasher(parallel bool) *hasher { h := hasherPool.Get().(*hasher) - h.parallel = parallel + h.parallel = parallel && runtime.NumCPU() > 1 return h }

The interop upgrade introduces cross-chain message. Transactions are checked for cross-chain message safety before and during inclusion into a block. This also includes tx-pool ingress filtering.

diff --git go-ethereum/eth/interop.go op-geth/eth/interop.go new file mode 100644 index 0000000000000000000000000000000000000000..07e374df3f656f31d4339ac3a32a17297ec4bc67 --- /dev/null +++ op-geth/eth/interop.go @@ -0,0 +1,56 @@ +package eth + +import ( + "context" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/types/interoptypes" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/internal/ethapi" +) + +func (s *Ethereum) CheckMessages(ctx context.Context, messages []interoptypes.Message, minSafety interoptypes.SafetyLevel) error { + if s.interopRPC == nil { + return errors.New("cannot check interop messages, no RPC available") + } + return s.interopRPC.CheckMessages(ctx, messages, minSafety) +} + +// SimLogs simulates the logs that would be generated by a transaction if it were executed on the current state. +// This is used by the interop filter to determine if a transaction should be allowed. +// if errors are encountered, no logs are returned. +func (s *Ethereum) SimLogs(tx *types.Transaction) ([]*types.Log, error) { + chainConfig := s.APIBackend.ChainConfig() + if !chainConfig.IsOptimism() { + return nil, errors.New("expected OP-Stack chain config, SimLogs is an OP-Stack feature") + } + header := s.BlockChain().CurrentBlock() + if chainConfig.InteropTime == nil { + return nil, errors.New("expected Interop fork to be configured, SimLogs is unavailable pre-interop") + } + state, err := s.BlockChain().StateAt(header.Root) + if err != nil { + return nil, fmt.Errorf("state %s (block %d) is unavailable for log simulation: %w", header.Root, header.Number.Uint64(), err) + } + var vmConf vm.Config + signer := types.MakeSigner(chainConfig, header.Number, header.Time) + message, err := core.TransactionToMessage(tx, signer, header.BaseFee) + if err != nil { + return nil, fmt.Errorf("cannot convert tx to message for log simulation: %w", err) + } + chainCtx := ethapi.NewChainContext(context.Background(), s.APIBackend) + blockCtx := core.NewEVMBlockContext(header, chainCtx, &header.Coinbase, chainConfig, state) + vmenv := vm.NewEVM(blockCtx, state, chainConfig, vmConf) + state.SetTxContext(tx.Hash(), 0) + result, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(header.GasLimit)) + if err != nil { + return nil, fmt.Errorf("failed to execute tx: %w", err) + } + if result.Failed() { // failed txs do not have log events + return nil, nil + } + return state.GetLogs(tx.Hash(), header.Number.Uint64(), header.Hash()), nil +}

Encode the Deposit Tx properties, the L1 costs, and daisy-chain RPC-calls for pre-Bedrock historical data

Pre-Bedrock L1-cost receipt data is loaded from the database if available, and post-Bedrock the L1-cost metadata is hydrated on-the-fly based on the L1 fee information in the corresponding block.

diff --git go-ethereum/core/rawdb/accessors_chain.go op-geth/core/rawdb/accessors_chain.go index c4735c850c02785330703b563fa21a1eea998dcd..4914d961ec60e48ba3194f8f2a2eecfd8909c55d 100644 --- go-ethereum/core/rawdb/accessors_chain.go +++ op-geth/core/rawdb/accessors_chain.go @@ -625,7 +625,6 @@ log.Error("Missing body but have receipt", "hash", hash, "number", number) return nil } header := ReadHeader(db, hash, number) - var baseFee *big.Int if header == nil { baseFee = big.NewInt(0) @@ -675,6 +674,15 @@ type storedReceiptRLP struct { PostStateOrStatus []byte CumulativeGasUsed uint64 Logs []*types.Log + + // Remaining fields are declared to allow the receipt RLP to be parsed without errors. + // However, they must not be used as they may not be populated correctly due to multiple receipt formats + // being combined into a single list of optional fields which can be mistaken for each other. + // DepositNonce (*uint64) from Regolith deposit tx receipts will be parsed into L1GasUsed + L1GasUsed *big.Int `rlp:"optional"` // OVM legacy + L1GasPrice *big.Int `rlp:"optional"` // OVM legacy + L1Fee *big.Int `rlp:"optional"` // OVM legacy + FeeScalar string `rlp:"optional"` // OVM legacy }   // ReceiptLogs is a barebone version of ReceiptForStorage which only keeps
diff --git go-ethereum/core/types/gen_receipt_json.go op-geth/core/types/gen_receipt_json.go index 4c641a972795f70ce27e98baf1b3c2e032fe89c2..4e544a0b52b61bac03f57c71581117f04280f81e 100644 --- go-ethereum/core/types/gen_receipt_json.go +++ op-geth/core/types/gen_receipt_json.go @@ -16,21 +16,30 @@ // MarshalJSON marshals as JSON. func (r Receipt) MarshalJSON() ([]byte, error) { type Receipt struct { - Type hexutil.Uint64 `json:"type,omitempty"` - PostState hexutil.Bytes `json:"root"` - Status hexutil.Uint64 `json:"status"` - CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` - TxHash common.Hash `json:"transactionHash" gencodec:"required"` - ContractAddress common.Address `json:"contractAddress"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - EffectiveGasPrice *hexutil.Big `json:"effectiveGasPrice"` - BlobGasUsed hexutil.Uint64 `json:"blobGasUsed,omitempty"` - BlobGasPrice *hexutil.Big `json:"blobGasPrice,omitempty"` - BlockHash common.Hash `json:"blockHash,omitempty"` - BlockNumber *hexutil.Big `json:"blockNumber,omitempty"` - TransactionIndex hexutil.Uint `json:"transactionIndex"` + Type hexutil.Uint64 `json:"type,omitempty"` + PostState hexutil.Bytes `json:"root"` + Status hexutil.Uint64 `json:"status"` + CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Logs []*Log `json:"logs" gencodec:"required"` + TxHash common.Hash `json:"transactionHash" gencodec:"required"` + ContractAddress common.Address `json:"contractAddress"` + GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + EffectiveGasPrice *hexutil.Big `json:"effectiveGasPrice"` + BlobGasUsed hexutil.Uint64 `json:"blobGasUsed,omitempty"` + BlobGasPrice *hexutil.Big `json:"blobGasPrice,omitempty"` + DepositNonce *hexutil.Uint64 `json:"depositNonce,omitempty"` + DepositReceiptVersion *hexutil.Uint64 `json:"depositReceiptVersion,omitempty"` + BlockHash common.Hash `json:"blockHash,omitempty"` + BlockNumber *hexutil.Big `json:"blockNumber,omitempty"` + TransactionIndex hexutil.Uint `json:"transactionIndex"` + L1GasPrice *hexutil.Big `json:"l1GasPrice,omitempty"` + L1BlobBaseFee *hexutil.Big `json:"l1BlobBaseFee,omitempty"` + L1GasUsed *hexutil.Big `json:"l1GasUsed,omitempty"` + L1Fee *hexutil.Big `json:"l1Fee,omitempty"` + FeeScalar *big.Float `json:"l1FeeScalar,omitempty"` + L1BaseFeeScalar *hexutil.Uint64 `json:"l1BaseFeeScalar,omitempty"` + L1BlobBaseFeeScalar *hexutil.Uint64 `json:"l1BlobBaseFeeScalar,omitempty"` } var enc Receipt enc.Type = hexutil.Uint64(r.Type) @@ -45,30 +54,48 @@ enc.GasUsed = hexutil.Uint64(r.GasUsed) enc.EffectiveGasPrice = (*hexutil.Big)(r.EffectiveGasPrice) enc.BlobGasUsed = hexutil.Uint64(r.BlobGasUsed) enc.BlobGasPrice = (*hexutil.Big)(r.BlobGasPrice) + enc.DepositNonce = (*hexutil.Uint64)(r.DepositNonce) + enc.DepositReceiptVersion = (*hexutil.Uint64)(r.DepositReceiptVersion) enc.BlockHash = r.BlockHash enc.BlockNumber = (*hexutil.Big)(r.BlockNumber) enc.TransactionIndex = hexutil.Uint(r.TransactionIndex) + enc.L1GasPrice = (*hexutil.Big)(r.L1GasPrice) + enc.L1BlobBaseFee = (*hexutil.Big)(r.L1BlobBaseFee) + enc.L1GasUsed = (*hexutil.Big)(r.L1GasUsed) + enc.L1Fee = (*hexutil.Big)(r.L1Fee) + enc.FeeScalar = r.FeeScalar + enc.L1BaseFeeScalar = (*hexutil.Uint64)(r.L1BaseFeeScalar) + enc.L1BlobBaseFeeScalar = (*hexutil.Uint64)(r.L1BlobBaseFeeScalar) return json.Marshal(&enc) }   // UnmarshalJSON unmarshals from JSON. func (r *Receipt) UnmarshalJSON(input []byte) error { type Receipt struct { - Type *hexutil.Uint64 `json:"type,omitempty"` - PostState *hexutil.Bytes `json:"root"` - Status *hexutil.Uint64 `json:"status"` - CumulativeGasUsed *hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` - Bloom *Bloom `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` - TxHash *common.Hash `json:"transactionHash" gencodec:"required"` - ContractAddress *common.Address `json:"contractAddress"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - EffectiveGasPrice *hexutil.Big `json:"effectiveGasPrice"` - BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed,omitempty"` - BlobGasPrice *hexutil.Big `json:"blobGasPrice,omitempty"` - BlockHash *common.Hash `json:"blockHash,omitempty"` - BlockNumber *hexutil.Big `json:"blockNumber,omitempty"` - TransactionIndex *hexutil.Uint `json:"transactionIndex"` + Type *hexutil.Uint64 `json:"type,omitempty"` + PostState *hexutil.Bytes `json:"root"` + Status *hexutil.Uint64 `json:"status"` + CumulativeGasUsed *hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` + Bloom *Bloom `json:"logsBloom" gencodec:"required"` + Logs []*Log `json:"logs" gencodec:"required"` + TxHash *common.Hash `json:"transactionHash" gencodec:"required"` + ContractAddress *common.Address `json:"contractAddress"` + GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + EffectiveGasPrice *hexutil.Big `json:"effectiveGasPrice"` + BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed,omitempty"` + BlobGasPrice *hexutil.Big `json:"blobGasPrice,omitempty"` + DepositNonce *hexutil.Uint64 `json:"depositNonce,omitempty"` + DepositReceiptVersion *hexutil.Uint64 `json:"depositReceiptVersion,omitempty"` + BlockHash *common.Hash `json:"blockHash,omitempty"` + BlockNumber *hexutil.Big `json:"blockNumber,omitempty"` + TransactionIndex *hexutil.Uint `json:"transactionIndex"` + L1GasPrice *hexutil.Big `json:"l1GasPrice,omitempty"` + L1BlobBaseFee *hexutil.Big `json:"l1BlobBaseFee,omitempty"` + L1GasUsed *hexutil.Big `json:"l1GasUsed,omitempty"` + L1Fee *hexutil.Big `json:"l1Fee,omitempty"` + FeeScalar *big.Float `json:"l1FeeScalar,omitempty"` + L1BaseFeeScalar *hexutil.Uint64 `json:"l1BaseFeeScalar,omitempty"` + L1BlobBaseFeeScalar *hexutil.Uint64 `json:"l1BlobBaseFeeScalar,omitempty"` } var dec Receipt if err := json.Unmarshal(input, &dec); err != nil { @@ -115,6 +142,12 @@ } if dec.BlobGasPrice != nil { r.BlobGasPrice = (*big.Int)(dec.BlobGasPrice) } + if dec.DepositNonce != nil { + r.DepositNonce = (*uint64)(dec.DepositNonce) + } + if dec.DepositReceiptVersion != nil { + r.DepositReceiptVersion = (*uint64)(dec.DepositReceiptVersion) + } if dec.BlockHash != nil { r.BlockHash = *dec.BlockHash } @@ -123,6 +156,27 @@ r.BlockNumber = (*big.Int)(dec.BlockNumber) } if dec.TransactionIndex != nil { r.TransactionIndex = uint(*dec.TransactionIndex) + } + if dec.L1GasPrice != nil { + r.L1GasPrice = (*big.Int)(dec.L1GasPrice) + } + if dec.L1BlobBaseFee != nil { + r.L1BlobBaseFee = (*big.Int)(dec.L1BlobBaseFee) + } + if dec.L1GasUsed != nil { + r.L1GasUsed = (*big.Int)(dec.L1GasUsed) + } + if dec.L1Fee != nil { + r.L1Fee = (*big.Int)(dec.L1Fee) + } + if dec.FeeScalar != nil { + r.FeeScalar = dec.FeeScalar + } + if dec.L1BaseFeeScalar != nil { + r.L1BaseFeeScalar = (*uint64)(dec.L1BaseFeeScalar) + } + if dec.L1BlobBaseFeeScalar != nil { + r.L1BlobBaseFeeScalar = (*uint64)(dec.L1BlobBaseFeeScalar) } return nil }
diff --git go-ethereum/core/types/receipt.go op-geth/core/types/receipt.go index 47f16d950ae4d8e26e9009ef973449a1193c236a..e7dfe1865d5d9cf9b320b1ad046b4a023311ccf5 100644 --- go-ethereum/core/types/receipt.go +++ op-geth/core/types/receipt.go @@ -46,6 +46,9 @@ ReceiptStatusFailed = uint64(0)   // ReceiptStatusSuccessful is the status code of a transaction if execution succeeded. ReceiptStatusSuccessful = uint64(1) + + // The version number for post-canyon deposit receipts. + CanyonDepositReceiptVersion = uint64(1) )   // Receipt represents the results of a transaction. @@ -58,7 +61,8 @@ CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"`   - // Implementation fields: These fields are added by geth when processing a transaction. + // Implementation fields: These fields are added by geth when processing a transaction or retrieving a receipt. + // gencodec annotated fields: these are stored in the chain database. TxHash common.Hash `json:"transactionHash" gencodec:"required"` ContractAddress common.Address `json:"contractAddress"` GasUsed uint64 `json:"gasUsed" gencodec:"required"` @@ -66,11 +70,28 @@ EffectiveGasPrice *big.Int `json:"effectiveGasPrice"` // required, but tag omitted for backwards compatibility BlobGasUsed uint64 `json:"blobGasUsed,omitempty"` BlobGasPrice *big.Int `json:"blobGasPrice,omitempty"`   + // DepositNonce was introduced in Regolith to store the actual nonce used by deposit transactions + // The state transition process ensures this is only set for Regolith deposit transactions. + DepositNonce *uint64 `json:"depositNonce,omitempty"` + // DepositReceiptVersion was introduced in Canyon to indicate an update to how receipt hashes + // should be computed when set. The state transition process ensures this is only set for + // post-Canyon deposit transactions. + DepositReceiptVersion *uint64 `json:"depositReceiptVersion,omitempty"` + // Inclusion information: These fields provide information about the inclusion of the // transaction corresponding to this receipt. BlockHash common.Hash `json:"blockHash,omitempty"` BlockNumber *big.Int `json:"blockNumber,omitempty"` TransactionIndex uint `json:"transactionIndex"` + + // Optimism: extend receipts with L1 fee info + L1GasPrice *big.Int `json:"l1GasPrice,omitempty"` // Present from pre-bedrock. L1 Basefee after Bedrock + L1BlobBaseFee *big.Int `json:"l1BlobBaseFee,omitempty"` // Always nil prior to the Ecotone hardfork + L1GasUsed *big.Int `json:"l1GasUsed,omitempty"` // Present from pre-bedrock, deprecated as of Fjord + L1Fee *big.Int `json:"l1Fee,omitempty"` // Present from pre-bedrock + FeeScalar *big.Float `json:"l1FeeScalar,omitempty"` // Present from pre-bedrock to Ecotone. Nil after Ecotone + L1BaseFeeScalar *uint64 `json:"l1BaseFeeScalar,omitempty"` // Always nil prior to the Ecotone hardfork + L1BlobBaseFeeScalar *uint64 `json:"l1BlobBaseFeeScalar,omitempty"` // Always nil prior to the Ecotone hardfork }   type receiptMarshaling struct { @@ -84,6 +105,17 @@ BlobGasUsed hexutil.Uint64 BlobGasPrice *hexutil.Big BlockNumber *hexutil.Big TransactionIndex hexutil.Uint + + // Optimism + L1GasPrice *hexutil.Big + L1BlobBaseFee *hexutil.Big + L1GasUsed *hexutil.Big + L1Fee *hexutil.Big + FeeScalar *big.Float + L1BaseFeeScalar *hexutil.Uint64 + L1BlobBaseFeeScalar *hexutil.Uint64 + DepositNonce *hexutil.Uint64 + DepositReceiptVersion *hexutil.Uint64 }   // receiptRLP is the consensus encoding of a receipt. @@ -94,11 +126,98 @@ Bloom Bloom Logs []*Log }   +type depositReceiptRLP struct { + PostStateOrStatus []byte + CumulativeGasUsed uint64 + Bloom Bloom + Logs []*Log + // DepositNonce was introduced in Regolith to store the actual nonce used by deposit transactions. + // Must be nil for any transactions prior to Regolith or that aren't deposit transactions. + DepositNonce *uint64 `rlp:"optional"` + // Receipt hash post-Regolith but pre-Canyon inadvertently did not include the above + // DepositNonce. Post Canyon, receipts will have a non-empty DepositReceiptVersion indicating + // which post-Canyon receipt hash function to invoke. + DepositReceiptVersion *uint64 `rlp:"optional"` +} + // storedReceiptRLP is the storage encoding of a receipt. type storedReceiptRLP struct { PostStateOrStatus []byte CumulativeGasUsed uint64 Logs []*Log + // DepositNonce was introduced in Regolith to store the actual nonce used by deposit transactions. + // Must be nil for any transactions prior to Regolith or that aren't deposit transactions. + DepositNonce *uint64 `rlp:"optional"` + // Receipt hash post-Regolith but pre-Canyon inadvertently did not include the above + // DepositNonce. Post Canyon, receipts will have a non-empty DepositReceiptVersion indicating + // which post-Canyon receipt hash function to invoke. + DepositReceiptVersion *uint64 `rlp:"optional"` +} + +// LegacyOptimismStoredReceiptRLP is the pre bedrock storage encoding of a +// receipt. It will only exist in the database if it was migrated using the +// migration tool. Nodes that sync using snap-sync will not have any of these +// entries. +type LegacyOptimismStoredReceiptRLP struct { + PostStateOrStatus []byte + CumulativeGasUsed uint64 + Logs []*LogForStorage + L1GasUsed *big.Int + L1GasPrice *big.Int + L1Fee *big.Int + FeeScalar string +} + +// LogForStorage is a wrapper around a Log that handles +// backward compatibility with prior storage formats. +type LogForStorage Log + +// EncodeRLP implements rlp.Encoder. +func (l *LogForStorage) EncodeRLP(w io.Writer) error { + rl := Log{Address: l.Address, Topics: l.Topics, Data: l.Data} + return rlp.Encode(w, &rl) +} + +type legacyRlpStorageLog struct { + Address common.Address + Topics []common.Hash + Data []byte + BlockNumber uint64 + TxHash common.Hash + TxIndex uint + BlockHash common.Hash + Index uint +} + +// DecodeRLP implements rlp.Decoder. +// +// Note some redundant fields(e.g. block number, tx hash etc) will be assembled later. +func (l *LogForStorage) DecodeRLP(s *rlp.Stream) error { + blob, err := s.Raw() + if err != nil { + return err + } + var dec Log + err = rlp.DecodeBytes(blob, &dec) + if err == nil { + *l = LogForStorage{ + Address: dec.Address, + Topics: dec.Topics, + Data: dec.Data, + } + } else { + // Try to decode log with previous definition. + var dec legacyRlpStorageLog + err = rlp.DecodeBytes(blob, &dec) + if err == nil { + *l = LogForStorage{ + Address: dec.Address, + Topics: dec.Topics, + Data: dec.Data, + } + } + } + return err }   // NewReceipt creates a barebone transaction receipt, copying the init fields. @@ -136,7 +255,13 @@ // encodeTyped writes the canonical encoding of a typed receipt to w. func (r *Receipt) encodeTyped(data *receiptRLP, w *bytes.Buffer) error { w.WriteByte(r.Type) - return rlp.Encode(w, data) + switch r.Type { + case DepositTxType: + withNonce := &depositReceiptRLP{data.PostStateOrStatus, data.CumulativeGasUsed, data.Bloom, data.Logs, r.DepositNonce, r.DepositReceiptVersion} + return rlp.Encode(w, withNonce) + default: + return rlp.Encode(w, data) + } }   // MarshalBinary returns the consensus encoding of the receipt. @@ -212,6 +337,16 @@ return err } r.Type = b[0] return r.setFromRLP(data) + case DepositTxType: + var data depositReceiptRLP + err := rlp.DecodeBytes(b[1:], &data) + if err != nil { + return err + } + r.Type = b[0] + r.DepositNonce = data.DepositNonce + r.DepositReceiptVersion = data.DepositReceiptVersion + return r.setFromRLP(receiptRLP{data.PostStateOrStatus, data.CumulativeGasUsed, data.Bloom, data.Logs}) default: return ErrTxTypeNotSupported } @@ -275,6 +410,12 @@ return err } } w.ListEnd(logList) + if r.DepositNonce != nil { + w.WriteUint64(*r.DepositNonce) + if r.DepositReceiptVersion != nil { + w.WriteUint64(*r.DepositReceiptVersion) + } + } w.ListEnd(outerList) return w.Flush() } @@ -282,8 +423,51 @@ // DecodeRLP implements rlp.Decoder, and loads both consensus and implementation // fields of a receipt from an RLP stream. func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { + // Retrieve the entire receipt blob as we need to try multiple decoders + blob, err := s.Raw() + if err != nil { + return err + } + // First try to decode the latest receipt database format, try the pre-bedrock Optimism legacy format otherwise. + if err := decodeStoredReceiptRLP(r, blob); err == nil { + return nil + } + return decodeLegacyOptimismReceiptRLP(r, blob) +} + +func decodeLegacyOptimismReceiptRLP(r *ReceiptForStorage, blob []byte) error { + var stored LegacyOptimismStoredReceiptRLP + if err := rlp.DecodeBytes(blob, &stored); err != nil { + return err + } + if err := (*Receipt)(r).setStatus(stored.PostStateOrStatus); err != nil { + return err + } + r.CumulativeGasUsed = stored.CumulativeGasUsed + r.Logs = make([]*Log, len(stored.Logs)) + for i, log := range stored.Logs { + r.Logs[i] = (*Log)(log) + } + r.Bloom = CreateBloom(Receipts{(*Receipt)(r)}) + // UsingOVM + scalar := new(big.Float) + if stored.FeeScalar != "" { + var ok bool + scalar, ok = scalar.SetString(stored.FeeScalar) + if !ok { + return errors.New("cannot parse fee scalar") + } + } + r.L1GasUsed = stored.L1GasUsed + r.L1GasPrice = stored.L1GasPrice + r.L1Fee = stored.L1Fee + r.FeeScalar = scalar + return nil +} + +func decodeStoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { var stored storedReceiptRLP - if err := s.Decode(&stored); err != nil { + if err := rlp.DecodeBytes(blob, &stored); err != nil { return err } if err := (*Receipt)(r).setStatus(stored.PostStateOrStatus); err != nil { @@ -292,7 +476,10 @@ } r.CumulativeGasUsed = stored.CumulativeGasUsed r.Logs = stored.Logs r.Bloom = CreateBloom(Receipts{(*Receipt)(r)}) - + if stored.DepositNonce != nil { + r.DepositNonce = stored.DepositNonce + r.DepositReceiptVersion = stored.DepositReceiptVersion + } return nil }   @@ -302,7 +489,10 @@ // Len returns the number of receipts in this list. func (rs Receipts) Len() int { return len(rs) }   -// EncodeIndex encodes the i'th receipt to w. +// EncodeIndex encodes the i'th receipt to w. For DepositTxType receipts with non-nil DepositNonce +// but nil DepositReceiptVersion, the output will differ than calling r.MarshalBinary(); this +// behavior difference should not be changed to preserve backwards compatibility of receipt-root +// hash computation. func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) { r := rs[i] data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs} @@ -314,6 +504,14 @@ w.WriteByte(r.Type) switch r.Type { case AccessListTxType, DynamicFeeTxType, BlobTxType, SetCodeTxType: rlp.Encode(w, data) + case DepositTxType: + if r.DepositReceiptVersion != nil { + // post-canyon receipt hash computation update + depositData := &depositReceiptRLP{data.PostStateOrStatus, data.CumulativeGasUsed, r.Bloom, r.Logs, r.DepositNonce, r.DepositReceiptVersion} + rlp.Encode(w, depositData) + } else { + rlp.Encode(w, data) + } default: // For unsupported types, write nothing. Since this is for // DeriveSha, the error will be caught matching the derived hash @@ -351,7 +549,11 @@ // The contract address can be derived from the transaction itself if txs[i].To() == nil { // Deriving the signer is expensive, only do if it's actually needed from, _ := Sender(signer, txs[i]) - rs[i].ContractAddress = crypto.CreateAddress(from, txs[i].Nonce()) + nonce := txs[i].Nonce() + if rs[i].DepositNonce != nil { + nonce = *rs[i].DepositNonce + } + rs[i].ContractAddress = crypto.CreateAddress(from, nonce) } else { rs[i].ContractAddress = common.Address{} } @@ -373,5 +575,30 @@ rs[i].Logs[j].Index = logIndex logIndex++ } } + if config.Optimism != nil && len(txs) >= 2 && config.IsBedrock(new(big.Int).SetUint64(number)) { // need at least an info tx and a non-info tx + gasParams, err := extractL1GasParams(config, time, txs[0].Data()) + if err != nil { + return err + } + for i := 0; i < len(rs); i++ { + if txs[i].IsDepositTx() { + continue + } + rs[i].L1GasPrice = gasParams.l1BaseFee + rs[i].L1BlobBaseFee = gasParams.l1BlobBaseFee + rs[i].L1Fee, rs[i].L1GasUsed = gasParams.costFunc(txs[i].RollupCostData()) + rs[i].FeeScalar = gasParams.feeScalar + rs[i].L1BaseFeeScalar = u32ptrTou64ptr(gasParams.l1BaseFeeScalar) + rs[i].L1BlobBaseFeeScalar = u32ptrTou64ptr(gasParams.l1BlobBaseFeeScalar) + } + } return nil } + +func u32ptrTou64ptr(a *uint32) *uint64 { + if a == nil { + return nil + } + b := uint64(*a) + return &b +}

Forward transactions to the sequencer if configured.

diff --git go-ethereum/eth/api_backend.go op-geth/eth/api_backend.go index be2101c6ec8ab6b0d2fbc5025e17af65bc5aae00..541b9d203bf3f49343bb0b111aeb3c82d36e88b8 100644 --- go-ethereum/eth/api_backend.go +++ op-geth/eth/api_backend.go @@ -19,12 +19,14 @@ import ( "context" "errors" + "fmt" "math/big" "time"   "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" @@ -38,6 +40,7 @@ "github.com/ethereum/go-ethereum/eth/gasprice" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" ) @@ -46,6 +49,7 @@ // EthAPIBackend implements ethapi.Backend and tracers.Backend for full nodes type EthAPIBackend struct { extRPCEnabled bool allowUnprotectedTxs bool + disableTxPool bool eth *Ethereum gpo *gasprice.Oracle } @@ -190,10 +194,11 @@ func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) { // Pending state is only known by the miner if number == rpc.PendingBlockNumber { block, _, state := b.eth.miner.Pending() - if block == nil || state == nil { - return nil, nil, errors.New("pending state is not available") + if block != nil && state != nil { + return state, block.Header(), nil + } else { + number = rpc.LatestBlockNumber // fall back to latest state } - return state, block.Header(), nil } // Otherwise resolve the block number and return its state header, err := b.HeaderByNumber(ctx, number) @@ -201,7 +206,7 @@ if err != nil { return nil, nil, err } if header == nil { - return nil, nil, errors.New("header not found") + return nil, nil, fmt.Errorf("header %w", ethereum.NotFound) } stateDb, err := b.eth.BlockChain().StateAt(header.Root) if err != nil { @@ -220,7 +225,7 @@ if err != nil { return nil, nil, err } if header == nil { - return nil, nil, errors.New("header for hash not found") + return nil, nil, fmt.Errorf("header for hash %w", ethereum.NotFound) } if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash { return nil, nil, errors.New("hash is not currently canonical") @@ -257,7 +262,7 @@ var context vm.BlockContext if blockCtx != nil { context = *blockCtx } else { - context = core.NewEVMBlockContext(header, b.eth.BlockChain(), nil) + context = core.NewEVMBlockContext(header, b.eth.BlockChain(), nil, b.eth.blockchain.Config(), state) } return vm.NewEVM(context, state, b.ChainConfig(), *vmConfig) } @@ -279,6 +284,29 @@ return b.eth.BlockChain().SubscribeLogsEvent(ch) }   func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { + if b.ChainConfig().IsOptimism() && signedTx.Type() == types.BlobTxType { + return types.ErrTxTypeNotSupported + } + if b.eth.seqRPCService != nil { + data, err := signedTx.MarshalBinary() + if err != nil { + return err + } + if err := b.eth.seqRPCService.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data)); err != nil { + return err + } + if b.disableTxPool { + return nil + } + // Retain tx in local tx pool after forwarding, for local RPC usage. + if err := b.eth.txPool.Add([]*types.Transaction{signedTx}, true, false)[0]; err != nil { + log.Warn("successfully sent tx to sequencer, but failed to persist in local tx pool", "err", err, "tx", signedTx.Hash()) + } + return nil + } + if b.disableTxPool { + return nil + } return b.eth.txPool.Add([]*types.Transaction{signedTx}, true, false)[0] }   @@ -426,3 +454,11 @@ func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*types.Transaction, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) { return b.eth.stateAtTransaction(ctx, block, txIndex, reexec) } + +func (b *EthAPIBackend) HistoricalRPCService() *rpc.Client { + return b.eth.historicalRPCService +} + +func (b *EthAPIBackend) Genesis() *types.Block { + return b.eth.blockchain.Genesis() +}
diff --git go-ethereum/eth/backend.go op-geth/eth/backend.go index a3aa0a7b9b74a9b2ea7b94523395dce3670ef873..ef97d04119d2ab0230cf27e4d90186e3a8de94a4 100644 --- go-ethereum/eth/backend.go +++ op-geth/eth/backend.go @@ -18,11 +18,13 @@ // Package eth implements the Ethereum protocol. package eth   import ( + "context" "encoding/json" "fmt" "math/big" "runtime" "sync" + "time"   "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" @@ -40,12 +42,14 @@ "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/eth/interop" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/internal/sequencerapi" "github.com/ethereum/go-ethereum/internal/shutdowncheck" "github.com/ethereum/go-ethereum/internal/version" "github.com/ethereum/go-ethereum/log" @@ -58,6 +62,7 @@ "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" gethversion "github.com/ethereum/go-ethereum/version" + "golang.org/x/time/rate" )   // Config contains the configuration options of the ETH protocol. @@ -74,6 +79,11 @@ handler *handler discmix *enode.FairMix   + seqRPCService *rpc.Client + historicalRPCService *rpc.Client + + interopRPC *interop.InteropClient + // DB interfaces chainDb ethdb.Database // Block chain database   @@ -98,6 +108,8 @@ lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase)   shutdownTracker *shutdowncheck.ShutdownTracker // Tracks if and when the node has shutdown ungracefully + + nodeCloser func() error }   // New creates a new Ethereum object (including the initialisation of the common Ethereum object), @@ -164,13 +176,13 @@ bloomIndexer: core.NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms), p2pServer: stack.Server(), discmix: enode.NewFairMix(0), shutdownTracker: shutdowncheck.NewShutdownTracker(chainDb), + nodeCloser: stack.Close, } bcVersion := rawdb.ReadDatabaseVersion(chainDb) - var dbVer = "<nil>" + dbVer := "<nil>" if bcVersion != nil { dbVer = fmt.Sprintf("%d", *bcVersion) } - log.Info("Initialising Ethereum protocol", "network", networkID, "dbversion", dbVer)   if !config.SkipBcVersionCheck { if bcVersion != nil && *bcVersion > core.BlockChainVersion { @@ -217,23 +229,65 @@ } if config.OverrideVerkle != nil { overrides.OverrideVerkle = config.OverrideVerkle } + if config.OverrideOptimismCanyon != nil { + overrides.OverrideOptimismCanyon = config.OverrideOptimismCanyon + } + if config.OverrideOptimismEcotone != nil { + overrides.OverrideOptimismEcotone = config.OverrideOptimismEcotone + } + if config.OverrideOptimismFjord != nil { + overrides.OverrideOptimismFjord = config.OverrideOptimismFjord + } + if config.OverrideOptimismGranite != nil { + overrides.OverrideOptimismGranite = config.OverrideOptimismGranite + } + if config.OverrideOptimismHolocene != nil { + overrides.OverrideOptimismHolocene = config.OverrideOptimismHolocene + } + if config.OverrideOptimismIsthmus != nil { + overrides.OverrideOptimismIsthmus = config.OverrideOptimismIsthmus + } + if config.OverrideOptimismJovian != nil { + overrides.OverrideOptimismJovian = config.OverrideOptimismJovian + } + if config.OverrideOptimismInterop != nil { + overrides.OverrideOptimismInterop = config.OverrideOptimismInterop + } + overrides.ApplySuperchainUpgrades = config.ApplySuperchainUpgrades + eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, config.Genesis, &overrides, eth.engine, vmConfig, &config.TransactionHistory) if err != nil { return nil, err } + if chainConfig := eth.blockchain.Config(); chainConfig.Optimism != nil { // config.Genesis.Config.ChainID cannot be used because it's based on CLI flags only, thus default to mainnet L1 + config.NetworkId = chainConfig.ChainID.Uint64() // optimism defaults eth network ID to chain ID + eth.networkID = config.NetworkId + } + log.Info("Initialising Ethereum protocol", "network", config.NetworkId, "dbversion", dbVer) + eth.bloomIndexer.Start(eth.blockchain)   if config.BlobPool.Datadir != "" { config.BlobPool.Datadir = stack.ResolvePath(config.BlobPool.Datadir) } - blobPool := blobpool.New(config.BlobPool, eth.blockchain)   if config.TxPool.Journal != "" { config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal) } legacyPool := legacypool.New(config.TxPool, eth.blockchain)   - eth.txPool, err = txpool.New(config.TxPool.PriceLimit, eth.blockchain, []txpool.SubPool{legacyPool, blobPool}) + txPools := []txpool.SubPool{legacyPool} + if !eth.BlockChain().Config().IsOptimism() { + blobPool := blobpool.New(config.BlobPool, eth.blockchain) + txPools = append(txPools, blobPool) + } + // if interop is enabled, establish an Interop Filter connected to this Ethereum instance's + // simulated logs and message safety check functions + poolFilters := []txpool.IngressFilter{} + if config.InteropMessageRPC != "" && config.InteropMempoolFiltering { + poolFilters = append(poolFilters, txpool.NewInteropFilter(eth.SimLogs, eth.CheckMessages)) + } + eth.txPool, err = txpool.New(config.TxPool.PriceLimit, eth.blockchain, txPools, poolFilters) if err != nil { return nil, err } @@ -249,6 +303,7 @@ Sync: config.SyncMode, BloomCache: uint64(cacheLimit), EventMux: eth.eventMux, RequiredBlocks: config.RequiredBlocks, + NoTxGossip: config.RollupDisableTxPoolGossip, }); err != nil { return nil, err } @@ -256,12 +311,36 @@ eth.miner = miner.New(eth, config.Miner, eth.engine) eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData))   - eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil} + eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, config.RollupDisableTxPoolAdmission, eth, nil} if eth.APIBackend.allowUnprotectedTxs { log.Info("Unprotected transactions allowed") } eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, config.GPO, config.Miner.GasPrice)   + if config.RollupSequencerHTTP != "" { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + client, err := rpc.DialContext(ctx, config.RollupSequencerHTTP) + cancel() + if err != nil { + return nil, err + } + eth.seqRPCService = client + } + + if config.RollupHistoricalRPC != "" { + ctx, cancel := context.WithTimeout(context.Background(), config.RollupHistoricalRPCTimeout) + client, err := rpc.DialContext(ctx, config.RollupHistoricalRPC) + cancel() + if err != nil { + return nil, err + } + eth.historicalRPCService = client + } + + if config.InteropMessageRPC != "" { + eth.interopRPC = interop.NewInteropClient(config.InteropMessageRPC) + } + // Start the RPC service eth.netRPCService = ethapi.NewNetAPI(eth.p2pServer, networkID)   @@ -300,6 +379,13 @@ apis := ethapi.GetAPIs(s.APIBackend)   // Append any APIs exposed explicitly by the consensus engine apis = append(apis, s.engine.APIs(s.BlockChain())...) + + // Append any Sequencer APIs as enabled + if s.config.RollupSequencerTxConditionalEnabled { + log.Info("Enabling eth_sendRawTransactionConditional endpoint support") + costRateLimit := rate.Limit(s.config.RollupSequencerTxConditionalCostRateLimit) + apis = append(apis, sequencerapi.GetSendRawTxConditionalAPI(s.APIBackend, s.seqRPCService, costRateLimit)) + }   // Append all the local APIs and return return append(apis, []rpc.API{ @@ -412,6 +498,18 @@ close(s.closeBloomHandler) s.txPool.Close() s.blockchain.Stop() s.engine.Close() + if s.seqRPCService != nil { + s.seqRPCService.Close() + } + if s.historicalRPCService != nil { + s.historicalRPCService.Close() + } + if s.interopRPC != nil { + s.interopRPC.Close() + } + if s.miner != nil { + s.miner.Close() + }   // Clean shutdown marker as the last thing before closing db s.shutdownTracker.Stop() @@ -447,3 +545,33 @@ } // Nope, we're really full syncing return ethconfig.FullSync } + +// HandleRequiredProtocolVersion handles the protocol version signal. This implements opt-in halting, +// the protocol version data is already logged and metered when signaled through the Engine API. +func (s *Ethereum) HandleRequiredProtocolVersion(required params.ProtocolVersion) error { + var needLevel int + switch s.config.RollupHaltOnIncompatibleProtocolVersion { + case "major": + needLevel = 3 + case "minor": + needLevel = 2 + case "patch": + needLevel = 1 + default: + return nil // do not consider halting if not configured to + } + haveLevel := 0 + switch params.OPStackSupport.Compare(required) { + case params.OutdatedMajor: + haveLevel = 3 + case params.OutdatedMinor: + haveLevel = 2 + case params.OutdatedPatch: + haveLevel = 1 + } + if haveLevel >= needLevel { // halt if we opted in to do so at this granularity + log.Error("Opted to halt, unprepared for protocol change", "required", required, "local", params.OPStackSupport) + return s.nodeCloser() + } + return nil +}
diff --git go-ethereum/internal/ethapi/backend.go op-geth/internal/ethapi/backend.go index 3d8f7aa700b79235c1289f96ec6987117b7319de..fce1f724cb0d49e606a01cca096775f21a7cbc90 100644 --- go-ethereum/internal/ethapi/backend.go +++ op-geth/internal/ethapi/backend.go @@ -85,6 +85,8 @@ SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription   ChainConfig() *params.ChainConfig Engine() consensus.Engine + HistoricalRPCService() *rpc.Client + Genesis() *types.Block   // This is copied from filters.Backend // eth/filters needs to be initialized from this backend type, so methods needed by
diff --git go-ethereum/eth/state_accessor.go op-geth/eth/state_accessor.go index 99ed28d96afc437e2294bd38ed2b7c1477d6bd92..6f932fb0d98232cfd14de7d0441aae2f0e4327ab 100644 --- go-ethereum/eth/state_accessor.go +++ op-geth/eth/state_accessor.go @@ -235,7 +235,7 @@ if err != nil { return nil, vm.BlockContext{}, nil, nil, err } // Insert parent beacon block root in the state as per EIP-4788. - context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil) + context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil, eth.blockchain.Config(), statedb) evm := vm.NewEVM(context, statedb, eth.blockchain.Config(), vm.Config{}) if beaconRoot := block.BeaconRoot(); beaconRoot != nil { core.ProcessBeaconBlockRoot(*beaconRoot, evm)

Format deposit and L1-cost data in transaction responses. Add debug_chainConfig API.

diff --git go-ethereum/internal/ethapi/api.go op-geth/internal/ethapi/api.go index d9cec560ea2f8574ae080b56c48b6c185ad06837..34daf5a229eddcc55ff55dc050cc2392beb7f17b 100644 --- go-ethereum/internal/ethapi/api.go +++ op-geth/internal/ethapi/api.go @@ -27,6 +27,7 @@ "strings" "time"   "github.com/davecgh/go-spew/spew" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -323,6 +324,24 @@ // GetBalance returns the amount of wei for the given address in the state of the // given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta // block numbers are also allowed. func (api *BlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { + header, err := headerByNumberOrHash(ctx, api.b, blockNrOrHash) + if err != nil { + return nil, err + } + + if api.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if api.b.HistoricalRPCService() != nil { + var res hexutil.Big + err := api.b.HistoricalRPCService().CallContext(ctx, &res, "eth_getBalance", address, blockNrOrHash) + if err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) + } + return &res, nil + } else { + return nil, rpc.ErrNoHistoricalFallback + } + } + state, _, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err @@ -363,6 +382,22 @@ }   // GetProof returns the Merkle-proof for a given account and optionally some storage keys. func (api *BlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) { + header, err := headerByNumberOrHash(ctx, api.b, blockNrOrHash) + if err != nil { + return nil, err + } + if api.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if api.b.HistoricalRPCService() != nil { + var res AccountResult + err := api.b.HistoricalRPCService().CallContext(ctx, &res, "eth_getProof", address, storageKeys, blockNrOrHash) + if err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) + } + return &res, nil + } else { + return nil, rpc.ErrNoHistoricalFallback + } + } var ( keys = make([]common.Hash, len(storageKeys)) keyLengths = make([]int, len(storageKeys)) @@ -466,7 +501,7 @@ func (api *BlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { header, err := api.b.HeaderByNumber(ctx, number) if header != nil && err == nil { response := RPCMarshalHeader(header) - if number == rpc.PendingBlockNumber { + if number == rpc.PendingBlockNumber && api.b.ChainConfig().Optimism == nil { // Pending header need to nil out a few fields for _, field := range []string{"hash", "nonce", "miner"} { response[field] = nil @@ -496,14 +531,14 @@ // only the transaction hash is returned. func (api *BlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { block, err := api.b.BlockByNumber(ctx, number) if block != nil && err == nil { - response := RPCMarshalBlock(block, true, fullTx, api.b.ChainConfig()) - if number == rpc.PendingBlockNumber { + response, err := RPCMarshalBlock(ctx, block, true, fullTx, api.b.ChainConfig(), api.b) + if err == nil && number == rpc.PendingBlockNumber && api.b.ChainConfig().Optimism == nil { // Pending blocks need to nil out a few fields for _, field := range []string{"hash", "nonce", "miner"} { response[field] = nil } } - return response, nil + return response, err } return nil, err } @@ -513,7 +548,7 @@ // detail, otherwise only the transaction hash is returned. func (api *BlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) { block, err := api.b.BlockByHash(ctx, hash) if block != nil { - return RPCMarshalBlock(block, true, fullTx, api.b.ChainConfig()), nil + return RPCMarshalBlock(ctx, block, true, fullTx, api.b.ChainConfig(), api.b) } return nil, err } @@ -528,7 +563,7 @@ log.Debug("Requested uncle not found", "number", blockNr, "hash", block.Hash(), "index", index) return nil, nil } block = types.NewBlockWithHeader(uncles[index]) - return RPCMarshalBlock(block, false, false, api.b.ChainConfig()), nil + return RPCMarshalBlock(ctx, block, false, false, api.b.ChainConfig(), api.b) } return nil, err } @@ -543,7 +578,7 @@ log.Debug("Requested uncle not found", "number", block.Number(), "hash", blockHash, "index", index) return nil, nil } block = types.NewBlockWithHeader(uncles[index]) - return RPCMarshalBlock(block, false, false, api.b.ChainConfig()), nil + return RPCMarshalBlock(ctx, block, false, false, api.b.ChainConfig(), api.b) } return nil, err } @@ -568,10 +603,29 @@ }   // GetCode returns the code stored at the given address in the state for the given block number. func (api *BlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { + header, err := headerByNumberOrHash(ctx, api.b, blockNrOrHash) + if err != nil { + return nil, err + } + + if api.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if api.b.HistoricalRPCService() != nil { + var res hexutil.Bytes + err := api.b.HistoricalRPCService().CallContext(ctx, &res, "eth_getCode", address, blockNrOrHash) + if err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) + } + return res, nil + } else { + return nil, rpc.ErrNoHistoricalFallback + } + } + state, _, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } + code := state.GetCode(address) return code, state.Error() } @@ -580,10 +634,29 @@ // GetStorageAt returns the storage from the state at the given address, key and // block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block // numbers are also allowed. func (api *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, hexKey string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { + header, err := headerByNumberOrHash(ctx, api.b, blockNrOrHash) + if err != nil { + return nil, err + } + + if api.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if api.b.HistoricalRPCService() != nil { + var res hexutil.Bytes + err := api.b.HistoricalRPCService().CallContext(ctx, &res, "eth_getStorageAt", address, hexKey, blockNrOrHash) + if err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) + } + return res, nil + } else { + return nil, rpc.ErrNoHistoricalFallback + } + } + state, _, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } + key, _, err := decodeHash(hexKey) if err != nil { return nil, fmt.Errorf("unable to decode storage key: %s", err) @@ -592,6 +665,18 @@ res := state.GetState(address, key) return res[:], state.Error() }   +// The HeaderByNumberOrHash method returns a nil error and nil header +// if the header is not found, but only for nonexistent block numbers. This is +// different from StateAndHeaderByNumberOrHash. To account for this discrepancy, +// headerOrNumberByHash will properly convert the error into an ethereum.NotFound. +func headerByNumberOrHash(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) { + header, err := b.HeaderByNumberOrHash(ctx, blockNrOrHash) + if header == nil { + return nil, fmt.Errorf("header %w", ethereum.NotFound) + } + return header, err +} + // GetBlockReceipts returns the block receipts for the given block hash or number or tag. func (api *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) { block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash) @@ -614,7 +699,7 @@ signer := types.MakeSigner(api.b.ChainConfig(), block.Number(), block.Time())   result := make([]map[string]interface{}, len(receipts)) for i, receipt := range receipts { - result[i] = marshalReceipt(receipt, block.Hash(), block.NumberU64(), signer, txs[i], i) + result[i] = marshalReceipt(receipt, block.Hash(), block.NumberU64(), signer, txs[i], i, api.b.ChainConfig()) }   return result, nil @@ -653,7 +738,7 @@ return header }   func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, overrides *override.StateOverride, blockOverrides *override.BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { - blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) + blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil, b.ChainConfig(), state) if blockOverrides != nil { blockOverrides.Apply(&blockCtx) } @@ -752,6 +837,25 @@ if blockNrOrHash == nil { latest := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) blockNrOrHash = &latest } + + header, err := headerByNumberOrHash(ctx, api.b, *blockNrOrHash) + if err != nil { + return nil, err + } + + if api.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if api.b.HistoricalRPCService() != nil { + var res hexutil.Bytes + err := api.b.HistoricalRPCService().CallContext(ctx, &res, "eth_call", args, blockNrOrHash, overrides) + if err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) + } + return res, nil + } else { + return nil, rpc.ErrNoHistoricalFallback + } + } + result, err := DoCall(ctx, api.b, args, *blockNrOrHash, overrides, blockOverrides, api.b.RPCEVMTimeout(), api.b.RPCGasCap()) if err != nil { return nil, err @@ -856,6 +960,25 @@ bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) if blockNrOrHash != nil { bNrOrHash = *blockNrOrHash } + + header, err := headerByNumberOrHash(ctx, api.b, bNrOrHash) + if err != nil { + return 0, err + } + + if api.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if api.b.HistoricalRPCService() != nil { + var res hexutil.Uint64 + err := api.b.HistoricalRPCService().CallContext(ctx, &res, "eth_estimateGas", args, blockNrOrHash) + if err != nil { + return 0, fmt.Errorf("historical backend error: %w", err) + } + return res, nil + } else { + return 0, rpc.ErrNoHistoricalFallback + } + } + return DoEstimateGas(ctx, api.b, args, bNrOrHash, overrides, blockOverrides, api.b.RPCGasCap()) }   @@ -903,7 +1026,7 @@ // RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are // returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain // transaction hashes. -func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *params.ChainConfig) map[string]interface{} { +func RPCMarshalBlock(ctx context.Context, block *types.Block, inclTx bool, fullTx bool, config *params.ChainConfig, backend Backend) (map[string]interface{}, error) { fields := RPCMarshalHeader(block.Header()) fields["size"] = hexutil.Uint64(block.Size())   @@ -913,7 +1036,7 @@ return tx.Hash() } if fullTx { formatTx = func(idx int, tx *types.Transaction) interface{} { - return newRPCTransactionFromBlockIndex(block, uint64(idx), config) + return newRPCTransactionFromBlockIndex(ctx, block, uint64(idx), config, backend) } } txs := block.Transactions() @@ -932,7 +1055,7 @@ fields["uncles"] = uncleHashes if block.Withdrawals() != nil { fields["withdrawals"] = block.Withdrawals() } - return fields + return fields, nil }   // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction @@ -960,11 +1083,18 @@ V *hexutil.Big `json:"v"` R *hexutil.Big `json:"r"` S *hexutil.Big `json:"s"` YParity *hexutil.Uint64 `json:"yParity,omitempty"` + + // deposit-tx only + SourceHash *common.Hash `json:"sourceHash,omitempty"` + Mint *hexutil.Big `json:"mint,omitempty"` + IsSystemTx *bool `json:"isSystemTx,omitempty"` + // deposit-tx post-Canyon only + DepositReceiptVersion *hexutil.Uint64 `json:"depositReceiptVersion,omitempty"` }   // newRPCTransaction returns a transaction that will serialize to the RPC // representation, with the given location metadata set (if available). -func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, blockTime uint64, index uint64, baseFee *big.Int, config *params.ChainConfig) *RPCTransaction { +func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, blockTime uint64, index uint64, baseFee *big.Int, config *params.ChainConfig, receipt *types.Receipt) *RPCTransaction { signer := types.MakeSigner(config, new(big.Int).SetUint64(blockNumber), blockTime) from, _ := types.Sender(signer, tx) v, r, s := tx.RawSignatureValues() @@ -989,7 +1119,27 @@ result.TransactionIndex = (*hexutil.Uint64)(&index) }   switch tx.Type() { + case types.DepositTxType: + srcHash := tx.SourceHash() + isSystemTx := tx.IsSystemTx() + result.SourceHash = &srcHash + if isSystemTx { + // Only include IsSystemTx when true + result.IsSystemTx = &isSystemTx + } + result.Mint = (*hexutil.Big)(tx.Mint()) + if receipt != nil && receipt.DepositNonce != nil { + result.Nonce = hexutil.Uint64(*receipt.DepositNonce) + if receipt.DepositReceiptVersion != nil { + result.DepositReceiptVersion = new(hexutil.Uint64) + *result.DepositReceiptVersion = hexutil.Uint64(*receipt.DepositReceiptVersion) + } + } case types.LegacyTxType: + if v.Sign() == 0 && r.Sign() == 0 && s.Sign() == 0 { // pre-bedrock relayed tx does not have a signature + result.ChainID = (*hexutil.Big)(new(big.Int).Set(config.ChainID)) + break + } // if a legacy transaction has an EIP-155 chain id, include it explicitly if id := tx.ChainId(); id.Sign() != 0 { result.ChainID = (*hexutil.Big)(id) @@ -1074,20 +1224,36 @@ blockNumber = uint64(0) blockTime = uint64(0) ) if current != nil { - baseFee = eip1559.CalcBaseFee(config, current) + baseFee = eip1559.CalcBaseFee(config, current, current.Time+1) blockNumber = current.Number.Uint64() blockTime = current.Time } - return newRPCTransaction(tx, common.Hash{}, blockNumber, blockTime, 0, baseFee, config) + return newRPCTransaction(tx, common.Hash{}, blockNumber, blockTime, 0, baseFee, config, nil) }   // newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation. -func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, config *params.ChainConfig) *RPCTransaction { +func newRPCTransactionFromBlockIndex(ctx context.Context, b *types.Block, index uint64, config *params.ChainConfig, backend Backend) *RPCTransaction { txs := b.Transactions() if index >= uint64(len(txs)) { return nil } - return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), b.Time(), index, b.BaseFee(), config) + tx := txs[index] + rcpt := depositTxReceipt(ctx, b.Hash(), index, backend, tx) + return newRPCTransaction(tx, b.Hash(), b.NumberU64(), b.Time(), index, b.BaseFee(), config, rcpt) +} + +func depositTxReceipt(ctx context.Context, blockHash common.Hash, index uint64, backend Backend, tx *types.Transaction) *types.Receipt { + if tx.Type() != types.DepositTxType { + return nil + } + receipts, err := backend.GetReceipts(ctx, blockHash) + if err != nil { + return nil + } + if index >= uint64(len(receipts)) { + return nil + } + return receipts[index] }   // newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index. @@ -1111,12 +1277,27 @@ }   // CreateAccessList creates an EIP-2930 type AccessList for the given transaction. // Reexec and BlockNrOrHash can be specified to create the accessList on top of a certain state. -func (api *BlockChainAPI) CreateAccessList(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (*accessListResult, error) { +func (api *BlockChainAPI) CreateAccessList(ctx context.Context, args TransactionArgs, state *state.StateDB, blockNrOrHash *rpc.BlockNumberOrHash) (*accessListResult, error) { bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) if blockNrOrHash != nil { bNrOrHash = *blockNrOrHash } - acl, gasUsed, vmerr, err := AccessList(ctx, api.b, bNrOrHash, args) + + header, err := headerByNumberOrHash(ctx, api.b, bNrOrHash) + if err == nil && header != nil && api.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if api.b.HistoricalRPCService() != nil { + var res accessListResult + err := api.b.HistoricalRPCService().CallContext(ctx, &res, "eth_createAccessList", args, blockNrOrHash) + if err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) + } + return &res, nil + } else { + return nil, rpc.ErrNoHistoricalFallback + } + } + + acl, gasUsed, vmerr, err := AccessList(ctx, api.b, bNrOrHash, args, state) if err != nil { return nil, err } @@ -1130,7 +1311,7 @@ // AccessList creates an access list for the given transaction. // If the accesslist creation fails an error is returned. // If the transaction itself fails, an vmErr is returned. -func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash, args TransactionArgs) (acl types.AccessList, gasUsed uint64, vmErr error, err error) { +func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash, args TransactionArgs, state *state.StateDB) (acl types.AccessList, gasUsed uint64, vmErr error, err error) { // Retrieve the execution context db, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if db == nil || err != nil { @@ -1145,7 +1326,7 @@ if args.Nonce == nil { nonce := hexutil.Uint64(db.GetNonce(args.from())) args.Nonce = &nonce } - blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) + blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil, b.ChainConfig(), state) if err = args.CallDefaults(b.RPCGasCap(), blockCtx.BaseFee, b.ChainConfig().ChainID); err != nil { return nil, 0, nil, err } @@ -1239,7 +1420,7 @@ // GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. func (api *TransactionAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction { if block, _ := api.b.BlockByNumber(ctx, blockNr); block != nil { - return newRPCTransactionFromBlockIndex(block, uint64(index), api.b.ChainConfig()) + return newRPCTransactionFromBlockIndex(ctx, block, uint64(index), api.b.ChainConfig(), api.b) } return nil } @@ -1247,7 +1428,7 @@ // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. func (api *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction { if block, _ := api.b.BlockByHash(ctx, blockHash); block != nil { - return newRPCTransactionFromBlockIndex(block, uint64(index), api.b.ChainConfig()) + return newRPCTransactionFromBlockIndex(ctx, block, uint64(index), api.b.ChainConfig(), api.b) } return nil } @@ -1279,10 +1460,29 @@ } return (*hexutil.Uint64)(&nonce), nil } // Resolve block number and use its state to ask for the nonce + header, err := headerByNumberOrHash(ctx, api.b, blockNrOrHash) + if err != nil { + return nil, err + } + + if api.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if api.b.HistoricalRPCService() != nil { + var res hexutil.Uint64 + err := api.b.HistoricalRPCService().CallContext(ctx, &res, "eth_getTransactionCount", address, blockNrOrHash) + if err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) + } + return &res, nil + } else { + return nil, rpc.ErrNoHistoricalFallback + } + } + state, _, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } + nonce := state.GetNonce(address) return (*hexutil.Uint64)(&nonce), state.Error() } @@ -1305,7 +1505,8 @@ header, err := api.b.HeaderByHash(ctx, blockHash) if err != nil { return nil, err } - return newRPCTransaction(tx, blockHash, blockNumber, header.Time, index, header.BaseFee, api.b.ChainConfig()), nil + rcpt := depositTxReceipt(ctx, blockHash, index, api.b, tx) + return newRPCTransaction(tx, blockHash, blockNumber, header.Time, index, header.BaseFee, api.b.ChainConfig(), rcpt), nil }   // GetRawTransactionByHash returns the bytes of the transaction for the given hash. @@ -1348,11 +1549,11 @@ receipt := receipts[index]   // Derive the sender. signer := types.MakeSigner(api.b.ChainConfig(), header.Number, header.Time) - return marshalReceipt(receipt, blockHash, blockNumber, signer, tx, int(index)), nil + return marshalReceipt(receipt, blockHash, blockNumber, signer, tx, int(index), api.b.ChainConfig()), nil }   // marshalReceipt marshals a transaction receipt into a JSON object. -func marshalReceipt(receipt *types.Receipt, blockHash common.Hash, blockNumber uint64, signer types.Signer, tx *types.Transaction, txIndex int) map[string]interface{} { +func marshalReceipt(receipt *types.Receipt, blockHash common.Hash, blockNumber uint64, signer types.Signer, tx *types.Transaction, txIndex int, chainConfig *params.ChainConfig) map[string]interface{} { from, _ := types.Sender(signer, tx)   fields := map[string]interface{}{ @@ -1371,6 +1572,32 @@ "type": hexutil.Uint(tx.Type()), "effectiveGasPrice": (*hexutil.Big)(receipt.EffectiveGasPrice), }   + if chainConfig.Optimism != nil && !tx.IsDepositTx() { + fields["l1GasPrice"] = (*hexutil.Big)(receipt.L1GasPrice) + fields["l1GasUsed"] = (*hexutil.Big)(receipt.L1GasUsed) + fields["l1Fee"] = (*hexutil.Big)(receipt.L1Fee) + // Fields removed with Ecotone + if receipt.FeeScalar != nil { + fields["l1FeeScalar"] = receipt.FeeScalar.String() + } + // Fields added in Ecotone + if receipt.L1BlobBaseFee != nil { + fields["l1BlobBaseFee"] = (*hexutil.Big)(receipt.L1BlobBaseFee) + } + if receipt.L1BaseFeeScalar != nil { + fields["l1BaseFeeScalar"] = hexutil.Uint64(*receipt.L1BaseFeeScalar) + } + if receipt.L1BlobBaseFeeScalar != nil { + fields["l1BlobBaseFeeScalar"] = hexutil.Uint64(*receipt.L1BlobBaseFeeScalar) + } + } + if chainConfig.Optimism != nil && tx.IsDepositTx() && receipt.DepositNonce != nil { + fields["depositNonce"] = hexutil.Uint64(*receipt.DepositNonce) + if receipt.DepositReceiptVersion != nil { + fields["depositReceiptVersion"] = hexutil.Uint64(*receipt.DepositReceiptVersion) + } + } + // Assign receipt status or post state. if len(receipt.PostState) > 0 { fields["root"] = hexutil.Bytes(receipt.PostState) @@ -1543,6 +1770,9 @@ return nil, errors.New("gas not specified") } if args.GasPrice == nil && (args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil) { return nil, errors.New("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas") + } + if args.IsEIP4844() { + return nil, errBlobTxNotSupported } if args.Nonce == nil { return nil, errors.New("nonce not specified") @@ -1784,6 +2014,10 @@ func (api *DebugAPI) SetHead(number hexutil.Uint64) { api.b.SetHead(uint64(number)) }   +func (api *DebugAPI) ChainConfig() *params.ChainConfig { + return api.b.ChainConfig() +} + // NetAPI offers network related RPC methods type NetAPI struct { net *p2p.Server @@ -1824,3 +2058,8 @@ return fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, cap) } return nil } + +// CheckTxFee exports a helper function used to check whether the fee is reasonable +func CheckTxFee(gasPrice *big.Int, gas uint64, cap float64) error { + return checkTxFee(gasPrice, gas, cap) +}
diff --git go-ethereum/rpc/errors.go op-geth/rpc/errors.go index 438aff218c2e306d322160d8be8dcac16dd0dfa2..67c523d11a36294e4448988dc4c906f38541ec04 100644 --- go-ethereum/rpc/errors.go +++ op-geth/rpc/errors.go @@ -73,6 +73,16 @@ errMsgResponseTooLarge = "response too large" errMsgBatchTooLarge = "batch too large" )   +var ErrNoHistoricalFallback = NoHistoricalFallbackError{} + +type NoHistoricalFallbackError struct{} + +func (e NoHistoricalFallbackError) ErrorCode() int { return -32801 } + +func (e NoHistoricalFallbackError) Error() string { + return "no historical RPC is available for this historical (pre-bedrock) execution request" +} + type methodNotFoundError struct{ method string }   func (e *methodNotFoundError) ErrorCode() int { return -32601 }

Forward pre-bedrock tracing calls to legacy node.

diff --git go-ethereum/eth/tracers/api.go op-geth/eth/tracers/api.go index 22163030de0b2d29bb159d83db0c48d289a8cb3b..1581c9c388b91434118cae8dc80a4b98fc7f35f2 100644 --- go-ethereum/eth/tracers/api.go +++ op-geth/eth/tracers/api.go @@ -69,8 +69,6 @@ // trace states exceed this limit. maximumPendingTraceStates = 128 )   -var errTxNotFound = errors.New("transaction not found") - // StateReleaseFunc is used to deallocate resources held by constructing a // historical state for tracing purposes. type StateReleaseFunc func() @@ -89,6 +87,7 @@ Engine() consensus.Engine ChainDb() ethdb.Database StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, StateReleaseFunc, error) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*types.Transaction, vm.BlockContext, *state.StateDB, StateReleaseFunc, error) + HistoricalRPCService() *rpc.Client }   // API is the collection of tracing APIs exposed over the private debugging endpoint. @@ -210,6 +209,7 @@ // TraceChain returns the structured logs created during the execution of EVM // between two blocks (excluding start) and returns them as a JSON object. func (api *API) TraceChain(ctx context.Context, start, end rpc.BlockNumber, config *TraceConfig) (*rpc.Subscription, error) { // Fetch the block interval that we want to trace + // TODO: Need to implement a fallback for this from, err := api.blockByNumber(ctx, start) if err != nil { return nil, err @@ -268,7 +268,7 @@ // Fetch and execute the block trace taskCh for task := range taskCh { var ( signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number(), task.block.Time()) - blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil) + blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) ) // Trace all the transactions contained within for i, tx := range task.block.Transactions() { @@ -379,7 +379,7 @@ break } // Insert block's parent beacon block root in the state // as per EIP-4788. - context := core.NewEVMBlockContext(next.Header(), api.chainContext(ctx), nil) + context := core.NewEVMBlockContext(next.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) evm := vm.NewEVM(context, statedb, api.backend.ChainConfig(), vm.Config{}) if beaconRoot := next.BeaconRoot(); beaconRoot != nil { core.ProcessBeaconBlockRoot(*beaconRoot, evm) @@ -447,6 +447,20 @@ block, err := api.blockByNumber(ctx, number) if err != nil { return nil, err } + + if api.backend.ChainConfig().IsOptimismPreBedrock(block.Number()) { + if api.backend.HistoricalRPCService() != nil { + var histResult []*txTraceResult + err = api.backend.HistoricalRPCService().CallContext(ctx, &histResult, "debug_traceBlockByNumber", number, config) + if err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) + } + return histResult, nil + } else { + return nil, rpc.ErrNoHistoricalFallback + } + } + return api.traceBlock(ctx, block, config) }   @@ -457,6 +471,20 @@ block, err := api.blockByHash(ctx, hash) if err != nil { return nil, err } + + if api.backend.ChainConfig().IsOptimismPreBedrock(block.Number()) { + if api.backend.HistoricalRPCService() != nil { + var histResult []*txTraceResult + err = api.backend.HistoricalRPCService().CallContext(ctx, &histResult, "debug_traceBlockByHash", hash, config) + if err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) + } + return histResult, nil + } else { + return nil, rpc.ErrNoHistoricalFallback + } + } + return api.traceBlock(ctx, block, config) }   @@ -506,6 +534,7 @@ // IntermediateRoots executes a block (bad- or canon- or side-), and returns a list // of intermediate roots: the stateroot after each transaction. func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config *TraceConfig) ([]common.Hash, error) { block, _ := api.blockByHash(ctx, hash) + // TODO: Cannot get intermediate roots for pre-bedrock block without daisy chain if block == nil { // Check in the bad blocks block = rawdb.ReadBadBlock(api.backend.ChainDb(), hash) @@ -533,7 +562,7 @@ var ( roots []common.Hash signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) chainConfig = api.backend.ChainConfig() - vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, chainConfig, statedb) deleteEmptyObjects = chainConfig.IsEIP158(block.Number()) ) evm := vm.NewEVM(vmctx, statedb, chainConfig, vm.Config{}) @@ -599,7 +628,7 @@ return nil, err } defer release()   - blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) evm := vm.NewEVM(blockCtx, statedb, api.backend.ChainConfig(), vm.Config{}) if beaconRoot := block.BeaconRoot(); beaconRoot != nil { core.ProcessBeaconBlockRoot(*beaconRoot, evm) @@ -675,7 +704,7 @@ // Reconstruct the block context for each transaction // as the GetHash function of BlockContext is not safe for // concurrent use. // See: https://github.com/ethereum/go-ethereum/issues/29114 - blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) res, err := api.traceTx(ctx, txs[task.index], msg, txctx, blockCtx, task.statedb, config) if err != nil { results[task.index] = &txTraceResult{TxHash: txs[task.index].Hash(), Error: err.Error()} @@ -688,7 +717,7 @@ }   // Feed the transactions into the tracers and return var failed error - blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) evm := vm.NewEVM(blockCtx, statedb, api.backend.ChainConfig(), vm.Config{})   txloop: @@ -765,7 +794,7 @@ var ( dumps []string signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) chainConfig = api.backend.ChainConfig() - vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, chainConfig, statedb) canon = true ) // Check if there are any overrides: the caller may wish to enable a future @@ -858,13 +887,22 @@ // TraceTransaction returns the structured logs created during the execution of EVM // and returns them as a JSON object. func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) { - found, _, blockHash, blockNumber, index, err := api.backend.GetTransaction(ctx, hash) + _, _, blockHash, blockNumber, index, err := api.backend.GetTransaction(ctx, hash) if err != nil { return nil, ethapi.NewTxIndexingError() } - // Only mined txes are supported - if !found { - return nil, errTxNotFound + + if api.backend.ChainConfig().IsOptimismPreBedrock(new(big.Int).SetUint64(blockNumber)) { + if api.backend.HistoricalRPCService() != nil { + var histResult json.RawMessage + err := api.backend.HistoricalRPCService().CallContext(ctx, &histResult, "debug_traceTransaction", hash, config) + if err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) + } + return histResult, nil + } else { + return nil, rpc.ErrNoHistoricalFallback + } } // It shouldn't happen in practice. if blockNumber == 0 { @@ -930,6 +968,11 @@ } if err != nil { return nil, err } + + if api.backend.ChainConfig().IsOptimismPreBedrock(block.Number()) { + return nil, errors.New("l2geth does not have a debug_traceCall method") + } + // try to recompute the state reexec := defaultTraceReexec if config != nil && config.Reexec != nil { @@ -946,7 +989,7 @@ return nil, err } defer release()   - vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) // Apply the customization rules if required. if config != nil { config.BlockOverrides.Apply(&vmctx)
diff --git go-ethereum/eth/tracers/api_test.go op-geth/eth/tracers/api_test.go index 13a7b0aaaed37c4d5addb71552e6bedeee4b8733..8587f2e21fda7b0a4f92bffb8b76185b8acf7f16 100644 --- go-ethereum/eth/tracers/api_test.go +++ op-geth/eth/tracers/api_test.go @@ -23,12 +23,15 @@ "encoding/json" "errors" "fmt" "math/big" + "net" + "net/http" "reflect" "slices" "sync/atomic" "testing" "time"   + "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" @@ -45,8 +48,10 @@ "github.com/ethereum/go-ethereum/eth/tracers/logger" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/ethapi/override" + "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/mock" )   var ( @@ -54,6 +59,66 @@ errStateNotFound = errors.New("state not found") errBlockNotFound = errors.New("block not found") )   +type mockHistoricalBackend struct { + mock.Mock +} + +// mockHistoricalBackend does not have a TraceCall, because pre-bedrock there is no debug_traceCall available + +func (m *mockHistoricalBackend) TraceBlockByNumber(ctx context.Context, number rpc.BlockNumber, config *TraceConfig) ([]*txTraceResult, error) { + ret := m.Mock.MethodCalled("TraceBlockByNumber", number, config) + return ret[0].([]*txTraceResult), *ret[1].(*error) +} + +func (m *mockHistoricalBackend) ExpectTraceBlockByNumber(number rpc.BlockNumber, config *TraceConfig, out []*txTraceResult, err error) { + m.Mock.On("TraceBlockByNumber", number, config).Once().Return(out, &err) +} + +func (m *mockHistoricalBackend) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) { + ret := m.Mock.MethodCalled("TraceTransaction", hash, config) + return ret[0], *ret[1].(*error) +} + +func (m *mockHistoricalBackend) ExpectTraceTransaction(hash common.Hash, config *TraceConfig, out interface{}, err error) { + jsonOut, _ := json.Marshal(out) + m.Mock.On("TraceTransaction", hash, config).Once().Return(json.RawMessage(jsonOut), &err) +} + +func newMockHistoricalBackend(t *testing.T, backend *mockHistoricalBackend) string { + s := rpc.NewServer() + err := node.RegisterApis([]rpc.API{ + { + Namespace: "debug", + Service: backend, + Public: true, + Authenticated: false, + }, + }, nil, s) + if err != nil { + t.Fatalf("error creating mock historical backend: %v", err) + } + + hdlr := node.NewHTTPHandlerStack(s, []string{"*"}, []string{"*"}, nil) + mux := http.NewServeMux() + mux.Handle("/", hdlr) + + listener, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("error creating mock historical backend listener: %v", err) + } + + go func() { + httpS := &http.Server{Handler: mux} + httpS.Serve(listener) + + t.Cleanup(func() { + httpS.Shutdown(context.Background()) + }) + }() + + return fmt.Sprintf("http://%s", listener.Addr().String()) +} + type testBackend struct { chainConfig *params.ChainConfig engine consensus.Engine @@ -62,15 +127,28 @@ chain *core.BlockChain   refHook func() // Hook is invoked when the requested state is referenced relHook func() // Hook is invoked when the requested state is released + + historical *rpc.Client + mockHistorical *mockHistoricalBackend }   // newTestBackend creates a new test backend. OBS: After test is done, teardown must be // invoked in order to release associated resources. func newTestBackend(t *testing.T, n int, gspec *core.Genesis, generator func(i int, b *core.BlockGen)) *testBackend { + mock := new(mockHistoricalBackend) + historicalAddr := newMockHistoricalBackend(t, mock) + + historicalClient, err := rpc.Dial(historicalAddr) + if err != nil { + t.Fatalf("error making historical client: %v", err) + } + backend := &testBackend{ - chainConfig: gspec.Config, - engine: ethash.NewFaker(), - chaindb: rawdb.NewMemoryDatabase(), + chainConfig: gspec.Config, + engine: ethash.NewFaker(), + chaindb: rawdb.NewMemoryDatabase(), + historical: historicalClient, + mockHistorical: mock, } // Generate blocks for testing _, blocks, _ := core.GenerateChainWithGenesis(gspec, backend.engine, n, generator) @@ -172,7 +250,7 @@ return nil, vm.BlockContext{}, statedb, release, nil } // Recompute transactions up to the target index. signer := types.MakeSigner(b.chainConfig, block.Number(), block.Time()) - context := core.NewEVMBlockContext(block.Header(), b.chain, nil) + context := core.NewEVMBlockContext(block.Header(), b.chain, nil, b.chainConfig, statedb) evm := vm.NewEVM(context, statedb, b.chainConfig, vm.Config{}) for idx, tx := range block.Transactions() { if idx == txIndex { @@ -185,6 +263,10 @@ } statedb.Finalise(evm.ChainConfig().IsEIP158(block.Number())) } return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash()) +} + +func (b *testBackend) HistoricalRPCService() *rpc.Client { + return b.historical }   type stateTracer struct { @@ -255,7 +337,8 @@ To: &to, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), - Data: nil}), + Data: nil, + }), signer, key) b.AddTx(tx) nonce++ @@ -301,7 +384,8 @@ To: &accounts[1].addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), - Data: nil}), + Data: nil, + }), signer, accounts[0].key) b.AddTx(tx) nonce++ @@ -314,7 +398,8 @@ To: &accounts[2].addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), - Data: nil}), + Data: nil, + }), signer, accounts[0].key) b.AddTx(tx) nonce++ @@ -326,7 +411,8 @@ To: &accounts[1].addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), - Data: nil}), + Data: nil, + }), signer, accounts[0].key) b.AddTx(tx) nonce++ @@ -337,7 +423,7 @@ uintPtr := func(i int) *hexutil.Uint { x := hexutil.Uint(i); return &x }   defer backend.teardown() api := NewAPI(backend) - var testSuite = []struct { + testSuite := []struct { blockNumber rpc.BlockNumber call ethapi.TransactionArgs config *TraceCallConfig @@ -423,7 +509,7 @@ Value: (*hexutil.Big)(big.NewInt(1000)), }, config: nil, expectErr: fmt.Errorf("block #%d not found", genBlocks+1), - //expect: nil, + // expect: nil, }, // Standard JSON trace upon the latest block { @@ -517,7 +603,8 @@ To: &accounts[1].addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), - Data: nil}), + Data: nil, + }), signer, accounts[0].key) b.AddTx(tx) target = tx.Hash() @@ -540,11 +627,59 @@ StructLogs: []json.RawMessage{}, }) { t.Error("Transaction tracing result is different") } +}   - // Test non-existent transaction - _, err = api.TraceTransaction(context.Background(), common.Hash{42}, nil) - if !errors.Is(err, errTxNotFound) { - t.Fatalf("want %v, have %v", errTxNotFound, err) +func TestTraceTransactionHistorical(t *testing.T) { + t.Parallel() + + // Initialize test accounts + accounts := newAccounts(2) + genesis := &core.Genesis{ + Config: params.OptimismTestConfig, + Alloc: types.GenesisAlloc{ + accounts[0].addr: {Balance: big.NewInt(params.Ether)}, + accounts[1].addr: {Balance: big.NewInt(params.Ether)}, + }, + } + target := common.Hash{} + signer := types.HomesteadSigner{} + backend := newTestBackend(t, 1, genesis, func(i int, b *core.BlockGen) { + // Transfer from account[0] to account[1] + // value: 1000 wei + // fee: 0 wei + tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, b.BaseFee(), nil), signer, accounts[0].key) + b.AddTx(tx) + target = tx.Hash() + }) + defer backend.mockHistorical.AssertExpectations(t) + defer backend.chain.Stop() + backend.mockHistorical.ExpectTraceTransaction( + target, + nil, + logger.ExecutionResult{ + Gas: params.TxGas, + Failed: false, + ReturnValue: "", + StructLogs: []json.RawMessage{}, + }, + nil) + api := NewAPI(backend) + result, err := api.TraceTransaction(context.Background(), target, nil) + if err != nil { + t.Errorf("Failed to trace transaction %v", err) + } + var have *logger.ExecutionResult + spew.Dump(result) + if err := json.Unmarshal(result.(json.RawMessage), &have); err != nil { + t.Errorf("failed to unmarshal result %v", err) + } + if !reflect.DeepEqual(have, &logger.ExecutionResult{ + Gas: params.TxGas, + Failed: false, + ReturnValue: "", + StructLogs: []json.RawMessage{}, + }) { + t.Error("Transaction tracing result is different") } }   @@ -574,7 +709,8 @@ To: &accounts[1].addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), - Data: nil}), + Data: nil, + }), signer, accounts[0].key) b.AddTx(tx) txHash = tx.Hash() @@ -582,7 +718,7 @@ }) defer backend.chain.Stop() api := NewAPI(backend)   - var testSuite = []struct { + testSuite := []struct { blockNumber rpc.BlockNumber config *TraceConfig want string @@ -638,6 +774,59 @@ } } }   +func TestTraceBlockHistorical(t *testing.T) { + t.Parallel() + + // Initialize test accounts + accounts := newAccounts(3) + genesis := &core.Genesis{ + Config: params.OptimismTestConfig, + Alloc: types.GenesisAlloc{ + accounts[0].addr: {Balance: big.NewInt(params.Ether)}, + accounts[1].addr: {Balance: big.NewInt(params.Ether)}, + accounts[2].addr: {Balance: big.NewInt(params.Ether)}, + }, + } + genBlocks := 10 + signer := types.HomesteadSigner{} + backend := newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) { + // Transfer from account[0] to account[1] + // value: 1000 wei + // fee: 0 wei + tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, b.BaseFee(), nil), signer, accounts[0].key) + b.AddTx(tx) + }) + defer backend.mockHistorical.AssertExpectations(t) + defer backend.chain.Stop() + api := NewAPI(backend) + + var expectErr error + var config *TraceConfig + blockNumber := rpc.BlockNumber(3) + want := `[{"txHash":"0x0000000000000000000000000000000000000000000000000000000000000000","result":{"failed":false,"gas":21000,"returnValue":"","structLogs":[]}}]` + var ret []*txTraceResult + _ = json.Unmarshal([]byte(want), &ret) + + backend.mockHistorical.ExpectTraceBlockByNumber(blockNumber, config, ret, nil) + + result, err := api.TraceBlockByNumber(context.Background(), blockNumber, config) + if expectErr != nil { + if err == nil { + t.Errorf("want error %v", expectErr) + } + if !reflect.DeepEqual(err, expectErr) { + t.Errorf("error mismatch, want %v, get %v", expectErr, err) + } + } + if err != nil { + t.Errorf("want no error, have %v", err) + } + have, _ := json.Marshal(result) + if string(have) != want { + t.Errorf("result mismatch, have\n%v\n, want\n%v\n", string(have), want) + } +} + func TestTracingWithOverrides(t *testing.T) { t.Parallel() // Initialize test accounts @@ -671,7 +860,8 @@ To: &accounts[1].addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), - Data: nil}), + Data: nil, + }), signer, accounts[0].key) b.AddTx(tx) }) @@ -683,7 +873,7 @@ Gas int Failed bool ReturnValue string } - var testSuite = []struct { + testSuite := []struct { blockNumber rpc.BlockNumber call ethapi.TransactionArgs config *TraceCallConfig @@ -740,7 +930,7 @@ To: &randomAccounts[2].addr, Data: newRPCBytes(common.Hex2Bytes("8381f58a")), // call number() }, config: &TraceCallConfig{ - //Tracer: &tracer, + // Tracer: &tracer, StateOverrides: &override.StateOverride{ randomAccounts[2].addr: override.OverrideAccount{ Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033")), @@ -831,7 +1021,7 @@ State: newStates([]common.Hash{{}}, []common.Hash{{}}), }, }, }, - //want: `{"gas":46900,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000539"}`, + // want: `{"gas":46900,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000539"}`, want: `{"gas":44100,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000001"}`, }, { // No state override @@ -856,7 +1046,7 @@ byte(vm.PUSH1), 0x00, byte(vm.MSTORE), // RETURN (0, 32) byte(vm.PUSH1), 32, - byte(vm.PUSH1), 00, + byte(vm.PUSH1), 0o0, byte(vm.RETURN), }), }, @@ -891,7 +1081,7 @@ byte(vm.PUSH1), 0x00, byte(vm.MSTORE), // RETURN (0, 32) byte(vm.PUSH1), 32, - byte(vm.PUSH1), 00, + byte(vm.PUSH1), 0o0, byte(vm.RETURN), }), State: newStates( @@ -929,7 +1119,7 @@ byte(vm.PUSH1), 0x00, byte(vm.MSTORE), // RETURN (0, 32) byte(vm.PUSH1), 32, - byte(vm.PUSH1), 00, + byte(vm.PUSH1), 0o0, byte(vm.RETURN), }), StateDiff: map[common.Hash]common.Hash{ @@ -1042,7 +1232,7 @@ backend.relHook = func() { rel.Add(1) } api := NewAPI(backend)   single := `{"txHash":"0x0000000000000000000000000000000000000000000000000000000000000000","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}` - var cases = []struct { + cases := []struct { start uint64 end uint64 config *TraceConfig @@ -1130,7 +1320,7 @@ } genBlocks := 1 signer := types.HomesteadSigner{} var txHash common.Hash - var baseFee = new(big.Int) + baseFee := new(big.Int) backend := newTestMergedBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) { tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{ Nonce: uint64(i), @@ -1138,7 +1328,8 @@ To: &target, Value: big.NewInt(0), Gas: 5 * params.TxGas, GasPrice: b.BaseFee(), - Data: nil}), + Data: nil, + }), signer, accounts[0].key) b.AddTx(tx) txHash = tx.Hash() @@ -1147,7 +1338,7 @@ }) defer backend.chain.Stop() api := NewAPI(backend)   - var testSuite = []struct { + testSuite := []struct { blockNumber rpc.BlockNumber config *TraceConfig want string
diff --git go-ethereum/ethclient/ethclient_test.go op-geth/ethclient/ethclient_test.go index 4ad8a552d2688b311d96456c11a26b0a46aa1b77..12983014b5da8172c1bf03ee03c7568664f87887 100644 --- go-ethereum/ethclient/ethclient_test.go +++ op-geth/ethclient/ethclient_test.go @@ -22,9 +22,17 @@ "context" "errors" "fmt" "math/big" + "net" + "net/http" "reflect" "testing" "time" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/beacon" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/internal/ethapi/override"   "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" @@ -75,6 +83,21 @@ Timestamp: 9000, BaseFee: big.NewInt(params.InitialBaseFee), }   +var genesisForHistorical = &core.Genesis{ + Config: params.OptimismTestConfig, + Alloc: types.GenesisAlloc{testAddr: {Balance: testBalance}}, + ExtraData: []byte("test genesis"), + Timestamp: 9000, + BaseFee: big.NewInt(params.InitialBaseFee), +} + +var depositTx = types.NewTx(&types.DepositTx{ + Value: big.NewInt(12), + Gas: params.TxGas + 2000, + To: &common.Address{2}, + Data: make([]byte, 500), +}) + var testTx1 = types.MustSignNewTx(testKey, types.LatestSigner(genesis.Config), &types.LegacyTx{ Nonce: 0, Value: big.NewInt(12), @@ -91,9 +114,75 @@ Gas: params.TxGas, To: &common.Address{2}, })   -func newTestBackend(config *node.Config) (*node.Node, []*types.Block, error) { +type mockHistoricalBackend struct{} + +func (m *mockHistoricalBackend) Call(ctx context.Context, args ethapi.TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *override.StateOverride) (hexutil.Bytes, error) { + num, ok := blockNrOrHash.Number() + if ok && num == 1 { + return hexutil.Bytes("test"), nil + } + return nil, ethereum.NotFound +} + +func (m *mockHistoricalBackend) EstimateGas(ctx context.Context, args ethapi.TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { + num, ok := blockNrOrHash.Number() + if ok && num == 1 { + return hexutil.Uint64(12345), nil + } + return 0, ethereum.NotFound +} + +func newMockHistoricalBackend(t *testing.T) string { + s := rpc.NewServer() + err := node.RegisterApis([]rpc.API{ + { + Namespace: "eth", + Service: new(mockHistoricalBackend), + Public: true, + Authenticated: false, + }, + }, nil, s) + if err != nil { + t.Fatalf("error creating mock historical backend: %v", err) + } + + hdlr := node.NewHTTPHandlerStack(s, []string{"*"}, []string{"*"}, nil) + mux := http.NewServeMux() + mux.Handle("/", hdlr) + + listener, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("error creating mock historical backend listener: %v", err) + } + + go func() { + httpS := &http.Server{Handler: mux} + httpS.Serve(listener) + + t.Cleanup(func() { + httpS.Shutdown(context.Background()) + }) + }() + + return fmt.Sprintf("http://%s", listener.Addr().String()) +} + +func newTestBackend(t *testing.T, config *node.Config, enableHistoricalState bool) (*node.Node, []*types.Block, error) { + var consensusEngine consensus.Engine + var actualGenesis *core.Genesis + var chainLength int + if enableHistoricalState { + actualGenesis = genesisForHistorical + consensusEngine = beacon.New(ethash.NewFaker()) + chainLength = 10 + } else { + actualGenesis = genesis + consensusEngine = ethash.NewFaker() + chainLength = 2 + } + // Generate test chain. - blocks := generateTestChain() + blocks := generateTestChain(consensusEngine, actualGenesis, chainLength)   // Create node if config == nil { @@ -104,11 +193,19 @@ if err != nil { return nil, nil, fmt.Errorf("can't create new node: %v", err) } // Create Ethereum Service - ecfg := &ethconfig.Config{Genesis: genesis, RPCGasCap: 1000000} + ecfg := &ethconfig.Config{Genesis: actualGenesis, RPCGasCap: 1000000} + if enableHistoricalState { + histAddr := newMockHistoricalBackend(t) + ecfg.RollupHistoricalRPC = histAddr + ecfg.RollupHistoricalRPCTimeout = time.Second * 5 + } ethservice, err := eth.New(n, ecfg) if err != nil { return nil, nil, fmt.Errorf("can't create new ethereum service: %v", err) } + if enableHistoricalState { // swap to the pre-bedrock consensus-engine that we used to generate the historical blocks + ethservice.BlockChain().Engine().(*beacon.Beacon).SwapInner(ethash.NewFaker()) + } // Import the test chain. if err := n.Start(); err != nil { return nil, nil, fmt.Errorf("can't start test node: %v", err) @@ -116,6 +213,7 @@ } if _, err := ethservice.BlockChain().InsertChain(blocks[1:]); err != nil { return nil, nil, fmt.Errorf("can't import test blocks: %v", err) } + // Ensure the tx indexing is fully generated for ; ; time.Sleep(time.Millisecond * 100) { progress, err := ethservice.BlockChain().TxIndexProgress() @@ -123,28 +221,48 @@ if err == nil && progress.Done() { break } } + + if enableHistoricalState { + // Now that we have a filled DB, swap the pre-Bedrock consensus to OpLegacy, + // which does not support re-processing of pre-bedrock data. + ethservice.Engine().(*beacon.Beacon).SwapInner(&beacon.OpLegacy{}) + } + return n, blocks, nil }   -func generateTestChain() []*types.Block { +func generateTestChain(consensusEngine consensus.Engine, genesis *core.Genesis, length int) []*types.Block { generate := func(i int, g *core.BlockGen) { g.OffsetTime(5) g.SetExtra([]byte("test")) if i == 1 { // Test transactions are included in block #2. + if genesis.Config.Optimism != nil && genesis.Config.IsBedrock(big.NewInt(1)) { + g.AddTx(depositTx) + } g.AddTx(testTx1) g.AddTx(testTx2) } } - _, blocks, _ := core.GenerateChainWithGenesis(genesis, ethash.NewFaker(), 2, generate) + _, blocks, _ := core.GenerateChainWithGenesis(genesis, consensusEngine, length, generate) return append([]*types.Block{genesis.ToBlock()}, blocks...) }   +func TestEthClientHistoricalBackend(t *testing.T) { + backend, _, _ := newTestBackend(t, nil, true) + client := backend.Attach() + defer backend.Close() + defer client.Close() + + testHistoricalRPC(t, client) +} + func TestEthClient(t *testing.T) { - backend, chain, err := newTestBackend(nil) + backend, chain, err := newTestBackend(t, nil, false) if err != nil { t.Fatal(err) } + client := backend.Attach() defer backend.Close() defer client.Close() @@ -181,6 +299,9 @@ func(t *testing.T) { testAtFunctions(t, client) }, }, "TransactionSender": { func(t *testing.T) { testTransactionSender(t, client) }, + }, + "EstimateGas": { + func(t *testing.T) { testEstimateGas(t, client) }, }, }   @@ -622,6 +743,60 @@ t.Fatal(err) } if sender2 != testAddr { t.Fatal("wrong sender:", sender2) + } +} + +func testEstimateGas(t *testing.T, client *rpc.Client) { + ec := ethclient.NewClient(client) + + // EstimateGas + msg := ethereum.CallMsg{ + From: testAddr, + To: &common.Address{}, + Gas: 21000, + Value: big.NewInt(1), + } + gas, err := ec.EstimateGas(context.Background(), msg) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if gas != 21000 { + t.Fatalf("unexpected gas price: %v", gas) + } +} + +func testHistoricalRPC(t *testing.T, client *rpc.Client) { + ec := ethclient.NewClient(client) + + // Estimate Gas RPC + msg := ethereum.CallMsg{ + From: testAddr, + To: &common.Address{}, + Gas: 21000, + Value: big.NewInt(1), + } + var res hexutil.Uint64 + callMsg := map[string]interface{}{ + "from": msg.From, + "to": msg.To, + "gas": hexutil.Uint64(msg.Gas), + "value": (*hexutil.Big)(msg.Value), + } + err := client.CallContext(context.Background(), &res, "eth_estimateGas", callMsg, rpc.BlockNumberOrHashWithNumber(1)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if res != 12345 { + t.Fatalf("invalid result: %d", res) + } + + // Call Contract RPC + histVal, err := ec.CallContract(context.Background(), msg, big.NewInt(1)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(histVal) != "test" { + t.Fatalf("expected %s to equal test", string(histVal)) } }
diff --git go-ethereum/internal/ethapi/transaction_args_test.go op-geth/internal/ethapi/transaction_args_test.go index 7172fc883ff983548c2b32ca5bf5e71a5636b416..71c01b02e76153e9d42828268dbfd3401ebb9e97 100644 --- go-ethereum/internal/ethapi/transaction_args_test.go +++ op-geth/internal/ethapi/transaction_args_test.go @@ -401,4 +401,6 @@ func (b *backendMock) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { return nil }   -func (b *backendMock) Engine() consensus.Engine { return nil } +func (b *backendMock) Engine() consensus.Engine { return nil } +func (b *backendMock) HistoricalRPCService() *rpc.Client { return nil } +func (b *backendMock) Genesis() *types.Block { return nil }

Fix Debug API block marshaling to include deposits

diff --git go-ethereum/eth/api_debug.go op-geth/eth/api_debug.go index d5e4dda1401c9ae49a754077f837d0ebed760310..203764a00eb35145fa1577f7afdc2cfbf25a8818 100644 --- go-ethereum/eth/api_debug.go +++ op-geth/eth/api_debug.go @@ -24,8 +24,10 @@ "time"   "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/stateless" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/internal/ethapi" @@ -119,7 +121,10 @@ blockRlp = err.Error() // Hacky, but hey, it works } else { blockRlp = fmt.Sprintf("%#x", rlpBytes) } - blockJSON = ethapi.RPCMarshalBlock(block, true, true, api.eth.APIBackend.ChainConfig()) + var err error + if blockJSON, err = ethapi.RPCMarshalBlock(ctx, block, true, true, api.eth.APIBackend.ChainConfig(), api.eth.APIBackend); err != nil { + blockJSON = map[string]interface{}{"error": err.Error()} + } results = append(results, &BadBlockArgs{ Hash: block.Hash(), RLP: blockRlp, @@ -443,3 +448,46 @@ return "", errors.New("trie flush interval is undefined for path-based scheme") } return api.eth.blockchain.GetTrieFlushInterval().String(), nil } + +func (api *DebugAPI) ExecutionWitness(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*stateless.ExecutionWitness, error) { + block, err := api.eth.APIBackend.BlockByNumberOrHash(ctx, blockNrOrHash) + if err != nil { + return nil, fmt.Errorf("failed to retrieve block: %w", err) + } + if block == nil { + return nil, fmt.Errorf("block not found: %s", blockNrOrHash.String()) + } + + witness, err := generateWitness(api.eth.blockchain, block) + return witness.ToExecutionWitness(), err +} + +func generateWitness(blockchain *core.BlockChain, block *types.Block) (*stateless.Witness, error) { + witness, err := stateless.NewWitness(block.Header(), blockchain) + if err != nil { + return nil, fmt.Errorf("failed to create witness: %w", err) + } + + parentHeader := witness.Headers[0] + statedb, err := blockchain.StateAt(parentHeader.Root) + if err != nil { + return nil, fmt.Errorf("failed to retrieve parent state: %w", err) + } + + statedb.StartPrefetcher("debug_execution_witness", witness) + defer statedb.StopPrefetcher() + + res, err := blockchain.Processor().Process(block, statedb, *blockchain.GetVMConfig()) + if err != nil { + return nil, fmt.Errorf("failed to process block %d: %w", block.Number(), err) + } + + // OP-Stack warning: below has the side-effect of including the withdrawals storage-root + // into the execution witness through the storage lookup by ValidateState, triggering the pre-fetcher. + // The Process function only runs through Finalize steps, not through FinalizeAndAssemble, missing merkleization. + if err := blockchain.Validator().ValidateState(block, statedb, res, false); err != nil { + return nil, fmt.Errorf("failed to validate block %d: %w", block.Number(), err) + } + + return witness, nil +}

gasprice suggestion adjustments to accommodate faster L2 blocks and lower fees.

diff --git go-ethereum/eth/gasprice/gasprice.go op-geth/eth/gasprice/gasprice.go index 4fd3df742853c2ccb1faba5973dc2e11a879db1a..58a59cbdb930c96585807a39f0eca88ca2f04082 100644 --- go-ethereum/eth/gasprice/gasprice.go +++ op-geth/eth/gasprice/gasprice.go @@ -38,6 +38,8 @@ var ( DefaultMaxPrice = big.NewInt(500 * params.GWei) DefaultIgnorePrice = big.NewInt(2 * params.Wei) + + DefaultMinSuggestedPriorityFee = big.NewInt(1e6 * params.Wei) // 0.001 gwei, for Optimism fee suggestion )   type Config struct { @@ -47,6 +49,8 @@ MaxHeaderHistory uint64 MaxBlockHistory uint64 MaxPrice *big.Int `toml:",omitempty"` IgnorePrice *big.Int `toml:",omitempty"` + + MinSuggestedPriorityFee *big.Int `toml:",omitempty"` // for Optimism fee suggestion }   // OracleBackend includes all necessary background APIs for oracle. @@ -74,6 +78,8 @@ checkBlocks, percentile int maxHeaderHistory, maxBlockHistory uint64   historyCache *lru.Cache[cacheKey, processedFees] + + minSuggestedPriorityFee *big.Int // for Optimism fee suggestion }   // NewOracle returns a new gasprice oracle which can recommend suitable @@ -138,7 +144,7 @@ } }() }   - return &Oracle{ + r := &Oracle{ backend: backend, lastPrice: startPrice, maxPrice: maxPrice, @@ -149,6 +155,17 @@ maxHeaderHistory: maxHeaderHistory, maxBlockHistory: maxBlockHistory, historyCache: cache, } + + if backend.ChainConfig().IsOptimism() { + r.minSuggestedPriorityFee = params.MinSuggestedPriorityFee + if r.minSuggestedPriorityFee == nil || r.minSuggestedPriorityFee.Int64() <= 0 { + r.minSuggestedPriorityFee = DefaultMinSuggestedPriorityFee + log.Warn("Sanitizing invalid optimism gasprice oracle min priority fee suggestion", + "provided", params.MinSuggestedPriorityFee, + "updated", r.minSuggestedPriorityFee) + } + } + return r }   // SuggestTipCap returns a tip cap so that newly created transaction can have a @@ -178,6 +195,11 @@ oracle.cacheLock.RUnlock() if headHash == lastHead { return new(big.Int).Set(lastPrice), nil } + + if oracle.backend.ChainConfig().IsOptimism() { + return oracle.SuggestOptimismPriorityFee(ctx, head, headHash), nil + } + var ( sent, exp int number = head.Number.Uint64() @@ -284,3 +306,9 @@ case result <- results{prices, nil}: case <-quit: } } + +type bigIntArray []*big.Int + +func (s bigIntArray) Len() int { return len(s) } +func (s bigIntArray) Less(i, j int) bool { return s[i].Cmp(s[j]) < 0 } +func (s bigIntArray) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
diff --git go-ethereum/eth/gasprice/optimism-gasprice.go op-geth/eth/gasprice/optimism-gasprice.go new file mode 100644 index 0000000000000000000000000000000000000000..71cd021f637f92e4b6d99ec5fc337d27edf547e5 --- /dev/null +++ op-geth/eth/gasprice/optimism-gasprice.go @@ -0,0 +1,110 @@ +package gasprice + +import ( + "context" + "math/big" + "sort" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" +) + +// SuggestOptimismPriorityFee returns a max priority fee value that can be used such that newly +// created transactions have a very high chance to be included in the following blocks, using a +// simplified and more predictable algorithm appropriate for chains like Optimism with a single +// known block builder. +// +// In the typical case, which results whenever the last block had room for more transactions, this +// function returns a minimum suggested priority fee value. Otherwise it returns the higher of this +// minimum suggestion or 10% over the median effective priority fee from the last block. +// +// Rationale: For a chain such as Optimism where there is a single block builder whose behavior is +// known, we know priority fee (as long as it is non-zero) has no impact on the probability for tx +// inclusion as long as there is capacity for it in the block. In this case then, there's no reason +// to return any value higher than some fixed minimum. Blocks typically reach capacity only under +// extreme events such as airdrops, meaning predicting whether the next block is going to be at +// capacity is difficult *except* in the case where we're already experiencing the increased demand +// from such an event. We therefore expect whether the last known block is at capacity to be one of +// the best predictors of whether the next block is likely to be at capacity. (An even better +// predictor is to look at the state of the transaction pool, but we want an algorithm that works +// even if the txpool is private or unavailable.) +// +// In the event the next block may be at capacity, the algorithm should allow for average fees to +// rise in order to reach a market price that appropriately reflects demand. We accomplish this by +// returning a suggestion that is a significant amount (10%) higher than the median effective +// priority fee from the previous block. +func (oracle *Oracle) SuggestOptimismPriorityFee(ctx context.Context, h *types.Header, headHash common.Hash) *big.Int { + suggestion := new(big.Int).Set(oracle.minSuggestedPriorityFee) + + // find the maximum gas used by any of the transactions in the block to use as the capacity + // margin + receipts, err := oracle.backend.GetReceipts(ctx, headHash) + if receipts == nil || err != nil { + log.Error("failed to get block receipts", "err", err) + return suggestion + } + var maxTxGasUsed uint64 + for i := range receipts { + gu := receipts[i].GasUsed + if gu > maxTxGasUsed { + maxTxGasUsed = gu + } + } + + // sanity check the max gas used value + if maxTxGasUsed > h.GasLimit { + log.Error("found tx consuming more gas than the block limit", "gas", maxTxGasUsed) + return suggestion + } + + if h.GasUsed+maxTxGasUsed > h.GasLimit { + // A block is "at capacity" if, when it is built, there is a pending tx in the txpool that + // could not be included because the block's gas limit would be exceeded. Since we don't + // have access to the txpool, we instead adopt the following heuristic: consider a block as + // at capacity if the total gas consumed by its transactions is within max-tx-gas-used of + // the block limit, where max-tx-gas-used is the most gas used by any one transaction + // within the block. This heuristic is almost perfectly accurate when transactions always + // consume the same amount of gas, but becomes less accurate as tx gas consumption begins + // to vary. The typical error is we assume a block is at capacity when it was not because + // max-tx-gas-used will in most cases over-estimate the "capacity margin". But it's better + // to err on the side of returning a higher-than-needed suggestion than a lower-than-needed + // one in order to satisfy our desire for high chance of inclusion and rising fees under + // high demand. + block, err := oracle.backend.BlockByNumber(ctx, rpc.BlockNumber(h.Number.Int64())) + if block == nil || err != nil { + log.Error("failed to get last block", "err", err) + return suggestion + } + baseFee := block.BaseFee() + txs := block.Transactions() + if len(txs) == 0 { + log.Error("block was at capacity but doesn't have transactions") + return suggestion + } + tips := bigIntArray(make([]*big.Int, len(txs))) + for i := range txs { + tips[i] = txs[i].EffectiveGasTipValue(baseFee) + } + sort.Sort(tips) + median := tips[len(tips)/2] + newSuggestion := new(big.Int).Add(median, new(big.Int).Div(median, big.NewInt(10))) + // use the new suggestion only if it's bigger than the minimum + if newSuggestion.Cmp(suggestion) > 0 { + suggestion = newSuggestion + } + } + + // the suggestion should be capped by oracle.maxPrice + if suggestion.Cmp(oracle.maxPrice) > 0 { + suggestion.Set(oracle.maxPrice) + } + + oracle.cacheLock.Lock() + oracle.lastHead = headHash + oracle.lastPrice = suggestion + oracle.cacheLock.Unlock() + + return new(big.Int).Set(suggestion) +}

Upstream test of broken behavior; in Optimism, a zero signature is valid (pre-bedrock for deposit-txs), and the chain ID formula on signature data must not be used, or an underflow happens.

diff --git go-ethereum/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json op-geth/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json index 60f18bc1144e31ed88550eab56e9656f04e2c54f..56de19c2971d02547f218bed9b6057422358b790 100644 --- go-ethereum/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json +++ op-geth/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json @@ -29,7 +29,7 @@ "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", "transactionIndex": "0x0", "value": "0x6f", "type": "0x0", - "chainId": "0x7fffffffffffffee", + "chainId": "0x1", "v": "0x0", "r": "0x0", "s": "0x0"

sequencer api for conditional transaction inclusion enforced out of protocol

diff --git go-ethereum/core/state/statedb.go op-geth/core/state/statedb.go index 0310ee6973ca118411e5ed4dae642fae06a4268f..fd368c6be672046612a15c757f2a9fc1b049c5e2 100644 --- go-ethereum/core/state/statedb.go +++ op-geth/core/state/statedb.go @@ -39,7 +39,6 @@ "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/utils" "github.com/holiman/uint256" - "golang.org/x/sync/errgroup" )   // TriesInMemory represents the number of layers that are kept in RAM. @@ -155,6 +154,9 @@ AccountDeleted int // Number of accounts deleted during the state transition StorageLoaded int // Number of storage slots retrieved from the database during the state transition StorageUpdated atomic.Int64 // Number of storage slots updated during the state transition StorageDeleted atomic.Int64 // Number of storage slots deleted during the state transition + + // singlethreaded avoids creation of additional threads when set to true for compatibility with cannon. + singlethreaded bool }   // New creates a new state from a given trie. @@ -185,6 +187,10 @@ if db.TrieDB().IsVerkle() { sdb.accessEvents = NewAccessEvents(db.PointCache()) } return sdb, nil +} + +func (s *StateDB) MakeSinglethreaded() { + s.singlethreaded = true }   // StartPrefetcher initializes a new trie prefetcher to pull in nodes from the @@ -400,6 +406,40 @@ } return false }   +// CheckTransactionConditional validates the account preconditions against the statedb. +// +// NOTE: A lock is not held on the db while the conditional is checked. The caller must +// ensure no state changes occur while this check is executed. +func (s *StateDB) CheckTransactionConditional(cond *types.TransactionConditional) error { + cost := cond.Cost() + + // The max cost is an inclusive limit. + if cost > params.TransactionConditionalMaxCost { + return fmt.Errorf("conditional cost, %d, exceeded max: %d", cost, params.TransactionConditionalMaxCost) + } + + for addr, acct := range cond.KnownAccounts { + if root, isRoot := acct.Root(); isRoot { + storageRoot := s.GetStorageRoot(addr) + if storageRoot == (common.Hash{}) { // if the root is not found, replace with the empty root hash + storageRoot = types.EmptyRootHash + } + if root != storageRoot { + return fmt.Errorf("failed account storage root constraint. Got %s, Expected %s", storageRoot, root) + } + } + if slots, isSlots := acct.Slots(); isSlots { + for key, state := range slots { + accState := s.GetState(addr, key) + if state != accState { + return fmt.Errorf("failed account storage slot key %s constraint. Got %s, Expected %s", key, accState, state) + } + } + } + } + return nil +} + /* * SETTERS */ @@ -786,9 +826,9 @@ // Process all storage updates concurrently. The state object update root // method will internally call a blocking trie fetch from the prefetcher, // so there's no need to explicitly wait for the prefetchers to finish. var ( - start = time.Now() - workers errgroup.Group + start = time.Now() ) + workers := newWorkerGroup(s.singlethreaded) if s.db.TrieDB().IsVerkle() { // Whilst MPT storage tries are independent, Verkle has one single trie // for all the accounts and all the storage slots merged together. The @@ -1171,10 +1211,10 @@ // Handle all state updates afterwards, concurrently to one another to shave // off some milliseconds from the commit operation. Also accumulate the code // writes to run in parallel with the computations. var ( - start = time.Now() - root common.Hash - workers errgroup.Group + start = time.Now() + root common.Hash ) + workers := newWorkerGroup(s.singlethreaded) // Schedule the account trie first since that will be the biggest, so give // it the most time to crunch. // @@ -1401,6 +1441,12 @@ // SlotInAccessList returns true if the given (address, slot)-tuple is in the access list. func (s *StateDB) SlotInAccessList(addr common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) { return s.accessList.Contains(addr, slot) +} + +// OpenStorageTrie opens the storage trie for the storage root of the provided address. +func (s *StateDB) OpenStorageTrie(addr common.Address) (Trie, error) { + storageRoot := s.GetStorageRoot(addr) + return s.db.OpenStorageTrie(s.originalRoot, addr, storageRoot, s.trie) }   // markDelete is invoked when an account is deleted but the deletion is
diff --git go-ethereum/core/state/statedb_test.go op-geth/core/state/statedb_test.go index 67eb9cbdc6177b74a836bcee2d2cd7a5986d800d..fbe88287e403e44ed8b7f9cac85b3013081bb014 100644 --- go-ethereum/core/state/statedb_test.go +++ op-geth/core/state/statedb_test.go @@ -1368,3 +1368,221 @@ // the storage change is reverted, dirty value should be set back state.RevertToSnapshot(snap) checkDirty(common.Hash{0x1}, common.Hash{0x1}, true) } + +func TestCheckTransactionConditional(t *testing.T) { + type preAction struct { + Account common.Address + Slots map[common.Hash]common.Hash + } + + tests := []struct { + name string + preActions []preAction + cond types.TransactionConditional + valid bool + }{ + { + // Clean Prestate, no defined cond + name: "clean prestate", + preActions: []preAction{}, + cond: types.TransactionConditional{}, + valid: true, + }, + { + // Prestate: + // - address(1) + // - bytes32(0): bytes32(1) + // cond: + // - address(1) + // - bytes32(0): bytes32(1) + name: "matching storage slots", + preActions: []preAction{ + { + Account: common.Address{19: 1}, + Slots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 1}, + }, + }, + }, + cond: types.TransactionConditional{ + KnownAccounts: map[common.Address]types.KnownAccount{ + common.Address{19: 1}: types.KnownAccount{ + StorageSlots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 1}, + }, + }, + }, + }, + valid: true, + }, + { + // Prestate: + // - address(1) + // - bytes32(0): bytes32(1) + // cond: + // - address(1) + // - bytes32(0): bytes32(2) + name: "mismatched storage slots", + preActions: []preAction{ + { + Account: common.Address{19: 1}, + Slots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 1}, + }, + }, + }, + cond: types.TransactionConditional{ + KnownAccounts: map[common.Address]types.KnownAccount{ + common.Address{19: 1}: types.KnownAccount{ + StorageSlots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 2}, + }, + }, + }, + }, + valid: false, + }, + { + // Clean Prestate + // cond: + // - address(1) + // - emptyRoot + name: "matching storage root", + preActions: []preAction{}, + cond: types.TransactionConditional{ + KnownAccounts: map[common.Address]types.KnownAccount{ + common.Address{19: 1}: types.KnownAccount{ + StorageRoot: &types.EmptyRootHash, + }, + }, + }, + valid: true, + }, + { + // Prestate: + // - address(1) + // - bytes32(0): bytes32(1) + // cond: + // - address(1) + // - emptyRoot + name: "mismatched storage root", + preActions: []preAction{ + { + Account: common.Address{19: 1}, + Slots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 1}, + }, + }, + }, + cond: types.TransactionConditional{ + KnownAccounts: map[common.Address]types.KnownAccount{ + common.Address{19: 1}: types.KnownAccount{ + StorageRoot: &types.EmptyRootHash, + }, + }, + }, + valid: false, + }, + { + // Prestate: + // - address(1) + // - bytes32(0): bytes32(1) + // - address(2) + // - bytes32(0): bytes32(2) + // cond: + // - address(1) + // - bytes32(0): bytes32(1) + // - address(2) + // - bytes32(0): bytes32(2) + name: "multiple matching", + preActions: []preAction{ + { + Account: common.Address{19: 1}, + Slots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 1}, + }, + }, + { + Account: common.Address{19: 2}, + Slots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 2}, + }, + }, + }, + cond: types.TransactionConditional{ + KnownAccounts: map[common.Address]types.KnownAccount{ + common.Address{19: 1}: types.KnownAccount{ + StorageSlots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 1}, + }, + }, + common.Address{19: 2}: types.KnownAccount{ + StorageSlots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 2}, + }, + }, + }, + }, + valid: true, + }, + { + // Prestate: + // - address(1) + // - bytes32(0): bytes32(1) + // - address(2) + // - bytes32(0): bytes32(3) + // cond: + // - address(1) + // - bytes32(0): bytes32(1) + // - address(2) + // - bytes32(0): bytes32(2) + name: "multiple mismatch single", + preActions: []preAction{ + { + Account: common.Address{19: 1}, + Slots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 1}, + }, + }, + { + Account: common.Address{19: 2}, + Slots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 3}, + }, + }, + }, + cond: types.TransactionConditional{ + KnownAccounts: map[common.Address]types.KnownAccount{ + common.Address{19: 1}: types.KnownAccount{ + StorageSlots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 1}, + }, + }, + common.Address{19: 2}: types.KnownAccount{ + StorageSlots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 2}, + }, + }, + }, + }, + valid: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + state, _ := New(types.EmptyRootHash, NewDatabaseForTesting()) + for _, action := range test.preActions { + for key, value := range action.Slots { + state.SetState(action.Account, key, value) + } + } + + // write modifications to the trie + state.IntermediateRoot(false) + if err := state.CheckTransactionConditional(&test.cond); err == nil && !test.valid { + t.Errorf("Test %s got unvalid value: want %v, got err %v", test.name, test.valid, err) + } + }) + } +}
diff --git go-ethereum/core/types/block.go op-geth/core/types/block.go index c3db4d89e820457ad4987628472e28005b1cf19d..80650bda580496ca291701560880e259b8e1c98c 100644 --- go-ethereum/core/types/block.go +++ op-geth/core/types/block.go @@ -178,6 +178,23 @@ func (h *Header) EmptyReceipts() bool { return h.ReceiptHash == EmptyReceiptsHash }   +// CheckTransactionConditional validates the block preconditions against the header +func (h *Header) CheckTransactionConditional(cond *TransactionConditional) error { + if cond.BlockNumberMin != nil && cond.BlockNumberMin.Cmp(h.Number) > 0 { + return fmt.Errorf("failed block number minimum constraint") + } + if cond.BlockNumberMax != nil && cond.BlockNumberMax.Cmp(h.Number) < 0 { + return fmt.Errorf("failed block number maximmum constraint") + } + if cond.TimestampMin != nil && *cond.TimestampMin > h.Time { + return fmt.Errorf("failed timestamp minimum constraint") + } + if cond.TimestampMax != nil && *cond.TimestampMax < h.Time { + return fmt.Errorf("failed timestamp maximum constraint") + } + return nil +} + // Body is a simple (mutable, non-safe) data container for storing and moving // a block's data contents (transactions and uncles) together. type Body struct { @@ -232,12 +249,17 @@ Uncles []*Header Withdrawals []*Withdrawal `rlp:"optional"` }   +type BlockType interface { + HasOptimismWithdrawalsRoot(blkTime uint64) bool + IsIsthmus(blkTime uint64) bool +} + // NewBlock creates a new block. The input data is copied, changes to header and to the // field values will not affect the block. // // The body elements and the receipts are used to recompute and overwrite the // relevant portions of the header. -func NewBlock(header *Header, body *Body, receipts []*Receipt, hasher TrieHasher) *Block { +func NewBlock(header *Header, body *Body, receipts []*Receipt, hasher TrieHasher, bType BlockType) *Block { if body == nil { body = &Body{} } @@ -273,7 +295,14 @@ b.uncles[i] = CopyHeader(uncles[i]) } }   - if withdrawals == nil { + if bType.HasOptimismWithdrawalsRoot(b.header.Time) { + if withdrawals == nil || len(withdrawals) > 0 { + panic(fmt.Sprintf("expected non-nil empty withdrawals operation list in Isthmus, but got: %v", body.Withdrawals)) + } + b.header.WithdrawalsHash = header.WithdrawalsHash + b.withdrawals = make(Withdrawals, 0) + } else if withdrawals == nil { + // pre-Canyon b.header.WithdrawalsHash = nil } else if len(withdrawals) == 0 { b.header.WithdrawalsHash = &EmptyWithdrawalsHash @@ -394,6 +423,14 @@ func (b *Block) TxHash() common.Hash { return b.header.TxHash } func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash } func (b *Block) UncleHash() common.Hash { return b.header.UncleHash } func (b *Block) Extra() []byte { return common.CopyBytes(b.header.Extra) } + +func (b *Block) WithdrawalsRoot() *common.Hash { + if b.header.WithdrawalsHash == nil { + return nil + } + h := *b.header.WithdrawalsHash + return &h +}   func (b *Block) BaseFee() *big.Int { if b.header.BaseFee == nil {
diff --git go-ethereum/core/types/block_test.go op-geth/core/types/block_test.go index 1f61be89a5d6c7c9adc233fef54521afd1ac1370..52290bf8469b53f75918d28aa44b44abe0cd868d 100644 --- go-ethereum/core/types/block_test.go +++ op-geth/core/types/block_test.go @@ -255,7 +255,8 @@ Time: 9876543, Extra: []byte("benchmark uncle"), } } - return NewBlock(header, &Body{Transactions: txs, Uncles: uncles}, receipts, blocktest.NewHasher()) + withdrawals := make([]*Withdrawal, 0) + return NewBlock(header, &Body{Transactions: txs, Uncles: uncles, Withdrawals: withdrawals}, receipts, blocktest.NewHasher(), IsthmusBlockConfig) }   func TestRlpDecodeParentHash(t *testing.T) { @@ -318,3 +319,109 @@ } } } } + +func TestCheckTransactionConditional(t *testing.T) { + u64Ptr := func(n uint64) *uint64 { + return &n + } + + tests := []struct { + name string + header Header + cond TransactionConditional + valid bool + }{ + { + "BlockNumberMaxFails", + Header{Number: big.NewInt(2)}, + TransactionConditional{BlockNumberMax: big.NewInt(1)}, + false, + }, + { + "BlockNumberMaxEqualSucceeds", + Header{Number: big.NewInt(2)}, + TransactionConditional{BlockNumberMax: big.NewInt(2)}, + true, + }, + { + "BlockNumberMaxSucceeds", + Header{Number: big.NewInt(1)}, + TransactionConditional{BlockNumberMax: big.NewInt(2)}, + true, + }, + { + "BlockNumberMinFails", + Header{Number: big.NewInt(1)}, + TransactionConditional{BlockNumberMin: big.NewInt(2)}, + false, + }, + { + "BlockNumberMinEqualSuccess", + Header{Number: big.NewInt(2)}, + TransactionConditional{BlockNumberMin: big.NewInt(2)}, + true, + }, + { + "BlockNumberMinSuccess", + Header{Number: big.NewInt(4)}, + TransactionConditional{BlockNumberMin: big.NewInt(3)}, + true, + }, + { + "BlockNumberRangeSucceeds", + Header{Number: big.NewInt(5)}, + TransactionConditional{BlockNumberMin: big.NewInt(1), BlockNumberMax: big.NewInt(10)}, + true, + }, + { + "BlockNumberRangeFails", + Header{Number: big.NewInt(15)}, + TransactionConditional{BlockNumberMin: big.NewInt(1), BlockNumberMax: big.NewInt(10)}, + false, + }, + { + "BlockTimestampMinFails", + Header{Time: 1}, + TransactionConditional{TimestampMin: u64Ptr(2)}, + false, + }, + { + "BlockTimestampMinSucceeds", + Header{Time: 2}, + TransactionConditional{TimestampMin: u64Ptr(1)}, + true, + }, + { + "BlockTimestampMinEqualSucceeds", + Header{Time: 1}, + TransactionConditional{TimestampMin: u64Ptr(1)}, + true, + }, + { + "BlockTimestampMaxFails", + Header{Time: 2}, + TransactionConditional{TimestampMax: u64Ptr(1)}, + false, + }, + { + "BlockTimestampMaxSucceeds", + Header{Time: 1}, + TransactionConditional{TimestampMax: u64Ptr(2)}, + true, + }, + { + "BlockTimestampMaxEqualSucceeds", + Header{Time: 2}, + TransactionConditional{TimestampMax: u64Ptr(2)}, + true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if err := test.header.CheckTransactionConditional(&test.cond); err == nil && !test.valid { + t.Errorf("Test %s got unvalid value, want %v, got err %v", test.name, test.valid, err) + } + }) + } +}
diff --git go-ethereum/core/types/gen_transaction_conditional_json.go op-geth/core/types/gen_transaction_conditional_json.go new file mode 100644 index 0000000000000000000000000000000000000000..b2027353166e04c8cd676ca0bdf3d23f5d29c793 --- /dev/null +++ op-geth/core/types/gen_transaction_conditional_json.go @@ -0,0 +1,61 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package types + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/common/math" +) + +var _ = (*transactionConditionalMarshalling)(nil) + +// MarshalJSON marshals as JSON. +func (t TransactionConditional) MarshalJSON() ([]byte, error) { + type TransactionConditional struct { + KnownAccounts KnownAccounts `json:"knownAccounts"` + BlockNumberMin *math.HexOrDecimal256 `json:"blockNumberMin,omitempty"` + BlockNumberMax *math.HexOrDecimal256 `json:"blockNumberMax,omitempty"` + TimestampMin *math.HexOrDecimal64 `json:"timestampMin,omitempty"` + TimestampMax *math.HexOrDecimal64 `json:"timestampMax,omitempty"` + } + var enc TransactionConditional + enc.KnownAccounts = t.KnownAccounts + enc.BlockNumberMin = (*math.HexOrDecimal256)(t.BlockNumberMin) + enc.BlockNumberMax = (*math.HexOrDecimal256)(t.BlockNumberMax) + enc.TimestampMin = (*math.HexOrDecimal64)(t.TimestampMin) + enc.TimestampMax = (*math.HexOrDecimal64)(t.TimestampMax) + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (t *TransactionConditional) UnmarshalJSON(input []byte) error { + type TransactionConditional struct { + KnownAccounts *KnownAccounts `json:"knownAccounts"` + BlockNumberMin *math.HexOrDecimal256 `json:"blockNumberMin,omitempty"` + BlockNumberMax *math.HexOrDecimal256 `json:"blockNumberMax,omitempty"` + TimestampMin *math.HexOrDecimal64 `json:"timestampMin,omitempty"` + TimestampMax *math.HexOrDecimal64 `json:"timestampMax,omitempty"` + } + var dec TransactionConditional + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.KnownAccounts != nil { + t.KnownAccounts = *dec.KnownAccounts + } + if dec.BlockNumberMin != nil { + t.BlockNumberMin = (*big.Int)(dec.BlockNumberMin) + } + if dec.BlockNumberMax != nil { + t.BlockNumberMax = (*big.Int)(dec.BlockNumberMax) + } + if dec.TimestampMin != nil { + t.TimestampMin = (*uint64)(dec.TimestampMin) + } + if dec.TimestampMax != nil { + t.TimestampMax = (*uint64)(dec.TimestampMax) + } + return nil +}
diff --git go-ethereum/core/types/transaction_conditional.go op-geth/core/types/transaction_conditional.go new file mode 100644 index 0000000000000000000000000000000000000000..479b6f9fc5b284552e22129f5f306ddd2954dc57 --- /dev/null +++ op-geth/core/types/transaction_conditional.go @@ -0,0 +1,126 @@ +package types + +import ( + "encoding/json" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" +) + +// KnownAccounts represents a set of KnownAccounts +type KnownAccounts map[common.Address]KnownAccount + +// KnownAccount allows for a user to express their preference of a known +// prestate at a particular account. Only one of the storage root or +// storage slots is allowed to be set. If the storage root is set, then +// the user prefers their transaction to only be included in a block if +// the account's storage root matches. If the storage slots are set, +// then the user prefers their transaction to only be included if the +// particular storage slot values from state match. +type KnownAccount struct { + StorageRoot *common.Hash + StorageSlots map[common.Hash]common.Hash +} + +// UnmarshalJSON will parse the JSON bytes into a KnownAccount struct. +func (ka *KnownAccount) UnmarshalJSON(data []byte) error { + var hash common.Hash + if err := json.Unmarshal(data, &hash); err == nil { + ka.StorageRoot = &hash + ka.StorageSlots = make(map[common.Hash]common.Hash) + return nil + } + + var mapping map[common.Hash]common.Hash + if err := json.Unmarshal(data, &mapping); err != nil { + return err + } + ka.StorageSlots = mapping + return nil +} + +// MarshalJSON will serialize the KnownAccount into JSON bytes. +func (ka KnownAccount) MarshalJSON() ([]byte, error) { + if ka.StorageRoot != nil { + return json.Marshal(ka.StorageRoot) + } + return json.Marshal(ka.StorageSlots) +} + +// Root will return the storage root and true when the user prefers +// execution against an account's storage root, otherwise it will +// return false. +func (ka *KnownAccount) Root() (common.Hash, bool) { + if ka.StorageRoot == nil { + return common.Hash{}, false + } + return *ka.StorageRoot, true +} + +// Slots will return the storage slots and true when the user prefers +// execution against an account's particular storage slots, StorageRoot == nil, +// otherwise it will return false. +func (ka *KnownAccount) Slots() (map[common.Hash]common.Hash, bool) { + if ka.StorageRoot != nil { + return ka.StorageSlots, false + } + return ka.StorageSlots, true +} + +//go:generate go run github.com/fjl/gencodec -type TransactionConditional -field-override transactionConditionalMarshalling -out gen_transaction_conditional_json.go + +// TransactionConditional represents the preconditions that determine the +// inclusion of the transaction, enforced out-of-protocol by the sequencer. +type TransactionConditional struct { + // KnownAccounts represents account prestate conditions + KnownAccounts KnownAccounts `json:"knownAccounts"` + + // Header state conditionals (inclusive ranges) + BlockNumberMin *big.Int `json:"blockNumberMin,omitempty"` + BlockNumberMax *big.Int `json:"blockNumberMax,omitempty"` + TimestampMin *uint64 `json:"timestampMin,omitempty"` + TimestampMax *uint64 `json:"timestampMax,omitempty"` +} + +// field type overrides for gencodec +type transactionConditionalMarshalling struct { + BlockNumberMax *math.HexOrDecimal256 + BlockNumberMin *math.HexOrDecimal256 + TimestampMin *math.HexOrDecimal64 + TimestampMax *math.HexOrDecimal64 +} + +// Validate will perform sanity checks on the preconditions. This does not check the aggregate cost of the preconditions. +func (cond *TransactionConditional) Validate() error { + if cond.BlockNumberMin != nil && cond.BlockNumberMax != nil && cond.BlockNumberMin.Cmp(cond.BlockNumberMax) > 0 { + return fmt.Errorf("block number minimum constraint must be less than the maximum") + } + if cond.TimestampMin != nil && cond.TimestampMax != nil && *cond.TimestampMin > *cond.TimestampMax { + return fmt.Errorf("timestamp minimum constraint must be less than the maximum") + } + return nil +} + +// Cost computes the aggregate cost of the preconditions; total number of storage lookups required +func (cond *TransactionConditional) Cost() int { + cost := 0 + for _, account := range cond.KnownAccounts { + // default cost to handle empty accounts + cost += 1 + if _, isRoot := account.Root(); isRoot { + cost += 1 + } + if slots, isSlots := account.Slots(); isSlots { + cost += len(slots) + } + } + if cond.BlockNumberMin != nil || cond.BlockNumberMax != nil { + cost += 1 + } + if cond.TimestampMin != nil || cond.TimestampMax != nil { + cost += 1 + } + return cost +}
diff --git go-ethereum/core/types/transaction_conditional_test.go op-geth/core/types/transaction_conditional_test.go new file mode 100644 index 0000000000000000000000000000000000000000..6abfe946d0ca6a905aa0bf836f4c14f0cff6076f --- /dev/null +++ op-geth/core/types/transaction_conditional_test.go @@ -0,0 +1,264 @@ +package types + +import ( + "encoding/json" + "math/big" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +func TestTransactionConditionalCost(t *testing.T) { + uint64Ptr := func(num uint64) *uint64 { + return &num + } + + tests := []struct { + name string + cond TransactionConditional + cost int + }{ + { + name: "empty conditional", + cond: TransactionConditional{}, + cost: 0, + }, + { + name: "block number lookup counts once", + cond: TransactionConditional{BlockNumberMin: big.NewInt(1), BlockNumberMax: big.NewInt(2)}, + cost: 1, + }, + { + name: "timestamp lookup counts once", + cond: TransactionConditional{TimestampMin: uint64Ptr(0), TimestampMax: uint64Ptr(5)}, + cost: 1, + }, + { + name: "default cost per account", + cond: TransactionConditional{KnownAccounts: map[common.Address]KnownAccount{ + common.Address{19: 1}: KnownAccount{}, + common.Address{19: 2}: KnownAccount{}, + }}, + cost: 2, + }, + { + name: "storage root lookup", + cond: TransactionConditional{KnownAccounts: map[common.Address]KnownAccount{ + common.Address{19: 1}: KnownAccount{ + StorageRoot: &EmptyRootHash, + }}}, + cost: 2, + }, + { + name: "cost per storage slot lookup", + cond: TransactionConditional{KnownAccounts: map[common.Address]KnownAccount{ + common.Address{19: 1}: KnownAccount{ + StorageSlots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 1}, + common.Hash{31: 1}: common.Hash{31: 1}, + }, + }}}, + cost: 3, + }, + { + name: "cost summed together", + cond: TransactionConditional{ + BlockNumberMin: big.NewInt(1), + TimestampMin: uint64Ptr(1), + KnownAccounts: map[common.Address]KnownAccount{ + common.Address{19: 1}: KnownAccount{StorageRoot: &EmptyRootHash}, + common.Address{19: 2}: KnownAccount{ + StorageSlots: map[common.Hash]common.Hash{ + common.Hash{}: common.Hash{31: 1}, + common.Hash{31: 1}: common.Hash{31: 1}, + }, + }}}, + cost: 7, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + cost := test.cond.Cost() + if cost != test.cost { + t.Errorf("Test %s mismatch in TransactionConditional cost. Got %d, Expected: %d", test.name, cost, test.cost) + } + }) + } +} + +func TestTransactionConditionalValidation(t *testing.T) { + uint64Ptr := func(num uint64) *uint64 { + return &num + } + + tests := []struct { + name string + cond TransactionConditional + mustFail bool + }{ + { + name: "empty conditional", + cond: TransactionConditional{}, + mustFail: false, + }, + { + name: "equal block constraint", + cond: TransactionConditional{BlockNumberMin: big.NewInt(1), BlockNumberMax: big.NewInt(1)}, + mustFail: false, + }, + { + name: "block min greater than max", + cond: TransactionConditional{BlockNumberMin: big.NewInt(2), BlockNumberMax: big.NewInt(1)}, + mustFail: true, + }, + { + name: "equal timestamp constraint", + cond: TransactionConditional{TimestampMin: uint64Ptr(1), TimestampMax: uint64Ptr(1)}, + mustFail: false, + }, + { + name: "timestamp min greater than max", + cond: TransactionConditional{TimestampMin: uint64Ptr(2), TimestampMax: uint64Ptr(1)}, + mustFail: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := test.cond.Validate() + if test.mustFail && err == nil { + t.Errorf("Test %s should fail", test.name) + } + if !test.mustFail && err != nil { + t.Errorf("Test %s should pass but got err: %v", test.name, err) + } + }) + } +} + +func TestTransactionConditionalSerDeser(t *testing.T) { + uint64Ptr := func(num uint64) *uint64 { + return &num + } + hashPtr := func(hash common.Hash) *common.Hash { + return &hash + } + + tests := []struct { + name string + input string + mustFail bool + expected TransactionConditional + }{ + { + name: "StateRoot", + input: `{"knownAccounts":{"0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0":"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"}}`, + mustFail: false, + expected: TransactionConditional{ + KnownAccounts: map[common.Address]KnownAccount{ + common.HexToAddress("0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0"): KnownAccount{ + StorageRoot: hashPtr(common.HexToHash("0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")), + StorageSlots: make(map[common.Hash]common.Hash), + }, + }, + }, + }, + { + name: "StorageSlots", + input: `{"knownAccounts":{"0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0":{"0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8":"0x0000000000000000000000000000000000000000000000000000000000000000"}}}`, + mustFail: false, + expected: TransactionConditional{ + KnownAccounts: map[common.Address]KnownAccount{ + common.HexToAddress("0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0"): KnownAccount{ + StorageRoot: nil, + StorageSlots: map[common.Hash]common.Hash{ + common.HexToHash("0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8"): common.HexToHash("0x"), + }, + }, + }, + }, + }, + { + name: "EmptyObject", + input: `{"knownAccounts":{}}`, + mustFail: false, + expected: TransactionConditional{ + KnownAccounts: make(map[common.Address]KnownAccount), + }, + }, + { + name: "EmptyStrings", + input: `{"knownAccounts":{"":""}}`, + mustFail: true, + expected: TransactionConditional{KnownAccounts: nil}, + }, + { + name: "BlockNumberMin", + input: `{"blockNumberMin":"0x1"}`, + mustFail: false, + expected: TransactionConditional{ + BlockNumberMin: big.NewInt(1), + }, + }, + { + name: "BlockNumberMax", + input: `{"blockNumberMax":"0x2"}`, + mustFail: false, + expected: TransactionConditional{ + BlockNumberMax: big.NewInt(2), + }, + }, + { + name: "BlockNumber (decimal)", + input: `{"blockNumberMin": 0, "blockNumberMax": 1}`, + mustFail: false, + expected: TransactionConditional{ + BlockNumberMin: big.NewInt(0), + BlockNumberMax: big.NewInt(1), + }, + }, + { + name: "TimestampMin", + input: `{"timestampMin":"0xffff"}`, + mustFail: false, + expected: TransactionConditional{ + TimestampMin: uint64Ptr(uint64(0xffff)), + }, + }, + { + name: "TimestampMax", + input: `{"timestampMax":"0xffffff"}`, + mustFail: false, + expected: TransactionConditional{ + TimestampMax: uint64Ptr(uint64(0xffffff)), + }, + }, + { + name: "Timestamp (decimal)", + input: `{"timestampMin": 0, "timestampMax": 1}`, + mustFail: false, + expected: TransactionConditional{ + TimestampMin: uint64Ptr(0), + TimestampMax: uint64Ptr(1), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var cond TransactionConditional + err := json.Unmarshal([]byte(test.input), &cond) + if test.mustFail && err == nil { + t.Errorf("Test %s should fail", test.name) + } + if !test.mustFail && err != nil { + t.Errorf("Test %s should pass but got err: %v", test.name, err) + } + if !reflect.DeepEqual(cond, test.expected) { + t.Errorf("Test %s got unexpected value, want %#v, got %#v", test.name, test.expected, cond) + } + }) + } +}
diff --git go-ethereum/eth/protocols/eth/broadcast.go op-geth/eth/protocols/eth/broadcast.go index f0ed1d6bc9a0ee013488d9e2775deee6d7f173ea..e41e0aaf74fda9af0a6de5dcd4a396aa603c4dd0 100644 --- go-ethereum/eth/protocols/eth/broadcast.go +++ op-geth/eth/protocols/eth/broadcast.go @@ -47,7 +47,10 @@ txs []*types.Transaction size common.StorageSize ) for i := 0; i < len(queue) && size < maxTxPacketSize; i++ { - if tx := p.txpool.Get(queue[i]); tx != nil { + // Transaction conditionals are tied to the block builder it was + // submitted to. Thus we do not broadcast transactions to peers that + // have a conditional attached to them. + if tx := p.txpool.Get(queue[i]); tx != nil && tx.Conditional() == nil { txs = append(txs, tx) size += common.StorageSize(tx.Size()) }
diff --git go-ethereum/internal/sequencerapi/api.go op-geth/internal/sequencerapi/api.go new file mode 100644 index 0000000000000000000000000000000000000000..9a64258948ebe1e9620ad794fad58618f08cbaf5 --- /dev/null +++ op-geth/internal/sequencerapi/api.go @@ -0,0 +1,129 @@ +package sequencerapi + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" + "golang.org/x/time/rate" +) + +var ( + sendRawTxConditionalCostMeter = metrics.NewRegisteredMeter("sequencer/sendRawTransactionConditional/cost", nil) + sendRawTxConditionalRequestsCounter = metrics.NewRegisteredCounter("sequencer/sendRawTransactionConditional/requests", nil) + sendRawTxConditionalAcceptedCounter = metrics.NewRegisteredCounter("sequencer/sendRawTransactionConditional/accepted", nil) +) + +type sendRawTxCond struct { + b ethapi.Backend + seqRPC *rpc.Client + costLimiter *rate.Limiter +} + +func GetSendRawTxConditionalAPI(b ethapi.Backend, seqRPC *rpc.Client, costRateLimit rate.Limit) rpc.API { + // Applying a manual bump to the burst to allow conditional txs to queue. Metrics will + // will inform of adjustments that may need to be made here. + costLimiter := rate.NewLimiter(costRateLimit, 3*params.TransactionConditionalMaxCost) + return rpc.API{ + Namespace: "eth", + Service: &sendRawTxCond{b, seqRPC, costLimiter}, + } +} + +func (s *sendRawTxCond) SendRawTransactionConditional(ctx context.Context, txBytes hexutil.Bytes, cond types.TransactionConditional) (common.Hash, error) { + sendRawTxConditionalRequestsCounter.Inc(1) + + cost := cond.Cost() + sendRawTxConditionalCostMeter.Mark(int64(cost)) + if cost > params.TransactionConditionalMaxCost { + return common.Hash{}, &rpc.JsonError{ + Message: fmt.Sprintf("conditional cost, %d, exceeded max: %d", cost, params.TransactionConditionalMaxCost), + Code: params.TransactionConditionalCostExceededMaxErrCode, + } + } + + // Perform sanity validation prior to state lookups + if err := cond.Validate(); err != nil { + return common.Hash{}, &rpc.JsonError{ + Message: fmt.Sprintf("failed conditional validation: %s", err), + Code: params.TransactionConditionalRejectedErrCode, + } + } + + state, header, err := s.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber) + if err != nil { + return common.Hash{}, err + } + if err := header.CheckTransactionConditional(&cond); err != nil { + return common.Hash{}, &rpc.JsonError{ + Message: fmt.Sprintf("failed header check: %s", err), + Code: params.TransactionConditionalRejectedErrCode, + } + } + if err := state.CheckTransactionConditional(&cond); err != nil { + return common.Hash{}, &rpc.JsonError{ + Message: fmt.Sprintf("failed state check: %s", err), + Code: params.TransactionConditionalRejectedErrCode, + } + } + + // State is checked against an older block to remove the MEV incentive for this endpoint compared with sendRawTransaction + parentBlock := rpc.BlockNumberOrHash{BlockHash: &header.ParentHash} + parentState, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, parentBlock) + if err != nil { + return common.Hash{}, err + } + if err := parentState.CheckTransactionConditional(&cond); err != nil { + return common.Hash{}, &rpc.JsonError{ + Message: fmt.Sprintf("failed parent block %s state check: %s", header.ParentHash, err), + Code: params.TransactionConditionalRejectedErrCode, + } + } + + // enforce rate limit on the cost to be observed + if err := s.costLimiter.WaitN(ctx, cost); err != nil { + return common.Hash{}, &rpc.JsonError{ + Message: fmt.Sprintf("cost %d rate limited", cost), + Code: params.TransactionConditionalCostExceededMaxErrCode, + } + } + + tx := new(types.Transaction) + if err := tx.UnmarshalBinary(txBytes); err != nil { + return common.Hash{}, err + } + + // forward if seqRPC is set, otherwise submit the tx + if s.seqRPC != nil { + // Some precondition checks done by `ethapi.SubmitTransaction` that are good to also check here + if err := ethapi.CheckTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil { + return common.Hash{}, err + } + if !s.b.UnprotectedAllowed() && !tx.Protected() { + // Ensure only eip155 signed transactions are submitted if EIP155Required is set. + return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC") + } + + var hash common.Hash + err := s.seqRPC.CallContext(ctx, &hash, "eth_sendRawTransactionConditional", txBytes, cond) + return hash, err + } else { + // Set out-of-consensus internal tx fields + tx.SetTime(time.Now()) + tx.SetConditional(&cond) + + // `SubmitTransaction` which forwards to `b.SendTx` also checks if its internal `seqRPC` client is + // set. Since both of these client are constructed when `RollupSequencerHTTP` is supplied, the above + // block ensures that we're only adding to the txpool for this node. + sendRawTxConditionalAcceptedCounter.Inc(1) + return ethapi.SubmitTransaction(ctx, s.b, tx) + } +}
diff --git go-ethereum/params/conditional_tx_params.go op-geth/params/conditional_tx_params.go new file mode 100644 index 0000000000000000000000000000000000000000..a3d27a98379e715e42036752611f0df96b7b3df9 --- /dev/null +++ op-geth/params/conditional_tx_params.go @@ -0,0 +1,9 @@ +package params + +const ( + // An inclusive limit on the max cost for the conditional attached to a tx + TransactionConditionalMaxCost = 1000 + + TransactionConditionalRejectedErrCode = -32003 + TransactionConditionalCostExceededMaxErrCode = -32005 +)
diff --git go-ethereum/rpc/json.go op-geth/rpc/json.go index e932389d17c7bc63aecbe2deebdcb40073a797ec..bc8d69f143bcd25285cbe5f02679528397aa6266 100644 --- go-ethereum/rpc/json.go +++ op-geth/rpc/json.go @@ -41,6 +41,8 @@ )   var null = json.RawMessage("null")   +type JsonError = jsonError + type subscriptionResult struct { ID string `json:"subscription"` Result json.RawMessage `json:"result,omitempty"`

Extend the tools available in geth to improve external testing and tooling.

diff --git go-ethereum/accounts/abi/bind/backends/simulated.go op-geth/accounts/abi/bind/backends/simulated.go index dfd929695286568a72fcb10a8c671e7b00b8cf22..38ac9d60d091204326f9fd8ec932fff4f4721bc9 100644 --- go-ethereum/accounts/abi/bind/backends/simulated.go +++ op-geth/accounts/abi/bind/backends/simulated.go @@ -21,6 +21,7 @@ "context"   "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/ethclient/simulated" )   @@ -50,3 +51,11 @@ Backend: b, Client: b.Client(), } } + +func NewSimulatedBackendFromConfig(cfg ethconfig.Config) *SimulatedBackend { + b := simulated.NewBackendFromConfig(cfg) + return &SimulatedBackend{ + Backend: b, + Client: b.Client(), + } +}
diff --git go-ethereum/ethclient/simulated/backend.go op-geth/ethclient/simulated/backend.go index 65d44b9efade1f577058b31cfd520a788f9aa0d0..246a3768e4970ab224347e6b5ec388ba20b6871f 100644 --- go-ethereum/ethclient/simulated/backend.go +++ op-geth/ethclient/simulated/backend.go @@ -102,6 +102,27 @@ } return sim }   +func NewBackendFromConfig(conf ethconfig.Config) *Backend { + // Setup the node object + nodeConf := node.DefaultConfig + nodeConf.DataDir = "" + nodeConf.P2P = p2p.Config{NoDiscovery: true} + stack, err := node.New(&nodeConf) + if err != nil { + // This should never happen, if it does, please open an issue + panic(err) + } + + conf.SyncMode = ethconfig.FullSync + conf.TxPool.NoLocals = true + sim, err := newWithNode(stack, &conf, 0) + if err != nil { + // This should never happen, if it does, please open an issue + panic(err) + } + return sim +} + // newWithNode sets up a simulated backend on an existing node. The provided node // must not be started and will be started by this method. func newWithNode(stack *node.Node, conf *eth.Config, blockPeriod uint64) (*Backend, error) {

Track L1-deposited native currency that is coming into the L2 supply. The balance delta is considered to be a “withdrawal” from L1, similar to a withdrawal of the Beacon-chain into the Ethereum L1 execution chain.

diff --git go-ethereum/eth/tracers/live/supply.go op-geth/eth/tracers/live/supply.go index fa4e5b190431a408dbaa4783dd082c3a88a21d1f..fae9cb1afbbb202af2860d72c462a44a6bfc6db3 100644 --- go-ethereum/eth/tracers/live/supply.go +++ op-geth/eth/tracers/live/supply.go @@ -202,6 +202,9 @@ case tracing.BalanceDecreaseSelfdestructBurn: // BalanceDecreaseSelfdestructBurn is non-reversible as it happens // at the end of the transaction. s.delta.Burn.Misc.Sub(s.delta.Burn.Misc, diff) + // Technically an OP-Stack deposit mint is a "withdrawal" from L1, taking funds into L2. + case tracing.BalanceMint: + s.delta.Issuance.Withdrawals.Add(s.delta.Issuance.Withdrawals, diff) default: return }

The EVM t8ntool has not been updated with most op-stack features and does not use the same sealer logic as used in Geth consensus. Isthumus hard fork adds a withdrawalsRoot field in the block header. We note that the t8ntool is not updated to handle the newly added withdrawalsRoot field in the block header.

Additional or modified tests, not already captured by the above diff

diff --git go-ethereum/accounts/abi/packing_test.go op-geth/accounts/abi/packing_test.go index eae3b0df20562372b4e739ba0e72559c0d19bd96..9ed52a475eb900f5be20dfe9441ba25ac330defd 100644 --- go-ethereum/accounts/abi/packing_test.go +++ op-geth/accounts/abi/packing_test.go @@ -375,7 +375,7 @@ { def: `[{"type": "bytes"}]`, packed: "0000000000000000000000000000000000000000000000000000000000000020" + "0000000000000000000000000000000000000000000000000000000000000020" + - "0100000000000000000000000000000000000000000000000000000000000000", + "0100000000000000000000000000000000000000000000000000000000000000", //nolint:all unpacked: common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { @@ -476,7 +476,7 @@ { def: `[{"type": "int256[3]"}]`, packed: "0000000000000000000000000000000000000000000000000000000000000001" + "0000000000000000000000000000000000000000000000000000000000000002" + - "0000000000000000000000000000000000000000000000000000000000000003", + "0000000000000000000000000000000000000000000000000000000000000003", //nolint:all unpacked: [3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}, }, // multi dimensional, if these pass, all types that don't require length prefix should pass @@ -536,7 +536,7 @@ { def: `[{"type": "uint8[][2]"}]`, packed: "0000000000000000000000000000000000000000000000000000000000000020" + "0000000000000000000000000000000000000000000000000000000000000040" + - "0000000000000000000000000000000000000000000000000000000000000080" + + "0000000000000000000000000000000000000000000000000000000000000080" + //nolint:all "0000000000000000000000000000000000000000000000000000000000000001" + "0000000000000000000000000000000000000000000000000000000000000001" + "0000000000000000000000000000000000000000000000000000000000000001" + @@ -801,7 +801,7 @@ "0000000000000000000000000000000000000000000000000000000000000002" + // len(array[0]) = 2 "0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0] "0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1] "0000000000000000000000000000000000000000000000000000000000000003" + // len(array[1]) = 3 - "0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0] + "0300000000000000000000000000000000000000000000000000000000000000" + //nolint:all // array[1][0] "0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1] "0500000000000000000000000000000000000000000000000000000000000000", // array[1][2] }, @@ -845,7 +845,7 @@ E [2][3][32]byte }{1, big.NewInt(1), big.NewInt(-1), true, [2][3][32]byte{{{1}, {2}, {3}}, {{3}, {4}, {5}}}}, packed: "0000000000000000000000000000000000000000000000000000000000000001" + // struct[a] "0000000000000000000000000000000000000000000000000000000000000001" + // struct[b] - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // struct[c] + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + //nolint:all // struct[c] "0000000000000000000000000000000000000000000000000000000000000001" + // struct[d] "0100000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[0][0] "0200000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[0][1]
diff --git go-ethereum/consensus/misc/create2deployer_test.go op-geth/consensus/misc/create2deployer_test.go new file mode 100644 index 0000000000000000000000000000000000000000..c547a90fead351dc35ff8ee54e3abf18f77b5177 --- /dev/null +++ op-geth/consensus/misc/create2deployer_test.go @@ -0,0 +1,96 @@ +package misc + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" +) + +func TestEnsureCreate2Deployer(t *testing.T) { + canyonTime := uint64(1000) + tests := []struct { + name string + override func(cfg *params.ChainConfig) + timestamp uint64 + codeExists bool + applied bool + }{ + { + name: "at hardfork", + timestamp: canyonTime, + applied: true, + }, + { + name: "another chain ID", + override: func(cfg *params.ChainConfig) { + cfg.ChainID = big.NewInt(params.OPMainnetChainID) + }, + timestamp: canyonTime, + applied: true, + }, + { + name: "code already exists", + timestamp: canyonTime, + codeExists: true, + applied: true, + }, + { + name: "pre canyon", + timestamp: canyonTime - 1, + applied: false, + }, + { + name: "post hardfork", + timestamp: canyonTime + 1, + applied: false, + }, + { + name: "canyon not configured", + override: func(cfg *params.ChainConfig) { + cfg.CanyonTime = nil + }, + timestamp: canyonTime, + applied: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := params.ChainConfig{ + ChainID: big.NewInt(params.BaseMainnetChainID), + Optimism: &params.OptimismConfig{}, + CanyonTime: &canyonTime, + } + if tt.override != nil { + tt.override(&cfg) + } + state := &stateDb{ + codeExists: tt.codeExists, + } + EnsureCreate2Deployer(&cfg, tt.timestamp, state) + assert.Equal(t, tt.applied, state.codeSet) + }) + } +} + +type stateDb struct { + vm.StateDB + codeExists bool + codeSet bool +} + +func (s *stateDb) GetCodeSize(_ common.Address) int { + if s.codeExists { + return 1 + } + return 0 +} + +func (s *stateDb) SetCode(_ common.Address, _ []byte) []byte { + s.codeSet = true + return nil +}
diff --git go-ethereum/core/genesis_test.go op-geth/core/genesis_test.go index 964ef928c777be3b4ae018ac2dcf67cd70515478..a4280679c46c8b16b3f9abea6cde66ce8fb061fc 100644 --- go-ethereum/core/genesis_test.go +++ op-geth/core/genesis_test.go @@ -225,13 +225,16 @@ alloc = &types.GenesisAlloc{ {1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}}, {2}: {Balance: big.NewInt(2), Storage: map[common.Hash]common.Hash{{2}: {2}}}, } - hash, _ = hashAlloc(alloc, false) + stateRoot, storageRootMessagePasser, _ = hashAlloc(alloc, false, false) ) + if storageRootMessagePasser != (common.Hash{}) { + t.Fatalf("unexpected storage root") + } blob, _ := json.Marshal(alloc) - rawdb.WriteGenesisStateSpec(db, hash, blob) + rawdb.WriteGenesisStateSpec(db, stateRoot, blob)   var reload types.GenesisAlloc - err := reload.UnmarshalJSON(rawdb.ReadGenesisStateSpec(db, hash)) + err := reload.UnmarshalJSON(rawdb.ReadGenesisStateSpec(db, stateRoot)) if err != nil { t.Fatalf("Failed to load genesis state %v", err) }
diff --git go-ethereum/core/rawdb/accessors_chain_test.go op-geth/core/rawdb/accessors_chain_test.go index 0e986f66e00765f49a3e244c1b16c559b3c037d7..806b0ca62c5b1eb17630b957e86ddad2854d3a5f 100644 --- go-ethereum/core/rawdb/accessors_chain_test.go +++ op-geth/core/rawdb/accessors_chain_test.go @@ -20,6 +20,7 @@ import ( "bytes" "encoding/hex" "fmt" + "math" "math/big" "math/rand" "os" @@ -31,6 +32,7 @@ "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" + "github.com/stretchr/testify/require" "golang.org/x/crypto/sha3" )   @@ -347,6 +349,9 @@ // Create a live block since we need metadata to reconstruct the receipt tx1 := types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil) tx2 := types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil)   + header := &types.Header{ + Number: big.NewInt(0), + } body := &types.Body{Transactions: types.Transactions{tx1, tx2}}   // Create the two receipts to manage afterwards @@ -378,13 +383,16 @@ receipt2.Bloom = types.CreateBloom(types.Receipts{receipt2}) receipts := []*types.Receipt{receipt1, receipt2}   // Check that no receipt entries are in a pristine database - hash := common.BytesToHash([]byte{0x03, 0x14}) + hash := header.Hash() if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) != 0 { t.Fatalf("non existent receipts returned: %v", rs) } // Insert the body that corresponds to the receipts WriteBody(db, hash, 0, body)   + // Insert the header that corresponds to the receipts + WriteHeader(db, header) + // Insert the receipt slice into the database and check presence WriteReceipts(db, hash, 0, receipts) if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) == 0 { @@ -698,36 +706,56 @@ // Create a live block since we need metadata to reconstruct the receipt tx1 := types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil) tx2 := types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil) + tx3 := types.NewTransaction(3, common.HexToAddress("0x3"), big.NewInt(3), 3, big.NewInt(3), nil)   - body := &types.Body{Transactions: types.Transactions{tx1, tx2}} + body := &types.Body{Transactions: types.Transactions{tx1, tx2, tx3}}   - // Create the two receipts to manage afterwards - receipt1 := &types.Receipt{ + // Create the three receipts to manage afterwards + depositNonce := uint64(math.MaxUint64) + depositReceipt := types.Receipt{ Status: types.ReceiptStatusFailed, CumulativeGasUsed: 1, Logs: []*types.Log{ {Address: common.BytesToAddress([]byte{0x11})}, {Address: common.BytesToAddress([]byte{0x01, 0x11})}, }, - TxHash: tx1.Hash(), - ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), - GasUsed: 111111, + TxHash: tx1.Hash(), + ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), + GasUsed: 111111, + DepositNonce: &depositNonce, + DepositReceiptVersion: nil, } - receipt1.Bloom = types.CreateBloom(types.Receipts{receipt1}) + depositReceipt.Bloom = types.CreateBloom(types.Receipts{&depositReceipt})   - receipt2 := &types.Receipt{ - PostState: common.Hash{2}.Bytes(), + receiptVersion := types.CanyonDepositReceiptVersion + versionedDepositReceipt := types.Receipt{ + Status: types.ReceiptStatusFailed, CumulativeGasUsed: 2, Logs: []*types.Log{ {Address: common.BytesToAddress([]byte{0x22})}, - {Address: common.BytesToAddress([]byte{0x02, 0x22})}, + {Address: common.BytesToAddress([]byte{0x01, 0x11})}, + }, + TxHash: tx2.Hash(), + ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), + GasUsed: 222222, + DepositNonce: &depositNonce, + DepositReceiptVersion: &receiptVersion, + } + versionedDepositReceipt.Bloom = types.CreateBloom(types.Receipts{&versionedDepositReceipt}) + + receipt := types.Receipt{ + PostState: common.Hash{3}.Bytes(), + CumulativeGasUsed: 3, + Logs: []*types.Log{ + {Address: common.BytesToAddress([]byte{0x33})}, + {Address: common.BytesToAddress([]byte{0x03, 0x33})}, }, - TxHash: tx2.Hash(), - ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), - GasUsed: 222222, + TxHash: tx3.Hash(), + ContractAddress: common.BytesToAddress([]byte{0x03, 0x33, 0x33}), + GasUsed: 333333, } - receipt2.Bloom = types.CreateBloom(types.Receipts{receipt2}) - receipts := []*types.Receipt{receipt1, receipt2} + receipt.Bloom = types.CreateBloom(types.Receipts{&receipt}) + receipts := []*types.Receipt{&receipt, &depositReceipt, &versionedDepositReceipt}   hash := common.BytesToHash([]byte{0x03, 0x14}) // Check that no receipt entries are in a pristine database @@ -744,14 +772,13 @@ logs := ReadLogs(db, hash, 0) if len(logs) == 0 { t.Fatalf("no logs returned") } - if have, want := len(logs), 2; have != want { + if have, want := len(logs), 3; have != want { t.Fatalf("unexpected number of logs returned, have %d want %d", have, want) } - if have, want := len(logs[0]), 2; have != want { - t.Fatalf("unexpected number of logs[0] returned, have %d want %d", have, want) - } - if have, want := len(logs[1]), 2; have != want { - t.Fatalf("unexpected number of logs[1] returned, have %d want %d", have, want) + for i := range logs { + if have, want := len(logs[i]), 2; have != want { + t.Fatalf("unexpected number of logs[%d] returned, have %d want %d", i, have, want) + } }   for i, pr := range receipts { @@ -769,6 +796,36 @@ t.Fatalf("receipt #%d: receipt mismatch: have %s, want %s", i, hex.EncodeToString(rlpHave), hex.EncodeToString(rlpWant)) } } } +} + +func TestParseLegacyReceiptRLP(t *testing.T) { + // Create a gasUsed value greater than a uint64 can represent + gasUsed := big.NewInt(0) + gasUsed = gasUsed.SetUint64(math.MaxUint64) + gasUsed = gasUsed.Add(gasUsed, big.NewInt(math.MaxInt64)) + sanityCheck := (&big.Int{}).SetUint64(gasUsed.Uint64()) + require.NotEqual(t, gasUsed, sanityCheck) + receipt := types.LegacyOptimismStoredReceiptRLP{ + CumulativeGasUsed: 1, + Logs: []*types.LogForStorage{ + {Address: common.BytesToAddress([]byte{0x11})}, + {Address: common.BytesToAddress([]byte{0x01, 0x11})}, + }, + L1GasUsed: gasUsed, + L1GasPrice: gasUsed, + L1Fee: gasUsed, + FeeScalar: "6", + } + + data, err := rlp.EncodeToBytes(receipt) + require.NoError(t, err) + var result storedReceiptRLP + err = rlp.DecodeBytes(data, &result) + require.NoError(t, err) + require.Equal(t, receipt.L1GasUsed, result.L1GasUsed) + require.Equal(t, receipt.L1GasPrice, result.L1GasPrice) + require.Equal(t, receipt.L1Fee, result.L1Fee) + require.Equal(t, receipt.FeeScalar, result.FeeScalar) }   func TestDeriveLogFields(t *testing.T) {
diff --git go-ethereum/core/rawdb/accessors_indexes_test.go op-geth/core/rawdb/accessors_indexes_test.go index 1bee4555037c2f4dcc3488c104803addc5fe3fba..758b1c7f2540f5b56b4e788c81fa97d39d76f5d5 100644 --- go-ethereum/core/rawdb/accessors_indexes_test.go +++ op-geth/core/rawdb/accessors_indexes_test.go @@ -76,7 +76,7 @@ tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22}) tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}) txs := []*types.Transaction{tx1, tx2, tx3}   - block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, &types.Body{Transactions: txs}, nil, newTestHasher()) + block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, &types.Body{Transactions: txs}, nil, newTestHasher(), types.DefaultBlockConfig)   // Check that no transactions entries are in a pristine database for i, tx := range txs {
diff --git go-ethereum/core/rawdb/chain_iterator_test.go op-geth/core/rawdb/chain_iterator_test.go index 390424f673fc5bfd3e8ff1796341fe05fae3c873..3dd5cbff0788e18b75df0aab87d42606857ba2d1 100644 --- go-ethereum/core/rawdb/chain_iterator_test.go +++ op-geth/core/rawdb/chain_iterator_test.go @@ -34,7 +34,7 @@ var block *types.Block var txs []*types.Transaction to := common.BytesToAddress([]byte{0x11}) - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, newTestHasher()) // Empty genesis block + block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, newTestHasher(), types.DefaultBlockConfig) // Empty genesis block WriteBlock(chainDb, block) WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) for i := uint64(1); i <= 10; i++ { @@ -60,7 +60,7 @@ Data: []byte{0x11, 0x11, 0x11}, }) } txs = append(txs, tx) - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, &types.Body{Transactions: types.Transactions{tx}}, nil, newTestHasher()) + block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, &types.Body{Transactions: types.Transactions{tx}}, nil, newTestHasher(), types.DefaultBlockConfig) WriteBlock(chainDb, block) WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) } @@ -111,7 +111,7 @@ var txs []*types.Transaction to := common.BytesToAddress([]byte{0x11})   // Write empty genesis block - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, newTestHasher()) + block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, newTestHasher(), types.DefaultBlockConfig) WriteBlock(chainDb, block) WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64())   @@ -138,7 +138,7 @@ Data: []byte{0x11, 0x11, 0x11}, }) } txs = append(txs, tx) - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, &types.Body{Transactions: types.Transactions{tx}}, nil, newTestHasher()) + block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, &types.Body{Transactions: types.Transactions{tx}}, nil, newTestHasher(), types.DefaultBlockConfig) WriteBlock(chainDb, block) WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) }
diff --git go-ethereum/core/rlp_test.go op-geth/core/rlp_test.go index bc37408537a3999a3c9d417e7f3106e9836ad149..3652f7539b05c7d8f2e18b9c8478b935f9f0ae56 100644 --- go-ethereum/core/rlp_test.go +++ op-geth/core/rlp_test.go @@ -27,10 +27,14 @@ "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" + "github.com/stretchr/testify/require" "golang.org/x/crypto/sha3" )   -func getBlock(transactions int, uncles int, dataSize int) *types.Block { +func getBlock(config *params.ChainConfig, transactions int, uncles int, dataSize int) *types.Block { + if config == nil { + config = params.TestChainConfig + } var ( aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") engine = ethash.NewFaker() @@ -40,7 +44,7 @@ key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") address = crypto.PubkeyToAddress(key.PublicKey) funds = big.NewInt(1_000_000_000_000_000_000) gspec = &Genesis{ - Config: params.TestChainConfig, + Config: config, Alloc: types.GenesisAlloc{address: {Balance: funds}}, } ) @@ -83,7 +87,7 @@ }   func testRlpIterator(t *testing.T, txs, uncles, datasize int) { desc := fmt.Sprintf("%d txs [%d datasize] and %d uncles", txs, datasize, uncles) - bodyRlp, _ := rlp.EncodeToBytes(getBlock(txs, uncles, datasize).Body()) + bodyRlp, _ := rlp.EncodeToBytes(getBlock(nil, txs, uncles, datasize).Body()) it, err := rlp.NewListIterator(bodyRlp) if err != nil { t.Fatal(err) @@ -142,7 +146,7 @@ bodyRlp []byte blockRlp []byte ) { - block := getBlock(200, 2, 50) + block := getBlock(nil, 200, 2, 50) bodyRlp, _ = rlp.EncodeToBytes(block.Body()) blockRlp, _ = rlp.EncodeToBytes(block) } @@ -195,3 +199,25 @@ if got != exp { b.Fatalf("hash wrong, got %x exp %x", got, exp) } } + +func TestBlockRlpEncodeDecode(t *testing.T) { + zeroTime := uint64(0) + + // create a config where Isthmus upgrade is active + config := *params.OptimismTestConfig + config.ShanghaiTime = &zeroTime + config.IsthmusTime = &zeroTime + config.CancunTime = &zeroTime + require.True(t, config.IsOptimismIsthmus(zeroTime)) + + block := getBlock(&config, 10, 2, 50) + + blockRlp, err := rlp.EncodeToBytes(block) + require.NoError(t, err) + + var decoded types.Block + err = rlp.DecodeBytes(blockRlp, &decoded) + require.NoError(t, err) + + require.Equal(t, decoded.Hash(), block.Hash()) +}
diff --git go-ethereum/core/state_processor_test.go op-geth/core/state_processor_test.go index 2f841eb64aed22595fe06fb4989301a5bbfea185..011e7ac2b0dc1a346cc2e25a6765e936c3ca3b10 100644 --- go-ethereum/core/state_processor_test.go +++ op-geth/core/state_processor_test.go @@ -401,7 +401,7 @@ Time: parent.Time() + 10, UncleHash: types.EmptyUncleHash, } if config.IsLondon(header.Number) { - header.BaseFee = eip1559.CalcBaseFee(config, parent.Header()) + header.BaseFee = eip1559.CalcBaseFee(config, parent.Header(), header.Time) } if config.IsShanghai(header.Number, header.Time) { header.WithdrawalsHash = &types.EmptyWithdrawalsHash @@ -443,5 +443,5 @@ body := &types.Body{Transactions: txs} if config.IsShanghai(header.Number, header.Time) { body.Withdrawals = []*types.Withdrawal{} } - return types.NewBlock(header, body, receipts, trie.NewStackTrie(nil)) + return types.NewBlock(header, body, receipts, trie.NewStackTrie(nil), config) }
diff --git go-ethereum/core/superchain_test.go op-geth/core/superchain_test.go new file mode 100644 index 0000000000000000000000000000000000000000..a3ee2c8f0b394d4511ce987212365455390bcb2a --- /dev/null +++ op-geth/core/superchain_test.go @@ -0,0 +1,127 @@ +package core + +import ( + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/superchain" + "github.com/ethereum/go-ethereum/triedb" +) + +func TestOPStackGenesis(t *testing.T) { + for id, cfg := range superchain.Chains { + t.Run(fmt.Sprintf("chain-%s", cfg.Name), func(t *testing.T) { + t.Parallel() + _, err := LoadOPStackGenesis(id) + if err != nil { + t.Error(err) + } + }) + } +} + +func TestRegistryChainConfigOverride(t *testing.T) { + tests := []struct { + name string + overrides *ChainOverrides + setDenominator *uint64 + expectedDenominator uint64 + expectedRegolithTime *uint64 + }{ + { + name: "ApplySuperchainUpgrades", + overrides: &ChainOverrides{ApplySuperchainUpgrades: true}, + setDenominator: uint64ptr(50), + expectedDenominator: 250, + expectedRegolithTime: uint64ptr(0), + }, + { + name: "OverrideOptimismCanyon_denom_nil", + overrides: &ChainOverrides{OverrideOptimismCanyon: uint64ptr(1)}, + setDenominator: nil, + expectedDenominator: 250, + expectedRegolithTime: nil, + }, + { + name: "OverrideOptimismCanyon_denom_0", + overrides: &ChainOverrides{OverrideOptimismCanyon: uint64ptr(1)}, + setDenominator: uint64ptr(0), + expectedDenominator: 250, + expectedRegolithTime: nil, + }, + { + name: "OverrideOptimismCanyon_ignore_override", + overrides: &ChainOverrides{OverrideOptimismCanyon: uint64ptr(1)}, + setDenominator: uint64ptr(100), + expectedDenominator: 100, + expectedRegolithTime: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + db := rawdb.NewMemoryDatabase() + genesis, err := LoadOPStackGenesis(10) + if err != nil { + t.Fatal(err) + } + if genesis.Config.RegolithTime == nil { + t.Fatal("expected non-nil regolith time") + } + genesis.Config.RegolithTime = nil + + // initialize the DB + tdb := triedb.NewDatabase(db, newDbConfig(rawdb.PathScheme)) + genesis.MustCommit(db, tdb) + bl := genesis.ToBlock() + rawdb.WriteCanonicalHash(db, bl.Hash(), 0) + rawdb.WriteBlock(db, bl) + + if genesis.Config.Optimism == nil { + t.Fatal("expected non nil Optimism config") + } + genesis.Config.Optimism.EIP1559DenominatorCanyon = tt.setDenominator + // create chain config, even with incomplete genesis input: the chain config should be corrected + chainConfig, _, _, err := SetupGenesisBlockWithOverride(db, tdb, genesis, tt.overrides) + if err != nil { + t.Fatal(err) + } + + // check if we have a corrected chain config + if tt.expectedRegolithTime == nil { + if chainConfig.RegolithTime != nil { + t.Fatal("expected regolith time to be nil") + } + } else if *chainConfig.RegolithTime != *tt.expectedRegolithTime { + t.Fatalf("expected regolith time to be %d, but got %d", *tt.expectedRegolithTime, *chainConfig.RegolithTime) + } + + if *chainConfig.Optimism.EIP1559DenominatorCanyon != tt.expectedDenominator { + t.Fatalf("expected EIP1559DenominatorCanyon to be %d, but got %d", tt.expectedDenominator, *chainConfig.Optimism.EIP1559DenominatorCanyon) + } + }) + } +} + +func TestOPMainnetGenesisDB(t *testing.T) { + db := rawdb.NewMemoryDatabase() + genesis, err := LoadOPStackGenesis(10) + if err != nil { + t.Fatal(err) + } + tdb := triedb.NewDatabase(db, newDbConfig(rawdb.PathScheme)) + genesis.MustCommit(db, tdb) + bl := genesis.ToBlock() + expected := common.HexToHash("0x7ca38a1916c42007829c55e69d3e9a73265554b586a499015373241b8a3fa48b") + if blockHash := bl.Hash(); blockHash != expected { + t.Fatalf("block hash mismatch: %s <> %s", blockHash, expected) + } + // This is written separately to the DB by Commit() and is thus tested explicitly here + canonicalHash := rawdb.ReadCanonicalHash(db, 0) + if canonicalHash != expected { + t.Fatalf("canonical hash mismatch: %s <> %s", canonicalHash, expected) + } +}
diff --git go-ethereum/core/types/interoptypes/interop_test.go op-geth/core/types/interoptypes/interop_test.go new file mode 100644 index 0000000000000000000000000000000000000000..5bb303fecf23defccb270cf106a9a7b0c167ec83 --- /dev/null +++ op-geth/core/types/interoptypes/interop_test.go @@ -0,0 +1,178 @@ +package interoptypes + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" +) + +func FuzzMessage_DecodeEvent(f *testing.F) { + f.Fuzz(func(t *testing.T, validEvTopic bool, numTopics uint8, data []byte) { + if len(data) < 32 { + return + } + if len(data) > 100_000 { + return + } + if validEvTopic { // valid even signature topic implies a topic to be there + numTopics += 1 + } + if numTopics > 4 { // There can be no more than 4 topics per log event + return + } + if int(numTopics)*32 > len(data) { + return + } + var topics []common.Hash + if validEvTopic { + topics = append(topics, ExecutingMessageEventTopic) + } + for i := 0; i < int(numTopics); i++ { + var topic common.Hash + copy(topic[:], data[:]) + data = data[32:] + } + require.NotPanics(t, func() { + var m Message + _ = m.DecodeEvent(topics, data) + }) + }) +} + +func TestSafetyLevel(t *testing.T) { + require.True(t, Invalid.wellFormatted()) + require.True(t, Unsafe.wellFormatted()) + require.True(t, CrossUnsafe.wellFormatted()) + require.True(t, LocalSafe.wellFormatted()) + require.True(t, Safe.wellFormatted()) + require.True(t, Finalized.wellFormatted()) + require.False(t, SafetyLevel("hello").wellFormatted()) + require.False(t, SafetyLevel("").wellFormatted()) +} + +func TestInteropMessageFormatEdgeCases(t *testing.T) { + tests := []struct { + name string + log *types.Log + expectedError string + }{ + { + name: "Empty Topics", + log: &types.Log{ + Address: params.InteropCrossL2InboxAddress, + Topics: []common.Hash{}, + Data: make([]byte, 32*5), + }, + expectedError: "unexpected number of event topics: 0", + }, + { + name: "Wrong Event Topic", + log: &types.Log{ + Address: params.InteropCrossL2InboxAddress, + Topics: []common.Hash{ + common.BytesToHash([]byte("wrong topic")), + common.BytesToHash([]byte("payloadHash")), + }, + Data: make([]byte, 32*5), + }, + expectedError: "unexpected event topic", + }, + { + name: "Missing PayloadHash Topic", + log: &types.Log{ + Address: params.InteropCrossL2InboxAddress, + Topics: []common.Hash{ + common.BytesToHash(ExecutingMessageEventTopic[:]), + }, + Data: make([]byte, 32*5), + }, + expectedError: "unexpected number of event topics: 1", + }, + { + name: "Too Many Topics", + log: &types.Log{ + Address: params.InteropCrossL2InboxAddress, + Topics: []common.Hash{ + common.BytesToHash(ExecutingMessageEventTopic[:]), + common.BytesToHash([]byte("payloadHash")), + common.BytesToHash([]byte("extra")), + }, + Data: make([]byte, 32*5), + }, + expectedError: "unexpected number of event topics: 3", + }, + { + name: "Data Too Short", + log: &types.Log{ + Address: params.InteropCrossL2InboxAddress, + Topics: []common.Hash{ + common.BytesToHash(ExecutingMessageEventTopic[:]), + common.BytesToHash([]byte("payloadHash")), + }, + Data: make([]byte, 32*4), // One word too short + }, + expectedError: "unexpected identifier data length: 128", + }, + { + name: "Data Too Long", + log: &types.Log{ + Address: params.InteropCrossL2InboxAddress, + Topics: []common.Hash{ + common.BytesToHash(ExecutingMessageEventTopic[:]), + common.BytesToHash([]byte("payloadHash")), + }, + Data: make([]byte, 32*6), // One word too long + }, + expectedError: "unexpected identifier data length: 192", + }, + { + name: "Invalid Address Padding", + log: &types.Log{ + Address: params.InteropCrossL2InboxAddress, + Topics: []common.Hash{ + common.BytesToHash(ExecutingMessageEventTopic[:]), + common.BytesToHash([]byte("payloadHash")), + }, + Data: func() []byte { + data := make([]byte, 32*5) + data[0] = 1 // Add non-zero byte in address padding + return data + }(), + }, + expectedError: "invalid address padding", + }, + { + name: "Invalid Block Number Padding", + log: &types.Log{ + Address: params.InteropCrossL2InboxAddress, + Topics: []common.Hash{ + common.BytesToHash(ExecutingMessageEventTopic[:]), + common.BytesToHash([]byte("payloadHash")), + }, + Data: func() []byte { + data := make([]byte, 32*5) + data[32+23] = 1 // Add non-zero byte in block number padding + return data + }(), + }, + expectedError: "invalid block number padding", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var msg Message + err := msg.DecodeEvent(tt.log.Topics, tt.log.Data) + if tt.expectedError != "" { + require.Error(t, err) + require.ErrorContains(t, err, tt.expectedError) + } else { + require.NoError(t, err) + } + }) + } +}
diff --git go-ethereum/core/types/receipt_test.go op-geth/core/types/receipt_test.go index fc51eb11a528caea6627d1a6ff49705c00615292..733edb6c80a932647dadb74e3f1fed5b2a89cb30 100644 --- go-ethereum/core/types/receipt_test.go +++ op-geth/core/types/receipt_test.go @@ -19,6 +19,7 @@ import ( "bytes" "encoding/json" + "fmt" "math" "math/big" "reflect" @@ -29,9 +30,24 @@ "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/holiman/uint256" "github.com/kylelemons/godebug/diff" + "github.com/stretchr/testify/require" )   var ( + bedrockGenesisTestConfig = func() *params.ChainConfig { + conf := *params.AllCliqueProtocolChanges // copy the config + conf.Clique = nil + conf.BedrockBlock = big.NewInt(0) + conf.Optimism = &params.OptimismConfig{EIP1559Elasticity: 50, EIP1559Denominator: 10} + return &conf + }() + ecotoneTestConfig = func() *params.ChainConfig { + conf := *bedrockGenesisTestConfig // copy the config + time := uint64(0) + conf.EcotoneTime = &time + return &conf + }() + legacyReceipt = &Receipt{ Status: ReceiptStatusFailed, CumulativeGasUsed: 1, @@ -82,6 +98,63 @@ }, }, Type: DynamicFeeTxType, } + depositReceiptNoNonce = &Receipt{ + Status: ReceiptStatusFailed, + CumulativeGasUsed: 1, + Logs: []*Log{ + { + Address: common.BytesToAddress([]byte{0x11}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + Data: []byte{0x01, 0x00, 0xff}, + }, + { + Address: common.BytesToAddress([]byte{0x01, 0x11}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + Data: []byte{0x01, 0x00, 0xff}, + }, + }, + Type: DepositTxType, + } + nonce = uint64(1234) + depositReceiptWithNonce = &Receipt{ + Status: ReceiptStatusFailed, + CumulativeGasUsed: 1, + DepositNonce: &nonce, + DepositReceiptVersion: nil, + Logs: []*Log{ + { + Address: common.BytesToAddress([]byte{0x11}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + Data: []byte{0x01, 0x00, 0xff}, + }, + { + Address: common.BytesToAddress([]byte{0x01, 0x11}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + Data: []byte{0x01, 0x00, 0xff}, + }, + }, + Type: DepositTxType, + } + version = CanyonDepositReceiptVersion + depositReceiptWithNonceAndVersion = &Receipt{ + Status: ReceiptStatusFailed, + CumulativeGasUsed: 1, + DepositNonce: &nonce, + DepositReceiptVersion: &version, + Logs: []*Log{ + { + Address: common.BytesToAddress([]byte{0x11}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + Data: []byte{0x01, 0x00, 0xff}, + }, + { + Address: common.BytesToAddress([]byte{0x01, 0x11}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + Data: []byte{0x01, 0x00, 0xff}, + }, + }, + Type: DepositTxType, + }   // Create a few transactions to have receipts for to2 = common.HexToAddress("0x2") @@ -149,11 +222,23 @@ GasFeeCap: uint256.NewInt(1077), BlobFeeCap: uint256.NewInt(100077), BlobHashes: []common.Hash{{}, {}, {}}, }), + NewTx(&DepositTx{ + To: nil, // contract creation + Value: big.NewInt(6), + Gas: 50, + }), + NewTx(&DepositTx{ + To: nil, // contract creation + Value: big.NewInt(6), + Gas: 60, + }), } - - blockNumber = big.NewInt(1) - blockTime = uint64(2) - blockHash = common.BytesToHash([]byte{0x03, 0x14}) + depNonce1 = uint64(7) + depNonce2 = uint64(8) + blockNumber = big.NewInt(1) + blockTime = uint64(2) + blockHash = common.BytesToHash([]byte{0x03, 0x14}) + canyonDepositReceiptVersion = CanyonDepositReceiptVersion   // Create the corresponding receipts receipts = Receipts{ @@ -293,6 +378,78 @@ BlockHash: blockHash, BlockNumber: blockNumber, TransactionIndex: 6, }, + &Receipt{ + Type: DepositTxType, + PostState: common.Hash{5}.Bytes(), + CumulativeGasUsed: 50 + 28, + Logs: []*Log{ + { + Address: common.BytesToAddress([]byte{0x33}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + // derived fields: + BlockNumber: blockNumber.Uint64(), + TxHash: txs[7].Hash(), + TxIndex: 7, + BlockHash: blockHash, + Index: 4, + }, + { + Address: common.BytesToAddress([]byte{0x03, 0x33}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + // derived fields: + BlockNumber: blockNumber.Uint64(), + TxHash: txs[7].Hash(), + TxIndex: 7, + BlockHash: blockHash, + Index: 5, + }, + }, + TxHash: txs[7].Hash(), + ContractAddress: common.HexToAddress("0x3bb898b4bbe24f68a4e9be46cfe72d1787fd74f4"), + GasUsed: 50, + EffectiveGasPrice: big.NewInt(0), + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 7, + DepositNonce: &depNonce1, + DepositReceiptVersion: nil, + }, + &Receipt{ + Type: DepositTxType, + PostState: common.Hash{5}.Bytes(), + CumulativeGasUsed: 60 + 50 + 28, + Logs: []*Log{ + { + Address: common.BytesToAddress([]byte{0x33}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + // derived fields: + BlockNumber: blockNumber.Uint64(), + TxHash: txs[8].Hash(), + TxIndex: 8, + BlockHash: blockHash, + Index: 6, + }, + { + Address: common.BytesToAddress([]byte{0x03, 0x33}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + // derived fields: + BlockNumber: blockNumber.Uint64(), + TxHash: txs[8].Hash(), + TxIndex: 8, + BlockHash: blockHash, + Index: 7, + }, + }, + TxHash: txs[8].Hash(), + ContractAddress: common.HexToAddress("0x117814af22cb83d8ad6e8489e9477d28265bc105"), + GasUsed: 60, + EffectiveGasPrice: big.NewInt(0), + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 8, + DepositNonce: &depNonce2, + DepositReceiptVersion: &canyonDepositReceiptVersion, + }, } )   @@ -308,10 +465,10 @@ // Tests that receipt data can be correctly derived from the contextual infos func TestDeriveFields(t *testing.T) { // Re-derive receipts. - basefee := big.NewInt(1000) + baseFee := big.NewInt(1000) blobGasPrice := big.NewInt(920) derivedReceipts := clearComputedFieldsOnReceipts(receipts) - err := Receipts(derivedReceipts).DeriveFields(params.TestChainConfig, blockHash, blockNumber.Uint64(), blockTime, basefee, blobGasPrice, txs) + err := Receipts(derivedReceipts).DeriveFields(params.TestChainConfig, blockHash, blockNumber.Uint64(), blockTime, baseFee, blobGasPrice, txs) if err != nil { t.Fatalf("DeriveFields(...) = %v, want <nil>", err) } @@ -344,6 +501,18 @@ r := Receipt{} err = r.UnmarshalJSON(b) if err != nil { t.Fatal("error unmarshalling receipt from json:", err) + } + + // Make sure marshal/unmarshal doesn't affect receipt hash root computation by comparing + // the output of EncodeIndex + rsBefore := Receipts([]*Receipt{receipts[i]}) + rsAfter := Receipts([]*Receipt{&r}) + + encBefore, encAfter := bytes.Buffer{}, bytes.Buffer{} + rsBefore.EncodeIndex(0, &encBefore) + rsAfter.EncodeIndex(0, &encAfter) + if !bytes.Equal(encBefore.Bytes(), encAfter.Bytes()) { + t.Errorf("%v: EncodeIndex differs after JSON marshal/unmarshal", i) } } } @@ -527,3 +696,365 @@ l[i] = &cpy } return l } + +func getOptimismEcotoneTxReceipts(l1AttributesPayload []byte, l1GasPrice, l1BlobGasPrice, l1GasUsed, l1Fee *big.Int, baseFeeScalar, blobBaseFeeScalar *uint64) ([]*Transaction, []*Receipt) { + // Create a few transactions to have receipts for + txs := Transactions{ + NewTx(&DepositTx{ + To: nil, // contract creation + Value: big.NewInt(6), + Gas: 50, + Data: l1AttributesPayload, + }), + emptyTx, + } + + // Create the corresponding receipts + receipts := Receipts{ + &Receipt{ + Type: DepositTxType, + PostState: common.Hash{5}.Bytes(), + CumulativeGasUsed: 50 + 15, + Logs: []*Log{ + { + Address: common.BytesToAddress([]byte{0x33}), + // derived fields: + BlockNumber: blockNumber.Uint64(), + TxHash: txs[0].Hash(), + TxIndex: 0, + BlockHash: blockHash, + Index: 0, + }, + { + Address: common.BytesToAddress([]byte{0x03, 0x33}), + // derived fields: + BlockNumber: blockNumber.Uint64(), + TxHash: txs[0].Hash(), + TxIndex: 0, + BlockHash: blockHash, + Index: 1, + }, + }, + TxHash: txs[0].Hash(), + ContractAddress: common.HexToAddress("0x3bb898b4bbe24f68a4e9be46cfe72d1787fd74f4"), + GasUsed: 65, + EffectiveGasPrice: big.NewInt(0), + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 0, + DepositNonce: &depNonce1, + }, + &Receipt{ + Type: LegacyTxType, + EffectiveGasPrice: big.NewInt(0), + PostState: common.Hash{4}.Bytes(), + CumulativeGasUsed: 10, + Logs: []*Log{}, + // derived fields: + TxHash: txs[1].Hash(), + GasUsed: 18446744073709551561, + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 1, + L1GasPrice: l1GasPrice, + L1BlobBaseFee: l1BlobGasPrice, + L1GasUsed: l1GasUsed, + L1Fee: l1Fee, + L1BaseFeeScalar: baseFeeScalar, + L1BlobBaseFeeScalar: blobBaseFeeScalar, + }, + } + return txs, receipts +} + +func getOptimismTxReceipts(l1AttributesPayload []byte, l1GasPrice, l1GasUsed, l1Fee *big.Int, feeScalar *big.Float) ([]*Transaction, []*Receipt) { + // Create a few transactions to have receipts for + txs := Transactions{ + NewTx(&DepositTx{ + To: nil, // contract creation + Value: big.NewInt(6), + Gas: 50, + Data: l1AttributesPayload, + }), + emptyTx, + } + + // Create the corresponding receipts + receipts := Receipts{ + &Receipt{ + Type: DepositTxType, + PostState: common.Hash{5}.Bytes(), + CumulativeGasUsed: 50 + 15, + Logs: []*Log{ + { + Address: common.BytesToAddress([]byte{0x33}), + // derived fields: + BlockNumber: blockNumber.Uint64(), + TxHash: txs[0].Hash(), + TxIndex: 0, + BlockHash: blockHash, + Index: 0, + }, + { + Address: common.BytesToAddress([]byte{0x03, 0x33}), + // derived fields: + BlockNumber: blockNumber.Uint64(), + TxHash: txs[0].Hash(), + TxIndex: 0, + BlockHash: blockHash, + Index: 1, + }, + }, + TxHash: txs[0].Hash(), + ContractAddress: common.HexToAddress("0x3bb898b4bbe24f68a4e9be46cfe72d1787fd74f4"), + GasUsed: 65, + EffectiveGasPrice: big.NewInt(0), + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 0, + DepositNonce: &depNonce1, + }, + &Receipt{ + Type: LegacyTxType, + EffectiveGasPrice: big.NewInt(0), + PostState: common.Hash{4}.Bytes(), + CumulativeGasUsed: 10, + Logs: []*Log{}, + // derived fields: + TxHash: txs[1].Hash(), + GasUsed: 18446744073709551561, + BlockHash: blockHash, + BlockNumber: blockNumber, + TransactionIndex: 1, + L1GasPrice: l1GasPrice, + L1GasUsed: l1GasUsed, + L1Fee: l1Fee, + FeeScalar: feeScalar, + }, + } + return txs, receipts +} + +func TestDeriveOptimismBedrockTxReceipts(t *testing.T) { + // Bedrock style l1 attributes with L1Scalar=7_000_000 (becomes 7 after division), L1Overhead=50, L1BaseFee=1000*1e6 + payload := common.Hex2Bytes("015d8eb900000000000000000000000000000000000000000000000000000000000004d200000000000000000000000000000000000000000000000000000000000004d2000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000004d200000000000000000000000000000000000000000000000000000000000004d200000000000000000000000000000000000000000000000000000000000004d2000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000006acfc0015d8eb900000000000000000000000000000000000000000000000000000000000004d200000000000000000000000000000000000000000000000000000000000004d2000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000004d200000000000000000000000000000000000000000000000000000000000004d200000000000000000000000000000000000000000000000000000000000004d2000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000006acfc0") + // the parameters we use below are defined in rollup_test.go + l1GasPrice := baseFee + l1GasUsed := bedrockGas + feeScalar := big.NewFloat(float64(scalar.Uint64() / 1e6)) + l1Fee := bedrockFee + txs, receipts := getOptimismTxReceipts(payload, l1GasPrice, l1GasUsed, l1Fee, feeScalar) + + // Re-derive receipts. + baseFee := big.NewInt(1000) + derivedReceipts := clearComputedFieldsOnReceipts(receipts) + err := Receipts(derivedReceipts).DeriveFields(bedrockGenesisTestConfig, blockHash, blockNumber.Uint64(), 0, baseFee, nil, txs) + if err != nil { + t.Fatalf("DeriveFields(...) = %v, want <nil>", err) + } + checkBedrockReceipts(t, receipts, derivedReceipts) + + // Should get same result with the Ecotone config because it will assume this is "first ecotone block" + // if it sees the bedrock style L1 attributes. + err = Receipts(derivedReceipts).DeriveFields(ecotoneTestConfig, blockHash, blockNumber.Uint64(), 0, baseFee, nil, txs) + if err != nil { + t.Fatalf("DeriveFields(...) = %v, want <nil>", err) + } + checkBedrockReceipts(t, receipts, derivedReceipts) +} + +func TestDeriveOptimismEcotoneTxReceipts(t *testing.T) { + // Ecotone style l1 attributes with baseFeeScalar=2, blobBaseFeeScalar=3, baseFee=1000*1e6, blobBaseFee=10*1e6 + payload := common.Hex2Bytes("440a5e20000000020000000300000000000004d200000000000004d200000000000004d2000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000004d200000000000000000000000000000000000000000000000000000000000004d2") + // the parameters we use below are defined in rollup_test.go + baseFeeScalarUint64 := baseFeeScalar.Uint64() + blobBaseFeeScalarUint64 := blobBaseFeeScalar.Uint64() + txs, receipts := getOptimismEcotoneTxReceipts(payload, baseFee, blobBaseFee, ecotoneGas, ecotoneFee, &baseFeeScalarUint64, &blobBaseFeeScalarUint64) + + // Re-derive receipts. + baseFee := big.NewInt(1000) + derivedReceipts := clearComputedFieldsOnReceipts(receipts) + // Should error out if we try to process this with a pre-Ecotone config + err := Receipts(derivedReceipts).DeriveFields(bedrockGenesisTestConfig, blockHash, blockNumber.Uint64(), 0, baseFee, nil, txs) + if err == nil { + t.Fatalf("expected error from deriving ecotone receipts with pre-ecotone config, got none") + } + + err = Receipts(derivedReceipts).DeriveFields(ecotoneTestConfig, blockHash, blockNumber.Uint64(), 0, baseFee, nil, txs) + if err != nil { + t.Fatalf("DeriveFields(...) = %v, want <nil>", err) + } + diffReceipts(t, receipts, derivedReceipts) +} + +func diffReceipts(t *testing.T, receipts, derivedReceipts []*Receipt) { + // Check diff of receipts against derivedReceipts. + r1, err := json.MarshalIndent(receipts, "", " ") + if err != nil { + t.Fatal("error marshaling input receipts:", err) + } + r2, err := json.MarshalIndent(derivedReceipts, "", " ") + if err != nil { + t.Fatal("error marshaling derived receipts:", err) + } + d := diff.Diff(string(r1), string(r2)) + if d != "" { + t.Fatal("receipts differ:", d) + } +} + +func checkBedrockReceipts(t *testing.T, receipts, derivedReceipts []*Receipt) { + diffReceipts(t, receipts, derivedReceipts) + + // Check that we preserved the invariant: l1Fee = l1GasPrice * l1GasUsed * l1FeeScalar + // but with more difficult int math... + l2Rcpt := derivedReceipts[1] + l1GasCost := new(big.Int).Mul(l2Rcpt.L1GasPrice, l2Rcpt.L1GasUsed) + l1Fee := new(big.Float).Mul(new(big.Float).SetInt(l1GasCost), l2Rcpt.FeeScalar) + require.Equal(t, new(big.Float).SetInt(l2Rcpt.L1Fee), l1Fee) +} + +func TestBedrockDepositReceiptUnchanged(t *testing.T) { + expectedRlp := common.FromHex("7EF90156A003000000000000000000000000000000000000000000000000000000000000000AB9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0D7940000000000000000000000000000000000000033C001D7940000000000000000000000000000000000000333C002") + // Deposit receipt with no nonce + receipt := &Receipt{ + Type: DepositTxType, + PostState: common.Hash{3}.Bytes(), + CumulativeGasUsed: 10, + Logs: []*Log{ + {Address: common.BytesToAddress([]byte{0x33}), Data: []byte{1}, Topics: []common.Hash{}}, + {Address: common.BytesToAddress([]byte{0x03, 0x33}), Data: []byte{2}, Topics: []common.Hash{}}, + }, + TxHash: common.Hash{}, + ContractAddress: common.BytesToAddress([]byte{0x03, 0x33, 0x33}), + GasUsed: 4, + } + + rlp, err := receipt.MarshalBinary() + require.NoError(t, err) + require.Equal(t, expectedRlp, rlp) + + // Consensus values should be unchanged after reparsing + parsed := new(Receipt) + err = parsed.UnmarshalBinary(rlp) + require.NoError(t, err) + require.Equal(t, receipt.Status, parsed.Status) + require.Equal(t, receipt.CumulativeGasUsed, parsed.CumulativeGasUsed) + require.Equal(t, receipt.Bloom, parsed.Bloom) + require.EqualValues(t, receipt.Logs, parsed.Logs) + // And still shouldn't have a nonce + require.Nil(t, parsed.DepositNonce) + // ..or a deposit nonce + require.Nil(t, parsed.DepositReceiptVersion) +} + +// Regolith introduced an inconsistency in behavior between EncodeIndex and MarshalBinary for a +// deposit transaction receipt. TestReceiptEncodeIndexBugIsEnshrined makes sure this difference is +// preserved for backwards compatibility purposes, but also that there is no discrepancy for the +// post-Canyon encoding. +func TestReceiptEncodeIndexBugIsEnshrined(t *testing.T) { + // Check that a post-Regolith, pre-Canyon receipt produces the expected difference between + // EncodeIndex and MarshalBinary. + buf := new(bytes.Buffer) + receipts := Receipts{depositReceiptWithNonce} + receipts.EncodeIndex(0, buf) + indexBytes := buf.Bytes() + + regularBytes, _ := receipts[0].MarshalBinary() + + require.NotEqual(t, indexBytes, regularBytes) + + // Confirm the buggy encoding is as expected, which means it should encode as if it had no + // nonce specified (like that of a non-deposit receipt, whose encoding would differ only in the + // type byte). + buf.Reset() + tempReceipt := *depositReceiptWithNonce + tempReceipt.Type = eip1559Receipt.Type + buggyBytes, _ := tempReceipt.MarshalBinary() + + require.Equal(t, indexBytes[1:], buggyBytes[1:]) + + // check that the post-Canyon encoding has no differences between EncodeIndex and + // MarshalBinary. + buf.Reset() + receipts = Receipts{depositReceiptWithNonceAndVersion} + receipts.EncodeIndex(0, buf) + indexBytes = buf.Bytes() + + regularBytes, _ = receipts[0].MarshalBinary() + + require.Equal(t, indexBytes, regularBytes) + + // Check that bumping the nonce post-canyon changes the hash + bumpedReceipt := *depositReceiptWithNonceAndVersion + bumpedNonce := nonce + 1 + bumpedReceipt.DepositNonce = &bumpedNonce + bumpedBytes, _ := bumpedReceipt.MarshalBinary() + require.NotEqual(t, regularBytes, bumpedBytes) +} + +func TestRoundTripReceipt(t *testing.T) { + tests := []struct { + name string + rcpt *Receipt + }{ + {name: "Legacy", rcpt: legacyReceipt}, + {name: "AccessList", rcpt: accessListReceipt}, + {name: "EIP1559", rcpt: eip1559Receipt}, + {name: "DepositNoNonce", rcpt: depositReceiptNoNonce}, + {name: "DepositWithNonce", rcpt: depositReceiptWithNonce}, + {name: "DepositWithNonceAndVersion", rcpt: depositReceiptWithNonceAndVersion}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + data, err := test.rcpt.MarshalBinary() + require.NoError(t, err) + + d := &Receipt{} + err = d.UnmarshalBinary(data) + require.NoError(t, err) + require.Equal(t, test.rcpt, d) + require.Equal(t, test.rcpt.DepositNonce, d.DepositNonce) + require.Equal(t, test.rcpt.DepositReceiptVersion, d.DepositReceiptVersion) + }) + + t.Run(fmt.Sprintf("%sRejectExtraData", test.name), func(t *testing.T) { + data, err := test.rcpt.MarshalBinary() + require.NoError(t, err) + data = append(data, 1, 2, 3, 4) + d := &Receipt{} + err = d.UnmarshalBinary(data) + require.Error(t, err) + }) + } +} + +func TestRoundTripReceiptForStorage(t *testing.T) { + tests := []struct { + name string + rcpt *Receipt + }{ + {name: "Legacy", rcpt: legacyReceipt}, + {name: "AccessList", rcpt: accessListReceipt}, + {name: "EIP1559", rcpt: eip1559Receipt}, + {name: "DepositNoNonce", rcpt: depositReceiptNoNonce}, + {name: "DepositWithNonce", rcpt: depositReceiptWithNonce}, + {name: "DepositWithNonceAndVersion", rcpt: depositReceiptWithNonceAndVersion}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + data, err := rlp.EncodeToBytes((*ReceiptForStorage)(test.rcpt)) + require.NoError(t, err) + + d := &ReceiptForStorage{} + err = rlp.DecodeBytes(data, d) + require.NoError(t, err) + // Only check the stored fields - the others are derived later + require.Equal(t, test.rcpt.Status, d.Status) + require.Equal(t, test.rcpt.CumulativeGasUsed, d.CumulativeGasUsed) + require.Equal(t, test.rcpt.Logs, d.Logs) + require.Equal(t, test.rcpt.DepositNonce, d.DepositNonce) + require.Equal(t, test.rcpt.DepositReceiptVersion, d.DepositReceiptVersion) + }) + } +}
diff --git go-ethereum/core/types/rollup_cost_test.go op-geth/core/types/rollup_cost_test.go new file mode 100644 index 0000000000000000000000000000000000000000..8d0f1e92185986c420aaeebce0bb46662f6e3ab0 --- /dev/null +++ op-geth/core/types/rollup_cost_test.go @@ -0,0 +1,407 @@ +package types + +import ( + "bytes" + "encoding/binary" + "encoding/hex" + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/params" +) + +var ( + baseFee = big.NewInt(1000 * 1e6) + overhead = big.NewInt(50) + scalar = big.NewInt(7 * 1e6) + + blobBaseFee = big.NewInt(10 * 1e6) + baseFeeScalar = big.NewInt(2) + blobBaseFeeScalar = big.NewInt(3) + + // below are the expected cost func outcomes for the above parameter settings on the emptyTx + // which is defined in transaction_test.go + bedrockFee = big.NewInt(11326000000000) + regolithFee = big.NewInt(3710000000000) + ecotoneFee = big.NewInt(960900) // (480/16)*(2*16*1000 + 3*10) == 960900 + // the emptyTx is out of bounds for the linear regression so it uses the minimum size + fjordFee = big.NewInt(3203000) // 100_000_000 * (2 * 1000 * 1e6 * 16 + 3 * 10 * 1e6) / 1e12 + + bedrockGas = big.NewInt(1618) + regolithGas = big.NewInt(530) // 530 = 1618 - (16*68) + ecotoneGas = big.NewInt(480) + minimumFjordGas = big.NewInt(1600) // fastlz size of minimum txn, 100_000_000 * 16 / 1e6 +) + +func TestBedrockL1CostFunc(t *testing.T) { + costFunc0 := newL1CostFuncBedrockHelper(baseFee, overhead, scalar, false /*isRegolith*/) + costFunc1 := newL1CostFuncBedrockHelper(baseFee, overhead, scalar, true) + + c0, g0 := costFunc0(emptyTx.RollupCostData()) // pre-Regolith + c1, g1 := costFunc1(emptyTx.RollupCostData()) + + require.Equal(t, bedrockFee, c0) + require.Equal(t, bedrockGas, g0) // gas-used + + require.Equal(t, regolithFee, c1) + require.Equal(t, regolithGas, g1) +} + +func TestEcotoneL1CostFunc(t *testing.T) { + costFunc := newL1CostFuncEcotone(baseFee, blobBaseFee, baseFeeScalar, blobBaseFeeScalar) + + c0, g0 := costFunc(emptyTx.RollupCostData()) + + require.Equal(t, ecotoneGas, g0) + require.Equal(t, ecotoneFee, c0) +} + +func TestFjordL1CostFuncMinimumBounds(t *testing.T) { + costFunc := NewL1CostFuncFjord( + baseFee, + blobBaseFee, + baseFeeScalar, + blobBaseFeeScalar, + ) + + // Minimum size transactions: + // -42.5856 + 0.8365*110 = 49.4294 + // -42.5856 + 0.8365*150 = 82.8894 + // -42.5856 + 0.8365*170 = 99.6194 + for _, fastLzsize := range []uint64{100, 150, 170} { + c, g := costFunc(RollupCostData{ + FastLzSize: fastLzsize, + }) + + require.Equal(t, minimumFjordGas, g) + require.Equal(t, fjordFee, c) + } + + // Larger size transactions: + // -42.5856 + 0.8365*171 = 100.4559 + // -42.5856 + 0.8365*175 = 108.8019 + // -42.5856 + 0.8365*200 = 124.7144 + for _, fastLzsize := range []uint64{171, 175, 200} { + c, g := costFunc(RollupCostData{ + FastLzSize: fastLzsize, + }) + + require.Greater(t, g.Uint64(), minimumFjordGas.Uint64()) + require.Greater(t, c.Uint64(), fjordFee.Uint64()) + } +} + +// TestFjordL1CostSolidityParity tests that the cost function for the fjord upgrade matches a Solidity +// test to ensure the outputs are the same. +func TestFjordL1CostSolidityParity(t *testing.T) { + costFunc := NewL1CostFuncFjord( + big.NewInt(2*1e6), + big.NewInt(3*1e6), + big.NewInt(20), + big.NewInt(15), + ) + + c0, g0 := costFunc(RollupCostData{ + FastLzSize: 235, + }) + + require.Equal(t, big.NewInt(2463), g0) + require.Equal(t, big.NewInt(105484), c0) +} + +func TestExtractBedrockGasParams(t *testing.T) { + regolithTime := uint64(1) + config := &params.ChainConfig{ + Optimism: params.OptimismTestConfig.Optimism, + RegolithTime: &regolithTime, + } + + data := getBedrockL1Attributes(baseFee, overhead, scalar) + + gasparams, err := extractL1GasParams(config, regolithTime-1, data) + costFuncPreRegolith := gasparams.costFunc + require.NoError(t, err) + + // Function should continue to succeed even with extra data (that just gets ignored) since we + // have been testing the data size is at least the expected number of bytes instead of exactly + // the expected number of bytes. It's unclear if this flexibility was intentional, but since + // it's been in production we shouldn't change this behavior. + data = append(data, []byte{0xBE, 0xEE, 0xEE, 0xFF}...) // tack on garbage data + gasparams, err = extractL1GasParams(config, regolithTime, data) + costFuncRegolith := gasparams.costFunc + require.NoError(t, err) + + c, _ := costFuncPreRegolith(emptyTx.RollupCostData()) + require.Equal(t, bedrockFee, c) + + c, _ = costFuncRegolith(emptyTx.RollupCostData()) + require.Equal(t, regolithFee, c) + + // try to extract from data which has not enough params, should get error. + data = data[:len(data)-4-32] + _, err = extractL1GasParams(config, regolithTime, data) + require.Error(t, err) +} + +func TestExtractEcotoneGasParams(t *testing.T) { + zeroTime := uint64(0) + // create a config where ecotone upgrade is active + config := &params.ChainConfig{ + Optimism: params.OptimismTestConfig.Optimism, + RegolithTime: &zeroTime, + EcotoneTime: &zeroTime, + } + require.True(t, config.IsOptimismEcotone(zeroTime)) + + data := getEcotoneL1Attributes( + baseFee, + blobBaseFee, + baseFeeScalar, + blobBaseFeeScalar, + ) + + gasparams, err := extractL1GasParams(config, zeroTime, data) + require.NoError(t, err) + costFunc := gasparams.costFunc + + c, g := costFunc(emptyTx.RollupCostData()) + + require.Equal(t, ecotoneGas, g) + require.Equal(t, ecotoneFee, c) + + // make sure wrong amont of data results in error + data = append(data, 0x00) // tack on garbage byte + _, err = extractL1GasParamsPostEcotone(data) + require.Error(t, err) +} + +func TestExtractFjordGasParams(t *testing.T) { + zeroTime := uint64(0) + // create a config where fjord is active + config := &params.ChainConfig{ + Optimism: params.OptimismTestConfig.Optimism, + RegolithTime: &zeroTime, + EcotoneTime: &zeroTime, + FjordTime: &zeroTime, + } + require.True(t, config.IsOptimismFjord(zeroTime)) + + data := getEcotoneL1Attributes( + baseFee, + blobBaseFee, + baseFeeScalar, + blobBaseFeeScalar, + ) + + gasparams, err := extractL1GasParams(config, zeroTime, data) + require.NoError(t, err) + costFunc := gasparams.costFunc + + c, g := costFunc(emptyTx.RollupCostData()) + + require.Equal(t, minimumFjordGas, g) + require.Equal(t, fjordFee, c) +} + +// make sure the first block of the ecotone upgrade is properly detected, and invokes the bedrock +// cost function appropriately +func TestFirstBlockEcotoneGasParams(t *testing.T) { + zeroTime := uint64(0) + // create a config where ecotone upgrade is active + config := &params.ChainConfig{ + Optimism: params.OptimismTestConfig.Optimism, + RegolithTime: &zeroTime, + EcotoneTime: &zeroTime, + } + require.True(t, config.IsOptimismEcotone(0)) + + data := getBedrockL1Attributes(baseFee, overhead, scalar) + + gasparams, err := extractL1GasParams(config, zeroTime, data) + require.NoError(t, err) + oldCostFunc := gasparams.costFunc + c, g := oldCostFunc(emptyTx.RollupCostData()) + require.Equal(t, regolithGas, g) + require.Equal(t, regolithFee, c) +} + +func getBedrockL1Attributes(baseFee, overhead, scalar *big.Int) []byte { + uint256 := make([]byte, 32) + ignored := big.NewInt(1234) + data := []byte{} + data = append(data, BedrockL1AttributesSelector...) + data = append(data, ignored.FillBytes(uint256)...) // arg 0 + data = append(data, ignored.FillBytes(uint256)...) // arg 1 + data = append(data, baseFee.FillBytes(uint256)...) // arg 2 + data = append(data, ignored.FillBytes(uint256)...) // arg 3 + data = append(data, ignored.FillBytes(uint256)...) // arg 4 + data = append(data, ignored.FillBytes(uint256)...) // arg 5 + data = append(data, overhead.FillBytes(uint256)...) // arg 6 + data = append(data, scalar.FillBytes(uint256)...) // arg 7 + return data +} + +func getEcotoneL1Attributes(baseFee, blobBaseFee, baseFeeScalar, blobBaseFeeScalar *big.Int) []byte { + ignored := big.NewInt(1234) + data := []byte{} + uint256Slice := make([]byte, 32) + uint64Slice := make([]byte, 8) + uint32Slice := make([]byte, 4) + data = append(data, EcotoneL1AttributesSelector...) + data = append(data, baseFeeScalar.FillBytes(uint32Slice)...) + data = append(data, blobBaseFeeScalar.FillBytes(uint32Slice)...) + data = append(data, ignored.FillBytes(uint64Slice)...) + data = append(data, ignored.FillBytes(uint64Slice)...) + data = append(data, ignored.FillBytes(uint64Slice)...) + data = append(data, baseFee.FillBytes(uint256Slice)...) + data = append(data, blobBaseFee.FillBytes(uint256Slice)...) + data = append(data, ignored.FillBytes(uint256Slice)...) + data = append(data, ignored.FillBytes(uint256Slice)...) + return data +} + +type testStateGetter struct { + baseFee, blobBaseFee, overhead, scalar *big.Int + baseFeeScalar, blobBaseFeeScalar uint32 +} + +func (sg *testStateGetter) GetState(addr common.Address, slot common.Hash) common.Hash { + buf := common.Hash{} + switch slot { + case L1BaseFeeSlot: + sg.baseFee.FillBytes(buf[:]) + case OverheadSlot: + sg.overhead.FillBytes(buf[:]) + case ScalarSlot: + sg.scalar.FillBytes(buf[:]) + case L1BlobBaseFeeSlot: + sg.blobBaseFee.FillBytes(buf[:]) + case L1FeeScalarsSlot: + // fetch Ecotone fee sclars + offset := scalarSectionStart + binary.BigEndian.PutUint32(buf[offset:offset+4], sg.baseFeeScalar) + binary.BigEndian.PutUint32(buf[offset+4:offset+8], sg.blobBaseFeeScalar) + default: + panic("unknown slot") + } + return buf +} + +// TestNewL1CostFunc tests that the appropriate cost function is selected based on the +// configuration and statedb values. +func TestNewL1CostFunc(t *testing.T) { + time := uint64(10) + timeInFuture := uint64(20) + config := &params.ChainConfig{ + Optimism: params.OptimismTestConfig.Optimism, + } + statedb := &testStateGetter{ + baseFee: baseFee, + overhead: overhead, + scalar: scalar, + blobBaseFee: blobBaseFee, + baseFeeScalar: uint32(baseFeeScalar.Uint64()), + blobBaseFeeScalar: uint32(blobBaseFeeScalar.Uint64()), + } + + costFunc := NewL1CostFunc(config, statedb) + require.NotNil(t, costFunc) + + // empty cost data should result in nil fee + fee := costFunc(RollupCostData{}, time) + require.Nil(t, fee) + + // emptyTx fee w/ bedrock config should be the bedrock fee + fee = costFunc(emptyTx.RollupCostData(), time) + require.NotNil(t, fee) + require.Equal(t, bedrockFee, fee) + + // emptyTx fee w/ regolith config should be the regolith fee + config.RegolithTime = &time + costFunc = NewL1CostFunc(config, statedb) + require.NotNil(t, costFunc) + fee = costFunc(emptyTx.RollupCostData(), time) + require.NotNil(t, fee) + require.Equal(t, regolithFee, fee) + + // emptyTx fee w/ ecotone config should be the ecotone fee + config.EcotoneTime = &time + costFunc = NewL1CostFunc(config, statedb) + fee = costFunc(emptyTx.RollupCostData(), time) + require.NotNil(t, fee) + require.Equal(t, ecotoneFee, fee) + + // emptyTx fee w/ fjord config should be the fjord fee + config.FjordTime = &time + costFunc = NewL1CostFunc(config, statedb) + fee = costFunc(emptyTx.RollupCostData(), time) + require.NotNil(t, fee) + require.Equal(t, fjordFee, fee) + + // emptyTx fee w/ ecotone config, but simulate first ecotone block by blowing away the ecotone + // params. Should result in regolith fee. + config.FjordTime = &timeInFuture + statedb.baseFeeScalar = 0 + statedb.blobBaseFeeScalar = 0 + statedb.blobBaseFee = new(big.Int) + costFunc = NewL1CostFunc(config, statedb) + fee = costFunc(emptyTx.RollupCostData(), time) + require.NotNil(t, fee) + require.Equal(t, regolithFee, fee) + + // emptyTx fee w/ fjord config, but simulate first ecotone block by blowing away the ecotone + // params. Should result in regolith fee. + config.EcotoneTime = &time + config.FjordTime = &time + statedb.baseFeeScalar = 0 + statedb.blobBaseFeeScalar = 0 + statedb.blobBaseFee = new(big.Int) + costFunc = NewL1CostFunc(config, statedb) + fee = costFunc(emptyTx.RollupCostData(), time) + require.NotNil(t, fee) + require.Equal(t, regolithFee, fee) +} + +func TestFlzCompressLen(t *testing.T) { + var ( + emptyTxBytes, _ = emptyTx.MarshalBinary() + contractCallTxStr = "02f901550a758302df1483be21b88304743f94f8" + + "0e51afb613d764fa61751affd3313c190a86bb870151bd62fd12adb8" + + "e41ef24f3f0000000000000000000000000000000000000000000000" + + "00000000000000006e000000000000000000000000af88d065e77c8c" + + "c2239327c5edb3a432268e5831000000000000000000000000000000" + + "000000000000000000000000000003c1e50000000000000000000000" + + "00000000000000000000000000000000000000000000000000000000" + + "000000000000000000000000000000000000000000000000a0000000" + + "00000000000000000000000000000000000000000000000000000000" + + "148c89ed219d02f1a5be012c689b4f5b731827bebe00000000000000" + + "0000000000c001a033fd89cb37c31b2cba46b6466e040c61fc9b2a36" + + "75a7f5f493ebd5ad77c497f8a07cdf65680e238392693019b4092f61" + + "0222e71b7cec06449cb922b93b6a12744e" + contractCallTx, _ = hex.DecodeString(contractCallTxStr) + ) + + testCases := []struct { + input []byte + expectedLen uint32 + }{ + // empty input + {[]byte{}, 0}, + // all 1 inputs + {bytes.Repeat([]byte{1}, 1000), 21}, + // all 0 inputs + {make([]byte, 1000), 21}, + // empty tx input + {emptyTxBytes, 31}, + // contract call tx: https://optimistic.etherscan.io/tx/0x8eb9dd4eb6d33f4dc25fb015919e4b1e9f7542f9b0322bf6622e268cd116b594 + {contractCallTx, 202}, + } + + for _, tc := range testCases { + output := FlzCompressLen(tc.input) + require.Equal(t, tc.expectedLen, output) + } +}
diff --git go-ethereum/core/types/transaction_marshalling_test.go op-geth/core/types/transaction_marshalling_test.go new file mode 100644 index 0000000000000000000000000000000000000000..4ab93a539d19bbcffa0293738b2e4dcc3ebe7ad2 --- /dev/null +++ op-geth/core/types/transaction_marshalling_test.go @@ -0,0 +1,103 @@ +package types + +import ( + "encoding/json" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestTransactionUnmarshalJsonDeposit(t *testing.T) { + tx := NewTx(&DepositTx{ + SourceHash: common.HexToHash("0x1234"), + IsSystemTransaction: true, + Mint: big.NewInt(34), + }) + json, err := tx.MarshalJSON() + require.NoError(t, err, "Failed to marshal tx JSON") + + got := &Transaction{} + err = got.UnmarshalJSON(json) + require.NoError(t, err, "Failed to unmarshal tx JSON") + require.Equal(t, tx.Hash(), got.Hash()) +} + +func TestTransactionUnmarshalJSON(t *testing.T) { + tests := []struct { + name string + json string + expectedError string + }{ + { + name: "No gas", + json: `{"type":"0x7e","nonce":null,"gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","from":"0x0000000000000000000000000000000000000001","isSystemTx":false,"hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`, + expectedError: "missing required field 'gas'", + }, + { + name: "No value", + json: `{"type":"0x7e","nonce":null,"gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","from":"0x0000000000000000000000000000000000000001","isSystemTx":false,"hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`, + expectedError: "missing required field 'value'", + }, + { + name: "No input", + json: `{"type":"0x7e","nonce":null,"gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","from":"0x0000000000000000000000000000000000000001","isSystemTx":false,"hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`, + expectedError: "missing required field 'input'", + }, + { + name: "No from", + json: `{"type":"0x7e","nonce":null,"gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","isSystemTx":false,"hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`, + expectedError: "missing required field 'from'", + }, + { + name: "No sourceHash", + json: `{"type":"0x7e","nonce":null,"gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"from":"0x0000000000000000000000000000000000000001","isSystemTx":false,"hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`, + expectedError: "missing required field 'sourceHash'", + }, + { + name: "No mint", + json: `{"type":"0x7e","nonce":null,"gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","from":"0x0000000000000000000000000000000000000001","isSystemTx":false,"hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`, + // Allowed + }, + { + name: "No IsSystemTx", + json: `{"type":"0x7e","nonce":null,"gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","from":"0x0000000000000000000000000000000000000001","hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`, + // Allowed + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var parsedTx = &Transaction{} + err := json.Unmarshal([]byte(test.json), &parsedTx) + if test.expectedError == "" { + require.NoError(t, err) + } else { + require.ErrorContains(t, err, test.expectedError) + } + }) + } + + tests = []struct { + name string + json string + expectedError string + }{ + { + name: "Valid deposit sender", + json: `{"type":"0x7e","nonce":"0x1","gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","from":"0x0000000000000000000000000000000000000001","hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var parsedTx = &Transaction{} + err := json.Unmarshal([]byte(test.json), &parsedTx) + require.NoError(t, err) + + signer := NewLondonSigner(big.NewInt(123)) + sender, err := signer.Sender(parsedTx) + require.NoError(t, err) + require.Equal(t, common.HexToAddress("0x1"), sender) + }) + } +}
diff --git go-ethereum/core/verkle_witness_test.go op-geth/core/verkle_witness_test.go index 02e94963c42dae31ab496a2dd45af02b8e30ae2f..cc830780568269ca1bd67ae6946872f4affbcca4 100644 --- go-ethereum/core/verkle_witness_test.go +++ op-geth/core/verkle_witness_test.go @@ -226,7 +226,7 @@ // Process n blocks, from 1 .. num var num = 2 for i := 1; i <= num; i++ { header := &types.Header{ParentHash: common.Hash{byte(i)}, Number: big.NewInt(int64(i)), Difficulty: new(big.Int)} - vmContext := NewEVMBlockContext(header, nil, new(common.Address)) + vmContext := NewEVMBlockContext(header, nil, new(common.Address), testVerkleChainConfig, statedb) evm := vm.NewEVM(vmContext, statedb, params.MergedTestChainConfig, vm.Config{}) ProcessParentBlockHash(header.ParentHash, evm) }
diff --git go-ethereum/core/vm/contracts_test.go op-geth/core/vm/contracts_test.go index b627f2ada506e5bb890875c18128a311a1c7b912..cd7803526ceb95f21c0903a1a0908b8705884fba 100644 --- go-ethereum/core/vm/contracts_test.go +++ op-geth/core/vm/contracts_test.go @@ -25,6 +25,7 @@ "testing" "time"   "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/params" )   // precompiledTest defines the input/output pairs for precompiled contract tests. @@ -54,17 +55,22 @@ common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, common.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true}, common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, - common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + common.BytesToAddress([]byte{8}): &bn256PairingGranite{}, common.BytesToAddress([]byte{9}): &blake2F{}, common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},   common.BytesToAddress([]byte{0x0f, 0x0a}): &bls12381G1Add{}, - common.BytesToAddress([]byte{0x0f, 0x0b}): &bls12381G1MultiExp{}, + common.BytesToAddress([]byte{0x0f, 0x0b}): &bls12381G1MultiExpPrague{}, + common.BytesToAddress([]byte{0x1f, 0x0b}): &bls12381G1MultiExpIsthmus{}, common.BytesToAddress([]byte{0x0f, 0x0c}): &bls12381G2Add{}, - common.BytesToAddress([]byte{0x0f, 0x0d}): &bls12381G2MultiExp{}, - common.BytesToAddress([]byte{0x0f, 0x0e}): &bls12381Pairing{}, + common.BytesToAddress([]byte{0x0f, 0x0d}): &bls12381G2MultiExpPrague{}, + common.BytesToAddress([]byte{0x1f, 0x0d}): &bls12381G2MultiExpIsthmus{}, + common.BytesToAddress([]byte{0x0f, 0x0e}): &bls12381PairingPrague{}, + common.BytesToAddress([]byte{0x1f, 0x0e}): &bls12381PairingIsthmus{}, common.BytesToAddress([]byte{0x0f, 0x0f}): &bls12381MapG1{}, common.BytesToAddress([]byte{0x0f, 0x10}): &bls12381MapG2{}, + + common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{}, }   // EIP-152 test vectors @@ -270,6 +276,38 @@ testPrecompiledFailure("09", test, t) } }   +func TestPrecompileBn256PairingTooLargeInput(t *testing.T) { + big := make([]byte, params.Bn256PairingMaxInputSizeGranite+1) + testPrecompiledFailure("08", precompiledFailureTest{ + Input: common.Bytes2Hex(big), + ExpectedError: "bad elliptic curve pairing input size", + Name: "bn256Pairing_input_too_big", + }, t) +} + +func TestPrecompileBlsInputSize(t *testing.T) { + big := make([]byte, params.Bls12381G1MulMaxInputSizeIsthmus+1) + testPrecompiledFailure("1f0b", precompiledFailureTest{ + Input: common.Bytes2Hex(big), + ExpectedError: "g1 msm input size exceeds maximum", + Name: "bls12381G1MSM_input_too_big", + }, t) + + big = make([]byte, params.Bls12381G2MulMaxInputSizeIsthmus+1) + testPrecompiledFailure("1f0d", precompiledFailureTest{ + Input: common.Bytes2Hex(big), + ExpectedError: "g2 msm input size exceeds maximum", + Name: "bls12381G2MSM_input_too_big", + }, t) + + big = make([]byte, params.Bls12381PairingMaxInputSizeIsthmus+1) + testPrecompiledFailure("1f0e", precompiledFailureTest{ + Input: common.Bytes2Hex(big), + ExpectedError: "pairing input size exceeds maximum", + Name: "bls12381Pairing_input_too_big", + }, t) +} + func TestPrecompiledEcrecover(t *testing.T) { testJson("ecRecover", "01", t) }   func testJson(name, addr string, t *testing.T) { @@ -393,3 +431,15 @@ NoBenchmark: false, } benchmarkPrecompiled("f0f", testcase, b) } + +// Benchmarks the sample inputs from the P256VERIFY precompile. +func BenchmarkPrecompiledP256Verify(bench *testing.B) { + t := precompiledTest{ + Input: "4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e", + Expected: "0000000000000000000000000000000000000000000000000000000000000001", + Name: "p256Verify", + } + benchmarkPrecompiled("100", t, bench) +} + +func TestPrecompiledP256Verify(t *testing.T) { testJson("p256Verify", "100", t) }
diff --git go-ethereum/core/vm/gas_table_test.go op-geth/core/vm/gas_table_test.go index be868852619308e7a08c540d3ff229893ff083bf..0e1e0c878bff3c9bfafc6b63b0cc33a7b8ea4279 100644 --- go-ethereum/core/vm/gas_table_test.go +++ op-geth/core/vm/gas_table_test.go @@ -117,7 +117,7 @@ gasUsed uint64 minimumGas uint64 }{ // legacy create(0, 0, 0xc000) without 3860 used - {"0x61C00060006000f0" + "600052" + "60206000F3", false, 41237, 41237}, + {"0x61C00060006000f0" + "600052" + "60206000F3", false, 41237, 41237}, //nolint:all // legacy create(0, 0, 0xc000) _with_ 3860 {"0x61C00060006000f0" + "600052" + "60206000F3", true, 44309, 44309}, // create2(0, 0, 0xc001, 0) without 3860
diff --git go-ethereum/crypto/signify/signify_test.go op-geth/crypto/signify/signify_test.go index 9bac2c825f2c844bff70f7566bbe3d953a16f583..56195649dfb3b2ccfcc3e5239bae8bd33d28796a 100644 --- go-ethereum/crypto/signify/signify_test.go +++ op-geth/crypto/signify/signify_test.go @@ -48,7 +48,7 @@ if err = tmpFile.Close(); err != nil { t.Fatal(err) }   - err = SignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "clé", "croissants") + err = SignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "clé", "croissants") //nolint:all if err != nil { t.Fatal(err) }
diff --git go-ethereum/eth/api_debug_test.go op-geth/eth/api_debug_test.go index 02b85f69fde28faffbfef5ece2270076525e4bd3..2edd2082dce2a7f722a7a1bce940cffdd73da1d7 100644 --- go-ethereum/eth/api_debug_test.go +++ op-geth/eth/api_debug_test.go @@ -19,6 +19,7 @@ import ( "bytes" "fmt" + "math/big" "reflect" "slices" "strings" @@ -26,13 +27,18 @@ "testing"   "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/triedb" "github.com/holiman/uint256" + "github.com/stretchr/testify/require" )   var dumper = spew.ConfigState{Indent: " "} @@ -224,3 +230,30 @@ test.start, test.limit, dumper.Sdump(result), dumper.Sdump(&test.want)) } } } + +func TestExecutionWitness(t *testing.T) { + t.Parallel() + + // Create a database pre-initialize with a genesis block + db := rawdb.NewMemoryDatabase() + gspec := &core.Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{testAddr: {Balance: big.NewInt(1000000)}}, + } + chain, _ := core.NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil) + + blockNum := 10 + _, bs, _ := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), blockNum, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + + block := chain.GetBlockByNumber(uint64(blockNum - 1)) + require.NotNil(t, block) + + witness, err := generateWitness(chain, block) + require.NoError(t, err) + + _, _, err = core.ExecuteStateless(params.TestChainConfig, *chain.GetVMConfig(), block, witness) + require.NoError(t, err) +}
diff --git go-ethereum/eth/catalyst/api_test.go op-geth/eth/catalyst/api_test.go index e0a155f12b8d4cb2b054d30029d039305fb78601..52efb5d2510314055558849bbc20b36106054bce 100644 --- go-ethereum/eth/catalyst/api_test.go +++ op-geth/eth/catalyst/api_test.go @@ -29,6 +29,8 @@ "sync" "testing" "time"   + "github.com/stretchr/testify/require" + "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -215,6 +217,7 @@ Random: blockParams.Random, BeaconRoot: blockParams.BeaconRoot, Version: engine.PayloadV1, }).Id() + require.NoError(t, waitForApiPayloadToBuild(api, payloadID)) execData, err := api.getPayload(payloadID, true) if err != nil { t.Fatalf("error getting payload, err=%v", err) @@ -321,7 +324,7 @@ }, 1) if err != nil { t.Fatalf("Failed to create the executable data, block %d: %v", i, err) } - block, err := engine.ExecutableDataToBlock(*execData, nil, nil, nil) + block, err := engine.ExecutableDataToBlock(*execData, nil, nil, nil, ethservice.BlockChain().Config()) if err != nil { t.Fatalf("Failed to convert executable data to block %v", err) } @@ -363,7 +366,7 @@ }) if err != nil { t.Fatalf("Failed to create the executable data %v", err) } - block, err := engine.ExecutableDataToBlock(*execData, nil, nil, nil) + block, err := engine.ExecutableDataToBlock(*execData, nil, nil, nil, ethservice.BlockChain().Config()) if err != nil { t.Fatalf("Failed to convert executable data to block %v", err) } @@ -438,6 +441,12 @@ }   // startEthService creates a full node instance for testing. func startEthService(t *testing.T, genesis *core.Genesis, blocks []*types.Block) (*node.Node, *eth.Ethereum) { + mcfg := miner.DefaultConfig + ethcfg := &ethconfig.Config{Genesis: genesis, SyncMode: ethconfig.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256, Miner: mcfg} + return startEthServiceWithConfigFn(t, blocks, ethcfg) +} + +func startEthServiceWithConfigFn(t *testing.T, blocks []*types.Block, ethcfg *ethconfig.Config) (*node.Node, *eth.Ethereum) { t.Helper()   n, err := node.New(&node.Config{ @@ -450,8 +459,7 @@ if err != nil { t.Fatal("can't create node:", err) }   - mcfg := miner.DefaultConfig - ethcfg := &ethconfig.Config{Genesis: genesis, SyncMode: ethconfig.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256, Miner: mcfg} + // OP-Stack test modification: default eth config is moved to startEthService, for reuse. ethservice, err := eth.New(n, ethcfg) if err != nil { t.Fatal("can't create eth service:", err) @@ -636,6 +644,7 @@ } if resp.PayloadStatus.Status != engine.VALID { t.Fatalf("error preparing payload, invalid status: %v", resp.PayloadStatus.Status) } + require.NoError(t, waitForApiPayloadToBuild(api, *resp.PayloadID)) // give the payload some time to be built if payload, err = api.getPayload(*resp.PayloadID, true); err != nil { t.Fatalf("can't get payload: %v", err) @@ -684,6 +693,7 @@ payload, err := api.eth.Miner().BuildPayload(args, false) if err != nil { return nil, err } + waitForPayloadToBuild(payload) return payload.ResolveFull(), nil }   @@ -934,6 +944,7 @@ payload, err := api.eth.Miner().BuildPayload(args, false) if err != nil { t.Fatalf("error preparing payload, err=%v", err) } + waitForPayloadToBuild(payload) data := *payload.Resolve().ExecutionPayload // We need to recompute the blockhash, since the miner computes a wrong (correct) blockhash txs, _ := decodeTransactions(data.Transactions) @@ -1012,7 +1023,7 @@ if testErr != nil { t.Fatal(testErr) } } - block, err := engine.ExecutableDataToBlock(*execData, nil, nil, nil) + block, err := engine.ExecutableDataToBlock(*execData, nil, nil, nil, ethservice.BlockChain().Config()) if err != nil { t.Fatalf("Failed to convert executable data to block %v", err) } @@ -1094,6 +1105,8 @@ Withdrawals: blockParams.Withdrawals, BeaconRoot: blockParams.BeaconRoot, Version: engine.PayloadV2, }).Id() + require.Equal(t, payloadID, *resp.PayloadID) + require.NoError(t, waitForApiPayloadToBuild(api, payloadID)) execData, err := api.GetPayloadV2(payloadID) if err != nil { t.Fatalf("error getting payload, err=%v", err) @@ -1128,7 +1141,8 @@ }, }, } fcState.HeadBlockHash = execData.ExecutionPayload.BlockHash - _, err = api.ForkchoiceUpdatedV2(fcState, &blockParams) + // note: diff, need latest response to get payload ID comparison right. + resp, err = api.ForkchoiceUpdatedV2(fcState, &blockParams) if err != nil { t.Fatalf("error preparing payload, err=%v", err) } @@ -1143,6 +1157,8 @@ Withdrawals: blockParams.Withdrawals, BeaconRoot: blockParams.BeaconRoot, Version: engine.PayloadV2, }).Id() + require.Equal(t, payloadID, *resp.PayloadID) + require.NoError(t, waitForApiPayloadToBuild(api, payloadID)) execData, err = api.GetPayloadV2(payloadID) if err != nil { t.Fatalf("error getting payload, err=%v", err) @@ -1282,6 +1298,8 @@ Parent: fcState.HeadBlockHash, Timestamp: test.blockParams.Timestamp, FeeRecipient: test.blockParams.SuggestedFeeRecipient, Random: test.blockParams.Random, + BeaconRoot: test.blockParams.BeaconRoot, + Withdrawals: test.blockParams.Withdrawals, Version: payloadVersion, }).Id() execData, err := api.GetPayloadV2(payloadID) @@ -1595,7 +1613,7 @@ Proofs: make([]kzg4844.Proof, 1), }, }   - block := types.NewBlock(&header, &types.Body{Transactions: txs}, nil, trie.NewStackTrie(nil)) + block := types.NewBlock(&header, &types.Body{Transactions: txs}, nil, trie.NewStackTrie(nil), types.DefaultBlockConfig) envelope := engine.BlockToExecutableData(block, nil, sidecars, nil) var want int for _, tx := range txs { @@ -1610,7 +1628,7 @@ } if got := len(envelope.BlobsBundle.Blobs); got != want { t.Fatalf("invalid number of blobs: got %v, want %v", got, want) } - _, err := engine.ExecutableDataToBlock(*envelope.ExecutionPayload, make([]common.Hash, 1), nil, nil) + _, err := engine.ExecutableDataToBlock(*envelope.ExecutionPayload, make([]common.Hash, 1), nil, nil, params.OptimismTestConfig) if err != nil { t.Error(err) } @@ -1660,6 +1678,8 @@ Withdrawals: blockParams.Withdrawals, BeaconRoot: blockParams.BeaconRoot, Version: engine.PayloadV3, }).Id() + require.Equal(t, payloadID, *resp.PayloadID) + require.NoError(t, waitForApiPayloadToBuild(api, *resp.PayloadID)) execData, err := api.GetPayloadV3(payloadID) if err != nil { t.Fatalf("error getting payload, err=%v", err) @@ -1699,6 +1719,16 @@ t.Fatalf("incorrect root stored: want %s, got %s", *blockParams.BeaconRoot, root) } }   +// OP Stack test diff: since we cut block-building short, we need to explicitly wait for a full payload to be built +func waitForPayloadToBuild(payload *miner.Payload) { + payload.WaitFull() +} + +// OP Stack test diff: see waitForPayloadToBuild +func waitForApiPayloadToBuild(api *ConsensusAPI, id engine.PayloadID) error { + return api.localBlocks.waitFull(id) +} + func TestWitnessCreationAndConsumption(t *testing.T) { //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(colorable.NewColorableStderr(), log.LevelTrace, true)))   @@ -1741,6 +1771,7 @@ Withdrawals: blockParams.Withdrawals, BeaconRoot: blockParams.BeaconRoot, Version: engine.PayloadV3, }).Id() + require.NoError(t, waitForApiPayloadToBuild(api, payloadID)) envelope, err := api.getPayload(payloadID, true) if err != nil { t.Fatalf("error getting payload, err=%v", err)
diff --git go-ethereum/eth/catalyst/superchain_test.go op-geth/eth/catalyst/superchain_test.go new file mode 100644 index 0000000000000000000000000000000000000000..7f1a04be81fda402d13c174825f6eacba4d7c3ea --- /dev/null +++ op-geth/eth/catalyst/superchain_test.go @@ -0,0 +1,118 @@ +package catalyst + +import ( + "testing" + "time" + + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/params" +) + +func TestSignalSuperchainV1(t *testing.T) { + genesis, preMergeBlocks := generateMergeChain(2, false) + n, ethservice := startEthService(t, genesis, preMergeBlocks) + defer n.Close() + api := NewConsensusAPI(ethservice) + t.Run("matching", func(t *testing.T) { + out, err := api.SignalSuperchainV1(&SuperchainSignal{ + Recommended: params.OPStackSupport, + Required: params.OPStackSupport, + }) + if err != nil { + t.Fatalf("failed to process signal: %v", err) + } + if out != params.OPStackSupport { + t.Fatalf("expected %s but got %s", params.OPStackSupport, out) + } + }) + t.Run("null_arg", func(t *testing.T) { + out, err := api.SignalSuperchainV1(nil) + if err != nil { + t.Fatalf("failed to process signal: %v", err) + } + if out != params.OPStackSupport { + t.Fatalf("expected %s but got %s", params.OPStackSupport, out) + } + }) +} + +func TestSignalSuperchainV1Halt(t *testing.T) { + // Note: depending on the params.OPStackSupport some types of bumps are not possible with active prerelease + testCases := []struct { + cfg string + bump string + halt bool + }{ + {"none", "major", false}, + {"major", "major", true}, + {"minor", "major", true}, + {"patch", "major", true}, + {"major", "minor", false}, + {"minor", "minor", true}, + {"patch", "minor", true}, + {"major", "patch", false}, + {"minor", "patch", false}, + {"patch", "patch", true}, + } + for _, tc := range testCases { + t.Run(tc.cfg+"_"+tc.bump, func(t *testing.T) { + genesis, preMergeBlocks := generateMergeChain(2, false) + ethcfg := &ethconfig.Config{Genesis: genesis, SyncMode: ethconfig.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256} + ethcfg.RollupHaltOnIncompatibleProtocolVersion = tc.cfg // opt-in to halting (or not) + n, ethservice := startEthServiceWithConfigFn(t, preMergeBlocks, ethcfg) + defer n.Close() // close at the end, regardless of any prior (failed) closing + api := NewConsensusAPI(ethservice) + _, build, major, minor, patch, preRelease := params.OPStackSupport.Parse() + if preRelease != 0 { // transform back from prerelease, so we can do a clean version bump + if patch != 0 { + patch -= 1 + } else if minor != 0 { + // can't patch-bump e.g. v3.1.0-1, the prerelease forces a minor bump: + // v3.0.999 is lower than the prerelease, v3.1.1-1 is a prerelease of v3.1.1. + if tc.bump == "patch" { + t.Skip() + } + minor -= 1 + } else if major != 0 { + if tc.bump == "minor" || tc.bump == "patch" { // can't minor-bump or patch-bump + t.Skip() + } + major -= 1 + } + preRelease = 0 + } + majorSignal, minorSignal, patchSignal := major, minor, patch + switch tc.bump { + case "major": + majorSignal += 1 + case "minor": + minorSignal += 1 + case "patch": + patchSignal += 1 + } + out, err := api.SignalSuperchainV1(&SuperchainSignal{ + Recommended: params.OPStackSupport, // required version change should be enough + Required: params.ProtocolVersionV0{Build: build, Major: majorSignal, Minor: minorSignal, Patch: patchSignal, PreRelease: preRelease}.Encode(), + }) + if err != nil { + t.Fatalf("failed to process signal: %v", err) + } + if out != params.OPStackSupport { + t.Fatalf("expected %s but got %s", params.OPStackSupport, out) + } + closeErr := n.Close() + if !tc.halt { + // assert no halt by closing, and not getting any error + if closeErr != nil { + t.Fatalf("expected not to have closed already, but just closed without error") + } + } else { + // assert halt by closing again, and seeing if we are not stopped already + if closeErr != node.ErrNodeStopped { + t.Fatalf("expected to have already closed and get a ErrNodeStopped error, but got %v", closeErr) + } + } + }) + } +}
diff --git go-ethereum/eth/downloader/downloader_test.go op-geth/eth/downloader/downloader_test.go index 47c89bf768fae1026de0ef110ea9e1e1636628ef..5f81f758af6f48502845a9f6b8a8429420f81100 100644 --- go-ethereum/eth/downloader/downloader_test.go +++ op-geth/eth/downloader/downloader_test.go @@ -76,7 +76,7 @@ tester := &downloadTester{ chain: chain, peers: make(map[string]*downloadTesterPeer), } - tester.downloader = New(db, new(event.TypeMux), tester.chain, tester.dropPeer, success) + tester.downloader = New(db, new(event.TypeMux), tester.chain, tester.dropPeer, success, 0) return tester }
diff --git go-ethereum/eth/downloader/queue_test.go op-geth/eth/downloader/queue_test.go index 857ac4813a7d334fb48ee23356b9eb992cb67d7c..863a64a8ea3e16a4570120afec7aa7da93213f27 100644 --- go-ethereum/eth/downloader/queue_test.go +++ op-geth/eth/downloader/queue_test.go @@ -97,7 +97,7 @@ func TestBasics(t *testing.T) { numOfBlocks := len(emptyChain.blocks) numOfReceipts := len(emptyChain.blocks) / 2   - q := newQueue(10, 10) + q := newQueue(nil, 10, 10) if !q.Idle() { t.Errorf("new queue should be idle") } @@ -196,7 +196,7 @@ func TestEmptyBlocks(t *testing.T) { numOfBlocks := len(emptyChain.blocks)   - q := newQueue(10, 10) + q := newQueue(nil, 10, 10)   q.Prepare(1, SnapSync)   @@ -275,7 +275,7 @@ world.progress(10) if false { log.SetDefault(log.NewLogger(slog.NewTextHandler(os.Stdout, nil))) } - q := newQueue(10, 10) + q := newQueue(nil, 10, 10) var wg sync.WaitGroup q.Prepare(1, SnapSync) wg.Add(1)
diff --git go-ethereum/eth/downloader/receiptreference_test.go op-geth/eth/downloader/receiptreference_test.go new file mode 100644 index 0000000000000000000000000000000000000000..85bc4e1aaa77aa18aafadf64bc41f0147486a455 --- /dev/null +++ op-geth/eth/downloader/receiptreference_test.go @@ -0,0 +1,108 @@ +package downloader + +import ( + "testing" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" +) + +// makeCorrection is a helper function to create a slice of receipts and a slice of corrected receipts +func makeCorrection(bn uint64, cid uint64, ns []uint64, ty []uint8) (types.Receipts, types.Receipts) { + receipts := make(types.Receipts, len(ns)) + correctedReceipts := make(types.Receipts, len(ns)) + transactions := make(types.Transactions, len(ns)) + for i := range ns { + receipts[i] = &types.Receipt{Type: ty[i], DepositNonce: &ns[i]} + correctedReceipts[i] = &types.Receipt{Type: ty[i], DepositNonce: &ns[i]} + transactions[i] = types.NewTx(&types.DepositTx{}) + } + + correctedReceipts = correctReceipts(correctedReceipts, transactions, bn, cid) + + return receipts, correctedReceipts +} + +func TestCorrectReceipts(t *testing.T) { + type testcase struct { + blockNum uint64 + chainID uint64 + nonces []uint64 + txTypes []uint8 + validate func(types.Receipts, types.Receipts) + } + + // Tests use the real reference data, so block numbers and chainIDs are selected for different test cases + testcases := []testcase{ + // Test case 1: No receipts + { + blockNum: 6825767, + chainID: 420, + nonces: []uint64{}, + txTypes: []uint8{}, + validate: func(receipts types.Receipts, correctedReceipts types.Receipts) { + assert.Empty(t, correctedReceipts) + }, + }, + // Test case 2: No deposits + { + blockNum: 6825767, + chainID: 420, + nonces: []uint64{1, 2, 3}, + txTypes: []uint8{1, 1, 1}, + validate: func(receipts types.Receipts, correctedReceipts types.Receipts) { + assert.Equal(t, receipts, correctedReceipts) + }, + }, + // Test case 3: all deposits with no correction + { + blockNum: 8835769, + chainID: 420, + nonces: []uint64{78756, 78757, 78758, 78759, 78760, 78761, 78762, 78763, 78764}, + txTypes: []uint8{126, 126, 126, 126, 126, 126, 126, 126, 126}, + validate: func(receipts types.Receipts, correctedReceipts types.Receipts) { + assert.Equal(t, receipts, correctedReceipts) + }, + }, + // Test case 4: all deposits with a correction + { + blockNum: 8835769, + chainID: 420, + nonces: []uint64{78756, 78757, 78758, 12345, 78760, 78761, 78762, 78763, 78764}, + txTypes: []uint8{126, 126, 126, 126, 126, 126, 126, 126, 126}, + validate: func(receipts types.Receipts, correctedReceipts types.Receipts) { + assert.NotEqual(t, receipts[3], correctedReceipts[3]) + for i := range receipts { + if i != 3 { + assert.Equal(t, receipts[i], correctedReceipts[i]) + } + } + }, + }, + // Test case 5: deposits with several corrections and non-deposits + { + blockNum: 8835769, + chainID: 420, + nonces: []uint64{0, 1, 2, 78759, 78760, 78761, 6, 78763, 78764, 9, 10, 11}, + txTypes: []uint8{126, 126, 126, 126, 126, 126, 126, 126, 126, 1, 1, 1}, + validate: func(receipts types.Receipts, correctedReceipts types.Receipts) { + // indexes 0, 1, 2, 6 were modified + // indexes 9, 10, 11 were added too, but they are not user deposits + assert.NotEqual(t, receipts[0], correctedReceipts[0]) + assert.NotEqual(t, receipts[1], correctedReceipts[1]) + assert.NotEqual(t, receipts[2], correctedReceipts[2]) + assert.NotEqual(t, receipts[6], correctedReceipts[6]) + for i := range receipts { + if i != 0 && i != 1 && i != 2 && i != 6 { + assert.Equal(t, receipts[i], correctedReceipts[i]) + } + } + }, + }, + } + + for _, tc := range testcases { + receipts, correctedReceipts := makeCorrection(tc.blockNum, tc.chainID, tc.nonces, tc.txTypes) + tc.validate(receipts, correctedReceipts) + } +}
diff --git go-ethereum/eth/gasprice/optimism-gasprice_test.go op-geth/eth/gasprice/optimism-gasprice_test.go new file mode 100644 index 0000000000000000000000000000000000000000..94599cdd78bb1c2901ee272ecc5faf5f0bfc1f8b --- /dev/null +++ op-geth/eth/gasprice/optimism-gasprice_test.go @@ -0,0 +1,145 @@ +// Copyright 2020 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 gasprice + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/trie" +) + +const ( + blockGasLimit = params.TxGas * 3 +) + +type testTxData struct { + priorityFee int64 + gasLimit uint64 +} + +type opTestBackend struct { + block *types.Block + receipts []*types.Receipt +} + +func (b *opTestBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { + panic("not implemented") +} + +func (b *opTestBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { + return b.block, nil +} + +func (b *opTestBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { + return b.receipts, nil +} + +func (b *opTestBackend) Pending() (*types.Block, types.Receipts, *state.StateDB) { + panic("not implemented") +} + +func (b *opTestBackend) ChainConfig() *params.ChainConfig { + return params.OptimismTestConfig +} + +func (b *opTestBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription { + return nil +} + +var _ OracleBackend = (*opTestBackend)(nil) + +func newOpTestBackend(t *testing.T, txs []testTxData) *opTestBackend { + var ( + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + signer = types.LatestSigner(params.TestChainConfig) + ) + // only the most recent block is considered for optimism priority fee suggestions, so this is + // where we add the test transactions + ts := []*types.Transaction{} + rs := []*types.Receipt{} + header := types.Header{} + header.GasLimit = blockGasLimit + var nonce uint64 + for _, tx := range txs { + txdata := &types.DynamicFeeTx{ + ChainID: params.TestChainConfig.ChainID, + Nonce: nonce, + To: &common.Address{}, + Gas: params.TxGas, + GasFeeCap: big.NewInt(100 * params.GWei), + GasTipCap: big.NewInt(tx.priorityFee), + Data: []byte{}, + } + t := types.MustSignNewTx(key, signer, txdata) + ts = append(ts, t) + r := types.Receipt{} + r.GasUsed = tx.gasLimit + header.GasUsed += r.GasUsed + rs = append(rs, &r) + nonce++ + } + hasher := trie.NewStackTrie(nil) + b := types.NewBlock(&header, &types.Body{Transactions: ts}, nil, hasher, types.DefaultBlockConfig) + return &opTestBackend{block: b, receipts: rs} +} + +func TestSuggestOptimismPriorityFee(t *testing.T) { + minSuggestion := new(big.Int).SetUint64(1e8 * params.Wei) + cases := []struct { + txdata []testTxData + want *big.Int + }{ + { + // block well under capacity, expect min priority fee suggestion + txdata: []testTxData{{params.GWei, 21000}}, + want: minSuggestion, + }, + { + // 2 txs, still under capacity, expect min priority fee suggestion + txdata: []testTxData{{params.GWei, 21000}, {params.GWei, 21000}}, + want: minSuggestion, + }, + { + // 2 txs w same priority fee (1 gwei), but second tx puts it right over capacity + txdata: []testTxData{{params.GWei, 21000}, {params.GWei, 21001}}, + want: big.NewInt(1100000000), // 10 percent over 1 gwei, the median + }, + { + // 3 txs, full block. return 10% over the median tx (10 gwei * 10% == 11 gwei) + txdata: []testTxData{{10 * params.GWei, 21000}, {1 * params.GWei, 21000}, {100 * params.GWei, 21000}}, + want: big.NewInt(11 * params.GWei), + }, + } + for i, c := range cases { + backend := newOpTestBackend(t, c.txdata) + oracle := NewOracle(backend, Config{MinSuggestedPriorityFee: minSuggestion}, big.NewInt(params.GWei)) + got := oracle.SuggestOptimismPriorityFee(context.Background(), backend.block.Header(), backend.block.Hash()) + if got.Cmp(c.want) != 0 { + t.Errorf("Gas price mismatch for test case %d: want %d, got %d", i, c.want, got) + } + } +}
diff --git go-ethereum/eth/protocols/eth/handler_test.go op-geth/eth/protocols/eth/handler_test.go index d0509f2f3ddbdbb931ce230fdabd26258c9bea5f..3e50843537f4676e42b9827e21778b9aadb51666 100644 --- go-ethereum/eth/protocols/eth/handler_test.go +++ op-geth/eth/protocols/eth/handler_test.go @@ -119,7 +119,7 @@ txconfig := legacypool.DefaultConfig txconfig.Journal = "" // Don't litter the disk with test journals   pool := legacypool.New(txconfig, chain) - txpool, _ := txpool.New(txconfig.PriceLimit, chain, []txpool.SubPool{pool}) + txpool, _ := txpool.New(txconfig.PriceLimit, chain, []txpool.SubPool{pool}, nil)   return &testBackend{ db: db,
diff --git go-ethereum/eth/tracers/internal/tracetest/flat_calltrace_test.go op-geth/eth/tracers/internal/tracetest/flat_calltrace_test.go index 553eaf1b57670793fa7558350ebd9f07469e48dc..72123bb41b5c9fdcc3cc213e109411e98488dca2 100644 --- go-ethereum/eth/tracers/internal/tracetest/flat_calltrace_test.go +++ op-geth/eth/tracers/internal/tracetest/flat_calltrace_test.go @@ -17,7 +17,6 @@ "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" - "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/tests" )   @@ -80,7 +79,7 @@ return fmt.Errorf("failed to parse testcase: %v", err) } // Configure a blockchain with the given prestate tx := new(types.Transaction) - if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil { + if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil { return fmt.Errorf("failed to parse testcase input: %v", err) } signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
diff --git go-ethereum/ethclient/example_test.go op-geth/ethclient/example_test.go index 5d0038f0c7ba2175346f0d87f1a86404b88760b5..0ba2cb8a4e66d02c4392f361954c6b4ecceb81bd 100644 --- go-ethereum/ethclient/example_test.go +++ op-geth/ethclient/example_test.go @@ -27,7 +27,7 @@ func init() { config := &node.Config{ HTTPHost: "127.0.0.1", } - n, _, err := newTestBackend(config) + n, _, err := newTestBackend(nil, config, false) if err != nil { panic("can't launch node: " + err.Error()) }
diff --git go-ethereum/internal/ethapi/api_test.go op-geth/internal/ethapi/api_test.go index 0303a0a6ea54ef72c2f75679c6dc89fe1757eac7..e22f2b11c61b9ea38081feae13841e43461c389f 100644 --- go-ethereum/internal/ethapi/api_test.go +++ op-geth/internal/ethapi/api_test.go @@ -61,6 +61,164 @@ "github.com/holiman/uint256" "github.com/stretchr/testify/require" )   +func TestNewRPCTransactionDepositTx(t *testing.T) { + tx := types.NewTx(&types.DepositTx{ + SourceHash: common.HexToHash("0x1234"), + IsSystemTransaction: true, + Mint: big.NewInt(34), + }) + nonce := uint64(7) + receipt := &types.Receipt{ + DepositNonce: &nonce, + } + got := newRPCTransaction(tx, common.Hash{}, uint64(12), uint64(1234), uint64(1), big.NewInt(0), &params.ChainConfig{}, receipt) + // Should provide zero values for unused fields that are required in other transactions + require.Equal(t, got.GasPrice, (*hexutil.Big)(big.NewInt(0)), "newRPCTransaction().GasPrice = %v, want 0x0", got.GasPrice) + require.Equal(t, got.V, (*hexutil.Big)(big.NewInt(0)), "newRPCTransaction().V = %v, want 0x0", got.V) + require.Equal(t, got.R, (*hexutil.Big)(big.NewInt(0)), "newRPCTransaction().R = %v, want 0x0", got.R) + require.Equal(t, got.S, (*hexutil.Big)(big.NewInt(0)), "newRPCTransaction().S = %v, want 0x0", got.S) + + // Should include deposit tx specific fields + require.Equal(t, *got.SourceHash, tx.SourceHash(), "newRPCTransaction().SourceHash = %v, want %v", got.SourceHash, tx.SourceHash()) + require.Equal(t, *got.IsSystemTx, tx.IsSystemTx(), "newRPCTransaction().IsSystemTx = %v, want %v", got.IsSystemTx, tx.IsSystemTx()) + require.Equal(t, got.Mint, (*hexutil.Big)(tx.Mint()), "newRPCTransaction().Mint = %v, want %v", got.Mint, tx.Mint()) + require.Equal(t, got.Nonce, (hexutil.Uint64)(nonce), "newRPCTransaction().Nonce = %v, want %v", got.Nonce, nonce) +} + +func TestRPCTransactionDepositTxWithVersion(t *testing.T) { + tx := types.NewTx(&types.DepositTx{ + SourceHash: common.HexToHash("0x1234"), + IsSystemTransaction: true, + Mint: big.NewInt(34), + }) + nonce := uint64(7) + version := types.CanyonDepositReceiptVersion + receipt := &types.Receipt{ + DepositNonce: &nonce, + DepositReceiptVersion: &version, + } + got := newRPCTransaction(tx, common.Hash{}, uint64(12), uint64(1234), uint64(1), big.NewInt(0), &params.ChainConfig{}, receipt) + // Should provide zero values for unused fields that are required in other transactions + require.Equal(t, got.GasPrice, (*hexutil.Big)(big.NewInt(0)), "newRPCTransaction().GasPrice = %v, want 0x0", got.GasPrice) + require.Equal(t, got.V, (*hexutil.Big)(big.NewInt(0)), "newRPCTransaction().V = %v, want 0x0", got.V) + require.Equal(t, got.R, (*hexutil.Big)(big.NewInt(0)), "newRPCTransaction().R = %v, want 0x0", got.R) + require.Equal(t, got.S, (*hexutil.Big)(big.NewInt(0)), "newRPCTransaction().S = %v, want 0x0", got.S) + + // Should include versioned deposit tx specific fields + require.Equal(t, *got.SourceHash, tx.SourceHash(), "newRPCTransaction().SourceHash = %v, want %v", got.SourceHash, tx.SourceHash()) + require.Equal(t, *got.IsSystemTx, tx.IsSystemTx(), "newRPCTransaction().IsSystemTx = %v, want %v", got.IsSystemTx, tx.IsSystemTx()) + require.Equal(t, got.Mint, (*hexutil.Big)(tx.Mint()), "newRPCTransaction().Mint = %v, want %v", got.Mint, tx.Mint()) + require.Equal(t, got.Nonce, (hexutil.Uint64)(nonce), "newRPCTransaction().Nonce = %v, want %v", got.Nonce, nonce) + require.Equal(t, *got.DepositReceiptVersion, (hexutil.Uint64(version)), "newRPCTransaction().DepositReceiptVersion = %v, want %v", *got.DepositReceiptVersion, version) + + // Make sure json marshal/unmarshal of the rpc tx preserves the receipt version + b, err := json.Marshal(got) + require.NoError(t, err, "marshalling failed: %w", err) + parsed := make(map[string]interface{}) + err = json.Unmarshal(b, &parsed) + require.NoError(t, err, "unmarshalling failed: %w", err) + require.Equal(t, "0x1", parsed["depositReceiptVersion"]) +} + +func TestNewRPCTransactionOmitIsSystemTxFalse(t *testing.T) { + tx := types.NewTx(&types.DepositTx{ + IsSystemTransaction: false, + }) + got := newRPCTransaction(tx, common.Hash{}, uint64(12), uint64(1234), uint64(1), big.NewInt(0), &params.ChainConfig{}, nil) + + require.Nil(t, got.IsSystemTx, "should omit IsSystemTx when false") +} + +func TestUnmarshalRpcDepositTx(t *testing.T) { + version := hexutil.Uint64(types.CanyonDepositReceiptVersion) + tests := []struct { + name string + modifier func(tx *RPCTransaction) + valid bool + }{ + { + name: "Unmodified", + modifier: func(tx *RPCTransaction) {}, + valid: true, + }, + { + name: "Zero Values", + modifier: func(tx *RPCTransaction) { + tx.V = (*hexutil.Big)(common.Big0) + tx.R = (*hexutil.Big)(common.Big0) + tx.S = (*hexutil.Big)(common.Big0) + tx.GasPrice = (*hexutil.Big)(common.Big0) + }, + valid: true, + }, + { + name: "Nil Values", + modifier: func(tx *RPCTransaction) { + tx.V = nil + tx.R = nil + tx.S = nil + tx.GasPrice = nil + }, + valid: true, + }, + { + name: "Non-Zero GasPrice", + modifier: func(tx *RPCTransaction) { + tx.GasPrice = (*hexutil.Big)(big.NewInt(43)) + }, + valid: false, + }, + { + name: "Non-Zero V", + modifier: func(tx *RPCTransaction) { + tx.V = (*hexutil.Big)(big.NewInt(43)) + }, + valid: false, + }, + { + name: "Non-Zero R", + modifier: func(tx *RPCTransaction) { + tx.R = (*hexutil.Big)(big.NewInt(43)) + }, + valid: false, + }, + { + name: "Non-Zero S", + modifier: func(tx *RPCTransaction) { + tx.S = (*hexutil.Big)(big.NewInt(43)) + }, + valid: false, + }, + { + name: "Non-nil deposit receipt version", + modifier: func(tx *RPCTransaction) { + tx.DepositReceiptVersion = &version + }, + valid: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + tx := types.NewTx(&types.DepositTx{ + SourceHash: common.HexToHash("0x1234"), + IsSystemTransaction: true, + Mint: big.NewInt(34), + }) + rpcTx := newRPCTransaction(tx, common.Hash{}, uint64(12), uint64(1234), uint64(1), big.NewInt(0), &params.ChainConfig{}, nil) + test.modifier(rpcTx) + json, err := json.Marshal(rpcTx) + require.NoError(t, err, "marshalling failed: %w", err) + parsed := &types.Transaction{} + err = parsed.UnmarshalJSON(json) + if test.valid { + require.NoError(t, err, "unmarshal failed: %w", err) + } else { + require.Error(t, err, "unmarshal should have failed but did not") + } + }) + } +} + func testTransactionMarshal(t *testing.T, tests []txData, config *params.ChainConfig) { var ( signer = types.LatestSigner(config) @@ -83,7 +241,7 @@ t.Fatalf("test %d: stx changed, want %x have %x", i, want, have) }   // rpcTransaction - rpcTx := newRPCTransaction(tx, common.Hash{}, 0, 0, 0, nil, config) + rpcTx := newRPCTransaction(tx, common.Hash{}, 0, 0, 0, nil, config, nil) if data, err := json.Marshal(rpcTx); err != nil { t.Fatalf("test %d: marshalling failed; %v", i, err) } else if err = tx2.UnmarshalJSON(data); err != nil { @@ -575,7 +733,7 @@ func (b testBackend) GetEVM(ctx context.Context, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockContext *vm.BlockContext) *vm.EVM { if vmConfig == nil { vmConfig = b.chain.GetVMConfig() } - context := core.NewEVMBlockContext(header, b.chain, nil) + context := core.NewEVMBlockContext(header, b.chain, nil, b.ChainConfig(), state) if blockContext != nil { context = *blockContext } @@ -622,6 +780,12 @@ panic("implement me") } func (b testBackend) BloomStatus() (uint64, uint64) { panic("implement me") } func (b testBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) { + panic("implement me") +} +func (b testBackend) HistoricalRPCService() *rpc.Client { + panic("implement me") +} +func (b testBackend) Genesis() *types.Block { panic("implement me") }   @@ -941,7 +1105,7 @@ From: &accounts[0].addr, To: &accounts[1].addr, Value: (*hexutil.Big)(big.NewInt(1000)), }, - expectErr: errors.New("header not found"), + expectErr: ethereum.NotFound, }, // transfer on the latest block { @@ -2379,8 +2543,11 @@ t.Fatalf("failed to fill tx defaults: %v\n", err) }   _, err = api.SignTransaction(context.Background(), argsFromTransaction(res.Tx, b.acc.Address)) - if err != nil { - t.Fatalf("should not fail on blob transaction") + if err == nil { + t.Fatalf("should fail on blob transaction") + } + if !errors.Is(err, errBlobTxNotSupported) { + t.Errorf("error mismatch. Have: %v, want: %v", err, errBlobTxNotSupported) } }   @@ -2714,7 +2881,7 @@ }) } txs = append(txs, tx) } - block := types.NewBlock(&types.Header{Number: big.NewInt(100)}, &types.Body{Transactions: txs}, nil, blocktest.NewHasher()) + block := types.NewBlock(&types.Header{Number: big.NewInt(100)}, &types.Body{Transactions: txs}, nil, blocktest.NewHasher(), types.DefaultBlockConfig)   var testSuite = []struct { inclTx bool @@ -2832,7 +2999,7 @@ "to": "0x0000000000000000000000000000000000000011", "transactionIndex": "0x1", "value": "0x6f", "type": "0x0", - "chainId": "0x7fffffffffffffee", + "chainId": "0x1", "v": "0x0", "r": "0x0", "s": "0x0" @@ -2870,7 +3037,7 @@ "to": "0x0000000000000000000000000000000000000011", "transactionIndex": "0x3", "value": "0x6f", "type": "0x0", - "chainId": "0x7fffffffffffffee", + "chainId": "0x1", "v": "0x0", "r": "0x0", "s": "0x0" @@ -2883,7 +3050,11 @@ }, }   for i, tc := range testSuite { - resp := RPCMarshalBlock(block, tc.inclTx, tc.fullTx, params.MainnetChainConfig) + resp, err := RPCMarshalBlock(context.Background(), block, tc.inclTx, tc.fullTx, params.MainnetChainConfig, testBackend{}) + if err != nil { + t.Errorf("test %d: got error %v", i, err) + continue + } out, err := json.Marshal(resp) if err != nil { t.Errorf("test %d: json marshal error: %v", i, err) @@ -2925,7 +3096,7 @@ Validator: 1, Address: common.Address{0x12, 0x34}, Amount: 10, } - pending = types.NewBlock(&types.Header{Number: big.NewInt(11), Time: 42}, &types.Body{Transactions: types.Transactions{tx}, Withdrawals: types.Withdrawals{withdrawal}}, nil, blocktest.NewHasher()) + pending = types.NewBlock(&types.Header{Number: big.NewInt(11), Time: 42}, &types.Body{Transactions: types.Transactions{tx}, Withdrawals: types.Withdrawals{withdrawal}}, nil, blocktest.NewHasher(), types.DefaultBlockConfig) ) backend := newTestBackend(t, genBlocks, genesis, ethash.NewFaker(), func(i int, b *core.BlockGen) { // Transfer from account[0] to account[1]
diff --git go-ethereum/params/config_test.go op-geth/params/config_test.go index f658c336dc3ae7c3f02980ceecd5b5ca9c450278..609ac3c05a875af41e3712a992a70a7a6f6d18ef 100644 --- go-ethereum/params/config_test.go +++ op-geth/params/config_test.go @@ -17,6 +17,7 @@ package params   import ( + "fmt" "math" "math/big" "reflect" @@ -32,6 +33,8 @@ stored, new *ChainConfig headBlock uint64 headTimestamp uint64 wantErr *ConfigCompatError + + genesisTimestamp *uint64 } tests := []test{ {stored: AllEthashProtocolChanges, new: AllEthashProtocolChanges, headBlock: 0, headTimestamp: 0, wantErr: nil}, @@ -110,13 +113,70 @@ NewTime: newUint64(20), RewindToTime: 9, }, }, + { + stored: &ChainConfig{CanyonTime: newUint64(10)}, + new: &ChainConfig{CanyonTime: newUint64(20)}, + headTimestamp: 25, + genesisTimestamp: newUint64(2), + wantErr: &ConfigCompatError{ + What: "Canyon fork timestamp", + StoredTime: newUint64(10), + NewTime: newUint64(20), + RewindToTime: 9, + }, + }, + { + stored: &ChainConfig{CanyonTime: newUint64(10)}, + new: &ChainConfig{CanyonTime: newUint64(20)}, + headTimestamp: 25, + genesisTimestamp: nil, + wantErr: &ConfigCompatError{ + What: "Canyon fork timestamp", + StoredTime: newUint64(10), + NewTime: newUint64(20), + RewindToTime: 9, + }, + }, + { + stored: &ChainConfig{CanyonTime: newUint64(10)}, + new: &ChainConfig{CanyonTime: newUint64(20)}, + headTimestamp: 25, + genesisTimestamp: newUint64(24), + wantErr: nil, + }, + { + stored: &ChainConfig{HoloceneTime: newUint64(10)}, + new: &ChainConfig{HoloceneTime: newUint64(20)}, + headTimestamp: 25, + genesisTimestamp: newUint64(15), + wantErr: &ConfigCompatError{ + What: "Holocene fork timestamp", + StoredTime: newUint64(10), + NewTime: newUint64(20), + RewindToTime: 9, + }, + }, + { + stored: &ChainConfig{HoloceneTime: newUint64(10)}, + new: &ChainConfig{HoloceneTime: newUint64(20)}, + headTimestamp: 15, + genesisTimestamp: newUint64(5), + wantErr: &ConfigCompatError{ + What: "Holocene fork timestamp", + StoredTime: newUint64(10), + NewTime: newUint64(20), + RewindToTime: 9, + }, + }, }   - for _, test := range tests { - err := test.stored.CheckCompatible(test.new, test.headBlock, test.headTimestamp) - if !reflect.DeepEqual(err, test.wantErr) { - t.Errorf("error mismatch:\nstored: %v\nnew: %v\nheadBlock: %v\nheadTimestamp: %v\nerr: %v\nwant: %v", test.stored, test.new, test.headBlock, test.headTimestamp, err, test.wantErr) - } + for i, test := range tests { + t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) { + err := test.stored.CheckCompatible(test.new, test.headBlock, test.headTimestamp, test.genesisTimestamp) + if !reflect.DeepEqual(err, test.wantErr) { + t.Errorf("error mismatch:\nstored: %v\nnew: %v\nheadBlock: %v\nheadTimestamp: %v\nerr: %v\nwant: %v", test.stored, test.new, test.headBlock, test.headTimestamp, err, test.wantErr) + } + }) } }   @@ -155,3 +215,23 @@ require.Equal(t, newTimestampCompatError(errWhat, newUint64(0), newUint64(1681338455)).Error(), "mismatching Shanghai fork timestamp in database (have timestamp 0, want timestamp 1681338455, rewindto timestamp 0)") } + +func TestConfigRulesRegolith(t *testing.T) { + c := &ChainConfig{ + RegolithTime: newUint64(500), + LondonBlock: new(big.Int), + Optimism: &OptimismConfig{}, + } + var stamp uint64 + if r := c.Rules(big.NewInt(0), true, stamp); r.IsOptimismRegolith { + t.Errorf("expected %v to not be regolith", stamp) + } + stamp = 500 + if r := c.Rules(big.NewInt(0), true, stamp); !r.IsOptimismRegolith { + t.Errorf("expected %v to be regolith", stamp) + } + stamp = math.MaxInt64 + if r := c.Rules(big.NewInt(0), true, stamp); !r.IsOptimismRegolith { + t.Errorf("expected %v to be regolith", stamp) + } +}
diff --git go-ethereum/params/superchain_test.go op-geth/params/superchain_test.go new file mode 100644 index 0000000000000000000000000000000000000000..953b614e65a12a196fe6f6ae30080c71a198d0ab --- /dev/null +++ op-geth/params/superchain_test.go @@ -0,0 +1,171 @@ +package params + +import ( + "fmt" + "testing" +) + +type HumanProtocolVersion struct { + VersionType uint8 + Major, Minor, Patch uint32 + Prerelease uint32 + Build [8]byte +} + +type ComparisonCase struct { + A, B HumanProtocolVersion + Cmp ProtocolVersionComparison +} + +func TestProtocolVersion_Compare(t *testing.T) { + testCases := []ComparisonCase{ + { + A: HumanProtocolVersion{0, 2, 1, 1, 1, [8]byte{}}, + B: HumanProtocolVersion{0, 1, 2, 2, 2, [8]byte{}}, + Cmp: AheadMajor, + }, + { + A: HumanProtocolVersion{0, 1, 2, 1, 1, [8]byte{}}, + B: HumanProtocolVersion{0, 1, 1, 2, 2, [8]byte{}}, + Cmp: AheadMinor, + }, + { + A: HumanProtocolVersion{0, 1, 1, 2, 1, [8]byte{}}, + B: HumanProtocolVersion{0, 1, 1, 1, 2, [8]byte{}}, + Cmp: AheadPatch, + }, + { + A: HumanProtocolVersion{0, 1, 1, 1, 2, [8]byte{}}, + B: HumanProtocolVersion{0, 1, 1, 1, 1, [8]byte{}}, + Cmp: AheadPrerelease, + }, + { + A: HumanProtocolVersion{0, 1, 2, 3, 4, [8]byte{}}, + B: HumanProtocolVersion{0, 1, 2, 3, 4, [8]byte{}}, + Cmp: Matching, + }, + { + A: HumanProtocolVersion{0, 3, 2, 1, 5, [8]byte{3}}, + B: HumanProtocolVersion{1, 1, 2, 3, 3, [8]byte{6}}, + Cmp: DiffVersionType, + }, + { + A: HumanProtocolVersion{0, 3, 2, 1, 5, [8]byte{3}}, + B: HumanProtocolVersion{0, 1, 2, 3, 3, [8]byte{6}}, + Cmp: DiffBuild, + }, + { + A: HumanProtocolVersion{0, 0, 0, 0, 0, [8]byte{}}, + B: HumanProtocolVersion{0, 1, 3, 3, 3, [8]byte{3}}, + Cmp: EmptyVersion, + }, + { + A: HumanProtocolVersion{0, 4, 0, 0, 0, [8]byte{}}, + B: HumanProtocolVersion{0, 4, 0, 0, 1, [8]byte{}}, + Cmp: AheadMajor, + }, + { + A: HumanProtocolVersion{0, 4, 1, 0, 0, [8]byte{}}, + B: HumanProtocolVersion{0, 4, 1, 0, 1, [8]byte{}}, + Cmp: AheadMinor, + }, + { + A: HumanProtocolVersion{0, 4, 0, 1, 0, [8]byte{}}, + B: HumanProtocolVersion{0, 4, 0, 1, 1, [8]byte{}}, + Cmp: AheadPatch, + }, + { + A: HumanProtocolVersion{0, 4, 0, 0, 2, [8]byte{}}, + B: HumanProtocolVersion{0, 4, 0, 0, 1, [8]byte{}}, + Cmp: AheadPrerelease, + }, + { + A: HumanProtocolVersion{0, 4, 1, 0, 1, [8]byte{}}, + B: HumanProtocolVersion{0, 4, 0, 0, 0, [8]byte{}}, + Cmp: AheadPatch, + }, + { + A: HumanProtocolVersion{0, 4, 0, 1, 1, [8]byte{}}, + B: HumanProtocolVersion{0, 4, 0, 0, 0, [8]byte{}}, + Cmp: AheadPrerelease, + }, + { + A: HumanProtocolVersion{0, 4, 1, 1, 1, [8]byte{}}, + B: HumanProtocolVersion{0, 4, 0, 0, 0, [8]byte{}}, + Cmp: AheadMinor, + }, + { + A: HumanProtocolVersion{0, 4, 0, 2, 1, [8]byte{}}, + B: HumanProtocolVersion{0, 4, 0, 0, 0, [8]byte{}}, + Cmp: AheadPatch, + }, + { + A: HumanProtocolVersion{0, 5, 0, 1, 1, [8]byte{}}, + B: HumanProtocolVersion{0, 4, 0, 0, 0, [8]byte{}}, + Cmp: AheadMajor, + }, + { + A: HumanProtocolVersion{0, 1, 0, 0, 1, [8]byte{}}, + B: HumanProtocolVersion{0, 0, 9, 0, 0, [8]byte{}}, + Cmp: AheadMinor, + }, + { + A: HumanProtocolVersion{0, 0, 1, 0, 1, [8]byte{}}, + B: HumanProtocolVersion{0, 0, 0, 9, 0, [8]byte{}}, + Cmp: AheadPatch, + }, + { + A: HumanProtocolVersion{0, 1, ^uint32(0), 0, 1, [8]byte{}}, + B: HumanProtocolVersion{0, 0, 1, 0, 0, [8]byte{}}, + Cmp: InvalidVersion, + }, + } + for i, tc := range testCases { + t.Run(fmt.Sprintf("case_%d", i), func(t *testing.T) { + a := ProtocolVersionV0{tc.A.Build, tc.A.Major, tc.A.Minor, tc.A.Patch, tc.A.Prerelease}.Encode() + a[0] = tc.A.VersionType + b := ProtocolVersionV0{tc.B.Build, tc.B.Major, tc.B.Minor, tc.B.Patch, tc.B.Prerelease}.Encode() + b[0] = tc.B.VersionType + cmp := a.Compare(b) + if cmp != tc.Cmp { + t.Fatalf("expected %d but got %d", tc.Cmp, cmp) + } + switch tc.Cmp { + case AheadMajor, AheadMinor, AheadPatch, AheadPrerelease: + inv := b.Compare(a) + if inv != -tc.Cmp { + t.Fatalf("expected inverse when reversing the comparison, %d but got %d", -tc.Cmp, inv) + } + case DiffVersionType, DiffBuild, EmptyVersion, Matching: + inv := b.Compare(a) + if inv != tc.Cmp { + t.Fatalf("expected comparison reversed to hold the same, expected %d but got %d", tc.Cmp, inv) + } + } + }) + } +} +func TestProtocolVersion_String(t *testing.T) { + testCases := []struct { + version ProtocolVersion + expected string + }{ + {ProtocolVersionV0{[8]byte{}, 0, 0, 0, 0}.Encode(), "v0.0.0"}, + {ProtocolVersionV0{[8]byte{}, 0, 0, 0, 1}.Encode(), "v0.0.0-1"}, + {ProtocolVersionV0{[8]byte{}, 0, 0, 1, 0}.Encode(), "v0.0.1"}, + {ProtocolVersionV0{[8]byte{}, 4, 3, 2, 1}.Encode(), "v4.3.2-1"}, + {ProtocolVersionV0{[8]byte{}, 0, 100, 2, 0}.Encode(), "v0.100.2"}, + {ProtocolVersionV0{[8]byte{'O', 'P', '-', 'm', 'o', 'd'}, 42, 0, 2, 1}.Encode(), "v42.0.2-1+OP-mod"}, + {ProtocolVersionV0{[8]byte{'b', 'e', 't', 'a', '.', '1', '2', '3'}, 1, 0, 0, 0}.Encode(), "v1.0.0+beta.123"}, + {ProtocolVersionV0{[8]byte{'a', 'b', 1}, 42, 0, 2, 0}.Encode(), "v42.0.2+0x6162010000000000"}, // do not render invalid alpha numeric + {ProtocolVersionV0{[8]byte{1, 2, 3, 4, 5, 6, 7, 8}, 42, 0, 2, 0}.Encode(), "v42.0.2+0x0102030405060708"}, + } + for _, tc := range testCases { + t.Run(tc.expected, func(t *testing.T) { + got := tc.version.String() + if got != tc.expected { + t.Fatalf("got %q but expected %q", got, tc.expected) + } + }) + } +}
diff --git go-ethereum/rpc/client_test.go op-geth/rpc/client_test.go index 6c1a4f8f6c00fefc37f0dfec24a55c9beca16753..1cfb52ecddfe42e9b68bc37cc13ee64beffccb83 100644 --- go-ethereum/rpc/client_test.go +++ op-geth/rpc/client_test.go @@ -681,7 +681,7 @@ var ( srv = NewServer() httpsrv = httptest.NewServer(srv.WebsocketHandler(nil)) - wsURL = "ws:" + strings.TrimPrefix(httpsrv.URL, "http:") + wsURL = "ws:" + strings.TrimPrefix(httpsrv.URL, "http:") //nolint:all ) defer srv.Stop() defer httpsrv.Close()
diff --git go-ethereum/superchain/superchain_test.go op-geth/superchain/superchain_test.go new file mode 100644 index 0000000000000000000000000000000000000000..2c08bc2c2a5bb27814e145233106f039c551e11f --- /dev/null +++ op-geth/superchain/superchain_test.go @@ -0,0 +1,20 @@ +package superchain + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestGetSuperchain(t *testing.T) { + mainnet, err := GetSuperchain("mainnet") + require.NoError(t, err) + + require.Equal(t, "Mainnet", mainnet.Name) + require.Equal(t, common.HexToAddress("0x8062AbC286f5e7D9428a0Ccb9AbD71e50d93b935"), mainnet.ProtocolVersionsAddr) + require.EqualValues(t, 1, mainnet.L1.ChainID) + + _, err = GetSuperchain("not a network") + require.Error(t, err) +}
diff --git go-ethereum/tests/state_test.go op-geth/tests/state_test.go index da4b8ef79d1e24c50776b6b1a7e2f99184038820..c2544f693e7fc08f5b1c8fc8c34506f4cccdc2a3 100644 --- go-ethereum/tests/state_test.go +++ op-geth/tests/state_test.go @@ -303,7 +303,7 @@ }   // Prepare the EVM. txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase) + context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase, config, state.StateDB) context.GetHash = vmTestBlockHash context.BaseFee = baseFee evm := vm.NewEVM(context, state.StateDB, config, vmconfig)
diff --git go-ethereum/beacon/engine/gen_ed.go op-geth/beacon/engine/gen_ed.go index 0ae5a3b8f1f1e90acfb3742679218d8bd1e844fb..7e0a091c308fed1a977f9426643874a00cb261ec 100644 --- go-ethereum/beacon/engine/gen_ed.go +++ op-geth/beacon/engine/gen_ed.go @@ -35,6 +35,7 @@ Withdrawals []*types.Withdrawal `json:"withdrawals"` BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"` + WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"` } var enc ExecutableData enc.ParentHash = e.ParentHash @@ -60,6 +61,7 @@ enc.Withdrawals = e.Withdrawals enc.BlobGasUsed = (*hexutil.Uint64)(e.BlobGasUsed) enc.ExcessBlobGas = (*hexutil.Uint64)(e.ExcessBlobGas) enc.ExecutionWitness = e.ExecutionWitness + enc.WithdrawalsRoot = e.WithdrawalsRoot return json.Marshal(&enc) }   @@ -84,6 +86,7 @@ Withdrawals []*types.Withdrawal `json:"withdrawals"` BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"` + WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"` } var dec ExecutableData if err := json.Unmarshal(input, &dec); err != nil { @@ -159,6 +162,9 @@ e.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas) } if dec.ExecutionWitness != nil { e.ExecutionWitness = dec.ExecutionWitness + } + if dec.WithdrawalsRoot != nil { + e.WithdrawalsRoot = dec.WithdrawalsRoot } return nil }
diff --git go-ethereum/beacon/engine/gen_epe.go op-geth/beacon/engine/gen_epe.go index deada06166c522f740839cb7836be9066f0bd174..93eba347ca62f9ce825ed46a2548c48287473511 100644 --- go-ethereum/beacon/engine/gen_epe.go +++ op-geth/beacon/engine/gen_epe.go @@ -7,6 +7,7 @@ "encoding/json" "errors" "math/big"   + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" )   @@ -15,12 +16,13 @@ // MarshalJSON marshals as JSON. func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) { type ExecutionPayloadEnvelope struct { - ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` - BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` - BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` - Requests []hexutil.Bytes `json:"executionRequests"` - Override bool `json:"shouldOverrideBuilder"` - Witness *hexutil.Bytes `json:"witness,omitempty"` + ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` + BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` + BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` + Requests []hexutil.Bytes `json:"executionRequests"` + Override bool `json:"shouldOverrideBuilder"` + Witness *hexutil.Bytes `json:"witness,omitempty"` + ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot,omitempty"` } var enc ExecutionPayloadEnvelope enc.ExecutionPayload = e.ExecutionPayload @@ -34,18 +36,20 @@ } } enc.Override = e.Override enc.Witness = e.Witness + enc.ParentBeaconBlockRoot = e.ParentBeaconBlockRoot return json.Marshal(&enc) }   // UnmarshalJSON unmarshals from JSON. func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error { type ExecutionPayloadEnvelope struct { - ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` - BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` - BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` - Requests []hexutil.Bytes `json:"executionRequests"` - Override *bool `json:"shouldOverrideBuilder"` - Witness *hexutil.Bytes `json:"witness,omitempty"` + ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` + BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` + BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` + Requests []hexutil.Bytes `json:"executionRequests"` + Override *bool `json:"shouldOverrideBuilder"` + Witness *hexutil.Bytes `json:"witness,omitempty"` + ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot,omitempty"` } var dec ExecutionPayloadEnvelope if err := json.Unmarshal(input, &dec); err != nil { @@ -73,6 +77,9 @@ e.Override = *dec.Override } if dec.Witness != nil { e.Witness = dec.Witness + } + if dec.ParentBeaconBlockRoot != nil { + e.ParentBeaconBlockRoot = dec.ParentBeaconBlockRoot } return nil }
diff --git go-ethereum/beacon/light/request/scheduler.go op-geth/beacon/light/request/scheduler.go index e80daf805e867dee175cf6900e6e5115bf971162..242ed56d2840d9c2618e12d82b62580c52e6d59a 100644 --- go-ethereum/beacon/light/request/scheduler.go +++ op-geth/beacon/light/request/scheduler.go @@ -269,7 +269,7 @@ s.eventLock.Unlock() s.Trigger() }   -// filterEvent sorts each Event either as a request event or a server event, +// filterEvents sorts each Event either as a request event or a server event, // depending on its type. Request events are also sorted in a map based on the // module that originally initiated the request. It also ensures that no events // related to a server are returned before EvRegistered or after EvUnregistered.
diff --git go-ethereum/cmd/era/main.go op-geth/cmd/era/main.go index 8b57fd695c531d3a45282f6cfdc944b34c2d9f93..8163e659994c20b908e45bfd4401c30223d86f6e 100644 --- go-ethereum/cmd/era/main.go +++ op-geth/cmd/era/main.go @@ -29,6 +29,7 @@ "time"   "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/internal/era" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/flags" @@ -122,7 +123,11 @@ if err != nil { return fmt.Errorf("error reading block %d: %w", num, err) } // Convert block to JSON and print. - val := ethapi.RPCMarshalBlock(block, ctx.Bool(txsFlag.Name), ctx.Bool(txsFlag.Name), params.MainnetChainConfig) + // TODO: without a proper Eth API Backend, this tool isn't expected to function correctly + val, err := ethapi.RPCMarshalBlock(ctx.Context, block, ctx.Bool(txsFlag.Name), ctx.Bool(txsFlag.Name), params.MainnetChainConfig, &eth.EthAPIBackend{}) + if err != nil { + return fmt.Errorf("error marshaling block: %w", err) + } b, err := json.MarshalIndent(val, "", " ") if err != nil { return fmt.Errorf("error marshaling json: %w", err)
diff --git go-ethereum/cmd/evm/internal/t8ntool/execution.go op-geth/cmd/evm/internal/t8ntool/execution.go index 9ff5a052902788eb61f34bae5e672b968ca2db94..042f892f1f3defae5a4e63fd2cf74f0e134a431a 100644 --- go-ethereum/cmd/evm/internal/t8ntool/execution.go +++ op-geth/cmd/evm/internal/t8ntool/execution.go @@ -353,6 +353,10 @@ // EIP-7251 core.ProcessConsolidationQueue(&requests, evm) }   + if chainConfig.IsIsthmus(vmContext.Time) { + requests = [][]byte{} + } + // Commit block root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber), chainConfig.IsCancun(vmContext.BlockNumber, vmContext.Time)) if err != nil {
diff --git go-ethereum/cmd/evm/internal/t8ntool/transition.go op-geth/cmd/evm/internal/t8ntool/transition.go index e946ccddd56715353ad3f1b8e7d24de75d1be300..15b34385b1a1eff8e65842526a0bd8b3b32df558 100644 --- go-ethereum/cmd/evm/internal/t8ntool/transition.go +++ op-geth/cmd/evm/internal/t8ntool/transition.go @@ -204,7 +204,7 @@ Number: new(big.Int).SetUint64(env.Number - 1), BaseFee: env.ParentBaseFee, GasUsed: env.ParentGasUsed, GasLimit: env.ParentGasLimit, - }) + }, env.Timestamp) return nil }
diff --git go-ethereum/consensus/clique/clique.go op-geth/consensus/clique/clique.go index d31efd7445109a9531d2e7040ae1ef1dd2f9572b..d1cfc2c876cf2c6c513eae4ddc31e1556df861a7 100644 --- go-ethereum/consensus/clique/clique.go +++ op-geth/consensus/clique/clique.go @@ -298,7 +298,7 @@ return errors.New("clique does not support shanghai fork") } // Verify the non-existence of withdrawalsHash. if header.WithdrawalsHash != nil { - return fmt.Errorf("invalid withdrawalsHash: have %x, expected nil", header.WithdrawalsHash) + return fmt.Errorf("invalid withdrawalsHash: have %s, expected nil", header.WithdrawalsHash) } if chain.Config().IsCancun(header.Number, header.Time) { return errors.New("clique does not support cancun fork") @@ -591,7 +591,7 @@ // Assign the final state root to header. header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))   // Assemble and return the final block for sealing. - return types.NewBlock(header, &types.Body{Transactions: body.Transactions}, receipts, trie.NewStackTrie(nil)), nil + return types.NewBlock(header, &types.Body{Transactions: body.Transactions}, receipts, trie.NewStackTrie(nil), chain.Config()), nil }   // Authorize injects a private key into the consensus engine to mint new blocks
diff --git go-ethereum/consensus/ethash/consensus.go op-geth/consensus/ethash/consensus.go index 4f92f1282b9e20207981ba80630bbf3ece872096..4d627c045095fd71725874d802652bbea6869ff4 100644 --- go-ethereum/consensus/ethash/consensus.go +++ op-geth/consensus/ethash/consensus.go @@ -270,7 +270,7 @@ return errors.New("ethash does not support shanghai fork") } // Verify the non-existence of withdrawalsHash. if header.WithdrawalsHash != nil { - return fmt.Errorf("invalid withdrawalsHash: have %x, expected nil", header.WithdrawalsHash) + return fmt.Errorf("invalid withdrawalsHash: have %s, expected nil", header.WithdrawalsHash) } if chain.Config().IsCancun(header.Number, header.Time) { return errors.New("ethash does not support cancun fork") @@ -522,7 +522,7 @@ // Assign the final state root to header. header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))   // Header seems complete, assemble into a block and return - return types.NewBlock(header, &types.Body{Transactions: body.Transactions, Uncles: body.Uncles}, receipts, trie.NewStackTrie(nil)), nil + return types.NewBlock(header, &types.Body{Transactions: body.Transactions, Uncles: body.Uncles, Withdrawals: body.Withdrawals}, receipts, trie.NewStackTrie(nil), chain.Config()), nil }   // SealHash returns the hash of a block prior to it being sealed.
diff --git go-ethereum/consensus/misc/create2deployer.bin op-geth/consensus/misc/create2deployer.bin new file mode 100644 index 0000000000000000000000000000000000000000..b4340998287cc17bcf6f2c9eb652652c0553e8e5 Binary files /dev/null and op-geth/consensus/misc/create2deployer.bin differ
diff --git go-ethereum/consensus/misc/create2deployer.go op-geth/consensus/misc/create2deployer.go new file mode 100644 index 0000000000000000000000000000000000000000..dbbb26594ce08d482411a3e8f5b0c42171923649 --- /dev/null +++ op-geth/consensus/misc/create2deployer.go @@ -0,0 +1,39 @@ +package misc + +import ( + _ "embed" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" +) + +// The original create2deployer contract could not be deployed to Base mainnet at +// the canonical address of 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2 due to +// an accidental nonce increment from a deposit transaction. See +// https://github.com/pcaversaccio/create2deployer/issues/128 for context. This +// file applies the contract code to the canonical address manually in the Canyon +// hardfork. + +var create2DeployerAddress = common.HexToAddress("0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2") +var create2DeployerCodeHash = common.HexToHash("0xb0550b5b431e30d38000efb7107aaa0ade03d48a7198a140edda9d27134468b2") + +//go:embed create2deployer.bin +var create2DeployerCode []byte + +func init() { + testCodeHash := crypto.Keccak256Hash(create2DeployerCode) + if testCodeHash != create2DeployerCodeHash { + panic("create2deployer hash and code mismatch") + } +} + +func EnsureCreate2Deployer(c *params.ChainConfig, timestamp uint64, db vm.StateDB) { + if !c.IsOptimism() || c.CanyonTime == nil || *c.CanyonTime != timestamp { + return + } + log.Info("Setting Create2Deployer code", "address", create2DeployerAddress, "codeHash", create2DeployerCodeHash) + db.SetCode(create2DeployerAddress, create2DeployerCode) +}
diff --git go-ethereum/core/block_validator.go op-geth/core/block_validator.go index 5885df9ee230df34e564335268db2006b6d2ce80..e45e27e5032d5a956267150589d0f6fef8996f3c 100644 --- go-ethereum/core/block_validator.go +++ op-geth/core/block_validator.go @@ -73,8 +73,13 @@ // Withdrawals list must be present in body after Shanghai. if block.Withdrawals() == nil { return errors.New("missing withdrawals in block body") } - if hash := types.DeriveSha(block.Withdrawals(), trie.NewStackTrie(nil)); hash != *header.WithdrawalsHash { - return fmt.Errorf("withdrawals root hash mismatch (header value %x, calculated %x)", *header.WithdrawalsHash, hash) + if v.config.IsOptimismIsthmus(header.Time) { + if len(block.Withdrawals()) > 0 { + return errors.New("no withdrawal block-operations allowed, withdrawalsRoot is set to storage root") + } + // The withdrawalsHash is verified in ValidateState, like the state root, as verification requires state merkleization. + } else if hash := types.DeriveSha(block.Withdrawals(), trie.NewStackTrie(nil)); hash != *header.WithdrawalsHash { + return fmt.Errorf("withdrawals root hash mismatch (header value %s, calculated %s)", *header.WithdrawalsHash, hash) } } else if block.Withdrawals() != nil { // Withdrawals are not allowed prior to Shanghai fork @@ -156,6 +161,15 @@ // Validate the state root against the received state root and throw // an error if they don't match. if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root { return fmt.Errorf("invalid merkle root (remote: %x local: %x) dberr: %w", header.Root, root, statedb.Error()) + } + if v.config.IsOptimismIsthmus(block.Time()) { + if header.WithdrawalsHash == nil { + return errors.New("expected withdrawals root in OP-Stack post-Isthmus block header") + } + // Validate the withdrawals root against the L2 withdrawals storage, similar to how the StateRoot is verified. + if root := statedb.GetStorageRoot(params.OptimismL2ToL1MessagePasser); *header.WithdrawalsHash != root { + return fmt.Errorf("invalid withdrawals hash (remote: %s local: %s) dberr: %w", *header.WithdrawalsHash, root, statedb.Error()) + } } return nil }
diff --git go-ethereum/core/chain_makers.go op-geth/core/chain_makers.go index 5298874a404e40eb93109e11941e2699cbdf4a87..6039ef3306bc967d368e4560288d41449cf5d0f4 100644 --- go-ethereum/core/chain_makers.go +++ op-geth/core/chain_makers.go @@ -98,7 +98,7 @@ // SetParentBeaconRoot sets the parent beacon root field of the generated // block. func (b *BlockGen) SetParentBeaconRoot(root common.Hash) { b.header.ParentBeaconRoot = &root - blockContext := NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase) + blockContext := NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase, b.cm.config, b.statedb) ProcessBeaconBlockRoot(root, vm.NewEVM(blockContext, b.statedb, b.cm.config, vm.Config{})) }   @@ -114,7 +114,7 @@ if b.gasPool == nil { b.SetCoinbase(common.Address{}) } var ( - blockContext = NewEVMBlockContext(b.header, bc, &b.header.Coinbase) + blockContext = NewEVMBlockContext(b.header, bc, &b.header.Coinbase, b.cm.config, b.statedb) evm = vm.NewEVM(blockContext, b.statedb, b.cm.config, vmConfig) ) b.statedb.SetTxContext(tx.Hash(), len(b.txs)) @@ -232,7 +232,7 @@ // The gas limit and price should be derived from the parent h.GasLimit = parent.GasLimit if b.cm.config.IsLondon(h.Number) { - h.BaseFee = eip1559.CalcBaseFee(b.cm.config, parent) + h.BaseFee = eip1559.CalcBaseFee(b.cm.config, parent, h.Time) if !b.cm.config.IsLondon(parent.Number) { parentGasLimit := parent.GasLimit * b.cm.config.ElasticityMultiplier() h.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit) @@ -318,13 +318,18 @@ if err := ParseDepositLogs(&requests, blockLogs, b.cm.config); err != nil { panic(fmt.Sprintf("failed to parse deposit log: %v", err)) } // create EVM for system calls - blockContext := NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase) + blockContext := NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase, b.cm.config, b.statedb) evm := vm.NewEVM(blockContext, statedb, b.cm.config, vm.Config{}) // EIP-7002 ProcessWithdrawalQueue(&requests, evm) // EIP-7251 ProcessConsolidationQueue(&requests, evm) } + + if b.cm.config.IsIsthmus(b.header.Time) { + requests = [][]byte{} + } + return requests }   @@ -357,13 +362,18 @@ // Set the difficulty for clique block. The chain maker doesn't have access // to a chain, so the difficulty will be left unset (nil). Set it here to the // correct value. if b.header.Difficulty == nil { - if config.TerminalTotalDifficulty == nil { + if config.TerminalTotalDifficulty == nil && !config.IsOptimismBedrock(b.header.Number) { // Clique chain b.header.Difficulty = big.NewInt(2) } else { // Post-merge chain b.header.Difficulty = big.NewInt(0) } + } + if config.IsOptimismIsthmus(b.header.Time) { + b.withdrawals = make([]*types.Withdrawal, 0) + h := types.EmptyWithdrawalsHash + b.header.WithdrawalsHash = &h }   // Mutate the state and block according to any hard-fork specs @@ -381,7 +391,7 @@ }   if config.IsPrague(b.header.Number, b.header.Time) { // EIP-2935 - blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase) + blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase, b.cm.config, b.statedb) blockContext.Random = &common.Hash{} // enable post-merge instruction set evm := vm.NewEVM(blockContext, statedb, cm.config, vm.Config{}) ProcessParentBlockHash(b.header.ParentHash, evm) @@ -490,7 +500,7 @@ // Pre-execution system calls. if config.IsPrague(b.header.Number, b.header.Time) { // EIP-2935 - blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase) + blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase, b.cm.config, b.statedb) evm := vm.NewEVM(blockContext, statedb, cm.config, vm.Config{}) ProcessParentBlockHash(b.header.ParentHash, evm) } @@ -588,7 +598,7 @@ Time: time, }   if cm.config.IsLondon(header.Number) { - header.BaseFee = eip1559.CalcBaseFee(cm.config, parent.Header()) + header.BaseFee = eip1559.CalcBaseFee(cm.config, parent.Header(), header.Time) if !cm.config.IsLondon(parent.Number()) { parentGasLimit := parent.GasLimit() * cm.config.ElasticityMultiplier() header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
diff --git go-ethereum/core/rawdb/database.go op-geth/core/rawdb/database.go index 53418d16460acd8bb9997facb3aeb5e1d25038a8..04694619c1c8fa5aa596b02827fd8d23e910236f 100644 --- go-ethereum/core/rawdb/database.go +++ op-geth/core/rawdb/database.go @@ -231,7 +231,7 @@ printChainMetadata(db) return nil, fmt.Errorf("failed to retrieve genesis from ancient %v", err) } else if !bytes.Equal(kvgenesis, frgenesis) { printChainMetadata(db) - return nil, fmt.Errorf("genesis mismatch: %#x (leveldb) != %#x (ancients)", kvgenesis, frgenesis) + return nil, fmt.Errorf("genesis mismatch: %#x (db) != %#x (ancients)", kvgenesis, frgenesis) } // Key-value store and freezer belong to the same network. Ensure that they // are contiguous, otherwise we might end up with a non-functional freezer. @@ -249,7 +249,7 @@ } } // We are about to exit on error. Print database metadata before exiting printChainMetadata(db) - return nil, fmt.Errorf("gap in the chain between ancients [0 - #%d] and leveldb [#%d - #%d] ", + return nil, fmt.Errorf("gap in the chain between ancients [0 - #%d] and db [#%d - #%d] ", frozen-1, number, head) } // Database contains only older data than the freezer, this happens if the
diff --git go-ethereum/core/state/database.go op-geth/core/state/database.go index faf4954650bf7c016af2f2da904bc4339d451fc8..4ca475a1898467621c31b16e13ad5a3d4a2aebab 100644 --- go-ethereum/core/state/database.go +++ op-geth/core/state/database.go @@ -235,6 +235,22 @@ } return tr, nil }   +// ContractCode retrieves a particular contract's code. Returns nil if not found. +// OP-Stack diff: used to serve snap-sync from legacy DB code storage scheme. +func (db *CachingDB) ContractCode(address common.Address, codeHash common.Hash) []byte { + code, _ := db.codeCache.Get(codeHash) + if len(code) > 0 { + return code + } + code = rawdb.ReadCode(db.disk, codeHash) // tries prefix first, then reads non-prefixed key if not found + if len(code) > 0 { + db.codeCache.Add(codeHash, code) + db.codeSizeCache.Add(codeHash, len(code)) + return code + } + return nil +} + // ContractCodeWithPrefix retrieves a particular contract's code. If the // code can't be found in the cache, then check the existence with **new** // db scheme.
diff --git go-ethereum/core/stateless/encoding.go op-geth/core/stateless/encoding.go index 5f4cb0ea3c0b2e0178c2bea38f4df1b3e129d069..b5174ab58602076289f7881077232c0f1b060a2a 100644 --- go-ethereum/core/stateless/encoding.go +++ op-geth/core/stateless/encoding.go @@ -19,7 +19,9 @@ import ( "io"   + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" )   @@ -74,3 +76,33 @@ Headers []*types.Header Codes [][]byte State [][]byte } + +// ExecutionWitness is a witness json encoding for transferring across clients +// in the future, we'll probably consider using the extWitness format instead for less overhead. +// currently we're using this format for compatibility with reth and also for simplicity in terms of parsing. +type ExecutionWitness struct { + Headers []*types.Header `json:"headers"` + Codes map[string]string `json:"codes"` + State map[string]string `json:"state"` +} + +func transformMap(in map[string]struct{}) map[string]string { + out := make(map[string]string, len(in)) + for item := range in { + bytes := []byte(item) + key := crypto.Keccak256Hash(bytes).Hex() + out[key] = hexutil.Encode(bytes) + } + return out +} + +// ToExecutionWitness converts a witness to an execution witness format that is compatible with reth. +// keccak(node) => node +// keccak(bytecodes) => bytecodes +func (w *Witness) ToExecutionWitness() *ExecutionWitness { + return &ExecutionWitness{ + Headers: w.Headers, + Codes: transformMap(w.Codes), + State: transformMap(w.State), + } +}
diff --git go-ethereum/core/tracing/gen_balance_change_reason_stringer.go op-geth/core/tracing/gen_balance_change_reason_stringer.go index d3a515a12d37bb2c106d4808984f83a72840c75b..891f586715ffb06aaacfaf796dd2d168cb3a49fd 100644 --- go-ethereum/core/tracing/gen_balance_change_reason_stringer.go +++ op-geth/core/tracing/gen_balance_change_reason_stringer.go @@ -23,15 +23,25 @@ _ = x[BalanceChangeTouchAccount-11] _ = x[BalanceIncreaseSelfdestruct-12] _ = x[BalanceDecreaseSelfdestruct-13] _ = x[BalanceDecreaseSelfdestructBurn-14] + _ = x[BalanceMint-200] }   -const _BalanceChangeReason_name = "BalanceChangeUnspecifiedBalanceIncreaseRewardMineUncleBalanceIncreaseRewardMineBlockBalanceIncreaseWithdrawalBalanceIncreaseGenesisBalanceBalanceIncreaseRewardTransactionFeeBalanceDecreaseGasBuyBalanceIncreaseGasReturnBalanceIncreaseDaoContractBalanceDecreaseDaoAccountBalanceChangeTransferBalanceChangeTouchAccountBalanceIncreaseSelfdestructBalanceDecreaseSelfdestructBalanceDecreaseSelfdestructBurn" +const ( + _BalanceChangeReason_name_0 = "BalanceChangeUnspecifiedBalanceIncreaseRewardMineUncleBalanceIncreaseRewardMineBlockBalanceIncreaseWithdrawalBalanceIncreaseGenesisBalanceBalanceIncreaseRewardTransactionFeeBalanceDecreaseGasBuyBalanceIncreaseGasReturnBalanceIncreaseDaoContractBalanceDecreaseDaoAccountBalanceChangeTransferBalanceChangeTouchAccountBalanceIncreaseSelfdestructBalanceDecreaseSelfdestructBalanceDecreaseSelfdestructBurn" + _BalanceChangeReason_name_1 = "BalanceMint" +)   -var _BalanceChangeReason_index = [...]uint16{0, 24, 54, 84, 109, 138, 173, 194, 218, 244, 269, 290, 315, 342, 369, 400} +var ( + _BalanceChangeReason_index_0 = [...]uint16{0, 24, 54, 84, 109, 138, 173, 194, 218, 244, 269, 290, 315, 342, 369, 400} +)   func (i BalanceChangeReason) String() string { - if i >= BalanceChangeReason(len(_BalanceChangeReason_index)-1) { + switch { + case i <= 14: + return _BalanceChangeReason_name_0[_BalanceChangeReason_index_0[i]:_BalanceChangeReason_index_0[i+1]] + case i == 200: + return _BalanceChangeReason_name_1 + default: return "BalanceChangeReason(" + strconv.FormatInt(int64(i), 10) + ")" } - return _BalanceChangeReason_name[_BalanceChangeReason_index[i]:_BalanceChangeReason_index[i+1]] }
diff --git go-ethereum/core/tracing/hooks.go op-geth/core/tracing/hooks.go index 4343edfe86f04dbbedd3ac457df692c80f2cf68f..a884db316d358c3cd18b18ae44f6face15a85cdc 100644 --- go-ethereum/core/tracing/hooks.go +++ op-geth/core/tracing/hooks.go @@ -250,6 +250,9 @@ // BalanceDecreaseSelfdestructBurn is ether that is sent to an already self-destructed // account within the same tx (captured at end of tx). // Note it doesn't account for a self-destruct which appoints itself as recipient. BalanceDecreaseSelfdestructBurn BalanceChangeReason = 14 + + // OP-Geth specific + BalanceMint BalanceChangeReason = 200 )   // GasChangeReason is used to indicate the reason for a gas change, useful
diff --git go-ethereum/core/types/block_config.go op-geth/core/types/block_config.go new file mode 100644 index 0000000000000000000000000000000000000000..87b5fb314aa68d8a136b0dafd02c624c263ccca6 --- /dev/null +++ op-geth/core/types/block_config.go @@ -0,0 +1,18 @@ +package types + +type BlockConfig struct { + IsIsthmusEnabled bool +} + +func (bc *BlockConfig) HasOptimismWithdrawalsRoot(blockTime uint64) bool { + return bc.IsIsthmusEnabled +} + +func (bc *BlockConfig) IsIsthmus(blockTime uint64) bool { + return bc.IsIsthmusEnabled +} + +var ( + DefaultBlockConfig = &BlockConfig{IsIsthmusEnabled: false} + IsthmusBlockConfig = &BlockConfig{IsIsthmusEnabled: true} +)
diff --git go-ethereum/core/types/interoptypes/interop.go op-geth/core/types/interoptypes/interop.go new file mode 100644 index 0000000000000000000000000000000000000000..742ecefdcd71e631eea9af3f11c10a69b7ee1f38 --- /dev/null +++ op-geth/core/types/interoptypes/interop.go @@ -0,0 +1,169 @@ +package interoptypes + +import ( + "encoding/binary" + "encoding/json" + "errors" + "fmt" + "math" + + "github.com/holiman/uint256" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" +) + +var ExecutingMessageEventTopic = crypto.Keccak256Hash([]byte("ExecutingMessage(bytes32,(address,uint256,uint256,uint256,uint256))")) + +type Message struct { + Identifier Identifier `json:"identifier"` + PayloadHash common.Hash `json:"payloadHash"` +} + +func (m *Message) DecodeEvent(topics []common.Hash, data []byte) error { + if len(topics) != 2 { // event hash, indexed payloadHash + return fmt.Errorf("unexpected number of event topics: %d", len(topics)) + } + if topics[0] != ExecutingMessageEventTopic { + return fmt.Errorf("unexpected event topic %q", topics[0]) + } + if len(data) != 32*5 { + return fmt.Errorf("unexpected identifier data length: %d", len(data)) + } + take := func(length uint) []byte { + taken := data[:length] + data = data[length:] + return taken + } + takeZeroes := func(length uint) error { + for _, v := range take(length) { + if v != 0 { + return errors.New("expected zero") + } + } + return nil + } + if err := takeZeroes(12); err != nil { + return fmt.Errorf("invalid address padding: %w", err) + } + m.Identifier.Origin = common.Address(take(20)) + if err := takeZeroes(32 - 8); err != nil { + return fmt.Errorf("invalid block number padding: %w", err) + } + m.Identifier.BlockNumber = binary.BigEndian.Uint64(take(8)) + if err := takeZeroes(32 - 4); err != nil { + return fmt.Errorf("invalid log index padding: %w", err) + } + m.Identifier.LogIndex = binary.BigEndian.Uint32(take(4)) + if err := takeZeroes(32 - 8); err != nil { + return fmt.Errorf("invalid timestamp padding: %w", err) + } + m.Identifier.Timestamp = binary.BigEndian.Uint64(take(8)) + m.Identifier.ChainID.SetBytes32(take(32)) + m.PayloadHash = topics[1] + return nil +} + +func ExecutingMessagesFromLogs(logs []*types.Log) ([]Message, error) { + var executingMessages []Message + for i, l := range logs { + if l.Address == params.InteropCrossL2InboxAddress { + // ignore events that do not match this + if len(l.Topics) == 0 || l.Topics[0] != ExecutingMessageEventTopic { + continue + } + var msg Message + if err := msg.DecodeEvent(l.Topics, l.Data); err != nil { + return nil, fmt.Errorf("invalid executing message %d, tx-log %d: %w", len(executingMessages), i, err) + } + executingMessages = append(executingMessages, msg) + } + } + return executingMessages, nil +} + +type Identifier struct { + Origin common.Address + BlockNumber uint64 + LogIndex uint32 + Timestamp uint64 + ChainID uint256.Int // flat, not a pointer, to make Identifier safe as map key +} + +type identifierMarshaling struct { + Origin common.Address `json:"origin"` + BlockNumber hexutil.Uint64 `json:"blockNumber"` + LogIndex hexutil.Uint64 `json:"logIndex"` + Timestamp hexutil.Uint64 `json:"timestamp"` + ChainID hexutil.U256 `json:"chainID"` +} + +func (id Identifier) MarshalJSON() ([]byte, error) { + var enc identifierMarshaling + enc.Origin = id.Origin + enc.BlockNumber = hexutil.Uint64(id.BlockNumber) + enc.LogIndex = hexutil.Uint64(id.LogIndex) + enc.Timestamp = hexutil.Uint64(id.Timestamp) + enc.ChainID = (hexutil.U256)(id.ChainID) + return json.Marshal(&enc) +} + +func (id *Identifier) UnmarshalJSON(input []byte) error { + var dec identifierMarshaling + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + id.Origin = dec.Origin + id.BlockNumber = uint64(dec.BlockNumber) + if dec.LogIndex > math.MaxUint32 { + return fmt.Errorf("log index too large: %d", dec.LogIndex) + } + id.LogIndex = uint32(dec.LogIndex) + id.Timestamp = uint64(dec.Timestamp) + id.ChainID = (uint256.Int)(dec.ChainID) + return nil +} + +type SafetyLevel string + +func (lvl SafetyLevel) String() string { + return string(lvl) +} + +// Valid returns if the safety level is a well-formatted safety level. +func (lvl SafetyLevel) wellFormatted() bool { + switch lvl { + case Finalized, Safe, LocalSafe, CrossUnsafe, Unsafe, Invalid: + return true + default: + return false + } +} + +func (lvl SafetyLevel) MarshalText() ([]byte, error) { + return []byte(lvl), nil +} + +func (lvl *SafetyLevel) UnmarshalText(text []byte) error { + if lvl == nil { + return errors.New("cannot unmarshal into nil SafetyLevel") + } + x := SafetyLevel(text) + if !x.wellFormatted() { + return fmt.Errorf("unrecognized safety level: %q", text) + } + *lvl = x + return nil +} + +const ( + Finalized SafetyLevel = "finalized" + Safe SafetyLevel = "safe" + LocalSafe SafetyLevel = "local-safe" + CrossUnsafe SafetyLevel = "cross-unsafe" + Unsafe SafetyLevel = "unsafe" + Invalid SafetyLevel = "invalid" +)
diff --git go-ethereum/core/types/tx_setcode.go op-geth/core/types/tx_setcode.go index 894bac10a33f586367f183b3f56a6530d2f26bb5..a4a626fdf4dbbbd29eaebf79f699bba1457e07fb 100644 --- go-ethereum/core/types/tx_setcode.go +++ op-geth/core/types/tx_setcode.go @@ -193,6 +193,7 @@ func (tx *SetCodeTx) gasPrice() *big.Int { return tx.GasFeeCap.ToBig() } func (tx *SetCodeTx) value() *big.Int { return tx.Value.ToBig() } func (tx *SetCodeTx) nonce() uint64 { return tx.Nonce } func (tx *SetCodeTx) to() *common.Address { tmp := tx.To; return &tmp } +func (tx *SetCodeTx) isSystemTx() bool { return false }   func (tx *SetCodeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { if baseFee == nil {
diff --git go-ethereum/crypto/crypto.go op-geth/crypto/crypto.go index aaa5cc43a2d0ee7a5476b173b69484156f14d75d..f9979aa4bb2cb6ff7588275df9d20ddd6f7d25e5 100644 --- go-ethereum/crypto/crypto.go +++ op-geth/crypto/crypto.go @@ -178,6 +178,9 @@ x, y := S256().Unmarshal(pub) if x == nil { return nil, errInvalidPubkey } + if !S256().IsOnCurve(x, y) { + return nil, errInvalidPubkey + } return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil }
diff --git go-ethereum/eth/api_miner.go op-geth/eth/api_miner.go index 8c96f4c54aff75bfd4d5c8e34284e4f2cea338ec..31f175ffe98d647edc5ee0cb4be04e3f82621814 100644 --- go-ethereum/eth/api_miner.go +++ op-geth/eth/api_miner.go @@ -56,3 +56,10 @@ func (api *MinerAPI) SetGasLimit(gasLimit hexutil.Uint64) bool { api.e.Miner().SetGasCeil(uint64(gasLimit)) return true } + +// SetMaxDASize sets the maximum data availability size of any tx allowed in a block, and the total max l1 data size of +// the block. 0 means no maximum. +func (api *MinerAPI) SetMaxDASize(maxTxSize hexutil.Big, maxBlockSize hexutil.Big) bool { + api.e.Miner().SetMaxDASize(maxTxSize.ToInt(), maxBlockSize.ToInt()) + return true +}
diff --git go-ethereum/eth/catalyst/queue.go op-geth/eth/catalyst/queue.go index 634dc1b2e6c2520f02e74f38ba66cba649685c86..aa5ed4751cddf9dd07b36b588f83a22caddd6062 100644 --- go-ethereum/eth/catalyst/queue.go +++ op-geth/eth/catalyst/queue.go @@ -17,6 +17,7 @@ package catalyst   import ( + "errors" "sync"   "github.com/ethereum/go-ethereum/beacon/engine" @@ -89,6 +90,23 @@ return item.payload.ResolveFull() } } return nil +} + +// waitFull waits until the first full payload has been built for the specified payload id +// The method returns immediately if the payload is unknown. +func (q *payloadQueue) waitFull(id engine.PayloadID) error { + q.lock.RLock() + defer q.lock.RUnlock() + for _, item := range q.payloads { + if item == nil { + return errors.New("unknown payload") + } + if item.id == id { + item.payload.WaitFull() + return nil + } + } + return errors.New("unknown payload") }   // has checks if a particular payload is already tracked.
diff --git go-ethereum/eth/catalyst/simulated_beacon.go op-geth/eth/catalyst/simulated_beacon.go index a24ff5210119268adab2d82fd9148f00999b9bc9..546a27663917501097074a4cc60f1f05d3dc3d4a 100644 --- go-ethereum/eth/catalyst/simulated_beacon.go +++ op-geth/eth/catalyst/simulated_beacon.go @@ -187,6 +187,10 @@ if fcResponse == engine.STATUS_SYNCING { return errors.New("chain rewind prevented invocation of payload creation") }   + if err := c.engineAPI.localBlocks.waitFull(*fcResponse.PayloadID); err != nil { + return err + } + envelope, err := c.engineAPI.getPayload(*fcResponse.PayloadID, true) if err != nil { return err
diff --git go-ethereum/eth/downloader/queue.go op-geth/eth/downloader/queue.go index a1c114f0578548a915ff339939d2cc27d53c6a18..7d268177a3b644726145eab53cb6361a5b87efaa 100644 --- go-ethereum/eth/downloader/queue.go +++ op-geth/eth/downloader/queue.go @@ -122,6 +122,10 @@ v := f.pending.Load() return v&(1<<kind) == 0 }   +type OPStackChainConfig interface { + IsOptimismIsthmus(time uint64) bool +} + // queue represents hashes that are either need fetching or are being fetched type queue struct { mode SyncMode // Synchronisation mode to decide on the block parts to schedule for fetching @@ -157,10 +161,15 @@ active *sync.Cond closed bool   logTime time.Time // Time instance when status was last reported + + // opConfig is used for OP-Stack chain configuration checks. + // This may be nil if not an OP-Stack chain. + opConfig OPStackChainConfig }   // newQueue creates a new download queue for scheduling block retrieval. -func newQueue(blockCacheLimit int, thresholdInitialSize int) *queue { +// The opConfig argument may be nil, if not an OP-Stack chain. +func newQueue(opConfig OPStackChainConfig, blockCacheLimit int, thresholdInitialSize int) *queue { lock := new(sync.RWMutex) q := &queue{ headerContCh: make(chan bool, 1), @@ -170,6 +179,7 @@ receiptTaskQueue: prque.New[int64, *types.Header](nil), receiptWakeCh: make(chan bool, 1), active: sync.NewCond(lock), lock: lock, + opConfig: opConfig, } q.Reset(blockCacheLimit, thresholdInitialSize) return q @@ -806,7 +816,13 @@ } else { // non-nil hash: body must have withdrawals if withdrawalLists[index] == nil { return errInvalidBody } - if withdrawalListHashes[index] != *header.WithdrawalsHash { + if q.opConfig != nil && q.opConfig.IsOptimismIsthmus(header.Time) { + // If Isthmus, we expect an empty list of withdrawal operations, + // but the WithdrawalsHash in the header is used for the withdrawals state storage-root. + if withdrawalListHashes[index] != types.EmptyWithdrawalsHash { + return errInvalidBody + } + } else if withdrawalListHashes[index] != *header.WithdrawalsHash { return errInvalidBody } }
diff --git go-ethereum/eth/gasestimator/gasestimator.go op-geth/eth/gasestimator/gasestimator.go index a6c4718cf4a2abb3bf075d337c802e0268a2bde8..2c50dac924034663ed94049a16bf1c3bbeeb876c 100644 --- go-ethereum/eth/gasestimator/gasestimator.go +++ op-geth/eth/gasestimator/gasestimator.go @@ -219,7 +219,7 @@ // call invocation. func run(ctx context.Context, call *core.Message, opts *Options) (*core.ExecutionResult, error) { // Assemble the call and the call context var ( - evmContext = core.NewEVMBlockContext(opts.Header, opts.Chain, nil) + evmContext = core.NewEVMBlockContext(opts.Header, opts.Chain, nil, opts.Config, opts.State) dirtyState = opts.State.Copy() ) if opts.BlockOverrides != nil {
diff --git go-ethereum/eth/gasprice/feehistory.go op-geth/eth/gasprice/feehistory.go index 1e625e21c0297a8c32b6c2c584186036763e97f3..51938e04a38bf3057aa5a3e7bab3c381b8a5e0f1 100644 --- go-ethereum/eth/gasprice/feehistory.go +++ op-geth/eth/gasprice/feehistory.go @@ -91,7 +91,7 @@ if bf.results.baseFee = bf.header.BaseFee; bf.results.baseFee == nil { bf.results.baseFee = new(big.Int) } if config.IsLondon(big.NewInt(int64(bf.blockNumber + 1))) { - bf.results.nextBaseFee = eip1559.CalcBaseFee(config, bf.header) + bf.results.nextBaseFee = eip1559.CalcBaseFee(config, bf.header, bf.header.Time+1) } else { bf.results.nextBaseFee = new(big.Int) }
diff --git go-ethereum/eth/interop/interop.go op-geth/eth/interop/interop.go new file mode 100644 index 0000000000000000000000000000000000000000..ae93189ac4cca9b103eefab4284a1e2ca39db5e9 --- /dev/null +++ op-geth/eth/interop/interop.go @@ -0,0 +1,57 @@ +package interop + +import ( + "context" + "errors" + "sync" + + "github.com/ethereum/go-ethereum/core/types/interoptypes" + "github.com/ethereum/go-ethereum/rpc" +) + +type InteropClient struct { + mu sync.Mutex + client *rpc.Client + endpoint string + closed bool // don't allow lazy-dials after Close +} + +// maybeDial dials the endpoint if it was not already. +func (cl *InteropClient) maybeDial(ctx context.Context) error { + cl.mu.Lock() + defer cl.mu.Unlock() + if cl.closed { + return errors.New("client is closed") + } + if cl.client != nil { + return nil + } + rpcClient, err := rpc.DialContext(ctx, cl.endpoint) + if err != nil { + return err + } + cl.client = rpcClient + return nil +} + +func (cl *InteropClient) Close() { + cl.mu.Lock() + defer cl.mu.Unlock() + if cl.client != nil { + cl.client.Close() + } + cl.closed = true +} + +func NewInteropClient(rpcEndpoint string) *InteropClient { + return &InteropClient{endpoint: rpcEndpoint} +} + +// CheckMessages checks if the given messages meet the given minimum safety level. +func (cl *InteropClient) CheckMessages(ctx context.Context, messages []interoptypes.Message, minSafety interoptypes.SafetyLevel) error { + // we lazy-dial the endpoint, so we can start geth, and build blocks, without supervisor endpoint availability. + if err := cl.maybeDial(ctx); err != nil { // a single dial attempt is made, the next call may retry. + return err + } + return cl.client.CallContext(ctx, nil, "supervisor_checkMessages", messages, minSafety) +}
diff --git go-ethereum/eth/tracers/native/call.go op-geth/eth/tracers/native/call.go index c2247d1ce491803a6810299a39fa8236ffac4574..23dee1831b99fb83a861eb62858e83950952890a 100644 --- go-ethereum/eth/tracers/native/call.go +++ op-geth/eth/tracers/native/call.go @@ -262,6 +262,12 @@ if len(t.callstack) != 1 { return nil, errors.New("incorrect number of top-level calls") }   + if t.callstack[0].Type == vm.STOP { + t.callstack[0].Error = "failed deposit transaction" + t.callstack[0].To = nil + t.callstack[0].Gas = 0 + } + res, err := json.Marshal(t.callstack[0]) if err != nil { return nil, err
diff --git go-ethereum/eth/tracers/native/call_flat.go op-geth/eth/tracers/native/call_flat.go index e56d0111391e1d0069b7eae7fc0db32a38d80e0d..408963c89b4dec2d535a6c1bf2fa84b7c7784c1e 100644 --- go-ethereum/eth/tracers/native/call_flat.go +++ op-geth/eth/tracers/native/call_flat.go @@ -224,6 +224,12 @@ if len(t.tracer.callstack) < 1 { return nil, errors.New("invalid number of calls") }   + if t.tracer.callstack[0].Type == vm.STOP { + t.tracer.callstack[0].Error = "failed deposit transaction" + t.tracer.callstack[0].To = nil + t.tracer.callstack[0].Gas = 0 + } + flat, err := flatFromNested(&t.tracer.callstack[0], []int{}, t.config.ConvertParityErrors, t.ctx) if err != nil { return nil, err @@ -254,7 +260,7 @@ case vm.CREATE, vm.CREATE2: frame = newFlatCreate(input) case vm.SELFDESTRUCT: frame = newFlatSelfdestruct(input) - case vm.CALL, vm.STATICCALL, vm.CALLCODE, vm.DELEGATECALL: + case vm.CALL, vm.STATICCALL, vm.CALLCODE, vm.DELEGATECALL, vm.STOP: frame = newFlatCall(input) default: return nil, fmt.Errorf("unrecognized call frame type: %s", input.Type)
diff --git go-ethereum/graphql/graphql.go op-geth/graphql/graphql.go index 7af1adbb4a8e6f3b0d317f158f073d9e3a0bbe8a..9790d593b3aa2a7eb8c087955770d19b4f6dba1b 100644 --- go-ethereum/graphql/graphql.go +++ op-geth/graphql/graphql.go @@ -780,7 +780,7 @@ if !chaincfg.IsLondon(new(big.Int).Add(header.Number, common.Big1)) { return nil, nil } } - nextBaseFee := eip1559.CalcBaseFee(chaincfg, header) + nextBaseFee := eip1559.CalcBaseFee(chaincfg, header, header.Time+1) return (*hexutil.Big)(nextBaseFee), nil }
diff --git go-ethereum/internal/build/env.go op-geth/internal/build/env.go index 35b2cd6ae7b9ba1d1f0cc73d3022016acb2ac28e..6a621495ba5441adbc045f1210f1f75c98a969b0 100644 --- go-ethereum/internal/build/env.go +++ op-geth/internal/build/env.go @@ -102,6 +102,10 @@ func LocalEnv() Environment { env := applyEnvFlags(Environment{Name: "local", Repo: "ethereum/go-ethereum"})   head := readGitFile("HEAD") + if info, err := os.Stat(".git/objects"); err == nil && info.IsDir() && env.Tag == "" { + env.Tag = firstLine(RunGit("tag", "-l", "--points-at", "HEAD")) + } + if fields := strings.Fields(head); len(fields) == 2 { head = fields[1] } else { @@ -123,9 +127,6 @@ if env.Branch == "" { if head != "HEAD" { env.Branch = strings.TrimPrefix(head, "refs/heads/") } - } - if info, err := os.Stat(".git/objects"); err == nil && info.IsDir() && env.Tag == "" { - env.Tag = firstLine(RunGit("tag", "-l", "--points-at", "HEAD")) } return env }
diff --git go-ethereum/internal/ethapi/simulate.go op-geth/internal/ethapi/simulate.go index 130eaa9724586a41855c3eb6b2a1bbe333578362..baaffbafd29a004257633113fb80db368865d6f9 100644 --- go-ethereum/internal/ethapi/simulate.go +++ op-geth/internal/ethapi/simulate.go @@ -131,7 +131,10 @@ result, callResults, err := sim.processBlock(ctx, &block, headers[bi], parent, headers[:bi], timeout) if err != nil { return nil, err } - enc := RPCMarshalBlock(result, true, sim.fullTx, sim.chainConfig) + enc, err := RPCMarshalBlock(ctx, result, true, sim.fullTx, sim.chainConfig, sim.b) + if err != nil { + return nil, err + } enc["calls"] = callResults results[bi] = enc   @@ -150,7 +153,7 @@ // This is because it creates an edge case in EVM where gasPrice < baseFee. // Base fee could have been overridden. if header.BaseFee == nil { if sim.validate { - header.BaseFee = eip1559.CalcBaseFee(sim.chainConfig, parent) + header.BaseFee = eip1559.CalcBaseFee(sim.chainConfig, parent, header.Time) } else { header.BaseFee = big.NewInt(0) } @@ -165,7 +168,7 @@ excess = eip4844.CalcExcessBlobGas(0, 0) } header.ExcessBlobGas = &excess } - blockContext := core.NewEVMBlockContext(header, sim.newSimulatedChainContext(ctx, headers), nil) + blockContext := core.NewEVMBlockContext(header, sim.newSimulatedChainContext(ctx, headers), nil, sim.chainConfig, sim.state) if block.BlockOverrides.BlobBaseFee != nil { blockContext.BlobBaseFee = block.BlockOverrides.BlobBaseFee.ToInt() } @@ -221,7 +224,7 @@ } else { root = sim.state.IntermediateRoot(sim.chainConfig.IsEIP158(blockContext.BlockNumber)).Bytes() } gasUsed += result.UsedGas - receipts[i] = core.MakeReceipt(evm, result, sim.state, blockContext.BlockNumber, common.Hash{}, tx, gasUsed, root) + receipts[i] = core.MakeReceipt(evm, result, sim.state, blockContext.BlockNumber, common.Hash{}, tx, gasUsed, root, sim.chainConfig, tx.Nonce()) blobGasUsed += receipts[i].BlobGasUsed logs := tracer.Logs() callRes := simCallResult{ReturnValue: result.Return(), Logs: logs, GasUsed: hexutil.Uint64(result.UsedGas)} @@ -248,7 +251,7 @@ var withdrawals types.Withdrawals if sim.chainConfig.IsShanghai(header.Number, header.Time) { withdrawals = make([]*types.Withdrawal, 0) } - b := types.NewBlock(header, &types.Body{Transactions: txes, Withdrawals: withdrawals}, receipts, trie.NewStackTrie(nil)) + b := types.NewBlock(header, &types.Body{Transactions: txes, Withdrawals: withdrawals}, receipts, trie.NewStackTrie(nil), sim.chainConfig) repairLogs(callResults, b.Hash()) return b, callResults, nil }
diff --git go-ethereum/internal/version/version.go op-geth/internal/version/version.go index a66782727344a9305786e818801b6aa53a0a92dc..e7d43769f9fac76b9257d24ea2b9ae8f5efd5d1f 100644 --- go-ethereum/internal/version/version.go +++ op-geth/internal/version/version.go @@ -29,16 +29,26 @@ const ourPath = "github.com/ethereum/go-ethereum" // Path to our module   // Family holds the textual version string for major.minor -var Family = fmt.Sprintf("%d.%d", version.Major, version.Minor) +var Family = fmt.Sprintf("%d.%d", version.OPGethMajor, version.OPGethMinor)   // Semantic holds the textual version string for major.minor.patch. -var Semantic = fmt.Sprintf("%d.%d.%d", version.Major, version.Minor, version.Patch) +var Semantic = fmt.Sprintf("%d.%d.%d", version.OPGethMajor, version.OPGethMinor, version.OPGethPatch) + +// UpstreamGethSemantic holds the textual upstream geth version string for major.minor.patch. +var UpstreamGethSemantic = func() string { + return fmt.Sprintf("%d.%d.%d", version.Major, version.Minor, version.Patch) +}() + +// UpstreamGethWithMeta holds the textual upstream geth version string including the metadata. +var UpstreamGethWithMeta = func() string { + return UpstreamGethSemantic + "-" + version.Meta +}()   // WithMeta holds the textual version string including the metadata. var WithMeta = func() string { v := Semantic - if version.Meta != "" { - v += "-" + version.Meta + if version.OPGethMeta != "" { + v += "-" + version.OPGethMeta } return v }() @@ -48,7 +58,7 @@ vsn := WithMeta if len(gitCommit) >= 8 { vsn += "-" + gitCommit[:8] } - if (version.Meta != "stable") && (gitDate != "") { + if (version.OPGethMeta != "stable") && (gitDate != "") { vsn += "-" + gitDate } return vsn @@ -59,8 +69,8 @@ // "1.8.11-dea1ce05" for stable releases, or "1.8.13-unstable-21c059b6" for unstable // releases. func Archive(gitCommit string) string { vsn := Semantic - if version.Meta != "stable" { - vsn += "-" + version.Meta + if version.OPGethMeta != "stable" { + vsn += "-" + version.OPGethMeta } if len(gitCommit) >= 8 { vsn += "-" + gitCommit[:8]
diff --git go-ethereum/internal/web3ext/web3ext.go op-geth/internal/web3ext/web3ext.go index 8ac8f44958b000a12e31482883bf56c66e17e40f..da534d68151e9378c5c2a6fa3b44775341182fc6 100644 --- go-ethereum/internal/web3ext/web3ext.go +++ op-geth/internal/web3ext/web3ext.go @@ -639,6 +639,12 @@ call: 'miner_setGasLimit', params: 1, inputFormatter: [web3._extend.utils.fromDecimal] }), + new web3._extend.Method({ + name: 'setMaxDASize', + call: 'miner_setMaxDASize', + params: 2, + inputFormatter: [web3._extend.utils.fromDecimal, web3._extend.utils.fromDecimal] + }), ], properties: [] });
diff --git go-ethereum/node/node.go op-geth/node/node.go index ec7382e7251618b775b746654041ab651e3548a0..24905c128ef316605fcfd058b0566954d1a29e9a 100644 --- go-ethereum/node/node.go +++ op-geth/node/node.go @@ -430,6 +430,14 @@ return nil }   initAuth := func(port int, secret []byte) error { + authModules := DefaultAuthModules + if slices.Contains(n.config.HTTPModules, "miner") { + authModules = append(authModules, "miner") + } + if slices.Contains(n.config.HTTPModules, "debug") { + authModules = append(authModules, "debug") + } + // Enable auth via HTTP server := n.httpAuth if err := server.setListenAddr(n.config.AuthAddr, port); err != nil { @@ -444,7 +452,7 @@ } err := server.enableRPC(allAPIs, httpConfig{ CorsAllowedOrigins: DefaultAuthCors, Vhosts: n.config.AuthVirtualHosts, - Modules: DefaultAuthModules, + Modules: authModules, prefix: DefaultAuthPrefix, rpcEndpointConfig: sharedConfig, }) @@ -666,7 +674,7 @@ // HTTPEndpoint returns the URL of the HTTP server. Note that this URL does not // contain the JSON-RPC path prefix set by HTTPPathPrefix. func (n *Node) HTTPEndpoint() string { - return "http://" + n.http.listenAddr() + return "http://" + n.http.listenAddr() //nolint:all }   // WSEndpoint returns the current JSON-RPC over WebSocket endpoint.
diff --git go-ethereum/params/interop.go op-geth/params/interop.go new file mode 100644 index 0000000000000000000000000000000000000000..148ece53fe7a18e6183a3affa9ea7ec74fa21436 --- /dev/null +++ op-geth/params/interop.go @@ -0,0 +1,5 @@ +package params + +import "github.com/ethereum/go-ethereum/common" + +var InteropCrossL2InboxAddress = common.HexToAddress("0x4200000000000000000000000000000000000022")
diff --git go-ethereum/rpc/http.go op-geth/rpc/http.go index f4b99429ef4fedc101bb6d5b1a7073630b3982c2..58cc9b374e9d185b4d717dbcc2e10e84f7757dd6 100644 --- go-ethereum/rpc/http.go +++ op-geth/rpc/http.go @@ -33,8 +33,9 @@ "time" )   const ( - defaultBodyLimit = 5 * 1024 * 1024 - contentType = "application/json" + maxRequestContentLength = 1024 * 1024 * 32 + defaultBodyLimit = 5 * 1024 * 1024 + contentType = "application/json" )   // https://www.jsonrpc.org/historical/json-rpc-over-http.html#id13
diff --git go-ethereum/superchain-registry-commit.txt op-geth/superchain-registry-commit.txt new file mode 100644 index 0000000000000000000000000000000000000000..9d6d076ba331337ef6e1d5907d19fc28309a21b7 --- /dev/null +++ op-geth/superchain-registry-commit.txt @@ -0,0 +1 @@ +68ebaf81202ee7e21638232c54404074a49a63f6 \ No newline at end of file
diff --git go-ethereum/superchain/chain.go op-geth/superchain/chain.go new file mode 100644 index 0000000000000000000000000000000000000000..4408dc043f1e939a304e031555dd55f0bcfbba46 --- /dev/null +++ op-geth/superchain/chain.go @@ -0,0 +1,145 @@ +package superchain + +import ( + "archive/zip" + "bytes" + _ "embed" + "encoding/json" + "fmt" + "io" + "path" + "sort" + "sync" + + "github.com/BurntSushi/toml" + "github.com/klauspost/compress/zstd" +) + +//go:embed superchain-configs.zip +var configData []byte + +var configDataReader *zip.Reader + +var genesisZstdDict []byte + +var Chains = make(map[uint64]*Chain) + +var idsByName = make(map[string]uint64) + +func ChainIDByName(name string) (uint64, error) { + id, ok := idsByName[name] + if !ok { + return 0, fmt.Errorf("unknown chain %q", name) + } + return id, nil +} + +func ChainNames() []string { + var out []string + for _, ch := range Chains { + out = append(out, ch.Name+"-"+ch.Network) + } + sort.Strings(out) + return out +} + +func GetChain(chainID uint64) (*Chain, error) { + chain, ok := Chains[chainID] + if !ok { + return nil, fmt.Errorf("unknown chain ID: %d", chainID) + } + return chain, nil +} + +type Chain struct { + Name string `json:"name"` + Network string `json:"network"` + + config *ChainConfig + genesis []byte + + // The config and genesis initialization is separated + // to allow for lazy loading. Reading genesis files is + // very expensive in Cannon so we only want to do it + // when necessary. + configOnce sync.Once + genesisOnce sync.Once + err error +} + +func (c *Chain) Config() (*ChainConfig, error) { + c.configOnce.Do(c.populateConfig) + return c.config, c.err +} + +func (c *Chain) GenesisData() ([]byte, error) { + c.genesisOnce.Do(c.populateGenesis) + return c.genesis, c.err +} + +func (c *Chain) populateConfig() { + configFile, err := configDataReader.Open(path.Join("configs", c.Network, c.Name+".toml")) + if err != nil { + c.err = fmt.Errorf("error opening chain config file %s/%s: %w", c.Network, c.Name, err) + return + } + defer configFile.Close() + + var cfg ChainConfig + if _, err := toml.NewDecoder(configFile).Decode(&cfg); err != nil { + c.err = fmt.Errorf("error decoding chain config file %s/%s: %w", c.Network, c.Name, err) + return + } + c.config = &cfg +} + +func (c *Chain) populateGenesis() { + genesisFile, err := configDataReader.Open(path.Join("genesis", c.Network, c.Name+".json.zst")) + if err != nil { + c.err = fmt.Errorf("error opening compressed genesis file %s/%s: %w", c.Network, c.Name, err) + return + } + defer genesisFile.Close() + zstdR, err := zstd.NewReader(genesisFile, zstd.WithDecoderDicts(genesisZstdDict)) + if err != nil { + c.err = fmt.Errorf("error creating zstd reader for %s/%s: %w", c.Network, c.Name, err) + return + } + defer zstdR.Close() + + out, err := io.ReadAll(zstdR) + if err != nil { + c.err = fmt.Errorf("error reading genesis file for %s/%s: %w", c.Network, c.Name, err) + return + } + c.genesis = out +} + +func init() { + var err error + configDataReader, err = zip.NewReader(bytes.NewReader(configData), int64(len(configData))) + if err != nil { + panic(fmt.Errorf("opening zip reader: %w", err)) + } + dictR, err := configDataReader.Open("dictionary") + if err != nil { + panic(fmt.Errorf("error opening dictionary: %w", err)) + } + defer dictR.Close() + genesisZstdDict, err = io.ReadAll(dictR) + if err != nil { + panic(fmt.Errorf("error reading dictionary: %w", err)) + } + chainFile, err := configDataReader.Open("chains.json") + if err != nil { + panic(fmt.Errorf("error opening chains file: %w", err)) + } + defer chainFile.Close() + if err := json.NewDecoder(chainFile).Decode(&Chains); err != nil { + panic(fmt.Errorf("error decoding chains file: %w", err)) + } + + for chainID, chain := range Chains { + idsByName[chain.Name+"-"+chain.Network] = chainID + } +}
diff --git go-ethereum/superchain/superchain-configs.zip op-geth/superchain/superchain-configs.zip new file mode 100644 index 0000000000000000000000000000000000000000..66e7f88581c054f418147ecb638d37cb6ae3e787 Binary files /dev/null and op-geth/superchain/superchain-configs.zip differ
diff --git go-ethereum/superchain/superchain.go op-geth/superchain/superchain.go new file mode 100644 index 0000000000000000000000000000000000000000..375ae904bf504e6397af1e1d0c00ac89d2116a4f --- /dev/null +++ op-geth/superchain/superchain.go @@ -0,0 +1,52 @@ +package superchain + +import ( + "fmt" + "path" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/naoina/toml" +) + +type Superchain struct { + Name string `toml:"name"` + ProtocolVersionsAddr common.Address `toml:"protocol_versions_addr"` + SuperchainConfigAddr common.Address `toml:"superchain_config_addr"` + OpContractsManagerProxyAddr common.Address `toml:"op_contracts_manager_proxy_addr"` + Hardforks HardforkConfig + L1 L1Config +} + +type L1Config struct { + ChainID uint64 `toml:"chain_id"` + PublicRPC string `toml:"public_rpc"` + Explorer string `toml:"explorer"` +} + +var ( + superchainsByNetwork = map[string]Superchain{} + mtx sync.Mutex +) + +func GetSuperchain(network string) (Superchain, error) { + mtx.Lock() + defer mtx.Unlock() + + var sc Superchain + if sc, ok := superchainsByNetwork[network]; ok { + return sc, nil + } + + zr, err := configDataReader.Open(path.Join("configs", network, "superchain.toml")) + if err != nil { + return sc, err + } + + if err := toml.NewDecoder(zr).Decode(&sc); err != nil { + return sc, fmt.Errorf("error decoding superchain config: %w", err) + } + + superchainsByNetwork[network] = sc + return sc, nil +}
diff --git go-ethereum/superchain/types.go op-geth/superchain/types.go new file mode 100644 index 0000000000000000000000000000000000000000..6085b377f704075352140772eeabb8e58d397170 --- /dev/null +++ op-geth/superchain/types.go @@ -0,0 +1,110 @@ +package superchain + +import ( + "github.com/ethereum/go-ethereum/common" +) + +type ChainConfig struct { + Name string `toml:"name"` + PublicRPC string `toml:"public_rpc"` + SequencerRPC string `toml:"sequencer_rpc"` + Explorer string `toml:"explorer"` + SuperchainLevel int `toml:"superchain_level"` + GovernedByOptimism bool `toml:"governed_by_optimism"` + SuperchainTime *uint64 `toml:"superchain_time"` + DataAvailabilityType string `toml:"data_availability_type"` + DeploymentTxHash *common.Hash `toml:"deployment_tx_hash"` + + ChainID uint64 `toml:"chain_id"` + BatchInboxAddr common.Address `toml:"batch_inbox_addr"` + BlockTime uint64 `toml:"block_time"` + SeqWindowSize uint64 `toml:"seq_window_size"` + MaxSequencerDrift uint64 `toml:"max_sequencer_drift"` + GasPayingToken *common.Address `toml:"gas_paying_token"` + Hardforks HardforkConfig `toml:"hardforks"` + Optimism *OptimismConfig `toml:"optimism,omitempty"` + + AltDA *AltDAConfig `toml:"alt_da,omitempty"` + + Genesis GenesisConfig `toml:"genesis"` + + Roles RolesConfig `toml:"roles"` + + Addresses AddressesConfig `toml:"addresses"` +} + +type HardforkConfig struct { + CanyonTime *uint64 `toml:"canyon_time"` + DeltaTime *uint64 `toml:"delta_time"` + EcotoneTime *uint64 `toml:"ecotone_time"` + FjordTime *uint64 `toml:"fjord_time"` + GraniteTime *uint64 `toml:"granite_time"` + HoloceneTime *uint64 `toml:"holocene_time"` + IsthmusTime *uint64 `toml:"isthmus_time"` + JovianTime *uint64 `toml:"jovian_time"` +} + +type OptimismConfig struct { + EIP1559Elasticity uint64 `toml:"eip1559_elasticity"` + EIP1559Denominator uint64 `toml:"eip1559_denominator"` + EIP1559DenominatorCanyon *uint64 `toml:"eip1559_denominator_canyon"` +} + +type AltDAConfig struct { + DaChallengeContractAddress common.Address `toml:"da_challenge_contract_address"` + DaChallengeWindow uint64 `toml:"da_challenge_window"` + DaResolveWindow uint64 `toml:"da_resolve_window"` + DaCommitmentType string `toml:"da_commitment_type"` +} + +type GenesisConfig struct { + L2Time uint64 `toml:"l2_time"` + L1 GenesisRef `toml:"l1"` + L2 GenesisRef `toml:"l2"` + SystemConfig SystemConfig `toml:"system_config"` +} + +type GenesisRef struct { + Hash common.Hash `toml:"hash"` + Number uint64 `toml:"number"` +} + +type SystemConfig struct { + BatcherAddr common.Address `json:"batcherAddr" toml:"batcherAddress"` + Overhead common.Hash `json:"overhead" toml:"overhead"` + Scalar common.Hash `json:"scalar" toml:"scalar"` + GasLimit uint64 `json:"gasLimit" toml:"gasLimit"` + BaseFeeScalar *uint64 `json:"baseFeeScalar,omitempty" toml:"baseFeeScalar,omitempty"` + BlobBaseFeeScalar *uint64 `json:"blobBaseFeeScalar,omitempty" toml:"blobBaseFeeScalar,omitempty"` +} + +type RolesConfig struct { + SystemConfigOwner *common.Address `json:"SystemConfigOwner" toml:"SystemConfigOwner"` + ProxyAdminOwner *common.Address `json:"ProxyAdminOwner" toml:"ProxyAdminOwner"` + Guardian *common.Address `json:"Guardian" toml:"Guardian"` + Challenger *common.Address `json:"Challenger" toml:"Challenger"` + Proposer *common.Address `json:"Proposer,omitempty" toml:"Proposer,omitempty"` + UnsafeBlockSigner *common.Address `json:"UnsafeBlockSigner,omitempty" toml:"UnsafeBlockSigner,omitempty"` + BatchSubmitter *common.Address `json:"BatchSubmitter" toml:"BatchSubmitter"` +} + +type AddressesConfig struct { + AddressManager *common.Address `toml:"AddressManager,omitempty" json:"AddressManager,omitempty"` + L1CrossDomainMessengerProxy *common.Address `toml:"L1CrossDomainMessengerProxy,omitempty" json:"L1CrossDomainMessengerProxy,omitempty"` + L1ERC721BridgeProxy *common.Address `toml:"L1ERC721BridgeProxy,omitempty" json:"L1ERC721BridgeProxy,omitempty"` + L1StandardBridgeProxy *common.Address `toml:"L1StandardBridgeProxy,omitempty" json:"L1StandardBridgeProxy,omitempty"` + L2OutputOracleProxy *common.Address `toml:"L2OutputOracleProxy,omitempty" json:"L2OutputOracleProxy,omitempty"` + OptimismMintableERC20FactoryProxy *common.Address `toml:"OptimismMintableERC20FactoryProxy,omitempty" json:"OptimismMintableERC20FactoryProxy,omitempty"` + OptimismPortalProxy *common.Address `toml:"OptimismPortalProxy,omitempty" json:"OptimismPortalProxy,omitempty"` + SystemConfigProxy *common.Address `toml:"SystemConfigProxy,omitempty" json:"SystemConfigProxy,omitempty"` + ProxyAdmin *common.Address `toml:"ProxyAdmin,omitempty" json:"ProxyAdmin,omitempty"` + SuperchainConfig *common.Address `toml:"SuperchainConfig,omitempty" json:"SuperchainConfig,omitempty"` + AnchorStateRegistryProxy *common.Address `toml:"AnchorStateRegistryProxy,omitempty" json:"AnchorStateRegistryProxy,omitempty"` + DelayedWETHProxy *common.Address `toml:"DelayedWETHProxy,omitempty" json:"DelayedWETHProxy,omitempty"` + DisputeGameFactoryProxy *common.Address `toml:"DisputeGameFactoryProxy,omitempty" json:"DisputeGameFactoryProxy,omitempty"` + FaultDisputeGame *common.Address `toml:"FaultDisputeGame,omitempty" json:"FaultDisputeGame,omitempty"` + MIPS *common.Address `toml:"MIPS,omitempty" json:"MIPS,omitempty"` + PermissionedDisputeGame *common.Address `toml:"PermissionedDisputeGame,omitempty" json:"PermissionedDisputeGame,omitempty"` + PreimageOracle *common.Address `toml:"PreimageOracle,omitempty" json:"PreimageOracle,omitempty"` + DAChallengeAddress *common.Address `toml:"DAChallengeAddress,omitempty" json:"DAChallengeAddress,omitempty"` +}
diff --git go-ethereum/sync-superchain.sh op-geth/sync-superchain.sh new file mode 100755 index 0000000000000000000000000000000000000000..007f37ba1d2c1decb0a381fdcdb4763cff289841 --- /dev/null +++ op-geth/sync-superchain.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash + +# This script is used to sync superchain configs in the registry with OP Geth. + +set -euo pipefail + +# Constants +REGISTRY_COMMIT=$(cat superchain-registry-commit.txt) +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +repodir=$(mktemp -d) +workdir=$(mktemp -d) + +# Clone the registry +echo "Cloning SR..." +cd "$repodir" +git clone --no-checkout --depth 1 --shallow-submodules https://github.com/ethereum-optimism/superchain-registry.git +cd "$repodir/superchain-registry" +git fetch --depth 1 origin "$REGISTRY_COMMIT" +git checkout "$REGISTRY_COMMIT" + +echo "Copying configs..." +cp -r superchain/configs "$workdir/configs" +cp -r superchain/extra/genesis "$workdir/genesis" +cp -r superchain/extra/dictionary "$workdir/dictionary" + +cd "$workdir" +echo "Using $workdir as workdir..." + +# Create a simple mapping of chain id -> config name to make looking up chains by their ID easier. +echo "Generating index of configs..." + +echo "{}" > chains.json + +# Function to process each network directory +process_network_dir() { + local network_dir="$1" + local network_name=$(basename "$network_dir") + + echo "Processing chains in $network_name superchain..." + + # Find all TOML files in the network directory + find "$network_dir" -type f -name "*.toml" | LC_ALL=C sort | while read -r toml_file; do + if [[ "$toml_file" == "configs/$network_name/superchain.toml" ]]; then + continue + fi + + echo "Processing $toml_file..." + # Extract chain_id from TOML file using dasel + chain_id=$(dasel -f "$toml_file" -r toml "chain_id" | tr -d '"') + + # Skip if chain_id is empty + if [ -z "$chain_id" ]; then + continue + fi + + # Create JSON object for this config + config_json=$(jq -n \ + --arg name "$(basename "${toml_file%.*}")" \ + --arg network "$network_name" \ + '{ + "name": $name, + "network": $network + }') + + # Add this config to the result JSON using the chain_id as the key + jq --argjson config "$config_json" \ + --arg chain_id "$chain_id" \ + '. + {($chain_id): $config}' chains.json > temp.json + mv temp.json chains.json + done +} + +# Process each network directory in configs +for network_dir in configs/*; do + if [ -d "$network_dir" ]; then + process_network_dir "$network_dir" + fi +done + +# Archive the genesis configs as a ZIP file. ZIP is used since it can be efficiently used as a filesystem. +echo "Archiving configs..." +echo "$REGISTRY_COMMIT" > COMMIT +# We need to normalize the lastmod dates and permissions to ensure the ZIP file is deterministic. +find . -exec touch -t 198001010000.00 {} + +chmod -R 755 ./* +files=$(find . -type f | LC_ALL=C sort) +echo -n "$files" | xargs zip -9 -oX --quiet superchain-configs.zip +zipinfo superchain-configs.zip +mv superchain-configs.zip "$SCRIPT_DIR/superchain/superchain-configs.zip" + +echo "Cleaning up..." +rm -rf "$repodir" +rm -rf "$workdir" + +echo "Done." \ No newline at end of file
diff --git go-ethereum/tests/state_test_util.go op-geth/tests/state_test_util.go index e658b62ebf1882c8c012e4da265868ef219c7113..5c75680cee3927647e67c9a949a427695a5f0d0b 100644 --- go-ethereum/tests/state_test_util.go +++ op-geth/tests/state_test_util.go @@ -299,7 +299,7 @@ } }   // Prepare the EVM. - context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase) + context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase, config, st.StateDB) context.GetHash = vmTestBlockHash context.BaseFee = baseFee context.Random = nil
diff --git go-ethereum/version/version.go op-geth/version/version.go index 52dfa0281e54ea4b1ec2f2cadd63f0764a1f57e0..107660f99e3724d9e0548fae4f3f211aeb322e72 100644 --- go-ethereum/version/version.go +++ op-geth/version/version.go @@ -16,9 +16,43 @@ // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.   package version   +import ( + "regexp" + "strconv" +) + +// Upstream geth version const ( Major = 1 // Major version component of the current release Minor = 14 // Minor version component of the current release Patch = 13 // Patch version component of the current release Meta = "unstable" // Version metadata to append to the version string ) + +// OPGeth is the version of op-geth +var ( + OPGethMajor = 0 // Major version component of the current release + OPGethMinor = 1 // Minor version component of the current release + OPGethPatch = 0 // Patch version component of the current release + OPGethMeta = "untagged" // Version metadata to append to the version string +) + +// This is set at build-time by the linker when the build is done by build/ci.go. +var gitTag string + +// Override the version variables if the gitTag was set at build time. +var _ = func() (_ string) { + semver := regexp.MustCompile(`^v([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?$`) + version := semver.FindStringSubmatch(gitTag) + if version == nil { + return + } + if version[4] == "" { + version[4] = "stable" + } + OPGethMajor, _ = strconv.Atoi(version[1]) + OPGethMinor, _ = strconv.Atoi(version[2]) + OPGethPatch, _ = strconv.Atoi(version[3]) + OPGethMeta = version[4] + return +}()
diff --git go-ethereum/.circleci/ci-docker-tag-op-geth-release.sh op-geth/.circleci/ci-docker-tag-op-geth-release.sh new file mode 100755 index 0000000000000000000000000000000000000000..376e8752e13274350f0bc832e33947e14e74537e --- /dev/null +++ op-geth/.circleci/ci-docker-tag-op-geth-release.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +set -euo pipefail + +DOCKER_REPO=$1 +GIT_TAG=$2 +GIT_SHA=$3 + +IMAGE_NAME="op-geth" +IMAGE_TAG=$GIT_TAG + +SOURCE_IMAGE_TAG="$DOCKER_REPO/$IMAGE_NAME:$GIT_SHA" +TARGET_IMAGE_TAG="$DOCKER_REPO/$IMAGE_NAME:$IMAGE_TAG" +TARGET_IMAGE_TAG_LATEST="$DOCKER_REPO/$IMAGE_NAME:latest" + +echo "Checking if docker images exist for '$IMAGE_NAME'" +echo "" +tags=$(gcloud container images list-tags "$DOCKER_REPO/$IMAGE_NAME" --limit 1 --format json) +if [ "$tags" = "[]" ]; then + echo "No existing docker images were found for '$IMAGE_NAME'. The code tagged with '$GIT_TAG' may not have an associated dockerfile or docker build job." + echo "If this service has a dockerfile, add a docker-publish job for it in the circleci config." + echo "" + echo "Exiting" + exit 0 +fi + +echo "Tagging $SOURCE_IMAGE_TAG with '$IMAGE_TAG'" +gcloud container images add-tag -q "$SOURCE_IMAGE_TAG" "$TARGET_IMAGE_TAG" + +# Only tag finalized releases with 'latest' +if ! [[ "$IMAGE_TAG" =~ ^v1\.[0-9]+\.[0-9]+$ ]]; then + echo "Not tagging with 'latest' because the release is not finalized." + exit 0 +fi + +echo "Tagging $SOURCE_IMAGE_TAG with 'latest'" +gcloud container images add-tag -q "$SOURCE_IMAGE_TAG" "$TARGET_IMAGE_TAG_LATEST"
diff --git go-ethereum/.circleci/config.yml op-geth/.circleci/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..166d0c25061cad3f5024a4b31cd8705287371e54 --- /dev/null +++ op-geth/.circleci/config.yml @@ -0,0 +1,270 @@ +version: 2.1 + +orbs: + gcp-cli: circleci/gcp-cli@3.0.1 + slack: circleci/slack@4.10.1 + utils: ethereum-optimism/circleci-utils@0.0.8 + +parameters: + go_version: + type: string + default: 1.22.7 # update CI Go version here + +commands: + gcp-oidc-authenticate: + description: "Authenticate with GCP using a CircleCI OIDC token." + parameters: + project_id: + type: env_var_name + default: GCP_PROJECT_ID + workload_identity_pool_id: + type: env_var_name + default: GCP_WIP_ID + workload_identity_pool_provider_id: + type: env_var_name + default: GCP_WIP_PROVIDER_ID + service_account_email: + type: env_var_name + default: GCP_SERVICE_ACCOUNT_EMAIL + gcp_cred_config_file_path: + type: string + default: /home/circleci/gcp_cred_config.json + oidc_token_file_path: + type: string + default: /home/circleci/oidc_token.json + steps: + - run: + name: "Create OIDC credential configuration" + command: | + # Store OIDC token in temp file + echo $CIRCLE_OIDC_TOKEN > << parameters.oidc_token_file_path >> + # Create a credential configuration for the generated OIDC ID Token + gcloud iam workload-identity-pools create-cred-config \ + "projects/${<< parameters.project_id >>}/locations/global/workloadIdentityPools/${<< parameters.workload_identity_pool_id >>}/providers/${<< parameters.workload_identity_pool_provider_id >>}"\ + --output-file="<< parameters.gcp_cred_config_file_path >>" \ + --service-account="${<< parameters.service_account_email >>}" \ + --credential-source-file=<< parameters.oidc_token_file_path >> + - run: + name: "Authenticate with GCP using OIDC" + command: | + # Configure gcloud to leverage the generated credential configuration + gcloud auth login --brief --cred-file "<< parameters.gcp_cred_config_file_path >>" + # Configure ADC + echo "export GOOGLE_APPLICATION_CREDENTIALS='<< parameters.gcp_cred_config_file_path >>'" | tee -a "$BASH_ENV" + +jobs: + build-and-deploy: + machine: + image: ubuntu-2004:current + steps: + - checkout + # Fetch more history for diffing + - run: + name: Fetch git history + command: | + git fetch --depth 1000 + + # Build forkdiff using Docker + - run: + name: Build forkdiff + command: | + docker run --volume $(pwd):/workspace \ + protolambda/forkdiff:0.1.0 \ + -repo=/workspace \ + -fork=/workspace/fork.yaml \ + -out=/workspace/index.html + + # Prepare pages directory + - run: + name: Build pages + command: | + mkdir -p /tmp/pages + mv index.html /tmp/pages/index.html + touch /tmp/pages/.nojekyll + if [ "$CIRCLE_PROJECT_REPONAME" == "op-geth" ] && [ "$CIRCLE_PROJECT_USERNAME" == "ethereum-optimism" ]; then + echo "op-geth.optimism.io" > /tmp/pages/CNAME + fi + - utils/get-github-access-token: + private-key-str: GITHUB_APP_KEY + app-id: GITHUB_APP_ID + repo: $CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME + - utils/github-pages-deploy: + src-pages-dir: /tmp/pages + docker-release: + environment: + DOCKER_BUILDKIT: 1 + parameters: + docker_name: + description: Docker image name + type: string + default: "op-geth" + docker_tags: + description: Docker image tags as csv + type: string + registry: + description: Docker registry + type: string + default: "us-docker.pkg.dev" + repo: + description: Docker repo + type: string + default: "oplabs-tools-artifacts/images" + push_tags: + description: Push release push tags + type: boolean + default: false + machine: + image: default + resource_class: xlarge + steps: + - gcp-cli/install + - gcp-oidc-authenticate + - checkout + - run: + name: Configure Docker + command: | + gcloud auth configure-docker <<parameters.registry>> + - run: + name: Build and push + command: | + RAW_TAGS="<<parameters.docker_tags>>" + if [ "$CIRCLE_BRANCH" = "optimism" ]; then + RAW_TAGS="$RAW_TAGS,optimism" + fi + IMAGE_BASE="<<parameters.registry>>/<<parameters.repo>>/<<parameters.docker_name>>" + DOCKER_TAGS=$(echo -ne "$RAW_TAGS" | sed "s/,/\n/g" | sed "s/[^a-zA-Z0-9\n.]/-/g" | sed -e "s|^|-t ${IMAGE_BASE}:|") + docker context create buildx-build + docker buildx create --use buildx-build + docker buildx build --push \ + $(echo -ne $DOCKER_TAGS | tr '\n' ' ') \ + --platform=linux/arm64,linux/amd64 \ + --build-arg VERSION=$CIRCLE_TAG \ + --build-arg COMMIT=$CIRCLE_SHA \ + --build-arg BUILDNUM=$CIRCLE_BUILD_NUM \ + --progress plain \ + -f Dockerfile . + - when: + condition: + equal: [true, <<parameters.push_tags>>] + steps: + - run: + name: Tag + command: | + ./.circleci/ci-docker-tag-op-geth-release.sh <<parameters.registry>>/<<parameters.repo>> $CIRCLE_TAG $CIRCLE_SHA1 + - when: + condition: + equal: [optimism, << pipeline.git.branch >>] + steps: + - gcp-oidc-authenticate: + service_account_email: GCP_SERVICE_ATTESTOR_ACCOUNT_EMAIL + - run: + name: Sign + command: | + git clone --branch v1.0.3 --depth 1 https://github.com/ethereum-optimism/binary_signer + cd binary_signer/signer + + IMAGE_PATH="<<parameters.registry>>/<<parameters.repo>>/<<parameters.docker_name>>:<<pipeline.git.revision>>" + echo $IMAGE_PATH + pip3 install -r requirements.txt + + python3 ./sign_image.py --command="sign"\ + --attestor-project-name="$ATTESTOR_PROJECT_NAME"\ + --attestor-name="$ATTESTOR_NAME"\ + --image-path="$IMAGE_PATH"\ + --signer-logging-level="INFO"\ + --attestor-key-id="//cloudkms.googleapis.com/v1/projects/$ATTESTOR_PROJECT_NAME/locations/global/keyRings/$ATTESTOR_NAME-key-ring/cryptoKeys/$ATTESTOR_NAME-key/cryptoKeyVersions/1" + + build-geth: + docker: + - image: cimg/go:<<pipeline.parameters.go_version>> + resource_class: xlarge + steps: + - checkout + - run: + command: go run build/ci.go install + unit-test: + resource_class: xlarge + docker: + - image: cimg/go:<<pipeline.parameters.go_version>> + steps: + - checkout + - run: + command: go run build/ci.go test + lint-geth: + resource_class: medium + docker: + - image: cimg/go:<<pipeline.parameters.go_version>> + steps: + - checkout + - run: + command: go run build/ci.go lint + tidy-geth: + resource_class: small + docker: + - image: cimg/go:<<pipeline.parameters.go_version>> + steps: + - checkout + - run: + command: go mod tidy && git diff --exit-code + check-sr-diff: + docker: + - image: cimg/go:<<pipeline.parameters.go_version>> + steps: + - checkout + - run: + name: install dasel + command: go install github.com/tomwright/dasel/v2/cmd/dasel@v2.8.1 + - run: + name: generate artifact and check diff + command: | + bash ./sync-superchain.sh + git diff --exit-code + +workflows: + main: + jobs: + - build-geth: + name: Build geth + - unit-test: + name: Run unit tests for geth + - lint-geth: + name: Run linter over geth + - tidy-geth: + name: Check geth go.mod file has been tidied + - docker-release: + name: Push to Docker + docker_tags: <<pipeline.git.revision>> + context: + - oplabs-gcr + - check-sr-diff: + name: Check superchain registry bundle diff + release: + jobs: + - hold: + type: approval + filters: + tags: + only: /^v.*/ + branches: + ignore: /.*/ + - docker-release: + name: Push to Docker (release) + filters: + tags: + only: /^v.*/ + branches: + ignore: /.*/ + docker_tags: <<pipeline.git.revision>>,<<pipeline.git.tag>> + push_tags: true + context: + - oplabs-gcr-release + requires: + - hold + + merge: + jobs: + - build-and-deploy: + context: circleci-repo-op-geth + filters: + branches: + only: optimism
diff --git go-ethereum/.github/CODEOWNERS op-geth/.github/CODEOWNERS index b56918085294df092b423fca77e912adccc6143f..e9ba9912c5ba2c0b060c68fcf37573368f326256 100644 --- go-ethereum/.github/CODEOWNERS +++ op-geth/.github/CODEOWNERS @@ -1,36 +1 @@ -# Lines starting with '#' are comments. -# Each line is a file pattern followed by one or more owners. - -accounts/usbwallet/ @gballet -accounts/scwallet/ @gballet -accounts/abi/ @gballet @MariusVanDerWijden -beacon/engine/ @MariusVanDerWijden @lightclient @fjl -beacon/light/ @zsfelfoldi -beacon/merkle/ @zsfelfoldi -beacon/types/ @zsfelfoldi @fjl -beacon/params/ @zsfelfoldi @fjl -cmd/clef/ @holiman -cmd/evm/ @holiman @MariusVanDerWijden @lightclient -core/state/ @rjl493456442 @holiman -crypto/ @gballet @jwasinger @holiman @fjl -core/ @holiman @rjl493456442 -eth/ @holiman @rjl493456442 -eth/catalyst/ @MariusVanDerWijden @lightclient @fjl @jwasinger -eth/tracers/ @s1na -ethclient/ @fjl -ethdb/ @rjl493456442 -event/ @fjl -trie/ @rjl493456442 -triedb/ @rjl493456442 -core/tracing/ @s1na -graphql/ @s1na -internal/ethapi/ @fjl @s1na @lightclient -internal/era/ @lightclient -metrics/ @holiman -miner/ @MariusVanDerWijden @holiman @fjl @rjl493456442 -node/ @fjl -p2p/ @fjl @zsfelfoldi -rlp/ @fjl -params/ @fjl @holiman @karalabe @gballet @rjl493456442 @zsfelfoldi -rpc/ @fjl @holiman -signer/ @holiman +* @ethereum-optimism/op-geth-maintainers
diff --git go-ethereum/.github/workflows/go.yml op-geth/.github/workflows/go.yml deleted file mode 100644 index 6406d2fa3db0c8af8b373875cb7a34f2fad39968..0000000000000000000000000000000000000000 --- go-ethereum/.github/workflows/go.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: i386 linux tests - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - workflow_dispatch: - -jobs: - build: - runs-on: self-hosted - steps: - - uses: actions/checkout@v4 - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: 1.23.0 - cache: false - - name: Run tests - run: go test -short ./... - env: - GOOS: linux - GOARCH: 386
diff --git go-ethereum/.golangci.yml op-geth/.golangci.yml index b63251055b80abf19a1d04453fa0c506b38c8584..4215dcd43b43b9a843bfa16cd3408ed790dbfaff 100644 --- go-ethereum/.golangci.yml +++ op-geth/.golangci.yml @@ -1,4 +1,5 @@ # This file configures github.com/golangci/golangci-lint. +# see <https://golangci-lint.run/usage/configuration>   run: timeout: 20m @@ -54,7 +55,7 @@ issues: # default is true. Enables skipping of directories: # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ exclude-dirs-use-default: true - exclude-files: + exclude-dirs: - core/genesis_alloc.go exclude-rules: - path: crypto/bn256/cloudflare/optate.go
diff --git go-ethereum/Makefile op-geth/Makefile index f4932165a482d71590712199d6a43924b63dc90a..9e8b9569cd613c61d56e9ce9a0fd124fd1532c61 100644 --- go-ethereum/Makefile +++ op-geth/Makefile @@ -47,6 +47,12 @@ env GOBIN= go install ./cmd/abigen @type "solc" 2> /dev/null || echo 'Please install solc' @type "protoc" 2> /dev/null || echo 'Please install protoc'   +forkdiff: + docker run --rm \ + --mount src=$(shell pwd),target=/host-pwd,type=bind \ + protolambda/forkdiff:latest \ + -repo /host-pwd/ -fork /host-pwd/fork.yaml -out /host-pwd/forkdiff.html + #? help: Get more info on make commands. help: Makefile @echo ''
diff --git go-ethereum/core/vm/testdata/precompiles/p256Verify.json op-geth/core/vm/testdata/precompiles/p256Verify.json new file mode 100644 index 0000000000000000000000000000000000000000..b631d907ac523bd8ca8e3712314a0047f4cf4115 --- /dev/null +++ op-geth/core/vm/testdata/precompiles/p256Verify.json @@ -0,0 +1,5469 @@ +[ + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e184cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd762927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #1: signature malleability", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023d45c5740946b2a147f59262ee6f5bc90bd01ed280528b62b3aed5fc93f06f739b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #3: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #5: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e184cd60b865d442f5a3c7b11eb6c4e0ae79578ec6353a20bf783ecb4b6ea97b8252927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #8: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #9: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #10: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #11: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #12: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #13: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000000ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #14: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000000ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #15: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #16: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #17: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000001ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #18: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000001ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #19: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000001ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #20: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000001ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #21: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000001ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #22: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255100000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #23: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255100000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #24: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #25: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #26: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #27: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #28: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #29: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255000000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #30: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255000000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #31: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #32: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #33: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #34: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #35: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #36: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255200000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #37: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255200000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #38: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #39: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #40: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #41: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #42: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #43: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #44: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #45: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #46: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #47: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #48: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #49: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #50: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff0000000100000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #51: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff0000000100000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #52: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #53: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #54: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #55: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #56: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #57: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "70239dd877f7c944c422f44dea4ed1a52f2627416faf2f072fa50c772ed6f80764a1aab5000d0e804f3e2fc02bdee9be8ff312334e2ba16d11547c97711c898e6af015971cc30be6d1a206d4e013e0997772a2f91d73286ffd683b9bb2cf4f1b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #58: Edge case for Shamir multiplication", + "NoBenchmark": false + }, + { + "Input": "00000000690ed426ccf17803ebe2bd0884bcd58a1bb5e7477ead3645f356e7a916aea964a2f6506d6f78c81c91fc7e8bded7d397738448de1e19a0ec580bf266252cd762130c6667cfe8b7bc47d27d78391e8e80c578d1cd38c3ff033be928e92927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #59: special case hash", + "NoBenchmark": false + }, + { + "Input": "7300000000213f2a525c6035725235c2f696ad3ebb5ee47f140697ad25770d919cc98be2347d469bf476dfc26b9b733df2d26d6ef524af917c665baccb23c882093496459effe2d8d70727b82462f61d0ec1b7847929d10ea631dacb16b56c322927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #60: special case hash", + "NoBenchmark": false + }, + { + "Input": "ddf2000000005e0be0635b245f0b97978afd25daadeb3edb4a0161c27fe0604573b3c90ecd390028058164524dde892703dce3dea0d53fa8093999f07ab8aa432f67b0b8e20636695bb7d8bf0a651c802ed25a395387b5f4188c0c4075c886342927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #61: special case hash", + "NoBenchmark": false + }, + { + "Input": "67ab1900000000784769c4ecb9e164d6642b8499588b89855be1ec355d0841a0bfab3098252847b328fadf2f89b95c851a7f0eb390763378f37e90119d5ba3ddbdd64e234e832b1067c2d058ccb44d978195ccebb65c2aaf1e2da9b8b4987e3b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #62: special case hash", + "NoBenchmark": false + }, + { + "Input": "a2bf09460000000076d7dbeffe125eaf02095dff252ee905e296b6350fc311cf204a9784074b246d8bf8bf04a4ceb1c1f1c9aaab168b1596d17093c5cd21d2cd51cce41670636783dc06a759c8847868a406c2506fe17975582fe648d1d88b522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #63: special case hash", + "NoBenchmark": false + }, + { + "Input": "3554e827c700000000e1e75e624a06b3a0a353171160858129e15c544e4f0e65ed66dc34f551ac82f63d4aa4f81fe2cb0031a91d1314f835027bca0f1ceeaa0399ca123aa09b13cd194a422e18d5fda167623c3f6e5d4d6abb8953d67c0c48c72927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #64: special case hash", + "NoBenchmark": false + }, + { + "Input": "9b6cd3b812610000000026941a0f0bb53255ea4c9fd0cb3426e3a54b9fc6965c060b700bef665c68899d44f2356a578d126b062023ccc3c056bf0f60a237012b8d186c027832965f4fcc78a3366ca95dedbb410cbef3f26d6be5d581c11d36102927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #65: special case hash", + "NoBenchmark": false + }, + { + "Input": "883ae39f50bf0100000000e7561c26fc82a52baa51c71ca877162f93c4ae01869f6adfe8d5eb5b2c24d7aa7934b6cf29c93ea76cd313c9132bb0c8e38c96831db26a9c9e40e55ee0890c944cf271756c906a33e66b5bd15e051593883b5e99022927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #66: special case hash", + "NoBenchmark": false + }, + { + "Input": "a1ce5d6e5ecaf28b0000000000fa7cd010540f420fb4ff7401fe9fce011d0ba6a1af03ca91677b673ad2f33615e56174a1abf6da168cebfa8868f4ba273f16b720aa73ffe48afa6435cd258b173d0c2377d69022e7d098d75caf24c8c5e06b1c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #67: special case hash", + "NoBenchmark": false + }, + { + "Input": "8ea5f645f373f580930000000038345397330012a8ee836c5494cdffd5ee8054fdc70602766f8eed11a6c99a71c973d5659355507b843da6e327a28c11893db93df5349688a085b137b1eacf456a9e9e0f6d15ec0078ca60a7f83f2b10d213502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #68: special case hash", + "NoBenchmark": false + }, + { + "Input": "660570d323e9f75fa734000000008792d65ce93eabb7d60d8d9c1bbdcb5ef305b516a314f2fce530d6537f6a6c49966c23456f63c643cf8e0dc738f7b876e675d39ffd033c92b6d717dd536fbc5efdf1967c4bd80954479ba66b0120cd16fff22927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #69: special case hash", + "NoBenchmark": false + }, + { + "Input": "d0462673154cce587dde8800000000e98d35f1f45cf9c3bf46ada2de4c568c343b2cbf046eac45842ecb7984d475831582717bebb6492fd0a485c101e29ff0a84c9b7b47a98b0f82de512bc9313aaf51701099cac5f76e68c8595fc1c1d992582927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #70: special case hash", + "NoBenchmark": false + }, + { + "Input": "bd90640269a7822680cedfef000000000caef15a6171059ab83e7b4418d7278f30c87d35e636f540841f14af54e2f9edd79d0312cfa1ab656c3fb15bfde48dcf47c15a5a82d24b75c85a692bd6ecafeb71409ede23efd08e0db9abf6340677ed2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #71: special case hash", + "NoBenchmark": false + }, + { + "Input": "33239a52d72f1311512e41222a00000000d2dcceb301c54b4beae8e284788a7338686ff0fda2cef6bc43b58cfe6647b9e2e8176d168dec3c68ff262113760f52067ec3b651f422669601662167fa8717e976e2db5e6a4cf7c2ddabb3fde9d67d2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #72: special case hash", + "NoBenchmark": false + }, + { + "Input": "b8d64fbcd4a1c10f1365d4e6d95c000000007ee4a21a1cbe1dc84c2d941ffaf144a3e23bf314f2b344fc25c7f2de8b6af3e17d27f5ee844b225985ab6e2775cf2d48e223205e98041ddc87be532abed584f0411f5729500493c9cc3f4dd15e862927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #73: special case hash", + "NoBenchmark": false + }, + { + "Input": "01603d3982bf77d7a3fef3183ed092000000003a227420db4088b20fe0e9d84a2ded5b7ec8e90e7bf11f967a3d95110c41b99db3b5aa8d330eb9d638781688e97d5792c53628155e1bfc46fb1a67e3088de049c328ae1f44ec69238a009808f92927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #74: special case hash", + "NoBenchmark": false + }, + { + "Input": "9ea6994f1e0384c8599aa02e6cf66d9c000000004d89ef50b7e9eb0cfbff7363bdae7bcb580bf335efd3bc3d31870f923eaccafcd40ec2f605976f15137d8b8ff6dfa12f19e525270b0106eecfe257499f373a4fb318994f24838122ce7ec3c72927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #75: special case hash", + "NoBenchmark": false + }, + { + "Input": "d03215a8401bcf16693979371a01068a4700000000e2fa5bf692bc670905b18c50f9c4f0cd6940e162720957ffff513799209b78596956d21ece251c2401f1c6d7033a0a787d338e889defaaabb106b95a4355e411a59c32aa5167dfab2447262927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #76: special case hash", + "NoBenchmark": false + }, + { + "Input": "307bfaaffb650c889c84bf83f0300e5dc87e000000008408fd5f64b582e3bb14f612820687604fa01906066a378d67540982e29575d019aabe90924ead5c860d3f9367702dd7dd4f75ea98afd20e328a1a99f4857b316525328230ce294b0fef2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #77: special case hash", + "NoBenchmark": false + }, + { + "Input": "bab5c4f4df540d7b33324d36bb0c157551527c00000000e4af574bb4d54ea6b89505e407657d6e8bc93db5da7aa6f5081f61980c1949f56b0f2f507da5782a7ac60d31904e3669738ffbeccab6c3656c08e0ed5cb92b3cfa5e7f71784f9c50212927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #78: special case hash", + "NoBenchmark": false + }, + { + "Input": "d4ba47f6ae28f274e4f58d8036f9c36ec2456f5b00000000c3b869197ef5e15ebbd16fbbb656b6d0d83e6a7787cd691b08735aed371732723e1c68a40404517d9d8e35dba96028b7787d91315be675877d2d097be5e8ee34560e3e7fd25c0f002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #79: special case hash", + "NoBenchmark": false + }, + { + "Input": "79fd19c7235ea212f29f1fa00984342afe0f10aafd00000000801e47f8c184e12ec9760122db98fd06ea76848d35a6da442d2ceef7559a30cf57c61e92df327e7ab271da90859479701fccf86e462ee3393fb6814c27b760c4963625c0a198782927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #80: special case hash", + "NoBenchmark": false + }, + { + "Input": "8c291e8eeaa45adbaf9aba5c0583462d79cbeb7ac97300000000a37ea6700cda54e76b7683b6650baa6a7fc49b1c51eed9ba9dd463221f7a4f1005a89fe00c592ea076886c773eb937ec1cc8374b7915cfd11b1c1ae1166152f2f7806a31c8fd2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #81: special case hash", + "NoBenchmark": false + }, + { + "Input": "0eaae8641084fa979803efbfb8140732f4cdcf66c3f78a000000003c278a6b215291deaf24659ffbbce6e3c26f6021097a74abdbb69be4fb10419c0c496c946665d6fcf336d27cc7cdb982bb4e4ecef5827f84742f29f10abf83469270a03dc32927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #82: special case hash", + "NoBenchmark": false + }, + { + "Input": "e02716d01fb23a5a0068399bf01bab42ef17c6d96e13846c00000000afc0f89d207a3241812d75d947419dc58efb05e8003b33fc17eb50f9d15166a88479f107cdee749f2e492b213ce80b32d0574f62f1c5d70793cf55e382d5caadf75927672927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #83: special case hash", + "NoBenchmark": false + }, + { + "Input": "9eb0bf583a1a6b9a194e9a16bc7dab2a9061768af89d00659a00000000fc7de16554e49f82a855204328ac94913bf01bbe84437a355a0a37c0dee3cf81aa7728aea00de2507ddaf5c94e1e126980d3df16250a2eaebc8be486effe7f22b4f9292927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #84: special case hash", + "NoBenchmark": false + }, + { + "Input": "62aac98818b3b84a2c214f0d5e72ef286e1030cb53d9a82b690e00000000cd15a54c5062648339d2bff06f71c88216c26c6e19b4d80a8c602990ac82707efdfce99bbe7fcfafae3e69fd016777517aa01056317f467ad09aff09be73c9731b0d2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #85: special case hash", + "NoBenchmark": false + }, + { + "Input": "3760a7f37cf96218f29ae43732e513efd2b6f552ea4b6895464b9300000000c8975bd7157a8d363b309f1f444012b1a1d23096593133e71b4ca8b059cff37eaf7faa7a28b1c822baa241793f2abc930bd4c69840fe090f2aacc46786bf9196222927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #86: special case hash", + "NoBenchmark": false + }, + { + "Input": "0da0a1d2851d33023834f2098c0880096b4320bea836cd9cbb6ff6c8000000005694a6f84b8f875c276afd2ebcfe4d61de9ec90305afb1357b95b3e0da43885e0dffad9ffd0b757d8051dec02ebdf70d8ee2dc5c7870c0823b6ccc7c679cbaa42927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #87: special case hash", + "NoBenchmark": false + }, + { + "Input": "ffffffff293886d3086fd567aafd598f0fe975f735887194a764a231e82d289aa0c30e8026fdb2b4b4968a27d16a6d08f7098f1a98d21620d7454ba9790f1ba65e470453a8a399f15baf463f9deceb53acc5ca64459149688bd2760c654243392927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #88: special case hash", + "NoBenchmark": false + }, + { + "Input": "7bffffffff2376d1e3c03445a072e24326acdc4ce127ec2e0e8d9ca99527e7b7614ea84acf736527dd73602cd4bb4eea1dfebebd5ad8aca52aa0228cf7b99a88737cc85f5f2d2f60d1b8183f3ed490e4de14368e96a9482c2a4dd193195c902f2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #89: special case hash", + "NoBenchmark": false + }, + { + "Input": "a2b5ffffffffebb251b085377605a224bc80872602a6e467fd016807e97fa395bead6734ebe44b810d3fb2ea00b1732945377338febfd439a8d74dfbd0f942fa6bb18eae36616a7d3cad35919fd21a8af4bbe7a10f73b3e036a46b103ef56e2a2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #90: special case hash", + "NoBenchmark": false + }, + { + "Input": "641227ffffffff6f1b96fa5f097fcf3cc1a3c256870d45a67b83d0967d4b20c0499625479e161dacd4db9d9ce64854c98d922cbf212703e9654fae182df9bad242c177cf37b8193a0131108d97819edd9439936028864ac195b64fca76d9d6932927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #91: special case hash", + "NoBenchmark": false + }, + { + "Input": "958415d8ffffffffabad03e2fc662dc3ba203521177502298df56f36600e0f8b08f16b8093a8fb4d66a2c8065b541b3d31e3bfe694f6b89c50fb1aaa6ff6c9b29d6455e2d5d1779748573b611cb95d4a21f967410399b39b535ba3e5af81ca2e2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #92: special case hash", + "NoBenchmark": false + }, + { + "Input": "f1d8de4858ffffffff1281093536f47fe13deb04e1fbe8fb954521b6975420f8be26231b6191658a19dd72ddb99ed8f8c579b6938d19bce8eed8dc2b338cb5f8e1d9a32ee56cffed37f0f22b2dcb57d5c943c14f79694a03b9c5e96952575c892927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #93: special case hash", + "NoBenchmark": false + }, + { + "Input": "0927895f2802ffffffff10782dd14a3b32dc5d47c05ef6f1876b95c81fc31def15e76880898316b16204ac920a02d58045f36a229d4aa4f812638c455abe0443e74d357d3fcb5c8c5337bd6aba4178b455ca10e226e13f9638196506a19391232927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #94: special case hash", + "NoBenchmark": false + }, + { + "Input": "60907984aa7e8effffffff4f332862a10a57c3063fb5a30624cf6a0c3ac80589352ecb53f8df2c503a45f9846fc28d1d31e6307d3ddbffc1132315cc07f16dad1348dfa9c482c558e1d05c5242ca1c39436726ecd28258b1899792887dd0a3c62927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #95: special case hash", + "NoBenchmark": false + }, + { + "Input": "c6ff198484939170ffffffff0af42cda50f9a5f50636ea6942d6b9b8cd6ae1e24a40801a7e606ba78a0da9882ab23c7677b8642349ed3d652c5bfa5f2a9558fb3a49b64848d682ef7f605f2832f7384bdc24ed2925825bf8ea77dc59817257822927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #96: special case hash", + "NoBenchmark": false + }, + { + "Input": "de030419345ca15c75ffffffff8074799b9e0956cc43135d16dfbe4d27d7e68deacc5e1a8304a74d2be412b078924b3bb3511bac855c05c9e5e9e44df3d61e967451cd8e18d6ed1885dd827714847f96ec4bb0ed4c36ce9808db8f714204f6d12927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #97: special case hash", + "NoBenchmark": false + }, + { + "Input": "6f0e3eeaf42b28132b88fffffffff6c8665604d34acb19037e1ab78caaaac6ff2f7a5e9e5771d424f30f67fdab61e8ce4f8cd1214882adb65f7de94c31577052ac4e69808345809b44acb0b2bd889175fb75dd050c5a449ab9528f8f78daa10c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #98: special case hash", + "NoBenchmark": false + }, + { + "Input": "cdb549f773b3e62b3708d1ffffffffbe48f7c0591ddcae7d2cb222d1f8017ab9ffcda40f792ce4d93e7e0f0e95e1a2147dddd7f6487621c30a03d710b330021979938b55f8a17f7ed7ba9ade8f2065a1fa77618f0b67add8d58c422c2453a49a2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #99: special case hash", + "NoBenchmark": false + }, + { + "Input": "2c3f26f96a3ac0051df4989bffffffff9fd64886c1dc4f9924d8fd6f0edb048481f2359c4faba6b53d3e8c8c3fcc16a948350f7ab3a588b28c17603a431e39a8cd6f6a5cc3b55ead0ff695d06c6860b509e46d99fccefb9f7f9e101857f743002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #100: special case hash", + "NoBenchmark": false + }, + { + "Input": "ac18f8418c55a2502cb7d53f9affffffff5c31d89fda6a6b8476397c04edf411dfc8bf520445cbb8ee1596fb073ea283ea130251a6fdffa5c3f5f2aaf75ca808048e33efce147c9dd92823640e338e68bfd7d0dc7a4905b3a7ac711e577e90e72927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #101: special case hash", + "NoBenchmark": false + }, + { + "Input": "4f9618f98e2d3a15b24094f72bb5ffffffffa2fd3e2893683e5a6ab8cf0ee610ad019f74c6941d20efda70b46c53db166503a0e393e932f688227688ba6a576293320eb7ca0710255346bdbb3102cdcf7964ef2e0988e712bc05efe16c1993452927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #102: special case hash", + "NoBenchmark": false + }, + { + "Input": "422e82a3d56ed10a9cc21d31d37a25ffffffff67edf7c40204caae73ab0bc75aac8096842e8add68c34e78ce11dd71e4b54316bd3ebf7fffdeb7bd5a3ebc1883f5ca2f4f23d674502d4caf85d187215d36e3ce9f0ce219709f21a3aac003b7a82927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #103: special case hash", + "NoBenchmark": false + }, + { + "Input": "7075d245ccc3281b6e7b329ff738fbb417a5ffffffffa0842d9890b5cf95d018677b2d3a59b18a5ff939b70ea002250889ddcd7b7b9d776854b4943693fb92f76b4ba856ade7677bf30307b21f3ccda35d2f63aee81efd0bab6972cc0795db552927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #104: special case hash", + "NoBenchmark": false + }, + { + "Input": "3c80de54cd9226989443d593fa4fd6597e280ebeffffffffc1847eb76c217a95479e1ded14bcaed0379ba8e1b73d3115d84d31d4b7c30e1f05e1fc0d5957cfb0918f79e35b3d89487cf634a4f05b2e0c30857ca879f97c771e877027355b24432927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #105: special case hash", + "NoBenchmark": false + }, + { + "Input": "de21754e29b85601980bef3d697ea2770ce891a8cdffffffffc7906aa794b39b43dfccd0edb9e280d9a58f01164d55c3d711e14b12ac5cf3b64840ead512a0a31dbe33fa8ba84533cd5c4934365b3442ca1174899b78ef9a3199f495843897722927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #106: special case hash", + "NoBenchmark": false + }, + { + "Input": "8f65d92927cfb86a84dd59623fb531bb599e4d5f7289ffffffff2f1f2f57881c5b09ab637bd4caf0f4c7c7e4bca592fea20e9087c259d26a38bb4085f0bbff1145b7eb467b6748af618e9d80d6fdcd6aa24964e5a13f885bca8101de08eb0d752927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #107: special case hash", + "NoBenchmark": false + }, + { + "Input": "6b63e9a74e092120160bea3877dace8a2cc7cd0e8426cbfffffffffafc8c3ca85e9b1c5a028070df5728c5c8af9b74e0667afa570a6cfa0114a5039ed15ee06fb1360907e2d9785ead362bb8d7bd661b6c29eeffd3c5037744edaeb9ad990c202927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #108: special case hash", + "NoBenchmark": false + }, + { + "Input": "fc28259702a03845b6d75219444e8b43d094586e249c8699ffffffffe852512e0671a0a85c2b72d54a2fb0990e34538b4890050f5a5712f6d1a7a5fb8578f32edb1846bab6b7361479ab9c3285ca41291808f27fd5bd4fdac720e5854713694c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #109: special case hash", + "NoBenchmark": false + }, + { + "Input": "1273b4502ea4e3bccee044ee8e8db7f774ecbcd52e8ceb571757ffffffffe20a7673f8526748446477dbbb0590a45492c5d7d69859d301abbaedb35b2095103a3dc70ddf9c6b524d886bed9e6af02e0e4dec0d417a414fed3807ef4422913d7c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #110: special case hash", + "NoBenchmark": false + }, + { + "Input": "08fb565610a79baa0c566c66228d81814f8c53a15b96e602fb49ffffffffff6e7f085441070ecd2bb21285089ebb1aa6450d1a06c36d3ff39dfd657a796d12b5249712012029870a2459d18d47da9aa492a5e6cb4b2d8dafa9e4c5c54a2b9a8b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #111: special case hash", + "NoBenchmark": false + }, + { + "Input": "d59291cc2cf89f3087715fcb1aa4e79aa2403f748e97d7cd28ecaefeffffffff914c67fb61dd1e27c867398ea7322d5ab76df04bc5aa6683a8e0f30a5d287348fa07474031481dda4953e3ac1959ee8cea7e66ec412b38d6c96d28f6d37304ea2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #112: special case hash", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000004319055358e8617b0c46353d039cdaabffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e0ad99500288d466940031d72a9f5445a4d43784640855bf0a69874d2de5fe103c5011e6ef2c42dcd50d5d3d29f99ae6eba2c80c9244f4c5422f0979ff0c3ba5e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #113: k*G has a large x-coordinate", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000fffffffffffffffffffffffcffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e0ad99500288d466940031d72a9f5445a4d43784640855bf0a69874d2de5fe103c5011e6ef2c42dcd50d5d3d29f99ae6eba2c80c9244f4c5422f0979ff0c3ba5e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #114: r too large", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254eab05fd9d0de26b9ce6f4819652d9fc69193d0aa398f0fba8013e09c58220455419235271228c786759095d12b75af0692dd4103f19f6a8c32f49435a1e9b8d45", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #115: r,s are large", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd909135bdb6799286170f5ead2de4f6511453fe50914f3df2de54a36383df8dd480984f39a1ff38a86a68aa4201b6be5dfbfecf876219710b07badf6fdd4c6c5611feb97390d9826e7a06dfb41871c940d74415ed3cac2089f1445019bb55ed95", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #116: r and s^-1 have a large Hamming weight", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd27b4577ca009376f71303fd5dd227dcef5deb773ad5f5a84360644669ca249a54201b4272944201c3294f5baa9a3232b6dd687495fcc19a70a95bc602b4f7c0595c37eba9ee8171c1bb5ac6feaf753bc36f463e3aef16629572c0c0a8fb0800e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #117: r and s^-1 have a large Hamming weight", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502300000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001a71af64de5126a4a4e02b7922d66ce9415ce88a4c9d25514d91082c8725ac9575d47723c8fbe580bb369fec9c2665d8e30a435b9932645482e7c9f11e872296b", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #118: small r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000036627cec4f0731ea23fc2931f90ebe5b7572f597d20df08fc2b31ee8ef16b15726170ed77d8d0a14fc5c9c3c4c9be7f0d3ee18f709bb275eaf2073e258fe694a5", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #120: small r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000055a7c8825e85691cce1f5e7544c54e73f14afc010cb731343262ca7ec5a77f5bfef6edf62a4497c1bd7b147fb6c3d22af3c39bfce95f30e13a16d3d7b2812f813", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #122: small r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502300000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006cbe0c29132cd738364fedd603152990c048e5e2fff996d883fa6caca7978c73770af6a8ce44cb41224b2603606f4c04d188e80bff7cc31ad5189d4ab0d70e8c1", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #124: small r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325560000000000000000000000000000000000000000000000000000000000000006cbe0c29132cd738364fedd603152990c048e5e2fff996d883fa6caca7978c73770af6a8ce44cb41224b2603606f4c04d188e80bff7cc31ad5189d4ab0d70e8c1", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #126: r is larger than n", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000005ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc75fbd84be4178097002f0deab68f0d9a130e0ed33a6795d02a20796db83444b037e13920f13051e0eecdcfce4dacea0f50d1f247caa669f193c1b4075b51ae296d2d56", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #127: s is larger than n", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502300000000000000000000000000000000000000000000000000000000000001008f1e3c7862c58b16bb76eddbb76eddbb516af4f63f2d74d76e0d28c9bb75ea88d0f73792203716afd4be4329faa48d269f15313ebbba379d7783c97bf3e890d9971f4a3206605bec21782bf5e275c714417e8f566549e6bc68690d2363c89cc1", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #128: small r and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000000000000000000000002d9b4d347952d6ef3043e7329581dbb3974497710ab11505ee1c87ff907beebadd195a0ffe6d7a4838b2be35a6276a80ef9e228140f9d9b96ce83b7a254f71ccdebbb8054ce05ffa9cbc123c919b19e00238198d04069043bd660a828814051fcb8aac738a6c6b", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #129: smallish r and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000000000001033e67e37b32b445580bf4eff8b748b74000000008b748b748b748b7466e769ad4a16d3dcd87129b8e91d1b4d7393983ca30a520bbc4783dc9960746aab444ef520c0a8e771119aa4e74b0f64e9d7be1ab01a0bf626e709863e6a486dbaf32793afccf774e2c6cd27b1857526", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #130: 100-bit r and small s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000100ef9f6ba4d97c09d03178fa20b4aaad83be3cf9cb824a879fec3270fc4b81ef5b5ac331a1103fe966697379f356a937f350588a05477e308851b8a502d5dfcdc5fe9993df4b57939b2b8da095bf6d794265204cfe03be995a02e65d408c871c0b", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #131: small r and 100 bit s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502300000000000000000000000000000000000000062522bbd3ecbe7c39e93e7c25ef9f6ba4d97c09d03178fa20b4aaad83be3cf9cb824a879fec3270fc4b81ef5b1d209be8de2de877095a399d3904c74cc458d926e27bb8e58e5eae5767c41509dd59e04c214f7b18dce351fc2a549893a6860e80163f38cc60a4f2c9d040d8c9", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #132: 100-bit r and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6324d5555555550000000055555555555555553ef7a8e48d07df81a693439654210c70083539fbee44625e3acaafa2fcb41349392cef0633a1b8fabecee0c133b10e99915c1ebe7bf00df8535196770a58047ae2a402f26326bb7d41d4d7616337911e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #133: r and s^-1 are close to n", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023555555550000000055555555555555553ef7a8e48d07df81a693439654210c7000000000000000000000000000000000000000000000000000000000000000018aeb368a7027a4d64abdea37390c0c1d6a26f399e2d9734de1eb3d0e1937387405bd13834715e1dbae9b875cf07bd55e1b6691c7f7536aef3b19bf7a4adf576d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #134: s == 1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023555555550000000055555555555555553ef7a8e48d07df81a693439654210c7000000000000000000000000000000000000000000000000000000000000000008aeb368a7027a4d64abdea37390c0c1d6a26f399e2d9734de1eb3d0e1937387405bd13834715e1dbae9b875cf07bd55e1b6691c7f7536aef3b19bf7a4adf576d", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #135: s == 0", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8555555550000000055555555555555553ef7a8e48d07df81a693439654210c70b533d4695dd5b8c5e07757e55e6e516f7e2c88fa0239e23f60e8ec07dd70f2871b134ee58cc583278456863f33c3a85d881f7d4a39850143e29d4eaf009afe47", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #136: point at infinity during verify", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a97fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8f50d371b91bfb1d7d14e1323523bc3aa8cbf2c57f9e284de628c8b4536787b86f94ad887ac94d527247cd2e7d0c8b1291c553c9730405380b14cbb209f5fa2dd", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #137: edge case for signature malleability", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a97fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a968ec6e298eafe16539156ce57a14b04a7047c221bafc3a582eaeb0d857c4d94697bed1af17850117fdb39b2324f220a5698ed16c426a27335bb385ac8ca6fb30", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #138: edge case for signature malleability", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023555555550000000055555555555555553ef7a8e48d07df81a693439654210c70bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502369da0364734d2e530fece94019265fefb781a0f1b08f6c8897bdf6557927c8b866d2d3c7dcd518b23d726960f069ad71a933d86ef8abbcce8b20f71e2a847002", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #139: u1 == 1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023555555550000000055555555555555553ef7a8e48d07df81a693439654210c7044a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52ed8adc00023a8edc02576e2b63e3e30621a471e2b2320620187bf067a1ac1ff3233e2b50ec09807accb36131fff95ed12a09a86b4ea9690aa32861576ba2362e1", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #140: u1 == n - 1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023555555550000000055555555555555553ef7a8e48d07df81a693439654210c70555555550000000055555555555555553ef7a8e48d07df81a693439654210c703623ac973ced0a56fa6d882f03a7d5c7edca02cfc7b2401fab3690dbe75ab7858db06908e64b28613da7257e737f39793da8e713ba0643b92e9bb3252be7f8fe", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #141: u2 == 1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023555555550000000055555555555555553ef7a8e48d07df81a693439654210c70aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1cf04ea77e9622523d894b93ff52dc3027b31959503b6fa3890e5e04263f922f1e8528fb7c006b3983c8b8400e57b4ed71740c2f3975438821199bedeaecab2e9", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #142: u2 == n - 1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffde91e1ba60fdedb76a46bcb51dc0b8b4b7e019f0a28721885fa5d3a8196623397db7a2c8a1ab573e5929dc24077b508d7e683d49227996bda3e9f78dbeff773504f417f3bc9a88075c2e0aadd5a13311730cf7cc76a82f11a36eaf08a6c99a206", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #143: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdea5843ffeb73af94313ba4831b53fe24f799e525b1e8e8c87b59b95b430ad9dead11c7a5b396862f21974dc4752fadeff994efe9bbd05ab413765ea80b6e1f1de3f0640e8ac6edcf89cff53c40e265bb94078a343736df07aa0318fc7fe1ff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #144: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd03ffcabf2f1b4d2a65190db1680d62bb994e41c5251cd73b3c3dfc5e5bafc035d0bc472e0d7c81ebaed3a6ef96c18613bb1fea6f994326fbe80e00dfde67c7e9986c723ea4843d48389b946f64ad56c83ad70ff17ba85335667d1bb9fa619efd", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #145: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd4dfbc401f971cd304b33dfdb17d0fed0fe4c1a88ae648e0d2847f74977534989a0a44ca947d66a2acb736008b9c08d1ab2ad03776e02640f78495d458dd51c326337fe5cf8c4604b1f1c409dc2d872d4294a4762420df43a30a2392e40426add", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #146: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbc4024761cd2ffd43dfdb17d0fed112b988977055cd3a8e54971eba9cda5ca71c9c2115290d008b45fb65fad0f602389298c25420b775019d42b62c3ce8a96b73877d25a8080dc02d987ca730f0405c2c9dbefac46f9e601cc3f06e9713973fd", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #147: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd788048ed39a5ffa77bfb62fa1fda2257742bf35d128fb3459f2a0c909ee86f915eca1ef4c287dddc66b8bccf1b88e8a24c0018962f3c5e7efa83bc1a5ff6033e5e79c4cb2c245b8c45abdce8a8e4da758d92a607c32cd407ecaef22f1c934a71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #148: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd476d9131fd381bd917d0fed112bc9e0a5924b5ed5b11167edd8b23582b3cb15e5caaa030e7fdf0e4936bc7ab5a96353e0a01e4130c3f8bf22d473e317029a47adeb6adc462f7058f2a20d371e9702254e9b201642005b3ceda926b42b178bef9", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #149: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8374253e3e21bd154448d0a8f640fe46fafa8b19ce78d538f6cc0a19662d3601c2fd20bac06e555bb8ac0ce69eb1ea20f83a1fc3501c8a66469b1a31f619b0986237050779f52b615bd7b8d76a25fc95ca2ed32525c75f27ffc87ac397e6cbaf", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #150: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd357cfd3be4d01d413c5b9ede36cba5452c11ee7fe14879e749ae6a2d897a52d63fd6a1ca7f77fb3b0bbe726c372010068426e11ea6ae78ce17bedae4bba86ced03ce5516406bf8cfaab8745eac1cd69018ad6f50b5461872ddfc56e0db3c8ff4", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #151: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd29798c5c0ee287d4a5e8e6b799fd86b8df5225298e6ffc807cd2f2bc27a0a6d89cb8e51e27a5ae3b624a60d6dc32734e4989db20e9bca3ede1edf7b086911114b4c104ab3c677e4b36d6556e8ad5f523410a19f2e277aa895fc57322b4427544", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #152: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0b70f22c781092452dca1a5711fa3a5a1f72add1bf52c2ff7cae4820b30078dda3e52c156dcaf10502620b7955bc2b40bc78ef3d569e1223c262512d8f49602a4a2039f31c1097024ad3cc86e57321de032355463486164cf192944977df147f", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #153: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd16e1e458f021248a5b9434ae23f474b43ee55ba37ea585fef95c90416600f1baf19b78928720d5bee8e670fb90010fb15c37bf91b58a5157c3f3c059b2655e88cf701ec962fb4a11dcf273f5dc357e58468560c7cfeb942d074abd4329260509", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #154: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd2252d6856831b6cf895e4f0535eeaf0e5e5809753df848fe760ad86219016a9783a744459ecdfb01a5cf52b27a05bb7337482d242f235d7b4cb89345545c90a8c05d49337b9649813287de9ffe90355fd905df5f3c32945828121f37cc50de6e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #155: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd81ffe55f178da695b28c86d8b406b15dab1a9e39661a3ae017fbe390ac0972c3dd13c6b34c56982ddae124f039dfd23f4b19bbe88cee8e528ae51e5d6f3a21d7bfad4c2e6f263fe5eb59ca974d039fc0e4c3345692fb5320bdae4bd3b42a45ff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #156: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7fffffffaaaaaaaaffffffffffffffffe9a2538f37b28a2c513dee40fecbb71a67e6f659cdde869a2f65f094e94e5b4dfad636bbf95192feeed01b0f3deb7460a37e0a51f258b7aeb51dfe592f5cfd5685bbe58712c8d9233c62886437c38ba0", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #157: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdb62f26b5f2a2b26f6de86d42ad8a13da3ab3cccd0459b201de009e526adf21f22eb6412505aec05c6545f029932087e490d05511e8ec1f599617bb367f9ecaaf805f51efcc4803403f9b1ae0124890f06a43fedcddb31830f6669af292895cb0", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #158: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbb1d9ac949dd748cd02bbbe749bd351cd57b38bb61403d700686aa7b4c90851e84db645868eab35e3a9fd80e056e2e855435e3a6b68d75a50a854625fe0d7f356d2589ac655edc9a11ef3e075eddda9abf92e72171570ef7bf43a2ee39338cfe", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #159: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd66755a00638cdaec1c732513ca0234ece52545dac11f816e818f725b4f60aaf291b9e47c56278662d75c0983b22ca8ea6aa5059b7a2ff7637eb2975e386ad66349aa8ff283d0f77c18d6d11dc062165fd13c3c0310679c1408302a16854ecfbd", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #160: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd55a00c9fcdaebb6032513ca0234ecfffe98ebe492fdf02e48ca48e982beb3669f3ec2f13caf04d0192b47fb4c5311fb6d4dc6b0a9e802e5327f7ec5ee8e4834df97e3e468b7d0db867d6ecfe81e2b0f9531df87efdb47c1338ac321fefe5a432", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #161: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdab40193f9b5d76c064a27940469d9fffd31d7c925fbe05c919491d3057d66cd2d92b200aefcab6ac7dafd9acaf2fa10b3180235b8f46b4503e4693c670fccc885ef2f3aebf5b317475336256768f7c19efb7352d27e4cccadc85b6b8ab922c72", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #162: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdca0234ebb5fdcb13ca0234ecffffffffcb0dadbbc7f549f8a26b4408d0dc86000a88361eb92ecca2625b38e5f98bbabb96bf179b3d76fc48140a3bcd881523cde6bdf56033f84a5054035597375d90866aa2c96b86a41ccf6edebf47298ad489", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #163: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff3ea3677e082b9310572620ae19933a9e65b285598711c77298815ad3d0fb17ccd8fafe827e0c1afc5d8d80366e2b20e7f14a563a2ba50469d84375e868612569d39e2bb9f554355564646de99ac602cc6349cf8c1e236a7de7637d93", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #164: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd266666663bbbbbbbe6666666666666665b37902e023fab7c8f055d86e5cc41f4836f33bbc1dc0d3d3abbcef0d91f11e2ac4181076c9af0a22b1e4309d3edb2769ab443ff6f901e30c773867582997c2bec2b0cb8120d760236f3a95bbe881f75", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #165: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff36db6db7a492492492492492146c573f4c6dfc8d08a443e258970b0992f99fbe973ed4a299719baee4b432741237034dec8d72ba5103cb33e55feeb8033dd0e91134c734174889f3ebcf1b7a1ac05767289280ee7a794cebd6e69697", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #166: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff2aaaaaab7fffffffffffffffc815d0e60b3e596ecb1ad3a27cfd49c4d35ba58da30197d378e618ec0fa7e2e2d12cffd73ebbb2049d130bba434af09eff83986e6875e41ea432b7585a49b3a6c77cbb3c47919f8e82874c794635c1d2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #167: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7fffffff55555555ffffffffffffffffd344a71e6f651458a27bdc81fd976e378651ce490f1b46d73f3ff475149be29136697334a519d7ddab0725c8d0793224e11c65bd8ca92dc8bc9ae82911f0b52751ce21dd9003ae60900bd825f590cc28", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #168: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd3fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192aa6d8e1b12c831a0da8795650ff95f101ed921d9e2f72b15b1cdaca9826b9cfc6def6d63e2bc5c089570394a4bc9f892d5e6c7a6a637b20469a58c106ad486bf37", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #169: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d8ecd64a4eeba466815ddf3a4de9a8e6abd9c5db0a01eb80343553da648428f0ae580bae933b4ef2997cbdbb0922328ca9a410f627a0f7dff24cb4d920e15428911e7f8cc365a8a88eb81421a361ccc2b99e309d8dcd9a98ba83c3949d893e3", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #170: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569bb726660235793aa9957a61e76e00c2c435109cf9a15dd624d53f4301047856b5b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963838a40f2a36092e9004e92d8d940cf5638550ce672ce8b8d4e15eba5499249e9", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #171: point duplication during verification", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569bb726660235793aa9957a61e76e00c2c435109cf9a15dd624d53f4301047856b5b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc469637c75bf0c5c9f6d17ffb16d2726bf30a9c7aaf31a8d317472b1ea145ab66db616", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #172: duplication bug", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000001555555550000000055555555555555553ef7a8e48d07df81a693439654210c706adda82b90261b0f319faa0d878665a6b6da497f09c903176222c34acfef72a647e6f50dcc40ad5d9b59f7602bb222fad71a41bf5e1f9df4959a364c62e488d9", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #173: point with x-coordinate 0", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023555555550000000055555555555555553ef7a8e48d07df81a693439654210c703333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aa9dd86d3b5f4a13e8511083b78002081c53ff467f11ebd98a51a633db76665d25045d5c8200c89f2fa10d849349226d21d8dfaed6ff8d5cb3e1b7e17474ebc18f7", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #175: comparison with point at infinity ", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978555555550000000055555555555555553ef7a8e48d07df81a693439654210c704fea55b32cb32aca0c12c4cd0abfb4e64b0f5a516e578c016591a93f5a0fbcc5d7d3fd10b2be668c547b212f6bb14c88f0fecd38a8a4b2c785ed3be62ce4b280", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #176: extreme value for k and edgecase s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63ccc6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #177: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7851c2bbad08e54ec7a9af99f49f03644d6ec6d59b207fec98de85a7d15b956efcee9960283045075684b410be8d0f7494b91aa2379f60727319f10ddeb0fe9d6", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #178: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc476699783333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaaf6417c8a670584e388676949e53da7fc55911ff68318d1bf3061205acb19c48f8f2b743df34ad0f72674acb7505929784779cd9ac916c3669ead43026ab6d43f", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #179: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997849249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185501421277be45a5eefec6c639930d636032565af420cf3373f557faa7f8a06438673d6cb6076e1cfcdc7dfe7384c8e5cac08d74501f2ae6e89cad195d0aa1371", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #180: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997816a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb0d935bf9ffc115a527735f729ca8a4ca23ee01a4894adf0e3415ac84e808bb343195a3762fea29ed38912bd9ea6c4fde70c3050893a4375850ce61d82eba33c5", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #181: extreme value for k", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296555555550000000055555555555555553ef7a8e48d07df81a693439654210c705e59f50708646be8a589355014308e60b668fb670196206c41e748e64e4dca215de37fee5c97bcaf7144d5b459982f52eeeafbdf03aacbafef38e213624a01de", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #182: extreme value for k and edgecase s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc169fb797325843faff2f7a5b5445da9e2fd6226f7ef90ef0bfe924104b02db8e7bbb8de662c7b9b1cf9b22f7a2e582bd46d581d68878efb2b861b131d8a1d667", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #183: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7271cd89c000143096b62d4e9e4ca885aef2f7023d18affdaf8b7b548981487540a1c6e954e32108435b55fa385b0f76481a609b9149ccb4b02b2ca47fe8e4da5", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #184: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2963333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa3d0bc7ed8f09d2cb7ddb46ebc1ed799ab1563a9ab84bf524587a220afe499c12e22dc3b3c103824a4f378d96adb0a408abf19ce7d68aa6244f78cb216fa3f8df", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #185: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29649249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185a6c885ade1a4c566f9bb010d066974abb281797fa701288c721bcbd23663a9b72e424b690957168d193a6096fc77a2b004a9c7d467e007e1f2058458f98af316", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #186: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29616a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb8d3c2c2c3b765ba8289e6ac3812572a25bf75df62d87ab7330c3bdbad9ebfa5c4c6845442d66935b238578d43aec54f7caa1621d1af241d4632e0b780c423f5d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #187: extreme value for k", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #188: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502344a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #189: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #190: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502344a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #191: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855b292a619339f6e567a305c951c0dcbcc42d16e47f219f9e98e76e09d8770b34a0177e60492c5a8242f76f07bfe3661bde59ec2a17ce5bd2dab2abebdf89a62e204aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #192: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "dc1921946f4af96a2856e7be399007c9e807bdf4c5332f19f59ec9dd1bb8c7b3530bd6b0c9af2d69ba897f6b5fb59695cfbf33afe66dbadcf5b8d2a2a6538e23d85e489cb7a161fd55ededcedbf4cc0c0987e3e3f0f242cae934c72caa3f43e904aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #193: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023a8ea150cb80125d7381c4c1f1da8e9de2711f9917060406a73d7904519e51388f3ab9fa68bd47973a73b2d40480c2ba50c22c9d76ec217257288293285449b8604aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #194: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "de47c9b27eb8d300dbb5f2c353e632c393262cf06340c4fa7f1b40c4cbd36f90986e65933ef2ed4ee5aada139f52b70539aaf63f00a91f29c69178490d57fb713dafedfb8da6189d372308cbf1489bbbdabf0c0217d1c0ff0f701aaa7a694b9c04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #195: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d434e262a49eab7781e353a3565e482550dd0fd5defa013c7f29745eff3569f19b0c0a93f267fb6052fd8077be769c2b98953195d7bc10de844218305c6ba17a4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #196: x-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f910fe774355c04d060f76d79fd7a772e421463489221bf0a33add0be9b1979110b500dcba1c69a8fbd43fa4f57f743ce124ca8b91a1f325f3fac6181175df557374f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #197: x-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91bb40bf217bed3fb3950c7d39f03d36dc8e3b2cd79693f125bfd06595ee1135e3541bf3532351ebb032710bdb6a1bf1bfc89a1e291ac692b3fa4780745bb556774f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #198: x-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91664eb7ee6db84a34df3c86ea31389a5405badd5ca99231ff556d3e75a233e73a59f3c752e52eca46137642490a51560ce0badc678754b8f72e51a2901426a1bd3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #199: y-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f914cd0429bbabd2827009d6fcd843d4ce39c3e42e2d1631fd001985a79d1fd8b439638bf12dd682f60be7ef1d0e0d98f08b7bca77a1a2b869ae466189d2acdabe33cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #200: y-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91e56c6ea2d1b017091c44d8b6cb62b9f460e3ce9aed5e5fd41e8added97c56c04a308ec31f281e955be20b457e463440b4fcf2b80258078207fc1378180f89b553cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #201: y-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f911158a08d291500b4cabed3346d891eee57c176356a2624fb011f8fbbf3466830228a8c486a736006e082325b85290c5bc91f378b75d487dda46798c18f2855193cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #202: y-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91b1db9289649f59410ea36b0c0fc8d6aa2687b29176939dd23e0dde56d309fa9d3e1535e4280559015b0dbd987366dcf43a6d1af5c23c7d584e1c3f48a12513363cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #203: y-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91b7b16e762286cb96446aa8d4e6e7578b0a341a79f2dd1a220ac6f0ca4e24ed86ddc60a700a139b04661c547d07bbb0721780146df799ccf55e55234ecb8f12bc3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #204: y-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d82a7c2717261187c8e00d8df963ff35d796edad36bc6e6bd1c91c670d9105b43dcabddaf8fcaa61f4603e7cbac0f3c0351ecd5988efb23f680d07debd1399292829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #205: x-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f915eb9c8845de68eb13d5befe719f462d77787802baff30ce96a5cba063254af782c026ae9be2e2a5e7ca0ff9bbd92fb6e44972186228ee9a62b87ddbe2ef66fb52829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #206: x-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9196843dd03c22abd2f3b782b170239f90f277921becc117d0404a8e4e36230c28f2be378f526f74a543f67165976de9ed9a31214eb4d7e6db19e1ede123dd991d2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #207: x-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91766456dce1857c906f9996af729339464d27e9d98edc2d0e3b760297067421f6402385ecadae0d8081dccaf5d19037ec4e55376eced699e93646bfbbf19d0b41fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #208: x-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91c605c4b2edeab20419e6518a11b2dbc2b97ed8b07cced0b19c34f777de7b9fd9edf0f612c5f46e03c719647bc8af1b29b2cde2eda700fb1cff5e159d47326dbafffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #209: x-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d48b68e6cabfe03cf6141c9ac54141f210e64485d9929ad7b732bfe3b7eb8a84feedae50c61bd00e19dc26f9b7e2265e4508c389109ad2f208f0772315b6c941fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #210: x-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91b7c81457d4aeb6aa65957098569f0479710ad7f6595d5874c35a93d12a5dd4c7b7961a0b652878c2d568069a432ca18a1a9199f2ca574dad4b9e3a05c0a1cdb300000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #211: x-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f916b01332ddb6edfa9a30a1321d5858e1ee3cf97e263e669f8de5e9652e76ff3f75939545fced457309a6a04ace2bd0f70139c8f7d86b02cb1cc58f9e69e96cd5a00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #212: x-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91efdb884720eaeadc349f9fc356b6c0344101cd2fd8436b7d0e6a4fb93f106361f24bee6ad5dc05f7613975473aadf3aacba9e77de7d69b6ce48cb60d8113385d00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #213: x-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9131230428405560dcb88fb5a646836aea9b23a23dd973dcbe8014c87b8b20eb070f9344d6e812ce166646747694a41b0aaf97374e19f3c5fb8bd7ae3d9bd0beffbcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #214: y-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91caa797da65b320ab0d5c470cda0b36b294359c7db9841d679174db34c4855743cf543a62f23e212745391aaf7505f345123d2685ee3b941d3de6d9b36242e5a0bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #215: y-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f917e5f0ab5d900d3d3d7867657e5d6d36519bc54084536e7d21c336ed8001859459450c07f201faec94b82dfb322e5ac676688294aad35aa72e727ff0b19b646aabcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #216: y-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d7d70c581ae9e3f66dc6a480bf037ae23f8a1e4a2136fe4b03aa69f0ca25b35689c460f8a5a5c2bbba962c8a3ee833a413e85658e62a59e2af41d9127cc47224bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #217: y-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91341c1b9ff3c83dd5e0dfa0bf68bcdf4bb7aa20c625975e5eeee34bb396266b3472b69f061b750fd5121b22b11366fad549c634e77765a017902a67099e0a4469bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #218: y-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9170bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a9bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #219: y-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e184cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd762927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #1: signature malleability", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #2: Legacy:ASN encoding of s misses leading 0", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #3: valid", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502329a3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #118: modify first byte of integer", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e98b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #120: modify last byte of integer", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b491568475b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #121: modify last byte of integer", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1800b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b491568472927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #124: truncated integer", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #133: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023d45c5740946b2a147f59262ee6f5bc90bd01ed280528b62b3aed5fc93f06f739b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #134: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #137: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18b329f47aa2bbd0a4c384ee1493b1f518ada018ef05465583885980861905228a2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #139: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e184cd60b865d442f5a3c7b11eb6c4e0ae79578ec6353a20bf783ecb4b6ea97b8252927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #143: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #177: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #178: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #179: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #180: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #181: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #187: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #188: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #189: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #190: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #191: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #197: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #198: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #199: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #200: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #201: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #207: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #208: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #209: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #210: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #211: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #217: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #218: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #219: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #220: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #221: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "70239dd877f7c944c422f44dea4ed1a52f2627416faf2f072fa50c772ed6f80764a1aab5000d0e804f3e2fc02bdee9be8ff312334e2ba16d11547c97711c898e6af015971cc30be6d1a206d4e013e0997772a2f91d73286ffd683b9bb2cf4f1b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #230: Edge case for Shamir multiplication", + "NoBenchmark": false + }, + { + "Input": "00000000690ed426ccf17803ebe2bd0884bcd58a1bb5e7477ead3645f356e7a916aea964a2f6506d6f78c81c91fc7e8bded7d397738448de1e19a0ec580bf266252cd762130c6667cfe8b7bc47d27d78391e8e80c578d1cd38c3ff033be928e92927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #231: special case hash", + "NoBenchmark": false + }, + { + "Input": "7300000000213f2a525c6035725235c2f696ad3ebb5ee47f140697ad25770d919cc98be2347d469bf476dfc26b9b733df2d26d6ef524af917c665baccb23c882093496459effe2d8d70727b82462f61d0ec1b7847929d10ea631dacb16b56c322927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #232: special case hash", + "NoBenchmark": false + }, + { + "Input": "ddf2000000005e0be0635b245f0b97978afd25daadeb3edb4a0161c27fe0604573b3c90ecd390028058164524dde892703dce3dea0d53fa8093999f07ab8aa432f67b0b8e20636695bb7d8bf0a651c802ed25a395387b5f4188c0c4075c886342927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #233: special case hash", + "NoBenchmark": false + }, + { + "Input": "67ab1900000000784769c4ecb9e164d6642b8499588b89855be1ec355d0841a0bfab3098252847b328fadf2f89b95c851a7f0eb390763378f37e90119d5ba3ddbdd64e234e832b1067c2d058ccb44d978195ccebb65c2aaf1e2da9b8b4987e3b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #234: special case hash", + "NoBenchmark": false + }, + { + "Input": "a2bf09460000000076d7dbeffe125eaf02095dff252ee905e296b6350fc311cf204a9784074b246d8bf8bf04a4ceb1c1f1c9aaab168b1596d17093c5cd21d2cd51cce41670636783dc06a759c8847868a406c2506fe17975582fe648d1d88b522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #235: special case hash", + "NoBenchmark": false + }, + { + "Input": "3554e827c700000000e1e75e624a06b3a0a353171160858129e15c544e4f0e65ed66dc34f551ac82f63d4aa4f81fe2cb0031a91d1314f835027bca0f1ceeaa0399ca123aa09b13cd194a422e18d5fda167623c3f6e5d4d6abb8953d67c0c48c72927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #236: special case hash", + "NoBenchmark": false + }, + { + "Input": "9b6cd3b812610000000026941a0f0bb53255ea4c9fd0cb3426e3a54b9fc6965c060b700bef665c68899d44f2356a578d126b062023ccc3c056bf0f60a237012b8d186c027832965f4fcc78a3366ca95dedbb410cbef3f26d6be5d581c11d36102927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #237: special case hash", + "NoBenchmark": false + }, + { + "Input": "883ae39f50bf0100000000e7561c26fc82a52baa51c71ca877162f93c4ae01869f6adfe8d5eb5b2c24d7aa7934b6cf29c93ea76cd313c9132bb0c8e38c96831db26a9c9e40e55ee0890c944cf271756c906a33e66b5bd15e051593883b5e99022927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #238: special case hash", + "NoBenchmark": false + }, + { + "Input": "a1ce5d6e5ecaf28b0000000000fa7cd010540f420fb4ff7401fe9fce011d0ba6a1af03ca91677b673ad2f33615e56174a1abf6da168cebfa8868f4ba273f16b720aa73ffe48afa6435cd258b173d0c2377d69022e7d098d75caf24c8c5e06b1c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #239: special case hash", + "NoBenchmark": false + }, + { + "Input": "8ea5f645f373f580930000000038345397330012a8ee836c5494cdffd5ee8054fdc70602766f8eed11a6c99a71c973d5659355507b843da6e327a28c11893db93df5349688a085b137b1eacf456a9e9e0f6d15ec0078ca60a7f83f2b10d213502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #240: special case hash", + "NoBenchmark": false + }, + { + "Input": "660570d323e9f75fa734000000008792d65ce93eabb7d60d8d9c1bbdcb5ef305b516a314f2fce530d6537f6a6c49966c23456f63c643cf8e0dc738f7b876e675d39ffd033c92b6d717dd536fbc5efdf1967c4bd80954479ba66b0120cd16fff22927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #241: special case hash", + "NoBenchmark": false + }, + { + "Input": "d0462673154cce587dde8800000000e98d35f1f45cf9c3bf46ada2de4c568c343b2cbf046eac45842ecb7984d475831582717bebb6492fd0a485c101e29ff0a84c9b7b47a98b0f82de512bc9313aaf51701099cac5f76e68c8595fc1c1d992582927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #242: special case hash", + "NoBenchmark": false + }, + { + "Input": "bd90640269a7822680cedfef000000000caef15a6171059ab83e7b4418d7278f30c87d35e636f540841f14af54e2f9edd79d0312cfa1ab656c3fb15bfde48dcf47c15a5a82d24b75c85a692bd6ecafeb71409ede23efd08e0db9abf6340677ed2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #243: special case hash", + "NoBenchmark": false + }, + { + "Input": "33239a52d72f1311512e41222a00000000d2dcceb301c54b4beae8e284788a7338686ff0fda2cef6bc43b58cfe6647b9e2e8176d168dec3c68ff262113760f52067ec3b651f422669601662167fa8717e976e2db5e6a4cf7c2ddabb3fde9d67d2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #244: special case hash", + "NoBenchmark": false + }, + { + "Input": "b8d64fbcd4a1c10f1365d4e6d95c000000007ee4a21a1cbe1dc84c2d941ffaf144a3e23bf314f2b344fc25c7f2de8b6af3e17d27f5ee844b225985ab6e2775cf2d48e223205e98041ddc87be532abed584f0411f5729500493c9cc3f4dd15e862927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #245: special case hash", + "NoBenchmark": false + }, + { + "Input": "01603d3982bf77d7a3fef3183ed092000000003a227420db4088b20fe0e9d84a2ded5b7ec8e90e7bf11f967a3d95110c41b99db3b5aa8d330eb9d638781688e97d5792c53628155e1bfc46fb1a67e3088de049c328ae1f44ec69238a009808f92927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #246: special case hash", + "NoBenchmark": false + }, + { + "Input": "9ea6994f1e0384c8599aa02e6cf66d9c000000004d89ef50b7e9eb0cfbff7363bdae7bcb580bf335efd3bc3d31870f923eaccafcd40ec2f605976f15137d8b8ff6dfa12f19e525270b0106eecfe257499f373a4fb318994f24838122ce7ec3c72927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #247: special case hash", + "NoBenchmark": false + }, + { + "Input": "d03215a8401bcf16693979371a01068a4700000000e2fa5bf692bc670905b18c50f9c4f0cd6940e162720957ffff513799209b78596956d21ece251c2401f1c6d7033a0a787d338e889defaaabb106b95a4355e411a59c32aa5167dfab2447262927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #248: special case hash", + "NoBenchmark": false + }, + { + "Input": "307bfaaffb650c889c84bf83f0300e5dc87e000000008408fd5f64b582e3bb14f612820687604fa01906066a378d67540982e29575d019aabe90924ead5c860d3f9367702dd7dd4f75ea98afd20e328a1a99f4857b316525328230ce294b0fef2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #249: special case hash", + "NoBenchmark": false + }, + { + "Input": "bab5c4f4df540d7b33324d36bb0c157551527c00000000e4af574bb4d54ea6b89505e407657d6e8bc93db5da7aa6f5081f61980c1949f56b0f2f507da5782a7ac60d31904e3669738ffbeccab6c3656c08e0ed5cb92b3cfa5e7f71784f9c50212927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #250: special case hash", + "NoBenchmark": false + }, + { + "Input": "d4ba47f6ae28f274e4f58d8036f9c36ec2456f5b00000000c3b869197ef5e15ebbd16fbbb656b6d0d83e6a7787cd691b08735aed371732723e1c68a40404517d9d8e35dba96028b7787d91315be675877d2d097be5e8ee34560e3e7fd25c0f002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #251: special case hash", + "NoBenchmark": false + }, + { + "Input": "79fd19c7235ea212f29f1fa00984342afe0f10aafd00000000801e47f8c184e12ec9760122db98fd06ea76848d35a6da442d2ceef7559a30cf57c61e92df327e7ab271da90859479701fccf86e462ee3393fb6814c27b760c4963625c0a198782927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #252: special case hash", + "NoBenchmark": false + }, + { + "Input": "8c291e8eeaa45adbaf9aba5c0583462d79cbeb7ac97300000000a37ea6700cda54e76b7683b6650baa6a7fc49b1c51eed9ba9dd463221f7a4f1005a89fe00c592ea076886c773eb937ec1cc8374b7915cfd11b1c1ae1166152f2f7806a31c8fd2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #253: special case hash", + "NoBenchmark": false + }, + { + "Input": "0eaae8641084fa979803efbfb8140732f4cdcf66c3f78a000000003c278a6b215291deaf24659ffbbce6e3c26f6021097a74abdbb69be4fb10419c0c496c946665d6fcf336d27cc7cdb982bb4e4ecef5827f84742f29f10abf83469270a03dc32927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #254: special case hash", + "NoBenchmark": false + }, + { + "Input": "e02716d01fb23a5a0068399bf01bab42ef17c6d96e13846c00000000afc0f89d207a3241812d75d947419dc58efb05e8003b33fc17eb50f9d15166a88479f107cdee749f2e492b213ce80b32d0574f62f1c5d70793cf55e382d5caadf75927672927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #255: special case hash", + "NoBenchmark": false + }, + { + "Input": "9eb0bf583a1a6b9a194e9a16bc7dab2a9061768af89d00659a00000000fc7de16554e49f82a855204328ac94913bf01bbe84437a355a0a37c0dee3cf81aa7728aea00de2507ddaf5c94e1e126980d3df16250a2eaebc8be486effe7f22b4f9292927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #256: special case hash", + "NoBenchmark": false + }, + { + "Input": "62aac98818b3b84a2c214f0d5e72ef286e1030cb53d9a82b690e00000000cd15a54c5062648339d2bff06f71c88216c26c6e19b4d80a8c602990ac82707efdfce99bbe7fcfafae3e69fd016777517aa01056317f467ad09aff09be73c9731b0d2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #257: special case hash", + "NoBenchmark": false + }, + { + "Input": "3760a7f37cf96218f29ae43732e513efd2b6f552ea4b6895464b9300000000c8975bd7157a8d363b309f1f444012b1a1d23096593133e71b4ca8b059cff37eaf7faa7a28b1c822baa241793f2abc930bd4c69840fe090f2aacc46786bf9196222927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #258: special case hash", + "NoBenchmark": false + }, + { + "Input": "0da0a1d2851d33023834f2098c0880096b4320bea836cd9cbb6ff6c8000000005694a6f84b8f875c276afd2ebcfe4d61de9ec90305afb1357b95b3e0da43885e0dffad9ffd0b757d8051dec02ebdf70d8ee2dc5c7870c0823b6ccc7c679cbaa42927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #259: special case hash", + "NoBenchmark": false + }, + { + "Input": "ffffffff293886d3086fd567aafd598f0fe975f735887194a764a231e82d289aa0c30e8026fdb2b4b4968a27d16a6d08f7098f1a98d21620d7454ba9790f1ba65e470453a8a399f15baf463f9deceb53acc5ca64459149688bd2760c654243392927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #260: special case hash", + "NoBenchmark": false + }, + { + "Input": "7bffffffff2376d1e3c03445a072e24326acdc4ce127ec2e0e8d9ca99527e7b7614ea84acf736527dd73602cd4bb4eea1dfebebd5ad8aca52aa0228cf7b99a88737cc85f5f2d2f60d1b8183f3ed490e4de14368e96a9482c2a4dd193195c902f2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #261: special case hash", + "NoBenchmark": false + }, + { + "Input": "a2b5ffffffffebb251b085377605a224bc80872602a6e467fd016807e97fa395bead6734ebe44b810d3fb2ea00b1732945377338febfd439a8d74dfbd0f942fa6bb18eae36616a7d3cad35919fd21a8af4bbe7a10f73b3e036a46b103ef56e2a2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #262: special case hash", + "NoBenchmark": false + }, + { + "Input": "641227ffffffff6f1b96fa5f097fcf3cc1a3c256870d45a67b83d0967d4b20c0499625479e161dacd4db9d9ce64854c98d922cbf212703e9654fae182df9bad242c177cf37b8193a0131108d97819edd9439936028864ac195b64fca76d9d6932927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #263: special case hash", + "NoBenchmark": false + }, + { + "Input": "958415d8ffffffffabad03e2fc662dc3ba203521177502298df56f36600e0f8b08f16b8093a8fb4d66a2c8065b541b3d31e3bfe694f6b89c50fb1aaa6ff6c9b29d6455e2d5d1779748573b611cb95d4a21f967410399b39b535ba3e5af81ca2e2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #264: special case hash", + "NoBenchmark": false + }, + { + "Input": "f1d8de4858ffffffff1281093536f47fe13deb04e1fbe8fb954521b6975420f8be26231b6191658a19dd72ddb99ed8f8c579b6938d19bce8eed8dc2b338cb5f8e1d9a32ee56cffed37f0f22b2dcb57d5c943c14f79694a03b9c5e96952575c892927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #265: special case hash", + "NoBenchmark": false + }, + { + "Input": "0927895f2802ffffffff10782dd14a3b32dc5d47c05ef6f1876b95c81fc31def15e76880898316b16204ac920a02d58045f36a229d4aa4f812638c455abe0443e74d357d3fcb5c8c5337bd6aba4178b455ca10e226e13f9638196506a19391232927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #266: special case hash", + "NoBenchmark": false + }, + { + "Input": "60907984aa7e8effffffff4f332862a10a57c3063fb5a30624cf6a0c3ac80589352ecb53f8df2c503a45f9846fc28d1d31e6307d3ddbffc1132315cc07f16dad1348dfa9c482c558e1d05c5242ca1c39436726ecd28258b1899792887dd0a3c62927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #267: special case hash", + "NoBenchmark": false + }, + { + "Input": "c6ff198484939170ffffffff0af42cda50f9a5f50636ea6942d6b9b8cd6ae1e24a40801a7e606ba78a0da9882ab23c7677b8642349ed3d652c5bfa5f2a9558fb3a49b64848d682ef7f605f2832f7384bdc24ed2925825bf8ea77dc59817257822927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #268: special case hash", + "NoBenchmark": false + }, + { + "Input": "de030419345ca15c75ffffffff8074799b9e0956cc43135d16dfbe4d27d7e68deacc5e1a8304a74d2be412b078924b3bb3511bac855c05c9e5e9e44df3d61e967451cd8e18d6ed1885dd827714847f96ec4bb0ed4c36ce9808db8f714204f6d12927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #269: special case hash", + "NoBenchmark": false + }, + { + "Input": "6f0e3eeaf42b28132b88fffffffff6c8665604d34acb19037e1ab78caaaac6ff2f7a5e9e5771d424f30f67fdab61e8ce4f8cd1214882adb65f7de94c31577052ac4e69808345809b44acb0b2bd889175fb75dd050c5a449ab9528f8f78daa10c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #270: special case hash", + "NoBenchmark": false + }, + { + "Input": "cdb549f773b3e62b3708d1ffffffffbe48f7c0591ddcae7d2cb222d1f8017ab9ffcda40f792ce4d93e7e0f0e95e1a2147dddd7f6487621c30a03d710b330021979938b55f8a17f7ed7ba9ade8f2065a1fa77618f0b67add8d58c422c2453a49a2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #271: special case hash", + "NoBenchmark": false + }, + { + "Input": "2c3f26f96a3ac0051df4989bffffffff9fd64886c1dc4f9924d8fd6f0edb048481f2359c4faba6b53d3e8c8c3fcc16a948350f7ab3a588b28c17603a431e39a8cd6f6a5cc3b55ead0ff695d06c6860b509e46d99fccefb9f7f9e101857f743002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #272: special case hash", + "NoBenchmark": false + }, + { + "Input": "ac18f8418c55a2502cb7d53f9affffffff5c31d89fda6a6b8476397c04edf411dfc8bf520445cbb8ee1596fb073ea283ea130251a6fdffa5c3f5f2aaf75ca808048e33efce147c9dd92823640e338e68bfd7d0dc7a4905b3a7ac711e577e90e72927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #273: special case hash", + "NoBenchmark": false + }, + { + "Input": "4f9618f98e2d3a15b24094f72bb5ffffffffa2fd3e2893683e5a6ab8cf0ee610ad019f74c6941d20efda70b46c53db166503a0e393e932f688227688ba6a576293320eb7ca0710255346bdbb3102cdcf7964ef2e0988e712bc05efe16c1993452927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #274: special case hash", + "NoBenchmark": false + }, + { + "Input": "422e82a3d56ed10a9cc21d31d37a25ffffffff67edf7c40204caae73ab0bc75aac8096842e8add68c34e78ce11dd71e4b54316bd3ebf7fffdeb7bd5a3ebc1883f5ca2f4f23d674502d4caf85d187215d36e3ce9f0ce219709f21a3aac003b7a82927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #275: special case hash", + "NoBenchmark": false + }, + { + "Input": "7075d245ccc3281b6e7b329ff738fbb417a5ffffffffa0842d9890b5cf95d018677b2d3a59b18a5ff939b70ea002250889ddcd7b7b9d776854b4943693fb92f76b4ba856ade7677bf30307b21f3ccda35d2f63aee81efd0bab6972cc0795db552927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #276: special case hash", + "NoBenchmark": false + }, + { + "Input": "3c80de54cd9226989443d593fa4fd6597e280ebeffffffffc1847eb76c217a95479e1ded14bcaed0379ba8e1b73d3115d84d31d4b7c30e1f05e1fc0d5957cfb0918f79e35b3d89487cf634a4f05b2e0c30857ca879f97c771e877027355b24432927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #277: special case hash", + "NoBenchmark": false + }, + { + "Input": "de21754e29b85601980bef3d697ea2770ce891a8cdffffffffc7906aa794b39b43dfccd0edb9e280d9a58f01164d55c3d711e14b12ac5cf3b64840ead512a0a31dbe33fa8ba84533cd5c4934365b3442ca1174899b78ef9a3199f495843897722927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #278: special case hash", + "NoBenchmark": false + }, + { + "Input": "8f65d92927cfb86a84dd59623fb531bb599e4d5f7289ffffffff2f1f2f57881c5b09ab637bd4caf0f4c7c7e4bca592fea20e9087c259d26a38bb4085f0bbff1145b7eb467b6748af618e9d80d6fdcd6aa24964e5a13f885bca8101de08eb0d752927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #279: special case hash", + "NoBenchmark": false + }, + { + "Input": "6b63e9a74e092120160bea3877dace8a2cc7cd0e8426cbfffffffffafc8c3ca85e9b1c5a028070df5728c5c8af9b74e0667afa570a6cfa0114a5039ed15ee06fb1360907e2d9785ead362bb8d7bd661b6c29eeffd3c5037744edaeb9ad990c202927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #280: special case hash", + "NoBenchmark": false + }, + { + "Input": "fc28259702a03845b6d75219444e8b43d094586e249c8699ffffffffe852512e0671a0a85c2b72d54a2fb0990e34538b4890050f5a5712f6d1a7a5fb8578f32edb1846bab6b7361479ab9c3285ca41291808f27fd5bd4fdac720e5854713694c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #281: special case hash", + "NoBenchmark": false + }, + { + "Input": "1273b4502ea4e3bccee044ee8e8db7f774ecbcd52e8ceb571757ffffffffe20a7673f8526748446477dbbb0590a45492c5d7d69859d301abbaedb35b2095103a3dc70ddf9c6b524d886bed9e6af02e0e4dec0d417a414fed3807ef4422913d7c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #282: special case hash", + "NoBenchmark": false + }, + { + "Input": "08fb565610a79baa0c566c66228d81814f8c53a15b96e602fb49ffffffffff6e7f085441070ecd2bb21285089ebb1aa6450d1a06c36d3ff39dfd657a796d12b5249712012029870a2459d18d47da9aa492a5e6cb4b2d8dafa9e4c5c54a2b9a8b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #283: special case hash", + "NoBenchmark": false + }, + { + "Input": "d59291cc2cf89f3087715fcb1aa4e79aa2403f748e97d7cd28ecaefeffffffff914c67fb61dd1e27c867398ea7322d5ab76df04bc5aa6683a8e0f30a5d287348fa07474031481dda4953e3ac1959ee8cea7e66ec412b38d6c96d28f6d37304ea2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #284: special case hash", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000fffffffffffffffffffffffcffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e0ad99500288d466940031d72a9f5445a4d43784640855bf0a69874d2de5fe103c5011e6ef2c42dcd50d5d3d29f99ae6eba2c80c9244f4c5422f0979ff0c3ba5e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #286: r too large", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254eab05fd9d0de26b9ce6f4819652d9fc69193d0aa398f0fba8013e09c58220455419235271228c786759095d12b75af0692dd4103f19f6a8c32f49435a1e9b8d45", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #287: r,s are large", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd909135bdb6799286170f5ead2de4f6511453fe50914f3df2de54a36383df8dd480984f39a1ff38a86a68aa4201b6be5dfbfecf876219710b07badf6fdd4c6c5611feb97390d9826e7a06dfb41871c940d74415ed3cac2089f1445019bb55ed95", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #288: r and s^-1 have a large Hamming weight", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd27b4577ca009376f71303fd5dd227dcef5deb773ad5f5a84360644669ca249a54201b4272944201c3294f5baa9a3232b6dd687495fcc19a70a95bc602b4f7c0595c37eba9ee8171c1bb5ac6feaf753bc36f463e3aef16629572c0c0a8fb0800e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #289: r and s^-1 have a large Hamming weight", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6324d5555555550000000055555555555555553ef7a8e48d07df81a693439654210c70083539fbee44625e3acaafa2fcb41349392cef0633a1b8fabecee0c133b10e99915c1ebe7bf00df8535196770a58047ae2a402f26326bb7d41d4d7616337911e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #301: r and s^-1 are close to n", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8555555550000000055555555555555553ef7a8e48d07df81a693439654210c70b533d4695dd5b8c5e07757e55e6e516f7e2c88fa0239e23f60e8ec07dd70f2871b134ee58cc583278456863f33c3a85d881f7d4a39850143e29d4eaf009afe47", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #304: point at infinity during verify", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a97fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8f50d371b91bfb1d7d14e1323523bc3aa8cbf2c57f9e284de628c8b4536787b86f94ad887ac94d527247cd2e7d0c8b1291c553c9730405380b14cbb209f5fa2dd", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #305: edge case for signature malleability", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a97fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a968ec6e298eafe16539156ce57a14b04a7047c221bafc3a582eaeb0d857c4d94697bed1af17850117fdb39b2324f220a5698ed16c426a27335bb385ac8ca6fb30", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #306: edge case for signature malleability", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023555555550000000055555555555555553ef7a8e48d07df81a693439654210c70bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502369da0364734d2e530fece94019265fefb781a0f1b08f6c8897bdf6557927c8b866d2d3c7dcd518b23d726960f069ad71a933d86ef8abbcce8b20f71e2a847002", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #307: u1 == 1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023555555550000000055555555555555553ef7a8e48d07df81a693439654210c7044a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52ed8adc00023a8edc02576e2b63e3e30621a471e2b2320620187bf067a1ac1ff3233e2b50ec09807accb36131fff95ed12a09a86b4ea9690aa32861576ba2362e1", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #308: u1 == n - 1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023555555550000000055555555555555553ef7a8e48d07df81a693439654210c70555555550000000055555555555555553ef7a8e48d07df81a693439654210c703623ac973ced0a56fa6d882f03a7d5c7edca02cfc7b2401fab3690dbe75ab7858db06908e64b28613da7257e737f39793da8e713ba0643b92e9bb3252be7f8fe", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #309: u2 == 1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023555555550000000055555555555555553ef7a8e48d07df81a693439654210c70aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1cf04ea77e9622523d894b93ff52dc3027b31959503b6fa3890e5e04263f922f1e8528fb7c006b3983c8b8400e57b4ed71740c2f3975438821199bedeaecab2e9", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #310: u2 == n - 1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffde91e1ba60fdedb76a46bcb51dc0b8b4b7e019f0a28721885fa5d3a8196623397db7a2c8a1ab573e5929dc24077b508d7e683d49227996bda3e9f78dbeff773504f417f3bc9a88075c2e0aadd5a13311730cf7cc76a82f11a36eaf08a6c99a206", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #311: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdea5843ffeb73af94313ba4831b53fe24f799e525b1e8e8c87b59b95b430ad9dead11c7a5b396862f21974dc4752fadeff994efe9bbd05ab413765ea80b6e1f1de3f0640e8ac6edcf89cff53c40e265bb94078a343736df07aa0318fc7fe1ff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #312: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd03ffcabf2f1b4d2a65190db1680d62bb994e41c5251cd73b3c3dfc5e5bafc035d0bc472e0d7c81ebaed3a6ef96c18613bb1fea6f994326fbe80e00dfde67c7e9986c723ea4843d48389b946f64ad56c83ad70ff17ba85335667d1bb9fa619efd", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #313: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd4dfbc401f971cd304b33dfdb17d0fed0fe4c1a88ae648e0d2847f74977534989a0a44ca947d66a2acb736008b9c08d1ab2ad03776e02640f78495d458dd51c326337fe5cf8c4604b1f1c409dc2d872d4294a4762420df43a30a2392e40426add", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #314: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbc4024761cd2ffd43dfdb17d0fed112b988977055cd3a8e54971eba9cda5ca71c9c2115290d008b45fb65fad0f602389298c25420b775019d42b62c3ce8a96b73877d25a8080dc02d987ca730f0405c2c9dbefac46f9e601cc3f06e9713973fd", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #315: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd788048ed39a5ffa77bfb62fa1fda2257742bf35d128fb3459f2a0c909ee86f915eca1ef4c287dddc66b8bccf1b88e8a24c0018962f3c5e7efa83bc1a5ff6033e5e79c4cb2c245b8c45abdce8a8e4da758d92a607c32cd407ecaef22f1c934a71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #316: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd476d9131fd381bd917d0fed112bc9e0a5924b5ed5b11167edd8b23582b3cb15e5caaa030e7fdf0e4936bc7ab5a96353e0a01e4130c3f8bf22d473e317029a47adeb6adc462f7058f2a20d371e9702254e9b201642005b3ceda926b42b178bef9", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #317: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8374253e3e21bd154448d0a8f640fe46fafa8b19ce78d538f6cc0a19662d3601c2fd20bac06e555bb8ac0ce69eb1ea20f83a1fc3501c8a66469b1a31f619b0986237050779f52b615bd7b8d76a25fc95ca2ed32525c75f27ffc87ac397e6cbaf", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #318: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd357cfd3be4d01d413c5b9ede36cba5452c11ee7fe14879e749ae6a2d897a52d63fd6a1ca7f77fb3b0bbe726c372010068426e11ea6ae78ce17bedae4bba86ced03ce5516406bf8cfaab8745eac1cd69018ad6f50b5461872ddfc56e0db3c8ff4", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #319: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd29798c5c0ee287d4a5e8e6b799fd86b8df5225298e6ffc807cd2f2bc27a0a6d89cb8e51e27a5ae3b624a60d6dc32734e4989db20e9bca3ede1edf7b086911114b4c104ab3c677e4b36d6556e8ad5f523410a19f2e277aa895fc57322b4427544", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #320: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0b70f22c781092452dca1a5711fa3a5a1f72add1bf52c2ff7cae4820b30078dda3e52c156dcaf10502620b7955bc2b40bc78ef3d569e1223c262512d8f49602a4a2039f31c1097024ad3cc86e57321de032355463486164cf192944977df147f", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #321: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd16e1e458f021248a5b9434ae23f474b43ee55ba37ea585fef95c90416600f1baf19b78928720d5bee8e670fb90010fb15c37bf91b58a5157c3f3c059b2655e88cf701ec962fb4a11dcf273f5dc357e58468560c7cfeb942d074abd4329260509", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #322: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd2252d6856831b6cf895e4f0535eeaf0e5e5809753df848fe760ad86219016a9783a744459ecdfb01a5cf52b27a05bb7337482d242f235d7b4cb89345545c90a8c05d49337b9649813287de9ffe90355fd905df5f3c32945828121f37cc50de6e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #323: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd81ffe55f178da695b28c86d8b406b15dab1a9e39661a3ae017fbe390ac0972c3dd13c6b34c56982ddae124f039dfd23f4b19bbe88cee8e528ae51e5d6f3a21d7bfad4c2e6f263fe5eb59ca974d039fc0e4c3345692fb5320bdae4bd3b42a45ff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #324: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7fffffffaaaaaaaaffffffffffffffffe9a2538f37b28a2c513dee40fecbb71a67e6f659cdde869a2f65f094e94e5b4dfad636bbf95192feeed01b0f3deb7460a37e0a51f258b7aeb51dfe592f5cfd5685bbe58712c8d9233c62886437c38ba0", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #325: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdb62f26b5f2a2b26f6de86d42ad8a13da3ab3cccd0459b201de009e526adf21f22eb6412505aec05c6545f029932087e490d05511e8ec1f599617bb367f9ecaaf805f51efcc4803403f9b1ae0124890f06a43fedcddb31830f6669af292895cb0", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #326: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbb1d9ac949dd748cd02bbbe749bd351cd57b38bb61403d700686aa7b4c90851e84db645868eab35e3a9fd80e056e2e855435e3a6b68d75a50a854625fe0d7f356d2589ac655edc9a11ef3e075eddda9abf92e72171570ef7bf43a2ee39338cfe", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #327: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd66755a00638cdaec1c732513ca0234ece52545dac11f816e818f725b4f60aaf291b9e47c56278662d75c0983b22ca8ea6aa5059b7a2ff7637eb2975e386ad66349aa8ff283d0f77c18d6d11dc062165fd13c3c0310679c1408302a16854ecfbd", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #328: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd55a00c9fcdaebb6032513ca0234ecfffe98ebe492fdf02e48ca48e982beb3669f3ec2f13caf04d0192b47fb4c5311fb6d4dc6b0a9e802e5327f7ec5ee8e4834df97e3e468b7d0db867d6ecfe81e2b0f9531df87efdb47c1338ac321fefe5a432", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #329: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdab40193f9b5d76c064a27940469d9fffd31d7c925fbe05c919491d3057d66cd2d92b200aefcab6ac7dafd9acaf2fa10b3180235b8f46b4503e4693c670fccc885ef2f3aebf5b317475336256768f7c19efb7352d27e4cccadc85b6b8ab922c72", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #330: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdca0234ebb5fdcb13ca0234ecffffffffcb0dadbbc7f549f8a26b4408d0dc86000a88361eb92ecca2625b38e5f98bbabb96bf179b3d76fc48140a3bcd881523cde6bdf56033f84a5054035597375d90866aa2c96b86a41ccf6edebf47298ad489", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #331: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff3ea3677e082b9310572620ae19933a9e65b285598711c77298815ad3d0fb17ccd8fafe827e0c1afc5d8d80366e2b20e7f14a563a2ba50469d84375e868612569d39e2bb9f554355564646de99ac602cc6349cf8c1e236a7de7637d93", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #332: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd266666663bbbbbbbe6666666666666665b37902e023fab7c8f055d86e5cc41f4836f33bbc1dc0d3d3abbcef0d91f11e2ac4181076c9af0a22b1e4309d3edb2769ab443ff6f901e30c773867582997c2bec2b0cb8120d760236f3a95bbe881f75", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #333: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff36db6db7a492492492492492146c573f4c6dfc8d08a443e258970b0992f99fbe973ed4a299719baee4b432741237034dec8d72ba5103cb33e55feeb8033dd0e91134c734174889f3ebcf1b7a1ac05767289280ee7a794cebd6e69697", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #334: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff2aaaaaab7fffffffffffffffc815d0e60b3e596ecb1ad3a27cfd49c4d35ba58da30197d378e618ec0fa7e2e2d12cffd73ebbb2049d130bba434af09eff83986e6875e41ea432b7585a49b3a6c77cbb3c47919f8e82874c794635c1d2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #335: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7fffffff55555555ffffffffffffffffd344a71e6f651458a27bdc81fd976e378651ce490f1b46d73f3ff475149be29136697334a519d7ddab0725c8d0793224e11c65bd8ca92dc8bc9ae82911f0b52751ce21dd9003ae60900bd825f590cc28", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #336: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd3fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192aa6d8e1b12c831a0da8795650ff95f101ed921d9e2f72b15b1cdaca9826b9cfc6def6d63e2bc5c089570394a4bc9f892d5e6c7a6a637b20469a58c106ad486bf37", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #337: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d8ecd64a4eeba466815ddf3a4de9a8e6abd9c5db0a01eb80343553da648428f0ae580bae933b4ef2997cbdbb0922328ca9a410f627a0f7dff24cb4d920e15428911e7f8cc365a8a88eb81421a361ccc2b99e309d8dcd9a98ba83c3949d893e3", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #338: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569bb726660235793aa9957a61e76e00c2c435109cf9a15dd624d53f4301047856b5b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963838a40f2a36092e9004e92d8d940cf5638550ce672ce8b8d4e15eba5499249e9", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #339: point duplication during verification", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569bb726660235793aa9957a61e76e00c2c435109cf9a15dd624d53f4301047856b5b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc469637c75bf0c5c9f6d17ffb16d2726bf30a9c7aaf31a8d317472b1ea145ab66db616", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #340: duplication bug", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023555555550000000055555555555555553ef7a8e48d07df81a693439654210c703333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aa9dd86d3b5f4a13e8511083b78002081c53ff467f11ebd98a51a633db76665d25045d5c8200c89f2fa10d849349226d21d8dfaed6ff8d5cb3e1b7e17474ebc18f7", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #343: comparison with point at infinity ", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978555555550000000055555555555555553ef7a8e48d07df81a693439654210c704fea55b32cb32aca0c12c4cd0abfb4e64b0f5a516e578c016591a93f5a0fbcc5d7d3fd10b2be668c547b212f6bb14c88f0fecd38a8a4b2c785ed3be62ce4b280", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #344: extreme value for k and edgecase s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63ccc6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #345: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7851c2bbad08e54ec7a9af99f49f03644d6ec6d59b207fec98de85a7d15b956efcee9960283045075684b410be8d0f7494b91aa2379f60727319f10ddeb0fe9d6", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #346: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc476699783333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaaf6417c8a670584e388676949e53da7fc55911ff68318d1bf3061205acb19c48f8f2b743df34ad0f72674acb7505929784779cd9ac916c3669ead43026ab6d43f", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #347: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997849249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185501421277be45a5eefec6c639930d636032565af420cf3373f557faa7f8a06438673d6cb6076e1cfcdc7dfe7384c8e5cac08d74501f2ae6e89cad195d0aa1371", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #348: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050237cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997816a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb0d935bf9ffc115a527735f729ca8a4ca23ee01a4894adf0e3415ac84e808bb343195a3762fea29ed38912bd9ea6c4fde70c3050893a4375850ce61d82eba33c5", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #349: extreme value for k", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296555555550000000055555555555555553ef7a8e48d07df81a693439654210c705e59f50708646be8a589355014308e60b668fb670196206c41e748e64e4dca215de37fee5c97bcaf7144d5b459982f52eeeafbdf03aacbafef38e213624a01de", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #350: extreme value for k and edgecase s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc169fb797325843faff2f7a5b5445da9e2fd6226f7ef90ef0bfe924104b02db8e7bbb8de662c7b9b1cf9b22f7a2e582bd46d581d68878efb2b861b131d8a1d667", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #351: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7271cd89c000143096b62d4e9e4ca885aef2f7023d18affdaf8b7b548981487540a1c6e954e32108435b55fa385b0f76481a609b9149ccb4b02b2ca47fe8e4da5", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #352: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2963333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa3d0bc7ed8f09d2cb7ddb46ebc1ed799ab1563a9ab84bf524587a220afe499c12e22dc3b3c103824a4f378d96adb0a408abf19ce7d68aa6244f78cb216fa3f8df", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #353: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29649249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185a6c885ade1a4c566f9bb010d066974abb281797fa701288c721bcbd23663a9b72e424b690957168d193a6096fc77a2b004a9c7d467e007e1f2058458f98af316", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #354: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050236b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29616a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb8d3c2c2c3b765ba8289e6ac3812572a25bf75df62d87ab7330c3bdbad9ebfa5c4c6845442d66935b238578d43aec54f7caa1621d1af241d4632e0b780c423f5d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #355: extreme value for k", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #356: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502344a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #357: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #358: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502344a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #359: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855b292a619339f6e567a305c951c0dcbcc42d16e47f219f9e98e76e09d8770b34a0177e60492c5a8242f76f07bfe3661bde59ec2a17ce5bd2dab2abebdf89a62e204aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #360: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "dc1921946f4af96a2856e7be399007c9e807bdf4c5332f19f59ec9dd1bb8c7b3530bd6b0c9af2d69ba897f6b5fb59695cfbf33afe66dbadcf5b8d2a2a6538e23d85e489cb7a161fd55ededcedbf4cc0c0987e3e3f0f242cae934c72caa3f43e904aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #361: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023a8ea150cb80125d7381c4c1f1da8e9de2711f9917060406a73d7904519e51388f3ab9fa68bd47973a73b2d40480c2ba50c22c9d76ec217257288293285449b8604aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #362: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "de47c9b27eb8d300dbb5f2c353e632c393262cf06340c4fa7f1b40c4cbd36f90986e65933ef2ed4ee5aada139f52b70539aaf63f00a91f29c69178490d57fb713dafedfb8da6189d372308cbf1489bbbdabf0c0217d1c0ff0f701aaa7a694b9c04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #363: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d434e262a49eab7781e353a3565e482550dd0fd5defa013c7f29745eff3569f19b0c0a93f267fb6052fd8077be769c2b98953195d7bc10de844218305c6ba17a4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #364: x-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f910fe774355c04d060f76d79fd7a772e421463489221bf0a33add0be9b1979110b500dcba1c69a8fbd43fa4f57f743ce124ca8b91a1f325f3fac6181175df557374f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #365: x-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91bb40bf217bed3fb3950c7d39f03d36dc8e3b2cd79693f125bfd06595ee1135e3541bf3532351ebb032710bdb6a1bf1bfc89a1e291ac692b3fa4780745bb556774f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #366: x-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91664eb7ee6db84a34df3c86ea31389a5405badd5ca99231ff556d3e75a233e73a59f3c752e52eca46137642490a51560ce0badc678754b8f72e51a2901426a1bd3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #367: y-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f914cd0429bbabd2827009d6fcd843d4ce39c3e42e2d1631fd001985a79d1fd8b439638bf12dd682f60be7ef1d0e0d98f08b7bca77a1a2b869ae466189d2acdabe33cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #368: y-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91e56c6ea2d1b017091c44d8b6cb62b9f460e3ce9aed5e5fd41e8added97c56c04a308ec31f281e955be20b457e463440b4fcf2b80258078207fc1378180f89b553cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #369: y-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f911158a08d291500b4cabed3346d891eee57c176356a2624fb011f8fbbf3466830228a8c486a736006e082325b85290c5bc91f378b75d487dda46798c18f2855193cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #370: y-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91b1db9289649f59410ea36b0c0fc8d6aa2687b29176939dd23e0dde56d309fa9d3e1535e4280559015b0dbd987366dcf43a6d1af5c23c7d584e1c3f48a12513363cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #371: y-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91b7b16e762286cb96446aa8d4e6e7578b0a341a79f2dd1a220ac6f0ca4e24ed86ddc60a700a139b04661c547d07bbb0721780146df799ccf55e55234ecb8f12bc3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #372: y-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d82a7c2717261187c8e00d8df963ff35d796edad36bc6e6bd1c91c670d9105b43dcabddaf8fcaa61f4603e7cbac0f3c0351ecd5988efb23f680d07debd1399292829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #373: x-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f915eb9c8845de68eb13d5befe719f462d77787802baff30ce96a5cba063254af782c026ae9be2e2a5e7ca0ff9bbd92fb6e44972186228ee9a62b87ddbe2ef66fb52829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #374: x-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9196843dd03c22abd2f3b782b170239f90f277921becc117d0404a8e4e36230c28f2be378f526f74a543f67165976de9ed9a31214eb4d7e6db19e1ede123dd991d2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #375: x-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91766456dce1857c906f9996af729339464d27e9d98edc2d0e3b760297067421f6402385ecadae0d8081dccaf5d19037ec4e55376eced699e93646bfbbf19d0b41fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #376: x-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91c605c4b2edeab20419e6518a11b2dbc2b97ed8b07cced0b19c34f777de7b9fd9edf0f612c5f46e03c719647bc8af1b29b2cde2eda700fb1cff5e159d47326dbafffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #377: x-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d48b68e6cabfe03cf6141c9ac54141f210e64485d9929ad7b732bfe3b7eb8a84feedae50c61bd00e19dc26f9b7e2265e4508c389109ad2f208f0772315b6c941fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #378: x-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91b7c81457d4aeb6aa65957098569f0479710ad7f6595d5874c35a93d12a5dd4c7b7961a0b652878c2d568069a432ca18a1a9199f2ca574dad4b9e3a05c0a1cdb300000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #379: x-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f916b01332ddb6edfa9a30a1321d5858e1ee3cf97e263e669f8de5e9652e76ff3f75939545fced457309a6a04ace2bd0f70139c8f7d86b02cb1cc58f9e69e96cd5a00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #380: x-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91efdb884720eaeadc349f9fc356b6c0344101cd2fd8436b7d0e6a4fb93f106361f24bee6ad5dc05f7613975473aadf3aacba9e77de7d69b6ce48cb60d8113385d00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #381: x-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9131230428405560dcb88fb5a646836aea9b23a23dd973dcbe8014c87b8b20eb070f9344d6e812ce166646747694a41b0aaf97374e19f3c5fb8bd7ae3d9bd0beffbcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #382: y-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91caa797da65b320ab0d5c470cda0b36b294359c7db9841d679174db34c4855743cf543a62f23e212745391aaf7505f345123d2685ee3b941d3de6d9b36242e5a0bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #383: y-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f917e5f0ab5d900d3d3d7867657e5d6d36519bc54084536e7d21c336ed8001859459450c07f201faec94b82dfb322e5ac676688294aad35aa72e727ff0b19b646aabcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #384: y-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d7d70c581ae9e3f66dc6a480bf037ae23f8a1e4a2136fe4b03aa69f0ca25b35689c460f8a5a5c2bbba962c8a3ee833a413e85658e62a59e2af41d9127cc47224bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #385: y-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91341c1b9ff3c83dd5e0dfa0bf68bcdf4bb7aa20c625975e5eeee34bb396266b3472b69f061b750fd5121b22b11366fad549c634e77765a017902a67099e0a4469bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #386: y-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9170bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a9bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #387: y-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e184cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd762927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1: signature malleability", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #2: Legacy:ASN encoding of s misses leading 0", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #3: valid", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502329a3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #118: modify first byte of integer", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e98b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #120: modify last byte of integer", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b491568475b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #121: modify last byte of integer", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1800b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b491568472927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #124: truncated integer", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #133: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023d45c5740946b2a147f59262ee6f5bc90bd01ed280528b62b3aed5fc93f06f739b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #134: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #137: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18b329f47aa2bbd0a4c384ee1493b1f518ada018ef05465583885980861905228a2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #139: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e184cd60b865d442f5a3c7b11eb6c4e0ae79578ec6353a20bf783ecb4b6ea97b8252927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #143: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #177: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #178: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #179: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #180: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #181: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #187: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #188: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #189: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #190: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #191: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #197: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #198: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #199: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #200: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #201: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #207: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #208: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #209: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #210: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #211: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #217: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #218: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #219: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #220: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #221: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "70239dd877f7c944c422f44dea4ed1a52f2627416faf2f072fa50c772ed6f80764a1aab5000d0e804f3e2fc02bdee9be8ff312334e2ba16d11547c97711c898e6af015971cc30be6d1a206d4e013e0997772a2f91d73286ffd683b9bb2cf4f1b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #230: Edge case for Shamir multiplication", + "NoBenchmark": false + }, + { + "Input": "00000000690ed426ccf17803ebe2bd0884bcd58a1bb5e7477ead3645f356e7a916aea964a2f6506d6f78c81c91fc7e8bded7d397738448de1e19a0ec580bf266252cd762130c6667cfe8b7bc47d27d78391e8e80c578d1cd38c3ff033be928e92927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #231: special case hash", + "NoBenchmark": false + }, + { + "Input": "7300000000213f2a525c6035725235c2f696ad3ebb5ee47f140697ad25770d919cc98be2347d469bf476dfc26b9b733df2d26d6ef524af917c665baccb23c882093496459effe2d8d70727b82462f61d0ec1b7847929d10ea631dacb16b56c322927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #232: special case hash", + "NoBenchmark": false + }, + { + "Input": "ddf2000000005e0be0635b245f0b97978afd25daadeb3edb4a0161c27fe0604573b3c90ecd390028058164524dde892703dce3dea0d53fa8093999f07ab8aa432f67b0b8e20636695bb7d8bf0a651c802ed25a395387b5f4188c0c4075c886342927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #233: special case hash", + "NoBenchmark": false + }, + { + "Input": "67ab1900000000784769c4ecb9e164d6642b8499588b89855be1ec355d0841a0bfab3098252847b328fadf2f89b95c851a7f0eb390763378f37e90119d5ba3ddbdd64e234e832b1067c2d058ccb44d978195ccebb65c2aaf1e2da9b8b4987e3b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #234: special case hash", + "NoBenchmark": false + }, + { + "Input": "a2bf09460000000076d7dbeffe125eaf02095dff252ee905e296b6350fc311cf204a9784074b246d8bf8bf04a4ceb1c1f1c9aaab168b1596d17093c5cd21d2cd51cce41670636783dc06a759c8847868a406c2506fe17975582fe648d1d88b522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #235: special case hash", + "NoBenchmark": false + }, + { + "Input": "3554e827c700000000e1e75e624a06b3a0a353171160858129e15c544e4f0e65ed66dc34f551ac82f63d4aa4f81fe2cb0031a91d1314f835027bca0f1ceeaa0399ca123aa09b13cd194a422e18d5fda167623c3f6e5d4d6abb8953d67c0c48c72927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #236: special case hash", + "NoBenchmark": false + }, + { + "Input": "9b6cd3b812610000000026941a0f0bb53255ea4c9fd0cb3426e3a54b9fc6965c060b700bef665c68899d44f2356a578d126b062023ccc3c056bf0f60a237012b8d186c027832965f4fcc78a3366ca95dedbb410cbef3f26d6be5d581c11d36102927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #237: special case hash", + "NoBenchmark": false + }, + { + "Input": "883ae39f50bf0100000000e7561c26fc82a52baa51c71ca877162f93c4ae01869f6adfe8d5eb5b2c24d7aa7934b6cf29c93ea76cd313c9132bb0c8e38c96831db26a9c9e40e55ee0890c944cf271756c906a33e66b5bd15e051593883b5e99022927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #238: special case hash", + "NoBenchmark": false + }, + { + "Input": "a1ce5d6e5ecaf28b0000000000fa7cd010540f420fb4ff7401fe9fce011d0ba6a1af03ca91677b673ad2f33615e56174a1abf6da168cebfa8868f4ba273f16b720aa73ffe48afa6435cd258b173d0c2377d69022e7d098d75caf24c8c5e06b1c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #239: special case hash", + "NoBenchmark": false + }, + { + "Input": "8ea5f645f373f580930000000038345397330012a8ee836c5494cdffd5ee8054fdc70602766f8eed11a6c99a71c973d5659355507b843da6e327a28c11893db93df5349688a085b137b1eacf456a9e9e0f6d15ec0078ca60a7f83f2b10d213502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #240: special case hash", + "NoBenchmark": false + }, + { + "Input": "660570d323e9f75fa734000000008792d65ce93eabb7d60d8d9c1bbdcb5ef305b516a314f2fce530d6537f6a6c49966c23456f63c643cf8e0dc738f7b876e675d39ffd033c92b6d717dd536fbc5efdf1967c4bd80954479ba66b0120cd16fff22927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #241: special case hash", + "NoBenchmark": false + }, + { + "Input": "d0462673154cce587dde8800000000e98d35f1f45cf9c3bf46ada2de4c568c343b2cbf046eac45842ecb7984d475831582717bebb6492fd0a485c101e29ff0a84c9b7b47a98b0f82de512bc9313aaf51701099cac5f76e68c8595fc1c1d992582927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #242: special case hash", + "NoBenchmark": false + }, + { + "Input": "bd90640269a7822680cedfef000000000caef15a6171059ab83e7b4418d7278f30c87d35e636f540841f14af54e2f9edd79d0312cfa1ab656c3fb15bfde48dcf47c15a5a82d24b75c85a692bd6ecafeb71409ede23efd08e0db9abf6340677ed2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #243: special case hash", + "NoBenchmark": false + }, + { + "Input": "33239a52d72f1311512e41222a00000000d2dcceb301c54b4beae8e284788a7338686ff0fda2cef6bc43b58cfe6647b9e2e8176d168dec3c68ff262113760f52067ec3b651f422669601662167fa8717e976e2db5e6a4cf7c2ddabb3fde9d67d2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #244: special case hash", + "NoBenchmark": false + }, + { + "Input": "b8d64fbcd4a1c10f1365d4e6d95c000000007ee4a21a1cbe1dc84c2d941ffaf144a3e23bf314f2b344fc25c7f2de8b6af3e17d27f5ee844b225985ab6e2775cf2d48e223205e98041ddc87be532abed584f0411f5729500493c9cc3f4dd15e862927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #245: special case hash", + "NoBenchmark": false + }, + { + "Input": "01603d3982bf77d7a3fef3183ed092000000003a227420db4088b20fe0e9d84a2ded5b7ec8e90e7bf11f967a3d95110c41b99db3b5aa8d330eb9d638781688e97d5792c53628155e1bfc46fb1a67e3088de049c328ae1f44ec69238a009808f92927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #246: special case hash", + "NoBenchmark": false + }, + { + "Input": "9ea6994f1e0384c8599aa02e6cf66d9c000000004d89ef50b7e9eb0cfbff7363bdae7bcb580bf335efd3bc3d31870f923eaccafcd40ec2f605976f15137d8b8ff6dfa12f19e525270b0106eecfe257499f373a4fb318994f24838122ce7ec3c72927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #247: special case hash", + "NoBenchmark": false + }, + { + "Input": "d03215a8401bcf16693979371a01068a4700000000e2fa5bf692bc670905b18c50f9c4f0cd6940e162720957ffff513799209b78596956d21ece251c2401f1c6d7033a0a787d338e889defaaabb106b95a4355e411a59c32aa5167dfab2447262927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #248: special case hash", + "NoBenchmark": false + }, + { + "Input": "307bfaaffb650c889c84bf83f0300e5dc87e000000008408fd5f64b582e3bb14f612820687604fa01906066a378d67540982e29575d019aabe90924ead5c860d3f9367702dd7dd4f75ea98afd20e328a1a99f4857b316525328230ce294b0fef2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #249: special case hash", + "NoBenchmark": false + }, + { + "Input": "bab5c4f4df540d7b33324d36bb0c157551527c00000000e4af574bb4d54ea6b89505e407657d6e8bc93db5da7aa6f5081f61980c1949f56b0f2f507da5782a7ac60d31904e3669738ffbeccab6c3656c08e0ed5cb92b3cfa5e7f71784f9c50212927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #250: special case hash", + "NoBenchmark": false + }, + { + "Input": "d4ba47f6ae28f274e4f58d8036f9c36ec2456f5b00000000c3b869197ef5e15ebbd16fbbb656b6d0d83e6a7787cd691b08735aed371732723e1c68a40404517d9d8e35dba96028b7787d91315be675877d2d097be5e8ee34560e3e7fd25c0f002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #251: special case hash", + "NoBenchmark": false + }, + { + "Input": "79fd19c7235ea212f29f1fa00984342afe0f10aafd00000000801e47f8c184e12ec9760122db98fd06ea76848d35a6da442d2ceef7559a30cf57c61e92df327e7ab271da90859479701fccf86e462ee3393fb6814c27b760c4963625c0a198782927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #252: special case hash", + "NoBenchmark": false + }, + { + "Input": "8c291e8eeaa45adbaf9aba5c0583462d79cbeb7ac97300000000a37ea6700cda54e76b7683b6650baa6a7fc49b1c51eed9ba9dd463221f7a4f1005a89fe00c592ea076886c773eb937ec1cc8374b7915cfd11b1c1ae1166152f2f7806a31c8fd2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #253: special case hash", + "NoBenchmark": false + }, + { + "Input": "0eaae8641084fa979803efbfb8140732f4cdcf66c3f78a000000003c278a6b215291deaf24659ffbbce6e3c26f6021097a74abdbb69be4fb10419c0c496c946665d6fcf336d27cc7cdb982bb4e4ecef5827f84742f29f10abf83469270a03dc32927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #254: special case hash", + "NoBenchmark": false + }, + { + "Input": "e02716d01fb23a5a0068399bf01bab42ef17c6d96e13846c00000000afc0f89d207a3241812d75d947419dc58efb05e8003b33fc17eb50f9d15166a88479f107cdee749f2e492b213ce80b32d0574f62f1c5d70793cf55e382d5caadf75927672927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #255: special case hash", + "NoBenchmark": false + }, + { + "Input": "9eb0bf583a1a6b9a194e9a16bc7dab2a9061768af89d00659a00000000fc7de16554e49f82a855204328ac94913bf01bbe84437a355a0a37c0dee3cf81aa7728aea00de2507ddaf5c94e1e126980d3df16250a2eaebc8be486effe7f22b4f9292927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #256: special case hash", + "NoBenchmark": false + }, + { + "Input": "62aac98818b3b84a2c214f0d5e72ef286e1030cb53d9a82b690e00000000cd15a54c5062648339d2bff06f71c88216c26c6e19b4d80a8c602990ac82707efdfce99bbe7fcfafae3e69fd016777517aa01056317f467ad09aff09be73c9731b0d2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #257: special case hash", + "NoBenchmark": false + }, + { + "Input": "3760a7f37cf96218f29ae43732e513efd2b6f552ea4b6895464b9300000000c8975bd7157a8d363b309f1f444012b1a1d23096593133e71b4ca8b059cff37eaf7faa7a28b1c822baa241793f2abc930bd4c69840fe090f2aacc46786bf9196222927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #258: special case hash", + "NoBenchmark": false + }, + { + "Input": "0da0a1d2851d33023834f2098c0880096b4320bea836cd9cbb6ff6c8000000005694a6f84b8f875c276afd2ebcfe4d61de9ec90305afb1357b95b3e0da43885e0dffad9ffd0b757d8051dec02ebdf70d8ee2dc5c7870c0823b6ccc7c679cbaa42927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #259: special case hash", + "NoBenchmark": false + }, + { + "Input": "ffffffff293886d3086fd567aafd598f0fe975f735887194a764a231e82d289aa0c30e8026fdb2b4b4968a27d16a6d08f7098f1a98d21620d7454ba9790f1ba65e470453a8a399f15baf463f9deceb53acc5ca64459149688bd2760c654243392927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #260: special case hash", + "NoBenchmark": false + }, + { + "Input": "7bffffffff2376d1e3c03445a072e24326acdc4ce127ec2e0e8d9ca99527e7b7614ea84acf736527dd73602cd4bb4eea1dfebebd5ad8aca52aa0228cf7b99a88737cc85f5f2d2f60d1b8183f3ed490e4de14368e96a9482c2a4dd193195c902f2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #261: special case hash", + "NoBenchmark": false + }, + { + "Input": "a2b5ffffffffebb251b085377605a224bc80872602a6e467fd016807e97fa395bead6734ebe44b810d3fb2ea00b1732945377338febfd439a8d74dfbd0f942fa6bb18eae36616a7d3cad35919fd21a8af4bbe7a10f73b3e036a46b103ef56e2a2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #262: special case hash", + "NoBenchmark": false + }, + { + "Input": "641227ffffffff6f1b96fa5f097fcf3cc1a3c256870d45a67b83d0967d4b20c0499625479e161dacd4db9d9ce64854c98d922cbf212703e9654fae182df9bad242c177cf37b8193a0131108d97819edd9439936028864ac195b64fca76d9d6932927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #263: special case hash", + "NoBenchmark": false + }, + { + "Input": "958415d8ffffffffabad03e2fc662dc3ba203521177502298df56f36600e0f8b08f16b8093a8fb4d66a2c8065b541b3d31e3bfe694f6b89c50fb1aaa6ff6c9b29d6455e2d5d1779748573b611cb95d4a21f967410399b39b535ba3e5af81ca2e2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #264: special case hash", + "NoBenchmark": false + }, + { + "Input": "f1d8de4858ffffffff1281093536f47fe13deb04e1fbe8fb954521b6975420f8be26231b6191658a19dd72ddb99ed8f8c579b6938d19bce8eed8dc2b338cb5f8e1d9a32ee56cffed37f0f22b2dcb57d5c943c14f79694a03b9c5e96952575c892927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #265: special case hash", + "NoBenchmark": false + }, + { + "Input": "0927895f2802ffffffff10782dd14a3b32dc5d47c05ef6f1876b95c81fc31def15e76880898316b16204ac920a02d58045f36a229d4aa4f812638c455abe0443e74d357d3fcb5c8c5337bd6aba4178b455ca10e226e13f9638196506a19391232927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #266: special case hash", + "NoBenchmark": false + }, + { + "Input": "60907984aa7e8effffffff4f332862a10a57c3063fb5a30624cf6a0c3ac80589352ecb53f8df2c503a45f9846fc28d1d31e6307d3ddbffc1132315cc07f16dad1348dfa9c482c558e1d05c5242ca1c39436726ecd28258b1899792887dd0a3c62927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #267: special case hash", + "NoBenchmark": false + }, + { + "Input": "c6ff198484939170ffffffff0af42cda50f9a5f50636ea6942d6b9b8cd6ae1e24a40801a7e606ba78a0da9882ab23c7677b8642349ed3d652c5bfa5f2a9558fb3a49b64848d682ef7f605f2832f7384bdc24ed2925825bf8ea77dc59817257822927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #268: special case hash", + "NoBenchmark": false + }, + { + "Input": "de030419345ca15c75ffffffff8074799b9e0956cc43135d16dfbe4d27d7e68deacc5e1a8304a74d2be412b078924b3bb3511bac855c05c9e5e9e44df3d61e967451cd8e18d6ed1885dd827714847f96ec4bb0ed4c36ce9808db8f714204f6d12927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #269: special case hash", + "NoBenchmark": false + }, + { + "Input": "6f0e3eeaf42b28132b88fffffffff6c8665604d34acb19037e1ab78caaaac6ff2f7a5e9e5771d424f30f67fdab61e8ce4f8cd1214882adb65f7de94c31577052ac4e69808345809b44acb0b2bd889175fb75dd050c5a449ab9528f8f78daa10c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #270: special case hash", + "NoBenchmark": false + }, + { + "Input": "cdb549f773b3e62b3708d1ffffffffbe48f7c0591ddcae7d2cb222d1f8017ab9ffcda40f792ce4d93e7e0f0e95e1a2147dddd7f6487621c30a03d710b330021979938b55f8a17f7ed7ba9ade8f2065a1fa77618f0b67add8d58c422c2453a49a2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #271: special case hash", + "NoBenchmark": false + }, + { + "Input": "2c3f26f96a3ac0051df4989bffffffff9fd64886c1dc4f9924d8fd6f0edb048481f2359c4faba6b53d3e8c8c3fcc16a948350f7ab3a588b28c17603a431e39a8cd6f6a5cc3b55ead0ff695d06c6860b509e46d99fccefb9f7f9e101857f743002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #272: special case hash", + "NoBenchmark": false + }, + { + "Input": "ac18f8418c55a2502cb7d53f9affffffff5c31d89fda6a6b8476397c04edf411dfc8bf520445cbb8ee1596fb073ea283ea130251a6fdffa5c3f5f2aaf75ca808048e33efce147c9dd92823640e338e68bfd7d0dc7a4905b3a7ac711e577e90e72927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #273: special case hash", + "NoBenchmark": false + }, + { + "Input": "4f9618f98e2d3a15b24094f72bb5ffffffffa2fd3e2893683e5a6ab8cf0ee610ad019f74c6941d20efda70b46c53db166503a0e393e932f688227688ba6a576293320eb7ca0710255346bdbb3102cdcf7964ef2e0988e712bc05efe16c1993452927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #274: special case hash", + "NoBenchmark": false + }, + { + "Input": "422e82a3d56ed10a9cc21d31d37a25ffffffff67edf7c40204caae73ab0bc75aac8096842e8add68c34e78ce11dd71e4b54316bd3ebf7fffdeb7bd5a3ebc1883f5ca2f4f23d674502d4caf85d187215d36e3ce9f0ce219709f21a3aac003b7a82927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #275: special case hash", + "NoBenchmark": false + }, + { + "Input": "7075d245ccc3281b6e7b329ff738fbb417a5ffffffffa0842d9890b5cf95d018677b2d3a59b18a5ff939b70ea002250889ddcd7b7b9d776854b4943693fb92f76b4ba856ade7677bf30307b21f3ccda35d2f63aee81efd0bab6972cc0795db552927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #276: special case hash", + "NoBenchmark": false + }, + { + "Input": "3c80de54cd9226989443d593fa4fd6597e280ebeffffffffc1847eb76c217a95479e1ded14bcaed0379ba8e1b73d3115d84d31d4b7c30e1f05e1fc0d5957cfb0918f79e35b3d89487cf634a4f05b2e0c30857ca879f97c771e877027355b24432927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #277: special case hash", + "NoBenchmark": false + }, + { + "Input": "de21754e29b85601980bef3d697ea2770ce891a8cdffffffffc7906aa794b39b43dfccd0edb9e280d9a58f01164d55c3d711e14b12ac5cf3b64840ead512a0a31dbe33fa8ba84533cd5c4934365b3442ca1174899b78ef9a3199f495843897722927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #278: special case hash", + "NoBenchmark": false + }, + { + "Input": "8f65d92927cfb86a84dd59623fb531bb599e4d5f7289ffffffff2f1f2f57881c5b09ab637bd4caf0f4c7c7e4bca592fea20e9087c259d26a38bb4085f0bbff1145b7eb467b6748af618e9d80d6fdcd6aa24964e5a13f885bca8101de08eb0d752927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #279: special case hash", + "NoBenchmark": false + }, + { + "Input": "6b63e9a74e092120160bea3877dace8a2cc7cd0e8426cbfffffffffafc8c3ca85e9b1c5a028070df5728c5c8af9b74e0667afa570a6cfa0114a5039ed15ee06fb1360907e2d9785ead362bb8d7bd661b6c29eeffd3c5037744edaeb9ad990c202927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #280: special case hash", + "NoBenchmark": false + }, + { + "Input": "fc28259702a03845b6d75219444e8b43d094586e249c8699ffffffffe852512e0671a0a85c2b72d54a2fb0990e34538b4890050f5a5712f6d1a7a5fb8578f32edb1846bab6b7361479ab9c3285ca41291808f27fd5bd4fdac720e5854713694c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #281: special case hash", + "NoBenchmark": false + }, + { + "Input": "1273b4502ea4e3bccee044ee8e8db7f774ecbcd52e8ceb571757ffffffffe20a7673f8526748446477dbbb0590a45492c5d7d69859d301abbaedb35b2095103a3dc70ddf9c6b524d886bed9e6af02e0e4dec0d417a414fed3807ef4422913d7c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #282: special case hash", + "NoBenchmark": false + }, + { + "Input": "08fb565610a79baa0c566c66228d81814f8c53a15b96e602fb49ffffffffff6e7f085441070ecd2bb21285089ebb1aa6450d1a06c36d3ff39dfd657a796d12b5249712012029870a2459d18d47da9aa492a5e6cb4b2d8dafa9e4c5c54a2b9a8b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #283: special case hash", + "NoBenchmark": false + }, + { + "Input": "d59291cc2cf89f3087715fcb1aa4e79aa2403f748e97d7cd28ecaefeffffffff914c67fb61dd1e27c867398ea7322d5ab76df04bc5aa6683a8e0f30a5d287348fa07474031481dda4953e3ac1959ee8cea7e66ec412b38d6c96d28f6d37304ea2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #284: special case hash", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25ffffffff00000001000000000000000000000000fffffffffffffffffffffffcffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254ed705d16f80987e2d9b1a6957d29ce22febf7d10fa515153182415c8361baaca4b1fc105ee5ce80d514ec1238beae2037a6f83625593620d460819e8682160926", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #636: r too large", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e3cd8d2f81d6953b0844c09d7b560d527cd2ef67056893eadafa52c8501387d59ee41fdb4d10402ce7a0c5e3b747adfa3a490b62a6b7719068903485c0bb6dc2d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #637: r,s are large", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd909135bdb6799286170f5ead2de4f6511453fe50914f3df2de54a36383df8dd48240cd81edd91cb6936133508c3915100e81f332c4545d41189b481196851378e05b06e72d4a1bff80ea5db514aa2f93ea6dd6d9c0ae27b7837dc432f9ce89d9", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #638: r and s^-1 have a large Hamming weight", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd27b4577ca009376f71303fd5dd227dcef5deb773ad5f5a84360644669ca249a5b062947356748b0fc17f1704c65aa1dca6e1bfe6779756fa616d91eaad13df2c0b38c17f3d0672e7409cfc5992a99fff12b84a4f8432293b431113f1b2fb579d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #639: r and s^-1 have a large Hamming weight", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6324d5555555550000000055555555555555553ef7a8e48d07df81a693439654210c707a736d8e326a9ca62bbe25a34ea4e3633b499a96afa7aaa3fcf3fd88f8e07edeb3e45879d8622b93e818443a686e869eeda7bf9ae46aa3eafcc48a5934864627", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #651: r and s^-1 are close to n", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8555555550000000055555555555555553ef7a8e48d07df81a693439654210c700203736fcb198b15d8d7a0c80f66dddd15259240aa78d08aae67c467de04503434383438d5041ea9a387ee8e4d4e84b4471b160c6bcf2568b072f8f20e87a996", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #654: point at infinity during verify", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a97fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a878d844dc7f16b73b1f2a39730da5d8cd99fe2e70a18482384e37dcd2bfea02e1ed6572e01eb7a8d113d02c666c45ef22d3b9a6a6dea99aa43a8183c26e75d336", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #655: edge case for signature malleability", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a97fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9dec6c8257dde94110eacc8c09d2e5789cc5beb81a958b02b4d62da9599a7401466fae1614174be63970b83f6524421067b06dd6f4e9c56baca4e344fdd690f1d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #656: edge case for signature malleability", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25555555550000000055555555555555553ef7a8e48d07df81a693439654210c70532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25a17f5b75a35ed64623ca5cbf1f91951292db0c23f0c2ea24c3d0cad0988cabc083a7a618625c228940730b4fa3ee64faecbb2fc20fdde7c58b3a3f6300424dc6", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #657: u1 == 1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25555555550000000055555555555555553ef7a8e48d07df81a693439654210c70acd155416a8b77f34089464733ff7cd39c400e9c69af7beb9eac5054ed2ec72c04ba0cba291a37db13f33bf90dab628c04ec8393a0200419e9eaa1ebcc9fb5c31f3a0a0e6823a49b625ad57b12a32d4047970fc3428f0f0049ecf4265dc12f62", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #658: u1 == n - 1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25555555550000000055555555555555553ef7a8e48d07df81a693439654210c70555555550000000055555555555555553ef7a8e48d07df81a693439654210c70692b6c828e0feed63d8aeaa2b7322f9ccbe8723a1ed39f229f204a434b8900efa1f6f6abcb38ea3b8fde38b98c7c271f274af56a8c5628dc3329069ae4dd5716", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #659: u2 == 1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25555555550000000055555555555555553ef7a8e48d07df81a693439654210c70aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e100cefd9162d13e64cb93687a9cd8f9755ebb5a3ef7632f800f84871874ccef09543ecbeaf7e8044ef721be2fb5f549e4b8480d2587404ebf7dbbef2c54bc0cb1", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #660: u2 == n - 1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd710f8e3edc7c2d5a3fd23de844002bb949d9f794f6d5405f6d97c1bb03dd2bd2b975183b42551cf52f291d5c1921fd5e12f50c8c85a4beb9de03efa3f0f244862243018e6866df922dc313612020311ff21e242ce3fb15bc78c406b25ab43091", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #661: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdedffbc270f722c243069a7e5f40335a61a58525c7b4db2e7a8e269274ffe4e1bc25f1d166f3e211cdf042a26f8abf6094d48b8d17191d74ed71714927446699965d06dd6a88abfa49e8b4c5da6bb922851969adf9604b5accfb52a114e77ccdb", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #662: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffda25adcae105ed7ff4f95d2344e24ee523314c3e178525d007904b68919ba4d538fe5e88243a76e41a004236218a3c3a2d6eee398a23c3a0b008d7f0164cbc0ca98a20d1bdcf573513c7cfd9b83c63e3a82d40127c897697c86b8cb387af7f240", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #663: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd2e4348c645707dce6760d773de3f3e87346924b2f64bd3dd0297e766b5805ebb02148256b530fbc470c7b341970b38243ecee6d5a840a37beca2efb37e8dff2cc0adbea0882482a7489ca703a399864ba987eeb6ddb738af53a83573473cb30d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #664: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd348c673b07dce3920d773de3f3e87408869e916dbcf797d8f9684fb67753d1dca34db012ce6eda1e9c7375c5fcf3e54ed698e19615124273b3a621d021c76f8e777458d6f55a364c221e39e1205d5510bb4fbb7ddf08d8d8fdde13d1d6df7f14", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #665: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd6918ce760fb9c7241aee7bc7e7d0e8110d3d22db79ef2fb1f2d09f6ceea7a3b8b97af3fe78be15f2912b6271dd8a43badb6dd2a1b315b2ce7ae37b4e7778041d930d71ee1992d2466495c42102d08e81154c305307d1dcd52d0fa4c479b278e7", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #666: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd73b3c694391d8eadde3f3e874089464715ac20e4c126bbf6d864d648969f5b5a81e7198a3c3f23901cedc7a1d6eff6e9bf81108e6c35cd8559139af3135dbcbb9ef1568530291a8061b90c9f4285eefcba990d4570a4e3b7b737525b5d580034", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #667: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbb07ac7a86948c2c2989a16db1930ef1b89ce112595197656877e53c41457f28ab4d792ca121d1dba39cb9de645149c2ab573e8becc6ddff3cc9960f188ddf737f90ba23664153e93262ff73355415195858d7be1315a69456386de68285a3c8", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #668: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd27e4d82cb6c061dd9337c69bf9332ed3d198662d6f2299443f62c861187db648518412b69af43aae084476a68d59bbde51fbfa9e5be80563f587c9c2652f88ef2d3b90d25baa6bdb7b0c55e5240a3a98fbc24afed8523edec1c70503fc10f233", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #669: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffde7c5cf3aac2e88923b77850515fff6a12d13b356dfe9ec275c3dd81ae94609a4a08f14a644b9a935dffea4761ebaf592d1f66fe6cd373aa7f5d370af34f8352da54b5bc4025cf335900a914c2934ec2fec7a396d0a7affcad732a5741c7aaaf5", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #670: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc77838df91c1e953e016e10bddffea2317f9fee32bacfe553cede9e57a748f68ccf2296a6a89b62b90739d38af4ae3a20e9f45715b90044639241061e33f8f8caace0046491eeaa1c6e9a472b96d88f4af83e7ff1bb84438c7e058034412ae08", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #671: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8ef071c02383d2a6c02dc217bbffd446730d0318b0425e2586220907f885f97f94b0fc1525bcabf82b1f34895e5819a06c02b23e04002276e165f962c86e3927be7c2ab4d0b25303204fb32a1f8292902792225e16a6d2dbfb29fbc89a9c3376", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #672: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5668aaa0b545bbf9a044a32399ffbe69ce20074e34d7bdf5cf56282a769763965351f37e1de0c88c508527d89882d183ccdcf2efca407edb0627cadfd16de6ec44b4b57cdf960d32ebcc4c97847eed218425853b5b675eb781b766a1a1300349", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #673: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd12d6e56882f6c0027cae91a27127728f7fddf478fb4fdc2b65f40a60b0eb952748bbafc320e6735cb64019710a269c6c2b5d147bdc831325cb2fb276ac971a69d655e9a755bc9d800ad21ee3fd4d980d93a7a49a8c5ccd37005177578f51163", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #674: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7fffffffaaaaaaaaffffffffffffffffe9a2538f37b28a2c513dee40fecbb71a14b3bbd75c5e1c0c36535a934d4ab85112410b3b90fa97a31c33038964fd85cc112f7d837f8f9c36b460d636c965a5f818f2b50c5d00fb3f9705561dd6631883", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #675: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdb62f26b5f2a2b26f6de86d42ad8a13da3ab3cccd0459b201de009e526adf21f2d823533c04cd8edc6d6f950a8e08ade04a9bafa2f14a590356935671ae9305bf43178d1f88b6a57a96924c265f0ddb75b58312907b195acb59d7797303123775", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #676: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbb1d9ac949dd748cd02bbbe749bd351cd57b38bb61403d700686aa7b4c90851edb2b3408b3167d91030624c6328e8ce3ec108c105575c2f3d209b92e654bab69c34318139c50b0802c6e612f0fd3189d800df7c996d5d7b7c3d6be82836fa258", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #677: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd66755a00638cdaec1c732513ca0234ece52545dac11f816e818f725b4f60aaf209179ce7c59225392216453b2ac1e9d178c24837dfae26bc1dd7ab60638527425556b42e330289f3b826b2db7a86d19d45c2860a59f2be1ddcc3b691f95a9255", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #678: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd55a00c9fcdaebb6032513ca0234ecfffe98ebe492fdf02e48ca48e982beb366901959fb8deda56e5467b7e4b214ea4c2d0c2fb29d70ff19b6b1eccebd6568d7ed9dbd77a918297fd970bff01e1343f6925167db5a14d098a211c39cc3a413398", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #679: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdab40193f9b5d76c064a27940469d9fffd31d7c925fbe05c919491d3057d66cd2567f1fdc387e5350c852b4e8f8ba9d6d947e1c5dd7ccc61a5938245dd6bcab3a9960bebaf919514f9535c22eaaf0b5812857970e26662267b1f3eb1011130a11", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #680: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdca0234ebb5fdcb13ca0234ecffffffffcb0dadbbc7f549f8a26b4408d0dc86003499f974ff4ca6bbb2f51682fd5f51762f9dd6dd2855262660b36d46d3e4bec2f498fae2487807e220119152f0122476c64d4fa46ddce85c4546630f0d5c5e81", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #681: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff3ea3677e082b9310572620ae19933a9e65b285598711c77298815ad32c5c01662cf00c1929596257db13b26ecf30d0f3ec4b9f0351b0f27094473426e986a086060d086eee822ddd2fc744247a0154b57f7a69c51d9fdafa484e4ac7", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #682: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd266666663bbbbbbbe6666666666666665b37902e023fab7c8f055d86e5cc41f491d4cba813a04d86dbae94c23be6f52c15774183be7ba5b2d9f3cf010b160501900b8adfea6491019a9ac080d516025a541bf4b952b0ad7be4b1874b02fd544a", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #683: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff36db6db7a492492492492492146c573f4c6dfc8d08a443e258970b09ef7fd0a3a36386638330ecad41e1a3b302af36960831d0210c614b948e8aa124ef0d6d800e4047d6d3c1be0fdeaf11fcd8cab5ab59c730eb34116e35a8c7d098", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #684: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff2aaaaaab7fffffffffffffffc815d0e60b3e596ecb1ad3a27cfd49c4a521dab13cc9152d8ca77035a607fea06c55cc3ca5dbeb868cea92eafe93df2a7bfb9b28531996635e6a5ccaa2826a406ce1111bdb9c2e0ca36500418a2f43de", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #685: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7fffffff55555555ffffffffffffffffd344a71e6f651458a27bdc81fd976e37474d58a4eec16e0d565f2187fe11d4e8e7a2683a12f38b4fc01d1237a81a10976e55f73bb7cdda46bdb67ef77f6fd2969df2b67920fb5945fde3a517a6ded4cd", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #686: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd3fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192aa692da5cd4309d9a6e5cb525c37da8fa0879f7b57208cdabbf47d223a5b23a62140e0daa78cfdd207a7389aaed61738b17fc5fc3e6a5ed3397d2902e9125e6ab4", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #687: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d8ecd64a4eeba466815ddf3a4de9a8e6abd9c5db0a01eb80343553da648428f85689b3e0775c7718a90279f14a8082cfcd4d1f1679274f4e9b8805c570a0670167fcc5ca734552e09afa3640f4a034e15b9b7ca661ec7ff70d3f240ebe705b1", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #688: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569f21d907e3890916dc4fa1f4703c1e50d3f54ddf7383e44023a41de562aa18ed80158137755b901f797a90d4ca8887e023cb2ef63b2ba2c0d455edaef42cf237e2a964fc00d377a8592b8b61aafa7a4aaa7c7b9fd2b41d6e0e17bd1ba5677edcd", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #689: point duplication during verification", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569f21d907e3890916dc4fa1f4703c1e50d3f54ddf7383e44023a41de562aa18ed80158137755b901f797a90d4ca8887e023cb2ef63b2ba2c0d455edaef42cf237ed569b03ef2c8857b6d4749e550585b5558384603d4be291f1e842e45a9881232", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #690: duplication bug", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25555555550000000055555555555555553ef7a8e48d07df81a693439654210c703333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aa9664ce273320d918d8bdb2e61201b4549b36b7cdc54e33b84adb6f2c10aac831e49e68831f18bda2973ac3d76bfbc8c5ee1cceed2dd862e2dc7c915c736cef1f4", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #693: comparison with point at infinity ", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978555555550000000055555555555555553ef7a8e48d07df81a693439654210c70961691a5e960d07a301dbbad4d86247ec27d7089faeb3ddd1add395efff1e0fe7254622cc371866cdf990d2c5377790e37d1f1519817f09a231bd260a9e78aeb", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #694: extreme value for k and edgecase s", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc5d283e13ce8ca60da868e3b0fb33e6b4f1074793274e2928250e71e2aca63e9c214dc74fa25371fb4d9e506d418ed9a1bfd6d0c8bb6591d3e0f44505a84886ce", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #695: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa70fc351da038ae0803bd1d86514ae0462f9f8216551d9315aa9d297f792eef6a341c74eed786f2d33da35360ca7aa925e753f00d6077a1e9e5fc339d634019c73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #696: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc476699783333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaaa1e34c8f16d138673fee55c080547c2bfd4de7550065f638322bba9430ce4b60662be9bb512663aa4d7df8ab3f3b4181c5d44a7bdf42436620b7d8a6b81ac936", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #697: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997849249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c1857e1a8a8338d7fd8cf41d322a302d2078a87a23c7186150ed7cda6e52817c1bdfd0a9135a89d21ce821e29014b2898349254d748272b2d4eb8d59ee34c615377f", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #698: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997816a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb5c19fe227a61abc65c61ee7a018cc9571b2c6f663ea33583f76a686f64be078b7b4a0d734940f613d52bc48673b457c2cf78492490a5cc5606c0541d17b24ddb", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #699: extreme value for k", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296555555550000000055555555555555553ef7a8e48d07df81a693439654210c70db02d1f3421d600e9d9ef9e47419dba3208eed08c2d4189a5db63abeb2739666e0ed26967b9ada9ed7ffe480827f90a0d210d5fd8ec628e31715e6b24125512a", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #700: extreme value for k and edgecase s", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc6222d1962655501893c29e441395b6c05711bd3ed5a0ef72cfab338b88229c4baaae079cb44a1af070362aaa520ee24cac2626423b0bf81af1c54311d8e2fd23", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #701: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa74ccfa24c67f3def7fa81bc99c70bb0419c0952ba599f4c03361da184b04cdca5db76b797f7f41d9c729a2219478a7e629728df870800be8cf6ca7a0a82153bfa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #702: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2963333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaaea1c72c91034036bac71402b6e9ecc4af3dbde7a99dc574061e99fefff9d84dab7dd057e75b78ac6f56e34eb048f0a9d29d5d055408c90d02bc2ea918c18cb63", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #703: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29649249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185c2879a66d86cb20b820b7795da2da62b38924f7817d1cd350d936988e90e79bc5431a7268ff6931c7a759de024eff90bcb0177216db6fd1f3aaaa11fa3b6a083", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #704: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29616a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bbab1c0f273f74abc2b848c75006f2ef3c54c26df27711b06558f455079aee0ba3df510f2ecef6d9a05997c776f14ad6456c179f0a13af1771e4d6c37fa48b47f2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #705: extreme value for k", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #706: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25acd155416a8b77f34089464733ff7cd39c400e9c69af7beb9eac5054ed2ec72c249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #707: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #708: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25acd155416a8b77f34089464733ff7cd39c400e9c69af7beb9eac5054ed2ec72c249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #709: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023a8ea150cb80125d7381c4c1f1da8e9de2711f9917060406a73d7904519e51388f3ab9fa68bd47973a73b2d40480c2ba50c22c9d76ec217257288293285449b8604aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1210: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e2530e782f964b2e2ff065a051bc7adc20615d8c43a1365713c88268822c253bcce5b16df652aa1ecb2dc8b46c515f9604e2e84cacfa7c6eec30428d2d3f4e08ed504aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1211: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855b292a619339f6e567a305c951c0dcbcc42d16e47f219f9e98e76e09d8770b34a0177e60492c5a8242f76f07bfe3661bde59ec2a17ce5bd2dab2abebdf89a62e204aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1212: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "de47c9b27eb8d300dbb5f2c353e632c393262cf06340c4fa7f1b40c4cbd36f90986e65933ef2ed4ee5aada139f52b70539aaf63f00a91f29c69178490d57fb713dafedfb8da6189d372308cbf1489bbbdabf0c0217d1c0ff0f701aaa7a694b9c04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1213: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d434e262a49eab7781e353a3565e482550dd0fd5defa013c7f29745eff3569f19b0c0a93f267fb6052fd8077be769c2b98953195d7bc10de844218305c6ba17a4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1303: x-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f910fe774355c04d060f76d79fd7a772e421463489221bf0a33add0be9b1979110b500dcba1c69a8fbd43fa4f57f743ce124ca8b91a1f325f3fac6181175df557374f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1304: x-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91bb40bf217bed3fb3950c7d39f03d36dc8e3b2cd79693f125bfd06595ee1135e3541bf3532351ebb032710bdb6a1bf1bfc89a1e291ac692b3fa4780745bb556774f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1305: x-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91664eb7ee6db84a34df3c86ea31389a5405badd5ca99231ff556d3e75a233e73a59f3c752e52eca46137642490a51560ce0badc678754b8f72e51a2901426a1bd3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1306: y-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f914cd0429bbabd2827009d6fcd843d4ce39c3e42e2d1631fd001985a79d1fd8b439638bf12dd682f60be7ef1d0e0d98f08b7bca77a1a2b869ae466189d2acdabe33cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1307: y-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91e56c6ea2d1b017091c44d8b6cb62b9f460e3ce9aed5e5fd41e8added97c56c04a308ec31f281e955be20b457e463440b4fcf2b80258078207fc1378180f89b553cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1308: y-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f911158a08d291500b4cabed3346d891eee57c176356a2624fb011f8fbbf3466830228a8c486a736006e082325b85290c5bc91f378b75d487dda46798c18f2855193cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1309: y-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91b1db9289649f59410ea36b0c0fc8d6aa2687b29176939dd23e0dde56d309fa9d3e1535e4280559015b0dbd987366dcf43a6d1af5c23c7d584e1c3f48a12513363cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1310: y-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91b7b16e762286cb96446aa8d4e6e7578b0a341a79f2dd1a220ac6f0ca4e24ed86ddc60a700a139b04661c547d07bbb0721780146df799ccf55e55234ecb8f12bc3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1311: y-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d82a7c2717261187c8e00d8df963ff35d796edad36bc6e6bd1c91c670d9105b43dcabddaf8fcaa61f4603e7cbac0f3c0351ecd5988efb23f680d07debd1399292829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1312: x-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f915eb9c8845de68eb13d5befe719f462d77787802baff30ce96a5cba063254af782c026ae9be2e2a5e7ca0ff9bbd92fb6e44972186228ee9a62b87ddbe2ef66fb52829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1313: x-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9196843dd03c22abd2f3b782b170239f90f277921becc117d0404a8e4e36230c28f2be378f526f74a543f67165976de9ed9a31214eb4d7e6db19e1ede123dd991d2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1314: x-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91766456dce1857c906f9996af729339464d27e9d98edc2d0e3b760297067421f6402385ecadae0d8081dccaf5d19037ec4e55376eced699e93646bfbbf19d0b41fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1315: x-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91c605c4b2edeab20419e6518a11b2dbc2b97ed8b07cced0b19c34f777de7b9fd9edf0f612c5f46e03c719647bc8af1b29b2cde2eda700fb1cff5e159d47326dbafffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1316: x-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d48b68e6cabfe03cf6141c9ac54141f210e64485d9929ad7b732bfe3b7eb8a84feedae50c61bd00e19dc26f9b7e2265e4508c389109ad2f208f0772315b6c941fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1317: x-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91b7c81457d4aeb6aa65957098569f0479710ad7f6595d5874c35a93d12a5dd4c7b7961a0b652878c2d568069a432ca18a1a9199f2ca574dad4b9e3a05c0a1cdb300000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1318: x-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f916b01332ddb6edfa9a30a1321d5858e1ee3cf97e263e669f8de5e9652e76ff3f75939545fced457309a6a04ace2bd0f70139c8f7d86b02cb1cc58f9e69e96cd5a00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1319: x-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91efdb884720eaeadc349f9fc356b6c0344101cd2fd8436b7d0e6a4fb93f106361f24bee6ad5dc05f7613975473aadf3aacba9e77de7d69b6ce48cb60d8113385d00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1320: x-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9131230428405560dcb88fb5a646836aea9b23a23dd973dcbe8014c87b8b20eb070f9344d6e812ce166646747694a41b0aaf97374e19f3c5fb8bd7ae3d9bd0beffbcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1321: y-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91caa797da65b320ab0d5c470cda0b36b294359c7db9841d679174db34c4855743cf543a62f23e212745391aaf7505f345123d2685ee3b941d3de6d9b36242e5a0bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1322: y-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f917e5f0ab5d900d3d3d7867657e5d6d36519bc54084536e7d21c336ed8001859459450c07f201faec94b82dfb322e5ac676688294aad35aa72e727ff0b19b646aabcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1323: y-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d7d70c581ae9e3f66dc6a480bf037ae23f8a1e4a2136fe4b03aa69f0ca25b35689c460f8a5a5c2bbba962c8a3ee833a413e85658e62a59e2af41d9127cc47224bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1324: y-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91341c1b9ff3c83dd5e0dfa0bf68bcdf4bb7aa20c625975e5eeee34bb396266b3472b69f061b750fd5121b22b11366fad549c634e77765a017902a67099e0a4469bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1325: y-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9170bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a9bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1326: y-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e184cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd762927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #1: signature malleability", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023d45c5740946b2a147f59262ee6f5bc90bd01ed280528b62b3aed5fc93f06f739b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #3: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #5: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050232ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e184cd60b865d442f5a3c7b11eb6c4e0ae79578ec6353a20bf783ecb4b6ea97b8252927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #8: Modified r or s, e.g. by adding or subtracting the order of the group", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #9: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #10: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #11: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #12: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #13: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000000ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #14: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000000ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #15: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #16: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #17: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000001ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #18: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000001ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #19: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000001ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #20: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000001ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #21: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230000000000000000000000000000000000000000000000000000000000000001ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #22: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255100000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #23: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255100000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #24: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #25: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #26: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #27: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #28: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #29: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255000000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #30: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255000000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #31: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #32: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #33: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #34: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #35: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #36: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255200000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #37: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255200000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #38: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #39: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #40: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #41: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #42: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #43: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #44: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #45: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #46: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #47: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #48: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #49: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #50: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff0000000100000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #51: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff0000000100000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000012927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #52: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325512927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #53: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #54: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #55: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000001000000000000000000000000ffffffffffffffffffffffff2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #56: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023ffffffff00000001000000000000000000000001000000000000000000000000ffffffff000000010000000000000000000000010000000000000000000000002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #57: Signature with special case values for r and s", + "NoBenchmark": false + }, + { + "Input": "70239dd877f7c944c422f44dea4ed1a52f2627416faf2f072fa50c772ed6f80764a1aab5000d0e804f3e2fc02bdee9be8ff312334e2ba16d11547c97711c898e6af015971cc30be6d1a206d4e013e0997772a2f91d73286ffd683b9bb2cf4f1b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #58: Edge case for Shamir multiplication", + "NoBenchmark": false + }, + { + "Input": "00000000690ed426ccf17803ebe2bd0884bcd58a1bb5e7477ead3645f356e7a916aea964a2f6506d6f78c81c91fc7e8bded7d397738448de1e19a0ec580bf266252cd762130c6667cfe8b7bc47d27d78391e8e80c578d1cd38c3ff033be928e92927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #59: special case hash", + "NoBenchmark": false + }, + { + "Input": "7300000000213f2a525c6035725235c2f696ad3ebb5ee47f140697ad25770d919cc98be2347d469bf476dfc26b9b733df2d26d6ef524af917c665baccb23c882093496459effe2d8d70727b82462f61d0ec1b7847929d10ea631dacb16b56c322927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #60: special case hash", + "NoBenchmark": false + }, + { + "Input": "ddf2000000005e0be0635b245f0b97978afd25daadeb3edb4a0161c27fe0604573b3c90ecd390028058164524dde892703dce3dea0d53fa8093999f07ab8aa432f67b0b8e20636695bb7d8bf0a651c802ed25a395387b5f4188c0c4075c886342927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #61: special case hash", + "NoBenchmark": false + }, + { + "Input": "67ab1900000000784769c4ecb9e164d6642b8499588b89855be1ec355d0841a0bfab3098252847b328fadf2f89b95c851a7f0eb390763378f37e90119d5ba3ddbdd64e234e832b1067c2d058ccb44d978195ccebb65c2aaf1e2da9b8b4987e3b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #62: special case hash", + "NoBenchmark": false + }, + { + "Input": "a2bf09460000000076d7dbeffe125eaf02095dff252ee905e296b6350fc311cf204a9784074b246d8bf8bf04a4ceb1c1f1c9aaab168b1596d17093c5cd21d2cd51cce41670636783dc06a759c8847868a406c2506fe17975582fe648d1d88b522927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #63: special case hash", + "NoBenchmark": false + }, + { + "Input": "3554e827c700000000e1e75e624a06b3a0a353171160858129e15c544e4f0e65ed66dc34f551ac82f63d4aa4f81fe2cb0031a91d1314f835027bca0f1ceeaa0399ca123aa09b13cd194a422e18d5fda167623c3f6e5d4d6abb8953d67c0c48c72927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #64: special case hash", + "NoBenchmark": false + }, + { + "Input": "9b6cd3b812610000000026941a0f0bb53255ea4c9fd0cb3426e3a54b9fc6965c060b700bef665c68899d44f2356a578d126b062023ccc3c056bf0f60a237012b8d186c027832965f4fcc78a3366ca95dedbb410cbef3f26d6be5d581c11d36102927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #65: special case hash", + "NoBenchmark": false + }, + { + "Input": "883ae39f50bf0100000000e7561c26fc82a52baa51c71ca877162f93c4ae01869f6adfe8d5eb5b2c24d7aa7934b6cf29c93ea76cd313c9132bb0c8e38c96831db26a9c9e40e55ee0890c944cf271756c906a33e66b5bd15e051593883b5e99022927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #66: special case hash", + "NoBenchmark": false + }, + { + "Input": "a1ce5d6e5ecaf28b0000000000fa7cd010540f420fb4ff7401fe9fce011d0ba6a1af03ca91677b673ad2f33615e56174a1abf6da168cebfa8868f4ba273f16b720aa73ffe48afa6435cd258b173d0c2377d69022e7d098d75caf24c8c5e06b1c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #67: special case hash", + "NoBenchmark": false + }, + { + "Input": "8ea5f645f373f580930000000038345397330012a8ee836c5494cdffd5ee8054fdc70602766f8eed11a6c99a71c973d5659355507b843da6e327a28c11893db93df5349688a085b137b1eacf456a9e9e0f6d15ec0078ca60a7f83f2b10d213502927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #68: special case hash", + "NoBenchmark": false + }, + { + "Input": "660570d323e9f75fa734000000008792d65ce93eabb7d60d8d9c1bbdcb5ef305b516a314f2fce530d6537f6a6c49966c23456f63c643cf8e0dc738f7b876e675d39ffd033c92b6d717dd536fbc5efdf1967c4bd80954479ba66b0120cd16fff22927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #69: special case hash", + "NoBenchmark": false + }, + { + "Input": "d0462673154cce587dde8800000000e98d35f1f45cf9c3bf46ada2de4c568c343b2cbf046eac45842ecb7984d475831582717bebb6492fd0a485c101e29ff0a84c9b7b47a98b0f82de512bc9313aaf51701099cac5f76e68c8595fc1c1d992582927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #70: special case hash", + "NoBenchmark": false + }, + { + "Input": "bd90640269a7822680cedfef000000000caef15a6171059ab83e7b4418d7278f30c87d35e636f540841f14af54e2f9edd79d0312cfa1ab656c3fb15bfde48dcf47c15a5a82d24b75c85a692bd6ecafeb71409ede23efd08e0db9abf6340677ed2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #71: special case hash", + "NoBenchmark": false + }, + { + "Input": "33239a52d72f1311512e41222a00000000d2dcceb301c54b4beae8e284788a7338686ff0fda2cef6bc43b58cfe6647b9e2e8176d168dec3c68ff262113760f52067ec3b651f422669601662167fa8717e976e2db5e6a4cf7c2ddabb3fde9d67d2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #72: special case hash", + "NoBenchmark": false + }, + { + "Input": "b8d64fbcd4a1c10f1365d4e6d95c000000007ee4a21a1cbe1dc84c2d941ffaf144a3e23bf314f2b344fc25c7f2de8b6af3e17d27f5ee844b225985ab6e2775cf2d48e223205e98041ddc87be532abed584f0411f5729500493c9cc3f4dd15e862927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #73: special case hash", + "NoBenchmark": false + }, + { + "Input": "01603d3982bf77d7a3fef3183ed092000000003a227420db4088b20fe0e9d84a2ded5b7ec8e90e7bf11f967a3d95110c41b99db3b5aa8d330eb9d638781688e97d5792c53628155e1bfc46fb1a67e3088de049c328ae1f44ec69238a009808f92927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #74: special case hash", + "NoBenchmark": false + }, + { + "Input": "9ea6994f1e0384c8599aa02e6cf66d9c000000004d89ef50b7e9eb0cfbff7363bdae7bcb580bf335efd3bc3d31870f923eaccafcd40ec2f605976f15137d8b8ff6dfa12f19e525270b0106eecfe257499f373a4fb318994f24838122ce7ec3c72927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #75: special case hash", + "NoBenchmark": false + }, + { + "Input": "d03215a8401bcf16693979371a01068a4700000000e2fa5bf692bc670905b18c50f9c4f0cd6940e162720957ffff513799209b78596956d21ece251c2401f1c6d7033a0a787d338e889defaaabb106b95a4355e411a59c32aa5167dfab2447262927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #76: special case hash", + "NoBenchmark": false + }, + { + "Input": "307bfaaffb650c889c84bf83f0300e5dc87e000000008408fd5f64b582e3bb14f612820687604fa01906066a378d67540982e29575d019aabe90924ead5c860d3f9367702dd7dd4f75ea98afd20e328a1a99f4857b316525328230ce294b0fef2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #77: special case hash", + "NoBenchmark": false + }, + { + "Input": "bab5c4f4df540d7b33324d36bb0c157551527c00000000e4af574bb4d54ea6b89505e407657d6e8bc93db5da7aa6f5081f61980c1949f56b0f2f507da5782a7ac60d31904e3669738ffbeccab6c3656c08e0ed5cb92b3cfa5e7f71784f9c50212927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #78: special case hash", + "NoBenchmark": false + }, + { + "Input": "d4ba47f6ae28f274e4f58d8036f9c36ec2456f5b00000000c3b869197ef5e15ebbd16fbbb656b6d0d83e6a7787cd691b08735aed371732723e1c68a40404517d9d8e35dba96028b7787d91315be675877d2d097be5e8ee34560e3e7fd25c0f002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #79: special case hash", + "NoBenchmark": false + }, + { + "Input": "79fd19c7235ea212f29f1fa00984342afe0f10aafd00000000801e47f8c184e12ec9760122db98fd06ea76848d35a6da442d2ceef7559a30cf57c61e92df327e7ab271da90859479701fccf86e462ee3393fb6814c27b760c4963625c0a198782927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #80: special case hash", + "NoBenchmark": false + }, + { + "Input": "8c291e8eeaa45adbaf9aba5c0583462d79cbeb7ac97300000000a37ea6700cda54e76b7683b6650baa6a7fc49b1c51eed9ba9dd463221f7a4f1005a89fe00c592ea076886c773eb937ec1cc8374b7915cfd11b1c1ae1166152f2f7806a31c8fd2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #81: special case hash", + "NoBenchmark": false + }, + { + "Input": "0eaae8641084fa979803efbfb8140732f4cdcf66c3f78a000000003c278a6b215291deaf24659ffbbce6e3c26f6021097a74abdbb69be4fb10419c0c496c946665d6fcf336d27cc7cdb982bb4e4ecef5827f84742f29f10abf83469270a03dc32927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #82: special case hash", + "NoBenchmark": false + }, + { + "Input": "e02716d01fb23a5a0068399bf01bab42ef17c6d96e13846c00000000afc0f89d207a3241812d75d947419dc58efb05e8003b33fc17eb50f9d15166a88479f107cdee749f2e492b213ce80b32d0574f62f1c5d70793cf55e382d5caadf75927672927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #83: special case hash", + "NoBenchmark": false + }, + { + "Input": "9eb0bf583a1a6b9a194e9a16bc7dab2a9061768af89d00659a00000000fc7de16554e49f82a855204328ac94913bf01bbe84437a355a0a37c0dee3cf81aa7728aea00de2507ddaf5c94e1e126980d3df16250a2eaebc8be486effe7f22b4f9292927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #84: special case hash", + "NoBenchmark": false + }, + { + "Input": "62aac98818b3b84a2c214f0d5e72ef286e1030cb53d9a82b690e00000000cd15a54c5062648339d2bff06f71c88216c26c6e19b4d80a8c602990ac82707efdfce99bbe7fcfafae3e69fd016777517aa01056317f467ad09aff09be73c9731b0d2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #85: special case hash", + "NoBenchmark": false + }, + { + "Input": "3760a7f37cf96218f29ae43732e513efd2b6f552ea4b6895464b9300000000c8975bd7157a8d363b309f1f444012b1a1d23096593133e71b4ca8b059cff37eaf7faa7a28b1c822baa241793f2abc930bd4c69840fe090f2aacc46786bf9196222927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #86: special case hash", + "NoBenchmark": false + }, + { + "Input": "0da0a1d2851d33023834f2098c0880096b4320bea836cd9cbb6ff6c8000000005694a6f84b8f875c276afd2ebcfe4d61de9ec90305afb1357b95b3e0da43885e0dffad9ffd0b757d8051dec02ebdf70d8ee2dc5c7870c0823b6ccc7c679cbaa42927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #87: special case hash", + "NoBenchmark": false + }, + { + "Input": "ffffffff293886d3086fd567aafd598f0fe975f735887194a764a231e82d289aa0c30e8026fdb2b4b4968a27d16a6d08f7098f1a98d21620d7454ba9790f1ba65e470453a8a399f15baf463f9deceb53acc5ca64459149688bd2760c654243392927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #88: special case hash", + "NoBenchmark": false + }, + { + "Input": "7bffffffff2376d1e3c03445a072e24326acdc4ce127ec2e0e8d9ca99527e7b7614ea84acf736527dd73602cd4bb4eea1dfebebd5ad8aca52aa0228cf7b99a88737cc85f5f2d2f60d1b8183f3ed490e4de14368e96a9482c2a4dd193195c902f2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #89: special case hash", + "NoBenchmark": false + }, + { + "Input": "a2b5ffffffffebb251b085377605a224bc80872602a6e467fd016807e97fa395bead6734ebe44b810d3fb2ea00b1732945377338febfd439a8d74dfbd0f942fa6bb18eae36616a7d3cad35919fd21a8af4bbe7a10f73b3e036a46b103ef56e2a2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #90: special case hash", + "NoBenchmark": false + }, + { + "Input": "641227ffffffff6f1b96fa5f097fcf3cc1a3c256870d45a67b83d0967d4b20c0499625479e161dacd4db9d9ce64854c98d922cbf212703e9654fae182df9bad242c177cf37b8193a0131108d97819edd9439936028864ac195b64fca76d9d6932927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #91: special case hash", + "NoBenchmark": false + }, + { + "Input": "958415d8ffffffffabad03e2fc662dc3ba203521177502298df56f36600e0f8b08f16b8093a8fb4d66a2c8065b541b3d31e3bfe694f6b89c50fb1aaa6ff6c9b29d6455e2d5d1779748573b611cb95d4a21f967410399b39b535ba3e5af81ca2e2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #92: special case hash", + "NoBenchmark": false + }, + { + "Input": "f1d8de4858ffffffff1281093536f47fe13deb04e1fbe8fb954521b6975420f8be26231b6191658a19dd72ddb99ed8f8c579b6938d19bce8eed8dc2b338cb5f8e1d9a32ee56cffed37f0f22b2dcb57d5c943c14f79694a03b9c5e96952575c892927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #93: special case hash", + "NoBenchmark": false + }, + { + "Input": "0927895f2802ffffffff10782dd14a3b32dc5d47c05ef6f1876b95c81fc31def15e76880898316b16204ac920a02d58045f36a229d4aa4f812638c455abe0443e74d357d3fcb5c8c5337bd6aba4178b455ca10e226e13f9638196506a19391232927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #94: special case hash", + "NoBenchmark": false + }, + { + "Input": "60907984aa7e8effffffff4f332862a10a57c3063fb5a30624cf6a0c3ac80589352ecb53f8df2c503a45f9846fc28d1d31e6307d3ddbffc1132315cc07f16dad1348dfa9c482c558e1d05c5242ca1c39436726ecd28258b1899792887dd0a3c62927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #95: special case hash", + "NoBenchmark": false + }, + { + "Input": "c6ff198484939170ffffffff0af42cda50f9a5f50636ea6942d6b9b8cd6ae1e24a40801a7e606ba78a0da9882ab23c7677b8642349ed3d652c5bfa5f2a9558fb3a49b64848d682ef7f605f2832f7384bdc24ed2925825bf8ea77dc59817257822927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #96: special case hash", + "NoBenchmark": false + }, + { + "Input": "de030419345ca15c75ffffffff8074799b9e0956cc43135d16dfbe4d27d7e68deacc5e1a8304a74d2be412b078924b3bb3511bac855c05c9e5e9e44df3d61e967451cd8e18d6ed1885dd827714847f96ec4bb0ed4c36ce9808db8f714204f6d12927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #97: special case hash", + "NoBenchmark": false + }, + { + "Input": "6f0e3eeaf42b28132b88fffffffff6c8665604d34acb19037e1ab78caaaac6ff2f7a5e9e5771d424f30f67fdab61e8ce4f8cd1214882adb65f7de94c31577052ac4e69808345809b44acb0b2bd889175fb75dd050c5a449ab9528f8f78daa10c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #98: special case hash", + "NoBenchmark": false + }, + { + "Input": "cdb549f773b3e62b3708d1ffffffffbe48f7c0591ddcae7d2cb222d1f8017ab9ffcda40f792ce4d93e7e0f0e95e1a2147dddd7f6487621c30a03d710b330021979938b55f8a17f7ed7ba9ade8f2065a1fa77618f0b67add8d58c422c2453a49a2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #99: special case hash", + "NoBenchmark": false + }, + { + "Input": "2c3f26f96a3ac0051df4989bffffffff9fd64886c1dc4f9924d8fd6f0edb048481f2359c4faba6b53d3e8c8c3fcc16a948350f7ab3a588b28c17603a431e39a8cd6f6a5cc3b55ead0ff695d06c6860b509e46d99fccefb9f7f9e101857f743002927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #100: special case hash", + "NoBenchmark": false + }, + { + "Input": "ac18f8418c55a2502cb7d53f9affffffff5c31d89fda6a6b8476397c04edf411dfc8bf520445cbb8ee1596fb073ea283ea130251a6fdffa5c3f5f2aaf75ca808048e33efce147c9dd92823640e338e68bfd7d0dc7a4905b3a7ac711e577e90e72927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #101: special case hash", + "NoBenchmark": false + }, + { + "Input": "4f9618f98e2d3a15b24094f72bb5ffffffffa2fd3e2893683e5a6ab8cf0ee610ad019f74c6941d20efda70b46c53db166503a0e393e932f688227688ba6a576293320eb7ca0710255346bdbb3102cdcf7964ef2e0988e712bc05efe16c1993452927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #102: special case hash", + "NoBenchmark": false + }, + { + "Input": "422e82a3d56ed10a9cc21d31d37a25ffffffff67edf7c40204caae73ab0bc75aac8096842e8add68c34e78ce11dd71e4b54316bd3ebf7fffdeb7bd5a3ebc1883f5ca2f4f23d674502d4caf85d187215d36e3ce9f0ce219709f21a3aac003b7a82927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #103: special case hash", + "NoBenchmark": false + }, + { + "Input": "7075d245ccc3281b6e7b329ff738fbb417a5ffffffffa0842d9890b5cf95d018677b2d3a59b18a5ff939b70ea002250889ddcd7b7b9d776854b4943693fb92f76b4ba856ade7677bf30307b21f3ccda35d2f63aee81efd0bab6972cc0795db552927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #104: special case hash", + "NoBenchmark": false + }, + { + "Input": "3c80de54cd9226989443d593fa4fd6597e280ebeffffffffc1847eb76c217a95479e1ded14bcaed0379ba8e1b73d3115d84d31d4b7c30e1f05e1fc0d5957cfb0918f79e35b3d89487cf634a4f05b2e0c30857ca879f97c771e877027355b24432927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #105: special case hash", + "NoBenchmark": false + }, + { + "Input": "de21754e29b85601980bef3d697ea2770ce891a8cdffffffffc7906aa794b39b43dfccd0edb9e280d9a58f01164d55c3d711e14b12ac5cf3b64840ead512a0a31dbe33fa8ba84533cd5c4934365b3442ca1174899b78ef9a3199f495843897722927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #106: special case hash", + "NoBenchmark": false + }, + { + "Input": "8f65d92927cfb86a84dd59623fb531bb599e4d5f7289ffffffff2f1f2f57881c5b09ab637bd4caf0f4c7c7e4bca592fea20e9087c259d26a38bb4085f0bbff1145b7eb467b6748af618e9d80d6fdcd6aa24964e5a13f885bca8101de08eb0d752927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #107: special case hash", + "NoBenchmark": false + }, + { + "Input": "6b63e9a74e092120160bea3877dace8a2cc7cd0e8426cbfffffffffafc8c3ca85e9b1c5a028070df5728c5c8af9b74e0667afa570a6cfa0114a5039ed15ee06fb1360907e2d9785ead362bb8d7bd661b6c29eeffd3c5037744edaeb9ad990c202927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #108: special case hash", + "NoBenchmark": false + }, + { + "Input": "fc28259702a03845b6d75219444e8b43d094586e249c8699ffffffffe852512e0671a0a85c2b72d54a2fb0990e34538b4890050f5a5712f6d1a7a5fb8578f32edb1846bab6b7361479ab9c3285ca41291808f27fd5bd4fdac720e5854713694c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #109: special case hash", + "NoBenchmark": false + }, + { + "Input": "1273b4502ea4e3bccee044ee8e8db7f774ecbcd52e8ceb571757ffffffffe20a7673f8526748446477dbbb0590a45492c5d7d69859d301abbaedb35b2095103a3dc70ddf9c6b524d886bed9e6af02e0e4dec0d417a414fed3807ef4422913d7c2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #110: special case hash", + "NoBenchmark": false + }, + { + "Input": "08fb565610a79baa0c566c66228d81814f8c53a15b96e602fb49ffffffffff6e7f085441070ecd2bb21285089ebb1aa6450d1a06c36d3ff39dfd657a796d12b5249712012029870a2459d18d47da9aa492a5e6cb4b2d8dafa9e4c5c54a2b9a8b2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #111: special case hash", + "NoBenchmark": false + }, + { + "Input": "d59291cc2cf89f3087715fcb1aa4e79aa2403f748e97d7cd28ecaefeffffffff914c67fb61dd1e27c867398ea7322d5ab76df04bc5aa6683a8e0f30a5d287348fa07474031481dda4953e3ac1959ee8cea7e66ec412b38d6c96d28f6d37304ea2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #112: special case hash", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25000000000000000000000000000000004319055358e8617b0c46353d039cdaabffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254ed705d16f80987e2d9b1a6957d29ce22febf7d10fa515153182415c8361baaca4b1fc105ee5ce80d514ec1238beae2037a6f83625593620d460819e8682160926", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #113: k*G has a large x-coordinate", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25ffffffff00000001000000000000000000000000fffffffffffffffffffffffcffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254ed705d16f80987e2d9b1a6957d29ce22febf7d10fa515153182415c8361baaca4b1fc105ee5ce80d514ec1238beae2037a6f83625593620d460819e8682160926", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #114: r too large", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e3cd8d2f81d6953b0844c09d7b560d527cd2ef67056893eadafa52c8501387d59ee41fdb4d10402ce7a0c5e3b747adfa3a490b62a6b7719068903485c0bb6dc2d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #115: r,s are large", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd909135bdb6799286170f5ead2de4f6511453fe50914f3df2de54a36383df8dd48240cd81edd91cb6936133508c3915100e81f332c4545d41189b481196851378e05b06e72d4a1bff80ea5db514aa2f93ea6dd6d9c0ae27b7837dc432f9ce89d9", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #116: r and s^-1 have a large Hamming weight", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd27b4577ca009376f71303fd5dd227dcef5deb773ad5f5a84360644669ca249a5b062947356748b0fc17f1704c65aa1dca6e1bfe6779756fa616d91eaad13df2c0b38c17f3d0672e7409cfc5992a99fff12b84a4f8432293b431113f1b2fb579d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #117: r and s^-1 have a large Hamming weight", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000014a03ef9f92eb268cafa601072489a56380fa0dc43171d7712813b3a19a1eb5e53e213e28a608ce9a2f4a17fd830c6654018a79b3e0263d91a8ba90622df6f2f0", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #118: small r and s", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e2500000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000003091194c1cba17f34e286b4833701606a41cef26177ada8850b601ea1f859e70127242fcec708828758403ce2fe501983a7984e6209f4d6b95db9ad77767f55eb", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #120: small r and s", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e2500000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005103c6ecceff59e71ea8f56fee3a4b2b148e81c2bdbdd39c195812c96dcfb41a72303a193dc591be150b883d770ec51ebb4ebce8b09042c2ecb16c448d8e57bf5", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #122: small r and s", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000063b66b829fe604638bcb2bfe8c22228be67390c20111bd2b451468927e87fb6eabc8e59c009361758b274ba2cad36b58fde485a3ed09dade76712fa9e9c4ac212", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #124: small r and s", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255600000000000000000000000000000000000000000000000000000000000000063b66b829fe604638bcb2bfe8c22228be67390c20111bd2b451468927e87fb6eabc8e59c009361758b274ba2cad36b58fde485a3ed09dade76712fa9e9c4ac212", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #126: r is larger than n", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e250000000000000000000000000000000000000000000000000000000000000005ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc75fbd84ff2f6c24e4a33cd71c09fdcbc74a6233961b874b8c8e0eb94582092cbc50c3084fa9547afda5c66335f3f937d4c79afa120486b534139d59ae82d61ead26420", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #127: s is larger than n", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e2500000000000000000000000000000000000000000000000000000000000001008f1e3c7862c58b16bb76eddbb76eddbb516af4f63f2d74d76e0d28c9bb75ea8884b959080bb30859cd53c2fb973cf14d60cdaa8ee00587889b5bc657ac588175a02ce5c1e53cb196113c78b4cb8dc7d360e5ea7850b0f6650b0c45af2c3cd7ca", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #128: small r and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25000000000000000000000000000000000000000000000000002d9b4d347952d6ef3043e7329581dbb3974497710ab11505ee1c87ff907beebadd195a0ffe6d7adf4083bd6ecbda5a77ae578e5d835fa7f74a07ebb91e0570e1ff32a563354e9925af80b09a167d9ef647df28e2d9acd0d4bc4f2deec5723818edaf9071e311f8", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #129: smallish r and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25000000000000000000000000000000000000001033e67e37b32b445580bf4eff8b748b74000000008b748b748b748b7466e769ad4a16d3dcd87129b8e91d1b4dc2569a3c9bf8c1838ca821f7ba6f000cc8679d278f3736b414a34a7c956a03770387ea85bc4f28804b4a91c9b7d65bc6434c975806795ab7d441a4e9683aeb09", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #130: 100-bit r and small s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e250000000000000000000000000000000000000000000000000000000000000100ef9f6ba4d97c09d03178fa20b4aaad83be3cf9cb824a879fec3270fc4b81ef5b4a9f7da2a6c359a16540c271774a6bf1c586357c978256f44a6496d80670968ac496e73a44563f8d56fbd7bb9e4e3ae304c86f2c508eb777b03924755beb40d4", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #131: small r and 100 bit s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e2500000000000000000000000000000000000000062522bbd3ecbe7c39e93e7c25ef9f6ba4d97c09d03178fa20b4aaad83be3cf9cb824a879fec3270fc4b81ef5b874146432b3cd2c9e26204c0a34136996067d466dde4917a8ff23a8e95ca106b709b3d50976ef8b385a813bc35f3a20710bdc6edd465e6f43ac4866703a6608c", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #132: 100-bit r and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6324d5555555550000000055555555555555553ef7a8e48d07df81a693439654210c707a736d8e326a9ca62bbe25a34ea4e3633b499a96afa7aaa3fcf3fd88f8e07edeb3e45879d8622b93e818443a686e869eeda7bf9ae46aa3eafcc48a5934864627", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #133: r and s^-1 are close to n", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25555555550000000055555555555555553ef7a8e48d07df81a693439654210c700000000000000000000000000000000000000000000000000000000000000001e84d9b232e971a43382630f99725e423ec1ecb41e55172e9c69748a03f0d5988618b15b427ad83363bd041ff75fac98ef2ee923714e7d1dfe31753793c7588d4", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #134: s == 1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25555555550000000055555555555555553ef7a8e48d07df81a693439654210c700000000000000000000000000000000000000000000000000000000000000000e84d9b232e971a43382630f99725e423ec1ecb41e55172e9c69748a03f0d5988618b15b427ad83363bd041ff75fac98ef2ee923714e7d1dfe31753793c7588d4", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #135: s == 0", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8555555550000000055555555555555553ef7a8e48d07df81a693439654210c700203736fcb198b15d8d7a0c80f66dddd15259240aa78d08aae67c467de04503434383438d5041ea9a387ee8e4d4e84b4471b160c6bcf2568b072f8f20e87a996", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #136: point at infinity during verify", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a97fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a878d844dc7f16b73b1f2a39730da5d8cd99fe2e70a18482384e37dcd2bfea02e1ed6572e01eb7a8d113d02c666c45ef22d3b9a6a6dea99aa43a8183c26e75d336", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #137: edge case for signature malleability", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a97fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9dec6c8257dde94110eacc8c09d2e5789cc5beb81a958b02b4d62da9599a7401466fae1614174be63970b83f6524421067b06dd6f4e9c56baca4e344fdd690f1d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #138: edge case for signature malleability", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25555555550000000055555555555555553ef7a8e48d07df81a693439654210c70532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25a17f5b75a35ed64623ca5cbf1f91951292db0c23f0c2ea24c3d0cad0988cabc083a7a618625c228940730b4fa3ee64faecbb2fc20fdde7c58b3a3f6300424dc6", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #139: u1 == 1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25555555550000000055555555555555553ef7a8e48d07df81a693439654210c70acd155416a8b77f34089464733ff7cd39c400e9c69af7beb9eac5054ed2ec72c04ba0cba291a37db13f33bf90dab628c04ec8393a0200419e9eaa1ebcc9fb5c31f3a0a0e6823a49b625ad57b12a32d4047970fc3428f0f0049ecf4265dc12f62", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #140: u1 == n - 1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25555555550000000055555555555555553ef7a8e48d07df81a693439654210c70555555550000000055555555555555553ef7a8e48d07df81a693439654210c70692b6c828e0feed63d8aeaa2b7322f9ccbe8723a1ed39f229f204a434b8900efa1f6f6abcb38ea3b8fde38b98c7c271f274af56a8c5628dc3329069ae4dd5716", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #141: u2 == 1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25555555550000000055555555555555553ef7a8e48d07df81a693439654210c70aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e100cefd9162d13e64cb93687a9cd8f9755ebb5a3ef7632f800f84871874ccef09543ecbeaf7e8044ef721be2fb5f549e4b8480d2587404ebf7dbbef2c54bc0cb1", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #142: u2 == n - 1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd710f8e3edc7c2d5a3fd23de844002bb949d9f794f6d5405f6d97c1bb03dd2bd2b975183b42551cf52f291d5c1921fd5e12f50c8c85a4beb9de03efa3f0f244862243018e6866df922dc313612020311ff21e242ce3fb15bc78c406b25ab43091", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #143: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdedffbc270f722c243069a7e5f40335a61a58525c7b4db2e7a8e269274ffe4e1bc25f1d166f3e211cdf042a26f8abf6094d48b8d17191d74ed71714927446699965d06dd6a88abfa49e8b4c5da6bb922851969adf9604b5accfb52a114e77ccdb", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #144: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffda25adcae105ed7ff4f95d2344e24ee523314c3e178525d007904b68919ba4d538fe5e88243a76e41a004236218a3c3a2d6eee398a23c3a0b008d7f0164cbc0ca98a20d1bdcf573513c7cfd9b83c63e3a82d40127c897697c86b8cb387af7f240", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #145: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd2e4348c645707dce6760d773de3f3e87346924b2f64bd3dd0297e766b5805ebb02148256b530fbc470c7b341970b38243ecee6d5a840a37beca2efb37e8dff2cc0adbea0882482a7489ca703a399864ba987eeb6ddb738af53a83573473cb30d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #146: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd348c673b07dce3920d773de3f3e87408869e916dbcf797d8f9684fb67753d1dca34db012ce6eda1e9c7375c5fcf3e54ed698e19615124273b3a621d021c76f8e777458d6f55a364c221e39e1205d5510bb4fbb7ddf08d8d8fdde13d1d6df7f14", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #147: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd6918ce760fb9c7241aee7bc7e7d0e8110d3d22db79ef2fb1f2d09f6ceea7a3b8b97af3fe78be15f2912b6271dd8a43badb6dd2a1b315b2ce7ae37b4e7778041d930d71ee1992d2466495c42102d08e81154c305307d1dcd52d0fa4c479b278e7", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #148: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd73b3c694391d8eadde3f3e874089464715ac20e4c126bbf6d864d648969f5b5a81e7198a3c3f23901cedc7a1d6eff6e9bf81108e6c35cd8559139af3135dbcbb9ef1568530291a8061b90c9f4285eefcba990d4570a4e3b7b737525b5d580034", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #149: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbb07ac7a86948c2c2989a16db1930ef1b89ce112595197656877e53c41457f28ab4d792ca121d1dba39cb9de645149c2ab573e8becc6ddff3cc9960f188ddf737f90ba23664153e93262ff73355415195858d7be1315a69456386de68285a3c8", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #150: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd27e4d82cb6c061dd9337c69bf9332ed3d198662d6f2299443f62c861187db648518412b69af43aae084476a68d59bbde51fbfa9e5be80563f587c9c2652f88ef2d3b90d25baa6bdb7b0c55e5240a3a98fbc24afed8523edec1c70503fc10f233", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #151: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffde7c5cf3aac2e88923b77850515fff6a12d13b356dfe9ec275c3dd81ae94609a4a08f14a644b9a935dffea4761ebaf592d1f66fe6cd373aa7f5d370af34f8352da54b5bc4025cf335900a914c2934ec2fec7a396d0a7affcad732a5741c7aaaf5", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #152: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc77838df91c1e953e016e10bddffea2317f9fee32bacfe553cede9e57a748f68ccf2296a6a89b62b90739d38af4ae3a20e9f45715b90044639241061e33f8f8caace0046491eeaa1c6e9a472b96d88f4af83e7ff1bb84438c7e058034412ae08", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #153: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8ef071c02383d2a6c02dc217bbffd446730d0318b0425e2586220907f885f97f94b0fc1525bcabf82b1f34895e5819a06c02b23e04002276e165f962c86e3927be7c2ab4d0b25303204fb32a1f8292902792225e16a6d2dbfb29fbc89a9c3376", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #154: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5668aaa0b545bbf9a044a32399ffbe69ce20074e34d7bdf5cf56282a769763965351f37e1de0c88c508527d89882d183ccdcf2efca407edb0627cadfd16de6ec44b4b57cdf960d32ebcc4c97847eed218425853b5b675eb781b766a1a1300349", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #155: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd12d6e56882f6c0027cae91a27127728f7fddf478fb4fdc2b65f40a60b0eb952748bbafc320e6735cb64019710a269c6c2b5d147bdc831325cb2fb276ac971a69d655e9a755bc9d800ad21ee3fd4d980d93a7a49a8c5ccd37005177578f51163", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #156: edge case for u1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7fffffffaaaaaaaaffffffffffffffffe9a2538f37b28a2c513dee40fecbb71a14b3bbd75c5e1c0c36535a934d4ab85112410b3b90fa97a31c33038964fd85cc112f7d837f8f9c36b460d636c965a5f818f2b50c5d00fb3f9705561dd6631883", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #157: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdb62f26b5f2a2b26f6de86d42ad8a13da3ab3cccd0459b201de009e526adf21f2d823533c04cd8edc6d6f950a8e08ade04a9bafa2f14a590356935671ae9305bf43178d1f88b6a57a96924c265f0ddb75b58312907b195acb59d7797303123775", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #158: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbb1d9ac949dd748cd02bbbe749bd351cd57b38bb61403d700686aa7b4c90851edb2b3408b3167d91030624c6328e8ce3ec108c105575c2f3d209b92e654bab69c34318139c50b0802c6e612f0fd3189d800df7c996d5d7b7c3d6be82836fa258", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #159: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd66755a00638cdaec1c732513ca0234ece52545dac11f816e818f725b4f60aaf209179ce7c59225392216453b2ac1e9d178c24837dfae26bc1dd7ab60638527425556b42e330289f3b826b2db7a86d19d45c2860a59f2be1ddcc3b691f95a9255", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #160: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd55a00c9fcdaebb6032513ca0234ecfffe98ebe492fdf02e48ca48e982beb366901959fb8deda56e5467b7e4b214ea4c2d0c2fb29d70ff19b6b1eccebd6568d7ed9dbd77a918297fd970bff01e1343f6925167db5a14d098a211c39cc3a413398", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #161: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdab40193f9b5d76c064a27940469d9fffd31d7c925fbe05c919491d3057d66cd2567f1fdc387e5350c852b4e8f8ba9d6d947e1c5dd7ccc61a5938245dd6bcab3a9960bebaf919514f9535c22eaaf0b5812857970e26662267b1f3eb1011130a11", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #162: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdca0234ebb5fdcb13ca0234ecffffffffcb0dadbbc7f549f8a26b4408d0dc86003499f974ff4ca6bbb2f51682fd5f51762f9dd6dd2855262660b36d46d3e4bec2f498fae2487807e220119152f0122476c64d4fa46ddce85c4546630f0d5c5e81", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #163: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff3ea3677e082b9310572620ae19933a9e65b285598711c77298815ad32c5c01662cf00c1929596257db13b26ecf30d0f3ec4b9f0351b0f27094473426e986a086060d086eee822ddd2fc744247a0154b57f7a69c51d9fdafa484e4ac7", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #164: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd266666663bbbbbbbe6666666666666665b37902e023fab7c8f055d86e5cc41f491d4cba813a04d86dbae94c23be6f52c15774183be7ba5b2d9f3cf010b160501900b8adfea6491019a9ac080d516025a541bf4b952b0ad7be4b1874b02fd544a", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #165: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff36db6db7a492492492492492146c573f4c6dfc8d08a443e258970b09ef7fd0a3a36386638330ecad41e1a3b302af36960831d0210c614b948e8aa124ef0d6d800e4047d6d3c1be0fdeaf11fcd8cab5ab59c730eb34116e35a8c7d098", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #166: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff2aaaaaab7fffffffffffffffc815d0e60b3e596ecb1ad3a27cfd49c4a521dab13cc9152d8ca77035a607fea06c55cc3ca5dbeb868cea92eafe93df2a7bfb9b28531996635e6a5ccaa2826a406ce1111bdb9c2e0ca36500418a2f43de", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #167: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7fffffff55555555ffffffffffffffffd344a71e6f651458a27bdc81fd976e37474d58a4eec16e0d565f2187fe11d4e8e7a2683a12f38b4fc01d1237a81a10976e55f73bb7cdda46bdb67ef77f6fd2969df2b67920fb5945fde3a517a6ded4cd", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #168: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd3fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192aa692da5cd4309d9a6e5cb525c37da8fa0879f7b57208cdabbf47d223a5b23a62140e0daa78cfdd207a7389aaed61738b17fc5fc3e6a5ed3397d2902e9125e6ab4", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #169: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d8ecd64a4eeba466815ddf3a4de9a8e6abd9c5db0a01eb80343553da648428f85689b3e0775c7718a90279f14a8082cfcd4d1f1679274f4e9b8805c570a0670167fcc5ca734552e09afa3640f4a034e15b9b7ca661ec7ff70d3f240ebe705b1", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #170: edge case for u2", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569f21d907e3890916dc4fa1f4703c1e50d3f54ddf7383e44023a41de562aa18ed80158137755b901f797a90d4ca8887e023cb2ef63b2ba2c0d455edaef42cf237e2a964fc00d377a8592b8b61aafa7a4aaa7c7b9fd2b41d6e0e17bd1ba5677edcd", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #171: point duplication during verification", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569f21d907e3890916dc4fa1f4703c1e50d3f54ddf7383e44023a41de562aa18ed80158137755b901f797a90d4ca8887e023cb2ef63b2ba2c0d455edaef42cf237ed569b03ef2c8857b6d4749e550585b5558384603d4be291f1e842e45a9881232", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #172: duplication bug", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e250000000000000000000000000000000000000000000000000000000000000001555555550000000055555555555555553ef7a8e48d07df81a693439654210c7038a084ffccc4ae2f8204be2abca9fb8ad4ab283b2aa50f13b6bb2347adabc69ca699799b77b1cc6dad271e88b899c12931986e958e1f5cf5653dddf7389365e2", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #173: point with x-coordinate 0", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25555555550000000055555555555555553ef7a8e48d07df81a693439654210c703333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aa9664ce273320d918d8bdb2e61201b4549b36b7cdc54e33b84adb6f2c10aac831e49e68831f18bda2973ac3d76bfbc8c5ee1cceed2dd862e2dc7c915c736cef1f4", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #175: comparison with point at infinity ", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978555555550000000055555555555555553ef7a8e48d07df81a693439654210c70961691a5e960d07a301dbbad4d86247ec27d7089faeb3ddd1add395efff1e0fe7254622cc371866cdf990d2c5377790e37d1f1519817f09a231bd260a9e78aeb", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #176: extreme value for k and edgecase s", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc5d283e13ce8ca60da868e3b0fb33e6b4f1074793274e2928250e71e2aca63e9c214dc74fa25371fb4d9e506d418ed9a1bfd6d0c8bb6591d3e0f44505a84886ce", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #177: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa70fc351da038ae0803bd1d86514ae0462f9f8216551d9315aa9d297f792eef6a341c74eed786f2d33da35360ca7aa925e753f00d6077a1e9e5fc339d634019c73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #178: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc476699783333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaaa1e34c8f16d138673fee55c080547c2bfd4de7550065f638322bba9430ce4b60662be9bb512663aa4d7df8ab3f3b4181c5d44a7bdf42436620b7d8a6b81ac936", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #179: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997849249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c1857e1a8a8338d7fd8cf41d322a302d2078a87a23c7186150ed7cda6e52817c1bdfd0a9135a89d21ce821e29014b2898349254d748272b2d4eb8d59ee34c615377f", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #180: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e257cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997816a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb5c19fe227a61abc65c61ee7a018cc9571b2c6f663ea33583f76a686f64be078b7b4a0d734940f613d52bc48673b457c2cf78492490a5cc5606c0541d17b24ddb", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #181: extreme value for k", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296555555550000000055555555555555553ef7a8e48d07df81a693439654210c70db02d1f3421d600e9d9ef9e47419dba3208eed08c2d4189a5db63abeb2739666e0ed26967b9ada9ed7ffe480827f90a0d210d5fd8ec628e31715e6b24125512a", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #182: extreme value for k and edgecase s", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc6222d1962655501893c29e441395b6c05711bd3ed5a0ef72cfab338b88229c4baaae079cb44a1af070362aaa520ee24cac2626423b0bf81af1c54311d8e2fd23", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #183: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa74ccfa24c67f3def7fa81bc99c70bb0419c0952ba599f4c03361da184b04cdca5db76b797f7f41d9c729a2219478a7e629728df870800be8cf6ca7a0a82153bfa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #184: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2963333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaaea1c72c91034036bac71402b6e9ecc4af3dbde7a99dc574061e99fefff9d84dab7dd057e75b78ac6f56e34eb048f0a9d29d5d055408c90d02bc2ea918c18cb63", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #185: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29649249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185c2879a66d86cb20b820b7795da2da62b38924f7817d1cd350d936988e90e79bc5431a7268ff6931c7a759de024eff90bcb0177216db6fd1f3aaaa11fa3b6a083", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #186: extreme value for k and s^-1", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e256b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29616a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bbab1c0f273f74abc2b848c75006f2ef3c54c26df27711b06558f455079aee0ba3df510f2ecef6d9a05997c776f14ad6456c179f0a13af1771e4d6c37fa48b47f2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #187: extreme value for k", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #188: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25acd155416a8b77f34089464733ff7cd39c400e9c69af7beb9eac5054ed2ec72c249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #189: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #190: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25acd155416a8b77f34089464733ff7cd39c400e9c69af7beb9eac5054ed2ec72c249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c26b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a", + "Expected": "", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #191: testing point duplication", + "NoBenchmark": false + }, + { + "Input": "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023a8ea150cb80125d7381c4c1f1da8e9de2711f9917060406a73d7904519e51388f3ab9fa68bd47973a73b2d40480c2ba50c22c9d76ec217257288293285449b8604aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #269: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e2530e782f964b2e2ff065a051bc7adc20615d8c43a1365713c88268822c253bcce5b16df652aa1ecb2dc8b46c515f9604e2e84cacfa7c6eec30428d2d3f4e08ed504aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #270: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855b292a619339f6e567a305c951c0dcbcc42d16e47f219f9e98e76e09d8770b34a0177e60492c5a8242f76f07bfe3661bde59ec2a17ce5bd2dab2abebdf89a62e204aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #271: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "de47c9b27eb8d300dbb5f2c353e632c393262cf06340c4fa7f1b40c4cbd36f90986e65933ef2ed4ee5aada139f52b70539aaf63f00a91f29c69178490d57fb713dafedfb8da6189d372308cbf1489bbbdabf0c0217d1c0ff0f701aaa7a694b9c04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #272: pseudorandom signature", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d434e262a49eab7781e353a3565e482550dd0fd5defa013c7f29745eff3569f19b0c0a93f267fb6052fd8077be769c2b98953195d7bc10de844218305c6ba17a4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #288: x-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f910fe774355c04d060f76d79fd7a772e421463489221bf0a33add0be9b1979110b500dcba1c69a8fbd43fa4f57f743ce124ca8b91a1f325f3fac6181175df557374f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #289: x-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91bb40bf217bed3fb3950c7d39f03d36dc8e3b2cd79693f125bfd06595ee1135e3541bf3532351ebb032710bdb6a1bf1bfc89a1e291ac692b3fa4780745bb556774f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #290: x-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91664eb7ee6db84a34df3c86ea31389a5405badd5ca99231ff556d3e75a233e73a59f3c752e52eca46137642490a51560ce0badc678754b8f72e51a2901426a1bd3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #291: y-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f914cd0429bbabd2827009d6fcd843d4ce39c3e42e2d1631fd001985a79d1fd8b439638bf12dd682f60be7ef1d0e0d98f08b7bca77a1a2b869ae466189d2acdabe33cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #292: y-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91e56c6ea2d1b017091c44d8b6cb62b9f460e3ce9aed5e5fd41e8added97c56c04a308ec31f281e955be20b457e463440b4fcf2b80258078207fc1378180f89b553cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #293: y-coordinate of the public key has many trailing 0's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f911158a08d291500b4cabed3346d891eee57c176356a2624fb011f8fbbf3466830228a8c486a736006e082325b85290c5bc91f378b75d487dda46798c18f2855193cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #294: y-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91b1db9289649f59410ea36b0c0fc8d6aa2687b29176939dd23e0dde56d309fa9d3e1535e4280559015b0dbd987366dcf43a6d1af5c23c7d584e1c3f48a12513363cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #295: y-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91b7b16e762286cb96446aa8d4e6e7578b0a341a79f2dd1a220ac6f0ca4e24ed86ddc60a700a139b04661c547d07bbb0721780146df799ccf55e55234ecb8f12bc3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #296: y-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d82a7c2717261187c8e00d8df963ff35d796edad36bc6e6bd1c91c670d9105b43dcabddaf8fcaa61f4603e7cbac0f3c0351ecd5988efb23f680d07debd1399292829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #297: x-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f915eb9c8845de68eb13d5befe719f462d77787802baff30ce96a5cba063254af782c026ae9be2e2a5e7ca0ff9bbd92fb6e44972186228ee9a62b87ddbe2ef66fb52829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #298: x-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9196843dd03c22abd2f3b782b170239f90f277921becc117d0404a8e4e36230c28f2be378f526f74a543f67165976de9ed9a31214eb4d7e6db19e1ede123dd991d2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #299: x-coordinate of the public key has many trailing 1's", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91766456dce1857c906f9996af729339464d27e9d98edc2d0e3b760297067421f6402385ecadae0d8081dccaf5d19037ec4e55376eced699e93646bfbbf19d0b41fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #300: x-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91c605c4b2edeab20419e6518a11b2dbc2b97ed8b07cced0b19c34f777de7b9fd9edf0f612c5f46e03c719647bc8af1b29b2cde2eda700fb1cff5e159d47326dbafffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #301: x-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d48b68e6cabfe03cf6141c9ac54141f210e64485d9929ad7b732bfe3b7eb8a84feedae50c61bd00e19dc26f9b7e2265e4508c389109ad2f208f0772315b6c941fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #302: x-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91b7c81457d4aeb6aa65957098569f0479710ad7f6595d5874c35a93d12a5dd4c7b7961a0b652878c2d568069a432ca18a1a9199f2ca574dad4b9e3a05c0a1cdb300000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #303: x-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f916b01332ddb6edfa9a30a1321d5858e1ee3cf97e263e669f8de5e9652e76ff3f75939545fced457309a6a04ace2bd0f70139c8f7d86b02cb1cc58f9e69e96cd5a00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #304: x-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91efdb884720eaeadc349f9fc356b6c0344101cd2fd8436b7d0e6a4fb93f106361f24bee6ad5dc05f7613975473aadf3aacba9e77de7d69b6ce48cb60d8113385d00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #305: x-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9131230428405560dcb88fb5a646836aea9b23a23dd973dcbe8014c87b8b20eb070f9344d6e812ce166646747694a41b0aaf97374e19f3c5fb8bd7ae3d9bd0beffbcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #306: y-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91caa797da65b320ab0d5c470cda0b36b294359c7db9841d679174db34c4855743cf543a62f23e212745391aaf7505f345123d2685ee3b941d3de6d9b36242e5a0bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #307: y-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f917e5f0ab5d900d3d3d7867657e5d6d36519bc54084536e7d21c336ed8001859459450c07f201faec94b82dfb322e5ac676688294aad35aa72e727ff0b19b646aabcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #308: y-coordinate of the public key is small", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91d7d70c581ae9e3f66dc6a480bf037ae23f8a1e4a2136fe4b03aa69f0ca25b35689c460f8a5a5c2bbba962c8a3ee833a413e85658e62a59e2af41d9127cc47224bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #309: y-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91341c1b9ff3c83dd5e0dfa0bf68bcdf4bb7aa20c625975e5eeee34bb396266b3472b69f061b750fd5121b22b11366fad549c634e77765a017902a67099e0a4469bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #310: y-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9170bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a9bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #311: y-coordinate of the public key is large", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9170bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a90000000000000000000000000000000000000000000000000000000000000000fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "Expected": "", + "Gas": 3450, + "Name": "invalid public key x param errors", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9170bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a9bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af0150000000000000000000000000000000000000000000000000000000000000000", + "Expected": "", + "Gas": 3450, + "Name": "invalid public key y param errors", + "NoBenchmark": false + }, + { + "Input": "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f9170bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "", + "Gas": 3450, + "Name": "reference point errors", + "NoBenchmark": false + } +] \ No newline at end of file
diff --git go-ethereum/eth/downloader/userDepositData/10.105235063-114696812.gob op-geth/eth/downloader/userDepositData/10.105235063-114696812.gob new file mode 100644 index 0000000000000000000000000000000000000000..f26643825f272cf945fc71c953265bac6336f40a Binary files /dev/null and op-geth/eth/downloader/userDepositData/10.105235063-114696812.gob differ
diff --git go-ethereum/eth/downloader/userDepositData/291.0-4192087.gob op-geth/eth/downloader/userDepositData/291.0-4192087.gob new file mode 100644 index 0000000000000000000000000000000000000000..0a94e024c6638124ac5af95ef101ff7209516331 Binary files /dev/null and op-geth/eth/downloader/userDepositData/291.0-4192087.gob differ
diff --git go-ethereum/eth/downloader/userDepositData/34443.0-2412409.gob op-geth/eth/downloader/userDepositData/34443.0-2412409.gob new file mode 100644 index 0000000000000000000000000000000000000000..750e6669594db72e1ce3d5d779651a56e3166cb2 Binary files /dev/null and op-geth/eth/downloader/userDepositData/34443.0-2412409.gob differ
diff --git go-ethereum/eth/downloader/userDepositData/420.6825766-17276566.gob op-geth/eth/downloader/userDepositData/420.6825766-17276566.gob new file mode 100644 index 0000000000000000000000000000000000000000..d17871da6e0a732ad24b8186136d3e18d6a53f91 Binary files /dev/null and op-geth/eth/downloader/userDepositData/420.6825766-17276566.gob differ
diff --git go-ethereum/eth/downloader/userDepositData/7777777.0-9149281.gob op-geth/eth/downloader/userDepositData/7777777.0-9149281.gob new file mode 100644 index 0000000000000000000000000000000000000000..ee63497b9c874cffc6435d680be8dc67958456c9 Binary files /dev/null and op-geth/eth/downloader/userDepositData/7777777.0-9149281.gob differ
diff --git go-ethereum/eth/downloader/userDepositData/8453.0-9101527.gob op-geth/eth/downloader/userDepositData/8453.0-9101527.gob new file mode 100644 index 0000000000000000000000000000000000000000..88f825e01ad52bbb543527b50d88ee5640728a2d Binary files /dev/null and op-geth/eth/downloader/userDepositData/8453.0-9101527.gob differ
diff --git go-ethereum/eth/tracers/internal/tracetest/testdata/call_tracer/deposit.json op-geth/eth/tracers/internal/tracetest/testdata/call_tracer/deposit.json new file mode 100644 index 0000000000000000000000000000000000000000..b946a1e5c5a4eb2136531c09cf298c5590c0cb17 --- /dev/null +++ op-geth/eth/tracers/internal/tracetest/testdata/call_tracer/deposit.json @@ -0,0 +1,52 @@ +{ + "context": { + "difficulty": "3699098917", + "gasLimit": "5258985", + "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", + "number": "2294631", + "timestamp": "1513675366" + }, + "genesis": { + "alloc": { + "0xBc339E628E6fe32C39E84392D087567B2743Ea35": { + "balance": "0x99999999999999999" + } + }, + "config": { + "chainId": 3, + "daoForkSupport": true, + "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", + "ethash": {}, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0 + }, + "difficulty": "3699098917", + "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", + "gasLimit": "5263953", + "hash": "0x03a0f62a8106793dafcfae7b75fd2654322062d585a19cea568314d7205790dc", + "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", + "mixHash": "0x15482cc64b7c00a947f5bf015dfc010db1a6a668c74df61974d6a7848c174408", + "nonce": "0xd1bdb150f6fd170e", + "number": "2294630", + "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1", + "timestamp": "1513675347", + "totalDifficulty": "7160543502214733" + }, + "input": "0x7ef85aa0b4f9f798a5fe956d1b79c3eff355febf9e1039a7440948845536982cb62aa03194bc339e628e6fe32c39e84392d087567b2743ea3594bc339e628e6fe32c39e84392d087567b2743ea3580871aa535d3d0c00083030d408000", + "result": { + "from":"0xBc339E628E6fe32C39E84392D087567B2743Ea35", + "to": "0xbc339e628e6fe32c39e84392d087567b2743ea35", + "gas":"0x30d40", + "gasUsed":"0x30d40", + "input":"0x00", + "value": "0x1aa535d3d0c000", + "type":"CALL" + } +} \ No newline at end of file
diff --git go-ethereum/eth/tracers/internal/tracetest/testdata/call_tracer/failed_deposit.json op-geth/eth/tracers/internal/tracetest/testdata/call_tracer/failed_deposit.json new file mode 100644 index 0000000000000000000000000000000000000000..2c43cdae0f732a4faae29e19cc8df11741d198fa --- /dev/null +++ op-geth/eth/tracers/internal/tracetest/testdata/call_tracer/failed_deposit.json @@ -0,0 +1,47 @@ +{ + "context": { + "difficulty": "3699098917", + "gasLimit": "5258985", + "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", + "number": "2294631", + "timestamp": "1513675366" + }, + "genesis": { + "alloc": {}, + "config": { + "chainId": 3, + "daoForkSupport": true, + "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", + "ethash": {}, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0 + }, + "difficulty": "3699098917", + "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", + "gasLimit": "5263953", + "hash": "0x03a0f62a8106793dafcfae7b75fd2654322062d585a19cea568314d7205790dc", + "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", + "mixHash": "0x15482cc64b7c00a947f5bf015dfc010db1a6a668c74df61974d6a7848c174408", + "nonce": "0xd1bdb150f6fd170e", + "number": "2294630", + "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1", + "timestamp": "1513675347", + "totalDifficulty": "7160543502214733" + }, + "input": "0x7ef85aa0b4f9f798a5fe956d1b79c3eff355febf9e1039a7440948845536982cb62aa03194bc339e628e6fe32c39e84392d087567b2743ea3594bc339e628e6fe32c39e84392d087567b2743ea3580871aa535d3d0c00083030d408000", + "result": { + "from":"0x0000000000000000000000000000000000000000", + "gas":"0x0", + "gasUsed":"0x30d40", + "input":"0x", + "error": "failed deposit transaction", + "type":"STOP" + } +}
diff --git go-ethereum/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deposit.json op-geth/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deposit.json new file mode 100644 index 0000000000000000000000000000000000000000..56133befc7b7d0ba33f93912955a09a9e965224d --- /dev/null +++ op-geth/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deposit.json @@ -0,0 +1,65 @@ +{ + "context": { + "difficulty": "3699098917", + "gasLimit": "5258985", + "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", + "number": "2294631", + "timestamp": "1513675366" + }, + "genesis": { + "alloc": { + "0xBc339E628E6fe32C39E84392D087567B2743Ea35": { + "balance": "0x99999999999999999" + } + }, + "config": { + "chainId": 3, + "daoForkSupport": true, + "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", + "ethash": {}, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0 + }, + "difficulty": "3699098917", + "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", + "gasLimit": "5263953", + "hash": "0x03a0f62a8106793dafcfae7b75fd2654322062d585a19cea568314d7205790dc", + "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", + "mixHash": "0x15482cc64b7c00a947f5bf015dfc010db1a6a668c74df61974d6a7848c174408", + "nonce": "0xd1bdb150f6fd170e", + "number": "2294630", + "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1", + "timestamp": "1513675347", + "totalDifficulty": "7160543502214733" + }, + "input": "0x7ef85aa0b4f9f798a5fe956d1b79c3eff355febf9e1039a7440948845536982cb62aa03194bc339e628e6fe32c39e84392d087567b2743ea3594bc339e628e6fe32c39e84392d087567b2743ea3580871aa535d3d0c00083030d408000", + "result": [{ + "type": "call", + "action": { + "author": "0x0000000000000000000000000000000000000000", + "refundAddress": "0x0000000000000000000000000000000000000000", + "from":"0xBc339E628E6fe32C39E84392D087567B2743Ea35", + "to": "0xbc339e628e6fe32c39e84392d087567b2743ea35", + "gas":"0x30d40", + "gasUsed":"0x30d40", + "input":"0x00", + "value": "0x1aa535d3d0c000", + "callType":"call", + "address": "0x0000000000000000000000000000000000000000", + "balance": "0x0" + }, + "result": { + "address": "0x0000000000000000000000000000000000000000", + "gasUsed": "0x30d40", + "output": "0x" + }, + "traceAddress": [] + }] +}
diff --git go-ethereum/eth/tracers/internal/tracetest/testdata/call_tracer_flat/failed_deposit.json op-geth/eth/tracers/internal/tracetest/testdata/call_tracer_flat/failed_deposit.json new file mode 100644 index 0000000000000000000000000000000000000000..540cd53579b1f58a9f72da481d2f86a8572ee430 --- /dev/null +++ op-geth/eth/tracers/internal/tracetest/testdata/call_tracer_flat/failed_deposit.json @@ -0,0 +1,59 @@ +{ + "context": { + "difficulty": "3699098917", + "gasLimit": "5258985", + "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", + "number": "2294631", + "timestamp": "1513675366" + }, + "genesis": { + "alloc": {}, + "config": { + "chainId": 3, + "daoForkSupport": true, + "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", + "ethash": {}, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0 + }, + "difficulty": "3699098917", + "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", + "gasLimit": "5263953", + "hash": "0x03a0f62a8106793dafcfae7b75fd2654322062d585a19cea568314d7205790dc", + "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", + "mixHash": "0x15482cc64b7c00a947f5bf015dfc010db1a6a668c74df61974d6a7848c174408", + "nonce": "0xd1bdb150f6fd170e", + "number": "2294630", + "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1", + "timestamp": "1513675347", + "totalDifficulty": "7160543502214733" + }, + "input": "0x7ef85aa0b4f9f798a5fe956d1b79c3eff355febf9e1039a7440948845536982cb62aa03194bc339e628e6fe32c39e84392d087567b2743ea3594bc339e628e6fe32c39e84392d087567b2743ea3580871aa535d3d0c00083030d408000", + "result": [ + { + "action": { + "callType": "stop", + "from": "0x0000000000000000000000000000000000000000", + "gas": "0x0", + "input": "0x", + "value": "0x0" + }, + "blockNumber": 0, + "error": "failed deposit transaction", + "result": { + "gasUsed": "0x0", + "output": "0x" + }, + "subtraces": 0, + "traceAddress": [], + "type": "call" + } + ] +}
(new)
+354
-0
diff --git go-ethereum/fork.yaml op-geth/fork.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0e821c2f129c8f9f2dd991ba4635b324d0a37da3 --- /dev/null +++ op-geth/fork.yaml @@ -0,0 +1,354 @@ +title: "op-geth - go-ethereum fork diff overview" +footer: | + Fork-diff overview of [`op-geth`](https://github.com/ethereum-optimism/op-geth), a fork of [`go-ethereum`](https://github.com/ethereum/go-ethereum). + and execution-engine of the [OP-stack](https://github.com/ethereum-optimism/optimism). +base: + name: go-ethereum + url: https://github.com/ethereum/go-ethereum + hash: f0e8a3e9c8a59ce3c97c2f474eee7a1e86544e8d # between v1.14.12 <> v1.14.13/v1.15 +fork: + name: op-geth + url: https://github.com/ethereum-optimism/op-geth + ref: refs/heads/optimism +def: + title: "op-geth" + description: | + This is an overview of the changes in [`op-geth`](https://github.com/ethereum-optimism/op-geth), + a fork of [`go-ethereum`](https://github.com/ethereum/go-ethereum), part of the OP-stack. + + The OP-stack architecture is modular, following the Consensus/Execution split of post-Merge Ethereum L1: + + - [`op-node`](https://github.com/ethereum-optimism/optimism/tree/develop/op-node) implements most rollup-specific functionality as Consensus-Layer, similar to a L1 beacon-node. + - [`op-geth`](https://github.com/ethereum-optimism/op-geth) implements the Execution-Layer, with **minimal changes** for a secure Ethereum-equivalent application environment. + + Related [op-stack specifications](https://github.com/ethereum-optimism/optimism/tree/develop/specs): + + - [L2 Execution Engine spec](https://github.com/ethereum-optimism/optimism/blob/develop/specs/exec-engine.md) + - [Deposit Transaction spec](https://github.com/ethereum-optimism/optimism/blob/develop/specs/deposits.md) + sub: + - title: "Core modifications" + sub: + - title: "State-transition modifications" + description: "" + sub: + - title: "Deposit Transaction type" + description: | + The Bedrock upgrade introduces a `Deposit` transaction-type (`0x7E`) to enable both users and the + rollup system itself to change the L2 state based on L1 events and system rules as + [specified](https://github.com/ethereum-optimism/optimism/blob/develop/specs/deposits.md). + globs: + - "core/types/deposit_tx.go" + - "core/types/transaction_marshalling.go" + - "core/types/transaction_signing.go" + - title: "Transaction properties" + description: | + The `Transaction` type now exposes the deposit-transaction and L1-cost properties required for the rollup. + globs: + - "core/types/transaction.go" + - "core/types/tx_access_list.go" + - "core/types/tx_dynamic_fee.go" + - "core/types/tx_legacy.go" + - "core/types/tx_blob.go" + - title: "EVM enhancements" + description: | + Apply L1 cost computation, and add EVM configuration for tooling and more: + - Disable bytecode size-limits (for large test/script contracts). + - Prank (solidity test terminology) the EVM-call message-sender. + - Override precompiles, to insert tooling precompiles and optimize precompile proving. + globs: + - "core/vm/evm.go" + - "core/vm/interpreter.go" + - "core/vm/gas_table.go" + - title: "L1 cost computation" + description: | + Transactions must pay an additional L1 cost based on the amount of rollup-data-gas they consume, + estimated based on gas-price-oracle information and encoded tx size." + globs: + - "core/evm.go" + - "core/types/rollup_cost.go" + - "core/state_processor.go" + - "core/state_prefetcher.go" + - title: Transaction processing + description: | + Deposit transactions have special processing rules: gas is pre-paid on L1, + and deposits with EVM-failure are included with rolled back changes (except mint). + For regular transactions, at the end of the transition, the 1559 burn and L1 cost are routed to vaults. + globs: + - "core/state_transition.go" + - title: "Core Error definitions" + globs: + - "core/error.go" + - title: "Gaslimit and EIP-1559 Params" + description: | + The gaslimit is free to be set by the Engine API caller, instead of enforcing adjustments of the + gaslimit in increments of 1/1024 of the previous gaslimit. The elasticity-multiplier and + base-fee-max-change-denominator EIP-1559 parameters can also be set by the Engine API caller through the + ExtraData field. The gaslimit and EIP-1559 parameters are changed (and limited) through the + `SystemConfig` contract. + globs: + - "consensus/misc/eip1559/*" + - title: "Consensus tweaks" + description: | + The Engine API is activated at the Merge transition, with a Total Terminal Difficulty (TTD). + The rollup starts post-merge, and thus sets the TTD to 0. + The TTD is always "reached" starting at the bedrock block. + globs: + - "consensus/beacon/consensus.go" + - title: "Legacy OP-mainnet / OP-goerli header-verification support" + description: | + Pre-Bedrock OP-mainnet and OP-Goerli had differently formatted block-headers, loosely compatible with the geth types (since it was based on Clique). + However, due to differences like the extra-data length (97+ bytes), these legacy block-headers need special verification. + The pre-merge "consensus" fallback is set to this custom but basic verifier, to accept these headers when syncing a pre-bedrock part of the chain, + independent of any clique code or configuration (which may be removed from geth at a later point). + All the custom verifier has to do is accept the headers, as the headers are already verified by block-hash through the reverse-header-sync. + globs: + - "consensus/beacon/oplegacy.go" + - title: "Engine API modifications" + description: | + The Engine API is extended to insert transactions into the block and optionally exclude the tx-pool, to + reproduce the exact block of the sequencer from just the inputs, as derived from L1 by the rollup-node. See + [L2 execution engine specs](https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/exec-engine.md). + It is also extended to support dynamic EIP-1559 parameters. See + [Holocene execution engine specs](https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/holocene/exec-engine.md). + globs: + - "beacon/engine/types.go" + - "beacon/engine/gen_blockparams.go" + - "eth/catalyst/api.go" + - title: "Block-building modifications" + description: | + The block-building code (in the "miner" package because of Proof-Of-Work legacy of ethereum) implements the + changes to support the transaction-inclusion, tx-pool toggle, gaslimit, and EIP-1559 parameters of the + Engine API. + This also includes experimental support for interop executing-messages to be verified through an RPC. + globs: + - "miner/*" + - title: "Tx-pool tx cost updates" + description: | + Transaction queueing and inclusion needs to account for the L1 cost component. + globs: + - "core/txpool/**/*" + - "core/txpool/legacypool/*" + - title: "RIP-7212" + description: "" + globs: + - "core/vm/contracts.go" + - "crypto/secp256r1/publickey.go" + - "crypto/secp256r1/verifier.go" + - title: "Chain Configuration" + sub: + - title: "Chain config" + description: | + The rollup functionality is enabled with the `optimism` field in the chain config. + The EIP-1559 parameters are configurable to adjust for faster more frequent and smaller blocks. + The parameters can be overriden for testing. + globs: + - "params/config.go" + - "params/protocol_params.go" + - "core/genesis.go" + - title: "Chain config cleanup" + description: | + The optimism Goerli testnet used clique-config data to make geth internals accept blocks. + Post-bedrock the beacon-consensus (i.e. follow Engine API) is now used, and the clique config is removed. + globs: + - "core/rawdb/accessors_metadata.go" + - title: Genesis loading + globs: + - "core/gen_genesis.go" + - title: "Superchain config" + description: Testing of the superchain configuration + globs: + - "core/superchain.go" + - "params/superchain.go" + - title: "Node modifications" + description: Changes to the node configuration and services. + sub: + - title: "CLI" + sub: + - title: "Flags" + description: | + Flag changes: + - Transactions can be forwarded to an RPC for sequencing. + - Historical calls can be forwarded to a legacy node. + - The tx pool propagation can be enabled/disabled. + - The Optimism bedrock fork activation can be changed for testing. + globs: + - "cmd/utils/flags.go" + - "cmd/geth/main.go" + - "internal/flags/categories.go" + - "cmd/geth/config.go" + - title: "Versioning" + description: List the op-geth and upstream go-ethereum versions. + globs: + - "cmd/geth/misccmd.go" + - "params/version.go" + - "build/ci.go" + - title: Node config + globs: + - "eth/ethconfig/config.go" + - title: Tx gossip disable option + globs: + - "eth/handler.go" + - "eth/handler_eth.go" + - title: Warn on missing hardfork data + globs: + - "core/blockchain.go" + - title: Optional Engine API extensions + globs: + - "eth/catalyst/superchain.go" + - title: Support legacy DBs when snap-syncing + description: Snap-sync does not serve unprefixed code by default. + globs: + - "core/blockchain_reader.go" + - "eth/protocols/snap/handler.go" + - title: Historical data for Snap-sync + description: Snap-sync has access to trusted Deposit Transaction Nonce Data. + globs: + - "eth/downloader/downloader.go" + - "eth/downloader/receiptreference.go" + - title: PathDB diff-layers limit + description: | + Prevent the write-buffer to grow too large, to keep the journal optional, + and not restart on top of unavailable state. + globs: + - "triedb/pathdb/buffer.go" + - title: Discv5 node discovery + description: Fix discv5 option to allow discv5 to be an active source for node-discovery. + globs: + - "p2p/server.go" + - title: Bootnodes + description: Discovery bootnode addresses. + globs: + - "params/bootnodes.go" + - title: Generated TOML config update + globs: + - "eth/ethconfig/gen_config.go" + - title: "Single threaded execution" + description: | + The cannon fault proofs virtual machine does not support the creation of threads. To ensure compatibility, + thread creation is avoided when only a single CPU is available. + globs: + - "core/state/workers.go" + - "trie/hasher.go" + - title: "Interop message checking" + description: | + The interop upgrade introduces cross-chain message. + Transactions are checked for cross-chain message safety before and during inclusion into a block. + This also includes tx-pool ingress filtering. + globs: + - "eth/interop.go" + - "core/txpool/ingress_filters.go" + - title: "User API enhancements" + description: "Encode the Deposit Tx properties, the L1 costs, and daisy-chain RPC-calls for pre-Bedrock historical data" + sub: + - title: "Receipts metadata" + description: | + Pre-Bedrock L1-cost receipt data is loaded from the database if available, and post-Bedrock the L1-cost + metadata is hydrated on-the-fly based on the L1 fee information in the corresponding block. + globs: + - "core/types/receipt.go" + - "core/types/gen_receipt_json.go" + - "core/rawdb/accessors_chain.go" + - title: "API Backend" + description: | + Forward transactions to the sequencer if configured. + globs: + - "eth/api_backend.go" + - "eth/backend.go" + - "internal/ethapi/backend.go" + - title: "Apply L1 cost in API responses" + globs: + - "eth/state_accessor.go" + - title: API frontend + description: Format deposit and L1-cost data in transaction responses. Add `debug_chainConfig` API. + globs: + - "internal/ethapi/api.go" + - "rpc/errors.go" + - title: Tracer RPC daisy-chain + description: Forward pre-bedrock tracing calls to legacy node. + globs: + - "eth/tracers/api.go" + - title: "Daisy Chain tests" + ignore: + - "internal/ethapi/transaction_args_test.go" + - "ethclient/ethclient_test.go" + - "eth/tracers/api_test.go" + - title: Debug API + description: Fix Debug API block marshaling to include deposits + globs: + - "eth/api_debug.go" + - title: Eth gasprice suggestions + description: gasprice suggestion adjustments to accommodate faster L2 blocks and lower fees. + globs: + - "eth/gasprice/gasprice.go" + - "eth/gasprice/optimism-gasprice.go" + - title: API testvector fix + description: | + Upstream test of broken behavior; in Optimism, a zero signature is valid (pre-bedrock for deposit-txs), + and the chain ID formula on signature data must not be used, or an underflow happens. + globs: + - "internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json" + - title: "4337 Improvements" + description: "" + sub: + - title: eth_sendRawTransactionConditional + description: sequencer api for conditional transaction inclusion enforced out of protocol + globs: + - "cmd/geth/main.go" + - "cmd/utils/flags.go" + - "core/state/statedb.go" + - "core/state/statedb_test.go" + - "core/types/block.go" + - "core/types/block_test.go" + - "core/types/transaction.go" + - "core/types/transaction_conditional.go" + - "core/types/transaction_conditional.go" + - "core/types/transaction_conditional_test.go" + - "core/types/gen_transaction_conditional_json.go" + - "eth/backend.go" + - "eth/ethconfig/config.go" + - "eth/protocols/eth/broadcast.go" + - "internal/sequencerapi/api.go" + - "miner/miner.go" + - "miner/miner_test.go" + - "miner/worker.go" + - "params/conditional_tx_params.go" + - "rpc/json.go" + - title: "Geth extras" + description: Extend the tools available in geth to improve external testing and tooling. + sub: + - title: Simulated Backend + globs: + - "accounts/abi/bind/backends/simulated.go" + - "ethclient/simulated/backend.go" + - title: Live tracer update + description: | + Track L1-deposited native currency that is coming into the L2 supply. + The balance delta is considered to be a "withdrawal" from L1, + similar to a withdrawal of the Beacon-chain into the Ethereum L1 execution chain. + globs: + - "eth/tracers/live/supply.go" + - title: EVM t8ntool + description: | + The EVM `t8ntool` has not been updated with most op-stack features and does not + use the same sealer logic as used in Geth consensus. Isthumus hard fork adds + a `withdrawalsRoot` field in the block header. We note that the `t8ntool` is + not updated to handle the newly added `withdrawalsRoot` field in the block header. + globs: + - "cmd/evm/internal/t8ntool/block.go" + - title: "Testing" + description: Additional or modified tests, not already captured by the above diff + ignore: + - "**/*_test.go" + +# ignored globally, does not count towards line count +ignore: + - ".circleci/*" + - "*.sum" + - "go.mod" + - "fork.yaml" + - "Makefile" + - ".golangci.yml" + - ".github/**" + - "**/*.gob" # data asset, not code + - "core/vm/testdata/precompiles/p256Verify.json" # data asset, not code + - "eth/tracers/internal/tracetest/testdata/**/*.json"
diff --git go-ethereum/go.mod op-geth/go.mod index fc768460c7c723257bcddd8ad1ec75db69b23654..bc10541dd63b3549a512e75de08a10ef4931e090 100644 --- go-ethereum/go.mod +++ op-geth/go.mod @@ -2,8 +2,11 @@ module github.com/ethereum/go-ethereum   go 1.22.0   +toolchain go1.22.7 + require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 + github.com/BurntSushi/toml v1.4.0 github.com/Microsoft/go-winio v0.6.2 github.com/VictoriaMetrics/fastcache v1.12.2 github.com/aws/aws-sdk-go-v2 v1.21.2 @@ -16,11 +19,11 @@ github.com/cockroachdb/pebble v1.1.2 github.com/consensys/gnark-crypto v0.14.0 github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a github.com/crate-crypto/go-kzg-4844 v1.1.0 - github.com/davecgh/go-spew v1.1.1 + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/deckarep/golang-set/v2 v2.6.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 - github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 + github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 github.com/ethereum/c-kzg-4844 v1.0.0 github.com/ethereum/go-verkle v0.2.2 github.com/fatih/color v1.16.0 @@ -45,6 +48,7 @@ github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c github.com/jackpal/go-nat-pmp v1.0.2 github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 + github.com/klauspost/compress v1.17.11 github.com/kylelemons/godebug v1.1.0 github.com/mattn/go-colorable v0.1.13 github.com/mattn/go-isatty v0.0.20 @@ -78,7 +82,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect - github.com/DataDog/zstd v1.4.5 // indirect + github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43 // indirect @@ -115,7 +119,6 @@ github.com/hashicorp/go-retryablehttp v0.7.4 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kilic/bls12-381 v0.1.0 // indirect - github.com/klauspost/compress v1.16.0 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -132,7 +135,7 @@ github.com/pion/logging v0.2.2 // indirect github.com/pion/transport/v2 v2.2.1 // indirect github.com/pion/transport/v3 v3.0.1 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.12.0 // indirect github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect github.com/prometheus/common v0.32.1 // indirect @@ -140,6 +143,7 @@ github.com/prometheus/procfs v0.7.3 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect @@ -148,3 +152,5 @@ golang.org/x/net v0.34.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) + +//replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain
diff --git go-ethereum/go.sum op-geth/go.sum index 82836a5d8c05876ff08d0452f23a86ef1bba4d6e..b9a27f99733b93d6b077de5f814177baab2cc571 100644 --- go-ethereum/go.sum +++ op-geth/go.sum @@ -44,9 +44,11 @@ github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0/go.mod h1:+6KLcKIVgxoBDMqMO/Nvy7bZ9a0nbU3I1DtFQK3YvB4= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e h1:ZIWapoIRN1VqT8GR8jAwb1Ie9GyehWjVcGh32Y2MznE= +github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= @@ -137,8 +139,9 @@ github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= @@ -156,8 +159,8 @@ github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 h1:C7t6eeMaEQVy6e8CarIhscYQlNmw5e3G36y7l7Y21Ao= github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw= github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5RVoRccG8a5DhOdWdQ4zN62zzo= +github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -342,8 +345,8 @@ github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= -github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -440,8 +443,9 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -497,6 +501,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=