Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial import (CI and code) #1

Merged
merged 3 commits into from
May 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
- package-ecosystem: gomod
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
reviewers:
- liamsi
- tzdybal
labels:
- T:dependencies
50 changes: 50 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Linters
on:
push:
tags:
- v*
branches:
- main
pull_request:

jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: 1.17
- name: golangci-lint
uses: golangci/golangci-lint-action@v3.2.0
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: latest

# Optional: working directory, useful for monorepos
# working-directory: somedir

# Optional: golangci-lint command line arguments.
# args: --issues-exit-code=0

# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true

# Optional: if set to true then the action will use pre-installed Go.
# skip-go-installation: true

# Optional: if set to true then the action don't cache or restore ~/go/pkg.
# skip-pkg-cache: true

# Optional: if set to true then the action don't cache or restore ~/.cache/go-build.
# skip-build-cache: true
markdownlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: markdownlint-cli
uses: nosborn/github-action-markdown-cli@v3.0.1
with:
files: .
config-file: .markdownlint.yaml
31 changes: 31 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Build and Test
on:
push:
tags:
- v*
branches:
- main
pull_request:
jobs:

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.17

- name: Build
run: go build -v ./...

- name: Test & Coverage
run: |
go install github.com/ory/go-acc@v0.2.6
go-acc -o coverage.txt ./... -- -v --race

- uses: codecov/codecov-action@v3
with:
file: ./coverage.txt
9 changes: 9 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
run:
timeout: 5m
modules-download-mode: readonly

linters:
enable:
- gofmt
- goimports
- misspell
7 changes: 7 additions & 0 deletions .markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
default: true
MD010:
code_blocks: false
MD013: false
MD024:
allow_different_nesting: true

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# go-cnc

celestia-node REST client in Go.
121 changes: 121 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package cnc

import (
"context"
"encoding/hex"
"errors"
"fmt"

"github.com/go-resty/resty/v2"
)

type Client struct {
c *resty.Client
}

func NewClient(baseURL string, options ...Option) (*Client, error) {
c := &Client{
c: resty.New(),
}

c.c.SetBaseURL(baseURL)

for _, option := range options {
if err := option(c); err != nil {
return nil, err
}
}

return c, nil
}

func (c *Client) Header(ctx context.Context, height uint64) /* Header */ error {
_ = headerPath()
return errors.New("method Header not implemented")
}

func (c *Client) Balance(ctx context.Context) error {
_ = balanceEndpoint
return errors.New("method Balance not implemented")
}

func (c *Client) SubmitTx(ctx context.Context, tx []byte) /* TxResponse */ error {
_ = submitTxEndpoint
return errors.New("method SubmitTx not implemented")
}

func (c *Client) SubmitPFD(ctx context.Context, namespaceID [8]byte, data []byte, gasLimit uint64) (*TxResponse, error) {
req := SubmitPFDRequest{
NamespaceID: hex.EncodeToString(namespaceID[:]),
Data: hex.EncodeToString(data),
GasLimit: gasLimit,
}
var res TxResponse
var rpcErr string
_, err := c.c.R().
SetContext(ctx).
SetBody(req).
SetResult(&res).
SetError(&rpcErr).
Post(submitPFDEndpoint)
if err != nil {
return nil, err
}
if rpcErr != "" {
return nil, errors.New(rpcErr)
}
return &res, nil
}

func (c *Client) NamespacedShares(ctx context.Context, namespaceID [8]byte, height uint64) ([][]byte, error) {
var res struct {
Shares [][]byte `json:"shares"`
Height uint64 `json:"height"`
}

err := c.callNamespacedEndpoint(ctx, namespaceID, height, namespacedSharesEndpoint, &res)
if err != nil {
return nil, err
}

return res.Shares, nil
}

func (c *Client) NamespacedData(ctx context.Context, namespaceID [8]byte, height uint64) ([][]byte, error) {
var res struct {
Data [][]byte `json:"data"`
Height uint64 `json:"height"`
}

err := c.callNamespacedEndpoint(ctx, namespaceID, height, namespacedDataEndpoint, &res)
if err != nil {
return nil, err
}

return res.Data, nil
}

// callNamespacedEndpoint fetches result of /namespaced_{type} family of endpoints into result (this should be pointer!)
func (c *Client) callNamespacedEndpoint(ctx context.Context, namespaceID [8]byte, height uint64, endpoint string, result interface{}) error {
var rpcErr string
_, err := c.c.R().
SetContext(ctx).
SetResult(result).
SetError(&rpcErr).
Get(namespacedPath(endpoint, namespaceID, height))
if err != nil {
return err
}
if rpcErr != "" {
return errors.New(rpcErr)
}
return nil
}

func headerPath() string {
return fmt.Sprintf("%s/%s", headerEndpoint, heightKey)
}

func namespacedPath(endpoint string, namespaceID [8]byte, height uint64) string {
return fmt.Sprintf("%s/%s/height/%d", endpoint, hex.EncodeToString(namespaceID[:]), height)
}
55 changes: 55 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cnc

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestNewClient(t *testing.T) {
cases := []struct {
name string
options []Option
expectedError error
}{
{"without options", nil, nil},
{"with timeout", []Option{WithTimeout(1 * time.Second)}, nil},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
client, err := NewClient("", c.options...)
assert.ErrorIs(t, err, c.expectedError)
if c.expectedError != nil {
assert.Nil(t, client)
} else {
assert.NotNil(t, client)
}
})
}
}

func TestNamespacedShares(t *testing.T) {
t.Skip()
client, err := NewClient("http://localhost:26658")
assert.NoError(t, err)
assert.NotNil(t, client)

shares, err := client.NamespacedShares(context.TODO(), [8]byte{1, 2, 3, 4, 5, 6, 7, 8}, 8)
assert.NoError(t, err)
assert.NotNil(t, shares)
assert.Len(t, shares, 4)
}

func TestSubmitPDF(t *testing.T) {
t.Skip()
client, err := NewClient("http://localhost:26658", WithTimeout(30*time.Second))
assert.NoError(t, err)
assert.NotNil(t, client)

txRes, err := client.SubmitPFD(context.TODO(), [8]byte{1, 2, 3, 4, 5, 6, 7, 8}, []byte("random data"), 100000)
assert.NoError(t, err)
assert.NotNil(t, txRes)
}
12 changes: 12 additions & 0 deletions consts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package cnc

const (
headerEndpoint = "/header"
balanceEndpoint = "/balance"
submitTxEndpoint = "/submit_tx"
submitPFDEndpoint = "/submit_pfd"
namespacedSharesEndpoint = "/namespaced_shares"
namespacedDataEndpoint = "/namespaced_data"

heightKey = "height"
)
2 changes: 2 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package cnrc implements a Celestia Node REST Client
package cnc
16 changes: 16 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module github.com/celestiaorg/go-cnc

go 1.17

require (
github.com/go-resty/resty/v2 v2.7.0
github.com/gogo/protobuf v1.3.2
github.com/stretchr/testify v1.7.1
)

require (
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/net v0.0.0-20211029224645-99673261e6eb // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
)
50 changes: 50 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
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/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
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.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
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.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
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.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
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=
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.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
12 changes: 12 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package cnc

import "time"

type Option func(*Client) error

func WithTimeout(timeout time.Duration) Option {
return func(c *Client) error {
c.c.SetTimeout(timeout)
return nil
}
}
Loading