Merge pull request #4573 from filecoin-project/steb/remove-worker-key-cache
Fetch worker key from correct block on sync
This commit is contained in:
commit
d43bc79050
@ -27,16 +27,11 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.WalletA
|
||||
return nil, xerrors.Errorf("failed to load tipset state: %w", err)
|
||||
}
|
||||
|
||||
lbts, err := stmgr.GetLookbackTipSetForRound(ctx, sm, pts, bt.Epoch)
|
||||
_, lbst, err := stmgr.GetLookbackTipSetForRound(ctx, sm, pts, bt.Epoch)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting lookback miner actor state: %w", err)
|
||||
}
|
||||
|
||||
lbst, _, err := sm.TipSetState(ctx, lbts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
worker, err := stmgr.GetMinerWorkerRaw(ctx, sm, lbst, bt.Miner)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get miner worker: %w", err)
|
||||
|
@ -391,7 +391,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
|
||||
return root, trace, nil
|
||||
}
|
||||
|
||||
func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.TipSet, round abi.ChainEpoch) (*types.TipSet, error) {
|
||||
func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.TipSet, round abi.ChainEpoch) (*types.TipSet, cid.Cid, error) {
|
||||
var lbr abi.ChainEpoch
|
||||
lb := policy.GetWinningPoStSectorSetLookback(sm.GetNtwkVersion(ctx, round))
|
||||
if round > lb {
|
||||
@ -399,16 +399,33 @@ func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.
|
||||
}
|
||||
|
||||
// more null blocks than our lookback
|
||||
if lbr > ts.Height() {
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
lbts, err := sm.ChainStore().GetTipsetByHeight(ctx, lbr, ts, true)
|
||||
if lbr >= ts.Height() {
|
||||
// This should never happen at this point, but may happen before
|
||||
// network version 3 (where the lookback was only 10 blocks).
|
||||
st, _, err := sm.TipSetState(ctx, ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get lookback tipset: %w", err)
|
||||
return nil, cid.Undef, err
|
||||
}
|
||||
return ts, st, nil
|
||||
}
|
||||
|
||||
return lbts, nil
|
||||
// Get the tipset after the lookback tipset, or the next non-null one.
|
||||
nextTs, err := sm.ChainStore().GetTipsetByHeight(ctx, lbr+1, ts, false)
|
||||
if err != nil {
|
||||
return nil, cid.Undef, xerrors.Errorf("failed to get lookback tipset+1: %w", err)
|
||||
}
|
||||
|
||||
if lbr > nextTs.Height() {
|
||||
return nil, cid.Undef, xerrors.Errorf("failed to find non-null tipset %s (%d) which is known to exist, found %s (%d)", ts.Key(), ts.Height(), nextTs.Key(), nextTs.Height())
|
||||
|
||||
}
|
||||
|
||||
lbts, err := sm.ChainStore().GetTipSetFromKey(nextTs.Parents())
|
||||
if err != nil {
|
||||
return nil, cid.Undef, xerrors.Errorf("failed to resolve lookback tipset: %w", err)
|
||||
}
|
||||
|
||||
return lbts, nextTs.ParentState(), nil
|
||||
}
|
||||
|
||||
func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule, tsk types.TipSetKey, round abi.ChainEpoch, maddr address.Address, pv ffiwrapper.Verifier) (*api.MiningBaseInfo, error) {
|
||||
@ -436,17 +453,11 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
|
||||
rbase = entries[len(entries)-1]
|
||||
}
|
||||
|
||||
lbts, err := GetLookbackTipSetForRound(ctx, sm, ts, round)
|
||||
lbts, lbst, err := GetLookbackTipSetForRound(ctx, sm, ts, round)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting lookback miner actor state: %w", err)
|
||||
}
|
||||
|
||||
// TODO: load the state instead of computing it?
|
||||
lbst, _, err := sm.TipSetState(ctx, lbts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
act, err := sm.LoadActorRaw(ctx, maddr, lbst)
|
||||
if xerrors.Is(err, types.ErrActorNotFound) {
|
||||
_, err := sm.LoadActor(ctx, maddr, ts)
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
@ -27,14 +26,11 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
||||
"github.com/filecoin-project/lotus/lib/bufbstore"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
"github.com/filecoin-project/lotus/metrics"
|
||||
"github.com/filecoin-project/lotus/node/impl/client"
|
||||
@ -227,9 +223,6 @@ type BlockValidator struct {
|
||||
// necessary for block validation
|
||||
chain *store.ChainStore
|
||||
stmgr *stmgr.StateManager
|
||||
|
||||
mx sync.Mutex
|
||||
keycache map[string]address.Address
|
||||
}
|
||||
|
||||
func NewBlockValidator(self peer.ID, chain *store.ChainStore, stmgr *stmgr.StateManager, blacklist func(peer.ID)) *BlockValidator {
|
||||
@ -242,7 +235,6 @@ func NewBlockValidator(self peer.ID, chain *store.ChainStore, stmgr *stmgr.State
|
||||
recvBlocks: newBlockReceiptCache(),
|
||||
chain: chain,
|
||||
stmgr: stmgr,
|
||||
keycache: make(map[string]address.Address),
|
||||
}
|
||||
}
|
||||
|
||||
@ -436,60 +428,25 @@ func (bv *BlockValidator) validateMsgMeta(ctx context.Context, msg *types.BlockM
|
||||
}
|
||||
|
||||
func (bv *BlockValidator) checkPowerAndGetWorkerKey(ctx context.Context, bh *types.BlockHeader) (address.Address, error) {
|
||||
addr := bh.Miner
|
||||
|
||||
bv.mx.Lock()
|
||||
key, ok := bv.keycache[addr.String()]
|
||||
bv.mx.Unlock()
|
||||
if !ok {
|
||||
// TODO I have a feeling all this can be simplified by cleverer DI to use the API
|
||||
ts := bv.chain.GetHeaviestTipSet()
|
||||
st, _, err := bv.stmgr.TipSetState(ctx, ts)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
buf := bufbstore.NewBufferedBstore(bv.chain.Blockstore())
|
||||
cst := cbor.NewCborStore(buf)
|
||||
state, err := state.LoadStateTree(cst, st)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
act, err := state.GetActor(addr)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
mst, err := miner.Load(bv.chain.Store(ctx), act)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
info, err := mst.Info()
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
worker := info.Worker
|
||||
key, err = bv.stmgr.ResolveToKeyAddress(ctx, worker, ts)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
bv.mx.Lock()
|
||||
bv.keycache[addr.String()] = key
|
||||
bv.mx.Unlock()
|
||||
}
|
||||
|
||||
// we check that the miner met the minimum power at the lookback tipset
|
||||
|
||||
baseTs := bv.chain.GetHeaviestTipSet()
|
||||
lbts, err := stmgr.GetLookbackTipSetForRound(ctx, bv.stmgr, baseTs, bh.Height)
|
||||
lbts, lbst, err := stmgr.GetLookbackTipSetForRound(ctx, bv.stmgr, baseTs, bh.Height)
|
||||
if err != nil {
|
||||
log.Warnf("failed to load lookback tipset for incoming block: %s", err)
|
||||
return address.Undef, ErrSoftFailure
|
||||
}
|
||||
|
||||
key, err := stmgr.GetMinerWorkerRaw(ctx, bv.stmgr, lbst, bh.Miner)
|
||||
if err != nil {
|
||||
log.Warnf("failed to resolve worker key for miner %s: %s", bh.Miner, err)
|
||||
return address.Undef, ErrSoftFailure
|
||||
}
|
||||
|
||||
// NOTE: we check to see if the miner was eligible in the lookback
|
||||
// tipset - 1 for historical reasons. DO NOT use the lookback state
|
||||
// returned by GetLookbackTipSetForRound.
|
||||
|
||||
eligible, err := stmgr.MinerEligibleToMine(ctx, bv.stmgr, bh.Miner, baseTs, lbts)
|
||||
if err != nil {
|
||||
log.Warnf("failed to determine if incoming block's miner has minimum power: %s", err)
|
||||
|
@ -730,16 +730,11 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock, use
|
||||
return xerrors.Errorf("load parent tipset failed (%s): %w", h.Parents, err)
|
||||
}
|
||||
|
||||
lbts, err := stmgr.GetLookbackTipSetForRound(ctx, syncer.sm, baseTs, h.Height)
|
||||
lbts, lbst, err := stmgr.GetLookbackTipSetForRound(ctx, syncer.sm, baseTs, h.Height)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get lookback tipset for block: %w", err)
|
||||
}
|
||||
|
||||
lbst, _, err := syncer.sm.TipSetState(ctx, lbts)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to compute lookback tipset state (epoch %d): %w", lbts.Height(), err)
|
||||
}
|
||||
|
||||
prevBeacon, err := syncer.store.GetLatestBeaconEntry(baseTs)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get latest beacon entry: %w", err)
|
||||
|
Loading…
Reference in New Issue
Block a user