mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
make Precompile injectable into block context
This commit is contained in:
parent
cca94792a4
commit
fbea4aab3e
1 changed files with 36 additions and 20 deletions
|
|
@ -35,24 +35,30 @@ type (
|
||||||
// GetHashFunc returns the n'th block hash in the blockchain
|
// GetHashFunc returns the n'th block hash in the blockchain
|
||||||
// and is used by the BLOCKHASH EVM op code.
|
// and is used by the BLOCKHASH EVM op code.
|
||||||
GetHashFunc func(uint64) common.Hash
|
GetHashFunc func(uint64) common.Hash
|
||||||
|
// HasPrecompileFunc checks if an address has a precompile contract associated with it.
|
||||||
|
// if yes, it returns the precompiled contract and a boolean
|
||||||
|
HasPrecompileFunc func(addr common.Address) (PrecompiledContract, bool)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
|
// getDefaultPrecompileFunc returns the default precompile function
|
||||||
var precompiles map[common.Address]PrecompiledContract
|
func getDefaultPrecompileFunc(chainRules params.Rules) HasPrecompileFunc {
|
||||||
switch {
|
return func(addr common.Address) (PrecompiledContract, bool) {
|
||||||
case evm.chainRules.IsCancun:
|
var precompiles map[common.Address]PrecompiledContract
|
||||||
precompiles = PrecompiledContractsCancun
|
switch {
|
||||||
case evm.chainRules.IsBerlin:
|
case chainRules.IsCancun:
|
||||||
precompiles = PrecompiledContractsBerlin
|
precompiles = PrecompiledContractsCancun
|
||||||
case evm.chainRules.IsIstanbul:
|
case chainRules.IsBerlin:
|
||||||
precompiles = PrecompiledContractsIstanbul
|
precompiles = PrecompiledContractsBerlin
|
||||||
case evm.chainRules.IsByzantium:
|
case chainRules.IsIstanbul:
|
||||||
precompiles = PrecompiledContractsByzantium
|
precompiles = PrecompiledContractsIstanbul
|
||||||
default:
|
case chainRules.IsByzantium:
|
||||||
precompiles = PrecompiledContractsHomestead
|
precompiles = PrecompiledContractsByzantium
|
||||||
|
default:
|
||||||
|
precompiles = PrecompiledContractsHomestead
|
||||||
|
}
|
||||||
|
p, ok := precompiles[addr]
|
||||||
|
return p, ok
|
||||||
}
|
}
|
||||||
p, ok := precompiles[addr]
|
|
||||||
return p, ok
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockContext provides the EVM with auxiliary information. Once provided
|
// BlockContext provides the EVM with auxiliary information. Once provided
|
||||||
|
|
@ -65,6 +71,8 @@ type BlockContext struct {
|
||||||
Transfer TransferFunc
|
Transfer TransferFunc
|
||||||
// GetHash returns the hash corresponding to n
|
// GetHash returns the hash corresponding to n
|
||||||
GetHash GetHashFunc
|
GetHash GetHashFunc
|
||||||
|
// HasPrecompile returns the precompile for an address
|
||||||
|
HasPrecompile HasPrecompileFunc
|
||||||
|
|
||||||
// Block information
|
// Block information
|
||||||
Coinbase common.Address // Provides information for COINBASE
|
Coinbase common.Address // Provides information for COINBASE
|
||||||
|
|
@ -137,15 +145,23 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig
|
||||||
blockCtx.BlobBaseFee = new(big.Int)
|
blockCtx.BlobBaseFee = new(big.Int)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
chainRules := chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time)
|
||||||
|
|
||||||
|
// set default precompile if is not set
|
||||||
|
if blockCtx.HasPrecompile == nil {
|
||||||
|
blockCtx.HasPrecompile = getDefaultPrecompileFunc(chainRules)
|
||||||
|
}
|
||||||
|
|
||||||
evm := &EVM{
|
evm := &EVM{
|
||||||
Context: blockCtx,
|
Context: blockCtx,
|
||||||
TxContext: txCtx,
|
TxContext: txCtx,
|
||||||
StateDB: statedb,
|
StateDB: statedb,
|
||||||
Config: config,
|
Config: config,
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time),
|
chainRules: chainRules,
|
||||||
}
|
}
|
||||||
evm.interpreter = NewEVMInterpreter(evm)
|
evm.interpreter = NewEVMInterpreter(evm)
|
||||||
|
|
||||||
return evm
|
return evm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,7 +202,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
return nil, gas, ErrInsufficientBalance
|
return nil, gas, ErrInsufficientBalance
|
||||||
}
|
}
|
||||||
snapshot := evm.StateDB.Snapshot()
|
snapshot := evm.StateDB.Snapshot()
|
||||||
p, isPrecompile := evm.precompile(addr)
|
p, isPrecompile := evm.Context.HasPrecompile(addr)
|
||||||
debug := evm.Config.Tracer != nil
|
debug := evm.Config.Tracer != nil
|
||||||
|
|
||||||
if !evm.StateDB.Exist(addr) {
|
if !evm.StateDB.Exist(addr) {
|
||||||
|
|
@ -286,7 +302,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.Context.HasPrecompile(addr); isPrecompile {
|
||||||
ret, gas, err = RunPrecompiledContract(p, input, gas)
|
ret, gas, err = RunPrecompiledContract(p, input, gas)
|
||||||
} else {
|
} else {
|
||||||
addrCopy := addr
|
addrCopy := addr
|
||||||
|
|
@ -331,7 +347,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.Context.HasPrecompile(addr); isPrecompile {
|
||||||
ret, gas, err = RunPrecompiledContract(p, input, gas)
|
ret, gas, err = RunPrecompiledContract(p, input, gas)
|
||||||
} else {
|
} else {
|
||||||
addrCopy := addr
|
addrCopy := addr
|
||||||
|
|
@ -380,7 +396,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
|
||||||
}(gas)
|
}(gas)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
if p, isPrecompile := evm.Context.HasPrecompile(addr); isPrecompile {
|
||||||
ret, gas, err = RunPrecompiledContract(p, input, gas)
|
ret, gas, err = RunPrecompiledContract(p, input, gas)
|
||||||
} else {
|
} else {
|
||||||
// At this point, we use a copy of address. If we don't, the go compiler will
|
// At this point, we use a copy of address. If we don't, the go compiler will
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue