persist precompiles in evm

This commit is contained in:
Sina Mahmoodi 2023-07-17 16:01:52 +02:00
parent b865824787
commit da3102e5ae
2 changed files with 34 additions and 23 deletions

View file

@ -40,9 +40,12 @@ type PrecompiledContract interface {
Run(input []byte) ([]byte, error) // Run runs the precompiled contract
}
// PrecompiledContractByName contains the precompiled contracts supported at the given fork.
type PrecompiledContracts map[common.Address]PrecompiledContract
// PrecompiledContractsHomestead contains the default set of pre-compiled Ethereum
// contracts used in the Frontier and Homestead releases.
var PrecompiledContractsHomestead = map[common.Address]PrecompiledContract{
var PrecompiledContractsHomestead = PrecompiledContracts{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
@ -51,7 +54,7 @@ var PrecompiledContractsHomestead = map[common.Address]PrecompiledContract{
// PrecompiledContractsByzantium contains the default set of pre-compiled Ethereum
// contracts used in the Byzantium release.
var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
var PrecompiledContractsByzantium = PrecompiledContracts{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
@ -64,7 +67,7 @@ var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
// PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum
// contracts used in the Istanbul release.
var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{
var PrecompiledContractsIstanbul = PrecompiledContracts{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
@ -78,7 +81,7 @@ var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{
// PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum
// contracts used in the Berlin release.
var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{
var PrecompiledContractsBerlin = PrecompiledContracts{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
@ -92,7 +95,7 @@ var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
// contracts specified in EIP-2537. These are exported for testing purposes.
var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
var PrecompiledContractsBLS = PrecompiledContracts{
common.BytesToAddress([]byte{10}): &bls12381G1Add{},
common.BytesToAddress([]byte{11}): &bls12381G1Mul{},
common.BytesToAddress([]byte{12}): &bls12381G1MultiExp{},
@ -126,6 +129,15 @@ func init() {
}
}
// Copy returns a copy of the precompiled contracts.
func (p PrecompiledContracts) Copy() PrecompiledContracts {
c := make(PrecompiledContracts)
for k, v := range p {
c[k] = v
}
return c
}
// ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules params.Rules) []common.Address {
switch {

View file

@ -41,24 +41,7 @@ type (
)
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
var precompiles map[common.Address]PrecompiledContract
switch {
case evm.chainRules.IsBerlin:
precompiles = PrecompiledContractsBerlin
case evm.chainRules.IsIstanbul:
precompiles = PrecompiledContractsIstanbul
case evm.chainRules.IsByzantium:
precompiles = PrecompiledContractsByzantium
default:
precompiles = PrecompiledContractsHomestead
}
// ECRecoverCode can be set only through RPC calls
if evm.Config.DisableECRecover {
if addr == common.BytesToAddress([]byte{1}) {
return nil, false
}
}
p, ok := precompiles[addr]
p, ok := evm.precompiles[addr]
return p, ok
}
@ -125,6 +108,8 @@ type EVM struct {
// available gas is calculated in gasCall* according to the 63/64 rule and later
// applied in opCall*.
callGasTemp uint64
// precompiles holds the precompiled contracts for the current epoch
precompiles map[common.Address]PrecompiledContract
}
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
@ -138,6 +123,20 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig
chainConfig: chainConfig,
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time),
}
switch {
case evm.chainRules.IsBerlin:
evm.precompiles = PrecompiledContractsBerlin.Copy()
case evm.chainRules.IsIstanbul:
evm.precompiles = PrecompiledContractsIstanbul.Copy()
case evm.chainRules.IsByzantium:
evm.precompiles = PrecompiledContractsByzantium.Copy()
default:
evm.precompiles = PrecompiledContractsHomestead.Copy()
}
// ECRecoverCode can be set only through RPC calls
if config.DisableECRecover {
delete(evm.precompiles, common.BytesToAddress([]byte{1}))
}
evm.interpreter = NewEVMInterpreter(evm)
return evm
}