Skip to content

Commit

Permalink
feat(share/byzantine): handle additional cases in befp validation (ce…
Browse files Browse the repository at this point in the history
…lestiaorg#2383)

Co-authored-by: Hlib Kanunnikov <[email protected]>
  • Loading branch information
vgonkivs and Wondertan authored Jul 17, 2023
1 parent 03976ab commit 6a6c68c
Showing 1 changed file with 39 additions and 6 deletions.
45 changes: 39 additions & 6 deletions share/eds/byzantine/bad_encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package byzantine

import (
"bytes"
"errors"
"fmt"

"github.com/celestiaorg/celestia-app/pkg/wrapper"
Expand Down Expand Up @@ -114,6 +115,7 @@ func (p *BadEncodingProof) Validate(hdr libhead.Header) error {
if !ok {
panic(fmt.Sprintf("invalid header type received during BEFP validation: expected %T, got %T", header, hdr))
}

if header.Height() != int64(p.BlockHeight) {
return fmt.Errorf("incorrect block height during BEFP validation: expected %d, got %d",
p.BlockHeight, header.Height(),
Expand All @@ -137,11 +139,13 @@ func (p *BadEncodingProof) Validate(hdr libhead.Header) error {
if p.Axis == rsmt2d.Row {
merkleRoots = header.DAH.ColumnRoots
}

if int(p.Index) >= len(merkleRoots) {
return fmt.Errorf("invalid %s proof: index out of bounds (%d >= %d)",
BadEncoding, int(p.Index), len(merkleRoots),
)
}

if len(p.Shares) != len(merkleRoots) {
// Since p.Shares should contain all the shares from either a row or a
// column, it should exactly match the number of row roots. In this
Expand All @@ -152,6 +156,22 @@ func (p *BadEncodingProof) Validate(hdr libhead.Header) error {
)
}

odsWidth := uint64(len(merkleRoots) / 2)
amount := uint64(0)
for _, share := range p.Shares {
if share == nil {
continue
}
amount++
if amount == odsWidth {
break
}
}

if amount < odsWidth {
return errors.New("fraud: invalid proof: not enough shares provided to reconstruct row/col")
}

// verify that Merkle proofs correspond to particular shares.
shares := make([][]byte, len(merkleRoots))
for index, shr := range p.Shares {
Expand All @@ -167,31 +187,44 @@ func (p *BadEncodingProof) Validate(hdr libhead.Header) error {
shares[index] = share.GetData(shr.Share)
}

odsWidth := uint64(len(merkleRoots) / 2)
codec := share.DefaultRSMT2DCodec()

// rebuild a row or col.
// We can conclude that the proof is valid in case we proved the inclusion of `Shares` but
// the row/col can't be reconstructed, or the building of NMTree fails.
rebuiltShares, err := codec.Decode(shares)
if err != nil {
return err
log.Infow("failed to decode shares at height",
"height", header.Height(), "err", err,
)
return nil
}

rebuiltExtendedShares, err := codec.Encode(rebuiltShares[0:odsWidth])
if err != nil {
return err
log.Infow("failed to encode shares at height",
"height", header.Height(), "err", err,
)
return nil
}
copy(rebuiltShares[odsWidth:], rebuiltExtendedShares)

tree := wrapper.NewErasuredNamespacedMerkleTree(odsWidth, uint(p.Index))
for _, share := range rebuiltShares {
err = tree.Push(share)
if err != nil {
return err
log.Infow("failed to build a tree from the reconstructed shares at height",
"height", header.Height(), "err", err,
)
return nil
}
}

expectedRoot, err := tree.Root()
if err != nil {
return err
log.Infow("failed to build a tree root at height",
"height", header.Height(), "err", err,
)
return nil
}

// root is a merkle root of the row/col where ErrByzantine occurred
Expand Down

0 comments on commit 6a6c68c

Please sign in to comment.