Skip to content

Commit

Permalink
Move system contract check to init. (#457)
Browse files Browse the repository at this point in the history
  • Loading branch information
blxdyx authored Jul 26, 2024
1 parent 3758fb6 commit 0da1c9c
Show file tree
Hide file tree
Showing 15 changed files with 112 additions and 233 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ on:
push:
branches:
- main
- erigon3
- 'release/**'
pull_request:
branches:
- main
- erigon3
- 'release/**'
types:
- opened
Expand Down
8 changes: 2 additions & 6 deletions accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,9 @@ func (b *SimulatedBackend) emptyPendingBlock() {
// stateByBlockNumber retrieves a state by a given blocknumber.
func (b *SimulatedBackend) stateByBlockNumber(db kv.Tx, blockNumber *big.Int) *state.IntraBlockState {
if blockNumber == nil || blockNumber.Cmp(b.pendingBlock.Number()) == 0 {
return state.New(b.m.NewHistoryStateReader(b.pendingBlock.NumberU64()+1, b.pendingBlock.Time(), db))
return state.New(b.m.NewHistoryStateReader(b.pendingBlock.NumberU64()+1, db))
}
header, err := b.BlockReader().HeaderByNumber(context.Background(), db, blockNumber.Uint64())
if err != nil {
return nil
}
return state.New(b.m.NewHistoryStateReader(blockNumber.Uint64()+1, header.Time+3, db))
return state.New(b.m.NewHistoryStateReader(blockNumber.Uint64()+1, db))
}

// CodeAt returns the code associated with a certain account in the blockchain.
Expand Down
25 changes: 14 additions & 11 deletions cmd/state/exec3/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ func (rw *Worker) RunTxTaskNoLock(txTask *state.TxTask) {
rules := txTask.Rules
var err error
header := txTask.Header
lastBlockTime := header.Time - rw.chainConfig.Parlia.Period
parent, _ := rw.blockReader.HeaderByHash(rw.ctx, rw.chainTx, header.ParentHash)
if parent != nil {
lastBlockTime = parent.Time
}
//fmt.Printf("txNum=%d blockNum=%d history=%t\n", txTask.TxNum, txTask.BlockNum, txTask.HistoryExecution)

switch {
Expand All @@ -215,26 +220,26 @@ func (rw *Worker) RunTxTaskNoLock(txTask *state.TxTask) {
return core.SysCallContract(contract, data, rw.chainConfig, ibs, header, rw.engine, constCall /* constCall */)
}
if rw.isPoSA && !rw.chainConfig.IsFeynman(header.Number.Uint64(), header.Time) {
lastBlockTime := header.Time - rw.chainConfig.Parlia.Period
parent, _ := rw.blockReader.HeaderByHash(rw.ctx, rw.chainTx, header.ParentHash)
if parent != nil {
lastBlockTime = parent.Time
}
systemcontracts.UpgradeBuildInSystemContract(rw.chainConfig, header.Number, lastBlockTime, header.Time, ibs, rw.logger)
}
rw.engine.Initialize(rw.chainConfig, rw.chain, header, ibs, syscall, rw.logger, nil)
txTask.Error = ibs.FinalizeTx(rules, noop)
if err := rw.engine.Initialize(rw.chainConfig, rw.chain, header, ibs, syscall, rw.logger, nil); err != nil {
txTask.Error = err
} else {
txTask.Error = ibs.FinalizeTx(rules, noop)
}
case txTask.Final:
if txTask.BlockNum == 0 {
break
}

if _, isPoSa := rw.engine.(consensus.PoSA); isPoSa {
// Is an empty block
if rw.chainConfig.IsFeynman(header.Number.Uint64(), header.Time) && txTask.TxIndex == 0 {
systemcontracts.UpgradeBuildInSystemContract(rw.chainConfig, header.Number, lastBlockTime, header.Time, ibs, rw.logger)
}
break
}

//fmt.Printf("txNum=%d, blockNum=%d, finalisation of the block\n", txTask.TxNum, txTask.BlockNum)
// End of block transaction in a block
syscall := func(contract libcommon.Address, data []byte) ([]byte, error) {
return core.SysCallContract(contract, data, rw.chainConfig, ibs, header, rw.engine, false /* constCall */)
}
Expand All @@ -254,13 +259,11 @@ func (rw *Worker) RunTxTaskNoLock(txTask *state.TxTask) {
}
}
case txTask.SystemTxIndex > 0:

syscall := func(contract libcommon.Address, data []byte) ([]byte, error) {
return core.SysCallContract(contract, data, rw.chainConfig, ibs, header, rw.engine, false /* constCall */)
}

systemCall := func(ibs *state.IntraBlockState, index int) ([]byte, bool, error) {

rw.taskGasPool.Reset(txTask.Tx.GetGas(), rw.chainConfig.GetMaxBlobGasPerBlock())
rw.callTracer.Reset()
rw.vmCfg.SkipAnalysis = txTask.SkipAnalysis
Expand Down
10 changes: 5 additions & 5 deletions consensus/aura/aura.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ func (c *AuRa) Prepare(chain consensus.ChainHeaderReader, header *types.Header,

func (c *AuRa) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header,
state *state.IntraBlockState, syscallCustom consensus.SysCallCustom, logger log.Logger, tracer *tracing.Hooks,
) {
) error {
blockNum := header.Number.Uint64()

//Check block gas limit from smart contract, if applicable
Expand Down Expand Up @@ -678,19 +678,19 @@ func (c *AuRa) Initialize(config *chain.Config, chain consensus.ChainHeaderReade
epoch, err := c.e.GetEpoch(header.ParentHash, blockNum-1)
if err != nil {
logger.Warn("[aura] initialize block: on epoch begin", "err", err)
return
return nil
}
isEpochBegin := epoch != nil
if !isEpochBegin {
return
return nil
}
err = c.cfg.Validators.onEpochBegin(isEpochBegin, header, syscall)
if err != nil {
logger.Warn("[aura] initialize block: on epoch begin", "err", err)
return
return nil
}
// check_and_lock_block -> check_epoch_end_signal END (before enact)

return nil
}

func (c *AuRa) applyRewards(header *types.Header, state *state.IntraBlockState, syscall consensus.SystemCall) error {
Expand Down
3 changes: 2 additions & 1 deletion consensus/clique/clique.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,8 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header
}

func (c *Clique) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header,
state *state.IntraBlockState, syscall consensus.SysCallCustom, logger log.Logger, tracer *tracing.Hooks) {
state *state.IntraBlockState, syscall consensus.SysCallCustom, logger log.Logger, tracer *tracing.Hooks) error {
return nil
}

func (c *Clique) CalculateRewards(config *chain.Config, header *types.Header, uncles []*types.Header, syscall consensus.SystemCall,
Expand Down
2 changes: 1 addition & 1 deletion consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ type EngineWriter interface {

// Initialize runs any pre-transaction state modifications (e.g. epoch start)
Initialize(config *chain.Config, chain ChainHeaderReader, header *types.Header,
state *state.IntraBlockState, syscall SysCallCustom, logger log.Logger, tracer *tracing.Hooks)
state *state.IntraBlockState, syscall SysCallCustom, logger log.Logger, tracer *tracing.Hooks) error

// Finalize runs any post-transaction state modifications (e.g. block rewards)
// but does not assemble the block.
Expand Down
3 changes: 2 additions & 1 deletion consensus/ethash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,10 +563,11 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H
}

func (ethash *Ethash) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header,
state *state.IntraBlockState, syscall consensus.SysCallCustom, logger log.Logger, tracer *tracing.Hooks) {
state *state.IntraBlockState, syscall consensus.SysCallCustom, logger log.Logger, tracer *tracing.Hooks) error {
if config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(header.Number) == 0 {
misc.ApplyDAOHardFork(state)
}
return nil
}

// Finalize implements consensus.Engine, accumulating the block and uncle rewards,
Expand Down
3 changes: 2 additions & 1 deletion consensus/merge/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ func (s *Merge) IsServiceTransaction(sender libcommon.Address, syscall consensus

func (s *Merge) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header,
state *state.IntraBlockState, syscall consensus.SysCallCustom, logger log.Logger, tracer *tracing.Hooks,
) {
) error {
if !misc.IsPoSHeader(header) {
s.eth1Engine.Initialize(config, chain, header, state, syscall, logger, tracer)
}
Expand All @@ -360,6 +360,7 @@ func (s *Merge) Initialize(config *chain.Config, chain consensus.ChainHeaderRead
if chain.Config().IsPrague(header.Time) {
misc.StoreBlockHashesEip2935(header, state, config, chain)
}
return nil
}

func (s *Merge) APIs(chain consensus.ChainHeaderReader) []rpc.API {
Expand Down
16 changes: 4 additions & 12 deletions consensus/parlia/bohrFork.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package parlia

import (
"errors"
"github.com/erigontech/erigon-lib/kv"
"github.com/erigontech/erigon-lib/kv/rawdbv3"
"github.com/erigontech/erigon-lib/log/v3"
"github.com/erigontech/erigon/common/u256"
"github.com/erigontech/erigon/consensus"
Expand All @@ -15,15 +13,15 @@ import (
mrand "math/rand"
)

func (p *Parlia) getTurnLength(chain consensus.ChainHeaderReader, header *types.Header, ibs *state.IntraBlockState, tx kv.Tx) (*uint8, error) {
func (p *Parlia) getTurnLength(chain consensus.ChainHeaderReader, header *types.Header, ibs *state.IntraBlockState) (*uint8, error) {
parent := chain.GetHeaderByHash(header.ParentHash)
if parent == nil {
return nil, errors.New("parent not found")
}

var turnLength uint8
if p.chainConfig.IsBohr(parent.Number.Uint64(), parent.Time) {
turnLengthFromContract, err := p.getTurnLengthFromContract(parent, ibs, tx)
turnLengthFromContract, err := p.getTurnLengthFromContract(parent, ibs)
if err != nil {
return nil, err
}
Expand All @@ -39,20 +37,14 @@ func (p *Parlia) getTurnLength(chain consensus.ChainHeaderReader, header *types.
return &turnLength, nil
}

func (p *Parlia) getTurnLengthFromContract(header *types.Header, ibs *state.IntraBlockState, tx kv.Tx) (turnLength *big.Int, err error) {
func (p *Parlia) getTurnLengthFromContract(header *types.Header, ibs *state.IntraBlockState) (turnLength *big.Int, err error) {
// mock to get turnLength from the contract
if params.FixedTurnLength >= 1 && params.FixedTurnLength <= 9 {
if params.FixedTurnLength == 2 {
return p.getRandTurnLength(header)
}
return big.NewInt(int64(params.FixedTurnLength)), nil
}

stateReader := state.NewHistoryReaderV3()
stateReader.SetTx(tx)
maxTxNum, _ := rawdbv3.TxNums.Max(tx, header.Number.Uint64()-1)
stateReader.SetTxNum(maxTxNum)
history := state.New(stateReader)
method := "getTurnLength"
data, err := p.validatorSetABI.Pack(method)
if err != nil {
Expand All @@ -62,7 +54,7 @@ func (p *Parlia) getTurnLengthFromContract(header *types.Header, ibs *state.Intr

// do smart contract call
msgData := Bytes(data)
_, returnData, err := p.systemCall(header.Coinbase, systemcontracts.ValidatorContract, msgData[:], history, header, u256.Num0)
_, returnData, err := p.systemCall(header.Coinbase, systemcontracts.ValidatorContract, msgData[:], ibs, header, u256.Num0)
if err != nil {
return nil, err
}
Expand Down
30 changes: 16 additions & 14 deletions consensus/parlia/feynmanfork.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,23 +102,25 @@ func (p *Parlia) updateValidatorSetV2(chain consensus.ChainHeaderReader, ibs *st
// 1. get all validators and its voting header.Nu power
parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)

stateReader := state.NewHistoryReaderV3()
stateReader.SetTx(tx)
maxTxNum, _ := rawdbv3.TxNums.Max(tx, header.Number.Uint64()-1)
stateReader.SetTxNum(maxTxNum)
history := state.New(stateReader)

validatorItems, err := p.getValidatorElectionInfo(parent, history)
if err != nil {
return true, err
}
maxElectedValidators, err := p.getMaxElectedValidators(parent, history)
if err != nil {
return true, err
if validatorItemsCache == nil && maxElectedValidatorsCache == big.NewInt(0) {
stateReader := state.NewHistoryReaderV3()
stateReader.SetTx(tx)
maxTxNum, _ := rawdbv3.TxNums.Max(tx, header.Number.Uint64()-1)
stateReader.SetTxNum(maxTxNum)
history := state.New(stateReader)
var err error
validatorItemsCache, err = p.getValidatorElectionInfo(parent, history)
if err != nil {
return true, err
}
maxElectedValidatorsCache, err = p.getMaxElectedValidators(parent, history)
if err != nil {
return true, err
}
}

// 2. sort by voting power
eValidators, eVotingPowers, eVoteAddrs := getTopValidatorsByVotingPower(validatorItems, maxElectedValidators)
eValidators, eVotingPowers, eVoteAddrs := getTopValidatorsByVotingPower(validatorItemsCache, maxElectedValidatorsCache)

// 3. update validator set to system contract
method := "updateValidatorSetV2"
Expand Down
Loading

0 comments on commit 0da1c9c

Please sign in to comment.