-
Notifications
You must be signed in to change notification settings - Fork 901
/
eds.go
85 lines (74 loc) · 2.62 KB
/
eds.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package core
import (
"context"
"errors"
"fmt"
"github.com/filecoin-project/dagstore"
"github.com/tendermint/tendermint/types"
"github.com/celestiaorg/celestia-app/app"
"github.com/celestiaorg/celestia-app/pkg/appconsts"
"github.com/celestiaorg/celestia-app/pkg/shares"
"github.com/celestiaorg/celestia-app/pkg/square"
"github.com/celestiaorg/celestia-app/pkg/wrapper"
"github.com/celestiaorg/nmt"
"github.com/celestiaorg/rsmt2d"
"github.com/celestiaorg/celestia-node/header"
"github.com/celestiaorg/celestia-node/pruner"
"github.com/celestiaorg/celestia-node/share"
"github.com/celestiaorg/celestia-node/share/eds"
"github.com/celestiaorg/celestia-node/share/ipld"
)
// extendBlock extends the given block data, returning the resulting
// ExtendedDataSquare (EDS). If there are no transactions in the block,
// nil is returned in place of the eds.
func extendBlock(data types.Data, appVersion uint64, options ...nmt.Option) (*rsmt2d.ExtendedDataSquare, error) {
if app.IsEmptyBlock(data, appVersion) {
return share.EmptyExtendedDataSquare(), nil
}
// Construct the data square from the block's transactions
dataSquare, err := square.Construct(data.Txs.ToSliceOfBytes(), appVersion, appconsts.SquareSizeUpperBound(appVersion))
if err != nil {
return nil, err
}
return extendShares(shares.ToBytes(dataSquare), options...)
}
func extendShares(s [][]byte, options ...nmt.Option) (*rsmt2d.ExtendedDataSquare, error) {
// Check that the length of the square is a power of 2.
if !shares.IsPowerOfTwo(len(s)) {
return nil, fmt.Errorf("number of shares is not a power of 2: got %d", len(s))
}
// here we construct a tree
// Note: uses the nmt wrapper to construct the tree.
squareSize := square.Size(len(s))
return rsmt2d.ComputeExtendedDataSquare(s,
appconsts.DefaultCodec(),
wrapper.NewConstructor(uint64(squareSize),
options...))
}
// storeEDS will only store extended block if it is not empty and doesn't already exist.
func storeEDS(
ctx context.Context,
eh *header.ExtendedHeader,
eds *rsmt2d.ExtendedDataSquare,
adder *ipld.ProofsAdder,
store *eds.Store,
window pruner.AvailabilityWindow,
) error {
if eds.Equals(share.EmptyExtendedDataSquare()) {
return nil
}
if !pruner.IsWithinAvailabilityWindow(eh.Time(), window) {
log.Debugw("skipping storage of historic block", "height", eh.Height())
return nil
}
ctx = ipld.CtxWithProofsAdder(ctx, adder)
err := store.Put(ctx, share.DataHash(eh.DataHash), eds)
if errors.Is(err, dagstore.ErrShardExists) {
// block with given root already exists, return nil
return nil
}
if err == nil {
log.Debugw("stored EDS for height", "height", eh.Height())
}
return err
}