Skip to content

Commit

Permalink
optimism: fix historical-blocks chain-gen and TTD check
Browse files Browse the repository at this point in the history
  • Loading branch information
protolambda committed Jan 20, 2024
1 parent 4bae064 commit 3080d04
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 32 deletions.
14 changes: 7 additions & 7 deletions consensus/beacon/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,10 @@ func (beacon *Beacon) InnerEngine() consensus.Engine {
return beacon.ethone
}

func (beacon *Beacon) SwapInner(inner consensus.Engine) {
beacon.ethone = inner
}

// SetThreads updates the mining threads. Delegate the call
// to the eth1 engine if it's threaded.
func (beacon *Beacon) SetThreads(threads int) {
Expand All @@ -478,13 +482,9 @@ func (beacon *Beacon) SetThreads(threads int) {
// If the parentHash is not stored in the database a UnknownAncestor error is returned.
func IsTTDReached(chain consensus.ChainHeaderReader, parentHash common.Hash, parentNumber uint64) (bool, error) {
if cfg := chain.Config(); cfg.Optimism != nil {
num := parentNumber
if num == ^(uint64(0)) { // caller can (intentionally?!) underflow on parent-of-block 0 case.
num = 0
}
if cfg.IsBedrock(new(big.Int).SetUint64(num)) {
return true, nil
}
// If OP-Stack then bedrock activation number determines when TTD (eth Merge) has been reached.
// Note: some tests/utils will set parentNumber == max_uint64 as "parent" of the genesis block, this is fine.
return cfg.IsBedrock(new(big.Int).SetUint64(parentNumber + 1)), nil
}
if chain.Config().TerminalTotalDifficulty == nil {
return false, nil
Expand Down
4 changes: 2 additions & 2 deletions consensus/beacon/oplegacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ func (o *OpLegacy) VerifyHeader(chain consensus.ChainHeaderReader, header *types
func (o *OpLegacy) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header) (chan<- struct{}, <-chan error) {
quit := make(chan struct{}, 1)
result := make(chan error, len(headers))
for range headers {
result <- nil
for _, h := range headers {
result <- o.VerifyHeader(chain, h)
}
return quit, result
}
Expand Down
2 changes: 1 addition & 1 deletion core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
// to a chain, so the difficulty will be left unset (nil). Set it here to the
// correct value.
if b.header.Difficulty == nil {
if config.TerminalTotalDifficulty == nil {
if config.TerminalTotalDifficulty == nil && !config.IsOptimismBedrock(b.header.Number) {
// Clique chain
b.header.Difficulty = big.NewInt(2)
} else {
Expand Down
2 changes: 1 addition & 1 deletion core/types/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, nu
logIndex++
}
}
if config.Optimism != nil && len(txs) >= 2 { // need at least an info tx and a non-info tx
if config.Optimism != nil && len(txs) >= 2 && config.IsBedrock(new(big.Int).SetUint64(number)) { // need at least an info tx and a non-info tx
l1BaseFee, costFunc, feeScalar, err := extractL1GasParams(config, time, txs[0].Data())
if err != nil {
return err
Expand Down
14 changes: 11 additions & 3 deletions core/types/receipt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,16 @@ import (
)

var (
bedrockGenesisTestConfig = func() *params.ChainConfig {
conf := *params.AllCliqueProtocolChanges // copy the config
conf.Clique = nil
conf.TerminalTotalDifficultyPassed = true
conf.BedrockBlock = big.NewInt(0)
conf.Optimism = &params.OptimismConfig{EIP1559Elasticity: 50, EIP1559Denominator: 10}
return &conf
}()
ecotoneTestConfig = func() *params.ChainConfig {
conf := *params.OptimismTestConfig // copy the config
conf := *bedrockGenesisTestConfig // copy the config
time := uint64(0)
conf.EcotoneTime = &time
return &conf
Expand Down Expand Up @@ -774,7 +782,7 @@ func TestDeriveOptimismBedrockTxReceipts(t *testing.T) {
// Re-derive receipts.
baseFee := big.NewInt(1000)
derivedReceipts := clearComputedFieldsOnReceipts(receipts)
err := Receipts(derivedReceipts).DeriveFields(params.OptimismTestConfig, blockHash, blockNumber.Uint64(), 0, baseFee, nil, txs)
err := Receipts(derivedReceipts).DeriveFields(bedrockGenesisTestConfig, blockHash, blockNumber.Uint64(), 0, baseFee, nil, txs)
if err != nil {
t.Fatalf("DeriveFields(...) = %v, want <nil>", err)
}
Expand Down Expand Up @@ -802,7 +810,7 @@ func TestDeriveOptimismEcotoneTxReceipts(t *testing.T) {
baseFee := big.NewInt(1000)
derivedReceipts := clearComputedFieldsOnReceipts(receipts)
// Should error out if we try to process this with a pre-Ecotone config
err := Receipts(derivedReceipts).DeriveFields(params.OptimismTestConfig, blockHash, blockNumber.Uint64(), 0, baseFee, nil, txs)
err := Receipts(derivedReceipts).DeriveFields(bedrockGenesisTestConfig, blockHash, blockNumber.Uint64(), 0, baseFee, nil, txs)
if err == nil {
t.Fatalf("expected error from deriving ecotone receipts with pre-ecotone config, got none")
}
Expand Down
47 changes: 29 additions & 18 deletions ethclient/ethclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
"time"

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/beacon"
"github.com/ethereum/go-ethereum/internal/ethapi"

"github.com/ethereum/go-ethereum"
Expand Down Expand Up @@ -286,21 +288,28 @@ func newMockHistoricalBackend(t *testing.T) string {
func newTestBackend(t *testing.T, enableHistoricalState bool) (*node.Node, []*types.Block) {
histAddr := newMockHistoricalBackend(t)

// Generate test chain.
blocks := generateTestChain(enableHistoricalState)
var consensusEngine consensus.Engine
var actualGenesis *core.Genesis
var chainLength int
if enableHistoricalState {
actualGenesis = genesisForHistorical
consensusEngine = beacon.New(ethash.NewFaker())
chainLength = 10
} else {
actualGenesis = genesis
consensusEngine = ethash.NewFaker()
chainLength = 2
}

// Generate test chain
blocks := generateTestChain(consensusEngine, actualGenesis, chainLength)

// Create node
n, err := node.New(&node.Config{})
if err != nil {
t.Fatalf("can't create new node: %v", err)
}
// Create Ethereum Service
var actualGenesis *core.Genesis
if enableHistoricalState {
actualGenesis = genesisForHistorical
} else {
actualGenesis = genesis
}
config := &ethconfig.Config{Genesis: actualGenesis}
if enableHistoricalState {
config.RollupHistoricalRPC = histAddr
Expand All @@ -310,37 +319,39 @@ func newTestBackend(t *testing.T, enableHistoricalState bool) (*node.Node, []*ty
if err != nil {
t.Fatalf("can't create new ethereum service: %v", err)
}
if enableHistoricalState { // swap to the pre-bedrock consensus-engine that we used to generate the historical blocks
ethservice.BlockChain().Engine().(*beacon.Beacon).SwapInner(ethash.NewFaker())
}
// Import the test chain.
if err := n.Start(); err != nil {
t.Fatalf("can't start test node: %v", err)
}
if _, err := ethservice.BlockChain().InsertChain(blocks[1:]); err != nil {
t.Fatalf("can't import test blocks: %v", err)
}
if enableHistoricalState {
// Now that we have a filled DB, swap the pre-Bedrock consensus to OpLegacy,
// which does not support re-processing of pre-bedrock data.
ethservice.Engine().(*beacon.Beacon).SwapInner(&beacon.OpLegacy{})
}
return n, blocks
}

func generateTestChain(enableHistoricalState bool) []*types.Block {
func generateTestChain(consensusEngine consensus.Engine, genesis *core.Genesis, length int) []*types.Block {
generate := func(i int, g *core.BlockGen) {
g.OffsetTime(5)
g.SetExtra([]byte("test"))
if i == 1 {
// Test transactions are included in block #2.
if enableHistoricalState {
if genesis.Config.Optimism != nil && genesis.Config.IsBedrock(big.NewInt(1)) {
g.AddTx(depositTx)
}
g.AddTx(testTx1)
g.AddTx(testTx2)
}
}
var actualGenesis *core.Genesis
if enableHistoricalState {
actualGenesis = genesisForHistorical
} else {
actualGenesis = genesis
}
_, blocks, _ := core.GenerateChainWithGenesis(actualGenesis, ethash.NewFaker(), 2, generate)
return append([]*types.Block{actualGenesis.ToBlock()}, blocks...)
_, blocks, _ := core.GenerateChainWithGenesis(genesis, consensusEngine, length, generate)
return append([]*types.Block{genesis.ToBlock()}, blocks...)
}

func TestEthClientHistoricalBackend(t *testing.T) {
Expand Down

0 comments on commit 3080d04

Please sign in to comment.