Skip to content

Commit

Permalink
namespace mh but finished and tested
Browse files Browse the repository at this point in the history
  • Loading branch information
Wondertan committed Dec 2, 2023
1 parent 9557030 commit 0113b90
Show file tree
Hide file tree
Showing 14 changed files with 245 additions and 72 deletions.
43 changes: 42 additions & 1 deletion share/eds/file.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package eds

import (
"context"
"fmt"
"io"
"os"
Expand All @@ -12,6 +13,7 @@ import (
"github.com/celestiaorg/rsmt2d"

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

type File interface {
Expand All @@ -20,7 +22,7 @@ type File interface {
ShareWithProof(axisType rsmt2d.Axis, axisIdx, shrIdx int) (share.Share, nmt.Proof, error)
Axis(axisType rsmt2d.Axis, axisIdx int) ([]share.Share, error)
AxisHalf(axisType rsmt2d.Axis, axisIdx int) ([]share.Share, error)
// Data(namespace share.Namespace, axisIdx int) ([]share.Share, nmt.Proof, error)
Data(namespace share.Namespace, axisIdx int) ([]share.Share, nmt.Proof, error)
EDS() (*rsmt2d.ExtendedDataSquare, error)
}

Expand Down Expand Up @@ -204,6 +206,15 @@ func (f *LazyFile) ShareWithProof(axisType rsmt2d.Axis, axisIdx, shrIdx int) (sh
return shrs[shrIdx], proof, nil
}

func (f *LazyFile) Data(namespace share.Namespace, axisIdx int) ([]share.Share, nmt.Proof, error) {
shrs, err := f.Axis(rsmt2d.Row, axisIdx)
if err != nil {
return nil, nmt.Proof{}, err
}

return NDFromShares(shrs, namespace, axisIdx)
}

func (f *LazyFile) EDS() (*rsmt2d.ExtendedDataSquare, error) {
shrLn := int(f.hdr.shareSize)
sqrLn := int(f.hdr.squareSize)
Expand Down Expand Up @@ -236,3 +247,33 @@ func (f *LazyFile) EDS() (*rsmt2d.ExtendedDataSquare, error) {
return nil, fmt.Errorf("invalid mode type") // TODO(@Wondertan): Do fields validation right after read
}
}

func NDFromShares(shrs []share.Share, namespace share.Namespace, axisIdx int) ([]share.Share, nmt.Proof, error) {
bserv := ipld.NewMemBlockservice()
batchAdder := ipld.NewNmtNodeAdder(context.TODO(), bserv, ipld.MaxSizeBatchOption(len(shrs)))
tree := wrapper.NewErasuredNamespacedMerkleTree(uint64(len(shrs)/2), uint(axisIdx),
nmt.NodeVisitor(batchAdder.Visit))
for _, shr := range shrs {
err := tree.Push(shr)
if err != nil {
return nil, nmt.Proof{}, err
}
}

root, err := tree.Root()
if err != nil {
return nil, nmt.Proof{}, err
}

err = batchAdder.Commit()
if err != nil {
return nil, nmt.Proof{}, err
}

cid := ipld.MustCidFromNamespacedSha256(root)
row, proof, err := ipld.GetSharesByNamespace(context.TODO(), bserv, cid, namespace, len(shrs))
if err != nil {
return nil, nmt.Proof{}, err
}
return row, *proof, nil
}
9 changes: 9 additions & 0 deletions share/eds/ods_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ func (f *MemFile) AxisHalf(axisType rsmt2d.Axis, axisIdx int) ([]share.Share, er
return getAxis(axisType, axisIdx, f.Eds)[:f.Size()/2], nil
}

func (f *MemFile) Data(namespace share.Namespace, axisIdx int) ([]share.Share, nmt.Proof, error) {
shrs, err := f.Axis(rsmt2d.Row, axisIdx)
if err != nil {
return nil, nmt.Proof{}, err
}

return NDFromShares(shrs, namespace, axisIdx)
}

func (f *MemFile) EDS() (*rsmt2d.ExtendedDataSquare, error) {
return f.Eds, nil
}
Expand Down
14 changes: 7 additions & 7 deletions share/ipldv2/axis.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,29 @@ func NewAxis(id AxisID, axisHalf []share.Share) *Axis {
// NewAxisFromEDS samples the EDS and constructs a new Axis.
func NewAxisFromEDS(
axisType rsmt2d.Axis,
idx int,
eds *rsmt2d.ExtendedDataSquare,
axisIdx int,
square *rsmt2d.ExtendedDataSquare,
height uint64,
) (*Axis, error) {
sqrLn := int(eds.Width())
sqrLn := int(square.Width())

// TODO(@Wondertan): Should be an rsmt2d method
var axisHalf [][]byte
switch axisType {
case rsmt2d.Row:
axisHalf = eds.Row(uint(idx))[:sqrLn/2]
axisHalf = square.Row(uint(axisIdx))[:sqrLn/2]
case rsmt2d.Col:
axisHalf = eds.Col(uint(idx))[:sqrLn/2]
axisHalf = square.Col(uint(axisIdx))[:sqrLn/2]
default:
panic("invalid axis")
}

root, err := share.NewRoot(eds)
root, err := share.NewRoot(square)
if err != nil {
return nil, fmt.Errorf("while computing root: %w", err)
}

id := NewAxisID(axisType, uint16(idx), root, height)
id := NewAxisID(axisType, uint16(axisIdx), root, height)
return NewAxis(id, axisHalf), nil
}

Expand Down
8 changes: 4 additions & 4 deletions share/ipldv2/axis_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ type AxisID struct {
}

// NewAxisID constructs a new AxisID.
func NewAxisID(axisType rsmt2d.Axis, idx uint16, root *share.Root, height uint64) AxisID {
dahroot := root.RowRoots[idx]
func NewAxisID(axisType rsmt2d.Axis, axisIdx uint16, root *share.Root, height uint64) AxisID {
dahroot := root.RowRoots[axisIdx]
if axisType == rsmt2d.Col {
dahroot = root.ColumnRoots[idx]
dahroot = root.ColumnRoots[axisIdx]
}
axisHash := hashBytes(dahroot)

return AxisID{
AxisType: axisType,
AxisIndex: idx,
AxisIndex: axisIdx,
AxisHash: axisHash,
Height: height,
}
Expand Down
18 changes: 9 additions & 9 deletions share/ipldv2/axis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,26 @@ import (
)

func TestAxis(t *testing.T) {
square := edstest.RandEDS(t, 2)
square := edstest.RandEDS(t, 8)

aid, err := NewAxisFromEDS(rsmt2d.Row, 1, square, 2)
axis, err := NewAxisFromEDS(rsmt2d.Row, 1, square, 2)
require.NoError(t, err)

data, err := aid.MarshalBinary()
data, err := axis.MarshalBinary()
require.NoError(t, err)

blk, err := aid.IPLDBlock()
blk, err := axis.IPLDBlock()
require.NoError(t, err)

cid, err := aid.AxisID.Cid()
cid, err := axis.AxisID.Cid()
require.NoError(t, err)
assert.EqualValues(t, blk.Cid(), cid)

sidOut := &Axis{}
err = sidOut.UnmarshalBinary(data)
axisOut := &Axis{}
err = axisOut.UnmarshalBinary(data)
require.NoError(t, err)
assert.EqualValues(t, aid, sidOut)
assert.EqualValues(t, axis, axisOut)

err = sidOut.Validate()
err = axisOut.Validate()
require.NoError(t, err)
}
12 changes: 5 additions & 7 deletions share/ipldv2/blockstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"

"github.com/celestiaorg/nmt"

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

Expand Down Expand Up @@ -135,12 +133,12 @@ func (b Blockstore[F]) getDataBlock(id DataID) (blocks.Block, error) {
return nil, fmt.Errorf("while getting ODS file from FS: %w", err)
}

// data, prf, err := f.Data(id.DataNamespace, int(id.AxisIndex))
// if err != nil {
// return nil, fmt.Errorf("while getting Data: %w", err)
// }
data, prf, err := f.Data(id.DataNamespace, int(id.AxisIndex))
if err != nil {
return nil, fmt.Errorf("while getting Data: %w", err)
}

s := NewData(id, nil, nmt.Proof{})
s := NewData(id, data, prf)
blk, err := s.IPLDBlock()
if err != nil {
return nil, fmt.Errorf("while coverting Data to IPLD block: %w", err)
Expand Down
76 changes: 48 additions & 28 deletions share/ipldv2/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import (
blocks "github.com/ipfs/go-block-format"

"github.com/celestiaorg/nmt"
nmtpb "github.com/celestiaorg/nmt/pb"
"github.com/celestiaorg/rsmt2d"

"github.com/celestiaorg/celestia-node/share"
"github.com/celestiaorg/celestia-node/share/eds"
ipldv2pb "github.com/celestiaorg/celestia-node/share/ipldv2/pb"
)

Expand All @@ -27,33 +30,36 @@ func NewData(id DataID, shares []share.Share, proof nmt.Proof) *Data {
}
}

// // NewDataFromEDS samples the EDS and constructs a new Data.
// func NewDataFromEDS(
// idx int,
// eds *rsmt2d.ExtendedDataSquare,
// height uint64,
// ) (*Data, error) {
// sqrLn := int(eds.Width())
//
// // TODO(@Wondertan): Should be an rsmt2d method
// var axisHalf [][]byte
// switch axisType {
// case rsmt2d.Row:
// axisHalf = eds.Row(uint(idx))[:sqrLn/2]
// case rsmt2d.Col:
// axisHalf = eds.Col(uint(idx))[:sqrLn/2]
// default:
// panic("invalid axis")
// }
//
// root, err := share.NewRoot(eds)
// if err != nil {
// return nil, fmt.Errorf("while computing root: %w", err)
// }
//
// id := NewDataID(axisType, uint16(idx), root, height)
// return NewData(id, axisHalf), nil
// }
// NewDataFromEDS samples the EDS and constructs Data for each row with the given namespace.
func NewDataFromEDS(
square *rsmt2d.ExtendedDataSquare,
height uint64,
namespace share.Namespace,
) ([]*Data, error) {
root, err := share.NewRoot(square)
if err != nil {
return nil, fmt.Errorf("while computing root: %w", err)
}

var datas []*Data
for rowIdx, rowRoot := range root.RowRoots {
if namespace.IsOutsideRange(rowRoot, rowRoot) {
continue
}

shrs := square.Row(uint(rowIdx))
// TDOD(@Wondertan): This will likely be removed
nd, proof, err := eds.NDFromShares(shrs, namespace, rowIdx)
if err != nil {
return nil, err
}

id := NewDataID(rowIdx, root, height, namespace)
datas = append(datas, NewData(id, nd, proof))
}

return datas, nil
}

// DataFromBlock converts blocks.Block into Data.
func DataFromBlock(blk blocks.Block) (*Data, error) {
Expand Down Expand Up @@ -92,8 +98,16 @@ func (s *Data) MarshalBinary() ([]byte, error) {
return nil, err
}

proof := &nmtpb.Proof{}
proof.Nodes = s.DataProof.Nodes()
proof.End = int64(s.DataProof.End())
proof.Start = int64(s.DataProof.Start())
proof.IsMaxNamespaceIgnored = s.DataProof.IsMaxNamespaceIDIgnored()
proof.LeafHash = s.DataProof.LeafHash()

return (&ipldv2pb.Data{
DataId: id,
DataProof: proof,
DataShares: s.DataShares,
}).Marshal()
}
Expand All @@ -110,6 +124,7 @@ func (s *Data) UnmarshalBinary(data []byte) error {
return err
}

s.DataProof = nmt.ProtoToProof(*proto.DataProof)
s.DataShares = proto.DataShares
return nil
}
Expand All @@ -124,8 +139,13 @@ func (s *Data) Validate() error {
return fmt.Errorf("empty DataShares")
}

shrs := make([][]byte, 0, len(s.DataShares))
for _, shr := range s.DataShares {
shrs = append(shrs, append(share.GetNamespace(shr), shr...))
}

s.DataProof.WithHashedProof(hasher())
if !s.DataProof.VerifyNamespace(hasher(), s.DataNamespace.ToNMT(), s.DataShares, s.AxisHash) {
if !s.DataProof.VerifyNamespace(hasher(), s.DataNamespace.ToNMT(), shrs, s.AxisHash) {
return fmt.Errorf("invalid DataProof")
}

Expand Down
8 changes: 4 additions & 4 deletions share/ipldv2/data_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type DataID struct {
}

// NewDataID constructs a new DataID.
func NewDataID(namespace share.Namespace, axisIdx int, root *share.Root, height uint64) DataID {
func NewDataID(axisIdx int, root *share.Root, height uint64, namespace share.Namespace) DataID {
return DataID{
AxisID: NewAxisID(rsmt2d.Row, uint16(axisIdx), root, height),
DataNamespace: namespace,
Expand All @@ -48,18 +48,18 @@ func DataIDFromCID(cid cid.Cid) (id DataID, err error) {

// Cid returns sample ID encoded as CID.
func (s *DataID) Cid() (cid.Cid, error) {
// avoid using proto serialization for CID as it's not deterministicnot lambo though
// avoid using proto serialization for CID as it's not deterministic
data, err := s.MarshalBinary()
if err != nil {
return cid.Undef, err
}

buf, err := mh.Encode(data, sampleMultihashCode)
buf, err := mh.Encode(data, dataMultihashCode)
if err != nil {
return cid.Undef, err
}

return cid.NewCidV1(sampleCodec, buf), nil
return cid.NewCidV1(dataCodec, buf), nil
}

// MarshalBinary encodes DataID into binary form.
Expand Down
2 changes: 1 addition & 1 deletion share/ipldv2/data_id_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestDataID(t *testing.T) {
root, err := share.NewRoot(square)
require.NoError(t, err)

sid := NewDataID(sharetest.RandV0Namespace(), 2, root, 1)
sid := NewDataID(2, root, 1, sharetest.RandV0Namespace())
id, err := sid.Cid()
require.NoError(t, err)

Expand Down
Loading

0 comments on commit 0113b90

Please sign in to comment.