actors: Fallback post progress

This commit is contained in:
Łukasz Magiera 2019-11-28 13:46:56 +01:00
parent 7afc0d4dbe
commit aefd432422
10 changed files with 84 additions and 60 deletions

View File

@ -31,7 +31,7 @@ func SupportedSectorSize(ssize uint64) bool {
// ///// // /////
// Payments // Payments
// Blocks // Epochs
const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours
// ///// // /////
@ -40,13 +40,13 @@ const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours
// Seconds // Seconds
const AllowableClockDrift = BlockDelay * 2 const AllowableClockDrift = BlockDelay * 2
// Blocks // Epochs
const ForkLengthThreshold = Finality const ForkLengthThreshold = Finality
// Blocks (e) // Blocks (e)
const BlocksPerEpoch = 5 const BlocksPerEpoch = 5
// Blocks // Epochs
const Finality = 500 const Finality = 500
// constants for Weight calculation // constants for Weight calculation
@ -57,40 +57,45 @@ const WRatioDen = 2
// ///// // /////
// Proofs // Proofs
// PoStChallangeTime sets the window in which post computation should happen
// Blocks
const PoStChallangeTime = ProvingPeriodDuration - 6
// PoStRandomnessLookback is additional randomness lookback for PoSt computation // PoStRandomnessLookback is additional randomness lookback for PoSt computation
// To compute randomness epoch in a given proving period: // To compute randomness epoch in a given proving period:
// RandH = PPE - PoStChallangeTime - PoStRandomnessLookback // RandH = PPE - PoStChallangeTime - PoStRandomnessLookback
// //
// Blocks // Epochs
const PoStRandomnessLookback = 1 const PoStRandomnessLookback = 1
// Blocks // Epochs
const SealRandomnessLookback = Finality const SealRandomnessLookback = Finality
// Blocks // Epochs
const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000 const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000
// 1 / n // 1 / n
const SectorChallengeRatioDiv = 25 const SectorChallengeRatioDiv = 25
const MaxFallbackPostChallengeCount = 10
// FallbackPoStBegin is the number of epochs the miner needs to wait after
// ElectionPeriodStart before starting fallback post computation
//
// Epochs
const FallbackPoStBegin = 1000
// SlashablePowerDelay is the number of epochs
// Epochs
const SlashablePowerDelay = 2000
// ///// // /////
// Mining // Mining
// Blocks // Epochs
const EcRandomnessLookback = 300 const EcRandomnessLookback = 300
const FallbackPoStBegin = 1000
const SlashablePowerDelay = 2000
const PowerCollateralProportion = 5 const PowerCollateralProportion = 5
const PerCapitaCollateralProportion = 1 const PerCapitaCollateralProportion = 1
const CollateralPrecision = 1000 const CollateralPrecision = 1000
// Blocks // Epochs
const InteractivePoRepDelay = 10 const InteractivePoRepDelay = 10
// ///// // /////
@ -106,8 +111,8 @@ var InitialReward *big.Int
const FilecoinPrecision = 1_000_000_000_000_000_000 const FilecoinPrecision = 1_000_000_000_000_000_000
// six years // six years
// Blocks // Epochs
const HalvingPeriodBlocks = 6 * 365 * 24 * 60 * 2 const HalvingPeriodEpochs = 6 * 365 * 24 * 60 * 2
// TODO: Move other important consts here // TODO: Move other important consts here
@ -125,6 +130,6 @@ func init() {
// Sync // Sync
const BadBlockCacheSize = 1 << 15 const BadBlockCacheSize = 1 << 15
// assuming 4000 blocks per round, this lets us not lose any messages across a // assuming 4000 messages per round, this lets us not lose any messages across a
// 10 block reorg. // 10 block reorg.
const BlsSignatureCacheSize = 40000 const BlsSignatureCacheSize = 40000

View File

@ -391,14 +391,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC
type SubmitPoStParams struct { type SubmitPoStParams struct {
Proof []byte Proof []byte
} Candidates []types.EPostTicket
func ProvingPeriodEnd(setPeriodEnd, height uint64) (uint64, uint64) {
offset := setPeriodEnd % build.ProvingPeriodDuration
period := ((height - offset - 1) / build.ProvingPeriodDuration) + 1
end := (period * build.ProvingPeriodDuration) + offset
return end, period
} }
func (sma StorageMinerActor) SubmitFallbackPoSt(act *types.Actor, vmctx types.VMContext, params *SubmitPoStParams) ([]byte, ActorError) { func (sma StorageMinerActor) SubmitFallbackPoSt(act *types.Actor, vmctx types.VMContext, params *SubmitPoStParams) ([]byte, ActorError) {
@ -482,13 +475,21 @@ func (sma StorageMinerActor) SubmitFallbackPoSt(act *types.Actor, vmctx types.VM
faults := self.CurrentFaultSet.All() faults := self.CurrentFaultSet.All()
_ = faults _ = faults
_ = seed
//VerifyPoStRandomness()
proverID := vmctx.Message().To // TODO: normalize to ID address proverID := vmctx.Message().To // TODO: normalize to ID address
if ok, lerr := sectorbuilder.VerifyPost(vmctx.Context(), mi.SectorSize, var candidates []sectorbuilder.EPostCandidate
sectorbuilder.NewSortedPublicSectorInfo(sectorInfos), params.Proof.PostRand, params.Proof.Proof, winners, proverID); !ok || lerr != nil { for _, t := range params.Candidates {
var partial [32]byte
copy(partial[:], t.Partial)
candidates = append(candidates, sectorbuilder.EPostCandidate{
PartialTicket: partial,
SectorID: t.SectorID,
SectorChallengeIndex: t.ChallengeIndex,
})
}
if ok, lerr := sectorbuilder.VerifyFallbackPost(vmctx.Context(), mi.SectorSize,
sectorbuilder.NewSortedPublicSectorInfo(sectorInfos), seed[:], params.Proof, candidates, proverID); !ok || lerr != nil {
if lerr != nil { if lerr != nil {
// TODO: study PoST errors // TODO: study PoST errors
return nil, aerrors.Absorb(lerr, 4, "PoST error") return nil, aerrors.Absorb(lerr, 4, "PoST error")

View File

@ -506,7 +506,7 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add
PostRand: vrfout, PostRand: vrfout,
} }
for _, win := range winners { for _, win := range winners {
ept.Winners = append(ept.Winners, types.EPostTicket{ ept.Candidates = append(ept.Candidates, types.EPostTicket{
Partial: win.PartialTicket[:], Partial: win.PartialTicket[:],
SectorID: win.SectorID, SectorID: win.SectorID,
ChallengeIndex: win.SectorChallengeIndex, ChallengeIndex: win.SectorChallengeIndex,

View File

@ -555,7 +555,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return xerrors.Errorf("failed to get sector size for block miner: %w", err) return xerrors.Errorf("failed to get sector size for block miner: %w", err)
} }
for _, t := range h.EPostProof.Winners { for _, t := range h.EPostProof.Candidates {
if !types.IsTicketWinner(t.Partial, ssize, tpow, 1) { if !types.IsTicketWinner(t.Partial, ssize, tpow, 1) {
return xerrors.Errorf("miner created a block but was not a winner") return xerrors.Errorf("miner created a block but was not a winner")
} }
@ -667,7 +667,7 @@ func (syncer *Syncer) VerifyElectionPoStProof(ctx context.Context, h *types.Bloc
} }
var winners []sectorbuilder.EPostCandidate var winners []sectorbuilder.EPostCandidate
for _, t := range h.EPostProof.Winners { for _, t := range h.EPostProof.Candidates {
var partial [32]byte var partial [32]byte
copy(partial[:], t.Partial) copy(partial[:], t.Partial)
winners = append(winners, sectorbuilder.EPostCandidate{ winners = append(winners, sectorbuilder.EPostCandidate{
@ -689,7 +689,7 @@ func (syncer *Syncer) VerifyElectionPoStProof(ctx context.Context, h *types.Bloc
return xerrors.Errorf("[TESTING] election post was invalid") return xerrors.Errorf("[TESTING] election post was invalid")
} }
hvrf := sha256.Sum256(h.EPostProof.PostRand) hvrf := sha256.Sum256(h.EPostProof.PostRand)
ok, err := sectorbuilder.VerifyPost(ctx, ssize, *sectorInfo, hvrf[:], h.EPostProof.Proof, winners, h.Miner) ok, err := sectorbuilder.VerifyElectionPost(ctx, ssize, *sectorInfo, hvrf[:], h.EPostProof.Proof, winners, h.Miner)
if err != nil { if err != nil {
return xerrors.Errorf("failed to verify election post: %w", err) return xerrors.Errorf("failed to verify election post: %w", err)
} }

View File

@ -29,7 +29,7 @@ type EPostTicket struct {
type EPostProof struct { type EPostProof struct {
Proof []byte Proof []byte
PostRand []byte PostRand []byte
Winners []EPostTicket Candidates []EPostTicket
} }
type BlockHeader struct { type BlockHeader struct {

View File

@ -349,11 +349,11 @@ func (t *EPostProof) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.t.Winners ([]types.EPostTicket) (slice) // t.t.Candidates ([]types.EPostTicket) (slice)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Winners)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Candidates)))); err != nil {
return err return err
} }
for _, v := range t.Winners { for _, v := range t.Candidates {
if err := v.MarshalCBOR(w); err != nil { if err := v.MarshalCBOR(w); err != nil {
return err return err
} }
@ -410,21 +410,21 @@ func (t *EPostProof) UnmarshalCBOR(r io.Reader) error {
if _, err := io.ReadFull(br, t.PostRand); err != nil { if _, err := io.ReadFull(br, t.PostRand); err != nil {
return err return err
} }
// t.t.Winners ([]types.EPostTicket) (slice) // t.t.Candidates ([]types.EPostTicket) (slice)
maj, extra, err = cbg.CborReadHeader(br) maj, extra, err = cbg.CborReadHeader(br)
if err != nil { if err != nil {
return err return err
} }
if extra > 8192 { if extra > 8192 {
return fmt.Errorf("t.Winners: array too large (%d)", extra) return fmt.Errorf("t.Candidates: array too large (%d)", extra)
} }
if maj != cbg.MajArray { if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array") return fmt.Errorf("expected cbor array")
} }
if extra > 0 { if extra > 0 {
t.Winners = make([]EPostTicket, extra) t.Candidates = make([]EPostTicket, extra)
} }
for i := 0; i < int(extra); i++ { for i := 0; i < int(extra); i++ {
@ -433,7 +433,7 @@ func (t *EPostProof) UnmarshalCBOR(r io.Reader) error {
return err return err
} }
t.Winners[i] = v t.Candidates[i] = v
} }
return nil return nil

View File

@ -12,7 +12,7 @@ import (
func TestBlockReward(t *testing.T) { func TestBlockReward(t *testing.T) {
coffer := types.FromFil(build.MiningRewardTotal).Int coffer := types.FromFil(build.MiningRewardTotal).Int
sum := new(big.Int) sum := new(big.Int)
N := build.HalvingPeriodBlocks N := build.HalvingPeriodEpochs
for i := 0; i < N; i++ { for i := 0; i < N; i++ {
a := MiningReward(types.BigInt{coffer}) a := MiningReward(types.BigInt{coffer})
sum = sum.Add(sum, a.Int) sum = sum.Add(sum, a.Int)

View File

@ -192,7 +192,7 @@ func main() {
epost := time.Now() epost := time.Now()
ok, err := sectorbuilder.VerifyPost(context.TODO(), sectorSize, sinfos, challenge[:], proof, candidates[:1], maddr) ok, err := sectorbuilder.VerifyElectionPost(context.TODO(), sectorSize, sinfos, challenge[:], proof, candidates[:1], maddr)
if err != nil { if err != nil {
return err return err
} }

View File

@ -299,7 +299,7 @@ func (sb *SectorBuilder) GenerateEPostCandidates(sectorInfo SortedPublicSectorIn
return nil, err return nil, err
} }
challengeCount := challengeCount(uint64(len(sectorInfo.Values()))) challengeCount := electionPostChallengeCount(uint64(len(sectorInfo.Values())))
proverID := addressToProverID(sb.Miner) proverID := addressToProverID(sb.Miner)
return sectorbuilder.GenerateCandidates(sb.ssize, proverID, challengeSeed, challengeCount, privsectors) return sectorbuilder.GenerateCandidates(sb.ssize, proverID, challengeSeed, challengeCount, privsectors)
@ -334,10 +334,7 @@ func (sb *SectorBuilder) GenerateFallbackPoSt(sectorInfo SortedPublicSectorInfo,
return nil, err return nil, err
} }
challengeCount := challengeCount(uint64(len(sectorInfo.Values()))) challengeCount := fallbackPostChallengeCount(uint64(len(sectorInfo.Values())))
if challengeCount > 10 {
challengeCount = 10
}
proverID := addressToProverID(sb.Miner) proverID := addressToProverID(sb.Miner)
candidates, err := sectorbuilder.GenerateCandidates(sb.ssize, proverID, challengeSeed, challengeCount, privsectors) candidates, err := sectorbuilder.GenerateCandidates(sb.ssize, proverID, challengeSeed, challengeCount, privsectors)
@ -369,16 +366,29 @@ func NewSortedPublicSectorInfo(sectors []sectorbuilder.PublicSectorInfo) SortedP
return sectorbuilder.NewSortedPublicSectorInfo(sectors...) return sectorbuilder.NewSortedPublicSectorInfo(sectors...)
} }
func VerifyPost(ctx context.Context, sectorSize uint64, sectorInfo SortedPublicSectorInfo, challengeSeed []byte, proof []byte, winners []EPostCandidate, proverID address.Address) (bool, error) { func VerifyElectionPost(ctx context.Context, sectorSize uint64, sectorInfo SortedPublicSectorInfo, challengeSeed []byte, proof []byte, candidates []EPostCandidate, proverID address.Address) (bool, error) {
challengeCount := electionPostChallengeCount(uint64(len(sectorInfo.Values())))
return verifyPost(ctx, sectorSize, sectorInfo, challengeCount, challengeSeed, proof, candidates, proverID)
}
func VerifyFallbackPost(ctx context.Context, sectorSize uint64, sectorInfo SortedPublicSectorInfo, challengeSeed []byte, proof []byte, candidates []EPostCandidate, proverID address.Address) (bool, error) {
challengeCount := fallbackPostChallengeCount(uint64(len(sectorInfo.Values())))
return verifyPost(ctx, sectorSize, sectorInfo, challengeCount, challengeSeed, proof, candidates, proverID)
}
func verifyPost(ctx context.Context, sectorSize uint64, sectorInfo SortedPublicSectorInfo, challengeCount uint64, challengeSeed []byte, proof []byte, candidates []EPostCandidate, proverID address.Address) (bool, error) {
if challengeCount != uint64(len(candidates)) {
log.Warnf("verifyPost with wrong candidate count: expected %d, got %d", challengeCount, len(candidates))
return false, nil // user input, dont't error
}
var challengeSeeda [CommLen]byte var challengeSeeda [CommLen]byte
copy(challengeSeeda[:], challengeSeed) copy(challengeSeeda[:], challengeSeed)
challengeCount := challengeCount(uint64(len(sectorInfo.Values())))
_, span := trace.StartSpan(ctx, "VerifyPoSt") _, span := trace.StartSpan(ctx, "VerifyPoSt")
defer span.End() defer span.End()
prover := addressToProverID(proverID) prover := addressToProverID(proverID)
return sectorbuilder.VerifyPoSt(sectorSize, sectorInfo, challengeSeeda, challengeCount, proof, winners, prover) return sectorbuilder.VerifyPoSt(sectorSize, sectorInfo, challengeSeeda, challengeCount, proof, candidates, prover)
} }
func GeneratePieceCommitment(piece io.Reader, pieceSize uint64) (commP [CommLen]byte, err error) { func GeneratePieceCommitment(piece io.Reader, pieceSize uint64) (commP [CommLen]byte, err error) {
@ -399,7 +409,15 @@ func GenerateDataCommitment(ssize uint64, pieces []PublicPieceInfo) ([CommLen]by
return sectorbuilder.GenerateDataCommitment(ssize, pieces) return sectorbuilder.GenerateDataCommitment(ssize, pieces)
} }
func challengeCount(sectors uint64) uint64 { func electionPostChallengeCount(sectors uint64) uint64 {
// ceil(sectors / build.SectorChallengeRatioDiv) // ceil(sectors / build.SectorChallengeRatioDiv)
return (sectors + build.SectorChallengeRatioDiv - 1) / build.SectorChallengeRatioDiv return (sectors + build.SectorChallengeRatioDiv - 1) / build.SectorChallengeRatioDiv
} }
func fallbackPostChallengeCount(sectors uint64) uint64 {
challengeCount := electionPostChallengeCount(sectors)
if challengeCount > build.MaxFallbackPostChallengeCount {
return build.MaxFallbackPostChallengeCount
}
return challengeCount
}

View File

@ -102,7 +102,7 @@ func (s *seal) post(t *testing.T, sb *sectorbuilder.SectorBuilder) time.Time {
t.Fatalf("%+v", err) t.Fatalf("%+v", err)
} }
ok, err := sectorbuilder.VerifyPost(context.TODO(), sb.SectorSize(), ssi, cSeed[:], postProof, candndates, sb.Miner) ok, err := sectorbuilder.VerifyElectionPost(context.TODO(), sb.SectorSize(), ssi, cSeed[:], postProof, candndates, sb.Miner)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatalf("%+v", err)
} }