Skip to content

Commit 92b984c

Browse files
committed
revert changes in blob service
1 parent f6bf9f1 commit 92b984c

7 files changed

Lines changed: 367 additions & 226 deletions

File tree

blob/blob.go

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,49 +11,21 @@ import (
1111
"github.com/celestiaorg/go-square/v3/inclusion"
1212
libshare "github.com/celestiaorg/go-square/v3/share"
1313
"github.com/celestiaorg/nmt"
14-
15-
"github.com/celestiaorg/celestia-node/header"
16-
"github.com/celestiaorg/celestia-node/share"
17-
"github.com/celestiaorg/celestia-node/share/shwap"
1814
)
1915

16+
var errEmptyShares = errors.New("empty shares")
17+
2018
var subtreeRootThreshold = appconsts.SubtreeRootThreshold
2119

22-
// The Proof is a set of nmt proofs that can verify the inclusion of the blob
20+
// The Proof is a set of nmt proofs that can be verified only through
21+
// the included method (due to limitation of the nmt https://github.com/celestiaorg/nmt/issues/218).
22+
// Proof proves the WHOLE namespaced data to the row roots.
23+
// TODO (@vgonkivs): rework `Proof` in order to prove a particular blob.
24+
// https://github.com/celestiaorg/celestia-node/issues/2303
2325
type Proof []*nmt.Proof
2426

2527
func (p Proof) Len() int { return len(p) }
2628

27-
func (p Proof) verify(blob *Blob, header *header.ExtendedHeader) error {
28-
shrs, err := BlobsToShares(blob)
29-
if err != nil {
30-
return err
31-
}
32-
33-
fromCoords, err := shwap.SampleCoordsFrom1DIndex(blob.Index(), len(header.DAH.RowRoots)) // pass eds size
34-
if err != nil {
35-
return err
36-
}
37-
38-
hasher := share.NewSHA256Hasher()
39-
shareOffset := 0
40-
for proofIdx := 0; proofIdx < len(p); proofIdx++ {
41-
hasher.Reset()
42-
sharesInProof := p[proofIdx].End() - p[proofIdx].Start()
43-
valid := p[proofIdx].VerifyInclusion(
44-
hasher,
45-
blob.Namespace().Bytes(),
46-
libshare.ToBytes(shrs[shareOffset:shareOffset+sharesInProof]),
47-
header.DAH.RowRoots[fromCoords.Row+proofIdx],
48-
)
49-
if !valid {
50-
return ErrInvalidProof
51-
}
52-
shareOffset += sharesInProof
53-
}
54-
return nil
55-
}
56-
5729
// equal is a temporary method that compares two proofs.
5830
// should be removed in BlobService V1.
5931
func (p Proof) equal(input Proof) error {

blob/blob_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@ func TestBlob(t *testing.T) {
5959
assert.Equal(t, length, blobLength)
6060
},
6161
},
62+
{
63+
name: "shares to blobs",
64+
expectedRes: func(t *testing.T) {
65+
shares, err := BlobsToShares(blob...)
66+
require.NoError(t, err)
67+
p := &parser{length: len(shares), shares: shares}
68+
b, err := p.parse()
69+
require.NoError(t, err)
70+
assert.Equal(t, blob[0].Commitment, b.Commitment)
71+
},
72+
},
6273
{
6374
name: "blob marshaling",
6475
expectedRes: func(t *testing.T) {

blob/helper.go

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
package blob
22

33
import (
4-
"fmt"
54
"sort"
65

76
"github.com/celestiaorg/go-square/merkle"
87
"github.com/celestiaorg/go-square/v3/inclusion"
98
libshare "github.com/celestiaorg/go-square/v3/share"
10-
11-
"github.com/celestiaorg/celestia-node/share"
12-
"github.com/celestiaorg/celestia-node/share/shwap"
139
)
1410

1511
// BlobsToShares accepts blobs and convert them to the Shares.
@@ -57,76 +53,3 @@ func calculateIndex(rowLength, blobIndex int) (row, col int) {
5753
col = blobIndex - (row * rowLength)
5854
return row, col
5955
}
60-
61-
func fromShwapBlob(shBlob *shwap.Blob, odsSize int) (*Blob, error) {
62-
blb, err := shBlob.Blob()
63-
if err != nil {
64-
return nil, err
65-
}
66-
67-
commitment, err := shBlob.Commitment()
68-
if err != nil {
69-
return nil, err
70-
}
71-
72-
odsIndex := shBlob.Index()
73-
coords, err := shwap.SampleCoordsFrom1DIndex(odsIndex, odsSize)
74-
if err != nil {
75-
return nil, err
76-
}
77-
78-
edsIndex, err := shwap.SampleCoordsAs1DIndex(coords, odsSize*2)
79-
if err != nil {
80-
return nil, err
81-
}
82-
return &Blob{
83-
Blob: blb,
84-
Commitment: commitment,
85-
index: edsIndex,
86-
}, nil
87-
}
88-
89-
func buildProof(blob *shwap.Blob, odsSize int) (*Proof, error) {
90-
shares := blob.Shares
91-
numRows := len(shares)
92-
coords, err := shwap.SampleCoordsFrom1DIndex(blob.Index(), odsSize)
93-
if err != nil {
94-
return nil, err
95-
}
96-
proofs := make(Proof, numRows)
97-
if blob.FirstIncompleteRowProof != nil {
98-
proofs[0] = blob.FirstIncompleteRowProof
99-
}
100-
if blob.LastIncompleteRowProof != nil {
101-
proofs[numRows-1] = blob.LastIncompleteRowProof
102-
}
103-
104-
for i := 0; i < numRows; i++ {
105-
if proofs[i] != nil {
106-
continue
107-
}
108-
if len(shares[i]) != odsSize {
109-
return nil, fmt.Errorf("incomplete row of shares at: %d, %d != %d",
110-
coords.Row+i, len(shares[i]), odsSize,
111-
)
112-
}
113-
114-
extendedShares, err := share.ExtendShares(shares[i])
115-
if err != nil {
116-
return nil, err
117-
}
118-
119-
proof, err := shwap.GenerateSharesProofs(
120-
coords.Row+i,
121-
0,
122-
odsSize,
123-
odsSize,
124-
extendedShares,
125-
)
126-
if err != nil {
127-
return nil, err
128-
}
129-
proofs[i] = proof
130-
}
131-
return &proofs, nil
132-
}

blob/metrics.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import (
88
"go.opentelemetry.io/otel"
99
"go.opentelemetry.io/otel/attribute"
1010
"go.opentelemetry.io/otel/metric"
11-
12-
"github.com/celestiaorg/celestia-node/share/shwap"
1311
)
1412

1513
var meter = otel.Meter("blob")
@@ -93,7 +91,7 @@ func (m *metrics) observeRetrieval(ctx context.Context, duration time.Duration,
9391
if err != nil {
9492
errorType := errorTypeUnknown
9593
switch {
96-
case errors.Is(err, shwap.ErrBlobNotFound):
94+
case errors.Is(err, ErrBlobNotFound):
9795
errorType = errorTypeNotFound
9896
case errors.Is(err, context.DeadlineExceeded):
9997
errorType = errorTypeTimeout

blob/parser.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package blob
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
7+
"github.com/celestiaorg/go-square/merkle"
8+
"github.com/celestiaorg/go-square/v3/inclusion"
9+
libshare "github.com/celestiaorg/go-square/v3/share"
10+
)
11+
12+
// parser helps to collect shares and transform them into a blob.
13+
// It can handle only one blob at a time.
14+
type parser struct {
15+
// index is a position of the blob inside the EDS.
16+
index int
17+
// length is an amount of the shares needed to build the blob.
18+
length int
19+
// shares is a set of shares to build the blob.
20+
shares []libshare.Share
21+
verifyFn func(blob *Blob) bool
22+
}
23+
24+
// set tries to find the first blob's share by skipping padding shares and
25+
// sets the metadata of the blob(index and length)
26+
func (p *parser) set(index int, shrs []libshare.Share) ([]libshare.Share, error) {
27+
if len(shrs) == 0 {
28+
return nil, errEmptyShares
29+
}
30+
31+
shrs, err := p.skipPadding(shrs)
32+
if err != nil {
33+
return nil, err
34+
}
35+
36+
if len(shrs) == 0 {
37+
return nil, errEmptyShares
38+
}
39+
40+
// `+=` as index could be updated in `skipPadding`
41+
p.index += index
42+
length := shrs[0].SequenceLen()
43+
containsSigner := shrs[0].Version() == libshare.ShareVersionOne
44+
p.length = libshare.SparseSharesNeeded(length, containsSigner)
45+
return shrs, nil
46+
}
47+
48+
// addShares sets shares until the blob is completed and extra remaining shares back.
49+
// It assumes that the remaining shares required for blob completeness are correct and
50+
// do not include padding shares.
51+
func (p *parser) addShares(shares []libshare.Share) (shrs []libshare.Share, isComplete bool) {
52+
index := -1
53+
for i, sh := range shares {
54+
p.shares = append(p.shares, sh)
55+
if len(p.shares) == p.length {
56+
index = i
57+
isComplete = true
58+
break
59+
}
60+
}
61+
62+
if index == -1 {
63+
return shrs, isComplete
64+
}
65+
66+
if index+1 >= len(shares) {
67+
return shrs, true
68+
}
69+
return shares[index+1:], true
70+
}
71+
72+
// parse ensures that correct amount of shares was collected and create a blob from the existing
73+
// shares.
74+
func (p *parser) parse() (*Blob, error) {
75+
if p.length != len(p.shares) {
76+
return nil, fmt.Errorf("invalid shares amount. want:%d, have:%d", p.length, len(p.shares))
77+
}
78+
79+
blobs, err := libshare.ParseBlobs(p.shares)
80+
if err != nil {
81+
return nil, err
82+
}
83+
84+
if len(blobs) != 1 {
85+
return nil, errors.New("unexpected amount of blobs during parsing")
86+
}
87+
88+
com, err := inclusion.CreateCommitment(blobs[0], merkle.HashFromByteSlices, subtreeRootThreshold)
89+
if err != nil {
90+
return nil, err
91+
}
92+
93+
blob := &Blob{Blob: blobs[0], Commitment: com, index: p.index}
94+
return blob, nil
95+
}
96+
97+
// skipPadding iterates through the shares until non-padding share will be found. It guarantees that
98+
// the returned set of shares will start with non-padding share(or empty set of shares).
99+
func (p *parser) skipPadding(shares []libshare.Share) ([]libshare.Share, error) {
100+
if len(shares) == 0 {
101+
return nil, errEmptyShares
102+
}
103+
104+
offset := 0
105+
for _, sh := range shares {
106+
if !sh.IsPadding() {
107+
break
108+
}
109+
offset++
110+
}
111+
// set start index
112+
p.index = offset
113+
if len(shares) > offset {
114+
return shares[offset:], nil
115+
}
116+
return nil, nil
117+
}
118+
119+
func (p *parser) verify(blob *Blob) bool {
120+
if p.verifyFn == nil {
121+
return false
122+
}
123+
return p.verifyFn(blob)
124+
}
125+
126+
func (p *parser) isEmpty() bool {
127+
return p.index == 0 && p.length == 0 && len(p.shares) == 0
128+
}
129+
130+
// reset cleans up parser, so it can be re-used within the same verify functionality.
131+
func (p *parser) reset() {
132+
p.index = 0
133+
p.length = 0
134+
p.shares = nil
135+
}

0 commit comments

Comments
 (0)