feat: drand: refactor round verification
This commit is contained in:
parent
13248220a9
commit
a967a36445
@ -79,11 +79,21 @@ func ValidateBlockValues(bSchedule Schedule, nv network.Version, h *types.BlockH
|
|||||||
return xerrors.Errorf("expected to have beacon entries in this block, but didn't find any")
|
return xerrors.Errorf("expected to have beacon entries in this block, but didn't find any")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that the last beacon entry's round corresponds to the round we expect
|
||||||
last := h.BeaconEntries[len(h.BeaconEntries)-1]
|
last := h.BeaconEntries[len(h.BeaconEntries)-1]
|
||||||
if last.Round != maxRound {
|
if last.Round != maxRound {
|
||||||
return xerrors.Errorf("expected final beacon entry in block to be at round %d, got %d", maxRound, last.Round)
|
return xerrors.Errorf("expected final beacon entry in block to be at round %d, got %d", maxRound, last.Round)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that all other entries' rounds are as expected for the epochs in between parentEpoch and h.Height
|
||||||
|
for i, e := range h.BeaconEntries {
|
||||||
|
correctRound := b.MaxBeaconRoundForEpoch(nv, parentEpoch+abi.ChainEpoch(i)+1)
|
||||||
|
if e.Round != correctRound {
|
||||||
|
return xerrors.Errorf("unexpected beacon round %d, expected %d for epoch %d", e.Round, correctRound, parentEpoch+abi.ChainEpoch(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the beacon entries themselves
|
||||||
for i, e := range h.BeaconEntries {
|
for i, e := range h.BeaconEntries {
|
||||||
if err := b.VerifyEntry(e, prevEntry); err != nil {
|
if err := b.VerifyEntry(e, prevEntry); err != nil {
|
||||||
return xerrors.Errorf("beacon entry %d (%d - %x (%d)) was invalid: %w", i, e.Round, e.Data, len(e.Data), err)
|
return xerrors.Errorf("beacon entry %d (%d - %x (%d)) was invalid: %w", i, e.Round, e.Data, len(e.Data), err)
|
||||||
@ -132,10 +142,10 @@ func BeaconEntriesForBlock(ctx context.Context, bSchedule Schedule, nv network.V
|
|||||||
prev.Round = maxRound - 1
|
prev.Round = maxRound - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
cur := maxRound
|
|
||||||
var out []types.BeaconEntry
|
var out []types.BeaconEntry
|
||||||
for cur > prev.Round {
|
for currEpoch := epoch; currEpoch > parentEpoch; currEpoch-- {
|
||||||
rch := beacon.Entry(ctx, cur)
|
currRound := beacon.MaxBeaconRoundForEpoch(nv, currEpoch)
|
||||||
|
rch := beacon.Entry(ctx, currRound)
|
||||||
select {
|
select {
|
||||||
case resp := <-rch:
|
case resp := <-rch:
|
||||||
if resp.Err != nil {
|
if resp.Err != nil {
|
||||||
@ -143,7 +153,6 @@ func BeaconEntriesForBlock(ctx context.Context, bSchedule Schedule, nv network.V
|
|||||||
}
|
}
|
||||||
|
|
||||||
out = append(out, resp.Entry)
|
out = append(out, resp.Entry)
|
||||||
cur = resp.Entry.Round - 1
|
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil, xerrors.Errorf("context timed out waiting on beacon entry to come back for epoch %d: %w", epoch, ctx.Err())
|
return nil, xerrors.Errorf("context timed out waiting on beacon entry to come back for epoch %d: %w", epoch, ctx.Err())
|
||||||
}
|
}
|
||||||
|
@ -170,10 +170,6 @@ func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntr
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if curr.Round != prev.Round+1 {
|
|
||||||
return xerrors.Errorf("invalid beacon entry: cur (%d) != prev (%d) + 1", curr.Round, prev.Round)
|
|
||||||
}
|
|
||||||
|
|
||||||
if be := db.getCachedValue(curr.Round); be != nil {
|
if be := db.getCachedValue(curr.Round); be != nil {
|
||||||
if !bytes.Equal(curr.Data, be.Data) {
|
if !bytes.Equal(curr.Data, be.Data) {
|
||||||
return xerrors.New("invalid beacon value, does not match cached good value")
|
return xerrors.New("invalid beacon value, does not match cached good value")
|
||||||
@ -190,7 +186,8 @@ func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntr
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
db.cacheValue(curr)
|
db.cacheValue(curr)
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DrandBeacon) MaxBeaconRoundForEpoch(nv network.Version, filEpoch abi.ChainEpoch) uint64 {
|
func (db *DrandBeacon) MaxBeaconRoundForEpoch(nv network.Version, filEpoch abi.ChainEpoch) uint64 {
|
||||||
|
@ -704,25 +704,25 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, incoming *types.TipSet
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// ensure consistency of beacon entires
|
// ensure consistency of beacon entries
|
||||||
targetBE := incoming.Blocks()[0].BeaconEntries
|
targetBE := incoming.Blocks()[0].BeaconEntries
|
||||||
sorted := sort.SliceIsSorted(targetBE, func(i, j int) bool {
|
sorted := sort.SliceIsSorted(targetBE, func(i, j int) bool {
|
||||||
return targetBE[i].Round < targetBE[j].Round
|
return targetBE[i].Round < targetBE[j].Round
|
||||||
})
|
})
|
||||||
if !sorted {
|
if !sorted {
|
||||||
syncer.bad.Add(incoming.Cids()[0], NewBadBlockReason(incoming.Cids(), "wrong order of beacon entires"))
|
syncer.bad.Add(incoming.Cids()[0], NewBadBlockReason(incoming.Cids(), "wrong order of beacon entries"))
|
||||||
return nil, xerrors.Errorf("wrong order of beacon entires")
|
return nil, xerrors.Errorf("wrong order of beacon entries")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, bh := range incoming.Blocks()[1:] {
|
for _, bh := range incoming.Blocks()[1:] {
|
||||||
if len(targetBE) != len(bh.BeaconEntries) {
|
if len(targetBE) != len(bh.BeaconEntries) {
|
||||||
// cannot mark bad, I think @Kubuxu
|
// cannot mark bad, I think @Kubuxu
|
||||||
return nil, xerrors.Errorf("tipset contained different number for beacon entires")
|
return nil, xerrors.Errorf("tipset contained different number for beacon entries")
|
||||||
}
|
}
|
||||||
for i, be := range bh.BeaconEntries {
|
for i, be := range bh.BeaconEntries {
|
||||||
if targetBE[i].Round != be.Round || !bytes.Equal(targetBE[i].Data, be.Data) {
|
if targetBE[i].Round != be.Round || !bytes.Equal(targetBE[i].Data, be.Data) {
|
||||||
// cannot mark bad, I think @Kubuxu
|
// cannot mark bad, I think @Kubuxu
|
||||||
return nil, xerrors.Errorf("tipset contained different beacon entires")
|
return nil, xerrors.Errorf("tipset contained different beacon entries")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user