Integrate Poisson Sortition into chain sync

Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
This commit is contained in:
Jakub Sztandera 2020-06-23 16:59:44 +02:00
parent 97088e3109
commit 156a14eeeb
No known key found for this signature in database
GPG Key ID: 9A9AF56F8B3879BA
4 changed files with 33 additions and 11 deletions

View File

@ -559,11 +559,15 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch,
}
// TODO: wire in real power
if !types.IsTicketWinner(vrfout, mbi.MinerPower, mbi.NetworkPower) {
// TODO: is above TODO still applicable?
ep := &types.ElectionProof{VRFProof: vrfout}
j := ep.ComputeWinCount(mbi.MinerPower, mbi.NetworkPower)
ep.WinCount = j
if j < 1 {
return nil, nil
}
return &types.ElectionProof{VRFProof: vrfout}, nil
return ep, nil
}
type SignFunc func(context.Context, address.Address, []byte) (*crypto.Signature, error)

View File

@ -21,11 +21,11 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
if ts == nil {
return types.NewInt(0), nil
}
// >>> w[r] <<< + wFunction(totalPowerAtTipset(ts)) * 2^8 + (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
// >>> w[r] <<< + wFunction(totalPowerAtTipset(ts)) * 2^8 + (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks.ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den)
var out = new(big.Int).Set(ts.Blocks()[0].ParentWeight.Int)
// >>> wFunction(totalPowerAtTipset(ts)) * 2^8 <<< + (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
// >>> wFunction(totalPowerAtTipset(ts)) * 2^8 <<< + (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks.ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den)
tpow := big2.Zero()
{
@ -57,11 +57,19 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
out.Add(out, big.NewInt(log2P<<8))
// (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
// (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks.ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den)
eWeight := big.NewInt((log2P * int64(len(ts.Blocks())) * build.WRatioNum) << 8)
eWeight.Div(eWeight, big.NewInt(int64(build.BlocksPerEpoch*build.WRatioDen)))
out.Add(out, eWeight)
totalJ := uint64(0)
for _, b := range ts.Blocks() {
totalJ += b.ElectionProof.WinCount
}
eWeight := big.NewInt((log2P * build.WRatioNum))
eWeight = eWeight.Lsh(eWeight, 8)
eWeight = eWeight.Mul(eWeight, new(big.Int).SetUint64(totalJ))
eWeight = eWeight.Div(eWeight, big.NewInt(int64(build.BlocksPerEpoch*build.WRatioDen)))
out = out.Add(out, eWeight)
return types.BigInt{Int: out}, nil
}

View File

@ -210,6 +210,12 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub
return pubsub.ValidationReject
}
if blk.Header.ElectionProof.WinCount < 1 {
log.Errorf("block is not claiming to be winning")
recordFailure("not_winning")
return pubsub.ValidationReject
}
// it's a good block! make sure we've only seen it once
if bv.recvBlocks.add(blk.Header.Cid()) > 0 {
// TODO: once these changes propagate to the network, we can consider

View File

@ -651,6 +651,10 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
}
winnerCheck := async.Err(func() error {
if h.ElectionProof.WinCount < 1 {
return xerrors.Errorf("block is not claiming to be a winner")
}
rBeacon := *prevBeacon
if len(h.BeaconEntries) != 0 {
rBeacon = h.BeaconEntries[len(h.BeaconEntries)-1]
@ -660,7 +664,6 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
return xerrors.Errorf("failed to marshal miner address to cbor: %w", err)
}
//TODO: DST from spec actors when it is there
vrfBase, err := store.DrawRandomness(rBeacon.Data, crypto.DomainSeparationTag_ElectionProofProduction, h.Height, buf.Bytes())
if err != nil {
return xerrors.Errorf("could not draw randomness: %w", err)
@ -684,8 +687,9 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
return xerrors.Errorf("failed getting power: %w", err)
}
if !types.IsTicketWinner(h.ElectionProof.VRFProof, mpow.QualityAdjPower, tpow.QualityAdjPower) {
return xerrors.Errorf("miner created a block but was not a winner")
j := h.ElectionProof.ComputeWinCount(mpow.QualityAdjPower, tpow.QualityAdjPower)
if h.ElectionProof.WinCount != j {
return xerrors.Errorf("miner claims wrong number of wins: miner: %d, computed: %d", h.ElectionProof.WinCount, j)
}
return nil