ChainStore: Add a tiebreaker rule for tipsets of equal weight
This commit is contained in:
parent
e68c8cb1ee
commit
44405bd1a0
@ -424,7 +424,13 @@ func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipS
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.GreaterThan(heaviestW) {
|
heavier := w.GreaterThan(heaviestW)
|
||||||
|
if w.Equals(heaviestW) && !ts.Equals(cs.heaviest) {
|
||||||
|
log.Errorw("weight draw", "currTs", cs.heaviest, "ts", ts)
|
||||||
|
heavier = breakWeightTie(ts, cs.heaviest)
|
||||||
|
}
|
||||||
|
|
||||||
|
if heavier {
|
||||||
// TODO: don't do this for initial sync. Now that we don't have a
|
// TODO: don't do this for initial sync. Now that we don't have a
|
||||||
// difference between 'bootstrap sync' and 'caught up' sync, we need
|
// difference between 'bootstrap sync' and 'caught up' sync, we need
|
||||||
// some other heuristic.
|
// some other heuristic.
|
||||||
@ -438,9 +444,8 @@ func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipS
|
|||||||
}
|
}
|
||||||
|
|
||||||
return cs.takeHeaviestTipSet(ctx, ts)
|
return cs.takeHeaviestTipSet(ctx, ts)
|
||||||
} else if w.Equals(heaviestW) && !ts.Equals(cs.heaviest) {
|
|
||||||
log.Errorw("weight draw", "currTs", cs.heaviest, "ts", ts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1165,3 +1170,22 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h abi.ChainEpoch, t
|
|||||||
func (cs *ChainStore) Weight(ctx context.Context, hts *types.TipSet) (types.BigInt, error) { // todo remove
|
func (cs *ChainStore) Weight(ctx context.Context, hts *types.TipSet) (types.BigInt, error) { // todo remove
|
||||||
return cs.weight(ctx, cs.StateBlockstore(), hts)
|
return cs.weight(ctx, cs.StateBlockstore(), hts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// true if ts1 wins according to the filecoin tie-break rule
|
||||||
|
func breakWeightTie(ts1, ts2 *types.TipSet) bool {
|
||||||
|
s := len(ts1.Blocks())
|
||||||
|
if s > len(ts2.Blocks()) {
|
||||||
|
s = len(ts2.Blocks())
|
||||||
|
}
|
||||||
|
|
||||||
|
// blocks are already sorted by ticket
|
||||||
|
for i := 0; i < s; i++ {
|
||||||
|
if ts1.Blocks()[i].Ticket.Less(ts2.Blocks()[i].Ticket) {
|
||||||
|
log.Infof("weight tie broken in favour of %s", ts1.Key())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("weight tie left unbroken, default to %s", ts2.Key())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user