diff --git a/go.mod b/go.mod index 74789e0..ab9c9ed 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,18 @@ go 1.21.0 require ( github.com/cosmos/gogoproto v1.7.0 + github.com/stretchr/testify v1.8.4 google.golang.org/grpc v1.67.1 ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect github.com/google/go-cmp v0.6.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/text v0.17.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 4a7b86b..f585da5 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,15 @@ github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro= github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= @@ -16,3 +22,7 @@ google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/proto/sequencing/sequencing.proto b/proto/sequencing/sequencing.proto index 135763b..e488230 100644 --- a/proto/sequencing/sequencing.proto +++ b/proto/sequencing/sequencing.proto @@ -29,8 +29,12 @@ service SequencerOutput { // GetNextBatchRequest ... message GetNextBatchRequest { + // the unhashed rollup id + bytes rollup_id = 1; // Merkle tree hash of the last batch - bytes last_batch_hash = 1; + bytes last_batch_hash = 2; + // maximum bytes that execution client can support per block + uint64 max_bytes = 3; } // GetNextBatchResponse ... @@ -52,8 +56,10 @@ service BatchVerifier { // VerifyBatchRequest ... message VerifyBatchRequest { + // the unhashed rollup id + bytes rollup_id = 1; // Merkle tree hash of the batch - bytes batch_hash = 1; + bytes batch_hash = 2; } // VerifyBatchResponse diff --git a/proxy/grpc/client.go b/proxy/grpc/client.go index 1a15626..af39fee 100644 --- a/proxy/grpc/client.go +++ b/proxy/grpc/client.go @@ -2,7 +2,6 @@ package grpc import ( "context" - "time" "google.golang.org/grpc" @@ -46,34 +45,39 @@ func (c *Client) Stop() error { } // SubmitRollupTransaction submits a transaction from rollup to sequencer. -func (c *Client) SubmitRollupTransaction(ctx context.Context, rollupId []byte, tx []byte) error { +func (c *Client) SubmitRollupTransaction(ctx context.Context, req sequencing.SubmitRollupTransactionRequest) (*sequencing.SubmitRollupTransactionResponse, error) { _, err := c.SequencerInputClient.SubmitRollupTransaction(ctx, &pbseq.SubmitRollupTransactionRequest{ - RollupId: rollupId, - Data: tx, + RollupId: req.RollupId, + Data: req.Tx, }) - return err + if err != nil { + return nil, err + } + return &sequencing.SubmitRollupTransactionResponse{}, nil } // GetNextBatch returns the next batch of transactions from sequencer to rollup. -func (c *Client) GetNextBatch(ctx context.Context, lastBatchHash []byte) (*sequencing.Batch, time.Time, error) { - resp, err := c.SequencerOutputClient.GetNextBatch(ctx, &pbseq.GetNextBatchRequest{LastBatchHash: lastBatchHash[:]}) +func (c *Client) GetNextBatch(ctx context.Context, req sequencing.GetNextBatchRequest) (*sequencing.GetNextBatchResponse, error) { + resp, err := c.SequencerOutputClient.GetNextBatch(ctx, &pbseq.GetNextBatchRequest{RollupId: req.RollupId, LastBatchHash: req.LastBatchHash}) if err != nil { - return nil, time.Now(), err + return nil, err } b := &sequencing.Batch{} b.FromProto(resp.Batch) t, err := types.TimestampFromProto(resp.Timestamp) if err != nil { - return nil, time.Now(), err + return nil, err } - return b, t, nil + return &sequencing.GetNextBatchResponse{Batch: b, Timestamp: t}, nil } // VerifyBatch verifies a batch of transactions received from the sequencer. -func (c *Client) VerifyBatch(ctx context.Context, batchHash []byte) (bool, error) { - resp, err := c.BatchVerifierClient.VerifyBatch(ctx, &pbseq.VerifyBatchRequest{BatchHash: batchHash[:]}) +func (c *Client) VerifyBatch(ctx context.Context, req sequencing.VerifyBatchRequest) (*sequencing.VerifyBatchResponse, error) { + resp, err := c.BatchVerifierClient.VerifyBatch(ctx, &pbseq.VerifyBatchRequest{RollupId: req.RollupId, BatchHash: req.BatchHash}) if err != nil { - return false, err + return nil, err } - return resp.Status, nil + return &sequencing.VerifyBatchResponse{Status: resp.Status}, nil } + +var _ sequencing.Sequencer = &Client{} diff --git a/proxy/grpc/server.go b/proxy/grpc/server.go index 307bcff..3fbbd09 100644 --- a/proxy/grpc/server.go +++ b/proxy/grpc/server.go @@ -46,7 +46,7 @@ type proxyVerificationSrv struct { // SubmitRollupTransaction submits a transaction from rollup to sequencer. func (s *proxyInputSrv) SubmitRollupTransaction(ctx context.Context, req *pbseq.SubmitRollupTransactionRequest) (*pbseq.SubmitRollupTransactionResponse, error) { - err := s.SequencerInput.SubmitRollupTransaction(ctx, req.RollupId, req.Data) + _, err := s.SequencerInput.SubmitRollupTransaction(ctx, sequencing.SubmitRollupTransactionRequest{RollupId: req.RollupId, Tx: req.Data}) if err != nil { return nil, err } @@ -55,22 +55,22 @@ func (s *proxyInputSrv) SubmitRollupTransaction(ctx context.Context, req *pbseq. // GetNextBatch returns the next batch of transactions from sequencer to rollup. func (s *proxyOutputSrv) GetNextBatch(ctx context.Context, req *pbseq.GetNextBatchRequest) (*pbseq.GetNextBatchResponse, error) { - batch, timestamp, err := s.SequencerOutput.GetNextBatch(ctx, req.LastBatchHash[:]) + resp, err := s.SequencerOutput.GetNextBatch(ctx, sequencing.GetNextBatchRequest{RollupId: req.RollupId, LastBatchHash: req.LastBatchHash}) if err != nil { return nil, err } - ts, err := types.TimestampProto(timestamp) + ts, err := types.TimestampProto(resp.Timestamp) if err != nil { return nil, err } - return &pbseq.GetNextBatchResponse{Batch: batch.ToProto(), Timestamp: ts}, nil + return &pbseq.GetNextBatchResponse{Batch: resp.Batch.ToProto(), Timestamp: ts}, nil } // VerifyBatch verifies a batch of transactions received from the sequencer. func (s *proxyVerificationSrv) VerifyBatch(ctx context.Context, req *pbseq.VerifyBatchRequest) (*pbseq.VerifyBatchResponse, error) { - ok, err := s.BatchVerifier.VerifyBatch(ctx, req.BatchHash[:]) + resp, err := s.BatchVerifier.VerifyBatch(ctx, sequencing.VerifyBatchRequest{BatchHash: req.BatchHash}) if err != nil { return nil, err } - return &pbseq.VerifyBatchResponse{Status: ok}, nil + return &pbseq.VerifyBatchResponse{Status: resp.Status}, nil } diff --git a/sequencing.go b/sequencing.go index 461de14..44c0567 100644 --- a/sequencing.go +++ b/sequencing.go @@ -15,21 +15,29 @@ type Sequencer interface { // SequencerInput provides a method for submitting a transaction from rollup to sequencer type SequencerInput interface { // SubmitRollupTransaction submits a transaction from rollup to sequencer - SubmitRollupTransaction(ctx context.Context, rollupId RollupId, tx Tx) error + // RollupId is the unique identifier for the rollup chain + // Tx is the transaction to submit + // returns an error if any from the sequencer + SubmitRollupTransaction(ctx context.Context, req SubmitRollupTransactionRequest) (*SubmitRollupTransactionResponse, error) } // SequencerOutput provides a method for getting the next batch of transactions from sequencer to rollup type SequencerOutput interface { // GetNextBatch returns the next batch of transactions from sequencer to rollup - // lastBatch is the last batch of transactions received from the sequencer + // RollupId is the unique identifier for the rollup chain + // LastBatchHash is the cryptographic hash of the last batch received by the rollup + // MaxBytes is the maximum number of bytes to return in the batch // returns the next batch of transactions and an error if any from the sequencer - GetNextBatch(ctx context.Context, lastBatchHash Hash) (*Batch, time.Time, error) + GetNextBatch(ctx context.Context, req GetNextBatchRequest) (*GetNextBatchResponse, error) } // BatchVerifier provides a method for verifying a batch of transactions received from the sequencer type BatchVerifier interface { // VerifyBatch verifies a batch of transactions received from the sequencer - VerifyBatch(ctx context.Context, batchHash Hash) (bool, error) + // RollupId is the unique identifier for the rollup chain + // BatchHash is the cryptographic hash of the batch to verify + // returns a boolean indicating if the batch is valid and an error if any from the sequencer + VerifyBatch(ctx context.Context, req VerifyBatchRequest) (*VerifyBatchResponse, error) } // RollupId is a unique identifier for a rollup chain @@ -45,3 +53,37 @@ type Hash = []byte type Batch struct { Transactions []Tx } + +// SubmitRollupTransactionRequest is a request to submit a transaction from rollup to sequencer +type SubmitRollupTransactionRequest struct { + RollupId RollupId + Tx Tx +} + +// SubmitRollupTransactionResponse is a response to submitting a transaction from rollup to sequencer +type SubmitRollupTransactionResponse struct { +} + +// GetNextBatchRequest is a request to get the next batch of transactions from sequencer to rollup +type GetNextBatchRequest struct { + RollupId RollupId + LastBatchHash Hash + MaxBytes uint64 +} + +// GetNextBatchResponse is a response to getting the next batch of transactions from sequencer to rollup +type GetNextBatchResponse struct { + Batch *Batch + Timestamp time.Time +} + +// VerifyBatchRequest is a request to verify a batch of transactions received from the sequencer +type VerifyBatchRequest struct { + RollupId RollupId + BatchHash Hash +} + +// VerifyBatchResponse is a response to verifying a batch of transactions received from the sequencer +type VerifyBatchResponse struct { + Status bool +} diff --git a/serialization.go b/serialization.go index 0b65a65..936bf65 100644 --- a/serialization.go +++ b/serialization.go @@ -1,6 +1,8 @@ package sequencing import ( + "crypto/sha256" + pbseq "github.com/rollkit/go-sequencing/types/pb/sequencing" ) @@ -46,3 +48,13 @@ func (batch *Batch) Unmarshal(data []byte) error { batch.FromProto(&pb) return nil } + +// Hash returns the hash of a batch. +func (batch *Batch) Hash() ([]byte, error) { + batchBytes, err := batch.Marshal() + if err != nil { + return nil, err + } + hash := sha256.Sum256(batchBytes) + return hash[:], nil +} diff --git a/test/dummy.go b/test/dummy.go index 4936b82..83adbbf 100644 --- a/test/dummy.go +++ b/test/dummy.go @@ -3,16 +3,17 @@ package test import ( "bytes" "context" - "crypto/sha256" + "encoding/hex" "errors" + "math" "sync" "time" "github.com/rollkit/go-sequencing" ) -// ErrorRollupIdMismatch is returned when the rollup id does not match -var ErrorRollupIdMismatch = errors.New("rollup id mismatch") +// ErrInvalidRollupId is returned when the rollup id is invalid +var ErrInvalidRollupId = errors.New("invalid rollup id") // TransactionQueue is a queue of transactions type TransactionQueue struct { @@ -34,91 +35,131 @@ func (tq *TransactionQueue) AddTransaction(tx sequencing.Tx) { tq.queue = append(tq.queue, tx) } +func totalBytes(data [][]byte) int { + total := 0 + for _, sub := range data { + total += len(sub) + } + return total +} + // GetNextBatch extracts a batch of transactions from the queue -func (tq *TransactionQueue) GetNextBatch() *sequencing.Batch { +func (tq *TransactionQueue) GetNextBatch(maxBytes uint64) *sequencing.Batch { tq.mu.Lock() defer tq.mu.Unlock() - size := len(tq.queue) - if size == 0 { + var batch [][]byte + batchSize := uint64(len(tq.queue)) + if batchSize == 0 { + return &sequencing.Batch{Transactions: nil} + } + + if maxBytes == 0 { + maxBytes = math.MaxUint64 + } + + for batchSize > 0 { + batch = tq.queue[:batchSize] + blobSize := totalBytes(batch) + if uint64(blobSize) <= maxBytes { + break + } + batchSize = batchSize - 1 + } + if batchSize == 0 { + // No transactions can fit within maxBytes return &sequencing.Batch{Transactions: nil} } - batch := tq.queue[:size] - tq.queue = tq.queue[size:] + + tq.queue = tq.queue[batchSize:] return &sequencing.Batch{Transactions: batch} } // DummySequencer is a dummy sequencer for testing that serves a single rollup type DummySequencer struct { - sequencing.RollupId - - tq *TransactionQueue - lastBatchHash []byte + rollupId []byte + tq *TransactionQueue + lastBatchHash []byte + lastBatchHashMutex sync.RWMutex - seenBatches map[string]struct{} + seenBatches map[string]struct{} + seenBatchesMutex sync.Mutex } // SubmitRollupTransaction implements sequencing.Sequencer. -func (d *DummySequencer) SubmitRollupTransaction(ctx context.Context, rollupId []byte, tx []byte) error { - if d.RollupId == nil { - d.RollupId = rollupId - } else { - if !bytes.Equal(d.RollupId, rollupId) { - return ErrorRollupIdMismatch - } +func (d *DummySequencer) SubmitRollupTransaction(ctx context.Context, req sequencing.SubmitRollupTransactionRequest) (*sequencing.SubmitRollupTransactionResponse, error) { + if !d.isValid(req.RollupId) { + return nil, ErrInvalidRollupId } - d.tq.AddTransaction(tx) - return nil + d.tq.AddTransaction(req.Tx) + return &sequencing.SubmitRollupTransactionResponse{}, nil } // GetNextBatch implements sequencing.Sequencer. -func (d *DummySequencer) GetNextBatch(ctx context.Context, lastBatchHash []byte) (*sequencing.Batch, time.Time, error) { +func (d *DummySequencer) GetNextBatch(ctx context.Context, req sequencing.GetNextBatchRequest) (*sequencing.GetNextBatchResponse, error) { + if !d.isValid(req.RollupId) { + return nil, ErrInvalidRollupId + } now := time.Now() - if d.lastBatchHash == nil { - if lastBatchHash != nil { - return nil, now, errors.New("lastBatch is supposed to be nil") - } - } else if lastBatchHash == nil { - return nil, now, errors.New("lastBatch is not supposed to be nil") - } else { - if !bytes.Equal(d.lastBatchHash, lastBatchHash) { - return nil, now, errors.New("supplied lastBatch does not match with sequencer last batch") - } + d.lastBatchHashMutex.RLock() + lastBatchHash := d.lastBatchHash + d.lastBatchHashMutex.RUnlock() + + if lastBatchHash == nil && req.LastBatchHash != nil { + return nil, errors.New("lastBatch is supposed to be nil") + } else if lastBatchHash != nil && req.LastBatchHash == nil { + return nil, errors.New("lastBatch is not supposed to be nil") + } else if !bytes.Equal(lastBatchHash, req.LastBatchHash) { + return nil, errors.New("supplied lastBatch does not match with sequencer last batch") } - batch := d.tq.GetNextBatch() + batch := d.tq.GetNextBatch(req.MaxBytes) + batchRes := &sequencing.GetNextBatchResponse{Batch: batch, Timestamp: now} // If there are no transactions, return empty batch without updating the last batch hash if batch.Transactions == nil { - return batch, now, nil + return batchRes, nil } - batchBytes, err := batch.Marshal() + h, err := batch.Hash() if err != nil { - return nil, now, err + return nil, err } - d.lastBatchHash = hashSHA256(batchBytes) - d.seenBatches[string(d.lastBatchHash)] = struct{}{} - return batch, now, nil + d.lastBatchHashMutex.Lock() + d.lastBatchHash = h + d.lastBatchHashMutex.Unlock() + + d.seenBatchesMutex.Lock() + d.seenBatches[hex.EncodeToString(h)] = struct{}{} + d.seenBatchesMutex.Unlock() + return batchRes, nil } // VerifyBatch implements sequencing.Sequencer. -func (d *DummySequencer) VerifyBatch(ctx context.Context, batchHash []byte) (bool, error) { - _, ok := d.seenBatches[string(batchHash)] - return ok, nil +func (d *DummySequencer) VerifyBatch(ctx context.Context, req sequencing.VerifyBatchRequest) (*sequencing.VerifyBatchResponse, error) { + if !d.isValid(req.RollupId) { + return nil, ErrInvalidRollupId + } + d.seenBatchesMutex.Lock() + defer d.seenBatchesMutex.Unlock() + key := hex.EncodeToString(req.BatchHash) + if _, exists := d.seenBatches[key]; exists { + return &sequencing.VerifyBatchResponse{Status: true}, nil + } + return &sequencing.VerifyBatchResponse{Status: false}, nil +} + +func (d *DummySequencer) isValid(rollupId []byte) bool { + return bytes.Equal(d.rollupId, rollupId) } // NewDummySequencer creates a new DummySequencer -func NewDummySequencer() *DummySequencer { +func NewDummySequencer(rollupId []byte) *DummySequencer { return &DummySequencer{ + rollupId: rollupId, tq: NewTransactionQueue(), seenBatches: make(map[string]struct{}, 0), } } -func hashSHA256(data []byte) []byte { - hash := sha256.Sum256(data) - return hash[:] -} - var _ sequencing.Sequencer = &DummySequencer{} diff --git a/test/dummy_test.go b/test/dummy_test.go new file mode 100644 index 0000000..7ef7175 --- /dev/null +++ b/test/dummy_test.go @@ -0,0 +1,377 @@ +package test + +import ( + "context" + "math" + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/rollkit/go-sequencing" +) + +func TestTransactionQueue_AddTransaction(t *testing.T) { + queue := NewTransactionQueue() + + tx1 := []byte("transaction_1") + queue.AddTransaction(tx1) + + // Check that the transaction was added + batch := queue.GetNextBatch(math.MaxUint64) + assert.Equal(t, 1, len(batch.Transactions)) + assert.Equal(t, tx1, batch.Transactions[0]) +} + +func TestTransactionQueue_GetNextBatch(t *testing.T) { + queue := NewTransactionQueue() + + // Add multiple transactions + tx1 := []byte("transaction_1") + tx2 := []byte("transaction_2") + queue.AddTransaction(tx1) + queue.AddTransaction(tx2) + + // Get next batch and check if all transactions are retrieved + batch := queue.GetNextBatch(math.MaxUint64) + assert.Equal(t, 2, len(batch.Transactions)) + assert.Equal(t, tx1, batch.Transactions[0]) + assert.Equal(t, tx2, batch.Transactions[1]) + + // Ensure the queue is empty after retrieving the batch + emptyBatch := queue.GetNextBatch(math.MaxUint64) + assert.Equal(t, 0, len(emptyBatch.Transactions)) +} + +func TestDummySequencer_SubmitRollupTransaction(t *testing.T) { + // Define a test rollup ID and transaction + rollupId := []byte("test_rollup_id") + tx := []byte("test_transaction") + sequencer := NewDummySequencer(rollupId) + + // Submit a transaction + req := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx, + } + resp, err := sequencer.SubmitRollupTransaction(context.Background(), req) + + // Assert no error and check if transaction was added + assert.NoError(t, err) + assert.NotNil(t, resp) + + // Check that the transaction is in the queue + batch := sequencer.tq.GetNextBatch(math.MaxUint64) + assert.Equal(t, 1, len(batch.Transactions)) + assert.Equal(t, tx, batch.Transactions[0]) +} + +func TestDummySequencer_SubmitEmptyTransaction(t *testing.T) { + // Define a test rollup ID and an empty transaction + rollupId := []byte("test_rollup_id") + tx := []byte("") + sequencer := NewDummySequencer(rollupId) + + // Submit an empty transaction + req := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx, + } + resp, err := sequencer.SubmitRollupTransaction(context.Background(), req) + + // Assert no error (since the sequencer may accept empty transactions) and ensure the transaction was added + assert.NoError(t, err) + assert.NotNil(t, resp) + + // Check that the transaction is in the queue (even if empty) + batch := sequencer.tq.GetNextBatch(math.MaxUint64) + assert.Equal(t, 1, len(batch.Transactions)) + assert.Equal(t, tx, batch.Transactions[0]) +} + +func TestDummySequencer_SubmitMultipleTransactions(t *testing.T) { + // Define a test rollup ID and multiple transactions + rollupId := []byte("test_rollup_id") + tx1 := []byte("transaction_1") + tx2 := []byte("transaction_2") + tx3 := []byte("transaction_3") + sequencer := NewDummySequencer(rollupId) + + // Submit multiple transactions + req1 := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx1, + } + req2 := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx2, + } + req3 := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx3, + } + + _, err := sequencer.SubmitRollupTransaction(context.Background(), req1) + assert.NoError(t, err) + _, err = sequencer.SubmitRollupTransaction(context.Background(), req2) + assert.NoError(t, err) + _, err = sequencer.SubmitRollupTransaction(context.Background(), req3) + assert.NoError(t, err) + + // Check that all transactions are added to the queue + batch := sequencer.tq.GetNextBatch(math.MaxUint64) + assert.Equal(t, 3, len(batch.Transactions)) + assert.Equal(t, tx1, batch.Transactions[0]) + assert.Equal(t, tx2, batch.Transactions[1]) + assert.Equal(t, tx3, batch.Transactions[2]) +} + +func TestDummySequencer_GetNextBatch(t *testing.T) { + // Add a transaction to the queue + rollupId := []byte("test_rollup_id") + tx := []byte("test_transaction") + sequencer := NewDummySequencer(rollupId) + req := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx, + } + _, err := sequencer.SubmitRollupTransaction(context.Background(), req) + assert.NoError(t, err) + + // Retrieve the next batch + getBatchReq := sequencing.GetNextBatchRequest{ + RollupId: rollupId, + LastBatchHash: nil, + } + batchResp, err := sequencer.GetNextBatch(context.Background(), getBatchReq) + + // Assert no error + assert.NoError(t, err) + // Ensure the batch contains the transaction + assert.NotNil(t, batchResp) + assert.Equal(t, 1, len(batchResp.Batch.Transactions)) + assert.Equal(t, tx, batchResp.Batch.Transactions[0]) + + // Assert timestamp is recent + assert.WithinDuration(t, time.Now(), batchResp.Timestamp, time.Second) +} + +// Test retrieving a batch with no transactions +func TestDummySequencer_GetNextBatch_NoTransactions(t *testing.T) { + rollupId := []byte("test_rollup_id") + sequencer := NewDummySequencer(rollupId) + // Attempt to retrieve a batch with no transactions in the queue + getBatchReq := sequencing.GetNextBatchRequest{ + RollupId: rollupId, + LastBatchHash: nil, + } + batchResp, err := sequencer.GetNextBatch(context.Background(), getBatchReq) + + // Assert no error + assert.NoError(t, err) + // Assert that the batch is empty + assert.NotNil(t, batchResp) + assert.Equal(t, 0, len(batchResp.Batch.Transactions)) +} + +func TestDummySequencer_GetNextBatch_LastBatchHashMismatch(t *testing.T) { + // Submit a transaction + rollupId := []byte("test_rollup_id") + sequencer := NewDummySequencer(rollupId) + tx := []byte("test_transaction") + req := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx, + } + _, err := sequencer.SubmitRollupTransaction(context.Background(), req) + assert.NoError(t, err) + + // Retrieve the next batch + getBatchReq := sequencing.GetNextBatchRequest{ + RollupId: rollupId, + LastBatchHash: []byte("invalid_hash"), + } + _, err = sequencer.GetNextBatch(context.Background(), getBatchReq) + + // Assert that the batch hash mismatch error is returned + assert.Error(t, err) + assert.Equal(t, "lastBatch is supposed to be nil", err.Error()) +} + +// Test retrieving a batch with maxBytes limit +func TestDummySequencer_GetNextBatch_MaxBytesLimit(t *testing.T) { + // Define a test rollup ID and multiple transactions + rollupId := []byte("test_rollup_id") + sequencer := NewDummySequencer(rollupId) + tx1 := []byte("transaction_1") + tx2 := []byte("transaction_2") + tx3 := []byte("transaction_3") + + // Submit multiple transactions + req1 := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx1, + } + req2 := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx2, + } + req3 := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx3, + } + + _, err := sequencer.SubmitRollupTransaction(context.Background(), req1) + assert.NoError(t, err) + _, err = sequencer.SubmitRollupTransaction(context.Background(), req2) + assert.NoError(t, err) + _, err = sequencer.SubmitRollupTransaction(context.Background(), req3) + assert.NoError(t, err) + + // Retrieve the next batch with maxBytes limit (assuming maxBytes limits the size of transactions returned) + maxBytes := uint64(len(tx1) + len(tx2)) // Set maxBytes to the size of tx1 + tx2 + + getBatchReq := sequencing.GetNextBatchRequest{ + RollupId: rollupId, + LastBatchHash: nil, + MaxBytes: maxBytes, + } + batchResp, err := sequencer.GetNextBatch(context.Background(), getBatchReq) + + // Assert no error + assert.NoError(t, err) + // Assert that only two transactions (tx1 and tx2) are retrieved due to the maxBytes limit + assert.NotNil(t, batchResp) + assert.Equal(t, 2, len(batchResp.Batch.Transactions)) + assert.Equal(t, tx1, batchResp.Batch.Transactions[0]) + assert.Equal(t, tx2, batchResp.Batch.Transactions[1]) + + lastBatchHash, err := batchResp.Batch.Hash() + assert.NoError(t, err) + // Retrieve the remaining transaction (tx3) with another call + getBatchReq2 := sequencing.GetNextBatchRequest{ + RollupId: rollupId, + LastBatchHash: lastBatchHash, + MaxBytes: maxBytes, // This can be set higher to retrieve all remaining transactions + } + batchResp2, err2 := sequencer.GetNextBatch(context.Background(), getBatchReq2) + + // Assert no error and tx3 is retrieved + assert.NoError(t, err2) + assert.NotNil(t, batchResp2) + assert.Equal(t, 1, len(batchResp2.Batch.Transactions)) + assert.Equal(t, tx3, batchResp2.Batch.Transactions[0]) +} + +func TestDummySequencer_VerifyBatch(t *testing.T) { + // Add and retrieve a batch + rollupId := []byte("test_rollup_id") + sequencer := NewDummySequencer(rollupId) + tx := []byte("test_transaction") + req := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx, + } + _, err := sequencer.SubmitRollupTransaction(context.Background(), req) + assert.NoError(t, err) + + // Get the next batch to generate batch hash + getBatchReq := sequencing.GetNextBatchRequest{ + RollupId: rollupId, + LastBatchHash: nil, + } + batchResp, err := sequencer.GetNextBatch(context.Background(), getBatchReq) + assert.NoError(t, err) + + batchHash, err := batchResp.Batch.Hash() + assert.NoError(t, err) + // Verify the batch using the batch hash + verifyReq := sequencing.VerifyBatchRequest{ + RollupId: rollupId, + BatchHash: batchHash, + } + verifyResp, err := sequencer.VerifyBatch(context.Background(), verifyReq) + + // Assert no error and that the batch is verified successfully + assert.NoError(t, err) + assert.True(t, verifyResp.Status) +} + +func TestDummySequencer_VerifyEmptyBatch(t *testing.T) { + rollupId := []byte("test_rollup_id") + sequencer := NewDummySequencer(rollupId) + + // Create a request with an empty batch hash + emptyBatchHash := []byte{} + verifyReq := sequencing.VerifyBatchRequest{ + RollupId: rollupId, + BatchHash: emptyBatchHash, + } + + // Attempt to verify the empty batch + verifyResp, err := sequencer.VerifyBatch(context.Background(), verifyReq) + + // Assert that the batch is not verified (as it's empty) + assert.NoError(t, err) + assert.False(t, verifyResp.Status) +} + +func TestDummySequencer_VerifyBatchWithMultipleTransactions(t *testing.T) { + // Define a test rollup ID and multiple transactions + rollupId := []byte("test_rollup_id") + sequencer := NewDummySequencer(rollupId) + tx1 := []byte("transaction_1") + tx2 := []byte("transaction_2") + + // Submit multiple transactions + req1 := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx1, + } + req2 := sequencing.SubmitRollupTransactionRequest{ + RollupId: rollupId, + Tx: tx2, + } + + _, err := sequencer.SubmitRollupTransaction(context.Background(), req1) + assert.NoError(t, err) + _, err = sequencer.SubmitRollupTransaction(context.Background(), req2) + assert.NoError(t, err) + + // Get the next batch to generate the batch hash + getBatchReq := sequencing.GetNextBatchRequest{ + RollupId: rollupId, + LastBatchHash: nil, + } + batchResp, err := sequencer.GetNextBatch(context.Background(), getBatchReq) + assert.NoError(t, err) + + batchHash, err := batchResp.Batch.Hash() + assert.NoError(t, err) + // Verify the batch using the batch hash + verifyReq := sequencing.VerifyBatchRequest{ + RollupId: rollupId, + BatchHash: batchHash, + } + verifyResp, err := sequencer.VerifyBatch(context.Background(), verifyReq) + + // Assert that the batch with multiple transactions is verified successfully + assert.NoError(t, err) + assert.True(t, verifyResp.Status) +} + +func TestDummySequencer_VerifyBatch_NotFound(t *testing.T) { + rollupId := []byte("test_rollup_id") + sequencer := NewDummySequencer(rollupId) + + // Try verifying a batch with an invalid hash + verifyReq := sequencing.VerifyBatchRequest{ + RollupId: rollupId, + BatchHash: []byte("invalid_hash"), + } + verifyResp, err := sequencer.VerifyBatch(context.Background(), verifyReq) + + // Assert no error and that the batch is not found + assert.NoError(t, err) + assert.False(t, verifyResp.Status) +} diff --git a/types/pb/sequencing/sequencing.pb.go b/types/pb/sequencing/sequencing.pb.go index 706d0ae..0582234 100644 --- a/types/pb/sequencing/sequencing.pb.go +++ b/types/pb/sequencing/sequencing.pb.go @@ -122,8 +122,12 @@ var xxx_messageInfo_SubmitRollupTransactionResponse proto.InternalMessageInfo // GetNextBatchRequest ... type GetNextBatchRequest struct { + // the unhashed rollup id + RollupId []byte `protobuf:"bytes,1,opt,name=rollup_id,json=rollupId,proto3" json:"rollup_id,omitempty"` // Merkle tree hash of the last batch - LastBatchHash []byte `protobuf:"bytes,1,opt,name=last_batch_hash,json=lastBatchHash,proto3" json:"last_batch_hash,omitempty"` + LastBatchHash []byte `protobuf:"bytes,2,opt,name=last_batch_hash,json=lastBatchHash,proto3" json:"last_batch_hash,omitempty"` + // maximum bytes that execution client can support per block + MaxBytes uint64 `protobuf:"varint,3,opt,name=max_bytes,json=maxBytes,proto3" json:"max_bytes,omitempty"` } func (m *GetNextBatchRequest) Reset() { *m = GetNextBatchRequest{} } @@ -159,6 +163,13 @@ func (m *GetNextBatchRequest) XXX_DiscardUnknown() { var xxx_messageInfo_GetNextBatchRequest proto.InternalMessageInfo +func (m *GetNextBatchRequest) GetRollupId() []byte { + if m != nil { + return m.RollupId + } + return nil +} + func (m *GetNextBatchRequest) GetLastBatchHash() []byte { if m != nil { return m.LastBatchHash @@ -166,6 +177,13 @@ func (m *GetNextBatchRequest) GetLastBatchHash() []byte { return nil } +func (m *GetNextBatchRequest) GetMaxBytes() uint64 { + if m != nil { + return m.MaxBytes + } + return 0 +} + // GetNextBatchResponse ... type GetNextBatchResponse struct { Batch *Batch `protobuf:"bytes,1,opt,name=batch,proto3" json:"batch,omitempty"` @@ -266,8 +284,10 @@ func (m *Batch) GetTransactions() [][]byte { // VerifyBatchRequest ... type VerifyBatchRequest struct { + // the unhashed rollup id + RollupId []byte `protobuf:"bytes,1,opt,name=rollup_id,json=rollupId,proto3" json:"rollup_id,omitempty"` // Merkle tree hash of the batch - BatchHash []byte `protobuf:"bytes,1,opt,name=batch_hash,json=batchHash,proto3" json:"batch_hash,omitempty"` + BatchHash []byte `protobuf:"bytes,2,opt,name=batch_hash,json=batchHash,proto3" json:"batch_hash,omitempty"` } func (m *VerifyBatchRequest) Reset() { *m = VerifyBatchRequest{} } @@ -303,6 +323,13 @@ func (m *VerifyBatchRequest) XXX_DiscardUnknown() { var xxx_messageInfo_VerifyBatchRequest proto.InternalMessageInfo +func (m *VerifyBatchRequest) GetRollupId() []byte { + if m != nil { + return m.RollupId + } + return nil +} + func (m *VerifyBatchRequest) GetBatchHash() []byte { if m != nil { return m.BatchHash @@ -369,34 +396,36 @@ func init() { func init() { proto.RegisterFile("sequencing/sequencing.proto", fileDescriptor_b389fdbc59f03c95) } var fileDescriptor_b389fdbc59f03c95 = []byte{ - // 430 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x3d, 0x8f, 0xd3, 0x40, - 0x10, 0xb5, 0x81, 0x3b, 0x5d, 0x26, 0x3e, 0x4e, 0xec, 0x21, 0xb0, 0x7c, 0x62, 0x1d, 0x5c, 0xc0, - 0x89, 0x13, 0x8e, 0xe4, 0x6b, 0x68, 0x68, 0xae, 0x81, 0x34, 0x7c, 0x38, 0x11, 0x6d, 0xb4, 0x4e, - 0x36, 0xb1, 0x25, 0xc7, 0x36, 0xde, 0xb1, 0x44, 0xfe, 0x00, 0x35, 0x3f, 0x8b, 0x32, 0x25, 0x25, - 0x4a, 0xfe, 0x08, 0xf2, 0xfa, 0x5b, 0xc1, 0x88, 0xce, 0x7e, 0xf3, 0xe6, 0xcd, 0xbc, 0x37, 0x0b, - 0x57, 0x82, 0x7f, 0xcd, 0x78, 0xb4, 0x08, 0xa2, 0xf5, 0xb8, 0xf9, 0xb4, 0x93, 0x34, 0xc6, 0x98, - 0x40, 0x83, 0x18, 0xe6, 0x3a, 0x8e, 0xd7, 0x21, 0x1f, 0xcb, 0x8a, 0x97, 0xad, 0xc6, 0x18, 0x6c, - 0xb8, 0x40, 0xb6, 0x49, 0x0a, 0xb2, 0xf5, 0x19, 0xe8, 0x34, 0xf3, 0x36, 0x01, 0xba, 0x71, 0x18, - 0x66, 0xc9, 0x2c, 0x65, 0x91, 0x60, 0x0b, 0x0c, 0xe2, 0xc8, 0xcd, 0x55, 0x04, 0x92, 0x2b, 0x18, - 0xa4, 0xb2, 0x36, 0x0f, 0x96, 0xba, 0x3a, 0x52, 0xaf, 0x35, 0xf7, 0xac, 0x00, 0x26, 0x4b, 0x42, - 0xe0, 0xc1, 0x92, 0x21, 0xd3, 0xef, 0x49, 0x5c, 0x7e, 0x5b, 0xcf, 0xc1, 0xec, 0x95, 0x14, 0x49, - 0x1c, 0x09, 0x6e, 0xbd, 0x85, 0xcb, 0x77, 0x1c, 0x3f, 0xf0, 0x6f, 0x78, 0xc7, 0x70, 0xe1, 0x57, - 0xa3, 0x5e, 0xc0, 0x45, 0xc8, 0x04, 0xce, 0xbd, 0x1c, 0x9c, 0xfb, 0x4c, 0xf8, 0xe5, 0xc0, 0xf3, - 0x1c, 0x96, 0xd4, 0xf7, 0x4c, 0xf8, 0xd6, 0x16, 0x1e, 0x77, 0xdb, 0x0b, 0x59, 0xf2, 0x12, 0x4e, - 0x64, 0xab, 0xec, 0x1a, 0x3a, 0x8f, 0xec, 0x56, 0x36, 0x05, 0xb3, 0xa8, 0x93, 0x37, 0x30, 0xa8, - 0x83, 0x90, 0xbb, 0x0f, 0x1d, 0xc3, 0x2e, 0xa2, 0xb2, 0xab, 0xa8, 0xec, 0x59, 0xc5, 0x70, 0x1b, - 0xb2, 0x75, 0x03, 0x27, 0x52, 0x89, 0x58, 0xa0, 0x61, 0xe3, 0x4c, 0xe8, 0xea, 0xe8, 0xfe, 0xb5, - 0xe6, 0x76, 0x30, 0xeb, 0x16, 0xc8, 0x17, 0x9e, 0x06, 0xab, 0x6d, 0xc7, 0xe5, 0x33, 0x80, 0x23, - 0x83, 0x03, 0xaf, 0x36, 0xf7, 0x1a, 0x2e, 0x3b, 0x4d, 0xa5, 0xb7, 0x27, 0x70, 0x2a, 0x90, 0x61, - 0x26, 0x64, 0xc7, 0x99, 0x5b, 0xfe, 0x39, 0xdf, 0x55, 0x78, 0x38, 0x2d, 0x6c, 0xf2, 0x74, 0x12, - 0x25, 0x19, 0x12, 0x84, 0xa7, 0x3d, 0x07, 0x20, 0xaf, 0xda, 0x91, 0xfc, 0xfb, 0xf0, 0xc6, 0xcd, - 0x7f, 0x71, 0xcb, 0x8b, 0x2a, 0xce, 0x0a, 0x2e, 0xea, 0x3d, 0x3e, 0x66, 0x98, 0x2f, 0x32, 0x05, - 0xad, 0x7d, 0x27, 0x62, 0xb6, 0x15, 0xff, 0xf2, 0x00, 0x8c, 0x51, 0x3f, 0xa1, 0x9e, 0xc3, 0xe0, - 0x5c, 0x42, 0x32, 0xa4, 0x80, 0xa7, 0xe4, 0x13, 0x0c, 0x5b, 0x81, 0x11, 0xda, 0xd6, 0x38, 0x8e, - 0xdf, 0x30, 0x7b, 0xeb, 0xd5, 0x88, 0x3b, 0xfd, 0xe7, 0x9e, 0xaa, 0xbb, 0x3d, 0x55, 0x7f, 0xef, - 0xa9, 0xfa, 0xe3, 0x40, 0x95, 0xdd, 0x81, 0x2a, 0xbf, 0x0e, 0x54, 0xf1, 0x4e, 0xe5, 0xeb, 0xb8, - 0xfd, 0x13, 0x00, 0x00, 0xff, 0xff, 0xa0, 0xc1, 0x62, 0x61, 0x81, 0x03, 0x00, 0x00, + // 453 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcf, 0x8f, 0xd2, 0x40, + 0x14, 0xc7, 0x19, 0xf7, 0x47, 0xe0, 0xc1, 0xba, 0x71, 0xd6, 0x68, 0xd3, 0x8d, 0x03, 0xce, 0x41, + 0x89, 0x1b, 0x4b, 0x82, 0x17, 0xcf, 0x5c, 0x74, 0x2f, 0xba, 0x96, 0x8d, 0x57, 0x32, 0x85, 0x01, + 0x9a, 0xf4, 0x97, 0x9d, 0xd7, 0x08, 0xff, 0x80, 0x67, 0xff, 0x2c, 0x8f, 0x7b, 0xf4, 0x68, 0xe0, + 0x1f, 0x31, 0x9d, 0xb6, 0xb4, 0x04, 0x6b, 0xb8, 0xcd, 0xbc, 0xf7, 0xed, 0xf7, 0x3b, 0xfd, 0xbc, + 0x07, 0xd7, 0x4a, 0x7e, 0x4b, 0x64, 0x30, 0x75, 0x83, 0xc5, 0xa0, 0x3c, 0x5a, 0x51, 0x1c, 0x62, + 0x48, 0xa1, 0xac, 0x98, 0xdd, 0x45, 0x18, 0x2e, 0x3c, 0x39, 0xd0, 0x1d, 0x27, 0x99, 0x0f, 0xd0, + 0xf5, 0xa5, 0x42, 0xe1, 0x47, 0x99, 0x98, 0x7f, 0x01, 0x36, 0x4e, 0x1c, 0xdf, 0x45, 0x3b, 0xf4, + 0xbc, 0x24, 0xba, 0x8f, 0x45, 0xa0, 0xc4, 0x14, 0xdd, 0x30, 0xb0, 0x53, 0x17, 0x85, 0xf4, 0x1a, + 0x5a, 0xb1, 0xee, 0x4d, 0xdc, 0x99, 0x41, 0x7a, 0xa4, 0xdf, 0xb1, 0x9b, 0x59, 0xe1, 0x76, 0x46, + 0x29, 0x9c, 0xce, 0x04, 0x0a, 0xe3, 0x91, 0xae, 0xeb, 0x33, 0x7f, 0x09, 0xdd, 0x5a, 0x4b, 0x15, + 0x85, 0x81, 0x92, 0xfc, 0x3b, 0x5c, 0x7d, 0x90, 0xf8, 0x49, 0xae, 0x70, 0x24, 0x70, 0xba, 0x3c, + 0x2a, 0xea, 0x15, 0x5c, 0x7a, 0x42, 0xe1, 0xc4, 0x49, 0xbf, 0x98, 0x2c, 0x85, 0x5a, 0xe6, 0xa9, + 0x17, 0x69, 0x59, 0xfb, 0x7c, 0x14, 0x6a, 0x99, 0x9a, 0xf8, 0x62, 0x35, 0x71, 0xd6, 0x28, 0x95, + 0x71, 0xd2, 0x23, 0xfd, 0x53, 0xbb, 0xe9, 0x8b, 0xd5, 0x28, 0xbd, 0xf3, 0x35, 0x3c, 0xdd, 0x0f, + 0xce, 0x1e, 0x44, 0x5f, 0xc3, 0x99, 0xf6, 0xd5, 0xa9, 0xed, 0xe1, 0x13, 0xab, 0x42, 0x35, 0x53, + 0x66, 0x7d, 0xfa, 0x1e, 0x5a, 0x3b, 0x84, 0x3a, 0xbf, 0x3d, 0x34, 0xad, 0x0c, 0xb2, 0x55, 0x40, + 0xb6, 0xee, 0x0b, 0x85, 0x5d, 0x8a, 0xf9, 0x0d, 0x9c, 0x69, 0x27, 0xca, 0xa1, 0x83, 0x25, 0x13, + 0x65, 0x90, 0xde, 0x49, 0xbf, 0x63, 0xef, 0xd5, 0xf8, 0x1d, 0xd0, 0xaf, 0x32, 0x76, 0xe7, 0xeb, + 0xe3, 0xf9, 0xbc, 0x00, 0x38, 0x40, 0xd3, 0x72, 0x0a, 0x2c, 0xfc, 0x2d, 0x5c, 0xed, 0x39, 0xe6, + 0x3f, 0xfe, 0x0c, 0xce, 0x15, 0x0a, 0x4c, 0x94, 0xf6, 0x6b, 0xda, 0xf9, 0x6d, 0xf8, 0x83, 0xc0, + 0xe3, 0x71, 0xc6, 0x40, 0xc6, 0xb7, 0x41, 0x94, 0x20, 0x45, 0x78, 0x5e, 0x33, 0x57, 0xfa, 0xa6, + 0xca, 0xeb, 0xff, 0xfb, 0x64, 0xde, 0x1c, 0xa5, 0xcd, 0x17, 0xa5, 0x31, 0x9c, 0xc3, 0xe5, 0xee, + 0x1d, 0x9f, 0x13, 0x4c, 0x1f, 0x32, 0x86, 0x4e, 0x75, 0x88, 0xb4, 0x5b, 0x75, 0xfc, 0xc7, 0x5e, + 0x99, 0xbd, 0x7a, 0xc1, 0x2e, 0x47, 0xc0, 0x85, 0x2e, 0x69, 0x48, 0xae, 0x8c, 0xe9, 0x1d, 0xb4, + 0x2b, 0xc0, 0x28, 0xab, 0x7a, 0x1c, 0xce, 0xc6, 0xec, 0xd6, 0xf6, 0x8b, 0x88, 0x91, 0xf1, 0x6b, + 0xc3, 0xc8, 0xc3, 0x86, 0x91, 0x3f, 0x1b, 0x46, 0x7e, 0x6e, 0x59, 0xe3, 0x61, 0xcb, 0x1a, 0xbf, + 0xb7, 0xac, 0xe1, 0x9c, 0xeb, 0xd5, 0x79, 0xf7, 0x37, 0x00, 0x00, 0xff, 0xff, 0x1b, 0xd3, 0x53, + 0x7b, 0xd8, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -712,11 +741,23 @@ func (m *GetNextBatchRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.MaxBytes != 0 { + i = encodeVarintSequencing(dAtA, i, uint64(m.MaxBytes)) + i-- + dAtA[i] = 0x18 + } if len(m.LastBatchHash) > 0 { i -= len(m.LastBatchHash) copy(dAtA[i:], m.LastBatchHash) i = encodeVarintSequencing(dAtA, i, uint64(len(m.LastBatchHash))) i-- + dAtA[i] = 0x12 + } + if len(m.RollupId) > 0 { + i -= len(m.RollupId) + copy(dAtA[i:], m.RollupId) + i = encodeVarintSequencing(dAtA, i, uint64(len(m.RollupId))) + i-- dAtA[i] = 0xa } return len(dAtA) - i, nil @@ -826,6 +867,13 @@ func (m *VerifyBatchRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.BatchHash) i = encodeVarintSequencing(dAtA, i, uint64(len(m.BatchHash))) i-- + dAtA[i] = 0x12 + } + if len(m.RollupId) > 0 { + i -= len(m.RollupId) + copy(dAtA[i:], m.RollupId) + i = encodeVarintSequencing(dAtA, i, uint64(len(m.RollupId))) + i-- dAtA[i] = 0xa } return len(dAtA) - i, nil @@ -907,10 +955,17 @@ func (m *GetNextBatchRequest) Size() (n int) { } var l int _ = l + l = len(m.RollupId) + if l > 0 { + n += 1 + l + sovSequencing(uint64(l)) + } l = len(m.LastBatchHash) if l > 0 { n += 1 + l + sovSequencing(uint64(l)) } + if m.MaxBytes != 0 { + n += 1 + sovSequencing(uint64(m.MaxBytes)) + } return n } @@ -952,6 +1007,10 @@ func (m *VerifyBatchRequest) Size() (n int) { } var l int _ = l + l = len(m.RollupId) + if l > 0 { + n += 1 + l + sovSequencing(uint64(l)) + } l = len(m.BatchHash) if l > 0 { n += 1 + l + sovSequencing(uint64(l)) @@ -1175,6 +1234,40 @@ func (m *GetNextBatchRequest) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RollupId", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSequencing + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSequencing + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSequencing + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RollupId = append(m.RollupId[:0], dAtA[iNdEx:postIndex]...) + if m.RollupId == nil { + m.RollupId = []byte{} + } + iNdEx = postIndex + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field LastBatchHash", wireType) } @@ -1208,6 +1301,25 @@ func (m *GetNextBatchRequest) Unmarshal(dAtA []byte) error { m.LastBatchHash = []byte{} } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxBytes", wireType) + } + m.MaxBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSequencing + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxBytes |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipSequencing(dAtA[iNdEx:]) @@ -1463,6 +1575,40 @@ func (m *VerifyBatchRequest) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RollupId", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSequencing + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSequencing + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSequencing + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RollupId = append(m.RollupId[:0], dAtA[iNdEx:postIndex]...) + if m.RollupId == nil { + m.RollupId = []byte{} + } + iNdEx = postIndex + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field BatchHash", wireType) }