Skip to content

Commit

Permalink
refactoring!(share): migrating to go-square v2 types (#3782)
Browse files Browse the repository at this point in the history
Co-authored-by: Rootul P <rootulp@gmail.com>
Co-authored-by: Hlib Kanunnikov <hlibwondertan@gmail.com>
  • Loading branch information
3 people authored Oct 22, 2024
1 parent 1ed2b82 commit 1442cea
Show file tree
Hide file tree
Showing 142 changed files with 1,693 additions and 2,139 deletions.
3 changes: 2 additions & 1 deletion api/docgen/examples.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"github.com/celestiaorg/go-fraud"
libhead "github.com/celestiaorg/go-header"
libshare "github.com/celestiaorg/go-square/v2/share"
"github.com/celestiaorg/rsmt2d"

"github.com/celestiaorg/celestia-node/blob"
Expand Down Expand Up @@ -165,7 +166,7 @@ func init() {

// randomly generated namespace that's used in the blob example above
// (AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMJ/xGlNMdE=)
namespace, err := share.NewBlobNamespaceV0([]byte{0xc2, 0x7f, 0xc4, 0x69, 0x4d, 0x31, 0xd1})
namespace, err := libshare.NewV0Namespace([]byte{0xc2, 0x7f, 0xc4, 0x69, 0x4d, 0x31, 0xd1})
if err != nil {
panic(err)
}
Expand Down
35 changes: 19 additions & 16 deletions api/gateway/share.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ import (

"github.com/gorilla/mux"

"github.com/celestiaorg/go-square/shares"

"github.com/celestiaorg/celestia-node/share"
libshare "github.com/celestiaorg/go-square/v2/share"
)

const (
Expand All @@ -24,8 +22,8 @@ var namespaceKey = "nid"
// NamespacedSharesResponse represents the response to a
// SharesByNamespace request.
type NamespacedSharesResponse struct {
Shares []share.Share `json:"shares"`
Height uint64 `json:"height"`
Shares []libshare.Share `json:"shares"`
Height uint64 `json:"height"`
}

// NamespacedDataResponse represents the response to a
Expand Down Expand Up @@ -90,7 +88,11 @@ func (h *Handler) handleDataByNamespaceRequest(w http.ResponseWriter, r *http.Re
}
}

func (h *Handler) getShares(ctx context.Context, height uint64, namespace share.Namespace) ([]share.Share, error) {
func (h *Handler) getShares(
ctx context.Context,
height uint64,
namespace libshare.Namespace,
) ([]libshare.Share, error) {
header, err := h.header.GetByHeight(ctx, height)
if err != nil {
return nil, err
Expand All @@ -104,12 +106,8 @@ func (h *Handler) getShares(ctx context.Context, height uint64, namespace share.
return shares.Flatten(), nil
}

func dataFromShares(input []share.Share) (data [][]byte, err error) {
appShares, err := shares.FromBytes(input)
if err != nil {
return nil, err
}
sequences, err := shares.ParseShares(appShares, false)
func dataFromShares(input []libshare.Share) (data [][]byte, err error) {
sequences, err := libshare.ParseShares(input, false)
if err != nil {
return nil, err
}
Expand All @@ -123,19 +121,24 @@ func dataFromShares(input []share.Share) (data [][]byte, err error) {
return data, nil
}

func parseGetByNamespaceArgs(r *http.Request) (height uint64, namespace share.Namespace, err error) {
func parseGetByNamespaceArgs(r *http.Request) (height uint64, namespace libshare.Namespace, err error) {
vars := mux.Vars(r)
// if a height was given, parse it, otherwise get namespaced shares/data from the latest header
if strHeight, ok := vars[heightKey]; ok {
height, err = strconv.ParseUint(strHeight, 10, 64)
if err != nil {
return 0, nil, err
return 0, libshare.Namespace{}, err
}
}
hexNamespace := vars[namespaceKey]
namespace, err = hex.DecodeString(hexNamespace)
nsString, err := hex.DecodeString(hexNamespace)
if err != nil {
return 0, libshare.Namespace{}, err
}
ns, err := libshare.NewNamespaceFromBytes(nsString)
if err != nil {
return 0, nil, err
return 0, libshare.Namespace{}, err
}
namespace = ns
return height, namespace, namespace.ValidateForData()
}
23 changes: 8 additions & 15 deletions api/gateway/share_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ import (

"github.com/stretchr/testify/require"

"github.com/celestiaorg/celestia-app/v2/pkg/appconsts"
"github.com/celestiaorg/go-square/blob"
"github.com/celestiaorg/go-square/shares"

"github.com/celestiaorg/celestia-node/share/sharetest"
libshare "github.com/celestiaorg/go-square/v2/share"
)

func Test_dataFromShares(t *testing.T) {
Expand All @@ -20,17 +16,12 @@ func Test_dataFromShares(t *testing.T) {
[]byte("BEEEEAHP"),
}

ns := sharetest.RandV0Namespace()
sss := shares.NewSparseShareSplitter()
ns := libshare.RandomNamespace()
sss := libshare.NewSparseShareSplitter()
for _, data := range testData {
b := blob.Blob{
Data: data,
NamespaceId: ns.ID(),
NamespaceVersion: uint32(ns.Version()),
ShareVersion: uint32(appconsts.ShareVersionZero),
}
err := sss.Write(&b)
b, err := libshare.NewBlob(ns, data, libshare.ShareVersionZero, nil)
require.NoError(t, err)
require.NoError(t, sss.Write(b))
}

sssShares := sss.Export()
Expand All @@ -41,7 +32,9 @@ func Test_dataFromShares(t *testing.T) {
rawSSSShares[i] = d
}

parsedSSSShares, err := dataFromShares(rawSSSShares)
shrs, err := libshare.FromBytes(rawSSSShares)
require.NoError(t, err)
parsedSSSShares, err := dataFromShares(shrs)
require.NoError(t, err)

require.Equal(t, testData, parsedSSSShares)
Expand Down
111 changes: 53 additions & 58 deletions blob/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,20 @@ import (
"errors"
"fmt"

"github.com/tendermint/tendermint/crypto/merkle"

"github.com/celestiaorg/celestia-app/v2/pkg/appconsts"
v2 "github.com/celestiaorg/celestia-app/v2/pkg/appconsts/v2"
"github.com/celestiaorg/go-square/blob"
"github.com/celestiaorg/go-square/inclusion"
"github.com/celestiaorg/go-square/shares"
"github.com/celestiaorg/celestia-app/v3/pkg/appconsts"
"github.com/celestiaorg/go-square/merkle"
"github.com/celestiaorg/go-square/v2/inclusion"
libshare "github.com/celestiaorg/go-square/v2/share"
"github.com/celestiaorg/nmt"

"github.com/celestiaorg/celestia-node/share"
)

// appVersion is the current application version of celestia-app.
const appVersion = v2.Version
const appVersion = appconsts.LatestVersion

var errEmptyShares = errors.New("empty shares")

var subtreeRootThreshold = appconsts.SubtreeRootThreshold(appVersion)

// The Proof is a set of nmt proofs that can be verified only through
// the included method (due to limitation of the nmt https://github.com/celestiaorg/nmt/issues/218).
// Proof proves the WHOLE namespaced data to the row roots.
Expand Down Expand Up @@ -61,51 +58,52 @@ func (p Proof) equal(input Proof) error {

// Blob represents any application-specific binary data that anyone can submit to Celestia.
type Blob struct {
*blob.Blob `json:"blob"`
*libshare.Blob `json:"blob"`

Commitment Commitment `json:"commitment"`

// the celestia-node's namespace type
// this is to avoid converting to and from app's type
namespace share.Namespace

// index represents the index of the blob's first share in the EDS.
// Only retrieved, on-chain blobs will have the index set. Default is -1.
index int
}

// NewBlobV0 constructs a new blob from the provided Namespace and data.
// The blob will be formatted as v0 shares.
func NewBlobV0(namespace share.Namespace, data []byte) (*Blob, error) {
return NewBlob(appconsts.ShareVersionZero, namespace, data)
func NewBlobV0(namespace libshare.Namespace, data []byte) (*Blob, error) {
return NewBlob(libshare.ShareVersionZero, namespace, data, nil)
}

// NewBlob constructs a new blob from the provided Namespace, data and share version.
func NewBlob(shareVersion uint8, namespace share.Namespace, data []byte) (*Blob, error) {
// NewBlobV1 constructs a new blob from the provided Namespace, data, and signer.
// The blob will be formatted as v1 shares.
func NewBlobV1(namespace libshare.Namespace, data, signer []byte) (*Blob, error) {
return NewBlob(libshare.ShareVersionOne, namespace, data, signer)
}

// NewBlob constructs a new blob from the provided Namespace, data, signer, and share version.
func NewBlob(shareVersion uint8, namespace libshare.Namespace, data, signer []byte) (*Blob, error) {
if len(data) == 0 || len(data) > appconsts.DefaultMaxBytes {
return nil, fmt.Errorf("blob data must be > 0 && <= %d, but it was %d bytes", appconsts.DefaultMaxBytes, len(data))
}

if err := namespace.ValidateForBlob(); err != nil {
return nil, err
return nil, fmt.Errorf("invalid user namespace: %w", err)
}

blob := blob.Blob{
NamespaceId: namespace.ID(),
Data: data,
ShareVersion: uint32(shareVersion),
NamespaceVersion: uint32(namespace.Version()),
libBlob, err := libshare.NewBlob(namespace, data, shareVersion, signer)
if err != nil {
return nil, err
}

com, err := inclusion.CreateCommitment(&blob, merkle.HashFromByteSlices, appconsts.SubtreeRootThreshold(appVersion))
com, err := inclusion.CreateCommitment(libBlob, merkle.HashFromByteSlices, subtreeRootThreshold)
if err != nil {
return nil, err
}
return &Blob{Blob: &blob, Commitment: com, namespace: namespace, index: -1}, nil
return &Blob{Blob: libBlob, Commitment: com, index: -1}, nil
}

// Namespace returns blob's namespace.
func (b *Blob) Namespace() share.Namespace {
return b.namespace
func (b *Blob) Namespace() libshare.Namespace {
return b.Blob.Namespace()
}

// Index returns the blob's first share index in the EDS.
Expand All @@ -124,38 +122,34 @@ func (b *Blob) Length() (int, error) {
if len(s) == 0 {
return 0, errors.New("blob with zero shares received")
}
return libshare.SparseSharesNeeded(s[0].SequenceLen()), nil
}

appShare, err := shares.NewShare(s[0])
if err != nil {
return 0, err
}

seqLength, err := appShare.SequenceLen()
if err != nil {
return 0, err
}

return shares.SparseSharesNeeded(seqLength), nil
// Signer returns blob's author.
func (b *Blob) Signer() []byte {
return b.Blob.Signer()
}

func (b *Blob) compareCommitments(com Commitment) bool {
return bytes.Equal(b.Commitment, com)
}

type jsonBlob struct {
Namespace share.Namespace `json:"namespace"`
Data []byte `json:"data"`
ShareVersion uint32 `json:"share_version"`
Commitment Commitment `json:"commitment"`
Index int `json:"index"`
Namespace []byte `json:"namespace"`
Data []byte `json:"data"`
ShareVersion uint8 `json:"share_version"`
Commitment Commitment `json:"commitment"`
Signer []byte `json:"signer,omitempty"`
Index int `json:"index"`
}

func (b *Blob) MarshalJSON() ([]byte, error) {
blob := &jsonBlob{
Namespace: b.Namespace(),
Data: b.Data,
ShareVersion: b.ShareVersion,
Namespace: b.Namespace().Bytes(),
Data: b.Data(),
ShareVersion: b.ShareVersion(),
Commitment: b.Commitment,
Signer: b.Signer(),
Index: b.index,
}
return json.Marshal(blob)
Expand All @@ -168,17 +162,18 @@ func (b *Blob) UnmarshalJSON(data []byte) error {
return err
}

if len(jsonBlob.Namespace) == 0 {
return errors.New("expected a non-empty namespace")
ns, err := libshare.NewNamespaceFromBytes(jsonBlob.Namespace)
if err != nil {
return err
}

blob, err := NewBlob(jsonBlob.ShareVersion, ns, jsonBlob.Data, jsonBlob.Signer)
if err != nil {
return err
}

b.Blob = &blob.Blob{}
b.Blob.NamespaceVersion = uint32(jsonBlob.Namespace.Version())
b.Blob.NamespaceId = jsonBlob.Namespace.ID()
b.Blob.Data = jsonBlob.Data
b.Blob.ShareVersion = jsonBlob.ShareVersion
b.Commitment = jsonBlob.Commitment
b.namespace = jsonBlob.Namespace
b.index = jsonBlob.Index
blob.Commitment = jsonBlob.Commitment
blob.index = jsonBlob.Index
*b = *blob
return nil
}
6 changes: 3 additions & 3 deletions blob/blob_fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"path/filepath"
"testing"

"github.com/celestiaorg/celestia-node/blob/blobtest"
libshare "github.com/celestiaorg/go-square/v2/share"
)

func FuzzProofEqual(f *testing.F) {
Expand All @@ -15,12 +15,12 @@ func FuzzProofEqual(f *testing.F) {
}

// 1. Generate the corpus.
squareBlobs, err := blobtest.GenerateV0Blobs([]int{16}, false)
libBlobs, err := libshare.GenerateV0Blobs([]int{16}, false)
if err != nil {
f.Fatal(err)
}

blobs, err := convertBlobs(squareBlobs...)
blobs, err := convertBlobs(libBlobs...)
if err != nil {
f.Fatal(err)
}
Expand Down
Loading

0 comments on commit 1442cea

Please sign in to comment.