Commit 022af5bd authored by tdot's avatar tdot Committed by GitHub

feat: add tx data version byte (#9845)

* feat: add tx data version byte

* fix: check data len before version byte

* avoid passing version byte
parent 876e16ad
......@@ -400,7 +400,8 @@ func (l *BatchSubmitter) sendTransaction(ctx context.Context, txdata txData, que
l.recordFailedTx(txdata, err)
return nil
}
data = comm.Encode()
// signal plasma commitment tx with TxDataVersion1
data = comm.TxData()
}
candidate = l.calldataTxCandidate(data)
}
......
......@@ -253,7 +253,7 @@ func (s *L2Batcher) ActL2BatchSubmit(t Testing, txOpts ...func(tx *types.Dynamic
if s.l2BatcherCfg.UsePlasma {
comm, err := s.l2BatcherCfg.PlasmaDA.SetInput(t.Ctx(), payload)
require.NoError(t, err, "failed to set input for plasma")
payload = comm.Encode()
payload = comm.TxData()
}
nonce, err := s.l1.PendingNonceAt(t.Ctx(), s.batcherAddr)
......
......@@ -159,7 +159,8 @@ func (a *L2PlasmaDA) ActNewL2Tx(t Testing) {
a.batcher.ActL2BatchBuffer(t)
a.batcher.ActL2ChannelClose(t)
a.batcher.ActL2BatchSubmit(t, func(tx *types.DynamicFeeTx) {
a.lastComm = tx.Data
// skip txdata version byte
a.lastComm = tx.Data[1:]
})
a.miner.ActL1StartBlock(3)(t)
......
......@@ -4,6 +4,8 @@ import (
"encoding/hex"
"errors"
"fmt"
plasma "github.com/ethereum-optimism/optimism/op-plasma"
)
// count the tagging info as 200 in terms of buffer size.
......@@ -19,6 +21,9 @@ func frameSize(frame Frame) uint64 {
const DerivationVersion0 = 0
// DerivationVersion1 is reserved for batcher transactions containing plasma commitments.
const DerivationVersion1 = plasma.TxDataVersion1
// MaxSpanBatchSize is the maximum amount of bytes that will be needed
// to decode every span batch field. This value cannot be larger than
// MaxRLPBytesPerChannel because single batch cannot be larger than channel size.
......
......@@ -45,14 +45,22 @@ func (s *PlasmaDataSource) Next(ctx context.Context) (eth.Data, error) {
}
if s.comm == nil {
var err error
// the l1 source returns the input commitment for the batch.
data, err := s.src.Next(ctx)
if err != nil {
return nil, err
}
if len(data) == 0 {
return nil, NotEnoughData
}
// If the tx data type is not plasma, we forward it downstream to let the next
// steps validate and potentially parse it as L1 DA inputs.
if data[0] != plasma.TxDataVersion1 {
return data, nil
}
// validate batcher inbox data is a commitment.
comm, err := plasma.DecodeKeccak256(data)
comm, err := plasma.DecodeKeccak256(data[1:])
if err != nil {
s.log.Warn("invalid commitment", "commitment", data, "err", err)
return s.Next(ctx)
......
......@@ -134,7 +134,7 @@ func TestPlasmaDataSource(t *testing.T) {
Gas: 100_000,
To: &batcherInbox,
Value: big.NewInt(int64(0)),
Data: comm.Encode(),
Data: comm.TxData(),
})
require.NoError(t, err)
......@@ -234,7 +234,7 @@ func TestPlasmaDataSource(t *testing.T) {
Gas: 100_000,
To: &batcherInbox,
Value: big.NewInt(int64(0)),
Data: comm.Encode(),
Data: comm.TxData(),
})
require.NoError(t, err)
......@@ -351,7 +351,7 @@ func TestPlasmaDataSourceStall(t *testing.T) {
Gas: 100_000,
To: &batcherInbox,
Value: big.NewInt(int64(0)),
Data: comm.Encode(),
Data: comm.TxData(),
})
require.NoError(t, err)
......@@ -466,7 +466,7 @@ func TestPlasmaDataSourceInvalidData(t *testing.T) {
Gas: 100_000,
To: &batcherInbox,
Value: big.NewInt(int64(0)),
Data: comm.Encode(),
Data: comm.TxData(),
})
require.NoError(t, err)
......@@ -481,11 +481,11 @@ func TestPlasmaDataSourceInvalidData(t *testing.T) {
Gas: 100_000,
To: &batcherInbox,
Value: big.NewInt(int64(0)),
Data: comm2.Encode(),
Data: comm2.TxData(),
})
require.NoError(t, err)
// invalid commitment
// regular input instead of commitment
input3 := testutils.RandomData(rng, 32)
tx3, err := types.SignNewTx(batcherPriv, signer, &types.DynamicFeeTx{
ChainID: signer.ChainID(),
......@@ -506,12 +506,16 @@ func TestPlasmaDataSourceInvalidData(t *testing.T) {
src, err := factory.OpenData(ctx, ref, batcherAddr)
require.NoError(t, err)
// oversized input should be skipped
// oversized input is skipped and returns input2 directly
data, err := src.Next(ctx)
require.NoError(t, err)
require.Equal(t, hexutil.Bytes(input2), data)
// invalid commitment is skipped so should return an EOF
// regular input is passed through
data, err = src.Next(ctx)
require.NoError(t, err)
require.Equal(t, hexutil.Bytes(input3), data)
_, err = src.Next(ctx)
require.ErrorIs(t, err, io.EOF)
......
......@@ -27,6 +27,11 @@ func (c Keccak256Commitment) Encode() []byte {
return append([]byte{byte(Keccak256CommitmentType)}, c...)
}
// TxData adds an extra version byte to signal it's a commitment.
func (c Keccak256Commitment) TxData() []byte {
return append([]byte{TxDataVersion1}, c.Encode()...)
}
// Verify checks if the commitment matches the given input.
func (c Keccak256Commitment) Verify(input []byte) error {
if !bytes.Equal(c, crypto.Keccak256(input)) {
......
......@@ -4,3 +4,8 @@ package plasma
// 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
// TxDataVersion1 is the version number for batcher transactions containing
// plasma commitments. It should not collide with DerivationVersion which is still
// used downstream when parsing the frames.
const TxDataVersion1 = 1
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment