Tests pass
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
This commit is contained in:
parent
8e0ca306d2
commit
f1c890ca54
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user