feat: miner: implement FRC-0051

This commit is contained in:
Aayush 2023-08-10 16:07:08 -04:00
parent d71d647aaf
commit 91d2c02765
2 changed files with 39 additions and 5 deletions

View File

@ -105,6 +105,7 @@ var SupportedProofTypes = []abi.RegisteredSealProof{
var ConsensusMinerMinPower = abi.NewStoragePower(10 << 40) var ConsensusMinerMinPower = abi.NewStoragePower(10 << 40)
var PreCommitChallengeDelay = abi.ChainEpoch(150) var PreCommitChallengeDelay = abi.ChainEpoch(150)
var PropagationDelaySecs = uint64(10) var PropagationDelaySecs = uint64(10)
var EquivocationDelaySecs = uint64(2)
func init() { func init() {
if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" { if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" {

View File

@ -10,7 +10,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/hashicorp/golang-lru/arc/v2" "github.com/ipfs/go-cid"
logging "github.com/ipfs/go-log/v2" logging "github.com/ipfs/go-log/v2"
"go.opencensus.io/trace" "go.opencensus.io/trace"
"golang.org/x/xerrors" "golang.org/x/xerrors"
@ -373,8 +373,9 @@ minerLoop:
// MiningBase is the tipset on top of which we plan to construct our next block. // MiningBase is the tipset on top of which we plan to construct our next block.
// Refer to godocs on GetBestMiningCandidate. // Refer to godocs on GetBestMiningCandidate.
type MiningBase struct { type MiningBase struct {
TipSet *types.TipSet TipSet *types.TipSet
NullRounds abi.ChainEpoch ComputeTime time.Time
NullRounds abi.ChainEpoch
} }
// GetBestMiningCandidate implements the fork choice rule from a miner's // GetBestMiningCandidate implements the fork choice rule from a miner's
@ -412,7 +413,7 @@ func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error)
} }
} }
m.lastWork = &MiningBase{TipSet: bts} m.lastWork = &MiningBase{TipSet: bts, ComputeTime: time.Now()}
return m.lastWork, nil return m.lastWork, nil
} }
@ -560,6 +561,37 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (minedBlock *type
return nil, err return nil, err
} }
tEquivocateWait := build.Clock.Now()
// TODO: make param
m.niceSleep(time.Until(base.ComputeTime.Add(2 * time.Second)))
newBase, err := m.GetBestMiningCandidate(ctx)
if err != nil {
err = xerrors.Errorf("failed to refresh best mining candidate: %w", err)
return nil, err
}
// Only factor in equivocated blocks if doing so will not risk us missing a block
if newBase.TipSet.Height() == base.TipSet.Height() && newBase.TipSet.MinTicket().Equals(base.TipSet.MinTicket()) {
newBaseMap := map[cid.Cid]struct{}{}
for _, newBaseBlk := range newBase.TipSet.Cids() {
newBaseMap[newBaseBlk] = struct{}{}
}
refreshedBase := make([]*types.BlockHeader, 0, len(base.TipSet.Cids()))
for _, baseBlk := range base.TipSet.Blocks() {
if _, ok := newBaseMap[baseBlk.Cid()]; ok {
refreshedBase = append(refreshedBase, baseBlk)
}
}
base.TipSet, err = types.NewTipSet(refreshedBase)
if err != nil {
err = xerrors.Errorf("failed to create new tipset when refreshing: %w", err)
return nil, err
}
}
tPending := build.Clock.Now() tPending := build.Clock.Now()
// TODO: winning post proof // TODO: winning post proof
@ -582,7 +614,8 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (minedBlock *type
"tTicket ", tTicket.Sub(tPowercheck), "tTicket ", tTicket.Sub(tPowercheck),
"tSeed ", tSeed.Sub(tTicket), "tSeed ", tSeed.Sub(tTicket),
"tProof ", tProof.Sub(tSeed), "tProof ", tProof.Sub(tSeed),
"tPending ", tPending.Sub(tProof), "tEquivocateWait ", tEquivocateWait.Sub(tProof),
"tPending ", tPending.Sub(tEquivocateWait),
"tCreateBlock ", tCreateBlock.Sub(tPending)) "tCreateBlock ", tCreateBlock.Sub(tPending))
} }