Skip to content

Commit

Permalink
re-introduce InboxContractConfig (#122)
Browse files Browse the repository at this point in the history
* Revert "fix alt-da test"

This reverts commit bf97d60.

* add InboxContractConfig

* add some comment
  • Loading branch information
blockchaindevsh authored Dec 11, 2024
1 parent b9d71bd commit 62470c4
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 53 deletions.
45 changes: 26 additions & 19 deletions op-batcher/batcher/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -843,27 +843,32 @@ func (l *BatchSubmitter) sendTransaction(txdata txData, queue *txmgr.Queue[txRef
// sendTx uses the txmgr queue to send the given transaction candidate after setting its
// gaslimit. It will block if the txmgr queue has reached its MaxPendingTransactions limit.
func (l *BatchSubmitter) sendTx(txdata txData, isCancel bool, candidate *txmgr.TxCandidate, queue *txmgr.Queue[txRef], receiptsCh chan txmgr.TxReceipt[txRef]) {
isEOAPointer := l.inboxIsEOA.Load()
if isEOAPointer == nil {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
defer cancel()
var code []byte
code, err := l.L1Client.CodeAt(ctx, *candidate.To, nil)
if err != nil {
l.Log.Error("CodeAt failed, assuming code exists", "err", err)
// assume code exist, but don't persist the result
isEOA := false
isEOAPointer = &isEOA
} else {
isEOA := len(code) == 0
isEOAPointer = &isEOA
l.inboxIsEOA.Store(isEOAPointer)
var isEOAPointer *bool
if l.RollupConfig.UseInboxContract() {
// RollupConfig.UseInboxContract() being true just means the batcher's transaction status matters,
// but the actual inbox may still be an EOA.
isEOAPointer = l.inboxIsEOA.Load()
if isEOAPointer == nil {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
defer cancel()
var code []byte
code, err := l.L1Client.CodeAt(ctx, *candidate.To, nil)
if err != nil {
l.Log.Error("CodeAt failed, assuming code exists", "err", err)
// assume code exist, but don't persist the result
isEOA := false
isEOAPointer = &isEOA
} else {
isEOA := len(code) == 0
isEOAPointer = &isEOA
l.inboxIsEOA.Store(isEOAPointer)
}
}

}

// Set GasLimit as intrinstic gas if the inbox is EOA, otherwise
// Leave GasLimit unset when inbox is contract so that later on `EstimateGas` will be called
if *isEOAPointer {
if !l.RollupConfig.UseInboxContract() || *isEOAPointer {
intrinsicGas, err := core.IntrinsicGas(candidate.TxData, nil, false, true, true, false)
if err != nil {
// we log instead of return an error here because txmgr can do its own gas estimation
Expand Down Expand Up @@ -906,7 +911,7 @@ func (l *BatchSubmitter) handleReceipt(r txmgr.TxReceipt[txRef]) {
l.recordFailedTx(r.ID.id, r.Err)
} else {
// check tx status
if r.Receipt.Status == types.ReceiptStatusFailed {
if l.RollupConfig.UseInboxContract() && r.Receipt.Status == types.ReceiptStatusFailed {
l.recordFailedTx(r.ID.id, ErrInboxTransactionFailed)
return
}
Expand All @@ -931,7 +936,9 @@ func (l *BatchSubmitter) recordFailedDARequest(id txID, err error) {
}

func (l *BatchSubmitter) recordFailedTx(id txID, err error) {
l.inboxIsEOA.Store(nil)
if l.RollupConfig.UseInboxContract() {
l.inboxIsEOA.Store(nil)
}
l.Log.Warn("Transaction failed to send", logFields(id, err)...)
l.state.TxFailed(id)
}
Expand Down
12 changes: 12 additions & 0 deletions op-chain-ops/genesis/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ type L2InitializationConfig struct {
L2CoreDeployConfig
AltDADeployConfig
SoulGasTokenConfig
InboxContractConfig
}

func (d *L2InitializationConfig) Check(log log.Logger) error {
Expand Down Expand Up @@ -843,6 +844,12 @@ type SoulGasTokenConfig struct {
IsSoulBackedByNative bool `json:"isSoulBackedByNative,omitempty"`
}

// InboxContractConfig configures whether inbox contract is enabled.
// If enabled, the batcher tx will be further filtered by tx status.
type InboxContractConfig struct {
UseInboxContract bool `json:"useInboxContract,omitempty"`
}

// DependencyContext is the contextual configuration needed to verify the L1 dependencies,
// used by DeployConfig.CheckAddresses.
type DependencyContext struct {
Expand Down Expand Up @@ -1011,6 +1018,10 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Header, l2GenesisBlockHa
L2BlobTime: d.L2BlobTime(l1StartTime),
}
}
var inboxContractConfig *rollup.InboxContractConfig
if d.UseInboxContract {
inboxContractConfig = &rollup.InboxContractConfig{UseInboxContract: true}
}

return &rollup.Config{
Genesis: rollup.Genesis{
Expand Down Expand Up @@ -1050,6 +1061,7 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Header, l2GenesisBlockHa
ProtocolVersionsAddress: d.ProtocolVersionsProxy,
AltDAConfig: altDA,
L2BlobConfig: l2BlobConfig,
InboxContractConfig: inboxContractConfig,
}, nil
}

Expand Down
33 changes: 6 additions & 27 deletions op-node/rollup/derive/altda_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ func TestAltDADataSource(t *testing.T) {
nc := 0
firstChallengeExpirationBlock := uint64(95)

// for reusing after pipeline is reset
successfulReceipts := make(map[common.Hash]types.Receipts)
for i := uint64(0); i <= pcfg.ChallengeWindow+pcfg.ResolveWindow; i++ {
parent := l1Refs[len(l1Refs)-1]
// create a new mock l1 ref
Expand All @@ -119,6 +117,8 @@ func TestAltDADataSource(t *testing.T) {
}
l1Refs = append(l1Refs, ref)
logger.Info("new l1 block", "ref", ref)
// called for each l1 block to sync challenges
l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil)

// pick a random number of commitments to include in the l1 block
c := rng.Intn(4)
Expand Down Expand Up @@ -149,12 +149,6 @@ func TestAltDADataSource(t *testing.T) {
txs = append(txs, tx)

}

successfulReceipts[ref.Hash] = successfulReceiptsForTxs(txs)
// called by `getTxSucceed` to fetch tx status
l1F.ExpectFetchReceipts(ref.Hash, nil, successfulReceipts[ref.Hash], nil)
// called for each l1 block to sync challenges
l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil)
logger.Info("included commitments", "count", c)
l1F.ExpectInfoAndTxsByHash(ref.Hash, testutils.RandomBlockInfo(rng), txs, nil)
// called once per derivation
Expand Down Expand Up @@ -211,8 +205,6 @@ func TestAltDADataSource(t *testing.T) {
ref = l1Refs[i]
logger.Info("re deriving block", "ref", ref, "i", i)

// called by `getTxSucceed` to fetch tx status
l1F.ExpectFetchReceipts(ref.Hash, nil, successfulReceipts[ref.Hash], nil)
if i == len(l1Refs)-1 {
l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil)
}
Expand All @@ -228,6 +220,8 @@ func TestAltDADataSource(t *testing.T) {
}
l1Refs = append(l1Refs, ref)
logger.Info("new l1 block", "ref", ref)
// called for each l1 block to sync challenges
l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil)

// pick a random number of commitments to include in the l1 block
c := rng.Intn(4)
Expand Down Expand Up @@ -257,10 +251,6 @@ func TestAltDADataSource(t *testing.T) {
txs = append(txs, tx)

}
// called by `getTxSucceed` to fetch tx status
l1F.ExpectFetchReceipts(ref.Hash, nil, successfulReceiptsForTxs(txs), nil)
// called for each l1 block to sync challenges
l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil)
logger.Info("included commitments", "count", c)
l1F.ExpectInfoAndTxsByHash(ref.Hash, testutils.RandomBlockInfo(rng), txs, nil)
}
Expand Down Expand Up @@ -292,13 +282,6 @@ func TestAltDADataSource(t *testing.T) {
finalitySignal.AssertExpectations(t)
}

func successfulReceiptsForTxs(txs []*types.Transaction) (receipts types.Receipts) {
for _, tx := range txs {
receipts = append(receipts, &types.Receipt{TxHash: tx.Hash(), Status: types.ReceiptStatusSuccessful})
}
return
}

// This tests makes sure the pipeline returns a temporary error if data is not found.
func TestAltDADataSourceStall(t *testing.T) {
logger := testlog.Logger(t, log.LevelDebug)
Expand Down Expand Up @@ -367,6 +350,7 @@ func TestAltDADataSourceStall(t *testing.T) {
ParentHash: parent.Hash,
Time: parent.Time + l1Time,
}
l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil)
// mock input commitments in l1 transactions
input := testutils.RandomData(rng, 2000)
comm, _ := storage.SetInput(ctx, input)
Expand All @@ -385,9 +369,6 @@ func TestAltDADataSourceStall(t *testing.T) {

txs := []*types.Transaction{tx}

// called by `getTxSucceed` to fetch tx status
l1F.ExpectFetchReceipts(ref.Hash, nil, successfulReceiptsForTxs(txs), nil)
l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil)
l1F.ExpectInfoAndTxsByHash(ref.Hash, testutils.RandomBlockInfo(rng), txs, nil)

// delete the input from the DA provider so it returns not found
Expand Down Expand Up @@ -491,6 +472,7 @@ func TestAltDADataSourceInvalidData(t *testing.T) {
ParentHash: parent.Hash,
Time: parent.Time + l1Time,
}
l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil)
// mock input commitments in l1 transactions with an oversized input
input := testutils.RandomData(rng, altda.MaxInputSize+1)
comm, _ := storage.SetInput(ctx, input)
Expand Down Expand Up @@ -538,9 +520,6 @@ func TestAltDADataSourceInvalidData(t *testing.T) {

txs := []*types.Transaction{tx1, tx2, tx3}

// called by `getTxSucceed` to fetch tx status
l1F.ExpectFetchReceipts(ref.Hash, nil, successfulReceiptsForTxs(txs), nil)
l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil)
l1F.ExpectInfoAndTxsByHash(ref.Hash, testutils.RandomBlockInfo(rng), txs, nil)

src, err := factory.OpenData(ctx, ref, batcherAddr)
Expand Down
10 changes: 7 additions & 3 deletions op-node/rollup/derive/blob_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,12 @@ func (ds *BlobDataSource) Next(ctx context.Context) (eth.Data, error) {
return data, nil
}

// getTxSucceed returns a non-nil map which contains all successful tx hashes to batch inbox
func getTxSucceed(ctx context.Context, fetcher L1Fetcher, hash common.Hash, txs types.Transactions) (successTxs types.Transactions, err error) {
// getTxSucceed returns all successful txs
func getTxSucceed(ctx context.Context, useInboxContract bool, fetcher L1Fetcher, hash common.Hash, txs types.Transactions) (successTxs types.Transactions, err error) {
if !useInboxContract {
// if !useInboxContract, all txs are considered successful
return txs, nil
}
_, receipts, err := fetcher.FetchReceipts(ctx, hash)
if err != nil {
return nil, NewTemporaryError(fmt.Errorf("failed to fetch L1 block info and receipts: %w", err))
Expand Down Expand Up @@ -107,7 +111,7 @@ func (ds *BlobDataSource) open(ctx context.Context) ([]blobOrCalldata, error) {
}
return nil, NewTemporaryError(fmt.Errorf("failed to open blob data source: %w", err))
}
txs, err = getTxSucceed(ctx, ds.fetcher, ds.ref.Hash, txs)
txs, err = getTxSucceed(ctx, ds.dsCfg.useInboxContract, ds.fetcher, ds.ref.Hash, txs)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions op-node/rollup/derive/calldata_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func NewCalldataSource(ctx context.Context, log log.Logger, dsCfg DataSourceConf
batcherAddr: batcherAddr,
}
}
txs, err = getTxSucceed(ctx, fetcher, ref.Hash, txs)
txs, err = getTxSucceed(ctx, dsCfg.useInboxContract, fetcher, ref.Hash, txs)
if err != nil {
return &CalldataSource{
open: false,
Expand All @@ -67,7 +67,7 @@ func NewCalldataSource(ctx context.Context, log log.Logger, dsCfg DataSourceConf
func (ds *CalldataSource) Next(ctx context.Context) (eth.Data, error) {
if !ds.open {
if _, txs, err := ds.fetcher.InfoAndTxsByHash(ctx, ds.ref.Hash); err == nil {
txs, err := getTxSucceed(ctx, ds.fetcher, ds.ref.Hash, txs)
txs, err := getTxSucceed(ctx, ds.dsCfg.useInboxContract, ds.fetcher, ds.ref.Hash, txs)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/derive/calldata_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func TestDataFromEVMTransactions(t *testing.T) {
}
}

out := DataFromEVMTransactions(DataSourceConfig{cfg.L1Signer(), cfg.BatchInboxAddress, false}, batcherAddr, txs, testlog.Logger(t, log.LevelCrit))
out := DataFromEVMTransactions(DataSourceConfig{cfg.L1Signer(), cfg.BatchInboxAddress, false, false}, batcherAddr, txs, testlog.Logger(t, log.LevelCrit))
require.ElementsMatch(t, expectedData, out)
}

Expand Down
2 changes: 2 additions & 0 deletions op-node/rollup/derive/data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func NewDataSourceFactory(log log.Logger, cfg *rollup.Config, fetcher L1Fetcher,
l1Signer: cfg.L1Signer(),
batchInboxAddress: cfg.BatchInboxAddress,
altDAEnabled: cfg.AltDAEnabled(),
useInboxContract: cfg.UseInboxContract(),
}
return &DataSourceFactory{
log: log,
Expand Down Expand Up @@ -88,6 +89,7 @@ type DataSourceConfig struct {
l1Signer types.Signer
batchInboxAddress common.Address
altDAEnabled bool
useInboxContract bool
}

// isValidBatchTx returns true if:
Expand Down
12 changes: 11 additions & 1 deletion op-node/rollup/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,18 +140,28 @@ type Config struct {
// AltDAConfig. We are in the process of migrating to the AltDAConfig from these legacy top level values
AltDAConfig *AltDAConfig `json:"alt_da,omitempty"`

L2BlobConfig *L2BlobConfig `json:"l2_blob_config,omitempty"`
L2BlobConfig *L2BlobConfig `json:"l2_blob_config,omitempty"`
InboxContractConfig *InboxContractConfig `json:"inbox_contract_config,omitempty"`
}

type L2BlobConfig struct {
L2BlobTime *uint64 `json:"l2BlobTime,omitempty"`
}

type InboxContractConfig struct {
UseInboxContract bool `json:"use_inbox_contract,omitempty"`
}

// IsL2Blob returns whether l2 blob is enabled
func (cfg *Config) IsL2Blob(parentTime uint64) bool {
return cfg.IsL2BlobTimeSet() && *cfg.L2BlobConfig.L2BlobTime <= parentTime
}

// UseInboxContract returns whether inbox contract is enabled
func (cfg *Config) UseInboxContract() bool {
return cfg.InboxContractConfig != nil && cfg.InboxContractConfig.UseInboxContract
}

// IsL2BlobTimeSet returns whether l2 blob activation time is set
func (cfg *Config) IsL2BlobTimeSet() bool {
return cfg.L2BlobConfig != nil && cfg.L2BlobConfig.L2BlobTime != nil
Expand Down

0 comments on commit 62470c4

Please sign in to comment.