-
Notifications
You must be signed in to change notification settings - Fork 0
/
byzantine.go
62 lines (54 loc) · 1.57 KB
/
byzantine.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
package byzantine
import (
"context"
"fmt"
"github.com/ipfs/go-blockservice"
"github.com/furyaxyz/elysium-app/pkg/da"
"github.com/furyaxyz/rsmt2d"
"github.com/furyaxyz/elysium-node/share/ipld"
)
// ErrByzantine is a thrown when recovered data square is not correct
// (merkle proofs do not match parity erasure-coding data).
//
// It is converted from rsmt2d.ByzantineRow/Col +
// Merkle Proof for each share.
type ErrByzantine struct {
Index uint32
Shares []*ShareWithProof
Axis rsmt2d.Axis
}
func (e *ErrByzantine) Error() string {
return fmt.Sprintf("byzantine error(Axis:%v, Index:%v)", e.Axis, e.Index)
}
// NewErrByzantine creates new ErrByzantine from rsmt2d error.
// If error happens during proof collection, it terminates the process with os.Exit(1).
func NewErrByzantine(
ctx context.Context,
bGetter blockservice.BlockGetter,
dah *da.DataAvailabilityHeader,
errByz *rsmt2d.ErrByzantineData,
) *ErrByzantine {
root := [][][]byte{
dah.RowsRoots,
dah.ColumnRoots,
}[errByz.Axis][errByz.Index]
sharesWithProof, err := GetProofsForShares(
ctx,
bGetter,
ipld.MustCidFromNamespacedSha256(root),
errByz.Shares,
)
if err != nil {
// Fatal as rsmt2d proved that error is byzantine,
// but we cannot properly collect the proof,
// so verification will fail and thus services won't be stopped
// while we still have to stop them.
// TODO(@Wondertan): Find a better way to handle
log.Fatalw("getting proof for ErrByzantine", "err", err)
}
return &ErrByzantine{
Index: uint32(errByz.Index),
Shares: sharesWithProof,
Axis: errByz.Axis,
}
}