Skip to content
This repository has been archived by the owner on Aug 22, 2024. It is now read-only.

Commit

Permalink
feat(eigenda): support prefix derivation
Browse files Browse the repository at this point in the history
  • Loading branch information
emilianobonassi committed Apr 10, 2024
1 parent 8aaaf69 commit cc294f9
Show file tree
Hide file tree
Showing 19 changed files with 176 additions and 105 deletions.
16 changes: 9 additions & 7 deletions op-batcher/batcher/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,14 @@ type CLIConfig struct {
// ActiveSequencerCheckDuration is the duration between checks to determine the active sequencer endpoint.
ActiveSequencerCheckDuration time.Duration

TxMgrConfig txmgr.CLIConfig
LogConfig oplog.CLIConfig
MetricsConfig opmetrics.CLIConfig
PprofConfig oppprof.CLIConfig
RPC oprpc.CLIConfig
PlasmaDA plasma.CLIConfig
DAConfig eigenda.CLIConfig
TxMgrConfig txmgr.CLIConfig
LogConfig oplog.CLIConfig
MetricsConfig opmetrics.CLIConfig
PprofConfig oppprof.CLIConfig
RPC oprpc.CLIConfig
PlasmaDA plasma.CLIConfig
DAConfig eigenda.CLIConfig
PrefixDerivationEnabled bool
}

func (c *CLIConfig) Check() error {
Expand Down Expand Up @@ -169,5 +170,6 @@ func NewConfig(ctx *cli.Context) *CLIConfig {
RPC: oprpc.ReadCLIConfig(ctx),
PlasmaDA: plasma.ReadCLIConfig(ctx),
DAConfig: eigenda.ReadCLIConfig(ctx),
PrefixDerivationEnabled: ctx.Bool(flags.PrefixDerivationEnabledFlag.Name),
}
}
49 changes: 31 additions & 18 deletions op-batcher/batcher/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,17 @@ type RollupClient interface {

// DriverSetup is the collection of input/output interfaces and configuration that the driver operates on.
type DriverSetup struct {
Log log.Logger
Metr metrics.Metricer
RollupConfig *rollup.Config
Config BatcherConfig
Txmgr txmgr.TxManager
L1Client L1Client
EndpointProvider dial.L2EndpointProvider
ChannelConfig ChannelConfig
PlasmaDA *plasma.DAClient
DA eigenda.IEigenDA
Log log.Logger
Metr metrics.Metricer
RollupConfig *rollup.Config
Config BatcherConfig
Txmgr txmgr.TxManager
L1Client L1Client
EndpointProvider dial.L2EndpointProvider
ChannelConfig ChannelConfig
PlasmaDA *plasma.DAClient
DA eigenda.IEigenDA
PrefixDerivationEnabled bool
}

// BatchSubmitter encapsulates a service responsible for submitting L2 tx
Expand Down Expand Up @@ -463,14 +464,20 @@ func (l *BatchSubmitter) sendTransaction(ctx context.Context, txdata txData, que
blobInfo, err := l.DA.DisperseBlob(context.Background(), data)
if err != nil { // fallback to posting raw frame to calldata, although still within this proto wrapper
l.Log.Error("Unable to publish batch frameset to EigenDA, falling back to calldata", "err", err)
calldataFrame := &op_service.CalldataFrame{
Value: &op_service.CalldataFrame_Frame{
Frame: data,
},
}
wrappedData, err = proto.Marshal(calldataFrame)
if err != nil {
return err
if l.PrefixDerivationEnabled {
// do not wrap
l.Log.Info("Prefix derivation enabled, not wrapping calldata with FrameRef")
wrappedData = data
} else {
calldataFrame := &op_service.CalldataFrame{
Value: &op_service.CalldataFrame_Frame{
Frame: data,
},
}
wrappedData, err = proto.Marshal(calldataFrame)
if err != nil {
return err
}
}
} else { // happy path, post raw frame to eigenda then post frameRef to calldata
quorumIDs := make([]uint32, len(blobInfo.BlobHeader.BlobQuorumParams))
Expand All @@ -492,6 +499,12 @@ func (l *BatchSubmitter) sendTransaction(ctx context.Context, txdata txData, que
if err != nil {
return err
}

if l.PrefixDerivationEnabled {
// prepend the derivation version to the data
l.Log.Info("Prepending derivation version to calldata")
wrappedData = append([]byte{eigenda.DerivationVersionEigenda}, wrappedData...)
}
}

data = wrappedData
Expand Down
25 changes: 14 additions & 11 deletions op-batcher/batcher/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ type BatcherService struct {

NotSubmittingOnStart bool

DA eigenda.IEigenDA
DA eigenda.IEigenDA
PrefixDerivationEnabled bool
}

// BatcherServiceFromCLIConfig creates a new BatcherService from a CLIConfig.
Expand Down Expand Up @@ -125,6 +126,7 @@ func (bs *BatcherService) initFromCLIConfig(ctx context.Context, version string,
if err := bs.initDA(cfg); err != nil {
return fmt.Errorf("failed to init DA: %w", err)
}
bs.PrefixDerivationEnabled = cfg.PrefixDerivationEnabled
bs.initDriver()
if err := bs.initRPCServer(cfg); err != nil {
return fmt.Errorf("failed to start RPC server: %w", err)
Expand Down Expand Up @@ -293,16 +295,17 @@ func (bs *BatcherService) initMetricsServer(cfg *CLIConfig) error {

func (bs *BatcherService) initDriver() {
bs.driver = NewBatchSubmitter(DriverSetup{
Log: bs.Log,
Metr: bs.Metrics,
RollupConfig: bs.RollupConfig,
Config: bs.BatcherConfig,
Txmgr: bs.TxManager,
L1Client: bs.L1Client,
EndpointProvider: bs.EndpointProvider,
ChannelConfig: bs.ChannelConfig,
PlasmaDA: bs.PlasmaDA,
DA: bs.DA,
Log: bs.Log,
Metr: bs.Metrics,
RollupConfig: bs.RollupConfig,
Config: bs.BatcherConfig,
Txmgr: bs.TxManager,
L1Client: bs.L1Client,
EndpointProvider: bs.EndpointProvider,
ChannelConfig: bs.ChannelConfig,
PlasmaDA: bs.PlasmaDA,
DA: bs.DA,
PrefixDerivationEnabled: bs.PrefixDerivationEnabled,
})
}

Expand Down
7 changes: 7 additions & 0 deletions op-batcher/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ var (
Value: 2 * time.Minute,
EnvVars: prefixEnvVars("ACTIVE_SEQUENCER_CHECK_DURATION"),
}
PrefixDerivationEnabledFlag = &cli.BoolFlag{
Name: "da-prefix-derivation-enabled",
Usage: "Enable prefix derivation",
Value: false,
EnvVars: prefixEnvVars("DA_PREFIX_DERIVATION_ENABLED"),
}
// Legacy Flags
SequencerHDPathFlag = txmgr.SequencerHDPathFlag
)
Expand All @@ -152,6 +158,7 @@ var optionalFlags = []cli.Flag{
BatchTypeFlag,
DataAvailabilityTypeFlag,
ActiveSequencerCheckDurationFlag,
PrefixDerivationEnabledFlag,
}

func init() {
Expand Down
7 changes: 7 additions & 0 deletions op-node/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,12 @@ var (
Value: "http://da:26658",
EnvVars: prefixEnvVars("DA_RPC"),
}
PrefixDerivationEnabledFlag = &cli.BoolFlag{
Name: "da-prefix-derivation-enabled",
Usage: "Enable prefix derivation",
Value: false,
EnvVars: prefixEnvVars("DA_PREFIX_DERIVATION_ENABLED"),
}
)

var requiredFlags = []cli.Flag{
Expand Down Expand Up @@ -406,6 +412,7 @@ var optionalFlags = []cli.Flag{
ConductorRpcFlag,
ConductorRpcTimeoutFlag,
SafeDBPath,
PrefixDerivationEnabledFlag,
}

var DeprecatedFlags = []cli.Flag{
Expand Down
3 changes: 2 additions & 1 deletion op-node/node/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ type Config struct {
// but if log-events are not coming in (e.g. not syncing blocks) then the reload ensures the config stays accurate.
RuntimeConfigReloadInterval time.Duration

DA eigenda.Config
DA eigenda.Config
PrefixDerivationEnabled bool

// Optional
Tracer Tracer
Expand Down
2 changes: 1 addition & 1 deletion op-node/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ func (n *OpNode) initL2(ctx context.Context, cfg *Config, snapshotLog log.Logger
} else {
n.safeDB = safedb.Disabled
}
n.l2Driver = driver.NewDriver(&cfg.Driver, &cfg.Rollup, n.l2Source, n.l1Source, n.beacon, n, n, n.log, snapshotLog, n.metrics, cfg.ConfigPersistence, n.safeDB, &cfg.Sync, sequencerConductor, plasmaDA, &cfg.DA)
n.l2Driver = driver.NewDriver(&cfg.Driver, &cfg.Rollup, n.l2Source, n.l1Source, n.beacon, n, n, n.log, snapshotLog, n.metrics, cfg.ConfigPersistence, n.safeDB, &cfg.Sync, sequencerConductor, plasmaDA, &cfg.DA, cfg.PrefixDerivationEnabled)
return nil
}

Expand Down
40 changes: 21 additions & 19 deletions op-node/rollup/derive/blob_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,28 @@ type blobOrCalldata struct {
// BlobDataSource fetches blobs or calldata as appropriate and transforms them into usable rollup
// data.
type BlobDataSource struct {
data []blobOrCalldata
ref eth.L1BlockRef
batcherAddr common.Address
dsCfg DataSourceConfig
fetcher L1TransactionFetcher
blobsFetcher L1BlobsFetcher
log log.Logger
daClient eigenda.IEigenDA
data []blobOrCalldata
ref eth.L1BlockRef
batcherAddr common.Address
dsCfg DataSourceConfig
fetcher L1TransactionFetcher
blobsFetcher L1BlobsFetcher
log log.Logger
daClient eigenda.IEigenDA
prefixDerivationEnabled bool
}

// NewBlobDataSource creates a new blob data source.
func NewBlobDataSource(ctx context.Context, log log.Logger, dsCfg DataSourceConfig, fetcher L1TransactionFetcher, blobsFetcher L1BlobsFetcher, ref eth.L1BlockRef, batcherAddr common.Address, daClient eigenda.IEigenDA) DataIter {
func NewBlobDataSource(ctx context.Context, log log.Logger, dsCfg DataSourceConfig, fetcher L1TransactionFetcher, blobsFetcher L1BlobsFetcher, ref eth.L1BlockRef, batcherAddr common.Address, daClient eigenda.IEigenDA, prefixDerivationEnabled bool) DataIter {
return &BlobDataSource{
ref: ref,
dsCfg: dsCfg,
fetcher: fetcher,
log: log.New("origin", ref),
batcherAddr: batcherAddr,
blobsFetcher: blobsFetcher,
daClient: daClient,
ref: ref,
dsCfg: dsCfg,
fetcher: fetcher,
log: log.New("origin", ref),
batcherAddr: batcherAddr,
blobsFetcher: blobsFetcher,
daClient: daClient,
prefixDerivationEnabled: prefixDerivationEnabled,
}
}

Expand Down Expand Up @@ -89,7 +91,7 @@ func (ds *BlobDataSource) open(ctx context.Context) ([]blobOrCalldata, error) {
return nil, NewTemporaryError(fmt.Errorf("failed to open blob data source: %w", err))
}

data, hashes := dataAndHashesFromTxs(txs, &ds.dsCfg, ds.batcherAddr, ds.daClient)
data, hashes := dataAndHashesFromTxs(txs, &ds.dsCfg, ds.batcherAddr, ds.daClient, ds.prefixDerivationEnabled)

if len(hashes) == 0 {
// there are no blobs to fetch so we can return immediately
Expand Down Expand Up @@ -118,7 +120,7 @@ func (ds *BlobDataSource) open(ctx context.Context) ([]blobOrCalldata, error) {
// dataAndHashesFromTxs extracts calldata and datahashes from the input transactions and returns them. It
// creates a placeholder blobOrCalldata element for each returned blob hash that must be populated
// by fillBlobPointers after blob bodies are retrieved.
func dataAndHashesFromTxs(txs types.Transactions, config *DataSourceConfig, batcherAddr common.Address, daClient eigenda.IEigenDA) ([]blobOrCalldata, []eth.IndexedBlobHash) {
func dataAndHashesFromTxs(txs types.Transactions, config *DataSourceConfig, batcherAddr common.Address, daClient eigenda.IEigenDA, prefixDerivationEnabled bool) ([]blobOrCalldata, []eth.IndexedBlobHash) {
data := []blobOrCalldata{}
var hashes []eth.IndexedBlobHash
blobIndex := 0 // index of each blob in the block's blob sidecar
Expand All @@ -131,7 +133,7 @@ func dataAndHashesFromTxs(txs types.Transactions, config *DataSourceConfig, batc
}
// handle non-blob batcher transactions by extracting their calldata
if tx.Type() != types.BlobTxType {
calldata := DataFromEVMTransactions(*config, batcherAddr, types.Transactions{tx}, logger, daClient)
calldata := DataFromEVMTransactions(*config, batcherAddr, types.Transactions{tx}, logger, daClient, prefixDerivationEnabled)
if len(calldata) == 0 {
log.Warn("eigenda: skipping empty calldata")
continue
Expand Down
10 changes: 5 additions & 5 deletions op-node/rollup/derive/blob_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestDataAndHashesFromTxs(t *testing.T) {
}
calldataTx, _ := types.SignNewTx(privateKey, signer, txData)
txs := types.Transactions{calldataTx}
data, blobHashes := dataAndHashesFromTxs(txs, &config, batcherAddr, nil)
data, blobHashes := dataAndHashesFromTxs(txs, &config, batcherAddr, nil, false)
require.Equal(t, 1, len(data))
require.Equal(t, 0, len(blobHashes))

Expand All @@ -57,22 +57,22 @@ func TestDataAndHashesFromTxs(t *testing.T) {
}
blobTx, _ := types.SignNewTx(privateKey, signer, blobTxData)
txs = types.Transactions{blobTx}
data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr, nil)
data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr, nil, false)
require.Equal(t, 1, len(data))
require.Equal(t, 1, len(blobHashes))
require.Nil(t, data[0].calldata)

// try again with both the blob & calldata transactions and make sure both are picked up
txs = types.Transactions{blobTx, calldataTx}
data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr, nil)
data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr, nil, false)
require.Equal(t, 2, len(data))
require.Equal(t, 1, len(blobHashes))
require.NotNil(t, data[1].calldata)

// make sure blob tx to the batch inbox is ignored if not signed by the batcher
blobTx, _ = types.SignNewTx(testutils.RandomKey(), signer, blobTxData)
txs = types.Transactions{blobTx}
data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr, nil)
data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr, nil, false)
require.Equal(t, 0, len(data))
require.Equal(t, 0, len(blobHashes))

Expand All @@ -81,7 +81,7 @@ func TestDataAndHashesFromTxs(t *testing.T) {
blobTxData.To = testutils.RandomAddress(rng)
blobTx, _ = types.SignNewTx(privateKey, signer, blobTxData)
txs = types.Transactions{blobTx}
data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr, nil)
data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr, nil, false)
require.Equal(t, 0, len(data))
require.Equal(t, 0, len(blobHashes))
}
Expand Down
Loading

0 comments on commit cc294f9

Please sign in to comment.