Skip to content

Commit

Permalink
feat: skip oversized inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
tchardin committed Feb 27, 2024
1 parent 428a4c6 commit 0bcd84b
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 0 deletions.
5 changes: 5 additions & 0 deletions op-batcher/batcher/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,11 @@ func (bs *BatcherService) initChannelConfig(cfg *CLIConfig) error {
default:
return fmt.Errorf("unknown data availability type: %v", cfg.DataAvailabilityType)
}

if bs.UsePlasma && bs.ChannelConfig.MaxFrameSize > plasma.MaxInputSize {
return fmt.Errorf("max frame size %d exceeds plasma max input size %d", bs.ChannelConfig.MaxFrameSize, plasma.MaxInputSize)
}

bs.ChannelConfig.MaxFrameSize-- // subtract 1 byte for version

if bs.UseBlobs && !bs.RollupConfig.IsEcotone(uint64(time.Now().Unix())) {
Expand Down
6 changes: 6 additions & 0 deletions op-node/rollup/derive/plasma_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ func (s *PlasmaDataSource) Next(ctx context.Context) (eth.Data, error) {
// return temporary error so we can keep retrying.
return nil, NewTemporaryError(fmt.Errorf("failed to fetch input data with comm %x from da service: %w", s.comm, err))
}
// inputs are limited to a max size to ensure they can be challenged in the DA contract.
if len(data) > plasma.MaxInputSize {
s.log.Warn("input data exceeds max size", "size", len(data), "max", plasma.MaxInputSize)
s.comm = nil
return s.Next(ctx)
}
// reset the commitment so we can fetch the next one from the source at the next iteration.
s.comm = nil
return data, nil
Expand Down
87 changes: 87 additions & 0 deletions op-node/rollup/derive/plasma_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,3 +369,90 @@ func TestPlasmaDataSourceStall(t *testing.T) {

l1F.AssertExpectations(t)
}

func TestPlasmaDataSourceOversizedInput(t *testing.T) {
logger := testlog.Logger(t, log.LevelDebug)
ctx := context.Background()

rng := rand.New(rand.NewSource(1234))

l1F := &testutils.MockL1Source{}

storage := plasma.NewMockDAClient(logger)

pcfg := plasma.Config{
ChallengeWindow: 90, ResolveWindow: 90,
}

da := plasma.NewPlasmaDAWithStorage(logger, pcfg, storage, l1F, &plasma.NoopMetrics{})

// Create rollup genesis and config
l1Time := uint64(2)
refA := testutils.RandomBlockRef(rng)
refA.Number = 1
l1Refs := []eth.L1BlockRef{refA}
refA0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: 0,
ParentHash: common.Hash{},
Time: refA.Time,
L1Origin: refA.ID(),
SequenceNumber: 0,
}
batcherPriv := testutils.RandomKey()
batcherAddr := crypto.PubkeyToAddress(batcherPriv.PublicKey)
batcherInbox := common.Address{42}
cfg := &rollup.Config{
Genesis: rollup.Genesis{
L1: refA.ID(),
L2: refA0.ID(),
L2Time: refA0.Time,
},
BlockTime: 1,
SeqWindowSize: 20,
BatchInboxAddress: batcherInbox,
DAChallengeAddress: common.Address{43},
}

signer := cfg.L1Signer()

factory := NewDataSourceFactory(logger, cfg, l1F, nil, da)

parent := l1Refs[0]
// create a new mock l1 ref
ref := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: parent.Number + 1,
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, plasma.MaxInputSize+1)
comm, _ := storage.SetInput(ctx, input)

tx, err := types.SignNewTx(batcherPriv, signer, &types.DynamicFeeTx{
ChainID: signer.ChainID(),
Nonce: 0,
GasTipCap: big.NewInt(2 * params.GWei),
GasFeeCap: big.NewInt(30 * params.GWei),
Gas: 100_000,
To: &batcherInbox,
Value: big.NewInt(int64(0)),
Data: comm,
})
require.NoError(t, err)

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

l1F.ExpectInfoAndTxsByHash(ref.Hash, testutils.RandomBlockInfo(rng), txs, nil)

src, err := factory.OpenData(ctx, ref, batcherAddr)
require.NoError(t, err)

// data is skipped so should return an EOF
_, err = src.Next(ctx)
require.ErrorIs(t, err, io.EOF)

l1F.AssertExpectations(t)
}
6 changes: 6 additions & 0 deletions op-plasma/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package plasma

// Max input size ensures the canonical chain cannot include input batches too large to
// challenge in the Data Availability Challenge contract. Value in number of bytes.
// This value can only be changed in a hard fork.
const MaxInputSize = 130672

0 comments on commit 0bcd84b

Please sign in to comment.