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 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 // 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 = map[common.Address]PrecompiledContract{ var PrecompiledContractsHomestead = PrecompiledContracts{
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{},
@ -51,7 +54,7 @@ var PrecompiledContractsHomestead = map[common.Address]PrecompiledContract{
// 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 = map[common.Address]PrecompiledContract{ var PrecompiledContractsByzantium = PrecompiledContracts{
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{},
@ -64,7 +67,7 @@ var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
// 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 = map[common.Address]PrecompiledContract{ var PrecompiledContractsIstanbul = PrecompiledContracts{
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{},
@ -78,7 +81,7 @@ var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{
// 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 = map[common.Address]PrecompiledContract{ var PrecompiledContractsBerlin = PrecompiledContracts{
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{},
@ -92,7 +95,7 @@ var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum // PrecompiledContractsBLS contains the set of pre-compiled Ethereum
// contracts specified in EIP-2537. These are exported for testing purposes. // 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{10}): &bls12381G1Add{},
common.BytesToAddress([]byte{11}): &bls12381G1Mul{}, common.BytesToAddress([]byte{11}): &bls12381G1Mul{},
common.BytesToAddress([]byte{12}): &bls12381G1MultiExp{}, 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. // ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules params.Rules) []common.Address { func ActivePrecompiles(rules params.Rules) []common.Address {
switch { switch {

View file

@ -41,24 +41,7 @@ type (
) )
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
var precompiles map[common.Address]PrecompiledContract p, ok := evm.precompiles[addr]
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]
return p, ok return p, ok
} }
@ -125,6 +108,8 @@ type EVM struct {
// available gas is calculated in gasCall* according to the 63/64 rule and later // available gas is calculated in gasCall* according to the 63/64 rule and later
// applied in opCall*. // applied in opCall*.
callGasTemp uint64 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 // 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, chainConfig: chainConfig,
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time), 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) evm.interpreter = NewEVMInterpreter(evm)
return evm return evm
} }