Tests pass

Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
This commit is contained in:
Jakub Sztandera 2020-04-08 18:31:16 +02:00
parent 8e0ca306d2
commit f1c890ca54
7 changed files with 71 additions and 49 deletions

View File

@ -124,7 +124,7 @@ func (mb *mockBeacon) IsEntryForEpoch(e types.BeaconEntry, epoch abi.ChainEpoch,
func (mb *mockBeacon) BeaconRoundsForEpoch(epoch abi.ChainEpoch, prevEntry types.BeaconEntry) []uint64 {
var out []uint64
for i := prevEntry.Round + 1; i < uint64(epoch); i++ {
for i := prevEntry.Round + 1; i <= uint64(epoch); i++ {
out = append(out, i)
}
return out

View File

@ -280,12 +280,30 @@ func CarWalkFunc(nd format.Node) (out []*format.Link, err error) {
func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m address.Address, round abi.ChainEpoch) ([]types.BeaconEntry, *types.Ticket, error) {
mc := &mca{w: cg.w, sm: cg.sm}
prev, err := cg.cs.GetLatestBeaconEntry(pts)
if err != nil {
return nil, nil, xerrors.Errorf("getLatestBeaconEntry: %w", err)
}
entries, err := beacon.BeaconEntriesForBlock(ctx, cg.beacon, abi.ChainEpoch(round), *prev)
if err != nil {
return nil, nil, xerrors.Errorf("get beacon entries for block: %w", err)
}
if len(entries) == 0 {
panic("no drand")
}
rbase := *prev
if len(entries) > 0 {
rbase = entries[len(entries)-1]
}
buf := new(bytes.Buffer)
if err := m.MarshalCBOR(buf); err != nil {
return nil, nil, xerrors.Errorf("failed to cbor marshal address: %w", err)
}
ticketRand, err := mc.ChainGetRandomness(ctx, pts.Key(), crypto.DomainSeparationTag_TicketProduction, abi.ChainEpoch(round-build.EcRandomnessLookback), buf.Bytes())
ticketRand, err := store.DrawRandomness(rbase.Data, 17, round, buf.Bytes())
if err != nil {
return nil, nil, err
}
@ -306,21 +324,6 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
VRFProof: vrfout,
}
prev, err := cg.cs.GetLatestBeaconEntry(pts)
if err != nil {
return nil, nil, xerrors.Errorf("getLatestBeaconEntry: %w", err)
}
entries, err := beacon.BeaconEntriesForBlock(ctx, cg.beacon, abi.ChainEpoch(round), *prev)
if err != nil {
return nil, nil, xerrors.Errorf("get beacon entries for block: %w", err)
}
rbase := *prev
if len(entries) > 0 {
rbase = entries[len(entries)-1]
}
// TODO winning post return?
_, err = IsRoundWinner(ctx, pts, round, m, rbase, mc)
if err != nil {
@ -359,6 +362,9 @@ func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Ad
if err != nil {
return nil, xerrors.Errorf("next block proof: %w", err)
}
if len(bvals) == 0 {
panic("no drand")
}
if t != nil {
// TODO: winning post proof

View File

@ -893,6 +893,7 @@ func (cs *ChainStore) TryFillTipSet(ts *types.TipSet) (*FullTipSet, error) {
}
func DrawRandomness(rbase []byte, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
// log.Desugar().WithOptions(zap.AddCallerSkip(2)).Sugar().Warnw("DrawRandomness", "base", rbase, "dsep", pers, "round", round, "entropy", entropy)
h := blake2b.New256()
if err := binary.Write(h, binary.BigEndian, int64(pers)); err != nil {
return nil, xerrors.Errorf("deriving randomness: %w", err)

View File

@ -511,12 +511,12 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return xerrors.Errorf("load parent tipset failed (%s): %w", h.Parents, err)
}
prevBeacon, err := syncer.getLatestBeaconEntry(baseTs)
prevBeacon, err := syncer.store.GetLatestBeaconEntry(baseTs)
if err != nil {
return xerrors.Errorf("failed to get latest beacon entry: %w", err)
}
nulls := h.Height - (baseTs.Height() + 1)
//nulls := h.Height - (baseTs.Height() + 1)
// fast checks first
if h.BlockSig == nil {
@ -614,7 +614,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
})
beaconValuesCheck := async.Err(func() error {
if err := beacon.ValidateBlockValues(syncer.beacon, h, int(nulls)); err != nil {
if err := beacon.ValidateBlockValues(syncer.beacon, h, *prevBeacon); err != nil {
return xerrors.Errorf("failed to validate blocks random beacon values: %w", err)
}
// TODO: check if first value links to value from previous block/previous block containing a value
@ -622,14 +622,9 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
})
tktsCheck := async.Err(func() error {
buf := new(bytes.Buffer)
if err := h.Miner.MarshalCBOR(buf); err != nil {
return xerrors.Errorf("failed to marshal miner address to cbor: %w", err)
}
baseBeacon := prevBeacon
if len(h.BeaconEntries) > 0 {
baseBeacon = h.BeaconEntries[len(h.BeaconEntries)-1]
baseBeacon = &h.BeaconEntries[len(h.BeaconEntries)-1]
}
buf := new(bytes.Buffer)
@ -638,7 +633,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
}
// TODO: use real DST from specs actors when it lands
vrfBase, err := store.DrawRandomness(baseBeacon.Data, 17, int64(h.Height), buf.Bytes())
vrfBase, err := store.DrawRandomness(baseBeacon.Data, 17, h.Height, buf.Bytes())
if err != nil {
return xerrors.Errorf("failed to compute vrf base for ticket: %w", err)
}
@ -650,19 +645,19 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return nil
})
eproofCheck := async.Err(func() error {
if err := syncer.VerifyElectionPoStProof(ctx, h, waddr); err != nil {
return xerrors.Errorf("invalid election post: %w", err)
}
return nil
})
//eproofCheck := async.Err(func() error {
//if err := syncer.VerifyElectionPoStProof(ctx, h, waddr); err != nil {
//return xerrors.Errorf("invalid election post: %w", err)
//}
//return nil
//})
await := []async.ErrorFuture{
minerCheck,
tktsCheck,
blockSigCheck,
beaconValuesCheck,
eproofCheck,
//eproofCheck,
winnerCheck,
msgsCheck,
}
@ -704,7 +699,7 @@ func (syncer *Syncer) VerifyElectionPoStProof(ctx context.Context, h *types.Bloc
if err := h.Miner.MarshalCBOR(buf); err != nil {
return xerrors.Errorf("failed to marshal miner to cbor: %w", err)
}
rand, err := syncer.sm.ChainStore().GetRandomness(ctx, curTs.Cids(), crypto.DomainSeparationTag_ElectionPoStChallengeSeed, int64(h.Height-build.EcRandomnessLookback), buf.Bytes())
rand, err := syncer.sm.ChainStore().GetRandomness(ctx, curTs.Cids(), crypto.DomainSeparationTag_ElectionPoStChallengeSeed, h.Height-build.EcRandomnessLookback, buf.Bytes())
if err != nil {
return xerrors.Errorf("failed to get randomness for verifying election proof: %w", err)
}
@ -979,10 +974,10 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to
syncer.bad.Add(from.Cids()[0], "no beacon entires")
return nil, xerrors.Errorf("block (%s) contained no drand entires", from.Cids()[0])
}
cur := targetBE[0].Index
cur := targetBE[0].Round
for _, e := range targetBE[1:] {
if cur >= e.Index {
if cur >= e.Round {
syncer.bad.Add(from.Cids()[0], "wrong order of beacon entires")
return nil, xerrors.Errorf("wrong order of beacon entires")
}
@ -994,7 +989,7 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to
return nil, xerrors.Errorf("tipset contained different number for beacon entires")
}
for i, be := range bh.BeaconEntries {
if targetBE[i].Index != be.Index || !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
return nil, xerrors.Errorf("tipset contained different number for beacon entires")
}
@ -1331,3 +1326,24 @@ func (syncer *Syncer) MarkBad(blk cid.Cid) {
func (syncer *Syncer) CheckBadBlockCache(blk cid.Cid) (string, bool) {
return syncer.bad.Has(blk)
}
func (syncer *Syncer) getLatestBeaconEntry(ctx context.Context, ts *types.TipSet) (*types.BeaconEntry, error) {
cur := ts
for i := 0; i < 20; i++ {
cbe := cur.Blocks()[0].BeaconEntries
if len(cbe) > 0 {
return &cbe[len(cbe)-1], nil
}
if cur.Height() == 0 {
return nil, xerrors.Errorf("made it back to genesis block without finding beacon entry")
}
next, err := syncer.store.LoadTipSet(cur.Parents())
if err != nil {
return nil, xerrors.Errorf("failed to load parents when searching back for latest beacon entry: %w", err)
}
cur = next
}
return nil, xerrors.Errorf("found NO beacon entries in the 20 blocks prior to given tipset")
}

View File

@ -52,7 +52,7 @@ func (crt *incrt) Read(buf []byte) (int, error) {
err := crt.rd.SetReadDeadline(start.Add(crt.wait))
if err != nil {
log.Warnf("unable to set deadline: %+v", err)
log.Debugf("unable to set deadline: %+v", err)
}
n, err := crt.rd.Read(buf)

View File

@ -9,13 +9,13 @@ import (
address "github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
lru "github.com/hashicorp/golang-lru"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/beacon"
"github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
logging "github.com/ipfs/go-log/v2"
@ -340,16 +340,16 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB
log.Infof("Time delta between now and our mining base: %ds (nulls: %d)", uint64(time.Now().Unix())-base.ts.MinTimestamp(), base.nullRounds)
ticket, err := m.computeTicket(ctx, addr, base)
if err != nil {
return nil, xerrors.Errorf("scratching ticket failed: %w", err)
}
rbase := *beaconPrev
if len(bvals) > 0 {
rbase = bvals[len(bvals)-1]
}
ticket, err := m.computeTicket(ctx, addr, &rbase, base)
if err != nil {
return nil, xerrors.Errorf("scratching ticket failed: %w", err)
}
winner, err := gen.IsRoundWinner(ctx, base.ts, round, addr, rbase, m.api)
if err != nil {
return nil, xerrors.Errorf("failed to check if we win next round: %w", err)
@ -381,7 +381,7 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB
return b, nil
}
func (m *Miner) computeTicket(ctx context.Context, addr address.Address, base *MiningBase) (*types.Ticket, error) {
func (m *Miner) computeTicket(ctx context.Context, addr address.Address, brand *types.BeaconEntry, base *MiningBase) (*types.Ticket, error) {
w, err := m.api.StateMinerWorker(ctx, addr, types.EmptyTSK)
if err != nil {
return nil, err
@ -391,8 +391,7 @@ func (m *Miner) computeTicket(ctx context.Context, addr address.Address, base *M
if err := addr.MarshalCBOR(buf); err != nil {
return nil, xerrors.Errorf("failed to marshal address to cbor: %w", err)
}
input, err := m.api.ChainGetRandomness(ctx, base.ts.Key(), crypto.DomainSeparationTag_TicketProduction, (base.ts.Height()+base.nullRounds+1)-1, buf.Bytes())
input, err := store.DrawRandomness(brand.Data, 17, (base.ts.Height() + base.nullRounds + 1), buf.Bytes())
if err != nil {
return nil, err
}

View File

@ -59,7 +59,7 @@ func (a *ChainAPI) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey,
return nil, xerrors.Errorf("loading tipset key: %w", err)
}
return a.Chain.GetRandomness(ctx, pts.Cids(), personalization, int64(randEpoch), entropy)
return a.Chain.GetRandomness(ctx, pts.Cids(), personalization, randEpoch, entropy)
}
func (a *ChainAPI) ChainGetBlock(ctx context.Context, msg cid.Cid) (*types.BlockHeader, error) {