Skip to content

Commit

Permalink
core/state: add hook to precompiled contract and create (#382)
Browse files Browse the repository at this point in the history
* core/state: add evm hooks for precompile and create

These hooks are added to help resolve some issues on testnet.

* core/blockchain: add evm hook to blockchain object
  • Loading branch information
minh-bq authored Nov 20, 2023
1 parent c2ef093 commit 84eaf51
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
13 changes: 11 additions & 2 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ type BlockChain struct {
shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block.
shouldStoreInternalTxs bool
enableAdditionalChainEvent bool
evmHook vm.EVMHook
}

// NewBlockChain returns a fully initialised block chain using information
Expand Down Expand Up @@ -427,6 +428,14 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
return bc, nil
}

func (bc *BlockChain) SetHook(evmHook vm.EVMHook) {
bc.evmHook = evmHook
}

func (bc *BlockChain) GetHook() vm.EVMHook {
return bc.evmHook
}

func (bc *BlockChain) loadLatestDirtyAccounts() {
dirtyStateAccounts := rawdb.ReadDirtyAccounts(bc.db)
for _, data := range dirtyStateAccounts {
Expand Down Expand Up @@ -1515,9 +1524,9 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.

if status == CanonStatTy {
if bc.enableAdditionalChainEvent {
bc.sendNewBlockEvent(block, receipts, true, true)
bc.sendNewBlockEvent(block, receipts, true, true)
} else {
bc.sendNewBlockEvent(block, receipts, false, false)
bc.sendNewBlockEvent(block, receipts, false, false)
}
if len(logs) > 0 {
bc.logsFeed.Send(logs)
Expand Down
5 changes: 5 additions & 0 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"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/log"
"github.com/ethereum/go-ethereum/params"
)

Expand Down Expand Up @@ -74,6 +75,10 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg

blockContext := NewEVMBlockContext(header, p.bc, nil, publishEvents...)
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
if evmHook := p.bc.GetHook(); evmHook != nil {
log.Debug("set hook function for testnet")
vmenv.SetHook(evmHook)
}

txNum := len(block.Transactions())
commonTxs := make([]*types.Transaction, 0, txNum)
Expand Down
25 changes: 25 additions & 0 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ type (
)

func (evm *EVM) precompile(caller ContractRef, addr common.Address) (PrecompiledContract, bool) {
if evm.evmHook != nil {
mustReturn, contract, isPrecompile := evm.evmHook.PrecompileHook(evm, addr)
if mustReturn {
return contract, isPrecompile
}
}
if c := evm.ChainConfig().BlacklistContractAddress; evm.chainRules.IsOdysseusFork && evm.StateDB.Blacklisted(c, &addr) {
return &blacklistedAddress{}, true
}
Expand Down Expand Up @@ -161,6 +167,13 @@ type EVM struct {
// available gas is calculated in gasCall* according to the 63/64 rule and later
// applied in opCall*.
callGasTemp uint64

evmHook EVMHook
}

type EVMHook interface {
PrecompileHook(*EVM, common.Address) (bool, PrecompiledContract, bool)
CreateHook(*EVM, uint64, common.Address) (bool, []byte, common.Address, uint64, error)
}

// NewEVM returns a new EVM. The returned EVM is not thread safe and should
Expand Down Expand Up @@ -500,6 +513,14 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
}
}
}

if evm.evmHook != nil {
mustReturn, ret, address, gas, err := evm.evmHook.CreateHook(evm, gas, caller.Address())
if mustReturn {
return ret, address, gas, err
}
}

// Handle latest hardfork firstly.
if evm.chainRules.IsAntenna {
if !evm.StateDB.ValidDeployerV2(caller.Address(), evm.Context.Time, evm.ChainConfig().WhiteListDeployerContractV2Address) {
Expand Down Expand Up @@ -668,3 +689,7 @@ func (evm *EVM) PublishEvent(
)
}
}

func (evm *EVM) SetHook(evmHook EVMHook) {
evm.evmHook = evmHook
}

0 comments on commit 84eaf51

Please sign in to comment.