Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions cmd/evm/internal/t8ntool/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/systemcontracts"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
Expand Down Expand Up @@ -157,16 +157,12 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
GasLimit: pre.Env.GasLimit,
GetHash: getHash,
}
env := &pre.Env
env.BaseFee = eip1559.CalcBaseFeeDBFT(chainConfig, &types.Header{
Number: new(big.Int).SetUint64(env.Number - 1),
BaseFee: env.ParentBaseFee,
GasUsed: env.ParentGasUsed,
GasLimit: env.ParentGasLimit,
}, statedb)
// If currentBaseFee is defined, add it to the vmContext.
// If currentBaseFee is defined, add it to the vmContext and to the state DB.
if pre.Env.BaseFee != nil {
vmContext.BaseFee = new(big.Int).Set(pre.Env.BaseFee)
if chainConfig.IsNeoXBurn(vmContext.BlockNumber, vmContext.Time) {
statedb.SetState(systemcontracts.PolicyProxyHash, systemcontracts.GetBaseFeeStateHash(), common.BigToHash(pre.Env.BaseFee))
}
}
// If random is defined, add it to the vmContext.
if pre.Env.Random != nil {
Expand Down
22 changes: 22 additions & 0 deletions cmd/evm/internal/t8ntool/transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/eth/tracers/logger"
Expand Down Expand Up @@ -172,6 +174,9 @@ func Transition(ctx *cli.Context) error {
if err := applyLondonChecks(&prestate.Env, chainConfig); err != nil {
return err
}
if err := applyNeoXBurnChecks(&prestate.Env, chainConfig); err != nil {
return err
}
if err := applyShanghaiChecks(&prestate.Env, chainConfig); err != nil {
return err
}
Expand All @@ -192,6 +197,17 @@ func Transition(ctx *cli.Context) error {
return dispatchOutput(ctx, baseDir, result, collector, body)
}

func applyNeoXBurnChecks(env *stEnv, chainConfig *params.ChainConfig) error {
if !chainConfig.IsNeoXBurn(big.NewInt(int64(env.Number)), env.Timestamp) {
return nil
}
// Sanity check, to not `panic` in state_transition
if env.BaseFee == nil {
return NewError(ErrorConfig, errors.New("NeoXBurn config but missing 'currentBaseFee' in env section"))
}
return nil
}

func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
if !chainConfig.IsLondon(big.NewInt(int64(env.Number))) {
return nil
Expand All @@ -204,6 +220,12 @@ func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
if env.ParentBaseFee == nil || env.Number == 0 {
return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section"))
}
env.BaseFee = eip1559.CalcBaseFee(chainConfig, &types.Header{
Number: new(big.Int).SetUint64(env.Number - 1),
BaseFee: env.ParentBaseFee,
GasUsed: env.ParentGasUsed,
GasLimit: env.ParentGasLimit,
})
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion consensus/dbft/dbft.go
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ func (c *DBFT) verifyCascadingFields(chain consensus.ChainHeaderReader, header *
if err := misc.VerifyGaslimit(parent.GasLimit, header.GasLimit); err != nil {
return err
}
} else if err := eip1559.VerifyEIP1559HeaderDBFT(chain.Config(), parent, header); err != nil {
} else if err := eip1559.VerifyEIP1559Header(chain.Config(), parent, header); err != nil {
// Verify the header's EIP-1559 attributes.
return err
}
Expand Down
25 changes: 5 additions & 20 deletions consensus/misc/eip1559/eip1559.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ func VerifyEIP1559Header(config *params.ChainConfig, parent, header *types.Heade
if header.BaseFee == nil {
return errors.New("header is missing baseFee")
}
// For NeoXBurn block BaseFee verification is performed by consensus nodes and hence
// not included into the state-independent ordinary block verification rules.
if config.IsNeoXBurn(parent.Number, parent.Time) {
return nil
}
// Verify the baseFee is correct based on the parent header.
expectedBaseFee := CalcBaseFee(config, parent)
if header.BaseFee.Cmp(expectedBaseFee) != 0 {
Expand Down Expand Up @@ -96,26 +101,6 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
}
}

// VerifyEIP1559HeaderDBFT verifies some header attributes which were changed in EIP-1559 with dbft consensus,
// - gas limit check
// - basefee check, basefee value check moved to VerifyBlock.
func VerifyEIP1559HeaderDBFT(config *params.ChainConfig, parent, header *types.Header) error {
// Verify that the gas limit remains within allowed bounds
parentGasLimit := parent.GasLimit
if !config.IsLondon(parent.Number) {
parentGasLimit = parent.GasLimit * config.ElasticityMultiplier()
}
if err := misc.VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil {
return err
}
// Verify the header is not malformed
if header.BaseFee == nil {
return errors.New("header is missing baseFee")
}
// Verifing the baseFee is moved to VerifyBlock.
return nil
}

// CalcBaseFeeDBFT calculates the basefee of the header.
// if is neoXBurn fork, get basefee from Policy contract.
func CalcBaseFeeDBFT(config *params.ChainConfig, parent *types.Header, state *state.StateDB) *big.Int {
Expand Down
2 changes: 1 addition & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -2473,7 +2473,7 @@ func (bc *BlockChain) getParentState(block *types.Block) (*state.StateDB, *types
}

// ProcessState processes the state changes according to the Ethereum rules by running
// the transaction messages using the statedb and applying any rewards to both
// the transaction messages using the statedb (if given) and applying any rewards to both
// the processor (coinbase) and any included uncles. It doesn't persist any data.
func (bc *BlockChain) ProcessState(block *types.Block, statedb *state.StateDB) (*state.StateDB, types.Receipts, []*types.Log, uint64, error) {
var err error
Expand Down
12 changes: 4 additions & 8 deletions eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@ import (
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
cmath "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/systemcontracts"
"github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
Expand Down Expand Up @@ -365,16 +363,14 @@ func (b *EthAPIBackend) SyncProgress() ethereum.SyncProgress {
}

func (b *EthAPIBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
suggestTipCap, err := b.gpo.SuggestTipCap(ctx)
suggestTipCap, minGasTipCap, err := b.gpo.SuggestTipCap(ctx)
if err != nil {
return nil, err
}
stateDb, _, err := b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber)
if err != nil {
return nil, err
if minGasTipCap != nil && minGasTipCap.Sign() > 0 {
return minGasTipCap, nil
}
minGasTipCap := stateDb.GetState(systemcontracts.PolicyProxyHash, systemcontracts.GetMinGasTipCapStateHash()).Big()
return cmath.BigMax(suggestTipCap, minGasTipCap), nil
return suggestTipCap, nil
}

func (b *EthAPIBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (firstBlock *big.Int, reward [][]*big.Int, baseFee []*big.Int, gasUsedRatio []float64, err error) {
Expand Down
40 changes: 28 additions & 12 deletions eth/filters/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,21 +164,33 @@ func (api *FilterAPI) NewPendingTransactions(ctx context.Context, fullTx *bool)
defer pendingTxSub.Unsubscribe()

chainConfig := api.sys.backend.ChainConfig()
currHeader := api.sys.backend.CurrentHeader()
state, _, err := api.sys.backend.StateAndHeaderByNumber(context.Background(), rpc.BlockNumber(currHeader.Number.Int64()))
if err != nil {
log.Error("Failed to get state to handle pending transactions", "err", err, "header number", currHeader.Number)
return
}
baseFee := eip1559.CalcBaseFeeDBFT(chainConfig, currHeader, state)

for {
select {
case txs := <-txs:
// Update base fee cache only if new block is available.
if latestHeader := api.sys.backend.CurrentHeader(); latestHeader.Number.Cmp(currHeader.Number) > 0 {
currHeader = latestHeader
state, _, err = api.sys.backend.StateAndHeaderByNumber(context.Background(), rpc.BlockNumber(currHeader.Number.Int64()))
if err != nil {
// We're toast, use the old base fee value.
log.Error("Failed to get state to handle pending transactions", "err", err, "header number", currHeader.Number)
} else {
baseFee = eip1559.CalcBaseFeeDBFT(chainConfig, currHeader, state)
}
}
// To keep the original behaviour, send a single tx hash in one notification.
// TODO(rjl493456442) Send a batch of tx hashes in one notification
latest := api.sys.backend.CurrentHeader()
state, _, err := api.sys.backend.StateAndHeaderByNumber(context.Background(), rpc.BlockNumber(latest.Number.Int64()))
if err != nil {
log.Error("Failed to get state", "err", err, "header number", latest.Number)
}
baseFee := eip1559.CalcBaseFeeDBFT(chainConfig, latest, state)
for _, tx := range txs {
if fullTx != nil && *fullTx {
rpcTx := ethapi.NewRPCPendingTransaction(tx, latest, chainConfig, baseFee)
rpcTx := ethapi.NewRPCPendingTransaction(tx, currHeader, chainConfig, baseFee)
notifier.Notify(rpcSub.ID, rpcTx)
} else {
notifier.Notify(rpcSub.ID, tx.Hash())
Expand Down Expand Up @@ -436,11 +448,6 @@ func (api *FilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) {

chainConfig := api.sys.backend.ChainConfig()
latest := api.sys.backend.CurrentHeader()
state, _, err := api.sys.backend.StateAndHeaderByNumber(context.Background(), rpc.BlockNumber(latest.Number.Int64()))
if err != nil {
log.Error("Failed to get state", "err", err, "header number", latest.Number)
}
baseFee := eip1559.CalcBaseFeeDBFT(chainConfig, latest, state)

if f, found := api.filters[id]; found {
if !f.deadline.Stop() {
Expand All @@ -458,6 +465,15 @@ func (api *FilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) {
case PendingTransactionsSubscription:
if f.fullTx {
txs := make([]*ethapi.RPCTransaction, 0, len(f.txs))
var baseFee *big.Int
if latest != nil {
state, _, err := api.sys.backend.StateAndHeaderByNumber(context.Background(), rpc.BlockNumber(latest.Number.Int64()))
if err != nil {
log.Error("Failed to get state to retrieve filter changes", "err", err, "header number", latest.Number)
return txs, err
}
baseFee = eip1559.CalcBaseFeeDBFT(chainConfig, latest, state)
}
for _, tx := range f.txs {
txs = append(txs, ethapi.NewRPCPendingTransaction(tx, latest, chainConfig, baseFee))
}
Expand Down
15 changes: 8 additions & 7 deletions eth/gasprice/feehistory.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"sync/atomic"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
Expand Down Expand Up @@ -77,17 +76,19 @@ type txGasAndReward struct {
// processBlock takes a blockFees structure with the blockNumber, the header and optionally
// the block field filled in, retrieves the block from the backend if not present yet and
// fills in the rest of the fields.
func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
func (oracle *Oracle) processBlock(ctx context.Context, bf *blockFees, percentiles []float64) {
chainconfig := oracle.backend.ChainConfig()
if bf.results.baseFee = bf.header.BaseFee; bf.results.baseFee == nil {
bf.results.baseFee = new(big.Int)
}
if chainconfig.IsLondon(big.NewInt(int64(bf.blockNumber + 1))) {
state, _, err := oracle.backend.StateAndHeaderByNumber(context.Background(), rpc.BlockNumber(bf.blockNumber))
_, baseFee, _, err := oracle.suggestTipCapInternal(ctx, bf.header)
if err != nil {
log.Error("Failed to get state", "err", err, "header number", bf.blockNumber)
log.Error(fmt.Sprintf("Failed to calculate BaseFee: %s", err))
bf.results.nextBaseFee = new(big.Int)
} else {
bf.results.nextBaseFee = baseFee
}
bf.results.nextBaseFee = eip1559.CalcBaseFeeDBFT(chainconfig, bf.header, state)
} else {
bf.results.nextBaseFee = new(big.Int)
}
Expand Down Expand Up @@ -267,7 +268,7 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL
if pendingBlock != nil && blockNumber >= pendingBlock.NumberU64() {
fees.block, fees.receipts = pendingBlock, pendingReceipts
fees.header = fees.block.Header()
oracle.processBlock(fees, rewardPercentiles)
oracle.processBlock(ctx, fees, rewardPercentiles)
results <- fees
} else {
cacheKey := cacheKey{number: blockNumber, percentiles: string(percentileKey)}
Expand All @@ -286,7 +287,7 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL
fees.header, fees.err = oracle.backend.HeaderByNumber(ctx, rpc.BlockNumber(blockNumber))
}
if fees.header != nil && fees.err == nil {
oracle.processBlock(fees, rewardPercentiles)
oracle.processBlock(ctx, fees, rewardPercentiles)
if fees.err == nil {
oracle.historyCache.Add(cacheKey, fees.results)
}
Expand Down
Loading