mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core: nicer 0-basefee, make it work for blob fees too
This commit is contained in:
parent
849c0d4a40
commit
de24a7a612
6 changed files with 39 additions and 27 deletions
|
|
@ -77,11 +77,15 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
|
|||
|
||||
// NewEVMTxContext creates a new transaction context for a single transaction.
|
||||
func NewEVMTxContext(msg *Message) vm.TxContext {
|
||||
return vm.TxContext{
|
||||
ctx := vm.TxContext{
|
||||
Origin: msg.From,
|
||||
GasPrice: new(big.Int).Set(msg.GasPrice),
|
||||
BlobHashes: msg.BlobHashes,
|
||||
}
|
||||
if msg.BlobGasFeeCap != nil {
|
||||
ctx.BlobFeeCap = new(big.Int).Set(msg.BlobGasFeeCap)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
// GetHashFn returns a GetHashFunc which retrieves header hashes by number
|
||||
|
|
|
|||
|
|
@ -287,7 +287,6 @@ func (st *StateTransition) preCheck() error {
|
|||
msg.From.Hex(), codeHash)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
|
||||
if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
|
||||
// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
|
||||
|
|
@ -307,7 +306,7 @@ func (st *StateTransition) preCheck() error {
|
|||
// This will panic if baseFee is nil, but basefee presence is verified
|
||||
// as part of header validation.
|
||||
if msg.GasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
|
||||
return fmt.Errorf("%w: address %v, maxFeePerGas: %s baseFee: %s", ErrFeeCapTooLow,
|
||||
return fmt.Errorf("%w: address %v, maxFeePerGas: %s, baseFee: %s", ErrFeeCapTooLow,
|
||||
msg.From.Hex(), msg.GasFeeCap, st.evm.Context.BaseFee)
|
||||
}
|
||||
}
|
||||
|
|
@ -324,17 +323,24 @@ func (st *StateTransition) preCheck() error {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the user is paying at least the current blob fee
|
||||
if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) {
|
||||
if st.blobGasUsed() > 0 {
|
||||
// Check that the user is paying at least the current blob fee
|
||||
blobFee := st.evm.Context.BlobBaseFee
|
||||
if st.msg.BlobGasFeeCap.Cmp(blobFee) < 0 {
|
||||
return fmt.Errorf("%w: address %v have %v want %v", ErrBlobFeeCapTooLow, st.msg.From.Hex(), st.msg.BlobGasFeeCap, blobFee)
|
||||
// Skip the checks if gas fields are zero and blobBaseFee was explicitly disabled (eth_call)
|
||||
if !st.evm.Config.NoBaseFee && msg.BlobGasFeeCap.BitLen() > 0 {
|
||||
if l := msg.BlobGasFeeCap.BitLen(); l > 256 {
|
||||
return fmt.Errorf("%w: address %v, blobGasFeeCap bit length: %d", ErrFeeCapVeryHigh,
|
||||
msg.From.Hex(), l)
|
||||
}
|
||||
// This will panic if blobBaseFee is nil, but blobBaseFee presence
|
||||
// is verified as part of header validation.
|
||||
if msg.BlobGasFeeCap.Cmp(st.evm.Context.BlobBaseFee) < 0 {
|
||||
return fmt.Errorf("%w: address %v blobGasFeeCap: %v, blobBaseFee: %v", ErrBlobFeeCapTooLow,
|
||||
msg.From.Hex(), msg.BlobGasFeeCap, st.evm.Context.BlobBaseFee)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return st.buyGas()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -215,12 +215,8 @@ func opTstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
|
|||
|
||||
// opBaseFee implements BASEFEE opcode
|
||||
func opBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
if interpreter.evm.Config.NoBaseFee {
|
||||
scope.Stack.push(new(uint256.Int))
|
||||
} else {
|
||||
baseFee, _ := uint256.FromBig(interpreter.evm.Context.BaseFee)
|
||||
scope.Stack.push(baseFee)
|
||||
}
|
||||
baseFee, _ := uint256.FromBig(interpreter.evm.Context.BaseFee)
|
||||
scope.Stack.push(baseFee)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ type BlockContext struct {
|
|||
BlockNumber *big.Int // Provides information for NUMBER
|
||||
Time uint64 // Provides information for TIME
|
||||
Difficulty *big.Int // Provides information for DIFFICULTY
|
||||
BaseFee *big.Int // Provides information for BASEFEE
|
||||
BlobBaseFee *big.Int // Provides information for BLOBBASEFEE
|
||||
BaseFee *big.Int // Provides information for BASEFEE (0 if vm runs with NoBaseFee flag and 0 gas price)
|
||||
BlobBaseFee *big.Int // Provides information for BLOBBASEFEE (0 if vm runs with NoBaseFee flag and 0 blob gas price)
|
||||
Random *common.Hash // Provides information for PREVRANDAO
|
||||
}
|
||||
|
||||
|
|
@ -82,7 +82,8 @@ type BlockContext struct {
|
|||
type TxContext struct {
|
||||
// Message information
|
||||
Origin common.Address // Provides information for ORIGIN
|
||||
GasPrice *big.Int // Provides information for GASPRICE
|
||||
GasPrice *big.Int // Provides information for GASPRICE (and is used to zero the basefee if NoBaseFee is set)
|
||||
BlobFeeCap *big.Int // Provides information for BLOBGASPRICE(?) (and is used to zero the blobbasefee if NoBaseFee is set)
|
||||
BlobHashes []common.Hash // Provides information for BLOBHASH
|
||||
}
|
||||
|
||||
|
|
@ -125,6 +126,17 @@ type EVM struct {
|
|||
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
|
||||
// only ever be used *once*.
|
||||
func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM {
|
||||
// If basefee tracking is disabled (eth_call, eth_estimateGas, etc), and no
|
||||
// gas prices were specified, lower the basefee to 0 to avoid breaking EVM
|
||||
// invariants (basefee < feecap)
|
||||
if config.NoBaseFee {
|
||||
if txCtx.GasPrice.BitLen() == 0 {
|
||||
blockCtx.BaseFee = new(big.Int)
|
||||
}
|
||||
if txCtx.BlobFeeCap != nil && txCtx.BlobFeeCap.BitLen() == 0 {
|
||||
blockCtx.BlobBaseFee = new(big.Int)
|
||||
}
|
||||
}
|
||||
evm := &EVM{
|
||||
Context: blockCtx,
|
||||
TxContext: txCtx,
|
||||
|
|
@ -160,14 +172,6 @@ func (evm *EVM) Interpreter() *EVMInterpreter {
|
|||
return evm.interpreter
|
||||
}
|
||||
|
||||
// SetBlockContext updates the block context of the EVM.
|
||||
func (evm *EVM) SetBlockContext(blockCtx BlockContext) {
|
||||
evm.Context = blockCtx
|
||||
num := blockCtx.BlockNumber
|
||||
timestamp := blockCtx.Time
|
||||
evm.chainRules = evm.chainConfig.Rules(num, blockCtx.Random != nil, timestamp)
|
||||
}
|
||||
|
||||
// Call executes the contract associated with the addr with the given input as
|
||||
// parameters. It also handles any necessary value transfer required and takes
|
||||
// the necessary steps to create accounts and reverses the state in case of an
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ func NewEnv(cfg *Config) *vm.EVM {
|
|||
Origin: cfg.Origin,
|
||||
GasPrice: cfg.GasPrice,
|
||||
BlobHashes: cfg.BlobHashes,
|
||||
BlobFeeCap: cfg.BlobFeeCap,
|
||||
}
|
||||
blockContext := vm.BlockContext{
|
||||
CanTransfer: core.CanTransfer,
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ type Config struct {
|
|||
BaseFee *big.Int
|
||||
BlobBaseFee *big.Int
|
||||
BlobHashes []common.Hash
|
||||
BlobFeeCap *big.Int
|
||||
Random *common.Hash
|
||||
|
||||
State *state.StateDB
|
||||
|
|
@ -97,7 +98,7 @@ func setDefaults(cfg *Config) {
|
|||
cfg.BaseFee = big.NewInt(params.InitialBaseFee)
|
||||
}
|
||||
if cfg.BlobBaseFee == nil {
|
||||
cfg.BlobBaseFee = new(big.Int)
|
||||
cfg.BlobBaseFee = big.NewInt(params.BlobTxMinBlobGasprice)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue