Skip to content

Commit

Permalink
feat: gRPC proxy (#14)
Browse files Browse the repository at this point in the history
* feat: gRPC definitions for DA interface
* chore: improve protobuf generation
* test: make test suite publicly visible
* feat: initial gRPC proxy implementation
* lint: fix linter errors
* chore: go mod tidy
* fix: add package directive to protobuf file
* ci: use group number instead of name for docker
  • Loading branch information
tzdybal authored Oct 24, 2023
1 parent 6bd21b7 commit 57bc360
Show file tree
Hide file tree
Showing 15 changed files with 3,686 additions and 135 deletions.
15 changes: 6 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ cover:
deps:
@echo "--> Installing dependencies"
@go mod download
# @make proto-gen
@make proto-gen
@go mod tidy
.PHONY: deps

Expand Down Expand Up @@ -65,17 +65,14 @@ test: vet
@go test -v -race -covermode=atomic -coverprofile=coverage.txt $(pkgs) -run $(run) -count=$(count)
.PHONY: test

# protobuf related targets will be uncommented while working on https://github.com/rollkit/go-da/issues/5

## proto-gen: Generate protobuf files. Requires docker.
proto-gen:
@echo "--> Generating Protobuf files"
# ./proto/get_deps.sh
# ./proto/gen.sh
#.PHONY: proto-gen
#
./proto/gen.sh
.PHONY: proto-gen

## proto-lint: Lint protobuf files. Requires docker.
proto-lint:
@echo "--> Linting Protobuf files"
# @$(DOCKER_BUF) lint --error-format=json
#.PHONY: proto-lint
@$(DOCKER_BUF) lint --error-format=json
.PHONY: proto-lint
10 changes: 10 additions & 0 deletions buf.gen.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: v1beta1

# The plugins to run.
plugins:
# The name of the plugin.
- name: gogofaster
# The the relative output directory.
out: types/pb
# Any options to provide to the plugin.
opt: plugins=grpc,paths=source_relative
27 changes: 27 additions & 0 deletions buf.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
version: v1beta1

build:
roots:
- proto
- third_party/proto
lint:
use:
- DEFAULT
- COMMENTS
- FILE_LOWER_SNAKE_CASE
except:
- COMMENT_ENUM
- COMMENT_ENUM_VALUE
- COMMENT_MESSAGE
- COMMENT_RPC
- COMMENT_SERVICE
- COMMENT_FIELD
- PACKAGE_VERSION_SUFFIX
- RPC_REQUEST_STANDARD_NAME
- SERVICE_SUFFIX
- UNARY_RPC
ignore:
- tendermint
breaking:
use:
- FILE
126 changes: 1 addition & 125 deletions da_test.go
Original file line number Diff line number Diff line change
@@ -1,136 +1,12 @@
package da_test

import (
"bytes"
"testing"
"time"

"github.com/rollkit/go-da/test"

"github.com/stretchr/testify/assert"

"github.com/rollkit/go-da"
)

func TestDummyDA(t *testing.T) {
dummy := test.NewDummyDA()
RunDATestSuite(t, dummy)
}

func RunDATestSuite(t *testing.T, dummy *test.DummyDA) {
t.Run("Basic DA test", func(t *testing.T) {
BasicDATest(t, dummy)
})
t.Run("Get IDs and all data", func(t *testing.T) {
GetIDsTest(t, dummy)
})
t.Run("Check Errors", func(t *testing.T) {
CheckErrors(t, dummy)
})
}

// TODO(tzdybal): how to get rid of this?!
type Blob = da.Blob
type ID = da.ID

func BasicDATest(t *testing.T, da da.DA) {
msg1 := []byte("message 1")
msg2 := []byte("message 2")

id1, proof1, err := da.Submit([]Blob{msg1})
assert.NoError(t, err)
assert.NotEmpty(t, id1)
assert.NotEmpty(t, proof1)

id2, proof2, err := da.Submit([]Blob{msg2})
assert.NoError(t, err)
assert.NotEmpty(t, id2)
assert.NotEmpty(t, proof2)

id3, proof3, err := da.Submit([]Blob{msg1})
assert.NoError(t, err)
assert.NotEmpty(t, id3)
assert.NotEmpty(t, proof3)

assert.NotEqual(t, id1, id2)
assert.NotEqual(t, id1, id3)

ret, err := da.Get(id1)
assert.NoError(t, err)
assert.Equal(t, []Blob{msg1}, ret)

commitment1, err := da.Commit([]Blob{msg1})
assert.NoError(t, err)
assert.NotEmpty(t, commitment1)

commitment2, err := da.Commit([]Blob{msg2})
assert.NoError(t, err)
assert.NotEmpty(t, commitment2)

oks, err := da.Validate(id1, proof1)
assert.NoError(t, err)
assert.NotEmpty(t, oks)
for _, ok := range oks {
assert.True(t, ok)
}

oks, err = da.Validate(id2, proof2)
assert.NoError(t, err)
assert.NotEmpty(t, oks)
for _, ok := range oks {
assert.True(t, ok)
}

oks, err = da.Validate(id1, proof2)
assert.NoError(t, err)
assert.NotEmpty(t, oks)
for _, ok := range oks {
assert.False(t, ok)
}

oks, err = da.Validate(id2, proof1)
assert.NoError(t, err)
assert.NotEmpty(t, oks)
for _, ok := range oks {
assert.False(t, ok)
}
}

func CheckErrors(t *testing.T, da da.DA) {
blob, err := da.Get([]ID{[]byte("invalid")})
assert.Error(t, err)
assert.Empty(t, blob)
}

func GetIDsTest(t *testing.T, da da.DA) {
msgs := [][]byte{[]byte("msg1"), []byte("msg2"), []byte("msg3")}

ids, proofs, err := da.Submit(msgs)
assert.NoError(t, err)
assert.Len(t, ids, len(msgs))
assert.Len(t, proofs, len(msgs))

found := false
end := time.Now().Add(1 * time.Second)
for i := uint64(1); !found && !time.Now().After(end); i++ {
ret, err := da.GetIDs(i)
if err != nil {
t.Error("failed to get IDs:", err)
}
if len(ret) > 0 {
blobs, err := da.Get(ret)
assert.NoError(t, err)

if len(blobs) == len(msgs) {
found = true
for b := 0; b < len(blobs); b++ {
if !bytes.Equal(blobs[b], msgs[b]) {
found = false
}
}
}
}
}

assert.True(t, found)
test.RunDATestSuite(t, dummy)
}
12 changes: 11 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@ module github.com/rollkit/go-da

go 1.21.1

require github.com/stretchr/testify v1.8.4
require (
github.com/gogo/protobuf v1.3.2
github.com/stretchr/testify v1.8.4
google.golang.org/grpc v1.58.3
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
51 changes: 51 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,60 @@
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/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
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.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
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=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
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=
Expand Down
92 changes: 92 additions & 0 deletions proto/da/da.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
syntax = "proto3";
package da;

// DAService is the protobuf service definition for interaction with Data Availability layers.
service DAService {
// Get returns Blob for each given ID, or an error.
rpc Get(GetRequest) returns (GetResponse) {}

// GetIDs returns IDs of all Blobs located in DA at given height.
rpc GetIDs(GetIDsRequest) returns (GetIDsResponse) {}

// Commit creates a Commitment for each given Blob.
rpc Commit(CommitRequest) returns (CommitResponse) {}

// Submit submits the given Blobs to Data Availability layer.
rpc Submit(SubmitRequest) returns (SubmitResponse) {}

// Validate validates Commitments against corresponding Proofs. This should be possible without retrieving Blob.
rpc Validate(ValidateRequest) returns (ValidateResponse) {}
}

// Blob is the data submitted/received from DA interface.
message Blob {
bytes value = 1;
}

// ID should contain serialized data required by the implementation to find blob in Data Availability layer.
message ID {
bytes value = 1;
}

// Commitment should contain serialized cryptographic commitment to Blob value.
message Commitment {
bytes value = 1;
}

// Proof should contain serialized proof of inclusion (publication) of Blob in Data Availability layer.
message Proof {
bytes value = 1;
}

// GetRequest is the request type for the Get rpc method.
message GetRequest {
repeated ID ids = 1;
}

// GetResponse is the response type for the Get rpc method.
message GetResponse {
repeated Blob blobs = 1;
}

// GetIDsRequest is the request type for the GetIDs rpc method.
message GetIDsRequest {
uint64 height = 1;
}

// GetIDsResponse is the response type for the GetIDs rpc method.
message GetIDsResponse {
repeated ID ids = 1;
}

// CommitRequest is the request type for the Commit rpc method.
message CommitRequest {
repeated Blob blobs = 1;
}

// CommitResponse is the response type for the Commit rpc method.
message CommitResponse {
repeated Commitment commitments = 1;
}

// SubmitRequest is the request type for the Submit rpc method.
message SubmitRequest {
repeated Blob blobs = 1;
}

// SubmitResponse is the response type for the Submit rpc method.
message SubmitResponse {
repeated ID ids = 1;
repeated Proof proofs = 2;
}

// ValidateRequest is the request type for the Validate rpc method.
message ValidateRequest {
repeated ID ids = 1;
repeated Proof proofs = 2;
}

// ValidateResponse is the response type for the Validate rpc method.
message ValidateResponse {
repeated bool results = 1;
}
10 changes: 10 additions & 0 deletions proto/gen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

# see: https://stackoverflow.com/a/246128
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"/..
TARGET_DIR=./types/pb

cd $SCRIPT_DIR
mkdir -p $TARGET_DIR
rm -rf $TARGET_DIR/*
docker run -u $UID:$(id -g) -e XDG_CACHE_HOME=/tmp/.cache -v $PWD:/workspace --workdir /workspace tendermintdev/docker-build-proto sh ./proto/protoc.sh
Loading

0 comments on commit 57bc360

Please sign in to comment.