Limit state sync by gas

This commit is contained in:
Ferran 2022-05-09 17:39:07 +04:00 committed by Shivam Sharma
parent f083705e00
commit e01a0f2619
2 changed files with 24 additions and 11 deletions

View file

@ -1144,7 +1144,8 @@ func (c *Bor) fetchAndCommitSpan(
msg := getSystemMessage(common.HexToAddress(c.config.ValidatorContract), data) msg := getSystemMessage(common.HexToAddress(c.config.ValidatorContract), data)
// apply message // apply message
return applyMessage(msg, state, header, c.chainConfig, chain) _, err = applyMessage(msg, state, header, c.chainConfig, chain)
return err
} }
// CommitStates commit states // 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() chainID := c.chainConfig.ChainID.String()
for _, eventRecord := range eventRecords { for _, eventRecord := range eventRecords {
if eventRecord.ID <= lastStateID { if eventRecord.ID <= lastStateID {
@ -1191,9 +1194,15 @@ func (c *Bor) CommitStates(
} }
stateSyncs = append(stateSyncs, &stateData) 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 return nil, err
} }
totalGas -= int(gasUsed)
if totalGas < 0 {
break
}
lastStateID++ lastStateID++
} }
return stateSyncs, nil return stateSyncs, nil
@ -1311,14 +1320,16 @@ func applyMessage(
header *types.Header, header *types.Header,
chainConfig *params.ChainConfig, chainConfig *params.ChainConfig,
chainContext core.ChainContext, chainContext core.ChainContext,
) error { ) (uint64, error) {
initialGas := msg.Gas()
// Create a new context to be used in the EVM environment // Create a new context to be used in the EVM environment
blockContext := core.NewEVMBlockContext(header, chainContext, &header.Coinbase) blockContext := core.NewEVMBlockContext(header, chainContext, &header.Coinbase)
// Create a new environment which holds all relevant information // Create a new environment which holds all relevant information
// about the transaction and calling mechanisms. // about the transaction and calling mechanisms.
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, state, chainConfig, vm.Config{}) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, state, chainConfig, vm.Config{})
// Apply the transaction to the current state (included in the env) // Apply the transaction to the current state (included in the env)
_, _, err := vmenv.Call( _, gasLeft, err := vmenv.Call(
vm.AccountRef(msg.From()), vm.AccountRef(msg.From()),
*msg.To(), *msg.To(),
msg.Data(), msg.Data(),
@ -1330,7 +1341,8 @@ func applyMessage(
state.Finalise(true) state.Finalise(true)
} }
return nil gasUsed := initialGas - gasLeft
return gasUsed, nil
} }
func validatorContains(a []*Validator, x *Validator) (*Validator, bool) { func validatorContains(a []*Validator, x *Validator) (*Validator, bool) {

View file

@ -53,25 +53,26 @@ func (gc *GenesisContractsClient) CommitState(
state *state.StateDB, state *state.StateDB,
header *types.Header, header *types.Header,
chCtx chainContext, chCtx chainContext,
) error { ) (uint64, error) {
eventRecord := event.BuildEventRecord() eventRecord := event.BuildEventRecord()
recordBytes, err := rlp.EncodeToBytes(eventRecord) recordBytes, err := rlp.EncodeToBytes(eventRecord)
if err != nil { if err != nil {
return err return 0, err
} }
method := "commitState" method := "commitState"
t := event.Time.Unix() t := event.Time.Unix()
data, err := gc.stateReceiverABI.Pack(method, big.NewInt(0).SetInt64(t), recordBytes) data, err := gc.stateReceiverABI.Pack(method, big.NewInt(0).SetInt64(t), recordBytes)
if err != nil { if err != nil {
log.Error("Unable to pack tx for commitState", "error", err) log.Error("Unable to pack tx for commitState", "error", err)
return err return 0, err
} }
log.Info("→ committing new state", "eventRecord", event.String()) log.Info("→ committing new state", "eventRecord", event.String())
msg := getSystemMessage(common.HexToAddress(gc.StateReceiverContract), data) msg := getSystemMessage(common.HexToAddress(gc.StateReceiverContract), data)
if err := applyMessage(msg, state, header, gc.chainConfig, chCtx); err != nil { gasUsed, err := applyMessage(msg, state, header, gc.chainConfig, chCtx)
return err if err != nil {
return 0, err
} }
return nil return gasUsed, nil
} }
func (gc *GenesisContractsClient) LastStateId(snapshotNumber uint64) (*big.Int, error) { func (gc *GenesisContractsClient) LastStateId(snapshotNumber uint64) (*big.Int, error) {