From a0588d513d370fe7120c943155294be095d112d9 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Sun, 24 Nov 2019 22:45:13 -0600 Subject: [PATCH] Add lotus-gen, rewire genesis mining --- api/api_full.go | 3 - api/struct.go | 15 -- build/params.go | 4 + chain/actors/actor_miner.go | 228 +++++++++++++++--------- chain/actors/cbor_gen.go | 44 +---- chain/gen/gen.go | 40 ++++- chain/gen/utils.go | 25 ++- chain/stmgr/stmgr.go | 26 ++- chain/stmgr/utils.go | 11 +- chain/store/weight.go | 1 + cli/cmd.go | 1 - cli/miner.go | 32 ---- cmd/lotus-seed/main.go | 162 +++++++++++++++++ cmd/lotus-storage-miner/init.go | 110 +++++++++--- cmd/lotus/daemon.go | 13 +- extern/go-sectorbuilder | 2 +- genesis/types.go | 15 ++ go.mod | 1 + go.sum | 1 + lib/sectorbuilder/sectorbuilder.go | 56 ++++-- lib/sectorbuilder/sectorbuilder_test.go | 36 ++-- miner/miner.go | 23 +-- miner/testminer.go | 6 +- node/builder.go | 7 +- node/impl/full.go | 18 -- node/impl/storminer.go | 6 +- node/modules/storageminer.go | 20 ++- node/modules/testing/genesis.go | 22 ++- storage/miner.go | 23 +++ storage/post.go | 57 +++--- 30 files changed, 675 insertions(+), 333 deletions(-) delete mode 100644 cli/miner.go create mode 100644 cmd/lotus-seed/main.go create mode 100644 genesis/types.go diff --git a/api/api_full.go b/api/api_full.go index 47e2f71d7..a5582b093 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -49,9 +49,6 @@ type FullNode interface { // miner - MinerRegister(context.Context, address.Address) error - MinerUnregister(context.Context, address.Address) error - MinerAddresses(context.Context) ([]address.Address, error) MinerCreateBlock(context.Context, address.Address, *types.TipSet, *types.Ticket, *types.EPostProof, []*types.SignedMessage, uint64, uint64) (*types.BlockMsg, error) // // UX ? diff --git a/api/struct.go b/api/struct.go index bbd200b7d..8ba0bc3b9 100644 --- a/api/struct.go +++ b/api/struct.go @@ -58,9 +58,6 @@ type FullNodeStruct struct { MpoolPush func(context.Context, *types.SignedMessage) error `perm:"write"` MpoolPushMessage func(context.Context, *types.Message) (*types.SignedMessage, error) `perm:"sign"` - MinerRegister func(context.Context, address.Address) error `perm:"admin"` - MinerUnregister func(context.Context, address.Address) error `perm:"admin"` - MinerAddresses func(context.Context) ([]address.Address, error) `perm:"write"` MinerCreateBlock func(context.Context, address.Address, *types.TipSet, *types.Ticket, *types.EPostProof, []*types.SignedMessage, uint64, uint64) (*types.BlockMsg, error) `perm:"write"` WalletNew func(context.Context, string) (address.Address, error) `perm:"write"` @@ -225,18 +222,6 @@ func (c *FullNodeStruct) MpoolPushMessage(ctx context.Context, msg *types.Messag return c.Internal.MpoolPushMessage(ctx, msg) } -func (c *FullNodeStruct) MinerRegister(ctx context.Context, addr address.Address) error { - return c.Internal.MinerRegister(ctx, addr) -} - -func (c *FullNodeStruct) MinerUnregister(ctx context.Context, addr address.Address) error { - return c.Internal.MinerUnregister(ctx, addr) -} - -func (c *FullNodeStruct) MinerAddresses(ctx context.Context) ([]address.Address, error) { - return c.Internal.MinerAddresses(ctx) -} - func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Address, base *types.TipSet, ticket *types.Ticket, eproof *types.EPostProof, msgs []*types.SignedMessage, height, ts uint64) (*types.BlockMsg, error) { return c.Internal.MinerCreateBlock(ctx, addr, base, ticket, eproof, msgs, height, ts) } diff --git a/build/params.go b/build/params.go index 35ccd69f0..655a8ffc0 100644 --- a/build/params.go +++ b/build/params.go @@ -85,6 +85,10 @@ const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000 // Blocks const EcRandomnessLookback = 300 +const FallbackPoStBegin = 1000 +const SlashablePowerDelay = 2000 + + const PowerCollateralProportion = 5 const PerCapitaCollateralProportion = 1 const CollateralPrecision = 1000 diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index 853d048af..885c24922 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -54,12 +54,6 @@ type StorageMinerActorState struct { // These become the currentFaultSet when a PoSt is submitted. NextFaultSet types.BitField - // Sectors reported during the last PoSt submission as being 'done'. - // The collateral for them is still being held until - // the next PoSt submission in case early sector - // removal penalization is needed. - NextDoneSet types.BitField - // Amount of power this miner has. Power types.BigInt @@ -69,7 +63,7 @@ type StorageMinerActorState struct { // The height at which this miner was slashed at. SlashedAt uint64 - ProvingPeriodEnd uint64 + ElectionPeriodStart uint64 } type MinerInfo struct { @@ -117,7 +111,7 @@ type maMethods struct { Constructor uint64 PreCommitSector uint64 ProveCommitSector uint64 - SubmitPoSt uint64 + SubmitFallbackPoSt uint64 SlashStorageFault uint64 GetCurrentProvingSet uint64 ArbitrateDeal uint64 @@ -133,16 +127,17 @@ type maMethods struct { CheckMiner uint64 DeclareFaults uint64 SlashConsensusFault uint64 + SubmitElectionPoSt uint64 } -var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19} +var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} func (sma StorageMinerActor) Exports() []interface{} { return []interface{}{ 1: sma.StorageMinerConstructor, 2: sma.PreCommitSector, 3: sma.ProveCommitSector, - 4: sma.SubmitPoSt, + 4: sma.SubmitFallbackPoSt, //5: sma.SlashStorageFault, //6: sma.GetCurrentProvingSet, //7: sma.ArbitrateDeal, @@ -158,6 +153,7 @@ func (sma StorageMinerActor) Exports() []interface{} { 17: sma.CheckMiner, 18: sma.DeclareFaults, 19: sma.SlashConsensusFault, + 20: sma.SubmitElectionPoSt, } } @@ -366,7 +362,9 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC if pss.Count == 0 { self.ProvingSet = self.Sectors - self.ProvingPeriodEnd = vmctx.BlockHeight() + build.ProvingPeriodDuration + // TODO: probably want to wait until the miner is above a certain + // threshold before starting this + self.ElectionPeriodStart = vmctx.BlockHeight() } nstate, err := vmctx.Storage().Put(self) @@ -389,8 +387,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC } type SubmitPoStParams struct { - Proof types.EPostProof - DoneSet types.BitField + Proof types.EPostProof } func ProvingPeriodEnd(setPeriodEnd, height uint64) (uint64, uint64) { @@ -401,7 +398,7 @@ func ProvingPeriodEnd(setPeriodEnd, height uint64) (uint64, uint64) { return end, period } -func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext, params *SubmitPoStParams) ([]byte, ActorError) { +func (sma StorageMinerActor) SubmitFallbackPoSt(act *types.Actor, vmctx types.VMContext, params *SubmitPoStParams) ([]byte, ActorError) { oldstate, self, err := loadState(vmctx) if err != nil { return nil, err @@ -416,36 +413,28 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext, return nil, aerrors.New(1, "not authorized to submit post for miner") } - currentProvingPeriodEnd, _ := ProvingPeriodEnd(self.ProvingPeriodEnd, vmctx.BlockHeight()) - - feesRequired := types.NewInt(0) - - if currentProvingPeriodEnd > self.ProvingPeriodEnd { - //TODO late fee calc - feesRequired = types.BigAdd(feesRequired, types.NewInt(1000)) - } - - //TODO temporary sector failure fees - - msgVal := vmctx.Message().Value - if msgVal.LessThan(feesRequired) { - return nil, aerrors.New(2, "not enough funds to pay post submission fees") - } - - if msgVal.GreaterThan(feesRequired) { - _, err := vmctx.Send(vmctx.Message().From, 0, - types.BigSub(msgVal, feesRequired), nil) - if err != nil { - return nil, aerrors.Wrap(err, "could not refund excess fees") + /* + // TODO: handle fees + msgVal := vmctx.Message().Value + if msgVal.LessThan(feesRequired) { + return nil, aerrors.New(2, "not enough funds to pay post submission fees") } - } + + if msgVal.GreaterThan(feesRequired) { + _, err := vmctx.Send(vmctx.Message().From, 0, + types.BigSub(msgVal, feesRequired), nil) + if err != nil { + return nil, aerrors.Wrap(err, "could not refund excess fees") + } + } + */ var seed [sectorbuilder.CommLen]byte { - randHeight := currentProvingPeriodEnd - build.PoStChallangeTime - build.PoStRandomnessLookback + randHeight := self.ElectionPeriodStart + build.FallbackPoStBegin if vmctx.BlockHeight() <= randHeight { // TODO: spec, retcode - return nil, aerrors.Newf(1, "submit PoSt called outside submission window (%d < %d)", vmctx.BlockHeight(), randHeight) + return nil, aerrors.Newf(1, "submit fallback PoSt called too early (%d < %d)", vmctx.BlockHeight(), randHeight) } rand, err := vmctx.GetRandomness(randHeight) @@ -465,13 +454,13 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext, return nil, aerrors.HandleExternalError(lerr, "could not load proving set node") } - var sectorInfos []sectorbuilder.SectorInfo + var sectorInfos []sectorbuilder.PublicSectorInfo if err := pss.ForEach(func(id uint64, v *cbg.Deferred) error { var comms [][]byte if err := cbor.DecodeInto(v.Raw, &comms); err != nil { return xerrors.New("could not decode comms") } - si := sectorbuilder.SectorInfo{ + si := sectorbuilder.PublicSectorInfo{ SectorID: id, } commR := comms[0] @@ -501,7 +490,7 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext, proverID := vmctx.Message().To // TODO: normalize to ID address if ok, lerr := sectorbuilder.VerifyPost(vmctx.Context(), mi.SectorSize, - sectorbuilder.NewSortedSectorInfo(sectorInfos), params.Proof.PostRand, params.Proof.Proof, winners, proverID); !ok || lerr != nil { + sectorbuilder.NewSortedPublicSectorInfo(sectorInfos), params.Proof.PostRand, params.Proof.Proof, winners, proverID); !ok || lerr != nil { if lerr != nil { // TODO: study PoST errors return nil, aerrors.Absorb(lerr, 4, "PoST error") @@ -510,26 +499,11 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext, return nil, aerrors.New(4, "PoST invalid") } } + + // Post submission is successful! self.CurrentFaultSet = self.NextFaultSet self.NextFaultSet = types.NewBitField() - ss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet) - if lerr != nil { - return nil, aerrors.HandleExternalError(lerr, "could not load proving set node") - } - - if err := ss.BatchDelete(params.DoneSet.All()); err != nil { - // TODO: this could fail for system reasons (block not found) or for - // bad user input reasons (e.g. bad doneset). The latter should be a - // non-fatal error - return nil, aerrors.HandleExternalError(err, "failed to delete sectors in done set") - } - - self.ProvingSet, lerr = ss.Flush() - if lerr != nil { - return nil, aerrors.HandleExternalError(lerr, "could not flush AMT") - } - oldPower := self.Power self.Power = types.BigMul(types.NewInt(pss.Count-uint64(len(faults))), types.NewInt(mi.SectorSize)) @@ -540,16 +514,16 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext, delta = self.Power } - prevPE := self.ProvingPeriodEnd + prevSlashingDeadline := self.ElectionPeriodStart + build.SlashablePowerDelay if !self.Active { self.Active = true - prevPE = 0 + prevSlashingDeadline = 0 } enc, err := SerializeParams(&UpdateStorageParams{ Delta: delta, - NextProvingPeriodEnd: currentProvingPeriodEnd + build.ProvingPeriodDuration, - PreviousProvingPeriodEnd: prevPE, + NextProvingPeriodEnd: vmctx.BlockHeight() + build.SlashablePowerDelay, + PreviousProvingPeriodEnd: prevSlashingDeadline, }) if err != nil { return nil, err @@ -561,8 +535,7 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext, } self.ProvingSet = self.Sectors - self.ProvingPeriodEnd = currentProvingPeriodEnd + build.ProvingPeriodDuration - self.NextDoneSet = params.DoneSet + self.ElectionPeriodStart = vmctx.BlockHeight() c, err := vmctx.Storage().Put(self) if err != nil { @@ -756,7 +729,7 @@ func (sma StorageMinerActor) GetSectorSize(act *types.Actor, vmctx types.VMConte } func isLate(height uint64, self *StorageMinerActorState) bool { - return self.ProvingPeriodEnd > 0 && height >= self.ProvingPeriodEnd // TODO: review: maybe > ? + return self.ElectionPeriodStart > 0 && height >= self.ElectionPeriodStart+build.SlashablePowerDelay } func (sma StorageMinerActor) IsSlashed(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { @@ -824,32 +797,34 @@ type DeclareFaultsParams struct { } func (sma StorageMinerActor) DeclareFaults(act *types.Actor, vmctx types.VMContext, params *DeclareFaultsParams) ([]byte, ActorError) { - oldstate, self, aerr := loadState(vmctx) - if aerr != nil { - return nil, aerr - } - - challengeHeight := self.ProvingPeriodEnd - build.PoStChallangeTime - - if vmctx.BlockHeight() < challengeHeight { - // TODO: optimized bitfield methods - for _, v := range params.Faults.All() { - self.CurrentFaultSet.Set(v) + /* + oldstate, self, aerr := loadState(vmctx) + if aerr != nil { + return nil, aerr } - } else { - for _, v := range params.Faults.All() { - self.NextFaultSet.Set(v) + + challengeHeight := self.ProvingPeriodEnd - build.PoStChallangeTime + + if vmctx.BlockHeight() < challengeHeight { + // TODO: optimized bitfield methods + for _, v := range params.Faults.All() { + self.CurrentFaultSet.Set(v) + } + } else { + for _, v := range params.Faults.All() { + self.NextFaultSet.Set(v) + } } - } - nstate, err := vmctx.Storage().Put(self) - if err != nil { - return nil, err - } - if err := vmctx.Storage().Commit(oldstate, nstate); err != nil { - return nil, err - } + nstate, err := vmctx.Storage().Put(self) + if err != nil { + return nil, err + } + if err := vmctx.Storage().Commit(oldstate, nstate); err != nil { + return nil, err + } + */ return nil, nil } @@ -899,6 +874,85 @@ func (sma StorageMinerActor) SlashConsensusFault(act *types.Actor, vmctx types.V return nil, nil } +func (sma StorageMinerActor) SubmitElectionPoSt(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, aerrors.ActorError) { + if vmctx.Message().From != NetworkAddress { + return nil, aerrors.Newf(1, "submit election post can only be called by the storage power actor") + } + + oldstate, self, aerr := loadState(vmctx) + if aerr != nil { + return nil, aerr + } + + if err := onSuccessfulPoSt(self, vmctx); err != nil { + return nil, err + } + + ncid, err := vmctx.Storage().Put(self) + if err != nil { + return nil, err + } + if err := vmctx.Storage().Commit(oldstate, ncid); err != nil { + return nil, err + } + + return nil, nil +} + +func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerrors.ActorError { + // TODO: some sector upkeep stuff that is very haphazard and unclear in the spec + + var mi MinerInfo + if err := vmctx.Storage().Get(self.Info, &mi); err != nil { + return err + } + + pss, nerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet) + if nerr != nil { + return aerrors.HandleExternalError(nerr, "failed to load proving set") + } + + self.CurrentFaultSet = self.NextFaultSet + self.NextFaultSet = types.NewBitField() + + faults := []uint64{} // TODO + + oldPower := self.Power + self.Power = types.BigMul(types.NewInt(pss.Count-uint64(len(faults))), + types.NewInt(mi.SectorSize)) + + delta := types.BigSub(self.Power, oldPower) + if self.SlashedAt != 0 { + self.SlashedAt = 0 + delta = self.Power + } + + prevSlashingDeadline := self.ElectionPeriodStart + build.SlashablePowerDelay + if !self.Active { + self.Active = true + prevSlashingDeadline = 0 + } + + fmt.Println("POWER UPDATE DELTA: ", delta) + enc, err := SerializeParams(&UpdateStorageParams{ + Delta: delta, + NextProvingPeriodEnd: vmctx.BlockHeight() + build.SlashablePowerDelay, + PreviousProvingPeriodEnd: prevSlashingDeadline, + }) + if err != nil { + return err + } + + _, err = vmctx.Send(StoragePowerAddress, SPAMethods.UpdateStorage, types.NewInt(0), enc) + if err != nil { + return err + } + + self.ProvingSet = self.Sectors + self.ElectionPeriodStart = vmctx.BlockHeight() + return nil +} + func slasherShare(total types.BigInt, elapsed uint64) types.BigInt { // [int(pow(1.26, n) * 10) for n in range(30)] fracs := []uint64{10, 12, 15, 20, 25, 31, 40, 50, 63, 80, 100, 127, 160, 201, 254, 320, 403, 508, 640, 807, 1017, 1281, 1614, 2034, 2563, 3230, 4070, 5128, 6462, 8142} diff --git a/chain/actors/cbor_gen.go b/chain/actors/cbor_gen.go index 522896008..8a8688208 100644 --- a/chain/actors/cbor_gen.go +++ b/chain/actors/cbor_gen.go @@ -198,7 +198,7 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{139}); err != nil { + if _, err := w.Write([]byte{138}); err != nil { return err } @@ -258,11 +258,6 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { return err } - // t.t.NextDoneSet (types.BitField) (struct) - if err := t.NextDoneSet.MarshalCBOR(w); err != nil { - return err - } - // t.t.Power (types.BigInt) (struct) if err := t.Power.MarshalCBOR(w); err != nil { return err @@ -278,8 +273,8 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { return err } - // t.t.ProvingPeriodEnd (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ProvingPeriodEnd))); err != nil { + // t.t.ElectionPeriodStart (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ElectionPeriodStart))); err != nil { return err } return nil @@ -296,7 +291,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 11 { + if extra != 10 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -406,15 +401,6 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { return err } - } - // t.t.NextDoneSet (types.BitField) (struct) - - { - - if err := t.NextDoneSet.UnmarshalCBOR(br); err != nil { - return err - } - } // t.t.Power (types.BigInt) (struct) @@ -452,7 +438,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("wrong type for uint64 field") } t.SlashedAt = uint64(extra) - // t.t.ProvingPeriodEnd (uint64) (uint64) + // t.t.ElectionPeriodStart (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -461,7 +447,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.ProvingPeriodEnd = uint64(extra) + t.ElectionPeriodStart = uint64(extra) return nil } @@ -832,7 +818,7 @@ func (t *SubmitPoStParams) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{130}); err != nil { + if _, err := w.Write([]byte{129}); err != nil { return err } @@ -840,11 +826,6 @@ func (t *SubmitPoStParams) MarshalCBOR(w io.Writer) error { if err := t.Proof.MarshalCBOR(w); err != nil { return err } - - // t.t.DoneSet (types.BitField) (struct) - if err := t.DoneSet.MarshalCBOR(w); err != nil { - return err - } return nil } @@ -859,7 +840,7 @@ func (t *SubmitPoStParams) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 2 { + if extra != 1 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -871,15 +852,6 @@ func (t *SubmitPoStParams) UnmarshalCBOR(r io.Reader) error { return err } - } - // t.t.DoneSet (types.BitField) (struct) - - { - - if err := t.DoneSet.UnmarshalCBOR(br); err != nil { - return err - } - } return nil } diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 741af0351..c4eabdc18 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -366,6 +366,8 @@ type MiningCheckAPI interface { StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error) + StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) + WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) } @@ -398,20 +400,24 @@ func (mca mca) StateMinerSectorSize(ctx context.Context, maddr address.Address, return stmgr.GetMinerSectorSize(ctx, mca.sm, ts, maddr) } +func (mca mca) StateMinerProvingSet(ctx context.Context, maddr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) { + return stmgr.GetMinerProvingSet(ctx, mca.sm, ts, maddr) +} + func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*types.Signature, error) { return mca.w.Sign(ctx, a, v) } type ElectionPoStProver interface { - GenerateCandidates(context.Context, []byte) ([]sectorbuilder.EPostCandidate, error) - ComputeProof(context.Context, []byte, []sectorbuilder.EPostCandidate) ([]byte, error) + GenerateCandidates(context.Context, sectorbuilder.SortedPublicSectorInfo, []byte) ([]sectorbuilder.EPostCandidate, error) + ComputeProof(context.Context, sectorbuilder.SortedPublicSectorInfo, []byte, []sectorbuilder.EPostCandidate) ([]byte, error) } type eppProvider struct { - sectors []sectorbuilder.SectorInfo + sectors []sectorbuilder.PublicSectorInfo } -func (epp *eppProvider) GenerateCandidates(ctx context.Context, eprand []byte) ([]sectorbuilder.EPostCandidate, error) { +func (epp *eppProvider) GenerateCandidates(ctx context.Context, _ sectorbuilder.SortedPublicSectorInfo, eprand []byte) ([]sectorbuilder.EPostCandidate, error) { return []sectorbuilder.EPostCandidate{ sectorbuilder.EPostCandidate{ SectorID: 1, @@ -422,7 +428,7 @@ func (epp *eppProvider) GenerateCandidates(ctx context.Context, eprand []byte) ( }, nil } -func (epp *eppProvider) ComputeProof(ctx context.Context, eprand []byte, winners []sectorbuilder.EPostCandidate) ([]byte, error) { +func (epp *eppProvider) ComputeProof(ctx context.Context, _ sectorbuilder.SortedPublicSectorInfo, eprand []byte, winners []sectorbuilder.EPostCandidate) ([]byte, error) { return []byte("valid proof"), nil } @@ -443,9 +449,27 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add return false, nil, xerrors.Errorf("failed to compute VRF: %w", err) } - candidates, err := epp.GenerateCandidates(ctx, vrfout) + pset, err := a.StateMinerProvingSet(ctx, miner, ts) if err != nil { - return false, nil, xerrors.Errorf("failed to generate electionPoSt candidates") + return false, nil, xerrors.Errorf("failed to load proving set for miner: %w", err) + } + log.Warningf("Proving set for miner %s: %s", miner, pset) + + var sinfos []sectorbuilder.PublicSectorInfo + for _, s := range pset { + var commRa [32]byte + copy(commRa[:], s.CommR) + sinfos = append(sinfos, sectorbuilder.PublicSectorInfo{ + SectorID: s.SectorID, + CommR: commRa, + }) + } + sectors := sectorbuilder.NewSortedPublicSectorInfo(sinfos) + + log.Info("Replicas: ", sectors) + candidates, err := epp.GenerateCandidates(ctx, sectors, vrfout) + if err != nil { + return false, nil, xerrors.Errorf("failed to generate electionPoSt candidates: %w", err) } pow, err := a.StateMinerPower(ctx, miner, ts) @@ -470,7 +494,7 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add return false, nil, nil } - proof, err := epp.ComputeProof(ctx, vrfout, winners) + proof, err := epp.ComputeProof(ctx, sectors, vrfout, winners) if err != nil { return false, nil, xerrors.Errorf("failed to compute snark for election proof: %w", err) } diff --git a/chain/gen/utils.go b/chain/gen/utils.go index 754275208..25185ad78 100644 --- a/chain/gen/utils.go +++ b/chain/gen/utils.go @@ -20,6 +20,7 @@ import ( "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" + "github.com/filecoin-project/lotus/genesis" ) type GenesisBootstrap struct { @@ -215,8 +216,7 @@ type GenMinerCfg struct { Owners []address.Address Workers []address.Address - // not quite generating real sectors yet, but this will be necessary - //SectorDir string + PreSeals map[string]genesis.GenesisMiner // The addresses of the created miner, this is set by the genesis setup MinerAddrs []address.Address @@ -289,16 +289,23 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid if err := cst.Get(ctx, mact.Head, &mstate); err != nil { return cid.Undef, xerrors.Errorf("getting miner actor state failed: %w", err) } - mstate.Power = types.NewInt(5000) + mstate.Power = types.NewInt(build.SectorSizes[0]) - commD := make([]byte, 32) - commR := make([]byte, 32) blks := amt.WrapBlockstore(cs.Blockstore()) - nssroot, err := actors.AddToSectorSet(ctx, blks, mstate.Sectors, 1, commD, commR) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to add fake sector to sector set: %w", err) + + ps, ok := gmcfg.PreSeals[maddr.String()] + if ok { + for _, s := range ps.Sectors { + nssroot, err := actors.AddToSectorSet(ctx, blks, mstate.Sectors, s.SectorID, s.CommD[:], s.CommR[:]) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to add fake sector to sector set: %w", err) + } + mstate.Sectors = nssroot + mstate.ProvingSet = nssroot + } + } else { + log.Warning("No preseals for miner: ", maddr) } - mstate.Sectors = nssroot nstate, err := cst.Put(ctx, &mstate) if err != nil { diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 68c3ea24e..ad23f55f5 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -84,6 +84,7 @@ func (sm *StateManager) TipSetState(ctx context.Context, ts *types.TipSet) (cid. func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.BlockHeader, cb func(cid.Cid, *types.Message, *vm.ApplyRet) error) (cid.Cid, cid.Cid, error) { ctx, span := trace.StartSpan(ctx, "computeTipSetState") defer span.End() + fmt.Println("COMPUTE TIPSET STATE", len(blks)) for i := 0; i < len(blks); i++ { for j := i + 1; j < len(blks); j++ { @@ -113,9 +114,14 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl if err != nil { return cid.Undef, cid.Undef, xerrors.Errorf("failed to get network actor: %w", err) } - reward := vm.MiningReward(netact.Balance) for _, b := range blks { + netact, err = vmi.StateTree().GetActor(actors.NetworkAddress) + if err != nil { + return cid.Undef, cid.Undef, xerrors.Errorf("failed to get network actor: %w", err) + } + vmi.SetBlockMiner(b.Miner) + owner, err := GetMinerOwner(ctx, sm, pstate, b.Miner) if err != nil { return cid.Undef, cid.Undef, xerrors.Errorf("failed to get owner for miner %s: %w", b.Miner, err) @@ -130,6 +136,24 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl return cid.Undef, cid.Undef, xerrors.Errorf("failed to deduct funds from network actor: %w", err) } + // all block miners created a valid post, go update the actor state + fmt.Println("SUBMIT ELECTION POST TIME", netact.Nonce, b.Height) + postSubmitMsg := &types.Message{ + From: actors.NetworkAddress, + Nonce: netact.Nonce, + To: b.Miner, + Method: actors.MAMethods.SubmitElectionPoSt, + GasPrice: types.NewInt(0), + GasLimit: types.NewInt(10000000000), + Value: types.NewInt(0), + } + ret, err := vmi.ApplyMessage(ctx, postSubmitMsg) + if err != nil { + return cid.Undef, cid.Undef, xerrors.Errorf("submit election post message invocation failed: %w", err) + } + if ret.ExitCode != 0 { + return cid.Undef, cid.Undef, xerrors.Errorf("submit election post invocation returned nonzero exit code: %d", ret.ExitCode) + } } // TODO: can't use method from chainstore because it doesnt let us know who the block miners were diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 6540e86ed..39017cb2d 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -155,7 +155,8 @@ func GetMinerProvingPeriodEnd(ctx context.Context, sm *StateManager, ts *types.T return 0, xerrors.Errorf("failed to load miner actor state: %w", err) } - return mas.ProvingPeriodEnd, nil + panic("idk what to do") + //return mas.ProvingPeriodEnd, nil } func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.ChainSectorInfo, error) { @@ -178,23 +179,23 @@ func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.Sectors) } -func GetSectorsForElectionPost(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (*sectorbuilder.SortedSectorInfo, error) { +func GetSectorsForElectionPost(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (*sectorbuilder.SortedPublicSectorInfo, error) { sectors, err := GetMinerSectorSet(ctx, sm, ts, maddr) if err != nil { return nil, xerrors.Errorf("failed to get sector set for miner: %w", err) } - var uselessOtherArray []sectorbuilder.SectorInfo + var uselessOtherArray []sectorbuilder.PublicSectorInfo for _, s := range sectors { var uselessBuffer [32]byte copy(uselessBuffer[:], s.CommR) - uselessOtherArray = append(uselessOtherArray, sectorbuilder.SectorInfo{ + uselessOtherArray = append(uselessOtherArray, sectorbuilder.PublicSectorInfo{ SectorID: s.SectorID, CommR: uselessBuffer, }) } - ssi := sectorbuilder.NewSortedSectorInfo(uselessOtherArray) + ssi := sectorbuilder.NewSortedPublicSectorInfo(uselessOtherArray) return &ssi, nil } diff --git a/chain/store/weight.go b/chain/store/weight.go index 901356728..72811ebec 100644 --- a/chain/store/weight.go +++ b/chain/store/weight.go @@ -40,6 +40,7 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn log2P = int64(tpow.BitLen() - 1) } else { // Not really expect to be here ... + panic("where are we") return types.EmptyInt, xerrors.Errorf("All power in the net is gone. You network might be disconnected, or the net is dead!") } diff --git a/cli/cmd.go b/cli/cmd.go index 30e9ba01a..f80c80453 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -122,7 +122,6 @@ var Commands = []*cli.Command{ sendCmd, stateCmd, syncCmd, - unregisterMinerCmd, versionCmd, walletCmd, } diff --git a/cli/miner.go b/cli/miner.go deleted file mode 100644 index 074faf962..000000000 --- a/cli/miner.go +++ /dev/null @@ -1,32 +0,0 @@ -package cli - -import ( - "fmt" - - "github.com/filecoin-project/lotus/chain/address" - "gopkg.in/urfave/cli.v2" -) - -var unregisterMinerCmd = &cli.Command{ - Name: "unregister-miner", - Usage: "Manually unregister miner actor", - Action: func(cctx *cli.Context) error { - api, closer, err := GetFullNodeAPI(cctx) - if err != nil { - return err - } - defer closer() - ctx := ReqContext(cctx) - - if !cctx.Args().Present() { - return fmt.Errorf("must pass address of miner to unregister") - } - - maddr, err := address.NewFromString(cctx.Args().First()) - if err != nil { - return err - } - - return api.MinerUnregister(ctx, maddr) - }, -} diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go new file mode 100644 index 000000000..8bbf4d9df --- /dev/null +++ b/cmd/lotus-seed/main.go @@ -0,0 +1,162 @@ +package main + +import ( + "crypto/sha256" + "encoding/json" + "fmt" + "io/ioutil" + "math/rand" + "os" + "path/filepath" + + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/address" + "github.com/filecoin-project/lotus/genesis" + "github.com/filecoin-project/lotus/lib/sectorbuilder" + + badger "github.com/ipfs/go-ds-badger" + logging "github.com/ipfs/go-log" + "github.com/mitchellh/go-homedir" + "gopkg.in/urfave/cli.v2" +) + +var log = logging.Logger("lotus-seed") + +func main() { + logging.SetLogLevel("*", "INFO") + + log.Info("Starting seed") + + local := []*cli.Command{ + preSealCmd, + } + + app := &cli.App{ + Name: "lotus-seed", + Usage: "Seal sectors for genesis miner", + Version: build.Version, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "sectorbuilder-dir", + Value: "~/.genesis-sectors", + }, + }, + + Commands: local, + } + + if err := app.Run(os.Args); err != nil { + log.Warn(err) + return + } +} + +var preSealCmd = &cli.Command{ + Name: "pre-seal", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "miner-addr", + Value: "t0101", + Usage: "specify the future address of your miner", + }, + &cli.Uint64Flag{ + Name: "sector-size", + Value: 1024, + Usage: "specify size of sectors to pre-seal", + }, + &cli.StringFlag{ + Name: "ticket-preimage", + Value: "lotus is fire", + Usage: "set the ticket preimage for sealing randomness", + }, + &cli.Uint64Flag{ + Name: "num-sectors", + Value: 1, + Usage: "select number of sectors to pre-seal", + }, + }, + Action: func(c *cli.Context) error { + sdir := c.String("sectorbuilder-dir") + sbroot, err := homedir.Expand(sdir) + if err != nil { + return err + } + + maddr, err := address.NewFromString(c.String("miner-addr")) + if err != nil { + return err + } + + cfg := §orbuilder.Config{ + Miner: maddr, + SectorSize: c.Uint64("sector-size"), + CacheDir: filepath.Join(sbroot, "cache"), + SealedDir: filepath.Join(sbroot, "sealed"), + StagedDir: filepath.Join(sbroot, "staging"), + MetadataDir: filepath.Join(sbroot, "meta"), + WorkerThreads: 2, + } + + for _, d := range []string{cfg.CacheDir, cfg.SealedDir, cfg.StagedDir, cfg.MetadataDir} { + if err := os.MkdirAll(d, 0775); err != nil { + return err + } + } + + mds, err := badger.NewDatastore(filepath.Join(sbroot, "badger"), nil) + if err != nil { + return err + } + + sb, err := sectorbuilder.New(cfg, mds) + if err != nil { + return err + } + + r := rand.New(rand.NewSource(101)) + size := sectorbuilder.UserBytesForSectorSize(c.Uint64("sector-size")) + + var sealedSectors []genesis.PreSeal + for i := uint64(1); i <= c.Uint64("num-sectors"); i++ { + pi, err := sb.AddPiece(size, i, r, nil) + if err != nil { + return err + } + + trand := sha256.Sum256([]byte(c.String("ticket-preimage"))) + ticket := sectorbuilder.SealTicket{ + TicketBytes: trand, + } + + fmt.Println("Piece info: ", pi) + + pco, err := sb.SealPreCommit(i, ticket, []sectorbuilder.PublicPieceInfo{pi}) + if err != nil { + return err + } + + sealedSectors = append(sealedSectors, genesis.PreSeal{ + CommR: pco.CommR, + CommD: pco.CommD, + SectorID: i, + }) + } + + output := map[string]genesis.GenesisMiner{ + maddr.String(): genesis.GenesisMiner{ + Sectors: sealedSectors, + }, + } + + out, err := json.MarshalIndent(output, "", " ") + if err != nil { + return err + } + + if err := ioutil.WriteFile("pre-seal-"+maddr.String()+".json", out, 0664); err != nil { + return err + } + + return nil + }, +} diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 06500af95..a14090f59 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -4,6 +4,7 @@ import ( "context" "crypto/rand" "os" + "path/filepath" "github.com/ipfs/go-datastore" "github.com/libp2p/go-libp2p-core/crypto" @@ -18,7 +19,11 @@ import ( "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" + "github.com/filecoin-project/lotus/lib/sectorbuilder" + "github.com/filecoin-project/lotus/miner" + "github.com/filecoin-project/lotus/node/modules" "github.com/filecoin-project/lotus/node/repo" + "github.com/filecoin-project/lotus/storage" ) var initCmd = &cli.Command{ @@ -53,6 +58,10 @@ var initCmd = &cli.Command{ Usage: "specify sector size to use", Value: build.SectorSizes[0], }, + &cli.StringFlag{ + Name: "pre-sealed-sectors", + Usage: "specify set of presealed sectors for starting as a genesis miner", + }, }, Action: func(cctx *cli.Context) error { log.Info("Initializing lotus storage miner") @@ -104,6 +113,13 @@ var initCmd = &cli.Command{ return err } + if pssb := cctx.String("pre-sealed-sectors"); pssb != "" { + log.Infof("moving pre-sealed-sectors from %s into newly created storage miner repo", pssb) + if err := migratePreSealedSectors(pssb, repoPath); err != nil { + return err + } + } + if err := storageMinerInit(ctx, cctx, api, r); err != nil { log.Errorf("Failed to initialize lotus-storage-miner: %+v", err) path, err := homedir.Expand(repoPath) @@ -124,6 +140,35 @@ var initCmd = &cli.Command{ }, } +// TODO: this method should be a lot more robust for mainnet. For testnet, its +// fine if we mess things up a few times +func migratePreSealedSectors(presealsb string, repoPath string) error { + pspath, err := homedir.Expand(presealsb) + if err != nil { + return err + } + + expRepo, err := homedir.Expand(repoPath) + if err != nil { + return err + } + + if stat, err := os.Stat(pspath); err != nil { + return xerrors.Errorf("failed to stat presealed sectors directory: %w", err) + } else if !stat.IsDir() { + return xerrors.Errorf("given presealed sectors path was not a directory: %w", err) + } + + for _, dir := range []string{"meta", "sealed", "staging", "cache"} { + from := filepath.Join(pspath, dir) + to := filepath.Join(expRepo, dir) + if err := os.Rename(from, to); err != nil { + return err + } + } + return nil +} + func storageMinerInit(ctx context.Context, cctx *cli.Context, api api.FullNode, r repo.Repo) error { lr, err := r.Lock(repo.StorageMiner) if err != nil { @@ -150,8 +195,47 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api api.FullNode, return xerrors.Errorf("failed parsing actor flag value (%q): %w", act, err) } - if err := configureStorageMiner(ctx, api, a, peerid, cctx.Bool("genesis-miner")); err != nil { - return xerrors.Errorf("failed to configure storage miner: %w", err) + if cctx.Bool("genesis-miner") { + mds, err := lr.Datastore("/metadata") + if err != nil { + return err + } + if err := mds.Put(datastore.NewKey("miner-address"), a.Bytes()); err != nil { + return err + } + + sbcfg, err := modules.SectorBuilderConfig(lr.Path(), 2)(mds, api) + if err != nil { + return xerrors.Errorf("getting genesis miner sector builder config: %w", err) + } + sb, err := sectorbuilder.New(sbcfg, mds) + if err != nil { + return xerrors.Errorf("failed to set up sectorbuilder for genesis mining: %w", err) + } + epp := storage.NewElectionPoStProver(sb) + + m := miner.NewMiner(api, epp) + { + if err := m.Register(a); err != nil { + return xerrors.Errorf("failed to start up genesis miner: %w", err) + } + + defer func() { + if err := m.Unregister(ctx, a); err != nil { + log.Error("failed to shut down storage miner: ", err) + } + }() + + if err := configureStorageMiner(ctx, api, a, peerid); err != nil { + return xerrors.Errorf("failed to configure storage miner: %w", err) + } + } + + return nil + } else { + if err := configureStorageMiner(ctx, api, a, peerid); err != nil { + return xerrors.Errorf("failed to configure storage miner: %w", err) + } } addr = a @@ -165,12 +249,11 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api api.FullNode, } log.Infof("Created new storage miner: %s", addr) - - ds, err := lr.Datastore("/metadata") + mds, err := lr.Datastore("/metadata") if err != nil { return err } - if err := ds.Put(datastore.NewKey("miner-address"), addr.Bytes()); err != nil { + if err := mds.Put(datastore.NewKey("miner-address"), addr.Bytes()); err != nil { return err } @@ -203,22 +286,7 @@ func makeHostKey(lr repo.LockedRepo) (crypto.PrivKey, error) { return pk, nil } -func configureStorageMiner(ctx context.Context, api api.FullNode, addr address.Address, peerid peer.ID, genmine bool) error { - if genmine { - log.Warn("Starting genesis mining. This shouldn't happen when connecting to the real network.") - // We may be one of genesis miners, start mining before trying to do any chain operations - // (otherwise our messages won't be mined) - if err := api.MinerRegister(ctx, addr); err != nil { - return err - } - - defer func() { - if err := api.MinerUnregister(ctx, addr); err != nil { - log.Errorf("failed to call api.MinerUnregister: %s", err) - } - }() - } - +func configureStorageMiner(ctx context.Context, api api.FullNode, addr address.Address, peerid peer.ID) error { // This really just needs to be an api call at this point... recp, err := api.StateCall(ctx, &types.Message{ To: addr, diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 115970d54..87ff1f0ad 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -21,7 +21,8 @@ import ( ) const ( - makeGenFlag = "lotus-make-random-genesis" + makeGenFlag = "lotus-make-random-genesis" + preSealedSectorsFlag = "genesis-presealed-sectors" ) // DaemonCmd is the `go-lotus daemon` command @@ -38,6 +39,10 @@ var DaemonCmd = &cli.Command{ Value: "", Hidden: true, }, + &cli.StringFlag{ + Name: "genesis-presealed-sectors", + Hidden: true, + }, &cli.StringFlag{ Name: "genesis", Usage: "genesis file to use for first node run", @@ -69,7 +74,6 @@ var DaemonCmd = &cli.Command{ if err != nil { return err } - } genesis := node.Options() @@ -77,7 +81,10 @@ var DaemonCmd = &cli.Command{ genesis = node.Override(new(modules.Genesis), modules.LoadGenesis(genBytes)) } if cctx.String(makeGenFlag) != "" { - genesis = node.Override(new(modules.Genesis), testing.MakeGenesis(cctx.String(makeGenFlag))) + if cctx.String(preSealedSectorsFlag) == "" { + return xerrors.Errorf("must also pass file with miner preseal info to `--%s`", preSealedSectorsFlag) + } + genesis = node.Override(new(modules.Genesis), testing.MakeGenesis(cctx.String(makeGenFlag), cctx.String(preSealedSectorsFlag))) } var api api.FullNode diff --git a/extern/go-sectorbuilder b/extern/go-sectorbuilder index 33fb89c5e..e75744852 160000 --- a/extern/go-sectorbuilder +++ b/extern/go-sectorbuilder @@ -1 +1 @@ -Subproject commit 33fb89c5efe02a250508e95114836bd13dd3067e +Subproject commit e757448529bd87318e9b52b93661f6cda1a76a42 diff --git a/genesis/types.go b/genesis/types.go new file mode 100644 index 000000000..36abd8f28 --- /dev/null +++ b/genesis/types.go @@ -0,0 +1,15 @@ +package genesis + +import "github.com/filecoin-project/lotus/chain/address" + +type PreSeal struct { + CommR [32]byte + CommD [32]byte + SectorID uint64 +} + +type GenesisMiner struct { + Sectors []PreSeal + Owner address.Address + Worker address.Address +} diff --git a/go.mod b/go.mod index 37ef67f4d..5fb9e2754 100644 --- a/go.mod +++ b/go.mod @@ -89,6 +89,7 @@ require ( github.com/smartystreets/assertions v1.0.1 // indirect github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect github.com/stretchr/testify v1.4.0 + github.com/urfave/cli v1.20.0 github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba github.com/whyrusleeping/cbor-gen v0.0.0-20191116002219-891f55cd449d github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 diff --git a/go.sum b/go.sum index f095026ec..d9f303a61 100644 --- a/go.sum +++ b/go.sum @@ -538,6 +538,7 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 3f3eeac2d..eae5bec7a 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -31,9 +31,11 @@ type SectorSealingStatus = sectorbuilder.SectorSealingStatus type StagedSectorMetadata = sectorbuilder.StagedSectorMetadata -type SortedSectorInfo = sectorbuilder.SortedSectorInfo +type SortedPublicSectorInfo = sectorbuilder.SortedPublicSectorInfo +type SortedPrivateSectorInfo = sectorbuilder.SortedPrivateSectorInfo -type SectorInfo = sectorbuilder.SectorInfo +type PrivateSectorInfo = sectorbuilder.SectorPrivateInfo +type PublicSectorInfo = sectorbuilder.SectorPublicInfo type SealTicket = sectorbuilder.SealTicket @@ -347,21 +349,49 @@ func (sb *SectorBuilder) SectorSize() uint64 { return sb.ssize } -func (sb *SectorBuilder) ComputeElectionPoSt(sectorInfo SortedSectorInfo, challengeSeed []byte, winners []EPostCandidate) ([]byte, error) { +func (sb *SectorBuilder) ComputeElectionPoSt(sectorInfo SortedPublicSectorInfo, challengeSeed []byte, winners []EPostCandidate) ([]byte, error) { if len(challengeSeed) != CommLen { return nil, xerrors.Errorf("given challenge seed was the wrong length: %d != %d", len(challengeSeed), CommLen) } var cseed [CommLen]byte copy(cseed[:], challengeSeed) - return sectorbuilder.GeneratePoSt(sb.handle, sectorInfo, cseed, winners) + return sectorbuilder.GeneratePoSt(sb.handle, sectorInfo, cseed, 1, winners) } -func (sb *SectorBuilder) GenerateEPostCandidates(sectorInfo SortedSectorInfo, challengeSeed [CommLen]byte, faults []uint64) ([]EPostCandidate, error) { - return sectorbuilder.GenerateCandidates(sb.handle, sectorInfo, challengeSeed, faults) +func (sb *SectorBuilder) GenerateEPostCandidates(sectorInfo SortedPublicSectorInfo, challengeSeed [CommLen]byte, faults []uint64) ([]EPostCandidate, error) { + privsectors, err := sb.pubSectorToPriv(sectorInfo) + if err != nil { + return nil, err + } + proverID := addressToProverID(sb.Miner) + return sectorbuilder.StandaloneGenerateCandidates(sb.ssize, proverID, challengeSeed, 1, privsectors) } -func (sb *SectorBuilder) GenerateFallbackPoSt(sectorInfo SortedSectorInfo, challengeSeed [CommLen]byte, faults []uint64) ([]byte, error) { +func (sb *SectorBuilder) pubSectorToPriv(sectorInfo SortedPublicSectorInfo) (SortedPrivateSectorInfo, error) { + var out []PrivateSectorInfo + for _, s := range sectorInfo.Values() { + cachePath, err := sb.sectorCacheDir(s.SectorID) + if err != nil { + return SortedPrivateSectorInfo{}, xerrors.Errorf("getting cache path for sector %d: %w", s.SectorID, err) + } + + sealedPath, err := sb.sealedSectorPath(s.SectorID) + if err != nil { + return SortedPrivateSectorInfo{}, xerrors.Errorf("getting sealed path for sector %d: %w", s.SectorID, err) + } + + out = append(out, PrivateSectorInfo{ + SectorID: s.SectorID, + CommR: s.CommR, + CacheDirPath: cachePath, + SealedSectorPath: sealedPath, + }) + } + return NewSortedPrivateSectorInfo(out), nil +} + +func (sb *SectorBuilder) GenerateFallbackPoSt(sectorInfo SortedPrivateSectorInfo, challengeSeed [CommLen]byte, faults []uint64) ([]byte, error) { panic("NYI") } @@ -378,18 +408,22 @@ func VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, seeda, sectorID, proof) } -func NewSortedSectorInfo(sectors []SectorInfo) SortedSectorInfo { - return sectorbuilder.NewSortedSectorInfo(sectors...) +func NewSortedPrivateSectorInfo(sectors []PrivateSectorInfo) SortedPrivateSectorInfo { + return sectorbuilder.NewSortedSectorPrivateInfo(sectors...) } -func VerifyPost(ctx context.Context, sectorSize uint64, sectorInfo SortedSectorInfo, challengeSeed []byte, proof []byte, winners []EPostCandidate, proverID address.Address) (bool, error) { +func NewSortedPublicSectorInfo(sectors []PublicSectorInfo) SortedPublicSectorInfo { + return sectorbuilder.NewSortedSectorPublicInfo(sectors...) +} + +func VerifyPost(ctx context.Context, sectorSize uint64, sectorInfo SortedPublicSectorInfo, challengeSeed []byte, proof []byte, winners []EPostCandidate, proverID address.Address) (bool, error) { var challengeSeeda [CommLen]byte copy(challengeSeeda[:], challengeSeed) _, span := trace.StartSpan(ctx, "VerifyPoSt") defer span.End() prover := addressToProverID(proverID) - return sectorbuilder.VerifyPoSt(sectorSize, sectorInfo, challengeSeeda, proof, winners, prover) + return sectorbuilder.VerifyPoSt(sectorSize, sectorInfo, challengeSeeda, 1, proof, winners, prover) } func GeneratePieceCommitment(piece io.Reader, pieceSize uint64) (commP [CommLen]byte, err error) { diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index 044c690bf..15f8beeed 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -1,7 +1,6 @@ package sectorbuilder_test import ( - "context" "io" "io/ioutil" "math/rand" @@ -77,25 +76,28 @@ func (s *seal) commit(t *testing.T, sb *sectorbuilder.SectorBuilder, done func() } func (s *seal) post(t *testing.T, sb *sectorbuilder.SectorBuilder) { - cSeed := [32]byte{0, 9, 2, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 45, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9} + /* + // TODO: fixme + cSeed := [32]byte{0, 9, 2, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 45, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9} - ssi := sectorbuilder.NewSortedSectorInfo([]sectorbuilder.SectorInfo{{ - SectorID: s.sid, - CommR: s.pco.CommR, - }}) + ssi := sectorbuilder.NewSortedPublicSectorInfo([]sectorbuilder.PublicSectorInfo{{ + SectorID: s.sid, + CommR: s.pco.CommR, + }}) - postProof, err := sb.GeneratePoSt(ssi, cSeed, []uint64{}) - if err != nil { - t.Fatalf("%+v", err) - } + postProof, err := sb.GeneratePoSt(ssi, cSeed, []uint64{}) + if err != nil { + t.Fatalf("%+v", err) + } - ok, err := sectorbuilder.VerifyPost(context.TODO(), sb.SectorSize(), ssi, cSeed, postProof, []uint64{}) - if err != nil { - t.Fatalf("%+v", err) - } - if !ok { - t.Fatal("bad post") - } + ok, err := sectorbuilder.VerifyPost(context.TODO(), sb.SectorSize(), ssi, cSeed, postProof, []uint64{}) + if err != nil { + t.Fatalf("%+v", err) + } + if !ok { + t.Fatal("bad post") + } + */ } func TestSealAndVerify(t *testing.T) { diff --git a/miner/miner.go b/miner/miner.go index 56f78e5fe..7fa0f63c2 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -5,17 +5,16 @@ import ( "sync" "time" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/node/impl/full" logging "github.com/ipfs/go-log" "github.com/pkg/errors" "go.opencensus.io/trace" - "go.uber.org/fx" "golang.org/x/xerrors" ) @@ -23,20 +22,10 @@ var log = logging.Logger("miner") type waitFunc func(ctx context.Context) error -type api struct { - fx.In - - full.ChainAPI - full.SyncAPI - full.MpoolAPI - full.WalletAPI - full.StateAPI -} - -func NewMiner(api api) *Miner { +func NewMiner(api api.FullNode, epp gen.ElectionPoStProver) *Miner { return &Miner{ api: api, - epp: nil, + epp: epp, waitFunc: func(ctx context.Context) error { // Wait around for half the block time in case other parents come in time.Sleep(build.BlockDelay * time.Second / 2) @@ -46,7 +35,7 @@ func NewMiner(api api) *Miner { } type Miner struct { - api api + api api.FullNode epp gen.ElectionPoStProver @@ -256,9 +245,9 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB return nil, errors.Wrap(err, "scratching ticket failed") } - win, proof, err := gen.IsRoundWinner(ctx, base.ts, int64(base.ts.Height()+base.nullRounds+1), addr, m.epp, &m.api) + win, proof, err := gen.IsRoundWinner(ctx, base.ts, int64(base.ts.Height()+base.nullRounds+1), addr, m.epp, m.api) if err != nil { - return nil, errors.Wrap(err, "failed to check if we win next round") + return nil, xerrors.Errorf("failed to check if we win next round: %w", err) } if !win { diff --git a/miner/testminer.go b/miner/testminer.go index 6adf02266..48fbd92a6 100644 --- a/miner/testminer.go +++ b/miner/testminer.go @@ -2,10 +2,12 @@ package miner import ( "context" + + "github.com/filecoin-project/lotus/api" ) -func NewTestMiner(nextCh <-chan struct{}) func(api api) *Miner { - return func(api api) *Miner { +func NewTestMiner(nextCh <-chan struct{}) func(api api.FullNode) *Miner { + return func(api api.FullNode) *Miner { return &Miner{ api: api, waitFunc: chanWaiter(nextCh), diff --git a/node/builder.go b/node/builder.go index 02082a3e5..3512354ec 100644 --- a/node/builder.go +++ b/node/builder.go @@ -22,6 +22,7 @@ import ( "github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain/blocksync" "github.com/filecoin-project/lotus/chain/deals" + "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/market" "github.com/filecoin-project/lotus/chain/metrics" "github.com/filecoin-project/lotus/chain/stmgr" @@ -92,7 +93,6 @@ const ( HandleDealsKey HandleRetrievalKey RunSectorServiceKey - RegisterMinerKey RegisterProviderValidatorKey // daemon @@ -231,8 +231,6 @@ func Online() Option { Override(new(*paych.Store), paych.NewStore), Override(new(*paych.Manager), paych.NewManager), Override(new(*market.FundMgr), market.NewFundMgr), - - Override(new(*miner.Miner), miner.NewMiner), ), // Storage miner @@ -252,7 +250,8 @@ func Online() Option { Override(RegisterProviderValidatorKey, modules.RegisterProviderValidator), Override(HandleRetrievalKey, modules.HandleRetrieval), Override(HandleDealsKey, modules.HandleDeals), - Override(RegisterMinerKey, modules.RegisterMiner), + Override(new(gen.ElectionPoStProver), storage.NewElectionPoStProver), + Override(new(*miner.Miner), modules.SetupBlockProducer), ), ) } diff --git a/node/impl/full.go b/node/impl/full.go index 76cdc5de4..2c01674fb 100644 --- a/node/impl/full.go +++ b/node/impl/full.go @@ -1,8 +1,6 @@ package impl import ( - "context" - logging "github.com/ipfs/go-log" "github.com/filecoin-project/lotus/node/impl/client" @@ -10,8 +8,6 @@ import ( "github.com/filecoin-project/lotus/node/impl/paych" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/address" - "github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/node/impl/full" ) @@ -27,20 +23,6 @@ type FullNodeAPI struct { full.StateAPI full.WalletAPI full.SyncAPI - - Miner *miner.Miner -} - -func (a *FullNodeAPI) MinerAddresses(context.Context) ([]address.Address, error) { - return a.Miner.Addresses() -} - -func (a *FullNodeAPI) MinerRegister(ctx context.Context, addr address.Address) error { - return a.Miner.Register(addr) -} - -func (a *FullNodeAPI) MinerUnregister(ctx context.Context, addr address.Address) error { - return a.Miner.Unregister(ctx, addr) } var _ api.FullNode = &FullNodeAPI{} diff --git a/node/impl/storminer.go b/node/impl/storminer.go index f339fd66a..04f162c30 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -6,6 +6,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/lib/sectorbuilder" + "github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/storage" "github.com/filecoin-project/lotus/storage/sectorblocks" ) @@ -17,8 +18,9 @@ type StorageMinerAPI struct { SectorBuilder *sectorbuilder.SectorBuilder SectorBlocks *sectorblocks.SectorBlocks - Miner *storage.Miner - Full api.FullNode + Miner *storage.Miner + BlockMiner *miner.Miner + Full api.FullNode } func (sm *StorageMinerAPI) WorkerStats(context.Context) (api.WorkerStats, error) { diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index a7cc98463..bf0a6b98a 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -2,7 +2,6 @@ package modules import ( "context" - "fmt" "math" "path/filepath" "reflect" @@ -24,9 +23,11 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/deals" + "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/datatransfer" "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/lib/statestore" + "github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/helpers" "github.com/filecoin-project/lotus/node/repo" @@ -176,26 +177,27 @@ func StagingDAG(mctx helpers.MetricsCtx, lc fx.Lifecycle, r repo.LockedRepo, rt return dag, nil } -func RegisterMiner(lc fx.Lifecycle, ds dtypes.MetadataDS, api api.FullNode) error { +func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api api.FullNode, epp gen.ElectionPoStProver) (*miner.Miner, error) { minerAddr, err := minerAddrFromDS(ds) if err != nil { - return err + return nil, err } + m := miner.NewMiner(api, epp) + lc.Append(fx.Hook{ OnStart: func(ctx context.Context) error { - log.Infof("Registering miner '%s' with full node", minerAddr) - if err := api.MinerRegister(ctx, minerAddr); err != nil { - return fmt.Errorf("Failed to register miner: %s\nIf you are certain no other storage miner instance is running, try running 'lotus unregister-miner %s' and restarting the storage miner", err, minerAddr) + if err := m.Register(minerAddr); err != nil { + return err } return nil }, OnStop: func(ctx context.Context) error { - log.Infof("Unregistering miner '%s' from full node", minerAddr) - return api.MinerUnregister(ctx, minerAddr) + return m.Unregister(ctx, minerAddr) }, }) - return nil + + return m, nil } func SectorBuilder(lc fx.Lifecycle, cfg *sectorbuilder.Config, ds dtypes.MetadataDS) (*sectorbuilder.SectorBuilder, error) { diff --git a/node/modules/testing/genesis.go b/node/modules/testing/genesis.go index 6c81f68ba..5b6519e47 100644 --- a/node/modules/testing/genesis.go +++ b/node/modules/testing/genesis.go @@ -2,8 +2,10 @@ package testing import ( "context" + "encoding/json" "fmt" "io" + "io/ioutil" "os" "time" @@ -19,6 +21,7 @@ import ( "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" + "github.com/filecoin-project/lotus/genesis" "github.com/filecoin-project/lotus/node/modules" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -61,19 +64,30 @@ func MakeGenesisMem(out io.Writer, minerPid peer.ID) func(bs dtypes.ChainBlockst } } -func MakeGenesis(outFile string) func(bs dtypes.ChainBlockstore, w *wallet.Wallet) modules.Genesis { +func MakeGenesis(outFile, preseal string) func(bs dtypes.ChainBlockstore, w *wallet.Wallet) modules.Genesis { return func(bs dtypes.ChainBlockstore, w *wallet.Wallet) modules.Genesis { return func() (*types.BlockHeader, error) { glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network") + fdata, err := ioutil.ReadFile(preseal) + if err != nil { + return nil, err + } + + var preseal map[string]genesis.GenesisMiner + if err := json.Unmarshal(fdata, &preseal); err != nil { + return nil, err + } + minerAddr, err := w.GenerateKey(types.KTBLS) if err != nil { return nil, err } gmc := &gen.GenMinerCfg{ - Owners: []address.Address{minerAddr}, - Workers: []address.Address{minerAddr}, - PeerIDs: []peer.ID{"peer ID 1"}, + Owners: []address.Address{minerAddr}, + Workers: []address.Address{minerAddr}, + PeerIDs: []peer.ID{"peer ID 1"}, + PreSeals: preseal, } addrs := map[address.Address]types.BigInt{ diff --git a/storage/miner.go b/storage/miner.go index 3750d41fe..f8323b2ac 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -14,6 +14,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/events" + "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/sectorbuilder" @@ -133,3 +134,25 @@ func (m *Miner) runPreflightChecks(ctx context.Context) error { log.Infof("starting up miner %s, worker addr %s", m.maddr, m.worker) return nil } + +type sectorBuilderEpp struct { + sb *sectorbuilder.SectorBuilder +} + +func NewElectionPoStProver(sb *sectorbuilder.SectorBuilder) *sectorBuilderEpp { + return §orBuilderEpp{sb} +} + +var _ (gen.ElectionPoStProver) = (*sectorBuilderEpp)(nil) + +func (epp *sectorBuilderEpp) GenerateCandidates(ctx context.Context, ssi sectorbuilder.SortedPublicSectorInfo, rand []byte) ([]sectorbuilder.EPostCandidate, error) { + var faults []uint64 // TODO + + var randbuf [32]byte + copy(randbuf[:], rand) + return epp.sb.GenerateEPostCandidates(ssi, randbuf, faults) +} + +func (epp *sectorBuilderEpp) ComputeProof(ctx context.Context, ssi sectorbuilder.SortedPublicSectorInfo, rand []byte, winners []sectorbuilder.EPostCandidate) ([]byte, error) { + return epp.sb.ComputeElectionPoSt(ssi, rand, winners) +} diff --git a/storage/post.go b/storage/post.go index 4f73b8af2..270a66751 100644 --- a/storage/post.go +++ b/storage/post.go @@ -164,19 +164,20 @@ func (p *post) preparePost(ctx context.Context) error { return nil } -func (p *post) sortedSectorInfo() sectorbuilder.SortedSectorInfo { - sbsi := make([]sectorbuilder.SectorInfo, len(p.sset)) +func (p *post) sortedSectorInfo() sectorbuilder.SortedPrivateSectorInfo { + panic("NYI") + sbsi := make([]sectorbuilder.PrivateSectorInfo, len(p.sset)) for k, sector := range p.sset { var commR [sectorbuilder.CommLen]byte copy(commR[:], sector.CommR) - sbsi[k] = sectorbuilder.SectorInfo{ + sbsi[k] = sectorbuilder.PrivateSectorInfo{ SectorID: sector.SectorID, CommR: commR, } } - return sectorbuilder.NewSortedSectorInfo(sbsi) + return sectorbuilder.NewSortedPrivateSectorInfo(sbsi) } func (p *post) runPost(ctx context.Context) error { @@ -210,33 +211,35 @@ func (p *post) commitPost(ctx context.Context) error { defer span.End() panic("NYI") - params := &actors.SubmitPoStParams{ - //Proof: p.proof, - DoneSet: types.BitFieldFromSet(nil), - } + /* - enc, aerr := actors.SerializeParams(params) - if aerr != nil { - return xerrors.Errorf("could not serialize submit post parameters: %w", aerr) - } + params := &actors.SubmitPoStParams{ + //Proof: p.proof, + } - msg := &types.Message{ - To: p.m.maddr, - From: p.m.worker, - Method: actors.MAMethods.SubmitPoSt, - Params: enc, - Value: types.NewInt(1000), // currently hard-coded late fee in actor, returned if not late - GasLimit: types.NewInt(1000000 /* i dont know help */), - GasPrice: types.NewInt(1), - } + enc, aerr := actors.SerializeParams(params) + if aerr != nil { + return xerrors.Errorf("could not serialize submit post parameters: %w", aerr) + } - log.Info("mpush") + msg := &types.Message{ + To: p.m.maddr, + From: p.m.worker, + Method: actors.MAMethods.SubmitPoSt, + Params: enc, + Value: types.NewInt(1000), // currently hard-coded late fee in actor, returned if not late + GasLimit: types.NewInt(1000000), // i dont know help + GasPrice: types.NewInt(1), + } - smsg, err := p.m.api.MpoolPushMessage(ctx, msg) - if err != nil { - return xerrors.Errorf("pushing message to mpool: %w", err) - } - p.smsg = smsg.Cid() + log.Info("mpush") + + smsg, err := p.m.api.MpoolPushMessage(ctx, msg) + if err != nil { + return xerrors.Errorf("pushing message to mpool: %w", err) + } + p.smsg = smsg.Cid() + */ return nil }