This commit is contained in:
Raúl Kripalani 2020-07-20 14:45:17 +01:00
parent 4d2d8b2d11
commit 226786c1da
13 changed files with 210 additions and 42 deletions

View File

@ -375,7 +375,7 @@ type FileRef struct {
type MinerSectors struct {
Sectors uint64
Active uint64
Active uint64
}
type SectorExpiration struct {

View File

@ -127,7 +127,7 @@ type FullNodeStruct struct {
StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"`
StateMinerSectors func(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerActiveSectors func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerActiveSectors func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerProvingDeadline func(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) `perm:"read"`
StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) `perm:"read"`
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) `perm:"read"`

View File

@ -209,7 +209,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
// var newAddress address.Address
if (info.Type == genesis.TAccount) {
if info.Type == genesis.TAccount {
var ainfo genesis.AccountMeta
if err := json.Unmarshal(info.Meta, &ainfo); err != nil {
return nil, xerrors.Errorf("unmarshaling account meta: %w", err)
@ -226,7 +226,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
if err != nil {
return nil, xerrors.Errorf("setting account from actmap: %w", err)
}
} else if (info.Type == genesis.TMultisig) {
} else if info.Type == genesis.TMultisig {
var ainfo genesis.MultisigMeta
if err := json.Unmarshal(info.Meta, &ainfo); err != nil {
return nil, xerrors.Errorf("unmarshaling account meta: %w", err)
@ -238,12 +238,12 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
}
st, err := cst.Put(ctx, &multisig.State{
Signers: ainfo.Signers,
Signers: ainfo.Signers,
NumApprovalsThreshold: uint64(ainfo.Threshold),
StartEpoch: abi.ChainEpoch(ainfo.VestingStart),
UnlockDuration: abi.ChainEpoch(ainfo.VestingDuration),
PendingTxns: pending,
InitialBalance: info.Balance,
StartEpoch: abi.ChainEpoch(ainfo.VestingStart),
UnlockDuration: abi.ChainEpoch(ainfo.VestingDuration),
PendingTxns: pending,
InitialBalance: info.Balance,
})
if err != nil {
return nil, err

View File

@ -59,6 +59,15 @@ const (
evtTypeHeadChange = iota
)
type HeadChangeEvt struct {
From types.TipSetKey
FromHeight abi.ChainEpoch
To types.TipSetKey
ToHeight abi.ChainEpoch
RevertCount int
ApplyCount int
}
// ChainStore is the main point of access to chain data.
//
// Raw chain data is stored in the Blockstore, with relevant markers (genesis,
@ -340,7 +349,7 @@ func (cs *ChainStore) reorgWorker(ctx context.Context, initialNotifees []ReorgNo
}
journal.MaybeAddEntry(cs.journal, cs.evtTypes[evtTypeHeadChange], func() interface{} {
return journal.HeadChangeEvt{
return HeadChangeEvt{
From: r.old.Key(),
FromHeight: r.old.Height(),
To: r.new.Key(),

View File

@ -1,16 +0,0 @@
package journal
import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/lotus/chain/types"
)
type HeadChangeEvt struct {
From types.TipSetKey `json:"from"`
FromHeight abi.ChainEpoch `json:"from_height"`
To types.TipSetKey `json:"to"`
ToHeight abi.ChainEpoch `json:"to_height"`
RevertCount int `json:"rev_cnt"`
ApplyCount int `json:"apply_cnt"`
}

View File

@ -37,7 +37,7 @@ type fsJournal struct {
// OpenFSJournal constructs a rolling filesystem journal, with a default
// per-file size limit of 1GiB.
func OpenFSJournal(lr repo.LockedRepo, lc fx.Lifecycle, disabled []EventType) (Journal, error) {
func OpenFSJournal(lr repo.LockedRepo, lc fx.Lifecycle, disabled DisabledEvents) (Journal, error) {
dir := filepath.Join(lr.Path(), "journal")
if err := os.MkdirAll(dir, 0755); err != nil {
return nil, fmt.Errorf("failed to mk directory %s for file journal: %w", dir, err)

View File

@ -50,7 +50,7 @@ func (o *observer) dispatch(entry *Entry) {
}
}
func NewMemoryJournal(lc fx.Lifecycle, disabled []EventType) *MemJournal {
func NewMemoryJournal(lc fx.Lifecycle, disabled DisabledEvents) *MemJournal {
m := &MemJournal{
eventTypeFactory: newEventTypeFactory(disabled),

View File

@ -5,6 +5,9 @@ import (
"time"
)
// DisabledEvents is the set of event types whose journaling is suppressed.
type DisabledEvents []EventType
// EventType represents the signature of an event.
type EventType struct {
System string
@ -70,7 +73,7 @@ type eventTypeFactory struct {
m map[string]EventType
}
func newEventTypeFactory(disabled []EventType) *eventTypeFactory {
func newEventTypeFactory(disabled DisabledEvents) *eventTypeFactory {
ret := &eventTypeFactory{
m: make(map[string]EventType, len(disabled)+32), // + extra capacity.
}

View File

@ -153,6 +153,7 @@ func defaults() []Option {
Override(new(dtypes.Bootstrapper), dtypes.Bootstrapper(false)),
Override(new(dtypes.ShutdownChan), make(chan struct{})),
Override(new(journal.Journal), journal.OpenFSJournal),
Override(new(journal.DisabledEvents), journal.DisabledEvents{}),
Override(InitJournalKey, func(j *journal.Journal) { /* forces the creation of the journal at startup */ }),
// Filecoin modules

View File

@ -42,6 +42,7 @@ import (
paramfetch "github.com/filecoin-project/go-paramfetch"
"github.com/filecoin-project/go-statestore"
"github.com/filecoin-project/go-storedcounter"
"github.com/filecoin-project/lotus/journal"
"github.com/filecoin-project/lotus/node/config"
sectorstorage "github.com/filecoin-project/sector-storage"
"github.com/filecoin-project/sector-storage/ffiwrapper"
@ -137,7 +138,34 @@ func SectorIDCounter(ds dtypes.MetadataDS) sealing.SectorIDCounter {
return &sidsc{sc}
}
func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api lapi.FullNode, h host.Host, ds dtypes.MetadataDS, sealer sectorstorage.SectorManager, sc sealing.SectorIDCounter, verif ffiwrapper.Verifier, gsd dtypes.GetSealingDelayFunc) (*storage.Miner, error) {
type StorageMinerParams struct {
fx.In
Lifecycle fx.Lifecycle
MetricsCtx helpers.MetricsCtx
API lapi.FullNode
Host host.Host
MetadataDS dtypes.MetadataDS
Sealer sectorstorage.SectorManager
SectorIDCounter sealing.SectorIDCounter
Verifier ffiwrapper.Verifier
GetSealingDelayFn dtypes.GetSealingDelayFunc
Journal journal.Journal
}
func StorageMiner(params StorageMinerParams) (*storage.Miner, error) {
var (
ds = params.MetadataDS
mctx = params.MetricsCtx
lc = params.Lifecycle
api = params.API
sealer = params.Sealer
h = params.Host
sc = params.SectorIDCounter
verif = params.Verifier
gsd = params.GetSealingDelayFn
jrnl = params.Journal
)
maddr, err := minerAddrFromDS(ds)
if err != nil {
return nil, err
@ -155,7 +183,7 @@ func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api lapi.FullNode, h
return nil, err
}
fps, err := storage.NewWindowedPoStScheduler(api, sealer, sealer, maddr, worker)
fps, err := storage.NewWindowedPoStScheduler(api, sealer, sealer, maddr, worker, jrnl)
if err != nil {
return nil, err
}

34
storage/journal_events.go Normal file
View File

@ -0,0 +1,34 @@
package storage
import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/ipfs/go-cid"
)
type WindowPoStEvt struct {
State string
Deadline *miner.DeadlineInfo
Height abi.ChainEpoch
TipSet []cid.Cid
Error error `json:",omitempty"`
Proofs *WindowPoStEvt_Proofs `json:",omitempty"`
Recoveries *WindowPoStEvt_Recoveries `json:",omitempty"`
Faults *WindowPoStEvt_Faults `json:",omitempty"`
}
type WindowPoStEvt_Proofs struct {
Partitions []miner.PoStPartition
MessageCID cid.Cid
}
type WindowPoStEvt_Recoveries struct {
Declarations []miner.RecoveryDeclaration
MessageCID cid.Cid
}
type WindowPoStEvt_Faults struct {
Declarations []miner.FaultDeclaration
MessageCID cid.Cid
}

View File

@ -14,17 +14,29 @@ import (
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/ipfs/go-cid"
"go.opencensus.io/trace"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/journal"
)
var errNoPartitions = errors.New("no partitions")
func (s *WindowPoStScheduler) failPost(deadline *miner.DeadlineInfo) {
func (s *WindowPoStScheduler) failPost(err error, deadline *miner.DeadlineInfo) {
journal.MaybeAddEntry(s.jrnl, s.evtTypes[evtTypeWindowPoSt], func() interface{} {
return WindowPoStEvt{
State: "failed",
Deadline: s.activeDeadline,
Height: s.cur.Height(),
TipSet: s.cur.Cids(),
Error: err,
}
})
log.Errorf("TODO")
/*s.failLk.Lock()
if eps > s.failed {
@ -39,6 +51,15 @@ func (s *WindowPoStScheduler) doPost(ctx context.Context, deadline *miner.Deadli
s.abort = abort
s.activeDeadline = deadline
journal.MaybeAddEntry(s.jrnl, s.evtTypes[evtTypeWindowPoSt], func() interface{} {
return WindowPoStEvt{
State: "started",
Deadline: s.activeDeadline,
Height: s.cur.Height(),
TipSet: s.cur.Cids(),
}
})
go func() {
defer abort()
@ -52,14 +73,23 @@ func (s *WindowPoStScheduler) doPost(ctx context.Context, deadline *miner.Deadli
case nil:
if err := s.submitPost(ctx, proof); err != nil {
log.Errorf("submitPost failed: %+v", err)
s.failPost(deadline)
s.failPost(err, deadline)
return
}
default:
log.Errorf("runPost failed: %+v", err)
s.failPost(deadline)
s.failPost(err, deadline)
return
}
journal.MaybeAddEntry(s.jrnl, s.evtTypes[evtTypeWindowPoSt], func() interface{} {
return WindowPoStEvt{
State: "succeeded",
Deadline: s.activeDeadline,
Height: s.cur.Height(),
TipSet: s.cur.Cids(),
}
})
}()
}
@ -112,11 +142,29 @@ func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, dlIdx uin
ctx, span := trace.StartSpan(ctx, "storage.checkNextRecoveries")
defer span.End()
var sm *types.SignedMessage
faulty := uint64(0)
params := &miner.DeclareFaultsRecoveredParams{
Recoveries: []miner.RecoveryDeclaration{},
}
faulty := uint64(0)
defer journal.MaybeAddEntry(s.jrnl, s.evtTypes[evtTypeWindowPoSt], func() interface{} {
var mcid cid.Cid
if sm != nil {
mcid = sm.Cid()
}
return WindowPoStEvt{
State: "recoveries_processed",
Deadline: s.activeDeadline,
Height: s.cur.Height(),
TipSet: s.cur.Cids(),
Recoveries: &WindowPoStEvt_Recoveries{
Declarations: params.Recoveries,
MessageCID: mcid,
},
}
})
for partIdx, partition := range partitions {
unrecovered, err := bitfield.SubtractBitField(partition.Faults, partition.Recoveries)
@ -180,7 +228,8 @@ func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, dlIdx uin
GasPrice: types.NewInt(2),
}
sm, err := s.api.MpoolPushMessage(ctx, msg)
var err error
sm, err = s.api.MpoolPushMessage(ctx, msg)
if err != nil {
return xerrors.Errorf("pushing message to mpool: %w", err)
}
@ -203,11 +252,28 @@ func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64,
ctx, span := trace.StartSpan(ctx, "storage.checkNextFaults")
defer span.End()
var sm *types.SignedMessage
bad := uint64(0)
params := &miner.DeclareFaultsParams{
Faults: []miner.FaultDeclaration{},
}
bad := uint64(0)
defer journal.MaybeAddEntry(s.jrnl, s.evtTypes[evtTypeWindowPoSt], func() interface{} {
var mcid cid.Cid
if sm != nil {
mcid = sm.Cid()
}
return WindowPoStEvt{
State: "faults_processed",
Deadline: s.activeDeadline,
Height: s.cur.Height(),
TipSet: s.cur.Cids(),
Faults: &WindowPoStEvt_Faults{
Declarations: params.Faults,
MessageCID: mcid,
},
}
})
for partIdx, partition := range partitions {
toCheck, err := partition.ActiveSectors()
@ -264,7 +330,8 @@ func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64,
GasPrice: types.NewInt(2),
}
sm, err := s.api.MpoolPushMessage(ctx, msg)
var err error
sm, err = s.api.MpoolPushMessage(ctx, msg)
if err != nil {
return xerrors.Errorf("pushing message to mpool: %w", err)
}
@ -450,6 +517,26 @@ func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.Submi
ctx, span := trace.StartSpan(ctx, "storage.commitPost")
defer span.End()
var sm *types.SignedMessage
defer journal.MaybeAddEntry(s.jrnl, s.evtTypes[evtTypeWindowPoSt], func() interface{} {
var mcid cid.Cid
if sm != nil {
mcid = sm.Cid()
}
return WindowPoStEvt{
State: "proofs_processed",
Deadline: s.activeDeadline,
Height: s.cur.Height(),
TipSet: s.cur.Cids(),
Proofs: &WindowPoStEvt_Proofs{
Partitions: proof.Partitions,
MessageCID: mcid,
},
}
})
enc, aerr := actors.SerializeParams(proof)
if aerr != nil {
return xerrors.Errorf("could not serialize submit post parameters: %w", aerr)
@ -467,7 +554,8 @@ func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.Submi
}
// TODO: consider maybe caring about the output
sm, err := s.api.MpoolPushMessage(ctx, msg)
var err error
sm, err = s.api.MpoolPushMessage(ctx, msg)
if err != nil {
return xerrors.Errorf("pushing message to mpool: %w", err)
}

View File

@ -17,10 +17,16 @@ import (
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/journal"
)
const StartConfidence = 4 // TODO: config
// Journal event types.
const (
evtTypeWindowPoSt = iota
)
type WindowPoStScheduler struct {
api storageMinerApi
prover storage.Prover
@ -36,12 +42,14 @@ type WindowPoStScheduler struct {
// if a post is in progress, this indicates for which ElectionPeriodStart
activeDeadline *miner.DeadlineInfo
abort context.CancelFunc
jrnl journal.Journal
evtTypes [1]journal.EventType
//failed abi.ChainEpoch // eps
//failLk sync.Mutex
// failed abi.ChainEpoch // eps
// failLk sync.Mutex
}
func NewWindowedPoStScheduler(api storageMinerApi, sb storage.Prover, ft sectorstorage.FaultTracker, actor address.Address, worker address.Address) (*WindowPoStScheduler, error) {
func NewWindowedPoStScheduler(api storageMinerApi, sb storage.Prover, ft sectorstorage.FaultTracker, actor address.Address, worker address.Address, jrnl journal.Journal) (*WindowPoStScheduler, error) {
mi, err := api.StateMinerInfo(context.TODO(), actor, types.EmptyTSK)
if err != nil {
return nil, xerrors.Errorf("getting sector size: %w", err)
@ -61,6 +69,10 @@ func NewWindowedPoStScheduler(api storageMinerApi, sb storage.Prover, ft sectors
actor: actor,
worker: worker,
jrnl: jrnl,
evtTypes: [...]journal.EventType{
evtTypeWindowPoSt: jrnl.RegisterEventType("storage", "wdpost"),
},
}, nil
}
@ -214,6 +226,15 @@ func (s *WindowPoStScheduler) abortActivePoSt() {
s.abort()
}
journal.MaybeAddEntry(s.jrnl, s.evtTypes[evtTypeWindowPoSt], func() interface{} {
return WindowPoStEvt{
State: "abort",
Deadline: s.activeDeadline,
Height: s.cur.Height(),
TipSet: s.cur.Cids(),
}
})
log.Warnf("Aborting Window PoSt (Deadline: %+v)", s.activeDeadline)
s.activeDeadline = nil