Skip to content

Commit

Permalink
Merge branch 'develop' into jg/ci
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] committed Apr 11, 2023
2 parents 5150cff + 0c0cf54 commit 7bf3cf0
Show file tree
Hide file tree
Showing 59 changed files with 3,783 additions and 174 deletions.
4 changes: 2 additions & 2 deletions op-batcher/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func NewMetrics(procName string) *Metrics {
Help: "1 if the op-batcher has finished starting up",
}),

ChannelEvs: opmetrics.NewEventVec(factory, ns, "channel", "Channel", []string{"stage"}),
ChannelEvs: opmetrics.NewEventVec(factory, ns, "", "channel", "Channel", []string{"stage"}),

PendingBlocksCount: *factory.NewGaugeVec(prometheus.GaugeOpts{
Namespace: ns,
Expand Down Expand Up @@ -145,7 +145,7 @@ func NewMetrics(procName string) *Metrics {
Buckets: append([]float64{0.1, 0.2}, prometheus.LinearBuckets(0.3, 0.05, 14)...),
}),

BatcherTxEvs: opmetrics.NewEventVec(factory, ns, "batcher_tx", "BatcherTx", []string{"stage"}),
BatcherTxEvs: opmetrics.NewEventVec(factory, ns, "", "batcher_tx", "BatcherTx", []string{"stage"}),
}
}

Expand Down
2 changes: 1 addition & 1 deletion op-e2e/actions/l2_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"errors"

"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-program/l2/engineapi"
"github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi"
"github.com/stretchr/testify/require"

"github.com/ethereum/go-ethereum/common"
Expand Down
4 changes: 2 additions & 2 deletions op-e2e/actions/l2_engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"math/big"
"testing"

"github.com/ethereum-optimism/optimism/op-program/l2/engineapi"
"github.com/ethereum-optimism/optimism/op-program/l2/engineapi/test"
"github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi"
"github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi/test"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/beacon"
"github.com/ethereum/go-ethereum/consensus/ethash"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (

"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/metrics"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-program/config"
"github.com/ethereum/go-ethereum/log"
)

Expand All @@ -23,8 +23,8 @@ type Driver struct {
pipeline Derivation
}

func NewDriver(logger log.Logger, cfg *config.Config, l1Source derive.L1Fetcher, l2Source derive.Engine) *Driver {
pipeline := derive.NewDerivationPipeline(logger, cfg.Rollup, l1Source, l2Source, metrics.NoopMetrics)
func NewDriver(logger log.Logger, cfg *rollup.Config, l1Source derive.L1Fetcher, l2Source derive.Engine) *Driver {
pipeline := derive.NewDerivationPipeline(logger, cfg, l1Source, l2Source, metrics.NoopMetrics)
pipeline.Reset()
return &Driver{
logger: logger,
Expand Down
File renamed without changes.
69 changes: 69 additions & 0 deletions op-program/client/l1/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package l1

import (
"context"
"errors"
"fmt"

"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
)

var (
ErrNotFound = ethereum.NotFound
ErrUnknownLabel = errors.New("unknown label")
)

type OracleL1Client struct {
oracle Oracle
head eth.L1BlockRef
}

func NewOracleL1Client(logger log.Logger, oracle Oracle, l1Head common.Hash) *OracleL1Client {
head := eth.InfoToL1BlockRef(oracle.HeaderByBlockHash(l1Head))
logger.Info("L1 head loaded", "hash", head.Hash, "number", head.Number)
return &OracleL1Client{
oracle: oracle,
head: head,
}
}

func (o OracleL1Client) L1BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L1BlockRef, error) {
if label != eth.Unsafe && label != eth.Safe && label != eth.Finalized {
return eth.L1BlockRef{}, fmt.Errorf("%w: %s", ErrUnknownLabel, label)
}
// The L1 head is pre-agreed and unchanging so it can be used for all of unsafe, safe and finalized
return o.head, nil
}

func (o OracleL1Client) L1BlockRefByNumber(ctx context.Context, number uint64) (eth.L1BlockRef, error) {
if number > o.head.Number {
return eth.L1BlockRef{}, fmt.Errorf("%w: block number %d", ErrNotFound, number)
}
block := o.head
for block.Number > number {
block = eth.InfoToL1BlockRef(o.oracle.HeaderByBlockHash(block.ParentHash))
}
return block, nil
}

func (o OracleL1Client) L1BlockRefByHash(ctx context.Context, hash common.Hash) (eth.L1BlockRef, error) {
return eth.InfoToL1BlockRef(o.oracle.HeaderByBlockHash(hash)), nil
}

func (o OracleL1Client) InfoByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, error) {
return o.oracle.HeaderByBlockHash(hash), nil
}

func (o OracleL1Client) FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) {
info, rcpts := o.oracle.ReceiptsByBlockHash(blockHash)
return info, rcpts, nil
}

func (o OracleL1Client) InfoAndTxsByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, types.Transactions, error) {
info, txs := o.oracle.TransactionsByBlockHash(hash)
return info, txs, nil
}
210 changes: 210 additions & 0 deletions op-program/client/l1/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
package l1

import (
"context"
"math/big"
"testing"

"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-node/testutils"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
)

var _ derive.L1Fetcher = (*OracleL1Client)(nil)

var head = blockNum(1000)

func TestInfoByHash(t *testing.T) {
client, oracle := newClient(t)
hash := common.HexToHash("0xAABBCC")
expected := &sources.HeaderInfo{}
oracle.blocks[hash] = expected

info, err := client.InfoByHash(context.Background(), hash)
require.NoError(t, err)
require.Equal(t, expected, info)
}

func TestL1BlockRefByHash(t *testing.T) {
client, oracle := newClient(t)
hash := common.HexToHash("0xAABBCC")
header := &sources.HeaderInfo{}
oracle.blocks[hash] = header
expected := eth.InfoToL1BlockRef(header)

ref, err := client.L1BlockRefByHash(context.Background(), hash)
require.NoError(t, err)
require.Equal(t, expected, ref)
}

func TestFetchReceipts(t *testing.T) {
client, oracle := newClient(t)
hash := common.HexToHash("0xAABBCC")
expectedInfo := &sources.HeaderInfo{}
expectedReceipts := types.Receipts{
&types.Receipt{},
}
oracle.blocks[hash] = expectedInfo
oracle.rcpts[hash] = expectedReceipts

info, rcpts, err := client.FetchReceipts(context.Background(), hash)
require.NoError(t, err)
require.Equal(t, expectedInfo, info)
require.Equal(t, expectedReceipts, rcpts)
}

func TestInfoAndTxsByHash(t *testing.T) {
client, oracle := newClient(t)
hash := common.HexToHash("0xAABBCC")
expectedInfo := &sources.HeaderInfo{}
expectedTxs := types.Transactions{
&types.Transaction{},
}
oracle.blocks[hash] = expectedInfo
oracle.txs[hash] = expectedTxs

info, txs, err := client.InfoAndTxsByHash(context.Background(), hash)
require.NoError(t, err)
require.Equal(t, expectedInfo, info)
require.Equal(t, expectedTxs, txs)
}

func TestL1BlockRefByLabel(t *testing.T) {
t.Run("Unsafe", func(t *testing.T) {
client, _ := newClient(t)
ref, err := client.L1BlockRefByLabel(context.Background(), eth.Unsafe)
require.NoError(t, err)
require.Equal(t, eth.InfoToL1BlockRef(head), ref)
})
t.Run("Safe", func(t *testing.T) {
client, _ := newClient(t)
ref, err := client.L1BlockRefByLabel(context.Background(), eth.Safe)
require.NoError(t, err)
require.Equal(t, eth.InfoToL1BlockRef(head), ref)
})
t.Run("Finalized", func(t *testing.T) {
client, _ := newClient(t)
ref, err := client.L1BlockRefByLabel(context.Background(), eth.Finalized)
require.NoError(t, err)
require.Equal(t, eth.InfoToL1BlockRef(head), ref)
})
t.Run("UnknownLabel", func(t *testing.T) {
client, _ := newClient(t)
ref, err := client.L1BlockRefByLabel(context.Background(), eth.BlockLabel("unknown"))
require.ErrorIs(t, err, ErrUnknownLabel)
require.Equal(t, eth.L1BlockRef{}, ref)
})
}

func TestL1BlockRefByNumber(t *testing.T) {
t.Run("Head", func(t *testing.T) {
client, _ := newClient(t)
ref, err := client.L1BlockRefByNumber(context.Background(), head.NumberU64())
require.NoError(t, err)
require.Equal(t, eth.InfoToL1BlockRef(head), ref)
})
t.Run("AfterHead", func(t *testing.T) {
client, _ := newClient(t)
ref, err := client.L1BlockRefByNumber(context.Background(), head.NumberU64()+1)
// Must be ethereum.NotFound error so the derivation pipeline knows it has gone past the chain head
require.ErrorIs(t, err, ethereum.NotFound)
require.Equal(t, eth.L1BlockRef{}, ref)
})
t.Run("ParentOfHead", func(t *testing.T) {
client, oracle := newClient(t)
parent := blockNum(head.NumberU64() - 1)
oracle.blocks[parent.Hash()] = parent

ref, err := client.L1BlockRefByNumber(context.Background(), parent.NumberU64())
require.NoError(t, err)
require.Equal(t, eth.InfoToL1BlockRef(parent), ref)
})
t.Run("AncestorOfHead", func(t *testing.T) {
client, oracle := newClient(t)
block := head
blocks := []eth.BlockInfo{block}
for i := 0; i < 10; i++ {
block = blockNum(block.NumberU64() - 1)
oracle.blocks[block.Hash()] = block
blocks = append(blocks, block)
}

for _, block := range blocks {
ref, err := client.L1BlockRefByNumber(context.Background(), block.NumberU64())
require.NoError(t, err)
require.Equal(t, eth.InfoToL1BlockRef(block), ref)
}
})
}

func newClient(t *testing.T) (*OracleL1Client, *stubOracle) {
stub := &stubOracle{
t: t,
blocks: make(map[common.Hash]eth.BlockInfo),
txs: make(map[common.Hash]types.Transactions),
rcpts: make(map[common.Hash]types.Receipts),
}
stub.blocks[head.Hash()] = head
client := NewOracleL1Client(testlog.Logger(t, log.LvlDebug), stub, head.Hash())
return client, stub
}

type stubOracle struct {
t *testing.T

// blocks maps block hash to eth.BlockInfo
blocks map[common.Hash]eth.BlockInfo

// txs maps block hash to transactions
txs map[common.Hash]types.Transactions

// rcpts maps Block hash to receipts
rcpts map[common.Hash]types.Receipts
}

func (o stubOracle) HeaderByBlockHash(blockHash common.Hash) eth.BlockInfo {
info, ok := o.blocks[blockHash]
if !ok {
o.t.Fatalf("unknown block %s", blockHash)
}
return info
}

func (o stubOracle) TransactionsByBlockHash(blockHash common.Hash) (eth.BlockInfo, types.Transactions) {
txs, ok := o.txs[blockHash]
if !ok {
o.t.Fatalf("unknown txs %s", blockHash)
}
return o.HeaderByBlockHash(blockHash), txs
}

func (o stubOracle) ReceiptsByBlockHash(blockHash common.Hash) (eth.BlockInfo, types.Receipts) {
rcpts, ok := o.rcpts[blockHash]
if !ok {
o.t.Fatalf("unknown rcpts %s", blockHash)
}
return o.HeaderByBlockHash(blockHash), rcpts
}

func blockNum(num uint64) eth.BlockInfo {
parentNum := num - 1
return &testutils.MockBlockInfo{
InfoHash: common.BytesToHash(big.NewInt(int64(num)).Bytes()),
InfoParentHash: common.BytesToHash(big.NewInt(int64(parentNum)).Bytes()),
InfoCoinbase: common.Address{},
InfoRoot: common.Hash{},
InfoNum: num,
InfoTime: num * 2,
InfoMixDigest: [32]byte{},
InfoBaseFee: nil,
InfoReceiptRoot: common.Hash{},
InfoGasUsed: 0,
}
}
18 changes: 18 additions & 0 deletions op-program/client/l1/oracle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package l1

import (
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)

type Oracle interface {
// HeaderByBlockHash retrieves the block header with the given hash.
HeaderByBlockHash(blockHash common.Hash) eth.BlockInfo

// TransactionsByBlockHash retrieves the transactions from the block with the given hash.
TransactionsByBlockHash(blockHash common.Hash) (eth.BlockInfo, types.Transactions)

// ReceiptsByBlockHash retrieves the receipts from the block with the given hash.
ReceiptsByBlockHash(blockHash common.Hash) (eth.BlockInfo, types.Receipts)
}
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion op-program/l2/engine.go → op-program/client/l2/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-program/l2/engineapi"
"github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"fmt"
"math/big"

"github.com/ethereum-optimism/optimism/op-program/l2/engineapi"
"github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/beacon"
Expand Down Expand Up @@ -39,6 +39,7 @@ func NewOracleBackedL2Chain(logger log.Logger, oracle Oracle, chainCfg *params.C
if err != nil {
return nil, fmt.Errorf("loading l2 head: %w", err)
}
logger.Info("Loaded L2 head", "hash", head.Hash(), "number", head.Number())
return &OracleBackedL2Chain{
log: logger,
oracle: oracle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (

"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-program/l2/engineapi"
"github.com/ethereum-optimism/optimism/op-program/l2/engineapi/test"
"github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi"
"github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi/test"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/beacon"
"github.com/ethereum/go-ethereum/core"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 7bf3cf0

Please sign in to comment.