Skip to content

Commit

Permalink
extend api to include rollup id, add Hash function to Batch, add maxB…
Browse files Browse the repository at this point in the history
…ytes
  • Loading branch information
gupadhyaya committed Oct 1, 2024
1 parent 0098194 commit 50fe9a6
Show file tree
Hide file tree
Showing 10 changed files with 419 additions and 82 deletions.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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.0
)

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
)
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -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=
Expand All @@ -16,3 +22,7 @@ google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
google.golang.org/grpc v1.67.0/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=
10 changes: 8 additions & 2 deletions proto/sequencing/sequencing.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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 ...
Expand All @@ -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
Expand Down
29 changes: 15 additions & 14 deletions proxy/grpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package grpc

import (
"context"
"time"

"google.golang.org/grpc"

Expand Down Expand Up @@ -46,34 +45,36 @@ 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.RollupId,
})
return err
return nil, err
}

// 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{}
12 changes: 6 additions & 6 deletions proxy/grpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
}
40 changes: 37 additions & 3 deletions sequencing.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ 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
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
// 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)
VerifyBatch(ctx context.Context, req VerifyBatchRequest) (*VerifyBatchResponse, error)
}

// RollupId is a unique identifier for a rollup chain
Expand All @@ -45,3 +45,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
}
11 changes: 11 additions & 0 deletions serialization.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package sequencing

import (
"crypto/sha256"

pbseq "github.com/rollkit/go-sequencing/types/pb/sequencing"
)

Expand Down Expand Up @@ -46,3 +48,12 @@ func (batch *Batch) Unmarshal(data []byte) error {
batch.FromProto(&pb)
return nil
}

func (batch *Batch) Hash() ([]byte, error) {

Check failure on line 52 in serialization.go

View workflow job for this annotation

GitHub Actions / lint / golangci-lint

exported: exported method Batch.Hash should have comment or be unexported (revive)
batchBytes, err := batch.Marshal()
if err != nil {
return nil, err
}
hash := sha256.Sum256(batchBytes)
return hash[:], nil
}
49 changes: 22 additions & 27 deletions test/dummy.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package test
import (
"bytes"
"context"
"crypto/sha256"
"errors"
"sync"
"time"
Expand Down Expand Up @@ -59,53 +58,54 @@ type DummySequencer struct {
}

// SubmitRollupTransaction implements sequencing.Sequencer.
func (d *DummySequencer) SubmitRollupTransaction(ctx context.Context, rollupId []byte, tx []byte) error {
func (d *DummySequencer) SubmitRollupTransaction(ctx context.Context, req sequencing.SubmitRollupTransactionRequest) (*sequencing.SubmitRollupTransactionResponse, error) {
if d.RollupId == nil {
d.RollupId = rollupId
d.RollupId = req.RollupId
} else {
if !bytes.Equal(d.RollupId, rollupId) {
return ErrorRollupIdMismatch
if !bytes.Equal(d.RollupId, req.RollupId) {
return nil, ErrorRollupIdMismatch
}
}
d.tq.AddTransaction(tx)
return nil
d.tq.AddTransaction(req.Tx)
return nil, 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) {
now := time.Now()
if d.lastBatchHash == nil {
if lastBatchHash != nil {
return nil, now, errors.New("lastBatch is supposed to be nil")
if req.LastBatchHash != nil {
return nil, 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 req.LastBatchHash == nil {
return nil, 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")
if !bytes.Equal(d.lastBatchHash, req.LastBatchHash) {
return nil, errors.New("supplied lastBatch does not match with sequencer last batch")
}
}

batch := d.tq.GetNextBatch()
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.lastBatchHash = h
d.seenBatches[string(d.lastBatchHash)] = struct{}{}
return batch, now, nil
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) {
_, ok := d.seenBatches[string(req.BatchHash)]
return &sequencing.VerifyBatchResponse{Status: ok}, nil
}

// NewDummySequencer creates a new DummySequencer
Expand All @@ -116,9 +116,4 @@ func NewDummySequencer() *DummySequencer {
}
}

func hashSHA256(data []byte) []byte {
hash := sha256.Sum256(data)
return hash[:]
}

var _ sequencing.Sequencer = &DummySequencer{}
Loading

0 comments on commit 50fe9a6

Please sign in to comment.