Skip to content

Commit

Permalink
feat(shwap): add shwap store getter (#3617)
Browse files Browse the repository at this point in the history
add store getter implementation of shwap.Getter. Unit are not implemented for same reason as #3584
  • Loading branch information
walldiss authored Aug 7, 2024
1 parent 6751df2 commit 5bb844a
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 0 deletions.
94 changes: 94 additions & 0 deletions store/getter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package store

import (
"context"
"errors"
"fmt"

"github.com/celestiaorg/rsmt2d"

"github.com/celestiaorg/celestia-node/header"
"github.com/celestiaorg/celestia-node/libs/utils"
"github.com/celestiaorg/celestia-node/share"
eds "github.com/celestiaorg/celestia-node/share/new_eds"
"github.com/celestiaorg/celestia-node/share/shwap"
)

var _ shwap.Getter = (*Getter)(nil)

type Getter struct {
store *Store
}

func NewGetter(store *Store) *Getter {
return &Getter{store: store}
}

func (g *Getter) GetShare(ctx context.Context, h *header.ExtendedHeader, row, col int) (share.Share, error) {
acc, err := g.store.GetByHeight(ctx, h.Height())
if err != nil {
if errors.Is(err, ErrNotFound) {
return nil, shwap.ErrNotFound
}
return nil, fmt.Errorf("get accessor from store:%w", err)
}
logger := log.With(
"height", h.Height(),
"row", row,
"col", col,
)
defer utils.CloseAndLog(logger, "getter/sample", acc)

sample, err := acc.Sample(ctx, row, col)
if err != nil {
return nil, fmt.Errorf("get sample from accessor:%w", err)
}
return sample.Share, nil
}

func (g *Getter) GetEDS(ctx context.Context, h *header.ExtendedHeader) (*rsmt2d.ExtendedDataSquare, error) {
acc, err := g.store.GetByHeight(ctx, h.Height())
if err != nil {
if errors.Is(err, ErrNotFound) {
return nil, shwap.ErrNotFound
}
return nil, fmt.Errorf("get accessor from store:%w", err)
}
logger := log.With("height", h.Height())
defer utils.CloseAndLog(logger, "getter/eds", acc)

shares, err := acc.Shares(ctx)
if err != nil {
return nil, fmt.Errorf("get shares from accessor:%w", err)
}
rsmt2d, err := eds.Rsmt2DFromShares(shares, len(h.DAH.RowRoots)/2)
if err != nil {
return nil, fmt.Errorf("build eds from shares:%w", err)
}
return rsmt2d.ExtendedDataSquare, nil
}

func (g *Getter) GetSharesByNamespace(
ctx context.Context,
h *header.ExtendedHeader,
ns share.Namespace,
) (shwap.NamespaceData, error) {
acc, err := g.store.GetByHeight(ctx, h.Height())
if err != nil {
if errors.Is(err, ErrNotFound) {
return nil, shwap.ErrNotFound
}
return nil, fmt.Errorf("get accessor from store:%w", err)
}
logger := log.With(
"height", h.Height(),
"namespace", ns.String(),
)
defer utils.CloseAndLog(logger, "getter/nd", acc)

nd, err := eds.NamespaceData(ctx, acc, ns)
if err != nil {
return nil, fmt.Errorf("get nd from accessor:%w", err)
}
return nd, nil
}
92 changes: 92 additions & 0 deletions store/getter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package store

import (
"context"
"sync/atomic"
"testing"

"github.com/stretchr/testify/require"

"github.com/celestiaorg/celestia-node/header/headertest"
"github.com/celestiaorg/celestia-node/share/eds/edstest"
"github.com/celestiaorg/celestia-node/share/sharetest"
"github.com/celestiaorg/celestia-node/share/shwap"
)

func TestStoreGetter(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)

edsStore, err := NewStore(DefaultParameters(), t.TempDir())
require.NoError(t, err)

sg := NewGetter(edsStore)
height := atomic.Uint64{}

t.Run("GetShare", func(t *testing.T) {
eds, roots := randomEDS(t)
eh := headertest.RandExtendedHeaderWithRoot(t, roots)
height := height.Add(1)
eh.RawHeader.Height = int64(height)

err := edsStore.Put(ctx, eh.DAH, height, eds)
require.NoError(t, err)

squareSize := int(eds.Width())
for i := 0; i < squareSize; i++ {
for j := 0; j < squareSize; j++ {
share, err := sg.GetShare(ctx, eh, i, j)
require.NoError(t, err)
require.Equal(t, eds.GetCell(uint(i), uint(j)), share)
}
}

// doesn't panic on indexes too high
_, err = sg.GetShare(ctx, eh, squareSize, squareSize)
require.ErrorIs(t, err, shwap.ErrOutOfBounds)
})

t.Run("GetEDS", func(t *testing.T) {
eds, roots := randomEDS(t)
eh := headertest.RandExtendedHeaderWithRoot(t, roots)
height := height.Add(1)
eh.RawHeader.Height = int64(height)

err := edsStore.Put(ctx, eh.DAH, height, eds)
require.NoError(t, err)

retrievedEDS, err := sg.GetEDS(ctx, eh)
require.NoError(t, err)
require.True(t, eds.Equals(retrievedEDS))

// root not found
eh.RawHeader.Height = 666
_, err = sg.GetEDS(ctx, eh)
require.ErrorIs(t, err, shwap.ErrNotFound)
})

t.Run("GetSharesByNamespace", func(t *testing.T) {
ns := sharetest.RandV0Namespace()
eds, roots := edstest.RandEDSWithNamespace(t, ns, 8, 16)
eh := headertest.RandExtendedHeaderWithRoot(t, roots)
height := height.Add(1)
eh.RawHeader.Height = int64(height)
err := edsStore.Put(ctx, eh.DAH, height, eds)
require.NoError(t, err)

shares, err := sg.GetSharesByNamespace(ctx, eh, ns)
require.NoError(t, err)
require.NoError(t, shares.Validate(eh.DAH, ns))

// namespace not found
randNamespace := sharetest.RandV0Namespace()
emptyShares, err := sg.GetSharesByNamespace(ctx, eh, randNamespace)
require.NoError(t, err)
require.Empty(t, emptyShares.Flatten())

// root not found
eh.RawHeader.Height = 666
_, err = sg.GetSharesByNamespace(ctx, eh, ns)
require.ErrorIs(t, err, shwap.ErrNotFound)
})
}

0 comments on commit 5bb844a

Please sign in to comment.