diff --git a/api/accounts/accounts.go b/api/accounts/accounts.go index 22698bdbd..485d8039b 100644 --- a/api/accounts/accounts.go +++ b/api/accounts/accounts.go @@ -259,6 +259,7 @@ func (a *Accounts) batchCall( Time: header.Timestamp(), GasLimit: header.GasLimit(), TotalScore: header.TotalScore(), + BaseFee: header.BaseFee(), }, a.forkConfig) results = make(BatchCallResults, 0) diff --git a/api/debug/debug.go b/api/debug/debug.go index 5ff54f1dc..f2534e7d6 100644 --- a/api/debug/debug.go +++ b/api/debug/debug.go @@ -261,6 +261,7 @@ func (d *Debug) traceCall(ctx context.Context, tracer tracers.Tracer, header *bl Time: header.Timestamp(), GasLimit: header.GasLimit(), TotalScore: header.TotalScore(), + BaseFee: header.BaseFee(), }, d.forkConfig) diff --git a/consensus/consensus.go b/consensus/consensus.go index 8d6f7a9c3..e6b7801bc 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -96,6 +96,7 @@ func (c *Consensus) NewRuntimeForReplay(header *block.Header, skipPoA bool) (*ru Time: header.Timestamp(), GasLimit: header.GasLimit(), TotalScore: header.TotalScore(), + BaseFee: header.BaseFee(), }, c.forkConfig), nil } diff --git a/consensus/consensus_test.go b/consensus/consensus_test.go index 5f2d777ec..97302405c 100644 --- a/consensus/consensus_test.go +++ b/consensus/consensus_test.go @@ -448,7 +448,6 @@ func TestValidateBlockHeader(t *testing.T) { }, { "Invalid BaseFee", func(t *testing.T) { - builder := tc.builder(tc.original.Header()) blk, err := tc.sign(builder.BaseFee(big.NewInt(10000))) assert.NoError(t, err) diff --git a/consensus/fork/galactica.go b/consensus/fork/galactica.go index eaba8dee7..718242d71 100644 --- a/consensus/fork/galactica.go +++ b/consensus/fork/galactica.go @@ -6,7 +6,6 @@ package fork import ( - "errors" "fmt" "math/big" @@ -25,8 +24,8 @@ func VerifyGalacticaHeader(config *thor.ForkConfig, parent, header *block.Header if parent.Number() < config.GALACTICA { parentGasLimit = parent.GasLimit() * thor.ElasticityMultiplier } - if err := VerifyGaslimit(parentGasLimit, header.GasLimit()); err != nil { - return err + if err := block.GasLimit(header.GasLimit()).IsValid(parentGasLimit); !err { + return fmt.Errorf("invalid gas limit: have %d, want %d", header.GasLimit(), parentGasLimit) } // Verify the header is not malformed if header.BaseFee() == nil { @@ -41,24 +40,6 @@ func VerifyGalacticaHeader(config *thor.ForkConfig, parent, header *block.Header return nil } -// VerifyGaslimit verifies the header gas limit according increase/decrease -// in relation to the parent gas limit. -func VerifyGaslimit(parentGasLimit, headerGasLimit uint64) error { - // Verify that the gas limit remains within allowed bounds - diff := int64(parentGasLimit) - int64(headerGasLimit) - if diff < 0 { - diff *= -1 - } - limit := parentGasLimit / thor.GasLimitBoundDivisor - if uint64(diff) >= limit { - return fmt.Errorf("invalid gas limit: have %d, want %d +-= %d", headerGasLimit, parentGasLimit, limit-1) - } - if headerGasLimit < thor.MinGasLimit { - return errors.New("invalid gas limit below 5000") - } - return nil -} - // CalcBaseFee calculates the basefee of the header. func CalcBaseFee(config *thor.ForkConfig, parent *block.Header) *big.Int { // If the current block is the first Galactica block, return the InitialBaseFee. diff --git a/consensus/fork/galactica_test.go b/consensus/fork/galactica_test.go index c1cee20c7..cdfa2b73f 100644 --- a/consensus/fork/galactica_test.go +++ b/consensus/fork/galactica_test.go @@ -33,20 +33,20 @@ func TestBlockGasLimits(t *testing.T) { }{ // Transitions from non-Galactica to Galactica {10000000, 4, 20000000, true}, // No change - {10000000, 4, 20019530, true}, // Upper limit - {10000000, 4, 20019531, false}, // Upper +1 - {10000000, 4, 19980470, true}, // Lower limit - {10000000, 4, 19980469, false}, // Lower limit -1 + {10000000, 4, 20019531, true}, // Upper limit + {10000000, 4, 20019532, false}, // Upper +1 + {10000000, 4, 19980469, true}, // Lower limit + {10000000, 4, 19980468, false}, // Lower limit -1 // Galactica to Galactica {20000000, 5, 20000000, true}, - {20000000, 5, 20019530, true}, // Upper limit - {20000000, 5, 20019531, false}, // Upper limit +1 - {20000000, 5, 19980470, true}, // Lower limit - {20000000, 5, 19980469, false}, // Lower limit -1 - {40000000, 5, 40039061, true}, // Upper limit - {40000000, 5, 40039062, false}, // Upper limit +1 - {40000000, 5, 39960939, true}, // lower limit - {40000000, 5, 39960938, false}, // Lower limit -1 + {20000000, 5, 20019531, true}, // Upper limit + {20000000, 5, 20019532, false}, // Upper limit +1 + {20000000, 5, 19980469, true}, // Lower limit + {20000000, 5, 19980468, false}, // Lower limit -1 + {40000000, 5, 40039062, true}, // Upper limit + {40000000, 5, 40039063, false}, // Upper limit +1 + {40000000, 5, 39960938, true}, // lower limit + {40000000, 5, 39960937, false}, // Lower limit -1 } { var parentID thor.Bytes32 binary.BigEndian.PutUint32(parentID[:], tc.pNum-1) @@ -85,33 +85,3 @@ func TestCalcBaseFee(t *testing.T) { } } } - -func TestVerifyGaslimit(t *testing.T) { - for i, tc := range []struct { - parentGasLimit uint64 - headerGasLimit uint64 - ok bool - }{ - // Valid gas limits - {20000000, 20000000, true}, - {20000000, 20019530, true}, // Upper limit - {20000000, 19980470, true}, // Lower limit - {40000000, 40039061, true}, // Upper limit - {40000000, 39960939, true}, // Lower limit - - // Invalid gas limits - {20000000, 20019531, false}, // Upper limit +1 - {20000000, 19980469, false}, // Lower limit -1 - {40000000, 40039062, false}, // Upper limit +1 - {40000000, 39960938, false}, // Lower limit -1 - {20000000, 4999, false}, // Below minimum gas limit - } { - err := VerifyGaslimit(tc.parentGasLimit, tc.headerGasLimit) - if tc.ok && err != nil { - t.Errorf("test %d: Expected valid gas limit: %s", i, err) - } - if !tc.ok && err == nil { - t.Errorf("test %d: Expected invalid gas limit", i) - } - } -} diff --git a/consensus/validator.go b/consensus/validator.go index d34778a96..70c4ef761 100644 --- a/consensus/validator.go +++ b/consensus/validator.go @@ -104,10 +104,6 @@ func (c *Consensus) validateBlockHeader(header *block.Header, parent *block.Head return errFutureBlock } - if !block.GasLimit(header.GasLimit()).IsValid(parent.GasLimit()) { - return consensusError(fmt.Sprintf("block gas limit invalid: parent %v, current %v", parent.GasLimit(), header.GasLimit())) - } - if header.GasUsed() > header.GasLimit() { return consensusError(fmt.Sprintf("block gas used exceeds limit: limit %v, used %v", header.GasLimit(), header.GasUsed())) } @@ -161,6 +157,10 @@ func (c *Consensus) validateBlockHeader(header *block.Header, parent *block.Head if header.BaseFee() != nil { return consensusError("invalid block: baseFee should not set before fork GALACTICA") } + + if !block.GasLimit(header.GasLimit()).IsValid(parent.GasLimit()) { + return consensusError(fmt.Sprintf("block gas limit invalid: parent %v, current %v", parent.GasLimit(), header.GasLimit())) + } } else { if err := fork.VerifyGalacticaHeader(&c.forkConfig, parent, header); err != nil { return consensusError(fmt.Sprintf("block header invalid: %v", err)) @@ -283,6 +283,7 @@ func (c *Consensus) verifyBlock(blk *block.Block, state *state.State, blockConfl Time: header.Timestamp(), GasLimit: header.GasLimit(), TotalScore: header.TotalScore(), + BaseFee: header.BaseFee(), }, c.forkConfig) diff --git a/packer/packer.go b/packer/packer.go index aa85ade87..39717fa91 100644 --- a/packer/packer.go +++ b/packer/packer.go @@ -131,6 +131,7 @@ func (p *Packer) Schedule(parent *chain.BlockSummary, nowTimestamp uint64) (flow Time: newBlockTime, GasLimit: p.gasLimit(parent.Header.GasLimit()), TotalScore: parent.Header.TotalScore() + score, + BaseFee: parent.Header.BaseFee(), }, p.forkConfig) @@ -163,6 +164,7 @@ func (p *Packer) Mock(parent *chain.BlockSummary, targetTime uint64, gasLimit ui Time: targetTime, GasLimit: gl, TotalScore: parent.Header.TotalScore() + 1, + BaseFee: parent.Header.BaseFee(), }, p.forkConfig) diff --git a/runtime/runtime.go b/runtime/runtime.go index 2ed7b472e..77dd51751 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -146,7 +146,13 @@ func (rt *Runtime) SetVMConfig(config vm.Config) *Runtime { } func (rt *Runtime) newEVM(stateDB *statedb.StateDB, clauseIndex uint32, txCtx *xenv.TransactionContext) *vm.EVM { - var lastNonNativeCallGas uint64 + var ( + lastNonNativeCallGas uint64 + baseFee *big.Int + ) + if rt.ctx.BaseFee != nil { + baseFee = new(big.Int).Set(rt.ctx.BaseFee) + } return vm.NewEVM(vm.Context{ CanTransfer: func(_ vm.StateDB, addr common.Address, amount *big.Int) bool { return stateDB.GetBalance(addr).Cmp(amount) >= 0 @@ -303,6 +309,7 @@ func (rt *Runtime) newEVM(stateDB *statedb.StateDB, clauseIndex uint32, txCtx *x BlockNumber: new(big.Int).SetUint64(uint64(rt.ctx.Number)), Time: new(big.Int).SetUint64(rt.ctx.Time), Difficulty: &big.Int{}, + BaseFee: baseFee, }, stateDB, &rt.chainConfig, rt.vmConfig) } diff --git a/vm/evm.go b/vm/evm.go index dc90009f3..daaf01d81 100644 --- a/vm/evm.go +++ b/vm/evm.go @@ -91,6 +91,7 @@ type Context struct { BlockNumber *big.Int // Provides information for NUMBER Time *big.Int // Provides information for TIME Difficulty *big.Int // Provides information for DIFFICULTY + BaseFee *big.Int // Provides information for BASEFEE } // EVM is the Ethereum Virtual Machine base object and provides diff --git a/xenv/env.go b/xenv/env.go index d801dc38a..232b8a478 100644 --- a/xenv/env.go +++ b/xenv/env.go @@ -28,6 +28,7 @@ type BlockContext struct { Time uint64 GasLimit uint64 TotalScore uint64 + BaseFee *big.Int } // TransactionContext transaction context.