From e01a0f26195b276385a716863fd607a16285e24b Mon Sep 17 00:00:00 2001 From: Ferran Date: Mon, 9 May 2022 17:39:07 +0400 Subject: [PATCH] Limit state sync by gas --- consensus/bor/bor.go | 22 +++++++++++++++++----- consensus/bor/genesis_contracts_client.go | 13 +++++++------ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 2623011d79..70e45bab22 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -1144,7 +1144,8 @@ func (c *Bor) fetchAndCommitSpan( msg := getSystemMessage(common.HexToAddress(c.config.ValidatorContract), data) // apply message - return applyMessage(msg, state, header, c.chainConfig, chain) + _, err = applyMessage(msg, state, header, c.chainConfig, chain) + return err } // CommitStates commit states @@ -1173,6 +1174,8 @@ func (c *Bor) CommitStates( } } + totalGas := 10000000 /// limit on gas for state sync per block + chainID := c.chainConfig.ChainID.String() for _, eventRecord := range eventRecords { if eventRecord.ID <= lastStateID { @@ -1191,9 +1194,15 @@ func (c *Bor) CommitStates( } stateSyncs = append(stateSyncs, &stateData) - if err := c.GenesisContractsClient.CommitState(eventRecord, state, header, chain); err != nil { + gasUsed, err := c.GenesisContractsClient.CommitState(eventRecord, state, header, chain) + if err != nil { return nil, err } + totalGas -= int(gasUsed) + if totalGas < 0 { + break + } + lastStateID++ } return stateSyncs, nil @@ -1311,14 +1320,16 @@ func applyMessage( header *types.Header, chainConfig *params.ChainConfig, chainContext core.ChainContext, -) error { +) (uint64, error) { + initialGas := msg.Gas() + // Create a new context to be used in the EVM environment blockContext := core.NewEVMBlockContext(header, chainContext, &header.Coinbase) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. vmenv := vm.NewEVM(blockContext, vm.TxContext{}, state, chainConfig, vm.Config{}) // Apply the transaction to the current state (included in the env) - _, _, err := vmenv.Call( + _, gasLeft, err := vmenv.Call( vm.AccountRef(msg.From()), *msg.To(), msg.Data(), @@ -1330,7 +1341,8 @@ func applyMessage( state.Finalise(true) } - return nil + gasUsed := initialGas - gasLeft + return gasUsed, nil } func validatorContains(a []*Validator, x *Validator) (*Validator, bool) { diff --git a/consensus/bor/genesis_contracts_client.go b/consensus/bor/genesis_contracts_client.go index 582358e0cb..456e3fe2e5 100644 --- a/consensus/bor/genesis_contracts_client.go +++ b/consensus/bor/genesis_contracts_client.go @@ -53,25 +53,26 @@ func (gc *GenesisContractsClient) CommitState( state *state.StateDB, header *types.Header, chCtx chainContext, -) error { +) (uint64, error) { eventRecord := event.BuildEventRecord() recordBytes, err := rlp.EncodeToBytes(eventRecord) if err != nil { - return err + return 0, err } method := "commitState" t := event.Time.Unix() data, err := gc.stateReceiverABI.Pack(method, big.NewInt(0).SetInt64(t), recordBytes) if err != nil { log.Error("Unable to pack tx for commitState", "error", err) - return err + return 0, err } log.Info("→ committing new state", "eventRecord", event.String()) msg := getSystemMessage(common.HexToAddress(gc.StateReceiverContract), data) - if err := applyMessage(msg, state, header, gc.chainConfig, chCtx); err != nil { - return err + gasUsed, err := applyMessage(msg, state, header, gc.chainConfig, chCtx) + if err != nil { + return 0, err } - return nil + return gasUsed, nil } func (gc *GenesisContractsClient) LastStateId(snapshotNumber uint64) (*big.Int, error) {