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

feat(nodebuilder/da): implement go-da v0.6.1 changes #3750

Merged
merged 10 commits into from
Oct 2, 2024
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ require (
github.com/multiformats/go-multihash v0.2.3
github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333
github.com/prometheus/client_golang v1.20.0
github.com/rollkit/go-da v0.5.0
github.com/rollkit/go-da v0.8.0
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0
Expand All @@ -74,7 +74,7 @@ require (
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa
golang.org/x/sync v0.8.0
golang.org/x/text v0.17.0
google.golang.org/grpc v1.65.0
google.golang.org/grpc v1.66.2
google.golang.org/protobuf v1.34.2
)

Expand Down Expand Up @@ -116,7 +116,7 @@ require (
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gogoproto v1.5.0 // indirect
github.com/cosmos/gogoproto v1.7.0 // indirect
github.com/cosmos/gorocksdb v1.2.0 // indirect
github.com/cosmos/iavl v0.19.6 // indirect
github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v6 v6.1.2 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,8 @@ github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRAp
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
github.com/cosmos/gogoproto v1.5.0 h1:SDVwzEqZDDBoslaeZg+dGE55hdzHfgUA40pEanMh52o=
github.com/cosmos/gogoproto v1.5.0/go.mod h1:iUM31aofn3ymidYG6bUR5ZFrk+Om8p5s754eMUcyp8I=
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/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y=
github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw=
github.com/cosmos/iavl v0.19.6 h1:XY78yEeNPrEYyNCKlqr9chrwoeSDJ0bV2VjocTk//OU=
Expand Down Expand Up @@ -1688,8 +1688,8 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rollkit/go-da v0.5.0 h1:sQpZricNS+2TLx3HMjNWhtRfqtvVC/U4pWHpfUz3eN4=
github.com/rollkit/go-da v0.5.0/go.mod h1:VsUeAoPvKl4Y8wWguu/VibscYiFFePkkrvZWyTjZHww=
github.com/rollkit/go-da v0.8.0 h1:oJKojC421eRC4mNqbujf40GzLFNp7HapgeB7Z/r0tyc=
github.com/rollkit/go-da v0.8.0/go.mod h1:3eHWK5gkv8lhwq6bjOZOi82WwHyS2B9rQOlUrE1GGws=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo=
github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
Expand Down Expand Up @@ -2694,8 +2694,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo=
google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
Expand Down
27 changes: 19 additions & 8 deletions nodebuilder/da/da.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ type Module interface {
// TODO(@distractedm1nd): These structs need to be autogenerated.
type API struct {
Internal struct {
MaxBlobSize func(ctx context.Context) (uint64, error) `perm:"read"`
Get func(ctx context.Context, ids []da.ID, ns da.Namespace) ([]da.Blob, error) `perm:"read"`
GetIDs func(ctx context.Context, height uint64, ns da.Namespace) ([]da.ID, error) `perm:"read"`
GetProofs func(ctx context.Context, ids []da.ID, ns da.Namespace) ([]da.Proof, error) `perm:"read"`
Commit func(ctx context.Context, blobs []da.Blob, ns da.Namespace) ([]da.Commitment, error) `perm:"read"`
Validate func(context.Context, []da.ID, []da.Proof, da.Namespace) ([]bool, error) `perm:"read"`
Submit func(context.Context, []da.Blob, float64, da.Namespace) ([]da.ID, error) `perm:"write"`
MaxBlobSize func(ctx context.Context) (uint64, error) `perm:"read"`
Get func(ctx context.Context, ids []da.ID, ns da.Namespace) ([]da.Blob, error) `perm:"read"`
GetIDs func(ctx context.Context, height uint64, ns da.Namespace) (*da.GetIDsResult, error) `perm:"read"`
GetProofs func(ctx context.Context, ids []da.ID, ns da.Namespace) ([]da.Proof, error) `perm:"read"`
Commit func(ctx context.Context, blobs []da.Blob, ns da.Namespace) ([]da.Commitment, error) `perm:"read"`
Validate func(context.Context, []da.ID, []da.Proof, da.Namespace) ([]bool, error) `perm:"read"`
Submit func(context.Context, []da.Blob, float64, da.Namespace) ([]da.ID, error) `perm:"write"`
SubmitWithOptions func(context.Context, []da.Blob, float64, da.Namespace, []byte) ([]da.ID, error) `perm:"write"`
}
}

Expand All @@ -33,7 +34,7 @@ func (api *API) Get(ctx context.Context, ids []da.ID, ns da.Namespace) ([]da.Blo
return api.Internal.Get(ctx, ids, ns)
}

func (api *API) GetIDs(ctx context.Context, height uint64, ns da.Namespace) ([]da.ID, error) {
func (api *API) GetIDs(ctx context.Context, height uint64, ns da.Namespace) (*da.GetIDsResult, error) {
return api.Internal.GetIDs(ctx, height, ns)
}

Expand All @@ -52,3 +53,13 @@ func (api *API) Validate(ctx context.Context, ids []da.ID, proofs []da.Proof, ns
func (api *API) Submit(ctx context.Context, blobs []da.Blob, gasPrice float64, ns da.Namespace) ([]da.ID, error) {
return api.Internal.Submit(ctx, blobs, gasPrice, ns)
}

func (api *API) SubmitWithOptions(
ctx context.Context,
blobs []da.Blob,
gasPrice float64,
ns da.Namespace,
options []byte,
) ([]da.ID, error) {
return api.Internal.SubmitWithOptions(ctx, blobs, gasPrice, ns, options)
}
82 changes: 74 additions & 8 deletions nodebuilder/da/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/celestiaorg/celestia-app/v2/pkg/appconsts"

"github.com/celestiaorg/celestia-node/blob"
"github.com/celestiaorg/celestia-node/header"
nodeblob "github.com/celestiaorg/celestia-node/nodebuilder/blob"
"github.com/celestiaorg/celestia-node/share"
"github.com/celestiaorg/celestia-node/state"
Expand All @@ -28,12 +29,32 @@ var log = logging.Logger("go-da")
const heightLen = 8

type Service struct {
blobServ nodeblob.Module
blobServ nodeblob.Module
headerGetter func(context.Context, uint64) (*header.ExtendedHeader, error)
}

func NewService(blobMod nodeblob.Module) *Service {
// SubmitOptions defines options for blob submission using SubmitWithOptions.
//
// SubmitWithOptions expects JSON serialized version of this struct; all fields are optional.
type SubmitOptions struct {
// KeyName is the name of key from the keystore used to sign transactions.
KeyName string `json:"key_name,omitempty"`

// SignerAddress is the address that signs the transaction.
// This address must be stored locally in the key store.
SignerAddress string `json:"signer_address,omitempty"`

// FeeGranterAddress specifies the account that will pay for the transaction fee.
FeeGranterAddress string `json:"fee_granter_address,omitempty"`
}

func NewService(
blobMod nodeblob.Module,
headerGetter func(context.Context, uint64) (*header.ExtendedHeader, error),
) *Service {
return &Service{
blobServ: blobMod,
blobServ: blobMod,
headerGetter: headerGetter,
}
}

Expand All @@ -59,21 +80,25 @@ func (s *Service) Get(ctx context.Context, ids []da.ID, ns da.Namespace) ([]da.B
}

// GetIDs returns IDs of all Blobs located in DA at given height.
func (s *Service) GetIDs(ctx context.Context, height uint64, namespace da.Namespace) ([]da.ID, error) {
func (s *Service) GetIDs(ctx context.Context, height uint64, namespace da.Namespace) (*da.GetIDsResult, error) {
var ids []da.ID //nolint:prealloc
log.Debugw("getting ids", "height", height, "namespace", share.Namespace(namespace))
blobs, err := s.blobServ.GetAll(ctx, height, []share.Namespace{namespace})
log.Debugw("got ids", "height", height, "namespace", share.Namespace(namespace))
if err != nil {
if strings.Contains(err.Error(), blob.ErrBlobNotFound.Error()) {
return nil, nil
return nil, nil //nolint:nilnil
}
return nil, err
}
for _, b := range blobs {
ids = append(ids, MakeID(height, b.Commitment))
}
return ids, nil
h, err := s.headerGetter(ctx, height)
if err != nil {
return nil, err
}
return &da.GetIDsResult{IDs: ids, Timestamp: h.Time()}, nil
}

// GetProofs returns inclusion Proofs for all Blobs located in DA at given height.
Expand Down Expand Up @@ -105,15 +130,31 @@ func (s *Service) Submit(
daBlobs []da.Blob,
gasPrice float64,
namespace da.Namespace,
) ([]da.ID, error) {
return s.SubmitWithOptions(ctx, daBlobs, gasPrice, namespace, nil)
}

// SubmitWithOptions submits the Blobs to Data Availability layer.
func (s *Service) SubmitWithOptions(
ctx context.Context,
daBlobs []da.Blob,
gasPrice float64,
namespace da.Namespace,
options []byte,
) ([]da.ID, error) {
blobs, _, err := s.blobsAndCommitments(daBlobs, namespace)
if err != nil {
return nil, err
}

opts := state.NewTxConfig(state.WithGasPrice(gasPrice))
opts, err := parseOptions(options)
if err != nil {
return nil, err
}
opts = append(opts, state.WithGasPrice(gasPrice))
cfg := state.NewTxConfig(opts...)

height, err := s.blobServ.Submit(ctx, blobs, opts)
height, err := s.blobServ.Submit(ctx, blobs, cfg)
if err != nil {
log.Error("failed to submit blobs", "height", height, "gas price", gasPrice)
return nil, err
Expand All @@ -126,6 +167,31 @@ func (s *Service) Submit(
return ids, nil
}

func parseOptions(options []byte) ([]state.ConfigOption, error) {
var opts []state.ConfigOption

if len(options) == 0 {
return opts, nil
}

parsedOpts := SubmitOptions{}
err := json.Unmarshal(options, &parsedOpts)
if err != nil {
return nil, err
}

if parsedOpts.KeyName != "" {
opts = append(opts, state.WithKeyName(parsedOpts.KeyName))
}
if parsedOpts.SignerAddress != "" {
opts = append(opts, state.WithSignerAddress(parsedOpts.SignerAddress))
}
if parsedOpts.FeeGranterAddress != "" {
opts = append(opts, state.WithFeeGranterAddress(parsedOpts.FeeGranterAddress))
}
return opts, nil
}

// blobsAndCommitments converts []da.Blob to []*blob.Blob and generates corresponding
// []da.Commitment
func (s *Service) blobsAndCommitments(
Expand Down
37 changes: 30 additions & 7 deletions nodebuilder/tests/da_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ func TestDaModule(t *testing.T) {
{
name: "GetProofs + Validate",
doFn: func(t *testing.T) {
t.Skip()
h, _ := da.SplitID(ids[0])
lightClient.Header.WaitForHeight(ctx, h)
proofs, err := lightClient.DA.GetProofs(ctx, ids, namespace)
Expand All @@ -105,11 +104,13 @@ func TestDaModule(t *testing.T) {
{
name: "GetIDs",
doFn: func(t *testing.T) {
t.Skip()
cristaloleg marked this conversation as resolved.
Show resolved Hide resolved
height, _ := da.SplitID(ids[0])
ids2, err := fullClient.DA.GetIDs(ctx, height, namespace)
result, err := fullClient.DA.GetIDs(ctx, height, namespace)
require.NoError(t, err)
require.EqualValues(t, ids, ids2)
require.EqualValues(t, ids, result.IDs)
header, err := lightClient.Header.GetByHeight(ctx, height)
require.NoError(t, err)
require.EqualValues(t, header.Time(), result.Timestamp)
},
},
{
Expand All @@ -128,8 +129,7 @@ func TestDaModule(t *testing.T) {
{
name: "Commit",
doFn: func(t *testing.T) {
t.Skip()
fetched, err := fullClient.DA.Commit(ctx, ids, namespace)
fetched, err := fullClient.DA.Commit(ctx, daBlobs, namespace)
require.NoError(t, err)
require.Len(t, fetched, len(ids))
for i := range fetched {
Expand All @@ -138,10 +138,33 @@ func TestDaModule(t *testing.T) {
}
},
},
{
name: "SubmitWithOptions - valid",
doFn: func(t *testing.T) {
ids, err := fullClient.DA.SubmitWithOptions(ctx, daBlobs, -1, namespace, []byte(`{"key_name": "validator"}`))
require.NoError(t, err)
require.NotEmpty(t, ids)
},
},
{
name: "SubmitWithOptions - invalid JSON",
doFn: func(t *testing.T) {
ids, err := fullClient.DA.SubmitWithOptions(ctx, daBlobs, -1, namespace, []byte("not JSON"))
require.Error(t, err)
require.Nil(t, ids)
},
},
{
name: "SubmitWithOptions - invalid key name",
doFn: func(t *testing.T) {
ids, err := fullClient.DA.SubmitWithOptions(ctx, daBlobs, -1, namespace, []byte(`{"key_name": "invalid"}`))
require.Error(t, err)
require.Nil(t, ids)
},
},
}

for _, tt := range test {
tt := tt
t.Run(tt.name, func(t *testing.T) {
tt.doFn(t)
})
Expand Down
Loading