github.com/sunrise-zone/sunrise-node@v0.13.1-sr2/share/eds/byzantine/byzantine.go (about)

     1  package byzantine
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/ipfs/boxo/blockservice"
     8  
     9  	"github.com/celestiaorg/rsmt2d"
    10  	"github.com/sunrise-zone/sunrise-app/pkg/da"
    11  
    12  	"github.com/sunrise-zone/sunrise-node/share/ipld"
    13  )
    14  
    15  // ErrByzantine is a thrown when recovered data square is not correct
    16  // (merkle proofs do not match parity erasure-coding data).
    17  //
    18  // It is converted from rsmt2d.ByzantineRow/Col +
    19  // Merkle Proof for each share.
    20  type ErrByzantine struct {
    21  	Index  uint32
    22  	Shares []*ShareWithProof
    23  	Axis   rsmt2d.Axis
    24  }
    25  
    26  func (e *ErrByzantine) Error() string {
    27  	return fmt.Sprintf("byzantine error(Axis:%v, Index:%v)", e.Axis, e.Index)
    28  }
    29  
    30  // NewErrByzantine creates new ErrByzantine from rsmt2d error.
    31  // If error happens during proof collection, it terminates the process with os.Exit(1).
    32  func NewErrByzantine(
    33  	ctx context.Context,
    34  	bGetter blockservice.BlockGetter,
    35  	dah *da.DataAvailabilityHeader,
    36  	errByz *rsmt2d.ErrByzantineData,
    37  ) error {
    38  	// changing the order to collect proofs against an orthogonal axis
    39  	roots := [][][]byte{
    40  		dah.ColumnRoots,
    41  		dah.RowRoots,
    42  	}[errByz.Axis]
    43  
    44  	sharesWithProof := make([]*ShareWithProof, len(errByz.Shares))
    45  
    46  	type result struct {
    47  		share *ShareWithProof
    48  		index int
    49  	}
    50  	resultCh := make(chan *result)
    51  	for index, share := range errByz.Shares {
    52  		if share == nil {
    53  			continue
    54  		}
    55  
    56  		index := index
    57  		go func() {
    58  			share, err := getProofsAt(
    59  				ctx, bGetter,
    60  				ipld.MustCidFromNamespacedSha256(roots[index]),
    61  				int(errByz.Index), len(errByz.Shares),
    62  			)
    63  			if err != nil {
    64  				log.Warn("requesting proof failed", "root", roots[index], "err", err)
    65  				return
    66  			}
    67  			resultCh <- &result{share, index}
    68  		}()
    69  	}
    70  
    71  	for i := 0; i < len(dah.RowRoots)/2; i++ {
    72  		select {
    73  		case t := <-resultCh:
    74  			sharesWithProof[t.index] = t.share
    75  		case <-ctx.Done():
    76  			return ipld.ErrNodeNotFound
    77  		}
    78  	}
    79  
    80  	return &ErrByzantine{
    81  		Index:  uint32(errByz.Index),
    82  		Shares: sharesWithProof,
    83  		Axis:   errByz.Axis,
    84  	}
    85  }