feat: drand: refactor round verification
This commit is contained in:
parent
8f73f15793
commit
6a6b03ef40
@ -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")
|
||||
}
|
||||
|
||||
// Verify that the last beacon entry's round corresponds to the round we expect
|
||||
last := h.BeaconEntries[len(h.BeaconEntries)-1]
|
||||
if last.Round != maxRound {
|
||||
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 {
|
||||
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)
|
||||
@ -132,10 +142,10 @@ func BeaconEntriesForBlock(ctx context.Context, bSchedule Schedule, nv network.V
|
||||
prev.Round = maxRound - 1
|
||||
}
|
||||
|
||||
cur := maxRound
|
||||
var out []types.BeaconEntry
|
||||
for cur > prev.Round {
|
||||
rch := beacon.Entry(ctx, cur)
|
||||
for currEpoch := epoch; currEpoch > parentEpoch; currEpoch-- {
|
||||
currRound := beacon.MaxBeaconRoundForEpoch(nv, currEpoch)
|
||||
rch := beacon.Entry(ctx, currRound)
|
||||
select {
|
||||
case resp := <-rch:
|
||||
if resp.Err != nil {
|
||||
@ -143,7 +153,6 @@ func BeaconEntriesForBlock(ctx context.Context, bSchedule Schedule, nv network.V
|
||||
}
|
||||
|
||||
out = append(out, resp.Entry)
|
||||
cur = resp.Entry.Round - 1
|
||||
case <-ctx.Done():
|
||||
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
|
||||
}
|
||||
|
||||
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 !bytes.Equal(curr.Data, be.Data) {
|
||||
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 {
|
||||
db.cacheValue(curr)
|
||||
}
|
||||
return err
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
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
|
||||
sorted := sort.SliceIsSorted(targetBE, func(i, j int) bool {
|
||||
return targetBE[i].Round < targetBE[j].Round
|
||||
})
|
||||
if !sorted {
|
||||
syncer.bad.Add(incoming.Cids()[0], NewBadBlockReason(incoming.Cids(), "wrong order of beacon entires"))
|
||||
return nil, xerrors.Errorf("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 entries")
|
||||
}
|
||||
|
||||
for _, bh := range incoming.Blocks()[1:] {
|
||||
if len(targetBE) != len(bh.BeaconEntries) {
|
||||
// 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 {
|
||||
if targetBE[i].Round != be.Round || !bytes.Equal(targetBE[i].Data, be.Data) {
|
||||
// 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