Skip to content

Commit

Permalink
feat(blob): add marshaling for blob and proof (#2286)
Browse files Browse the repository at this point in the history
  • Loading branch information
vgonkivs committed Jun 1, 2023
1 parent d53efbd commit 135622a
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 2 deletions.
6 changes: 6 additions & 0 deletions api/docgen/examples.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ import (
"golang.org/x/text/language"

"github.com/celestiaorg/go-fraud"
"github.com/celestiaorg/nmt"
"github.com/celestiaorg/rsmt2d"

"github.com/celestiaorg/celestia-node/blob"
"github.com/celestiaorg/celestia-node/das"
"github.com/celestiaorg/celestia-node/header"
"github.com/celestiaorg/celestia-node/nodebuilder/node"
Expand Down Expand Up @@ -128,6 +130,10 @@ func init() {
Addrs: []multiaddr.Multiaddr{ma},
}
addToExampleValues(addrInfo)

proof := nmt.NewInclusionProof(0, 4, [][]byte{[]byte("test")}, true)
blobProof := &blob.Proof{&proof}
addToExampleValues(blobProof)
}

func addToExampleValues(v interface{}) {
Expand Down
75 changes: 73 additions & 2 deletions blob/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package blob

import (
"bytes"
"encoding/json"
"fmt"

appns "github.com/celestiaorg/celestia-app/pkg/namespace"
"github.com/celestiaorg/celestia-app/x/blob/types"
"github.com/celestiaorg/nmt"
"github.com/celestiaorg/nmt/namespace"

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

// Commitment is a Merkle Root of the subtree built from shares of the Blob.
Expand Down Expand Up @@ -57,11 +60,47 @@ func (p Proof) equal(input Proof) error {
return nil
}

type jsonProof struct {
Start int `json:"start"`
End int `json:"end"`
Nodes [][]byte `json:"nodes"`
}

func (p *Proof) MarshalJSON() ([]byte, error) {
proofs := make([]jsonProof, 0, p.Len())
for _, pp := range *p {
proofs = append(proofs, jsonProof{
Start: pp.Start(),
End: pp.End(),
Nodes: pp.Nodes(),
})
}

return json.Marshal(proofs)
}

func (p *Proof) UnmarshalJSON(data []byte) error {
var proofs []jsonProof
err := json.Unmarshal(data, &proofs)
if err != nil {
return err
}

nmtProofs := make([]*nmt.Proof, len(proofs))
for i, jProof := range proofs {
nmtProof := nmt.NewInclusionProof(jProof.Start, jProof.End, jProof.Nodes, ipld.NMTIgnoreMaxNamespace)
nmtProofs[i] = &nmtProof
}

*p = nmtProofs
return nil
}

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

Commitment Commitment
Commitment Commitment `json:"commitment"`
}

// NewBlob constructs a new blob from the provided namespace.ID and data.
Expand Down Expand Up @@ -91,3 +130,35 @@ func NewBlob(shareVersion uint8, namespace namespace.ID, data []byte) (*Blob, er
func (b *Blob) Namespace() namespace.ID {
return append([]byte{uint8(b.NamespaceVersion)}, b.NamespaceId...)
}

type jsonBlob struct {
Namespace namespace.ID `json:"namespace"`
Data []byte `json:"data"`
ShareVersion uint32 `json:"share_version"`
Commitment Commitment `json:"commitment"`
}

func (b *Blob) MarshalJSON() ([]byte, error) {
blob := &jsonBlob{
Namespace: b.Namespace(),
Data: b.Data,
ShareVersion: b.ShareVersion,
Commitment: b.Commitment,
}
return json.Marshal(blob)
}

func (b *Blob) UnmarshalJSON(data []byte) error {
var blob jsonBlob
err := json.Unmarshal(data, &blob)
if err != nil {
return err
}

b.Blob.NamespaceVersion = uint32(blob.Namespace[0])
b.Blob.NamespaceId = blob.Namespace[1:]
b.Blob.Data = blob.Data
b.Blob.ShareVersion = blob.ShareVersion
b.Commitment = blob.Commitment
return nil
}
12 changes: 12 additions & 0 deletions blob/blob_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package blob

import (
"reflect"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -62,6 +63,17 @@ func TestBlob(t *testing.T) {
assert.Equal(t, blob[0].Commitment, b[0].Commitment)
},
},
{
name: "blob marshaling",
expectedRes: func(t *testing.T) {
data, err := blob[0].MarshalJSON()
require.NoError(t, err)

newBlob := &Blob{}
require.NoError(t, newBlob.UnmarshalJSON(data))
require.True(t, reflect.DeepEqual(blob[0], newBlob))
},
},
}

for _, tt := range test {
Expand Down
19 changes: 19 additions & 0 deletions blob/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,25 @@ func TestBlobService_Get(t *testing.T) {

},
},
{
name: "marshal proof",
doFn: func() (interface{}, error) {
proof, err := service.GetProof(ctx, 1, blobs0[1].Namespace(), blobs0[1].Commitment)
require.NoError(t, err)
return proof.MarshalJSON()
},
expectedResult: func(i interface{}, err error) {
require.NoError(t, err)
jsonData, ok := i.([]byte)
require.True(t, ok)
var proof Proof
require.NoError(t, proof.UnmarshalJSON(jsonData))

newProof, err := service.GetProof(ctx, 1, blobs0[1].Namespace(), blobs0[1].Commitment)
require.NoError(t, err)
require.NoError(t, proof.equal(*newProof))
},
},
}

for _, tt := range test {
Expand Down

0 comments on commit 135622a

Please sign in to comment.