mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 07:06:42 +00:00
refactor: stateful precompiles
This commit is contained in:
parent
6f3bb41e10
commit
eca91aa939
9 changed files with 120 additions and 106 deletions
|
|
@ -31,18 +31,46 @@ import (
|
||||||
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
|
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/vm/precompiles"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/crypto/blake2b"
|
"github.com/ethereum/go-ethereum/crypto/blake2b"
|
||||||
"github.com/ethereum/go-ethereum/crypto/bn256"
|
"github.com/ethereum/go-ethereum/crypto/bn256"
|
||||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
"golang.org/x/crypto/ripemd160"
|
"golang.org/x/crypto/ripemd160"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PrecompiledContract is the basic interface for native Go contracts. The implementation
|
||||||
|
// requires a deterministic gas count based on the input size of the Run method of the
|
||||||
|
// contract.
|
||||||
|
type PrecompiledContract interface {
|
||||||
|
Address() common.Address
|
||||||
|
RequiredGas(input []byte) uint64 // RequiredPrice calculates the contract gas use
|
||||||
|
Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrecompiledContracts contains the precompiled contracts supported at the given fork.
|
||||||
|
type PrecompiledContracts map[common.Address]PrecompiledContract
|
||||||
|
|
||||||
|
var CustomPrecompiledContracts = PrecompiledContracts{}
|
||||||
|
|
||||||
|
// WithCustomPrecompiles merge given precompiles with custom precompiles
|
||||||
|
func WithCustomPrecompiles(base PrecompiledContracts) PrecompiledContracts {
|
||||||
|
result := make(PrecompiledContracts)
|
||||||
|
maps.Copy(result, base)
|
||||||
|
for k, v := range CustomPrecompiledContracts {
|
||||||
|
if _, exists := result[k]; !exists {
|
||||||
|
result[k] = v
|
||||||
|
} else {
|
||||||
|
panic("Precompile address collision")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// PrecompiledContractsHomestead contains the default set of pre-compiled Ethereum
|
// PrecompiledContractsHomestead contains the default set of pre-compiled Ethereum
|
||||||
// contracts used in the Frontier and Homestead releases.
|
// contracts used in the Frontier and Homestead releases.
|
||||||
var PrecompiledContractsHomestead = precompiles.WithCustomPrecompiles(precompiles.PrecompiledContracts{
|
var PrecompiledContractsHomestead = WithCustomPrecompiles(PrecompiledContracts{
|
||||||
(&ecrecover{}).Address(): &ecrecover{},
|
(&ecrecover{}).Address(): &ecrecover{},
|
||||||
(&sha256hash{}).Address(): &sha256hash{},
|
(&sha256hash{}).Address(): &sha256hash{},
|
||||||
(&ripemd160hash{}).Address(): &ripemd160hash{},
|
(&ripemd160hash{}).Address(): &ripemd160hash{},
|
||||||
|
|
@ -51,7 +79,7 @@ var PrecompiledContractsHomestead = precompiles.WithCustomPrecompiles(precompile
|
||||||
|
|
||||||
// PrecompiledContractsByzantium contains the default set of pre-compiled Ethereum
|
// PrecompiledContractsByzantium contains the default set of pre-compiled Ethereum
|
||||||
// contracts used in the Byzantium release.
|
// contracts used in the Byzantium release.
|
||||||
var PrecompiledContractsByzantium = precompiles.WithCustomPrecompiles(precompiles.PrecompiledContracts{
|
var PrecompiledContractsByzantium = WithCustomPrecompiles(PrecompiledContracts{
|
||||||
(&ecrecover{}).Address(): &ecrecover{},
|
(&ecrecover{}).Address(): &ecrecover{},
|
||||||
(&sha256hash{}).Address(): &sha256hash{},
|
(&sha256hash{}).Address(): &sha256hash{},
|
||||||
(&ripemd160hash{}).Address(): &ripemd160hash{},
|
(&ripemd160hash{}).Address(): &ripemd160hash{},
|
||||||
|
|
@ -64,7 +92,7 @@ var PrecompiledContractsByzantium = precompiles.WithCustomPrecompiles(precompile
|
||||||
|
|
||||||
// PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum
|
// PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum
|
||||||
// contracts used in the Istanbul release.
|
// contracts used in the Istanbul release.
|
||||||
var PrecompiledContractsIstanbul = precompiles.WithCustomPrecompiles(precompiles.PrecompiledContracts{
|
var PrecompiledContractsIstanbul = WithCustomPrecompiles(PrecompiledContracts{
|
||||||
(&ecrecover{}).Address(): &ecrecover{},
|
(&ecrecover{}).Address(): &ecrecover{},
|
||||||
(&sha256hash{}).Address(): &sha256hash{},
|
(&sha256hash{}).Address(): &sha256hash{},
|
||||||
(&ripemd160hash{}).Address(): &ripemd160hash{},
|
(&ripemd160hash{}).Address(): &ripemd160hash{},
|
||||||
|
|
@ -78,7 +106,7 @@ var PrecompiledContractsIstanbul = precompiles.WithCustomPrecompiles(precompiles
|
||||||
|
|
||||||
// PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum
|
// PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum
|
||||||
// contracts used in the Berlin release.
|
// contracts used in the Berlin release.
|
||||||
var PrecompiledContractsBerlin = precompiles.WithCustomPrecompiles(precompiles.PrecompiledContracts{
|
var PrecompiledContractsBerlin = WithCustomPrecompiles(PrecompiledContracts{
|
||||||
(&ecrecover{}).Address(): &ecrecover{},
|
(&ecrecover{}).Address(): &ecrecover{},
|
||||||
(&sha256hash{}).Address(): &sha256hash{},
|
(&sha256hash{}).Address(): &sha256hash{},
|
||||||
(&ripemd160hash{}).Address(): &ripemd160hash{},
|
(&ripemd160hash{}).Address(): &ripemd160hash{},
|
||||||
|
|
@ -92,7 +120,7 @@ var PrecompiledContractsBerlin = precompiles.WithCustomPrecompiles(precompiles.P
|
||||||
|
|
||||||
// PrecompiledContractsCancun contains the default set of pre-compiled Ethereum
|
// PrecompiledContractsCancun contains the default set of pre-compiled Ethereum
|
||||||
// contracts used in the Cancun release.
|
// contracts used in the Cancun release.
|
||||||
var PrecompiledContractsCancun = precompiles.WithCustomPrecompiles(precompiles.PrecompiledContracts{
|
var PrecompiledContractsCancun = WithCustomPrecompiles(PrecompiledContracts{
|
||||||
(&ecrecover{}).Address(): &ecrecover{},
|
(&ecrecover{}).Address(): &ecrecover{},
|
||||||
(&sha256hash{}).Address(): &sha256hash{},
|
(&sha256hash{}).Address(): &sha256hash{},
|
||||||
(&ripemd160hash{}).Address(): &ripemd160hash{},
|
(&ripemd160hash{}).Address(): &ripemd160hash{},
|
||||||
|
|
@ -107,7 +135,7 @@ var PrecompiledContractsCancun = precompiles.WithCustomPrecompiles(precompiles.P
|
||||||
|
|
||||||
// PrecompiledContractsPrague contains the set of pre-compiled Ethereum
|
// PrecompiledContractsPrague contains the set of pre-compiled Ethereum
|
||||||
// contracts used in the Prague release.
|
// contracts used in the Prague release.
|
||||||
var PrecompiledContractsPrague = precompiles.WithCustomPrecompiles(precompiles.PrecompiledContracts{
|
var PrecompiledContractsPrague = WithCustomPrecompiles(PrecompiledContracts{
|
||||||
(&ecrecover{}).Address(): &ecrecover{},
|
(&ecrecover{}).Address(): &ecrecover{},
|
||||||
(&sha256hash{}).Address(): &sha256hash{},
|
(&sha256hash{}).Address(): &sha256hash{},
|
||||||
(&ripemd160hash{}).Address(): &ripemd160hash{},
|
(&ripemd160hash{}).Address(): &ripemd160hash{},
|
||||||
|
|
@ -161,7 +189,7 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func activePrecompiledContracts(rules params.Rules) precompiles.PrecompiledContracts {
|
func activePrecompiledContracts(rules params.Rules) PrecompiledContracts {
|
||||||
switch {
|
switch {
|
||||||
case rules.IsVerkle:
|
case rules.IsVerkle:
|
||||||
return PrecompiledContractsVerkle
|
return PrecompiledContractsVerkle
|
||||||
|
|
@ -181,7 +209,7 @@ func activePrecompiledContracts(rules params.Rules) precompiles.PrecompiledContr
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActivePrecompiledContracts returns a copy of precompiled contracts enabled with the current configuration.
|
// ActivePrecompiledContracts returns a copy of precompiled contracts enabled with the current configuration.
|
||||||
func ActivePrecompiledContracts(rules params.Rules) precompiles.PrecompiledContracts {
|
func ActivePrecompiledContracts(rules params.Rules) PrecompiledContracts {
|
||||||
return maps.Clone(activePrecompiledContracts(rules))
|
return maps.Clone(activePrecompiledContracts(rules))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,17 +236,29 @@ func ActivePrecompiles(rules params.Rules) []common.Address {
|
||||||
// - the returned bytes,
|
// - the returned bytes,
|
||||||
// - the _remaining_ gas,
|
// - the _remaining_ gas,
|
||||||
// - any error that occurred
|
// - any error that occurred
|
||||||
func RunPrecompiledContract(p precompiles.PrecompiledContract, input []byte, suppliedGas uint64, logger *tracing.Hooks) (ret []byte, remainingGas uint64, err error) {
|
func RunPrecompiledContract(
|
||||||
|
evm *EVM,
|
||||||
|
p PrecompiledContract,
|
||||||
|
caller common.Address,
|
||||||
|
input []byte,
|
||||||
|
suppliedGas uint64,
|
||||||
|
value *uint256.Int,
|
||||||
|
readOnly bool,
|
||||||
|
logger *tracing.Hooks,
|
||||||
|
) (ret []byte, remainingGas uint64, err error) {
|
||||||
|
inputCopy := make([]byte, len(input))
|
||||||
|
copy(inputCopy, input)
|
||||||
|
|
||||||
|
contract := NewContract(caller, p.Address(), value, suppliedGas, evm.jumpDests)
|
||||||
|
contract.Input = inputCopy
|
||||||
|
|
||||||
gasCost := p.RequiredGas(input)
|
gasCost := p.RequiredGas(input)
|
||||||
if suppliedGas < gasCost {
|
if !contract.UseGas(gasCost, logger, tracing.GasChangeCallPrecompiledContract) {
|
||||||
return nil, 0, ErrOutOfGas
|
return nil, 0, ErrOutOfGas
|
||||||
}
|
}
|
||||||
if logger != nil && logger.OnGasChange != nil {
|
|
||||||
logger.OnGasChange(suppliedGas, suppliedGas-gasCost, tracing.GasChangeCallPrecompiledContract)
|
output, err := p.Run(evm, contract, readOnly)
|
||||||
}
|
return output, contract.Gas, err
|
||||||
suppliedGas -= gasCost
|
|
||||||
output, err := p.Run(input)
|
|
||||||
return output, suppliedGas, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ecrecover implemented as a native contract.
|
// ecrecover implemented as a native contract.
|
||||||
|
|
@ -234,10 +274,10 @@ func (c *ecrecover) RequiredGas(input []byte) uint64 {
|
||||||
return params.EcrecoverGas
|
return params.EcrecoverGas
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ecrecover) Run(input []byte) ([]byte, error) {
|
func (c *ecrecover) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
const ecRecoverInputLength = 128
|
const ecRecoverInputLength = 128
|
||||||
|
|
||||||
input = common.RightPadBytes(input, ecRecoverInputLength)
|
input := common.RightPadBytes(contract.Input, ecRecoverInputLength)
|
||||||
// "input" is (hash, v, r, s), each 32 bytes
|
// "input" is (hash, v, r, s), each 32 bytes
|
||||||
// but for ecrecover we want (r, s, v)
|
// but for ecrecover we want (r, s, v)
|
||||||
|
|
||||||
|
|
@ -281,8 +321,8 @@ func (*sha256hash) Address() common.Address {
|
||||||
func (c *sha256hash) RequiredGas(input []byte) uint64 {
|
func (c *sha256hash) RequiredGas(input []byte) uint64 {
|
||||||
return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas
|
return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas
|
||||||
}
|
}
|
||||||
func (c *sha256hash) Run(input []byte) ([]byte, error) {
|
func (c *sha256hash) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
h := sha256.Sum256(input)
|
h := sha256.Sum256(contract.Input)
|
||||||
return h[:], nil
|
return h[:], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -302,9 +342,9 @@ func (*ripemd160hash) Address() common.Address {
|
||||||
func (c *ripemd160hash) RequiredGas(input []byte) uint64 {
|
func (c *ripemd160hash) RequiredGas(input []byte) uint64 {
|
||||||
return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas
|
return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas
|
||||||
}
|
}
|
||||||
func (c *ripemd160hash) Run(input []byte) ([]byte, error) {
|
func (c *ripemd160hash) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
ripemd := ripemd160.New()
|
ripemd := ripemd160.New()
|
||||||
ripemd.Write(input)
|
ripemd.Write(contract.Input)
|
||||||
return common.LeftPadBytes(ripemd.Sum(nil), 32), nil
|
return common.LeftPadBytes(ripemd.Sum(nil), 32), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -324,8 +364,8 @@ func (*dataCopy) Address() common.Address {
|
||||||
func (c *dataCopy) RequiredGas(input []byte) uint64 {
|
func (c *dataCopy) RequiredGas(input []byte) uint64 {
|
||||||
return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas
|
return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas
|
||||||
}
|
}
|
||||||
func (c *dataCopy) Run(in []byte) ([]byte, error) {
|
func (c *dataCopy) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
return common.CopyBytes(in), nil
|
return common.CopyBytes(contract.Input), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// bigModExp implements a native big integer exponential modular operation.
|
// bigModExp implements a native big integer exponential modular operation.
|
||||||
|
|
@ -461,7 +501,8 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
|
||||||
return gas.Uint64()
|
return gas.Uint64()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bigModExp) Run(input []byte) ([]byte, error) {
|
func (c *bigModExp) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
|
input := contract.Input
|
||||||
var (
|
var (
|
||||||
baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64()
|
baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64()
|
||||||
expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64()
|
expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64()
|
||||||
|
|
@ -547,8 +588,8 @@ func (c *bn256AddIstanbul) RequiredGas(input []byte) uint64 {
|
||||||
return params.Bn256AddGasIstanbul
|
return params.Bn256AddGasIstanbul
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bn256AddIstanbul) Run(input []byte) ([]byte, error) {
|
func (c *bn256AddIstanbul) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
return runBn256Add(input)
|
return runBn256Add(contract.Input)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bn256AddByzantium implements a native elliptic curve point addition
|
// bn256AddByzantium implements a native elliptic curve point addition
|
||||||
|
|
@ -566,8 +607,8 @@ func (c *bn256AddByzantium) RequiredGas(input []byte) uint64 {
|
||||||
return params.Bn256AddGasByzantium
|
return params.Bn256AddGasByzantium
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bn256AddByzantium) Run(input []byte) ([]byte, error) {
|
func (c *bn256AddByzantium) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
return runBn256Add(input)
|
return runBn256Add(contract.Input)
|
||||||
}
|
}
|
||||||
|
|
||||||
// runBn256ScalarMul implements the Bn256ScalarMul precompile, referenced by
|
// runBn256ScalarMul implements the Bn256ScalarMul precompile, referenced by
|
||||||
|
|
@ -597,8 +638,8 @@ func (c *bn256ScalarMulIstanbul) RequiredGas(input []byte) uint64 {
|
||||||
return params.Bn256ScalarMulGasIstanbul
|
return params.Bn256ScalarMulGasIstanbul
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bn256ScalarMulIstanbul) Run(input []byte) ([]byte, error) {
|
func (c *bn256ScalarMulIstanbul) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
return runBn256ScalarMul(input)
|
return runBn256ScalarMul(contract.Input)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bn256ScalarMulByzantium implements a native elliptic curve scalar
|
// bn256ScalarMulByzantium implements a native elliptic curve scalar
|
||||||
|
|
@ -616,8 +657,8 @@ func (c *bn256ScalarMulByzantium) RequiredGas(input []byte) uint64 {
|
||||||
return params.Bn256ScalarMulGasByzantium
|
return params.Bn256ScalarMulGasByzantium
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bn256ScalarMulByzantium) Run(input []byte) ([]byte, error) {
|
func (c *bn256ScalarMulByzantium) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
return runBn256ScalarMul(input)
|
return runBn256ScalarMul(contract.Input)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -677,8 +718,8 @@ func (c *bn256PairingIstanbul) RequiredGas(input []byte) uint64 {
|
||||||
return params.Bn256PairingBaseGasIstanbul + uint64(len(input)/192)*params.Bn256PairingPerPointGasIstanbul
|
return params.Bn256PairingBaseGasIstanbul + uint64(len(input)/192)*params.Bn256PairingPerPointGasIstanbul
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bn256PairingIstanbul) Run(input []byte) ([]byte, error) {
|
func (c *bn256PairingIstanbul) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
return runBn256Pairing(input)
|
return runBn256Pairing(contract.Input)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bn256PairingByzantium implements a pairing pre-compile for the bn256 curve
|
// bn256PairingByzantium implements a pairing pre-compile for the bn256 curve
|
||||||
|
|
@ -696,8 +737,8 @@ func (c *bn256PairingByzantium) RequiredGas(input []byte) uint64 {
|
||||||
return params.Bn256PairingBaseGasByzantium + uint64(len(input)/192)*params.Bn256PairingPerPointGasByzantium
|
return params.Bn256PairingBaseGasByzantium + uint64(len(input)/192)*params.Bn256PairingPerPointGasByzantium
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bn256PairingByzantium) Run(input []byte) ([]byte, error) {
|
func (c *bn256PairingByzantium) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
return runBn256Pairing(input)
|
return runBn256Pairing(contract.Input)
|
||||||
}
|
}
|
||||||
|
|
||||||
type blake2F struct{}
|
type blake2F struct{}
|
||||||
|
|
@ -728,7 +769,8 @@ var (
|
||||||
errBlake2FInvalidFinalFlag = errors.New("invalid final flag")
|
errBlake2FInvalidFinalFlag = errors.New("invalid final flag")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *blake2F) Run(input []byte) ([]byte, error) {
|
func (c *blake2F) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
|
input := contract.Input
|
||||||
// Make sure the input is valid (correct length and final flag)
|
// Make sure the input is valid (correct length and final flag)
|
||||||
if len(input) != blake2FInputLength {
|
if len(input) != blake2FInputLength {
|
||||||
return nil, errBlake2FInvalidInputLength
|
return nil, errBlake2FInvalidInputLength
|
||||||
|
|
@ -788,7 +830,8 @@ func (c *bls12381G1Add) RequiredGas(input []byte) uint64 {
|
||||||
return params.Bls12381G1AddGas
|
return params.Bls12381G1AddGas
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bls12381G1Add) Run(input []byte) ([]byte, error) {
|
func (c *bls12381G1Add) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
|
input := contract.Input
|
||||||
// Implements EIP-2537 G1Add precompile.
|
// Implements EIP-2537 G1Add precompile.
|
||||||
// > G1 addition call expects `256` bytes as an input that is interpreted as byte concatenation of two G1 points (`128` bytes each).
|
// > G1 addition call expects `256` bytes as an input that is interpreted as byte concatenation of two G1 points (`128` bytes each).
|
||||||
// > Output is an encoding of addition operation result - single G1 point (`128` bytes).
|
// > Output is an encoding of addition operation result - single G1 point (`128` bytes).
|
||||||
|
|
@ -844,7 +887,8 @@ func (c *bls12381G1MultiExp) RequiredGas(input []byte) uint64 {
|
||||||
return (uint64(k) * params.Bls12381G1MulGas * discount) / 1000
|
return (uint64(k) * params.Bls12381G1MulGas * discount) / 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bls12381G1MultiExp) Run(input []byte) ([]byte, error) {
|
func (c *bls12381G1MultiExp) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
|
input := contract.Input
|
||||||
// Implements EIP-2537 G1MultiExp precompile.
|
// 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).
|
// 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).
|
// Output is an encoding of multiexponentiation operation result - single G1 point (`128` bytes).
|
||||||
|
|
@ -896,7 +940,8 @@ func (c *bls12381G2Add) RequiredGas(input []byte) uint64 {
|
||||||
return params.Bls12381G2AddGas
|
return params.Bls12381G2AddGas
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bls12381G2Add) Run(input []byte) ([]byte, error) {
|
func (c *bls12381G2Add) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
|
input := contract.Input
|
||||||
// Implements EIP-2537 G2Add precompile.
|
// Implements EIP-2537 G2Add precompile.
|
||||||
// > G2 addition call expects `512` bytes as an input that is interpreted as byte concatenation of two G2 points (`256` bytes each).
|
// > G2 addition call expects `512` bytes as an input that is interpreted as byte concatenation of two G2 points (`256` bytes each).
|
||||||
// > Output is an encoding of addition operation result - single G2 point (`256` bytes).
|
// > Output is an encoding of addition operation result - single G2 point (`256` bytes).
|
||||||
|
|
@ -953,7 +998,8 @@ func (c *bls12381G2MultiExp) RequiredGas(input []byte) uint64 {
|
||||||
return (uint64(k) * params.Bls12381G2MulGas * discount) / 1000
|
return (uint64(k) * params.Bls12381G2MulGas * discount) / 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bls12381G2MultiExp) Run(input []byte) ([]byte, error) {
|
func (c *bls12381G2MultiExp) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
|
input := contract.Input
|
||||||
// Implements EIP-2537 G2MultiExp precompile logic
|
// 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).
|
// > 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).
|
// > Output is an encoding of multiexponentiation operation result - single G2 point (`256` bytes).
|
||||||
|
|
@ -1005,7 +1051,8 @@ func (c *bls12381Pairing) RequiredGas(input []byte) uint64 {
|
||||||
return params.Bls12381PairingBaseGas + uint64(len(input)/384)*params.Bls12381PairingPerPairGas
|
return params.Bls12381PairingBaseGas + uint64(len(input)/384)*params.Bls12381PairingPerPairGas
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bls12381Pairing) Run(input []byte) ([]byte, error) {
|
func (c *bls12381Pairing) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
|
input := contract.Input
|
||||||
// Implements EIP-2537 Pairing precompile logic.
|
// 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:
|
// > 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
|
// > - `128` bytes of G1 point encoding
|
||||||
|
|
@ -1163,7 +1210,8 @@ func (c *bls12381MapG1) RequiredGas(input []byte) uint64 {
|
||||||
return params.Bls12381MapG1Gas
|
return params.Bls12381MapG1Gas
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bls12381MapG1) Run(input []byte) ([]byte, error) {
|
func (c *bls12381MapG1) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
|
input := contract.Input
|
||||||
// Implements EIP-2537 Map_To_G1 precompile.
|
// Implements EIP-2537 Map_To_G1 precompile.
|
||||||
// > Field-to-curve call expects an `64` bytes input that is interpreted as an element of the base field.
|
// > Field-to-curve call expects an `64` bytes input that is interpreted as an element of the base field.
|
||||||
// > Output of this call is `128` bytes and is G1 point following respective encoding rules.
|
// > Output of this call is `128` bytes and is G1 point following respective encoding rules.
|
||||||
|
|
@ -1198,7 +1246,8 @@ func (c *bls12381MapG2) RequiredGas(input []byte) uint64 {
|
||||||
return params.Bls12381MapG2Gas
|
return params.Bls12381MapG2Gas
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *bls12381MapG2) Run(input []byte) ([]byte, error) {
|
func (c *bls12381MapG2) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
|
input := contract.Input
|
||||||
// Implements EIP-2537 Map_FP2_TO_G2 precompile logic.
|
// Implements EIP-2537 Map_FP2_TO_G2 precompile logic.
|
||||||
// > Field-to-curve call expects an `128` bytes input that is interpreted as an element of the quadratic extension field.
|
// > Field-to-curve call expects an `128` bytes input that is interpreted as an element of the quadratic extension field.
|
||||||
// > Output of this call is `256` bytes and is G2 point following respective encoding rules.
|
// > Output of this call is `256` bytes and is G2 point following respective encoding rules.
|
||||||
|
|
@ -1250,7 +1299,8 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Run executes the point evaluation precompile.
|
// Run executes the point evaluation precompile.
|
||||||
func (b *kzgPointEvaluation) Run(input []byte) ([]byte, error) {
|
func (b *kzgPointEvaluation) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
|
||||||
|
input := contract.Input
|
||||||
if len(input) != blobVerifyInputLength {
|
if len(input) != blobVerifyInputLength {
|
||||||
return nil, errBlobVerifyInvalidInputLength
|
return nil, errBlobVerifyInvalidInputLength
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FuzzPrecompiledContracts(f *testing.F) {
|
func FuzzPrecompiledContracts(f *testing.F) {
|
||||||
|
|
@ -36,7 +37,7 @@ func FuzzPrecompiledContracts(f *testing.F) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
inWant := string(input)
|
inWant := string(input)
|
||||||
RunPrecompiledContract(p, input, gas, nil)
|
RunPrecompiledContract(nil, p, common.Address{}, input, gas, uint256.NewInt(0), false, nil)
|
||||||
if inHave := string(input); inWant != inHave {
|
if inHave := string(input); inWant != inHave {
|
||||||
t.Errorf("Precompiled %v modified input data", a)
|
t.Errorf("Precompiled %v modified input data", a)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/vm/precompiles"
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
// precompiledTest defines the input/output pairs for precompiled contract tests.
|
// precompiledTest defines the input/output pairs for precompiled contract tests.
|
||||||
|
|
@ -46,7 +46,7 @@ type precompiledFailureTest struct {
|
||||||
|
|
||||||
// allPrecompiles does not map to the actual set of precompiles, as it also contains
|
// allPrecompiles does not map to the actual set of precompiles, as it also contains
|
||||||
// repriced versions of precompiles at certain slots
|
// repriced versions of precompiles at certain slots
|
||||||
var allPrecompiles = map[common.Address]precompiles.PrecompiledContract{
|
var allPrecompiles = map[common.Address]PrecompiledContract{
|
||||||
common.BytesToAddress([]byte{1}): &ecrecover{},
|
common.BytesToAddress([]byte{1}): &ecrecover{},
|
||||||
common.BytesToAddress([]byte{2}): &sha256hash{},
|
common.BytesToAddress([]byte{2}): &sha256hash{},
|
||||||
common.BytesToAddress([]byte{3}): &ripemd160hash{},
|
common.BytesToAddress([]byte{3}): &ripemd160hash{},
|
||||||
|
|
@ -97,7 +97,7 @@ func testPrecompiled(addr string, test precompiledTest, t *testing.T) {
|
||||||
in := common.Hex2Bytes(test.Input)
|
in := common.Hex2Bytes(test.Input)
|
||||||
gas := p.RequiredGas(in)
|
gas := p.RequiredGas(in)
|
||||||
t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) {
|
||||||
if res, _, err := RunPrecompiledContract(p, in, gas, nil); err != nil {
|
if res, _, err := RunPrecompiledContract(nil, p, common.Address{}, in, gas, uint256.NewInt(0), false, nil); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
} else if common.Bytes2Hex(res) != test.Expected {
|
} else if common.Bytes2Hex(res) != test.Expected {
|
||||||
t.Errorf("Expected %v, got %v", test.Expected, common.Bytes2Hex(res))
|
t.Errorf("Expected %v, got %v", test.Expected, common.Bytes2Hex(res))
|
||||||
|
|
@ -119,7 +119,7 @@ func testPrecompiledOOG(addr string, test precompiledTest, t *testing.T) {
|
||||||
gas := p.RequiredGas(in) - 1
|
gas := p.RequiredGas(in) - 1
|
||||||
|
|
||||||
t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) {
|
||||||
_, _, err := RunPrecompiledContract(p, in, gas, nil)
|
_, _, err := RunPrecompiledContract(nil, p, common.Address{}, in, gas, uint256.NewInt(0), false, nil)
|
||||||
if err.Error() != "out of gas" {
|
if err.Error() != "out of gas" {
|
||||||
t.Errorf("Expected error [out of gas], got [%v]", err)
|
t.Errorf("Expected error [out of gas], got [%v]", err)
|
||||||
}
|
}
|
||||||
|
|
@ -136,7 +136,7 @@ func testPrecompiledFailure(addr string, test precompiledFailureTest, t *testing
|
||||||
in := common.Hex2Bytes(test.Input)
|
in := common.Hex2Bytes(test.Input)
|
||||||
gas := p.RequiredGas(in)
|
gas := p.RequiredGas(in)
|
||||||
t.Run(test.Name, func(t *testing.T) {
|
t.Run(test.Name, func(t *testing.T) {
|
||||||
_, _, err := RunPrecompiledContract(p, in, gas, nil)
|
_, _, err := RunPrecompiledContract(nil, p, common.Address{}, in, gas, uint256.NewInt(0), false, nil)
|
||||||
if err.Error() != test.ExpectedError {
|
if err.Error() != test.ExpectedError {
|
||||||
t.Errorf("Expected error [%v], got [%v]", test.ExpectedError, err)
|
t.Errorf("Expected error [%v], got [%v]", test.ExpectedError, err)
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +168,7 @@ func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) {
|
||||||
bench.ResetTimer()
|
bench.ResetTimer()
|
||||||
for i := 0; i < bench.N; i++ {
|
for i := 0; i < bench.N; i++ {
|
||||||
copy(data, in)
|
copy(data, in)
|
||||||
res, _, err = RunPrecompiledContract(p, data, reqGas, nil)
|
res, _, err = RunPrecompiledContract(nil, p, common.Address{}, data, reqGas, uint256.NewInt(0), false, nil)
|
||||||
}
|
}
|
||||||
bench.StopTimer()
|
bench.StopTimer()
|
||||||
elapsed := uint64(time.Since(start))
|
elapsed := uint64(time.Since(start))
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm/precompiles"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
|
|
@ -41,7 +40,7 @@ type (
|
||||||
GetHashFunc func(uint64) common.Hash
|
GetHashFunc func(uint64) common.Hash
|
||||||
)
|
)
|
||||||
|
|
||||||
func (evm *EVM) precompile(addr common.Address) (precompiles.PrecompiledContract, bool) {
|
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
|
||||||
p, ok := evm.precompiles[addr]
|
p, ok := evm.precompiles[addr]
|
||||||
return p, ok
|
return p, ok
|
||||||
}
|
}
|
||||||
|
|
@ -121,7 +120,7 @@ type EVM struct {
|
||||||
callGasTemp uint64
|
callGasTemp uint64
|
||||||
|
|
||||||
// precompiles holds the precompiled contracts for the current epoch
|
// precompiles holds the precompiled contracts for the current epoch
|
||||||
precompiles map[common.Address]precompiles.PrecompiledContract
|
precompiles map[common.Address]PrecompiledContract
|
||||||
|
|
||||||
// jumpDests is the aggregated result of JUMPDEST analysis made through
|
// jumpDests is the aggregated result of JUMPDEST analysis made through
|
||||||
// the life cycle of EVM.
|
// the life cycle of EVM.
|
||||||
|
|
@ -149,7 +148,7 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon
|
||||||
// SetPrecompiles sets the precompiled contracts for the EVM.
|
// SetPrecompiles sets the precompiled contracts for the EVM.
|
||||||
// This method is only used through RPC calls.
|
// This method is only used through RPC calls.
|
||||||
// It is not thread-safe.
|
// It is not thread-safe.
|
||||||
func (evm *EVM) SetPrecompiles(precompiles precompiles.PrecompiledContracts) {
|
func (evm *EVM) SetPrecompiles(precompiles PrecompiledContracts) {
|
||||||
evm.precompiles = precompiles
|
evm.precompiles = precompiles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,7 +224,7 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
|
||||||
evm.Context.Transfer(evm.StateDB, caller, addr, value)
|
evm.Context.Transfer(evm.StateDB, caller, addr, value)
|
||||||
|
|
||||||
if isPrecompile {
|
if isPrecompile {
|
||||||
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
|
ret, gas, err = RunPrecompiledContract(evm, p, caller, input, gas, value, false, evm.Config.Tracer)
|
||||||
} else {
|
} else {
|
||||||
// Initialise a new contract and set the code that is to be used by the EVM.
|
// Initialise a new contract and set the code that is to be used by the EVM.
|
||||||
code := evm.resolveCode(addr)
|
code := evm.resolveCode(addr)
|
||||||
|
|
@ -289,7 +288,7 @@ func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byt
|
||||||
|
|
||||||
// It is allowed to call precompiles, even via delegatecall
|
// It is allowed to call precompiles, even via delegatecall
|
||||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
||||||
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
|
ret, gas, err = RunPrecompiledContract(evm, p, caller, input, gas, value, true, evm.Config.Tracer)
|
||||||
} else {
|
} else {
|
||||||
// Initialise a new contract and set the code that is to be used by the EVM.
|
// Initialise a new contract and set the code that is to be used by the EVM.
|
||||||
// The contract is a scoped environment for this execution context only.
|
// The contract is a scoped environment for this execution context only.
|
||||||
|
|
@ -332,7 +331,7 @@ func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address,
|
||||||
|
|
||||||
// It is allowed to call precompiles, even via delegatecall
|
// It is allowed to call precompiles, even via delegatecall
|
||||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
||||||
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
|
ret, gas, err = RunPrecompiledContract(evm, p, caller, input, gas, value, true, evm.Config.Tracer)
|
||||||
} else {
|
} else {
|
||||||
// Initialise a new contract and make initialise the delegate values
|
// Initialise a new contract and make initialise the delegate values
|
||||||
//
|
//
|
||||||
|
|
@ -384,7 +383,7 @@ func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []b
|
||||||
evm.StateDB.AddBalance(addr, new(uint256.Int), tracing.BalanceChangeTouchAccount)
|
evm.StateDB.AddBalance(addr, new(uint256.Int), tracing.BalanceChangeTouchAccount)
|
||||||
|
|
||||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
||||||
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
|
ret, gas, err = RunPrecompiledContract(evm, p, caller, input, gas, new(uint256.Int), true, evm.Config.Tracer)
|
||||||
} else {
|
} else {
|
||||||
// Initialise a new contract and set the code that is to be used by the EVM.
|
// Initialise a new contract and set the code that is to be used by the EVM.
|
||||||
// The contract is a scoped environment for this execution context only.
|
// The contract is a scoped environment for this execution context only.
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
package precompiles
|
|
||||||
|
|
||||||
import (
|
|
||||||
"maps"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PrecompiledContract is the basic interface for native Go contracts. The implementation
|
|
||||||
// requires a deterministic gas count based on the input size of the Run method of the
|
|
||||||
// contract.
|
|
||||||
type PrecompiledContract interface {
|
|
||||||
Address() common.Address
|
|
||||||
RequiredGas(input []byte) uint64 // RequiredPrice calculates the contract gas use
|
|
||||||
Run(input []byte) ([]byte, error) // Run runs the precompiled contract
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrecompiledContracts contains the precompiled contracts supported at the given fork.
|
|
||||||
type PrecompiledContracts map[common.Address]PrecompiledContract
|
|
||||||
|
|
||||||
var CustomPrecompiledContracts = PrecompiledContracts{}
|
|
||||||
|
|
||||||
// WithCustomPrecompiles merge given precompiles with custom precompiles
|
|
||||||
func WithCustomPrecompiles(base PrecompiledContracts) PrecompiledContracts {
|
|
||||||
result := make(PrecompiledContracts)
|
|
||||||
maps.Copy(result, base)
|
|
||||||
for k, v := range CustomPrecompiledContracts {
|
|
||||||
if _, exists := result[k]; !exists {
|
|
||||||
result[k] = v
|
|
||||||
} else {
|
|
||||||
panic("Precompile address collision")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
@ -37,7 +37,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/core/vm/precompiles"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth/gasestimator"
|
"github.com/ethereum/go-ethereum/eth/gasestimator"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||||
|
|
@ -689,7 +688,7 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.S
|
||||||
return applyMessage(ctx, b, args, state, header, timeout, gp, &blockCtx, &vm.Config{NoBaseFee: true}, precompiles, true)
|
return applyMessage(ctx, b, args, state, header, timeout, gp, &blockCtx, &vm.Config{NoBaseFee: true}, precompiles, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyMessage(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, timeout time.Duration, gp *core.GasPool, blockContext *vm.BlockContext, vmConfig *vm.Config, precompiles precompiles.PrecompiledContracts, skipChecks bool) (*core.ExecutionResult, error) {
|
func applyMessage(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, timeout time.Duration, gp *core.GasPool, blockContext *vm.BlockContext, vmConfig *vm.Config, precompiles vm.PrecompiledContracts, skipChecks bool) (*core.ExecutionResult, error) {
|
||||||
// Get a new instance of the EVM.
|
// Get a new instance of the EVM.
|
||||||
if err := args.CallDefaults(gp.Gas(), blockContext.BaseFee, b.ChainConfig().ChainID); err != nil {
|
if err := args.CallDefaults(gp.Gas(), blockContext.BaseFee, b.ChainConfig().ChainID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/core/vm/precompiles"
|
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -54,7 +53,7 @@ func (diff *StateOverride) has(address common.Address) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply overrides the fields of specified accounts into the given state.
|
// Apply overrides the fields of specified accounts into the given state.
|
||||||
func (diff *StateOverride) Apply(statedb *state.StateDB, precompiles precompiles.PrecompiledContracts) error {
|
func (diff *StateOverride) Apply(statedb *state.StateDB, precompiles vm.PrecompiledContracts) error {
|
||||||
if diff == nil {
|
if diff == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm/precompiles"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/triedb"
|
"github.com/ethereum/go-ethereum/triedb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -37,7 +37,9 @@ func (precompileContract) Address() common.Address {
|
||||||
|
|
||||||
func (p *precompileContract) RequiredGas(input []byte) uint64 { return 0 }
|
func (p *precompileContract) RequiredGas(input []byte) uint64 { return 0 }
|
||||||
|
|
||||||
func (p *precompileContract) Run(input []byte) ([]byte, error) { return nil, nil }
|
func (p *precompileContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([]byte, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
func TestStateOverrideMovePrecompile(t *testing.T) {
|
func TestStateOverrideMovePrecompile(t *testing.T) {
|
||||||
db := state.NewDatabase(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)
|
db := state.NewDatabase(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)
|
||||||
|
|
@ -45,7 +47,7 @@ func TestStateOverrideMovePrecompile(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create statedb: %v", err)
|
t.Fatalf("failed to create statedb: %v", err)
|
||||||
}
|
}
|
||||||
precompiles := map[common.Address]precompiles.PrecompiledContract{
|
precompiles := map[common.Address]vm.PrecompiledContract{
|
||||||
common.BytesToAddress([]byte{0x1}): &precompileContract{},
|
common.BytesToAddress([]byte{0x1}): &precompileContract{},
|
||||||
common.BytesToAddress([]byte{0x2}): &precompileContract{},
|
common.BytesToAddress([]byte{0x2}): &precompileContract{},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/core/vm/precompiles"
|
|
||||||
"github.com/ethereum/go-ethereum/internal/ethapi/override"
|
"github.com/ethereum/go-ethereum/internal/ethapi/override"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
|
@ -316,7 +315,7 @@ func (sim *simulator) sanitizeCall(call *TransactionArgs, state vm.StateDB, head
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sim *simulator) activePrecompiles(base *types.Header) precompiles.PrecompiledContracts {
|
func (sim *simulator) activePrecompiles(base *types.Header) vm.PrecompiledContracts {
|
||||||
var (
|
var (
|
||||||
isMerge = (base.Difficulty.Sign() == 0)
|
isMerge = (base.Difficulty.Sign() == 0)
|
||||||
rules = sim.chainConfig.Rules(base.Number, isMerge, base.Time)
|
rules = sim.chainConfig.Rules(base.Number, isMerge, base.Time)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue