Skip to content

Commit

Permalink
feat(share/store_v2) Update file interface to use shwap types (celest…
Browse files Browse the repository at this point in the history
…iaorg#3441)

Updates file interface to latest prototype version
  • Loading branch information
walldiss committed Jul 6, 2024
1 parent 4e122f0 commit 00566a2
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 114 deletions.
14 changes: 7 additions & 7 deletions share/eds/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,24 +121,24 @@ func CollectSharesByNamespace(
utils.SetStatusAndEnd(span, err)
}()

rootCIDs := ipld.FilterRootByNamespace(root, namespace)
if len(rootCIDs) == 0 {
rowIdxs := share.RowsWithNamespace(root, namespace)
if len(rowIdxs) == 0 {
return []share.NamespacedRow{}, nil
}

errGroup, ctx := errgroup.WithContext(ctx)
shares = make([]share.NamespacedRow, len(rootCIDs))
for i, rootCID := range rootCIDs {
shares = make([]share.NamespacedRow, len(rowIdxs))
for i, rowIdx := range rowIdxs {
// shadow loop variables, to ensure correct values are captured
i, rootCID := i, rootCID
rowIdx, rowRoot := rowIdx, root.RowRoots[rowIdx]
errGroup.Go(func() error {
row, proof, err := ipld.GetSharesByNamespace(ctx, bg, rootCID, namespace, len(root.RowRoots))
row, proof, err := ipld.GetSharesByNamespace(ctx, bg, rowRoot, namespace, len(root.RowRoots))
shares[i] = share.NamespacedRow{
Shares: row,
Proof: proof,
}
if err != nil {
return fmt.Errorf("retrieving shares by namespace %s for row %x: %w", namespace.String(), rootCID, err)
return fmt.Errorf("retrieving shares by namespace %s for row %d: %w", namespace.String(), rowIdx, err)
}
return nil
})
Expand Down
5 changes: 3 additions & 2 deletions share/ipld/get_shares.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ func GetShares(ctx context.Context, bg blockservice.BlockGetter, root cid.Cid, s
func GetSharesByNamespace(
ctx context.Context,
bGetter blockservice.BlockGetter,
root cid.Cid,
root []byte,
namespace share.Namespace,
maxShares int,
) ([]share.Share, *nmt.Proof, error) {
rootCid := MustCidFromNamespacedSha256(root)
data := NewNamespaceData(maxShares, namespace, WithLeaves(), WithProofs())
err := data.CollectLeavesByNamespace(ctx, bGetter, root)
err := data.CollectLeavesByNamespace(ctx, bGetter, rootCid)
if err != nil {
return nil, nil, err
}
Expand Down
10 changes: 4 additions & 6 deletions share/ipld/get_shares_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,7 @@ func TestGetSharesByNamespace(t *testing.T) {
rowRoots, err := eds.RowRoots()
require.NoError(t, err)
for _, row := range rowRoots {
rcid := MustCidFromNamespacedSha256(row)
rowShares, _, err := GetSharesByNamespace(ctx, bServ, rcid, namespace, len(rowRoots))
rowShares, _, err := GetSharesByNamespace(ctx, bServ, row, namespace, len(rowRoots))
if errors.Is(err, ErrNamespaceOutsideRange) {
continue
}
Expand Down Expand Up @@ -363,8 +362,7 @@ func TestGetSharesWithProofsByNamespace(t *testing.T) {
rowRoots, err := eds.RowRoots()
require.NoError(t, err)
for _, row := range rowRoots {
rcid := MustCidFromNamespacedSha256(row)
rowShares, proof, err := GetSharesByNamespace(ctx, bServ, rcid, namespace, len(rowRoots))
rowShares, proof, err := GetSharesByNamespace(ctx, bServ, row, namespace, len(rowRoots))
if namespace.IsOutsideRange(row, row) {
require.ErrorIs(t, err, ErrNamespaceOutsideRange)
continue
Expand All @@ -386,15 +384,15 @@ func TestGetSharesWithProofsByNamespace(t *testing.T) {
share.NewSHA256Hasher(),
namespace.ToNMT(),
leaves,
NamespacedSha256FromCID(rcid))
row)
require.True(t, verified)

// verify inclusion
verified = proof.VerifyInclusion(
share.NewSHA256Hasher(),
namespace.ToNMT(),
rowShares,
NamespacedSha256FromCID(rcid))
row)
require.True(t, verified)
}
}
Expand Down
51 changes: 51 additions & 0 deletions share/root.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package share

import (
"bytes"
"crypto/sha256"
"encoding/hex"
"fmt"
"hash"

"github.com/celestiaorg/celestia-app/pkg/da"
"github.com/celestiaorg/rsmt2d"
)
Expand All @@ -9,6 +15,30 @@ import (
// In practice, it is a commitment to all the Data in a square.
type Root = da.DataAvailabilityHeader

// DataHash is a representation of the Root hash.
type DataHash []byte

func (dh DataHash) Validate() error {
if len(dh) != 32 {
return fmt.Errorf("invalid hash size, expected 32, got %d", len(dh))
}
return nil
}

func (dh DataHash) String() string {
return fmt.Sprintf("%X", []byte(dh))
}

// IsEmptyRoot check whether DataHash corresponds to the root of an empty block EDS.
func (dh DataHash) IsEmptyRoot() bool {
return bytes.Equal(EmptyRoot().Hash(), dh)
}

// NewSHA256Hasher returns a new instance of a SHA-256 hasher.
func NewSHA256Hasher() hash.Hash {
return sha256.New()
}

// NewRoot generates Root(DataAvailabilityHeader) using the
// provided extended data square.
func NewRoot(eds *rsmt2d.ExtendedDataSquare) (*Root, error) {
Expand All @@ -29,3 +59,24 @@ func RowsWithNamespace(root *Root, namespace Namespace) (idxs []int) {
}
return
}

// RootHashForCoordinates returns the root hash for the given coordinates.
func RootHashForCoordinates(r *Root, axisType rsmt2d.Axis, rowIdx, colIdx uint) []byte {
if axisType == rsmt2d.Row {
return r.RowRoots[rowIdx]
}
return r.ColumnRoots[colIdx]
}

// MustDataHashFromString converts a hex string to a valid datahash.
func MustDataHashFromString(datahash string) DataHash {
dh, err := hex.DecodeString(datahash)
if err != nil {
panic(fmt.Sprintf("datahash conversion: passed string was not valid hex: %s", datahash))
}
err = DataHash(dh).Validate()
if err != nil {
panic(fmt.Sprintf("datahash validation: passed hex string failed: %s", err))
}
return dh
}
48 changes: 0 additions & 48 deletions share/share.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package share

import (
"bytes"
"crypto/sha256"
"encoding/hex"
"fmt"
"hash"

"github.com/celestiaorg/celestia-app/pkg/appconsts"
"github.com/celestiaorg/nmt"
Expand Down Expand Up @@ -72,48 +69,3 @@ func (s *ShareWithProof) Validate(rootHash []byte, x, y, edsSize int) bool {
rootHash,
)
}

// DataHash is a representation of the Root hash.
type DataHash []byte

func (dh DataHash) Validate() error {
if len(dh) != 32 {
return fmt.Errorf("invalid hash size, expected 32, got %d", len(dh))
}
return nil
}

func (dh DataHash) String() string {
return fmt.Sprintf("%X", []byte(dh))
}

// IsEmptyRoot check whether DataHash corresponds to the root of an empty block EDS.
func (dh DataHash) IsEmptyRoot() bool {
return bytes.Equal(EmptyRoot().Hash(), dh)
}

// MustDataHashFromString converts a hex string to a valid datahash.
func MustDataHashFromString(datahash string) DataHash {
dh, err := hex.DecodeString(datahash)
if err != nil {
panic(fmt.Sprintf("datahash conversion: passed string was not valid hex: %s", datahash))
}
err = DataHash(dh).Validate()
if err != nil {
panic(fmt.Sprintf("datahash validation: passed hex string failed: %s", err))
}
return dh
}

// NewSHA256Hasher returns a new instance of a SHA-256 hasher.
func NewSHA256Hasher() hash.Hash {
return sha256.New()
}

// RootHashForCoordinates returns the root hash for the given coordinates.
func RootHashForCoordinates(r *Root, axisType rsmt2d.Axis, rowIdx, colIdx uint) []byte {
if axisType == rsmt2d.Row {
return r.RowRoots[rowIdx]
}
return r.ColumnRoots[colIdx]
}
3 changes: 1 addition & 2 deletions share/shwap/row_namespace_data.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package shwap

import (
"crypto/sha256"
"fmt"

"github.com/celestiaorg/celestia-app/pkg/wrapper"
Expand Down Expand Up @@ -158,7 +157,7 @@ func (rnd RowNamespaceData) verifyInclusion(rowRoot []byte, namespace share.Name
leaves = append(leaves, append(namespaceBytes, shr...))
}
return rnd.Proof.VerifyNamespace(
sha256.New(),
share.NewSHA256Hasher(),
namespace.ToNMT(),
leaves,
rowRoot,
Expand Down
19 changes: 19 additions & 0 deletions share/store/file/axis_half.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package file

import (
"github.com/celestiaorg/celestia-node/share"
"github.com/celestiaorg/celestia-node/share/shwap"
)

type AxisHalf struct {
Shares []share.Share
IsParity bool
}

func (a AxisHalf) ToRow() shwap.Row {
side := shwap.Left
if a.IsParity {
side = shwap.Right
}
return shwap.NewRow(a.Shares, side)
}
11 changes: 6 additions & 5 deletions share/store/eds_file.go → share/store/file/eds_file.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package store
package file

import (
"context"
Expand All @@ -7,18 +7,19 @@ import (
"github.com/celestiaorg/rsmt2d"

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

type EdsFile interface {
io.Closer
// Size returns square size of the file.
Size() int
// Share returns share and corresponding proof for the given axis and share index in this axis.
Share(ctx context.Context, x, y int) (*share.ShareWithProof, error)
// AxisHalf returns shares for the first half of the axis of the given type and index.
AxisHalf(ctx context.Context, axisType rsmt2d.Axis, axisIdx int) ([]share.Share, error)
Share(ctx context.Context, rowIdx, colIdx int) (*shwap.Sample, error)
// AxisHalf returns Shares for the first half of the axis of the given type and index.
AxisHalf(ctx context.Context, axisType rsmt2d.Axis, axisIdx int) (AxisHalf, error)
// Data returns data for the given namespace and row index.
Data(ctx context.Context, namespace share.Namespace, rowIdx int) (share.NamespacedRow, error)
Data(ctx context.Context, namespace share.Namespace, rowIdx int) (shwap.RowNamespaceData, error)
// EDS returns extended data square stored in the file.
EDS(ctx context.Context) (*rsmt2d.ExtendedDataSquare, error)
}
Loading

0 comments on commit 00566a2

Please sign in to comment.