From 3e5654d575ecc24a3584830137b0fa8b3b59e6ca Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Thu, 24 Oct 2019 21:39:13 +0800 Subject: [PATCH 001/114] initial actor changes for interactive porep --- build/params.go | 3 + chain/actors/actor_miner.go | 93 ++++++++++++---- chain/actors/cbor_gen.go | 215 ++++++++++++++++++++++++++++-------- gen/main.go | 1 + storage/miner.go | 7 +- 5 files changed, 250 insertions(+), 69 deletions(-) diff --git a/build/params.go b/build/params.go index e810ff45f..f69fb05ef 100644 --- a/build/params.go +++ b/build/params.go @@ -81,6 +81,9 @@ const PowerCollateralProportion = 5 const PerCapitaCollateralProportion = 1 const CollateralPrecision = 1000 +// Blocks +const InteractivePoRepDelay = 10 + // ///// // Devnet settings diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index baa35d0d5..9e5689d1b 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -2,6 +2,7 @@ package actors import ( "context" + "encoding/binary" "fmt" "github.com/filecoin-project/lotus/build" @@ -52,9 +53,9 @@ type StorageMinerActorState struct { // removal penalization is needed. NextDoneSet types.BitField - // Deals this miner has been slashed for since the last post submission. - //TODO: unsupported map key type "Cid" (if you want to use struct keys, your atlas needs a transform to string) - //ArbitratedDeals map[cid.Cid]struct{} + // UnprovenSectors is the set of sectors that have been committed to but not + // yet had their proofs submitted + UnprovenSectors map[string]*UnprovenSector // Amount of power this miner has. Power types.BigInt @@ -90,6 +91,12 @@ type MinerInfo struct { SectorSize uint64 } +type UnprovenSector struct { + CommD []byte + CommR []byte + SubmitHeight uint64 +} + type StorageMinerConstructorParams struct { Owner address.Address Worker address.Address @@ -205,12 +212,11 @@ type OnChainSealVerifyInfo struct { Epoch uint64 Proof []byte - DealIDs []uint64 SectorNumber uint64 } func (sma StorageMinerActor) CommitSector(act *types.Actor, vmctx types.VMContext, params *OnChainSealVerifyInfo) ([]byte, ActorError) { - ctx := context.TODO() + ctx := vmctx.Context() oldstate, self, err := loadState(vmctx) if err != nil { return nil, err @@ -225,20 +231,6 @@ func (sma StorageMinerActor) CommitSector(act *types.Actor, vmctx types.VMContex return nil, aerrors.New(1, "not authorized to commit sector for miner") } - // TODO: this needs to get normalized to either the ID address or the actor address - maddr := vmctx.Message().To - - ticket, err := vmctx.GetRandomness(params.Epoch) - if err != nil { - return nil, aerrors.Wrap(err, "failed to get randomness for commitsector") - } - - if ok, err := ValidatePoRep(maddr, mi.SectorSize, params, ticket); err != nil { - return nil, err - } else if !ok { - return nil, aerrors.New(2, "bad proof!") - } - // make sure the miner isnt trying to submit a pre-existing sector unique, err := SectorIsUnique(ctx, vmctx.Storage(), self.Sectors, params.SectorNumber) if err != nil { @@ -257,10 +249,67 @@ func (sma StorageMinerActor) CommitSector(act *types.Actor, vmctx types.VMContex return nil, aerrors.New(4, "not enough collateral") } + self.UnprovenSectors[uintToStringKey(params.SectorNumber)] = &UnprovenSector{ + CommR: params.CommR, + CommD: params.CommD, + SubmitHeight: vmctx.BlockHeight(), + } + + 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 +} + +func uintToStringKey(i uint64) string { + buf := make([]byte, 10) + n := binary.PutUvarint(buf, i) + return string(buf[:n]) +} + +type SubmitSectorProofParams struct { + Proof []byte + SectorID uint64 + DealIDs []uint64 +} + +func (sma StorageMinerActor) SubmitSectorProof(act *types.Actor, vmctx types.VMContext, params *SubmitSectorProofParams) ([]byte, ActorError) { + ctx := vmctx.Context() + oldstate, self, err := loadState(vmctx) + if err != nil { + return nil, err + } + + mi, err := loadMinerInfo(vmctx, self) + if err != nil { + return nil, err + } + + us, ok := self.UnprovenSectors[uintToStringKey(params.SectorID)] + if !ok { + return nil, aerrors.New(1, "no pre-commitment found for sector") + } + delete(self.UnprovenSectors, uintToStringKey(params.SectorID)) + + // TODO: ensure normalization to ID address + maddr := vmctx.Message().To + + rand, err := vmctx.GetRandomness(us.SubmitHeight + build.InteractivePoRepDelay) + if ok, err := ValidatePoRep(maddr, mi.SectorSize, us.CommD, us.CommR, rand, params.Proof, params.SectorID); err != nil { + return nil, err + } else if !ok { + return nil, aerrors.New(2, "bad proof!") + } + // Note: There must exist a unique index in the miner's sector set for each // sector ID. The `faults`, `recovered`, and `done` parameters of the // SubmitPoSt method express indices into this sector set. - nssroot, err := AddToSectorSet(ctx, vmctx.Storage(), self.Sectors, params.SectorNumber, params.CommR, params.CommD) + nssroot, err := AddToSectorSet(ctx, vmctx.Storage(), self.Sectors, params.SectorID, us.CommR, us.CommD) if err != nil { return nil, err } @@ -525,8 +574,8 @@ func GetFromSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID return true, comms[0], comms[1], nil } -func ValidatePoRep(maddr address.Address, ssize uint64, params *OnChainSealVerifyInfo, ticket []byte) (bool, ActorError) { - ok, err := sectorbuilder.VerifySeal(ssize, params.CommR, params.CommD, maddr, ticket, params.SectorNumber, params.Proof) +func ValidatePoRep(maddr address.Address, ssize uint64, commD, commR, ticket, proof []byte, sectorID uint64) (bool, ActorError) { + ok, err := sectorbuilder.VerifySeal(ssize, commR, commD, maddr, ticket, sectorID, proof) if err != nil { return false, aerrors.Absorb(err, 25, "verify seal failed") } diff --git a/chain/actors/cbor_gen.go b/chain/actors/cbor_gen.go index 5444dafb0..3a87b61d5 100644 --- a/chain/actors/cbor_gen.go +++ b/chain/actors/cbor_gen.go @@ -197,7 +197,7 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{140}); err != nil { + if _, err := w.Write([]byte{141}); err != nil { return err } @@ -244,6 +244,26 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { return err } + // t.t.UnprovenSectors (map[string]*actors.UnprovenSector) + if err := cbg.CborWriteHeader(w, cbg.MajMap, uint64(len(t.UnprovenSectors))); err != nil { + return err + } + + for k, v := range t.UnprovenSectors { + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil { + return err + } + if _, err := w.Write([]byte(k)); err != nil { + return err + } + + if err := v.MarshalCBOR(w); err != nil { + return err + } + + } + // t.t.Power (types.BigInt) if err := t.Power.MarshalCBOR(w); err != nil { return err @@ -277,7 +297,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 12 { + if extra != 13 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -361,6 +381,59 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { return err } + } + // t.t.UnprovenSectors (map[string]*actors.UnprovenSector) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("expected a map (major type 5)") + } + if extra > 4096 { + return fmt.Errorf("t.UnprovenSectors: map too large") + } + + t.UnprovenSectors = make(map[string]*UnprovenSector, extra) + + for i, l := 0, int(extra); i < l; i++ { + + var k string + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + k = string(sval) + } + + var v *UnprovenSector + + { + + pb, err := br.PeekByte() + if err != nil { + return err + } + if pb == cbg.CborNull[0] { + var nbuf [1]byte + if _, err := br.Read(nbuf[:]); err != nil { + return err + } + } else { + v = new(UnprovenSector) + if err := v.UnmarshalCBOR(br); err != nil { + return err + } + } + + } + + t.UnprovenSectors[k] = v + } // t.t.Power (types.BigInt) @@ -497,7 +570,7 @@ func (t *OnChainSealVerifyInfo) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{134}); err != nil { + if _, err := w.Write([]byte{133}); err != nil { return err } @@ -530,16 +603,6 @@ func (t *OnChainSealVerifyInfo) MarshalCBOR(w io.Writer) error { return err } - // t.t.DealIDs ([]uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { - return err - } - for _, v := range t.DealIDs { - if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { - return err - } - } - // t.t.SectorNumber (uint64) if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.SectorNumber)); err != nil { return err @@ -558,7 +621,7 @@ func (t *OnChainSealVerifyInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 6 { + if extra != 5 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -623,36 +686,6 @@ func (t *OnChainSealVerifyInfo) UnmarshalCBOR(r io.Reader) error { if _, err := io.ReadFull(br, t.Proof); err != nil { return err } - // t.t.DealIDs ([]uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if extra > 8192 { - return fmt.Errorf("t.DealIDs: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.DealIDs = make([]uint64, extra) - } - for i := 0; i < int(extra); i++ { - - maj, val, err := cbg.CborReadHeader(br) - if err != nil { - return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) - } - - if maj != cbg.MajUnsignedInt { - return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) - } - - t.DealIDs[i] = val - } - // t.t.SectorNumber (uint64) maj, extra, err = cbg.CborReadHeader(br) @@ -666,6 +699,100 @@ func (t *OnChainSealVerifyInfo) UnmarshalCBOR(r io.Reader) error { return nil } +func (t *UnprovenSector) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{131}); err != nil { + return err + } + + // t.t.CommD ([]uint8) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommD)))); err != nil { + return err + } + if _, err := w.Write(t.CommD); err != nil { + return err + } + + // t.t.CommR ([]uint8) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommR)))); err != nil { + return err + } + if _, err := w.Write(t.CommR); err != nil { + return err + } + + // t.t.SubmitHeight (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.SubmitHeight)); err != nil { + return err + } + return nil +} + +func (t *UnprovenSector) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 3 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.CommD ([]uint8) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.CommD: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommD = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommD); err != nil { + return err + } + // t.t.CommR ([]uint8) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.CommR: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommR = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommR); err != nil { + return err + } + // t.t.SubmitHeight (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.SubmitHeight = extra + return nil +} + func (t *MinerInfo) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) diff --git a/gen/main.go b/gen/main.go index 127336a0b..fa8603a33 100644 --- a/gen/main.go +++ b/gen/main.go @@ -51,6 +51,7 @@ func main() { actors.StorageMinerActorState{}, actors.StorageMinerConstructorParams{}, actors.OnChainSealVerifyInfo{}, + actors.UnprovenSector{}, actors.MinerInfo{}, actors.SubmitPoStParams{}, actors.PaymentVerifyParams{}, diff --git a/storage/miner.go b/storage/miner.go index e563edaa4..6d2a6776a 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -170,18 +170,19 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal log.Error("seal we just created failed verification") } - deals, err := m.secst.DealsForCommit(sinfo.SectorID) + // TODO: 2 stage commit + /*deals, err := m.secst.DealsForCommit(sinfo.SectorID) if err != nil { return xerrors.Errorf("getting sector deals failed: %w", err) } - + */ params := &actors.OnChainSealVerifyInfo{ CommD: sinfo.CommD[:], CommR: sinfo.CommR[:], Proof: sinfo.Proof, Epoch: sinfo.Ticket.BlockHeight, - DealIDs: deals, + //DealIDs: deals, SectorNumber: sinfo.SectorID, } enc, aerr := actors.SerializeParams(params) From a4c0610cc3013a00a7301f21030e79a4490c56ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 30 Oct 2019 16:55:55 +0100 Subject: [PATCH 002/114] actors: Rename some storageminer stuff to match the spec --- chain/actors/actor_miner.go | 89 ++++++------ chain/actors/actor_storagepower.go | 1 + chain/actors/cbor_gen.go | 212 +++++++++++++---------------- gen/main.go | 2 +- storage/miner.go | 4 +- 5 files changed, 143 insertions(+), 165 deletions(-) diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index 9e5689d1b..28cc979a1 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -22,22 +22,27 @@ import ( type StorageMinerActor struct{} type StorageMinerActorState struct { - // Contains mostly static info about this miner - Info cid.Cid - - // Collateral that is waiting to be withdrawn. - DePledgedCollateral types.BigInt - - // Time at which the depledged collateral may be withdrawn. - DePledgeTime types.BigInt + // PreCommittedSectors is the set of sectors that have been committed to but not + // yet had their proofs submitted + PreCommittedSectors map[string]*UnprovenSector // All sectors this miner has committed. Sectors cid.Cid + // TODO: Spec says 'StagedCommittedSectors', which one is it? + // Sectors this miner is currently mining. It is only updated // when a PoSt is submitted (not as each new sector commitment is added). ProvingSet cid.Cid + // TODO: these: + // SectorTable + // SectorExpirationQueue + // ChallengeStatus + + // Contains mostly static info about this miner + Info cid.Cid + // Faulty sectors reported since last SubmitPost, // up to the current proving period's challenge time. CurrentFaultSet types.BitField @@ -53,10 +58,6 @@ type StorageMinerActorState struct { // removal penalization is needed. NextDoneSet types.BitField - // UnprovenSectors is the set of sectors that have been committed to but not - // yet had their proofs submitted - UnprovenSectors map[string]*UnprovenSector - // Amount of power this miner has. Power types.BigInt @@ -89,6 +90,8 @@ type MinerInfo struct { // Amount of space in each sector committed to the network by this miner. SectorSize uint64 + + // SubsectorCount } type UnprovenSector struct { @@ -106,7 +109,8 @@ type StorageMinerConstructorParams struct { type maMethods struct { Constructor uint64 - CommitSector uint64 + PreCommitSector uint64 + ProveCommitSector uint64 SubmitPoSt uint64 SlashStorageFault uint64 GetCurrentProvingSet uint64 @@ -121,32 +125,33 @@ type maMethods struct { ChangeWorker uint64 IsSlashed uint64 IsLate uint64 - AddFaults uint64 + DeclareFaults uint64 SlashConsensusFault uint64 } -var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18} +var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19} func (sma StorageMinerActor) Exports() []interface{} { return []interface{}{ 1: sma.StorageMinerConstructor, - 2: sma.CommitSector, - 3: sma.SubmitPoSt, - //4: sma.SlashStorageFault, - //5: sma.GetCurrentProvingSet, - //6: sma.ArbitrateDeal, - //7: sma.DePledge, - 8: sma.GetOwner, - 9: sma.GetWorkerAddr, - 10: sma.GetPower, - 11: sma.GetPeerID, - 12: sma.GetSectorSize, - 13: sma.UpdatePeerID, - //14: sma.ChangeWorker, - //15: sma.IsSlashed, - //16: sma.IsLate, - 17: sma.AddFaults, - 18: sma.SlashConsensusFault, + 2: sma.PreCommitSector, + 3: sma.ProveCommitSector, + 4: sma.SubmitPoSt, + //5: sma.SlashStorageFault, + //6: sma.GetCurrentProvingSet, + //7: sma.ArbitrateDeal, + //8: sma.DePledge, + 9: sma.GetOwner, + 10: sma.GetWorkerAddr, + 11: sma.GetPower, // TODO: Remove + 12: sma.GetPeerID, + 13: sma.GetSectorSize, + 14: sma.UpdatePeerID, + //15: sma.ChangeWorker, + //16: sma.IsSlashed, + //17: sma.IsLate, + 18: sma.DeclareFaults, + 19: sma.SlashConsensusFault, } } @@ -206,7 +211,7 @@ func (sma StorageMinerActor) StorageMinerConstructor(act *types.Actor, vmctx typ return nil, nil } -type OnChainSealVerifyInfo struct { +type SectorPreCommitInfo struct { CommD []byte // TODO: update proofs code CommR []byte @@ -215,7 +220,7 @@ type OnChainSealVerifyInfo struct { SectorNumber uint64 } -func (sma StorageMinerActor) CommitSector(act *types.Actor, vmctx types.VMContext, params *OnChainSealVerifyInfo) ([]byte, ActorError) { +func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMContext, params *SectorPreCommitInfo) ([]byte, ActorError) { ctx := vmctx.Context() oldstate, self, err := loadState(vmctx) if err != nil { @@ -249,7 +254,7 @@ func (sma StorageMinerActor) CommitSector(act *types.Actor, vmctx types.VMContex return nil, aerrors.New(4, "not enough collateral") } - self.UnprovenSectors[uintToStringKey(params.SectorNumber)] = &UnprovenSector{ + self.PreCommittedSectors[uintToStringKey(params.SectorNumber)] = &UnprovenSector{ CommR: params.CommR, CommD: params.CommD, SubmitHeight: vmctx.BlockHeight(), @@ -272,13 +277,13 @@ func uintToStringKey(i uint64) string { return string(buf[:n]) } -type SubmitSectorProofParams struct { +type SectorProveCommitInfo struct { Proof []byte SectorID uint64 DealIDs []uint64 } -func (sma StorageMinerActor) SubmitSectorProof(act *types.Actor, vmctx types.VMContext, params *SubmitSectorProofParams) ([]byte, ActorError) { +func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMContext, params *SectorProveCommitInfo) ([]byte, ActorError) { ctx := vmctx.Context() oldstate, self, err := loadState(vmctx) if err != nil { @@ -290,11 +295,11 @@ func (sma StorageMinerActor) SubmitSectorProof(act *types.Actor, vmctx types.VMC return nil, err } - us, ok := self.UnprovenSectors[uintToStringKey(params.SectorID)] + us, ok := self.PreCommittedSectors[uintToStringKey(params.SectorID)] if !ok { return nil, aerrors.New(1, "no pre-commitment found for sector") } - delete(self.UnprovenSectors, uintToStringKey(params.SectorID)) + delete(self.PreCommittedSectors, uintToStringKey(params.SectorID)) // TODO: ensure normalization to ID address maddr := vmctx.Message().To @@ -319,7 +324,7 @@ func (sma StorageMinerActor) SubmitSectorProof(act *types.Actor, vmctx types.VMC // Note: As written here, every miners first PoSt will only be over one sector. // We could set up a 'grace period' for starting mining that would allow miners // to submit several sectors for their first proving period. Alternatively, we - // could simply make the 'CommitSector' call take multiple sectors at a time. + // could simply make the 'PreCommitSector' call take multiple sectors at a time. // // Note: Proving period is a function of sector size; small sectors take less // time to prove than large sectors do. Sector size is selected when pledging. @@ -697,11 +702,11 @@ type PaymentVerifyParams struct { Proof []byte } -type AddFaultsParams struct { +type DeclareFaultsParams struct { Faults types.BitField } -func (sma StorageMinerActor) AddFaults(act *types.Actor, vmctx types.VMContext, params *AddFaultsParams) ([]byte, ActorError) { +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 diff --git a/chain/actors/actor_storagepower.go b/chain/actors/actor_storagepower.go index ea564bc62..e3f7cbfd3 100644 --- a/chain/actors/actor_storagepower.go +++ b/chain/actors/actor_storagepower.go @@ -329,6 +329,7 @@ func powerLookup(ctx context.Context, vmctx types.VMContext, self *StoragePowerS return types.EmptyInt, aerrors.New(1, "miner not registered with storage power actor") } + // TODO: Use local amt ret, err := vmctx.Send(miner, MAMethods.GetPower, types.NewInt(0), nil) if err != nil { return types.EmptyInt, aerrors.Wrap(err, "invoke Miner.GetPower") diff --git a/chain/actors/cbor_gen.go b/chain/actors/cbor_gen.go index 3a87b61d5..84de28117 100644 --- a/chain/actors/cbor_gen.go +++ b/chain/actors/cbor_gen.go @@ -197,24 +197,28 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{141}); err != nil { + if _, err := w.Write([]byte{139}); err != nil { return err } - // t.t.Info (cid.Cid) - - if err := cbg.WriteCid(w, t.Info); err != nil { - return xerrors.Errorf("failed to write cid field t.Info: %w", err) - } - - // t.t.DePledgedCollateral (types.BigInt) - if err := t.DePledgedCollateral.MarshalCBOR(w); err != nil { + // t.t.PreCommittedSectors (map[string]*actors.UnprovenSector) + if err := cbg.CborWriteHeader(w, cbg.MajMap, uint64(len(t.PreCommittedSectors))); err != nil { return err } - // t.t.DePledgeTime (types.BigInt) - if err := t.DePledgeTime.MarshalCBOR(w); err != nil { - return err + for k, v := range t.PreCommittedSectors { + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil { + return err + } + if _, err := w.Write([]byte(k)); err != nil { + return err + } + + if err := v.MarshalCBOR(w); err != nil { + return err + } + } // t.t.Sectors (cid.Cid) @@ -229,6 +233,12 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { return xerrors.Errorf("failed to write cid field t.ProvingSet: %w", err) } + // t.t.Info (cid.Cid) + + if err := cbg.WriteCid(w, t.Info); err != nil { + return xerrors.Errorf("failed to write cid field t.Info: %w", err) + } + // t.t.CurrentFaultSet (types.BitField) if err := t.CurrentFaultSet.MarshalCBOR(w); err != nil { return err @@ -244,26 +254,6 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { return err } - // t.t.UnprovenSectors (map[string]*actors.UnprovenSector) - if err := cbg.CborWriteHeader(w, cbg.MajMap, uint64(len(t.UnprovenSectors))); err != nil { - return err - } - - for k, v := range t.UnprovenSectors { - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil { - return err - } - if _, err := w.Write([]byte(k)); err != nil { - return err - } - - if err := v.MarshalCBOR(w); err != nil { - return err - } - - } - // t.t.Power (types.BigInt) if err := t.Power.MarshalCBOR(w); err != nil { return err @@ -297,92 +287,11 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 13 { + if extra != 11 { return fmt.Errorf("cbor input had wrong number of fields") } - // t.t.Info (cid.Cid) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.Info: %w", err) - } - - t.Info = c - - } - // t.t.DePledgedCollateral (types.BigInt) - - { - - if err := t.DePledgedCollateral.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.t.DePledgeTime (types.BigInt) - - { - - if err := t.DePledgeTime.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.t.Sectors (cid.Cid) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.Sectors: %w", err) - } - - t.Sectors = c - - } - // t.t.ProvingSet (cid.Cid) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.ProvingSet: %w", err) - } - - t.ProvingSet = c - - } - // t.t.CurrentFaultSet (types.BitField) - - { - - if err := t.CurrentFaultSet.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.t.NextFaultSet (types.BitField) - - { - - if err := t.NextFaultSet.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.t.NextDoneSet (types.BitField) - - { - - if err := t.NextDoneSet.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.t.UnprovenSectors (map[string]*actors.UnprovenSector) + // t.t.PreCommittedSectors (map[string]*actors.UnprovenSector) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -392,10 +301,10 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("expected a map (major type 5)") } if extra > 4096 { - return fmt.Errorf("t.UnprovenSectors: map too large") + return fmt.Errorf("t.PreCommittedSectors: map too large") } - t.UnprovenSectors = make(map[string]*UnprovenSector, extra) + t.PreCommittedSectors = make(map[string]*UnprovenSector, extra) for i, l := 0, int(extra); i < l; i++ { @@ -432,7 +341,70 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { } - t.UnprovenSectors[k] = v + t.PreCommittedSectors[k] = v + + } + // t.t.Sectors (cid.Cid) + + { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Sectors: %w", err) + } + + t.Sectors = c + + } + // t.t.ProvingSet (cid.Cid) + + { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.ProvingSet: %w", err) + } + + t.ProvingSet = c + + } + // t.t.Info (cid.Cid) + + { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Info: %w", err) + } + + t.Info = c + + } + // t.t.CurrentFaultSet (types.BitField) + + { + + if err := t.CurrentFaultSet.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.t.NextFaultSet (types.BitField) + + { + + if err := t.NextFaultSet.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.t.NextDoneSet (types.BitField) + + { + + if err := t.NextDoneSet.UnmarshalCBOR(br); err != nil { + return err + } } // t.t.Power (types.BigInt) @@ -565,7 +537,7 @@ func (t *StorageMinerConstructorParams) UnmarshalCBOR(r io.Reader) error { return nil } -func (t *OnChainSealVerifyInfo) MarshalCBOR(w io.Writer) error { +func (t *SectorPreCommitInfo) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) return err @@ -610,7 +582,7 @@ func (t *OnChainSealVerifyInfo) MarshalCBOR(w io.Writer) error { return nil } -func (t *OnChainSealVerifyInfo) UnmarshalCBOR(r io.Reader) error { +func (t *SectorPreCommitInfo) UnmarshalCBOR(r io.Reader) error { br := cbg.GetPeeker(r) maj, extra, err := cbg.CborReadHeader(br) diff --git a/gen/main.go b/gen/main.go index fa8603a33..102872f08 100644 --- a/gen/main.go +++ b/gen/main.go @@ -50,7 +50,7 @@ func main() { actors.AccountActorState{}, actors.StorageMinerActorState{}, actors.StorageMinerConstructorParams{}, - actors.OnChainSealVerifyInfo{}, + actors.SectorPreCommitInfo{}, actors.UnprovenSector{}, actors.MinerInfo{}, actors.SubmitPoStParams{}, diff --git a/storage/miner.go b/storage/miner.go index 6d2a6776a..540d662c7 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -176,7 +176,7 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal return xerrors.Errorf("getting sector deals failed: %w", err) } */ - params := &actors.OnChainSealVerifyInfo{ + params := &actors.SectorPreCommitInfo{ CommD: sinfo.CommD[:], CommR: sinfo.CommR[:], Proof: sinfo.Proof, @@ -193,7 +193,7 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal msg := &types.Message{ To: m.maddr, From: m.worker, - Method: actors.MAMethods.CommitSector, + Method: actors.MAMethods.PreCommitSector, Params: enc, Value: types.NewInt(0), // TODO: need to ensure sufficient collateral GasLimit: types.NewInt(1000000 /* i dont know help */), From 46d782b30be650f4600c99c1e62a83f0006b4c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 30 Oct 2019 18:37:38 +0100 Subject: [PATCH 003/114] storageminer: Drop commitment tracker --- api/api.go | 10 -- api/struct.go | 6 - chain/deals/provider.go | 5 +- chain/deals/provider_states.go | 10 +- cmd/lotus-storage-miner/commitments.go | 41 ----- cmd/lotus-storage-miner/main.go | 1 - node/builder.go | 2 - node/impl/storminer.go | 6 - node/modules/storageminer.go | 5 +- storage/commitment/tracker.go | 198 ------------------------- storage/miner.go | 9 +- 11 files changed, 10 insertions(+), 283 deletions(-) delete mode 100644 cmd/lotus-storage-miner/commitments.go delete mode 100644 storage/commitment/tracker.go diff --git a/api/api.go b/api/api.go index 463e5e9cb..635901ecb 100644 --- a/api/api.go +++ b/api/api.go @@ -168,8 +168,6 @@ type StorageMiner interface { SectorsList(context.Context) ([]uint64, error) SectorsRefs(context.Context) (map[string][]SealedRef, error) - - CommitmentsList(context.Context) ([]SectorCommitment, error) } // Version provides various build-time information @@ -332,14 +330,6 @@ type SyncState struct { Height uint64 } -type SectorCommitment struct { - SectorID uint64 - Miner address.Address - - CommitMsg cid.Cid - DealIDs []uint64 -} - type SyncStateStage int const ( diff --git a/api/struct.go b/api/struct.go index 47d88aa69..6eefe41dc 100644 --- a/api/struct.go +++ b/api/struct.go @@ -133,8 +133,6 @@ type StorageMinerStruct struct { SectorsList func(context.Context) ([]uint64, error) `perm:"read"` SectorsRefs func(context.Context) (map[string][]SealedRef, error) `perm:"read"` - - CommitmentsList func(context.Context) ([]SectorCommitment, error) `perm:"read"` } } @@ -481,10 +479,6 @@ func (c *StorageMinerStruct) SectorsRefs(ctx context.Context) (map[string][]Seal return c.Internal.SectorsRefs(ctx) } -func (c *StorageMinerStruct) CommitmentsList(ctx context.Context) ([]SectorCommitment, error) { - return c.Internal.CommitmentsList(ctx) -} - var _ Common = &CommonStruct{} var _ FullNode = &FullNodeStruct{} var _ StorageMiner = &StorageMinerStruct{} diff --git a/chain/deals/provider.go b/chain/deals/provider.go index 86383c61b..356f7d2e7 100644 --- a/chain/deals/provider.go +++ b/chain/deals/provider.go @@ -17,7 +17,6 @@ import ( "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/cborrpc" "github.com/filecoin-project/lotus/node/modules/dtypes" - "github.com/filecoin-project/lotus/storage/commitment" "github.com/filecoin-project/lotus/storage/sectorblocks" ) @@ -43,7 +42,6 @@ type Provider struct { askLk sync.Mutex secst *sectorblocks.SectorBlocks - commt *commitment.Tracker full api.FullNode // TODO: Use a custom protocol or graphsync in the future @@ -70,7 +68,7 @@ type minerDealUpdate struct { mut func(*MinerDeal) } -func NewProvider(ds dtypes.MetadataDS, secst *sectorblocks.SectorBlocks, commt *commitment.Tracker, dag dtypes.StagingDAG, fullNode api.FullNode) (*Provider, error) { +func NewProvider(ds dtypes.MetadataDS, secst *sectorblocks.SectorBlocks, dag dtypes.StagingDAG, fullNode api.FullNode) (*Provider, error) { addr, err := ds.Get(datastore.NewKey("miner-address")) if err != nil { return nil, err @@ -82,7 +80,6 @@ func NewProvider(ds dtypes.MetadataDS, secst *sectorblocks.SectorBlocks, commt * h := &Provider{ secst: secst, - commt: commt, dag: dag, full: fullNode, diff --git a/chain/deals/provider_states.go b/chain/deals/provider_states.go index 595f236da..6c86eb8e9 100644 --- a/chain/deals/provider_states.go +++ b/chain/deals/provider_states.go @@ -290,12 +290,14 @@ func (p *Provider) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal func (p *Provider) complete(ctx context.Context, deal MinerDeal) (func(*MinerDeal), error) { // TODO: Add dealID to commtracker (probably before sealing) - mcid, err := p.commt.WaitCommit(ctx, deal.Proposal.Provider, deal.SectorID) + /*mcid, err := p.commt.WaitCommit(ctx, deal.Proposal.Provider, deal.SectorID) if err != nil { log.Warnf("Waiting for sector commitment message: %s", err) - } + }*/ - err = p.sendSignedResponse(&Response{ + panic("fixme") + + /*err = p.sendSignedResponse(&Response{ State: api.DealComplete, Proposal: deal.ProposalCid, @@ -303,7 +305,7 @@ func (p *Provider) complete(ctx context.Context, deal MinerDeal) (func(*MinerDea }) if err != nil { log.Warnf("Sending deal response failed: %s", err) - } + }*/ return nil, nil } diff --git a/cmd/lotus-storage-miner/commitments.go b/cmd/lotus-storage-miner/commitments.go deleted file mode 100644 index a7825deb1..000000000 --- a/cmd/lotus-storage-miner/commitments.go +++ /dev/null @@ -1,41 +0,0 @@ -package main - -import ( - "fmt" - lcli "github.com/filecoin-project/lotus/cli" - - "gopkg.in/urfave/cli.v2" -) - -var commitmentsCmd = &cli.Command{ - Name: "commitments", - Usage: "interact with commitment tracker", - Subcommands: []*cli.Command{ - commitmentsListCmd, - }, -} - -var commitmentsListCmd = &cli.Command{ - Name: "list", - Usage: "List tracked sector commitments", - Action: func(cctx *cli.Context) error { - api, closer, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return err - } - defer closer() - - ctx := lcli.ReqContext(cctx) - - comms, err := api.CommitmentsList(ctx) - if err != nil { - return err - } - - for _, comm := range comms { - fmt.Printf("%s:%d msg:%s, deals: %v\n", comm.Miner, comm.SectorID, comm.CommitMsg, comm.DealIDs) - } - - return nil - }, -} diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index b6aad1d73..f8bf2aac1 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -26,7 +26,6 @@ func main() { infoCmd, storeGarbageCmd, sectorsCmd, - commitmentsCmd, } jaeger := tracing.SetupJaegerTracing("lotus") defer func() { diff --git a/node/builder.go b/node/builder.go index c316139ee..26b6bbd7f 100644 --- a/node/builder.go +++ b/node/builder.go @@ -40,7 +40,6 @@ import ( "github.com/filecoin-project/lotus/retrieval" "github.com/filecoin-project/lotus/retrieval/discovery" "github.com/filecoin-project/lotus/storage" - "github.com/filecoin-project/lotus/storage/commitment" "github.com/filecoin-project/lotus/storage/sector" "github.com/filecoin-project/lotus/storage/sectorblocks" ) @@ -234,7 +233,6 @@ func Online() Option { Override(new(*sectorbuilder.SectorBuilder), sectorbuilder.New), Override(new(*sector.Store), sector.NewStore), Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks), - Override(new(*commitment.Tracker), commitment.NewTracker), Override(new(sector.TicketFn), modules.SealTicketGen), Override(new(*storage.Miner), modules.StorageMiner), diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 8eb363fe2..c763dab5e 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -10,7 +10,6 @@ import ( "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/storage" - "github.com/filecoin-project/lotus/storage/commitment" "github.com/filecoin-project/lotus/storage/sector" "github.com/filecoin-project/lotus/storage/sectorblocks" @@ -24,7 +23,6 @@ type StorageMinerAPI struct { SectorBuilder *sectorbuilder.SectorBuilder Sectors *sector.Store SectorBlocks *sectorblocks.SectorBlocks - CommitmentTracker *commitment.Tracker Miner *storage.Miner } @@ -83,8 +81,4 @@ func (sm *StorageMinerAPI) SectorsRefs(context.Context) (map[string][]api.Sealed return out, nil } -func (sm *StorageMinerAPI) CommitmentsList(ctx context.Context) ([]api.SectorCommitment, error) { - return sm.CommitmentTracker.List() -} - var _ api.StorageMiner = &StorageMinerAPI{} diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 4f9df1c42..81b34522a 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -26,7 +26,6 @@ import ( "github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/retrieval" "github.com/filecoin-project/lotus/storage" - "github.com/filecoin-project/lotus/storage/commitment" "github.com/filecoin-project/lotus/storage/sector" ) @@ -72,13 +71,13 @@ func SectorBuilderConfig(storagePath string) func(dtypes.MetadataDS, api.FullNod } } -func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api api.FullNode, h host.Host, ds dtypes.MetadataDS, secst *sector.Store, commt *commitment.Tracker) (*storage.Miner, error) { +func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api api.FullNode, h host.Host, ds dtypes.MetadataDS, secst *sector.Store) (*storage.Miner, error) { maddr, err := minerAddrFromDS(ds) if err != nil { return nil, err } - sm, err := storage.NewMiner(api, maddr, h, ds, secst, commt) + sm, err := storage.NewMiner(api, maddr, h, ds, secst) if err != nil { return nil, err } diff --git a/storage/commitment/tracker.go b/storage/commitment/tracker.go deleted file mode 100644 index 90e2459bf..000000000 --- a/storage/commitment/tracker.go +++ /dev/null @@ -1,198 +0,0 @@ -package commitment - -import ( - "context" - "fmt" - "strconv" - "strings" - "sync" - - "github.com/ipfs/go-cid" - "github.com/ipfs/go-datastore" - "github.com/ipfs/go-datastore/namespace" - cbor "github.com/ipfs/go-ipld-cbor" - logging "github.com/ipfs/go-log" - "golang.org/x/xerrors" - - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/address" - "github.com/filecoin-project/lotus/node/modules/dtypes" - dsq "github.com/ipfs/go-datastore/query" -) - -var log = logging.Logger("commitment") - -func init() { - cbor.RegisterCborType(commitment{}) -} - -var commitmentDsPrefix = datastore.NewKey("/commitments") - -type Tracker struct { - commitments datastore.Datastore - - lk sync.Mutex - - waits map[datastore.Key]chan struct{} -} - -func NewTracker(ds dtypes.MetadataDS) *Tracker { - return &Tracker{ - commitments: namespace.Wrap(ds, commitmentDsPrefix), - waits: map[datastore.Key]chan struct{}{}, - } -} - -type commitment struct { - DealIDs []uint64 - Msg cid.Cid -} - -func commitmentKey(miner address.Address, sectorId uint64) datastore.Key { - return commitmentDsPrefix.ChildString(miner.String()).ChildString(fmt.Sprintf("%d", sectorId)) -} - -func (ct *Tracker) TrackCommitSectorMsg(miner address.Address, sectorId uint64, commitMsg cid.Cid) error { - key := commitmentKey(miner, sectorId) - - ct.lk.Lock() - defer ct.lk.Unlock() - - tracking, err := ct.commitments.Get(key) - switch err { - case nil: - var comm commitment - if err := cbor.DecodeInto(tracking, &comm); err != nil { - return err - } - - if !comm.Msg.Equals(commitMsg) { - log.Errorf("commitment tracking for miner %s, sector %d: already tracking %s, got another commitment message: %s", miner, sectorId, comm.Msg, commitMsg) - } - - log.Warnf("commitment.TrackCommitSectorMsg called more than once for miner %s, sector %d, message %s", miner, sectorId, commitMsg) - - // we still want to store it - fallthrough // TODO: ideally we'd keep around both (even though we'll - // usually only need the new one) - case datastore.ErrNotFound: - comm := &commitment{Msg: commitMsg} - commB, err := cbor.DumpObject(comm) - if err != nil { - return err - } - - if err := ct.commitments.Put(key, commB); err != nil { - return err - } - - waits, ok := ct.waits[key] - if ok { - close(waits) - delete(ct.waits, key) - } - return nil - default: - return err - } -} - -func (ct *Tracker) WaitCommit(ctx context.Context, miner address.Address, sectorId uint64) (cid.Cid, error) { - key := commitmentKey(miner, sectorId) - - ct.lk.Lock() - - tracking, err := ct.commitments.Get(key) - if err != datastore.ErrNotFound { - ct.lk.Unlock() - - if err != nil { - return cid.Undef, err - } - - var comm commitment - if err := cbor.DecodeInto(tracking, &comm); err != nil { - return cid.Undef, err - } - - return comm.Msg, nil - } - - wait, ok := ct.waits[key] - if !ok { - wait = make(chan struct{}) - ct.waits[key] = wait - } - - ct.lk.Unlock() - - select { - case <-wait: - tracking, err := ct.commitments.Get(key) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to get commitment after waiting: %w", err) - } - - var comm commitment - if err := cbor.DecodeInto(tracking, &comm); err != nil { - return cid.Undef, err - } - - return comm.Msg, nil - case <-ctx.Done(): - return cid.Undef, ctx.Err() - } -} - -func (ct *Tracker) List() ([]api.SectorCommitment, error) { - out := make([]api.SectorCommitment, 0) - - ct.lk.Lock() - defer ct.lk.Unlock() - - res, err := ct.commitments.Query(dsq.Query{}) - if err != nil { - return nil, err - } - defer res.Close() - - for { - res, ok := res.NextSync() - if !ok { - break - } - - if res.Error != nil { - return nil, xerrors.Errorf("iterating commitments: %w", err) - } - - parts := strings.Split(res.Key, "/") - if len(parts) != 4 { - return nil, xerrors.Errorf("expected commitment key to be 4 parts, Key %s", res.Key) - } - - miner, err := address.NewFromString(parts[2]) - if err != nil { - return nil, xerrors.Errorf("parsing miner address: %w", err) - } - - sectorID, err := strconv.ParseInt(parts[3], 10, 64) - if err != nil { - return nil, xerrors.Errorf("parsing sector id: %w", err) - } - - var comm commitment - if err := cbor.DecodeInto(res.Value, &comm); err != nil { - return nil, xerrors.Errorf("decoding commitment %s (`% X`): %w", res.Key, res.Value, err) - } - - out = append(out, api.SectorCommitment{ - SectorID: uint64(sectorID), - Miner: miner, - CommitMsg: comm.Msg, - DealIDs: comm.DealIDs, - }) - } - - return out, nil -} diff --git a/storage/miner.go b/storage/miner.go index 540d662c7..089a46a3e 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -18,7 +18,6 @@ import ( "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/sectorbuilder" - "github.com/filecoin-project/lotus/storage/commitment" "github.com/filecoin-project/lotus/storage/sector" ) @@ -31,7 +30,6 @@ type Miner struct { events *events.Events secst *sector.Store - commt *commitment.Tracker maddr address.Address @@ -70,7 +68,7 @@ type storageMinerApi interface { WalletHas(context.Context, address.Address) (bool, error) } -func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datastore.Batching, secst *sector.Store, commt *commitment.Tracker) (*Miner, error) { +func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datastore.Batching, secst *sector.Store) (*Miner, error) { return &Miner{ api: api, @@ -78,7 +76,6 @@ func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datasto h: h, ds: ds, secst: secst, - commt: commt, }, nil } @@ -214,10 +211,6 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal m.beginPosting(ctx) }() - if err := m.commt.TrackCommitSectorMsg(m.maddr, sinfo.SectorID, smsg.Cid()); err != nil { - return xerrors.Errorf("tracking sector commitment: %w", err) - } - return nil } From dd9d6c4ef02f50d04b71981d9fb60f1d2d555d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 30 Oct 2019 18:40:48 +0100 Subject: [PATCH 004/114] Update sectorbuilder, v15 params --- build/proof-params/parameters.json | 64 +++++++++++++++--------------- extern/go-sectorbuilder | 2 +- go.mod | 1 - go.sum | 7 +++- 4 files changed, 39 insertions(+), 35 deletions(-) diff --git a/build/proof-params/parameters.json b/build/proof-params/parameters.json index 0460fb226..e12686127 100644 --- a/build/proof-params/parameters.json +++ b/build/proof-params/parameters.json @@ -1,82 +1,82 @@ { - "v14-proof-of-spacetime-rational-535d1050e3adca2a0dfe6c3c0c4fa12097c9a7835fb969042f82a507b13310e0.params": { + "v15-proof-of-spacetime-rational-535d1050e3adca2a0dfe6c3c0c4fa12097c9a7835fb969042f82a507b13310e0.params": { "cid": "QmT22f1Np1GpW29NXD7Zrv3Ae4poMYhmkDjyscqL8QrJXY", "digest": "989fd8d989e0f7f1fe21bb010cf1b231", "sector_size": 16777216 }, - "v14-proof-of-spacetime-rational-535d1050e3adca2a0dfe6c3c0c4fa12097c9a7835fb969042f82a507b13310e0.vk": { + "v15-proof-of-spacetime-rational-535d1050e3adca2a0dfe6c3c0c4fa12097c9a7835fb969042f82a507b13310e0.vk": { "cid": "QmVqSdc23to4UwduCCb25223rpSccvtcgPMfRKY1qjucDc", "digest": "c6d258c37243b8544238a98100e3e399", "sector_size": 16777216 }, - "v14-proof-of-spacetime-rational-b99f15d0bdaaf4ffb68b2ca72b69ea8d915f66a2a56f667430ad69d87aa5febd.params": { + "v15-proof-of-spacetime-rational-b99f15d0bdaaf4ffb68b2ca72b69ea8d915f66a2a56f667430ad69d87aa5febd.params": { "cid": "QmRTCqgokEGTMfWVaSr7qFXTNotmpd2QBEi8RsvSQKmPLz", "digest": "ff77a5e270afc6e1c7fbc19e48348fac", "sector_size": 1073741824 }, - "v14-proof-of-spacetime-rational-b99f15d0bdaaf4ffb68b2ca72b69ea8d915f66a2a56f667430ad69d87aa5febd.vk": { + "v15-proof-of-spacetime-rational-b99f15d0bdaaf4ffb68b2ca72b69ea8d915f66a2a56f667430ad69d87aa5febd.vk": { "cid": "QmRssVAXRN3xp9VdSpTq1pNjkob3QiikoFZiM5hqrmh1VU", "digest": "b41f35ac26224258e366327716a835a4", "sector_size": 1073741824 }, - "v14-proof-of-spacetime-rational-ba14a058a9dea194f68596f8ecf6537074f038a15c8d1a8550e10e31d4728912.params": { + "v15-proof-of-spacetime-rational-ba14a058a9dea194f68596f8ecf6537074f038a15c8d1a8550e10e31d4728912.params": { "cid": "QmYNVRVzjXkuxJfnHTU5vmEcUBQf8dabXZ4m53SzqMkBv5", "digest": "d156b685e4a1fe3a1f7230b6a39b5ad4", "sector_size": 1024 }, - "v14-proof-of-spacetime-rational-ba14a058a9dea194f68596f8ecf6537074f038a15c8d1a8550e10e31d4728912.vk": { + "v15-proof-of-spacetime-rational-ba14a058a9dea194f68596f8ecf6537074f038a15c8d1a8550e10e31d4728912.vk": { "cid": "QmaCEcsCFVuepMKdC5WURbr5ucEyLMNGxQaB7HqSnr2KGh", "digest": "06ff067ac78cdab5d7bbc82170882241", "sector_size": 1024 }, - "v14-proof-of-spacetime-rational-c2ae2b440e693ee69fd6da9e85c4294c5c70c1a46d5785ca5f2a676d6cd4c8de.params": { + "v15-proof-of-spacetime-rational-c2ae2b440e693ee69fd6da9e85c4294c5c70c1a46d5785ca5f2a676d6cd4c8de.params": { "cid": "QmVuabRvJ797NwLisGKwRURASGxopBBgg4rfNsbZoSYzAc", "digest": "0e1ceb79a459a60508f480e5b1fed7ac", "sector_size": 268435456 }, - "v14-proof-of-spacetime-rational-c2ae2b440e693ee69fd6da9e85c4294c5c70c1a46d5785ca5f2a676d6cd4c8de.vk": { + "v15-proof-of-spacetime-rational-c2ae2b440e693ee69fd6da9e85c4294c5c70c1a46d5785ca5f2a676d6cd4c8de.vk": { "cid": "QmdWENZBAbuUty1vVNn9vmvj1XbJ5UC8qzpcVD35s5AJxG", "digest": "1b755c74b9d6823c014f6a7ef76249f2", "sector_size": 268435456 }, - "v14-stacked-proof-of-replication-0c0b444c6f31d11c8e98003cc99a3b938db26b77a296d4253cda8945c234266d.params": { - "cid": "QmPG38HmDNVFiQJskqKe9sfSjyHfvZRihcfry78rt22FDT", - "digest": "8ea0b47e72250d5d6dab5d4f859e65de", + "v15-stacked-proof-of-replication-0c0b444c6f31d11c8e98003cc99a3b938db26b77a296d4253cda8945c234266d.params": { + "cid": "QmZDVpWTw5Eti5pE7N5z1Cmqsw8hPXhUcvG3cQuceK56LH", + "digest": "6aa80306018ea1328f2d6faf8c080734", "sector_size": 16777216 }, - "v14-stacked-proof-of-replication-0c0b444c6f31d11c8e98003cc99a3b938db26b77a296d4253cda8945c234266d.vk": { - "cid": "Qmd3pNM22pgAoRT24tNyEZmeEWK2GtoZznBvzjie2YgqCn", - "digest": "e39f344757c919ae6bbc9b61311c73b2", + "v15-stacked-proof-of-replication-0c0b444c6f31d11c8e98003cc99a3b938db26b77a296d4253cda8945c234266d.vk": { + "cid": "QmaoXV7iVSJcfZ5qubYy7NBcXDSdnTzxH85d7M4bdDtfGZ", + "digest": "f6832eb736faf2960e920d32e9780b12", "sector_size": 16777216 }, - "v14-stacked-proof-of-replication-967b11bb59be11b7dc6f2b627520ba450a3aa50846dbbf886cb8b735fe25c4e7.params": { - "cid": "QmQsS6RqWmgdwPnHCwhBJH3WDPcAxhKfbQUs2bwa8D9su8", - "digest": "09879a69abcc51de5c1095f347c84e2b", + "v15-stacked-proof-of-replication-967b11bb59be11b7dc6f2b627520ba450a3aa50846dbbf886cb8b735fe25c4e7.params": { + "cid": "QmbUW3a3q5DHBb7Ufk8iSbnSCZgbwpe3serqfwKmcTd11w", + "digest": "64024e461b07c869df2463d33dd28035", "sector_size": 268435456 }, - "v14-stacked-proof-of-replication-967b11bb59be11b7dc6f2b627520ba450a3aa50846dbbf886cb8b735fe25c4e7.vk": { - "cid": "QmSFBL5rg2TJv8QjLzrbr4c2KV2uDNN13RBVNUgwemJgM1", - "digest": "db0f245f7e9989879d2fa6328bd57d32", + "v15-stacked-proof-of-replication-967b11bb59be11b7dc6f2b627520ba450a3aa50846dbbf886cb8b735fe25c4e7.vk": { + "cid": "Qme3QgBBE7hUgrK7G9ZfJhzkbvViN5HALFpFduYs5K1piv", + "digest": "32496f4dc434b0ed9ef49cb62497a7d1", "sector_size": 268435456 }, - "v14-stacked-proof-of-replication-d01cd22091627b721c60a3375b5219af653fb9f6928c70aa7400587d396bc07a.params": { - "cid": "QmZ9UVBfviaNFsKyazA4k8GZcM1tHNDpDyrEK9qkxaMJXx", - "digest": "402a7c7c82eaa4af9fba3c7e4402b65b", + "v15-stacked-proof-of-replication-d01cd22091627b721c60a3375b5219af653fb9f6928c70aa7400587d396bc07a.params": { + "cid": "QmZzgJmb8WXYDKxS22HDgnoBYcZzXDC7s2c2zsV7kouNZ9", + "digest": "cd91f7ccb2ff57a06f3375946dcbdc68", "sector_size": 1073741824 }, - "v14-stacked-proof-of-replication-d01cd22091627b721c60a3375b5219af653fb9f6928c70aa7400587d396bc07a.vk": { - "cid": "QmNmDcPVJ1bFFDcNCcRnEoQ6vNDNpKadLPHyEpUoF47gxV", - "digest": "2741c456346a3758e88249d1f4c0d227", + "v15-stacked-proof-of-replication-d01cd22091627b721c60a3375b5219af653fb9f6928c70aa7400587d396bc07a.vk": { + "cid": "QmRUMVzFnENbvyNb6aN2AJ2dnnewr1ESGA1UQLMVZZdsJM", + "digest": "92fc84b76dbe69c731518aebcb82ac82", "sector_size": 1073741824 }, - "v14-stacked-proof-of-replication-f464b92d805d03de6e2c20e2530135b2c8ec96045ec58f342d6feb90282bff8a.params": { - "cid": "QmNqgCv6UjdKDNMuiwDweZ22TQYMd3gV6nWiA5PjMtNDVu", - "digest": "a9d316d0dbca152e653d41ad8e40058a", + "v15-stacked-proof-of-replication-f464b92d805d03de6e2c20e2530135b2c8ec96045ec58f342d6feb90282bff8a.params": { + "cid": "QmSixsGkxJXTAuFfWKy5aEXEDJEnpcb1GkdQVF8TCPWoHy", + "digest": "f8339ae93478ded3840d0bc7efa19953", "sector_size": 1024 }, - "v14-stacked-proof-of-replication-f464b92d805d03de6e2c20e2530135b2c8ec96045ec58f342d6feb90282bff8a.vk": { - "cid": "QmTGQGThNFEjaMFgP32YLubACrtpkRoeVEfhDaWi5g6w8u", - "digest": "021b3e81e2980a50fd1ac07424d29a8d", + "v15-stacked-proof-of-replication-f464b92d805d03de6e2c20e2530135b2c8ec96045ec58f342d6feb90282bff8a.vk": { + "cid": "QmTMC8hdZ2TkZ9BFuzHzRLM9SuR2PQdUrSAwABeCuHyV2f", + "digest": "f27f08ce1246ee6612c250bb12803ef1", "sector_size": 1024 } } \ No newline at end of file diff --git a/extern/go-sectorbuilder b/extern/go-sectorbuilder index 692725ff2..e8231db9d 160000 --- a/extern/go-sectorbuilder +++ b/extern/go-sectorbuilder @@ -1 +1 @@ -Subproject commit 692725ff21919ce9c9df9ea87621b0c1e6a9746c +Subproject commit e8231db9dc64e79f7049e25c538b77b88eef54dc diff --git a/go.mod b/go.mod index b8eec445f..67f47edc4 100644 --- a/go.mod +++ b/go.mod @@ -84,7 +84,6 @@ require ( go.uber.org/zap v1.10.0 go4.org v0.0.0-20190313082347-94abd6928b1d // indirect golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 // indirect - golang.org/x/sys v0.0.0-20190904154756-749cb33beabd // indirect golang.org/x/time v0.0.0-20181108054448-85acf8d2951c golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 google.golang.org/api v0.9.0 // indirect diff --git a/go.sum b/go.sum index 3d9bc15a9..796ce0e24 100644 --- a/go.sum +++ b/go.sum @@ -445,6 +445,7 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -613,9 +614,9 @@ 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= -github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= +github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= @@ -714,6 +715,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -749,6 +751,7 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -801,6 +804,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -817,6 +821,7 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 7fa3e2db7a0dde153a099e6d9b0a32da24413de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 30 Oct 2019 19:10:29 +0100 Subject: [PATCH 005/114] WIP Interactive PoRep --- chain/actors/actor_miner.go | 9 ++++--- go.sum | 2 ++ lib/sectorbuilder/sectorbuilder.go | 33 ++++++++++++------------- lib/sectorbuilder/sectorbuilder_test.go | 2 ++ node/modules/storageminer.go | 2 ++ storage/miner.go | 4 ++- storage/sector/store.go | 14 +++++------ 7 files changed, 38 insertions(+), 28 deletions(-) diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index 28cc979a1..165c5ecd1 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -304,8 +304,11 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC // TODO: ensure normalization to ID address maddr := vmctx.Message().To + var pieces []sectorbuilder.PublicPieceInfo // TODO: GET ME FROM DEALS IN STORAGEMARKET + var seed []byte // TODO: GET ME FROM SOMEWHERE + rand, err := vmctx.GetRandomness(us.SubmitHeight + build.InteractivePoRepDelay) - if ok, err := ValidatePoRep(maddr, mi.SectorSize, us.CommD, us.CommR, rand, params.Proof, params.SectorID); err != nil { + if ok, err := ValidatePoRep(maddr, mi.SectorSize, us.CommD, us.CommR, rand, seed, params.Proof, params.SectorID, pieces); err != nil { return nil, err } else if !ok { return nil, aerrors.New(2, "bad proof!") @@ -579,8 +582,8 @@ func GetFromSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID return true, comms[0], comms[1], nil } -func ValidatePoRep(maddr address.Address, ssize uint64, commD, commR, ticket, proof []byte, sectorID uint64) (bool, ActorError) { - ok, err := sectorbuilder.VerifySeal(ssize, commR, commD, maddr, ticket, sectorID, proof) +func ValidatePoRep(maddr address.Address, ssize uint64, commD, commR, ticket, proof, seed []byte, sectorID uint64, pieces []sectorbuilder.PublicPieceInfo) (bool, ActorError) { + ok, err := sectorbuilder.VerifySeal(ssize, commR, commD, maddr, ticket, seed, sectorID, proof, pieces) if err != nil { return false, aerrors.Absorb(err, 25, "verify seal failed") } diff --git a/go.sum b/go.sum index 796ce0e24..e33480571 100644 --- a/go.sum +++ b/go.sum @@ -715,6 +715,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -751,6 +752,7 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index a2e4499b7..033372876 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -26,7 +26,11 @@ type SectorInfo = sectorbuilder.SectorInfo type SealTicket = sectorbuilder.SealTicket -type SealedSectorMetadata = sectorbuilder.SealedSectorMetadata +type SealSeed = sectorbuilder.SealSeed + +type SealCommitOutput = sectorbuilder.SealCommitOutput + +type PublicPieceInfo = sectorbuilder.PublicPieceInfo const CommLen = sectorbuilder.CommitmentBytesLen @@ -37,6 +41,7 @@ type SectorBuilder struct { type SectorBuilderConfig struct { SectorSize uint64 Miner address.Address + CacheDir string SealedDir string StagedDir string MetadataDir string @@ -44,8 +49,9 @@ type SectorBuilderConfig struct { func New(cfg *SectorBuilderConfig) (*SectorBuilder, error) { proverId := addressToProverID(cfg.Miner) + nemWorkerThreads := uint8(5) // TODO: from config - sbp, err := sectorbuilder.InitSectorBuilder(cfg.SectorSize, 2, 1, 0, cfg.MetadataDir, proverId, cfg.SealedDir, cfg.StagedDir, 16) + sbp, err := sectorbuilder.InitSectorBuilder(cfg.SectorSize, 2, 0, cfg.MetadataDir, proverId, cfg.SealedDir, cfg.StagedDir, cfg.CacheDir, 16, nemWorkerThreads) if err != nil { return nil, err } @@ -84,12 +90,12 @@ func (sb *SectorBuilder) ReadPieceFromSealedSector(pieceKey string) ([]byte, err return sectorbuilder.ReadPieceFromSealedSector(sb.handle, pieceKey) } -func (sb *SectorBuilder) SealSector(sectorID uint64, ticket SealTicket) (SealedSectorMetadata, error) { - return sectorbuilder.SealSector(sb.handle, sectorID, ticket) +func (sb *SectorBuilder) SealSector(sectorID uint64, seed SealSeed) (SealCommitOutput, error) { + return sectorbuilder.SealCommit(sb.handle, sectorID, seed) } -func (sb *SectorBuilder) ResumeSealSector(sectorID uint64) (SealedSectorMetadata, error) { - return sectorbuilder.ResumeSealSector(sb.handle, sectorID) +func (sb *SectorBuilder) ResumeSealCommit(sectorID uint64) (SealCommitOutput, error) { + return sectorbuilder.ResumeSealCommit(sb.handle, sectorID) } func (sb *SectorBuilder) SealStatus(sector uint64) (SectorSealingStatus, error) { @@ -122,22 +128,15 @@ func (sb *SectorBuilder) GeneratePoSt(sectorInfo SortedSectorInfo, challengeSeed var UserBytesForSectorSize = sectorbuilder.GetMaxUserBytesPerStagedSector -func VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address, ticket []byte, sectorID uint64, proof []byte) (bool, error) { - var commRa, commDa, ticketa [32]byte +func VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address, ticket []byte, seed []byte, sectorID uint64, proof []byte, pieces []PublicPieceInfo) (bool, error) { + var commRa, commDa, ticketa, seeda [32]byte copy(commRa[:], commR) copy(commDa[:], commD) copy(ticketa[:], ticket) + copy(seeda[:], seed) proverIDa := addressToProverID(proverID) - return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, sectorID, proof) -} - -func VerifyPieceInclusionProof(sectorSize uint64, pieceSize uint64, commP []byte, commD []byte, proof []byte) (bool, error) { - var commPa, commDa [32]byte - copy(commPa[:], commP) - copy(commDa[:], commD) - - return sectorbuilder.VerifyPieceInclusionProof(sectorSize, pieceSize, commPa, commDa, proof) + return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, seeda, sectorID, proof, pieces) } func NewSortedSectorInfo(sectors []SectorInfo) SortedSectorInfo { diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index b40a0b9cd..a4a2f7c15 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -36,12 +36,14 @@ func TestSealAndVerify(t *testing.T) { t.Fatal(err) } + cache := filepath.Join(dir, "cache") metadata := filepath.Join(dir, "meta") sealed := filepath.Join(dir, "sealed") staging := filepath.Join(dir, "staging") sb, err := sectorbuilder.New(§orbuilder.SectorBuilderConfig{ SectorSize: sectorSize, + CacheDir:cache, SealedDir: sealed, StagedDir: staging, MetadataDir: metadata, diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 81b34522a..22773c6a2 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -55,6 +55,7 @@ func SectorBuilderConfig(storagePath string) func(dtypes.MetadataDS, api.FullNod return nil, err } + cache := filepath.Join(sp, "cache") metadata := filepath.Join(sp, "meta") sealed := filepath.Join(sp, "sealed") staging := filepath.Join(sp, "staging") @@ -62,6 +63,7 @@ func SectorBuilderConfig(storagePath string) func(dtypes.MetadataDS, api.FullNod sb := §orbuilder.SectorBuilderConfig{ Miner: minerAddr, SectorSize: ssize, + CacheDir:cache, MetadataDir: metadata, SealedDir: sealed, StagedDir: staging, diff --git a/storage/miner.go b/storage/miner.go index 089a46a3e..15fa17c88 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -92,7 +92,7 @@ func (m *Miner) Run(ctx context.Context) error { } func (m *Miner) commitUntrackedSectors(ctx context.Context) error { - sealed, err := m.secst.Sealed() + sealed, err := m.secst.Commited() if err != nil { return err } @@ -159,6 +159,8 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal return xerrors.Errorf("failed to check out own sector size: %w", err) } + // TODO: Interactive porep + ok, err := sectorbuilder.VerifySeal(ssize, sinfo.CommR[:], sinfo.CommD[:], m.maddr, sinfo.Ticket.TicketBytes[:], sinfo.SectorID, sinfo.Proof) if err != nil { log.Error("failed to verify seal we just created: ", err) diff --git a/storage/sector/store.go b/storage/sector/store.go index 30363ee67..1073329f4 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -32,7 +32,7 @@ type dealMapping struct { Committed bool } -type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error) +type TicketFn func(context.Context) (*sectorbuilder.SealSeed, error) // TODO: eventually handle sector storage here instead of in rust-sectorbuilder type Store struct { @@ -65,7 +65,7 @@ func (s *Store) Service() { go s.service() } -func (s *Store) poll() { +func (s *Store) poll() { // TODO: REMOVE ME (and just use the fact that sectorbuilder methods are now blocking) log.Debug("polling for sealed sectors...") // get a list of sectors to poll @@ -87,7 +87,7 @@ func (s *Store) poll() { continue } - if status.State == sealing_state.Sealed { + if status.State == sealing_state.Committed { done = append(done, status) } } @@ -119,7 +119,7 @@ func (s *Store) restartSealing() { return } - if status.State != sealing_state.Paused { + if status.State != sealing_state.CommittingPaused { // TODO: Also handle PreCommit! continue } @@ -127,7 +127,7 @@ func (s *Store) restartSealing() { go func() { // TODO: when we refactor wait-for-seal below, care about this output too // (see SealSector below) - _, err := s.sb.ResumeSealSector(sid) + _, err := s.sb.ResumeSealCommit(sid) if err != nil { return } @@ -293,7 +293,7 @@ func (s *Store) WaitSeal(ctx context.Context, sector uint64) (sectorbuilder.Sect return s.sb.SealStatus(sector) } -func (s *Store) Sealed() ([]sectorbuilder.SectorSealingStatus, error) { +func (s *Store) Commited() ([]sectorbuilder.SectorSealingStatus, error) { l, err := s.sb.GetAllStagedSectors() if err != nil { return nil, err @@ -306,7 +306,7 @@ func (s *Store) Sealed() ([]sectorbuilder.SectorSealingStatus, error) { return nil, err } - if status.State != sealing_state.Sealed { + if status.State != sealing_state.Committed { continue } out = append(out, status) From 759094198c519d8ee7b9cbf4900088ce2e576ef0 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 30 Oct 2019 18:22:50 -0700 Subject: [PATCH 006/114] Some more progress on interactive porep --- chain/actors/actor_miner.go | 25 +++++++-- chain/actors/actor_storagemarket.go | 40 ++++++++++++++- chain/deals/state_store.go | 1 + gen/main.go | 1 + go.sum | 1 + lib/sectorbuilder/sectorbuilder.go | 10 +++- node/modules/storageminer.go | 2 +- storage/miner.go | 78 ++++++++++++++++++++++++----- storage/sector/store.go | 71 +++----------------------- 9 files changed, 144 insertions(+), 85 deletions(-) diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index 165c5ecd1..fd70f0af0 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -98,6 +98,7 @@ type UnprovenSector struct { CommD []byte CommR []byte SubmitHeight uint64 + TicketEpoch uint64 } type StorageMinerConstructorParams struct { @@ -216,7 +217,6 @@ type SectorPreCommitInfo struct { CommR []byte Epoch uint64 - Proof []byte SectorNumber uint64 } @@ -227,6 +227,14 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon return nil, err } + if params.Epoch >= vmctx.BlockHeight() { + return nil, aerrors.New(1, "sector commitment must be based off past randomness") + } + + if vmctx.BlockHeight()-params.Epoch > 1000 { + return nil, aerrors.New(2, "sector commitment must be recent enough") + } + mi, err := loadMinerInfo(vmctx, self) if err != nil { return nil, err @@ -258,6 +266,7 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon CommR: params.CommR, CommD: params.CommD, SubmitHeight: vmctx.BlockHeight(), + TicketEpoch: params.Epoch, } nstate, err := vmctx.Storage().Put(self) @@ -305,10 +314,18 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC maddr := vmctx.Message().To var pieces []sectorbuilder.PublicPieceInfo // TODO: GET ME FROM DEALS IN STORAGEMARKET - var seed []byte // TODO: GET ME FROM SOMEWHERE - rand, err := vmctx.GetRandomness(us.SubmitHeight + build.InteractivePoRepDelay) - if ok, err := ValidatePoRep(maddr, mi.SectorSize, us.CommD, us.CommR, rand, seed, params.Proof, params.SectorID, pieces); err != nil { + ticket, err := vmctx.GetRandomness(us.TicketEpoch) + if err != nil { + return nil, aerrors.Wrap(err, "failed to get ticket randomness") + } + + seed, err := vmctx.GetRandomness(us.SubmitHeight + build.InteractivePoRepDelay) + if err != nil { + return nil, aerrors.Wrap(err, "failed to get randomness for prove sector commitment") + } + + if ok, err := ValidatePoRep(maddr, mi.SectorSize, us.CommD, us.CommR, ticket, params.Proof, seed, params.SectorID, pieces); err != nil { return nil, err } else if !ok { return nil, aerrors.New(2, "bad proof!") diff --git a/chain/actors/actor_storagemarket.go b/chain/actors/actor_storagemarket.go index 9c3fcb9aa..798818c17 100644 --- a/chain/actors/actor_storagemarket.go +++ b/chain/actors/actor_storagemarket.go @@ -29,9 +29,10 @@ type smaMethods struct { SlashStorageDealCollateral uint64 GetLastExpirationFromDealIDs uint64 ActivateStorageDeals uint64 + ComputeDataCommitment uint64 } -var SMAMethods = smaMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} +var SMAMethods = smaMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} func (sma StorageMarketActor) Exports() []interface{} { return []interface{}{ @@ -45,6 +46,7 @@ func (sma StorageMarketActor) Exports() []interface{} { // 9: sma.SlashStorageDealCollateral, // 10: sma.GetLastExpirationFromDealIDs, 11: sma.ActivateStorageDeals, // TODO: move under PublishStorageDeals after specs team approves + 12: sma.ComputeDataCommitment, } } @@ -585,6 +587,42 @@ func transferFunds(from, to, amt types.BigInt) (types.BigInt, types.BigInt) { return types.BigSub(from, amt), types.BigAdd(to, amt) } +var ComputeDataCommitmentParams struct { + DealIDs []uint64 + SectorSize uint64 +} + +func (sma StorageMarketActor) ComputeDataCommitment(act *types.Actor, vmctx types.VMContext, params *ComputeDataCommitmentParams) ([]byte, ActorError) { + var self StorageMarketState + old := vmctx.Storage().GetHead() + if err := vmctx.Storage().Get(old, &self); err != nil { + return nil, err + } + + deals, err := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.Deals) + if err != nil { + // TODO: kind of annoying that this can be caused by gas, otherwise could be fatal + return nil, aerrors.HandleExternalError(err, "loading deals amt") + } + + for _, deal := range params.DealIDs { + var dealInfo OnChainDeal + if err := deals.Get(deal, &dealInfo); err != nil { + if _, is := err.(*amt.ErrNotFound); is { + return nil, aerrors.New(3, "deal not found") + } + return nil, aerrors.HandleExternalError(err, "getting deal info failed") + } + + _ = dealInfo + } + + // TODO: rust-fil-proofs-magic + var commDoutput [32]byte + + return commDoutput[:], nil +} + /* func (sma StorageMarketActor) HandleCronAction(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { diff --git a/chain/deals/state_store.go b/chain/deals/state_store.go index ae959146f..cde6240be 100644 --- a/chain/deals/state_store.go +++ b/chain/deals/state_store.go @@ -2,6 +2,7 @@ package deals import ( "bytes" + "github.com/filecoin-project/lotus/lib/cborrpc" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" diff --git a/gen/main.go b/gen/main.go index 102872f08..a588dfadb 100644 --- a/gen/main.go +++ b/gen/main.go @@ -88,6 +88,7 @@ func main() { actors.ActivateStorageDealsParams{}, actors.ProcessStorageDealsPaymentParams{}, actors.OnChainDeal{}, + actors.ComputeDataCommitmentParams{}, ) if err != nil { fmt.Println(err) diff --git a/go.sum b/go.sum index e33480571..76f9b1a65 100644 --- a/go.sum +++ b/go.sum @@ -823,6 +823,7 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 033372876..0bcf19506 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -28,6 +28,8 @@ type SealTicket = sectorbuilder.SealTicket type SealSeed = sectorbuilder.SealSeed +type SealPreCommitOutput = sectorbuilder.SealPreCommitOutput + type SealCommitOutput = sectorbuilder.SealCommitOutput type PublicPieceInfo = sectorbuilder.PublicPieceInfo @@ -41,7 +43,7 @@ type SectorBuilder struct { type SectorBuilderConfig struct { SectorSize uint64 Miner address.Address - CacheDir string + CacheDir string SealedDir string StagedDir string MetadataDir string @@ -90,7 +92,11 @@ func (sb *SectorBuilder) ReadPieceFromSealedSector(pieceKey string) ([]byte, err return sectorbuilder.ReadPieceFromSealedSector(sb.handle, pieceKey) } -func (sb *SectorBuilder) SealSector(sectorID uint64, seed SealSeed) (SealCommitOutput, error) { +func (sb *SectorBuilder) SealPreCommit(sectorID uint64, ticket SealTicket) (SealPreCommitOutput, error) { + return sectorbuilder.SealPreCommit(sb.handle, sectorID, ticket) +} + +func (sb *SectorBuilder) SealCommit(sectorID uint64, seed SealSeed) (SealCommitOutput, error) { return sectorbuilder.SealCommit(sb.handle, sectorID, seed) } diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 22773c6a2..73d55c5d1 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -63,7 +63,7 @@ func SectorBuilderConfig(storagePath string) func(dtypes.MetadataDS, api.FullNod sb := §orbuilder.SectorBuilderConfig{ Miner: minerAddr, SectorSize: ssize, - CacheDir:cache, + CacheDir: cache, MetadataDir: metadata, SealedDir: sealed, StagedDir: staging, diff --git a/storage/miner.go b/storage/miner.go index 15fa17c88..1ad4f3eea 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -12,6 +12,7 @@ import ( "golang.org/x/xerrors" "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/events" @@ -159,15 +160,7 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal return xerrors.Errorf("failed to check out own sector size: %w", err) } - // TODO: Interactive porep - - ok, err := sectorbuilder.VerifySeal(ssize, sinfo.CommR[:], sinfo.CommD[:], m.maddr, sinfo.Ticket.TicketBytes[:], sinfo.SectorID, sinfo.Proof) - if err != nil { - log.Error("failed to verify seal we just created: ", err) - } - if !ok { - log.Error("seal we just created failed verification") - } + _ = ssize // TODO: 2 stage commit /*deals, err := m.secst.DealsForCommit(sinfo.SectorID) @@ -178,7 +171,6 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal params := &actors.SectorPreCommitInfo{ CommD: sinfo.CommD[:], CommR: sinfo.CommR[:], - Proof: sinfo.Proof, Epoch: sinfo.Ticket.BlockHeight, //DealIDs: deals, @@ -205,12 +197,74 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal } go func() { - _, err := m.api.StateWaitMsg(ctx, smsg.Cid()) + // TODO: maybe just mark this down in the datastore and handle it differently? This feels complicated to restart + mw, err := m.api.StateWaitMsg(ctx, smsg.Cid()) if err != nil { return } - m.beginPosting(ctx) + randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay + + err = m.events.ChainAt(func(ts *types.TipSet, curH uint64) error { + go func() { + rand, err := m.api.ChainGetRandomness(ctx, ts, nil, ts.Height()-randHeight) + if err != nil { + log.Error(errors.Errorf("failed to get randomness for computing seal proof: %w", err)) + return + } + + // TODO: should this get scheduled to preserve proper resource consumption? + proof, err := m.secst.SealComputeProof(ctx, sinfo.SectorID, rand) + if err != nil { + log.Error(errors.Errorf("computing seal proof failed: %w", err)) + return + } + + params := &actors.SectorProveCommitInfo{ + Proof: proof, + SectorID: sinfo.SectorID, + //DealIDs: deals, + } + + enc, aerr := actors.SerializeParams(params) + if aerr != nil { + log.Errorf(errors.Wrap(aerr, "could not serialize commit sector parameters")) + return + } + + msg := &types.Message{ + To: m.maddr, + From: m.worker, + Method: actors.MAMethods.ProveCommitSector, + Params: enc, + Value: types.NewInt(0), // TODO: need to ensure sufficient collateral + GasLimit: types.NewInt(1000000 /* i dont know help */), + GasPrice: types.NewInt(1), + } + + smsg, err := m.api.MpoolPushMessage(ctx, msg) + if err != nil { + return errors.Wrap(err, "pushing message to mpool") + } + + // TODO: now wait for this to get included and handle errors? + _, err := m.api.StateWaitMsg(ctx, smsg.Cid()) + if err != nil { + log.Errorf("failed to wait for porep inclusion: %s", err) + return + } + + m.beginPosting(ctx) + }() + + return nil + }, func(ts *types.TipSet) error { + log.Warn("revert in interactive commit sector step") + return nil + }, 3, mw.TipSet.Height()+build.InteractivePoRepDelay) + if err != nil { + return + } }() return nil diff --git a/storage/sector/store.go b/storage/sector/store.go index 1073329f4..19460e8bb 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -5,7 +5,6 @@ import ( "fmt" "io" "sync" - "time" "github.com/filecoin-project/go-sectorbuilder/sealing_state" "github.com/ipfs/go-datastore" @@ -65,48 +64,6 @@ func (s *Store) Service() { go s.service() } -func (s *Store) poll() { // TODO: REMOVE ME (and just use the fact that sectorbuilder methods are now blocking) - log.Debug("polling for sealed sectors...") - - // get a list of sectors to poll - s.waitingLk.Lock() - toPoll := make([]uint64, 0, len(s.waiting)) - - for id := range s.waiting { - toPoll = append(toPoll, id) - } - s.waitingLk.Unlock() - - var done []sectorbuilder.SectorSealingStatus - - // check status of each - for _, sec := range toPoll { - status, err := s.sb.SealStatus(sec) - if err != nil { - log.Errorf("getting seal status: %s", err) - continue - } - - if status.State == sealing_state.Committed { - done = append(done, status) - } - } - - // send updates - s.waitingLk.Lock() - for _, sector := range done { - watch, ok := s.waiting[sector.SectorID] - if ok { - close(watch) - delete(s.waiting, sector.SectorID) - } - for _, c := range s.incoming { - c <- sector // TODO: ctx! - } - } - s.waitingLk.Unlock() -} - func (s *Store) restartSealing() { sectors, err := s.sb.GetAllStagedSectors() if err != nil { @@ -135,26 +92,6 @@ func (s *Store) restartSealing() { } } -func (s *Store) service() { - poll := time.Tick(5 * time.Second) - - s.restartSealing() - - for { - select { - case <-poll: - s.poll() - case <-s.closeCh: - s.waitingLk.Lock() - for _, c := range s.incoming { - close(c) - } - s.waitingLk.Unlock() - return - } - } -} - func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64) (sectorID uint64, err error) { sectorID, err = s.sb.AddPiece(ref, size, r) if err != nil { @@ -234,7 +171,7 @@ func (s *Store) DealsForCommit(sectorID uint64) ([]uint64, error) { } } -func (s *Store) SealSector(ctx context.Context, sectorID uint64) error { +func (s *Store) SealPreCommit(ctx context.Context, sectorID uint64) error { tkt, err := s.tktFn(ctx) if err != nil { return err @@ -242,13 +179,17 @@ func (s *Store) SealSector(ctx context.Context, sectorID uint64) error { // TODO: That's not async, is it? // - If not then we probably can drop this wait-for-seal hack below - _, err = s.sb.SealSector(sectorID, *tkt) + _, err = s.sb.SealPreCommit(sectorID, *tkt) if err != nil { return err } return nil } +func (s *Store) SealComputeProof(ctx context.Context, sectorID uint64, rand []byte) ([]byte, error) { + panic("TODO") +} + func (s *Store) CloseIncoming(c <-chan sectorbuilder.SectorSealingStatus) { s.waitingLk.Lock() var at = -1 From 4e478330a42c54b2a87aab60197ef9631e9d51ec Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Thu, 31 Oct 2019 09:55:35 -0700 Subject: [PATCH 007/114] more refactoring for interactive porep scheduling --- chain/actors/actor_miner.go | 21 ++- chain/actors/actor_storagemarket.go | 2 +- chain/actors/cbor_gen.go | 132 +++++++++++++---- chain/deals/provider.go | 8 +- chain/deals/provider_states.go | 60 ++++---- chain/types/cbor_gen.go | 2 +- lib/sectorbuilder/sectorbuilder.go | 4 +- lib/sectorbuilder/sectorbuilder_test.go | 38 ++--- storage/miner.go | 180 +----------------------- storage/sector/store.go | 44 ++---- 10 files changed, 191 insertions(+), 300 deletions(-) diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index fd70f0af0..e18fda36c 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -313,8 +313,6 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC // TODO: ensure normalization to ID address maddr := vmctx.Message().To - var pieces []sectorbuilder.PublicPieceInfo // TODO: GET ME FROM DEALS IN STORAGEMARKET - ticket, err := vmctx.GetRandomness(us.TicketEpoch) if err != nil { return nil, aerrors.Wrap(err, "failed to get ticket randomness") @@ -325,7 +323,20 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC return nil, aerrors.Wrap(err, "failed to get randomness for prove sector commitment") } - if ok, err := ValidatePoRep(maddr, mi.SectorSize, us.CommD, us.CommR, ticket, params.Proof, seed, params.SectorID, pieces); err != nil { + enc, err := SerializeParams(&ComputeDataCommitmentParams{ + DealIDs: params.DealIDs, + SectorSize: mi.SectorSize, + }) + if err != nil { + return nil, aerrors.Wrap(err, "failed to serialize ComputeDataCommitmentParams") + } + + commD, err := vmctx.Send(StorageMarketAddress, SMAMethods.ComputeDataCommitment, types.NewInt(0), enc) + if err != nil { + return nil, aerrors.Wrap(err, "failed to compute data commitment") + } + + if ok, err := ValidatePoRep(maddr, mi.SectorSize, commD, us.CommR, ticket, params.Proof, seed, params.SectorID); err != nil { return nil, err } else if !ok { return nil, aerrors.New(2, "bad proof!") @@ -599,8 +610,8 @@ func GetFromSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID return true, comms[0], comms[1], nil } -func ValidatePoRep(maddr address.Address, ssize uint64, commD, commR, ticket, proof, seed []byte, sectorID uint64, pieces []sectorbuilder.PublicPieceInfo) (bool, ActorError) { - ok, err := sectorbuilder.VerifySeal(ssize, commR, commD, maddr, ticket, seed, sectorID, proof, pieces) +func ValidatePoRep(maddr address.Address, ssize uint64, commD, commR, ticket, proof, seed []byte, sectorID uint64) (bool, ActorError) { + ok, err := sectorbuilder.VerifySeal(ssize, commR, commD, maddr, ticket, seed, sectorID, proof) if err != nil { return false, aerrors.Absorb(err, 25, "verify seal failed") } diff --git a/chain/actors/actor_storagemarket.go b/chain/actors/actor_storagemarket.go index 798818c17..6eeeb7f99 100644 --- a/chain/actors/actor_storagemarket.go +++ b/chain/actors/actor_storagemarket.go @@ -587,7 +587,7 @@ func transferFunds(from, to, amt types.BigInt) (types.BigInt, types.BigInt) { return types.BigSub(from, amt), types.BigAdd(to, amt) } -var ComputeDataCommitmentParams struct { +type ComputeDataCommitmentParams struct { DealIDs []uint64 SectorSize uint64 } diff --git a/chain/actors/cbor_gen.go b/chain/actors/cbor_gen.go index 84de28117..63202da1a 100644 --- a/chain/actors/cbor_gen.go +++ b/chain/actors/cbor_gen.go @@ -542,7 +542,7 @@ func (t *SectorPreCommitInfo) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{133}); err != nil { + if _, err := w.Write([]byte{132}); err != nil { return err } @@ -567,14 +567,6 @@ func (t *SectorPreCommitInfo) MarshalCBOR(w io.Writer) error { return err } - // t.t.Proof ([]uint8) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil { - return err - } - if _, err := w.Write(t.Proof); err != nil { - return err - } - // t.t.SectorNumber (uint64) if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.SectorNumber)); err != nil { return err @@ -593,7 +585,7 @@ func (t *SectorPreCommitInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 5 { + if extra != 4 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -641,23 +633,6 @@ func (t *SectorPreCommitInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("wrong type for uint64 field") } t.Epoch = extra - // t.t.Proof ([]uint8) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if extra > 8192 { - return fmt.Errorf("t.Proof: array too large (%d)", extra) - } - - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.Proof = make([]byte, extra) - if _, err := io.ReadFull(br, t.Proof); err != nil { - return err - } // t.t.SectorNumber (uint64) maj, extra, err = cbg.CborReadHeader(br) @@ -676,7 +651,7 @@ func (t *UnprovenSector) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{131}); err != nil { + if _, err := w.Write([]byte{132}); err != nil { return err } @@ -700,6 +675,11 @@ func (t *UnprovenSector) MarshalCBOR(w io.Writer) error { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.SubmitHeight)); err != nil { return err } + + // t.t.TicketEpoch (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.TicketEpoch)); err != nil { + return err + } return nil } @@ -714,7 +694,7 @@ func (t *UnprovenSector) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 3 { + if extra != 4 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -762,6 +742,16 @@ func (t *UnprovenSector) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("wrong type for uint64 field") } t.SubmitHeight = extra + // t.t.TicketEpoch (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.TicketEpoch = extra return nil } @@ -3697,3 +3687,87 @@ func (t *OnChainDeal) UnmarshalCBOR(r io.Reader) error { t.ActivationEpoch = extra return nil } + +func (t *ComputeDataCommitmentParams) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{130}); err != nil { + return err + } + + // t.t.DealIDs ([]uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { + return err + } + for _, v := range t.DealIDs { + if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { + return err + } + } + + // t.t.SectorSize (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.SectorSize)); err != nil { + return err + } + return nil +} + +func (t *ComputeDataCommitmentParams) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 2 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.DealIDs ([]uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.DealIDs: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.DealIDs = make([]uint64, extra) + } + for i := 0; i < int(extra); i++ { + + maj, val, err := cbg.CborReadHeader(br) + if err != nil { + return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) + } + + if maj != cbg.MajUnsignedInt { + return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) + } + + t.DealIDs[i] = val + } + + // t.t.SectorSize (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.SectorSize = extra + return nil +} diff --git a/chain/deals/provider.go b/chain/deals/provider.go index 356f7d2e7..132e3bf12 100644 --- a/chain/deals/provider.go +++ b/chain/deals/provider.go @@ -17,7 +17,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/cborrpc" "github.com/filecoin-project/lotus/node/modules/dtypes" - "github.com/filecoin-project/lotus/storage/sectorblocks" + "github.com/filecoin-project/lotus/storage" ) type MinerDeal struct { @@ -41,7 +41,7 @@ type Provider struct { ask *types.SignedStorageAsk askLk sync.Mutex - secst *sectorblocks.SectorBlocks + sminer *storage.Miner full api.FullNode // TODO: Use a custom protocol or graphsync in the future @@ -68,7 +68,7 @@ type minerDealUpdate struct { mut func(*MinerDeal) } -func NewProvider(ds dtypes.MetadataDS, secst *sectorblocks.SectorBlocks, dag dtypes.StagingDAG, fullNode api.FullNode) (*Provider, error) { +func NewProvider(ds dtypes.MetadataDS, sminer *storage.Miner, dag dtypes.StagingDAG, fullNode api.FullNode) (*Provider, error) { addr, err := ds.Get(datastore.NewKey("miner-address")) if err != nil { return nil, err @@ -79,7 +79,7 @@ func NewProvider(ds dtypes.MetadataDS, secst *sectorblocks.SectorBlocks, dag dty } h := &Provider{ - secst: secst, + sminer: sminer, dag: dag, full: fullNode, diff --git a/chain/deals/provider_states.go b/chain/deals/provider_states.go index 6c86eb8e9..c43628d13 100644 --- a/chain/deals/provider_states.go +++ b/chain/deals/provider_states.go @@ -4,7 +4,6 @@ import ( "bytes" "context" - "github.com/filecoin-project/go-sectorbuilder/sealing_state" "github.com/ipfs/go-cid" "github.com/ipfs/go-merkledag" unixfile "github.com/ipfs/go-unixfs/file" @@ -229,39 +228,48 @@ func (p *Provider) staged(ctx context.Context, deal MinerDeal) (func(*MinerDeal) if err != nil { return nil, err } + _ = pcid - sectorID, err := p.secst.AddUnixfsPiece(pcid, uf, deal.DealID) - if err != nil { - return nil, xerrors.Errorf("AddPiece failed: %s", err) - } + /* + sectorID, err := p.sminer.AddUnixfsPiece(pcid, uf, deal.DealID) + if err != nil { + return nil, xerrors.Errorf("AddPiece failed: %s", err) + } + log.Warnf("New Sector: %d", sectorID) - log.Warnf("New Sector: %d", sectorID) - return func(deal *MinerDeal) { - deal.SectorID = sectorID - }, nil + return func(deal *MinerDeal) { + deal.SectorID = sectorID + }, nil + */ + panic("fixme") } // SEALING func (p *Provider) waitSealed(ctx context.Context, deal MinerDeal) (sectorbuilder.SectorSealingStatus, error) { - status, err := p.secst.WaitSeal(ctx, deal.SectorID) - if err != nil { - return sectorbuilder.SectorSealingStatus{}, err - } + panic("fixme") - switch status.State { - case sealing_state.Sealed: - case sealing_state.Failed: - return sectorbuilder.SectorSealingStatus{}, xerrors.Errorf("sealing sector %d for deal %s (ref=%s) failed: %s", deal.SectorID, deal.ProposalCid, deal.Ref, status.SealErrorMsg) - case sealing_state.Pending: - return sectorbuilder.SectorSealingStatus{}, xerrors.Errorf("sector status was 'pending' after call to WaitSeal (for sector %d)", deal.SectorID) - case sealing_state.Sealing: - return sectorbuilder.SectorSealingStatus{}, xerrors.Errorf("sector status was 'wait' after call to WaitSeal (for sector %d)", deal.SectorID) - default: - return sectorbuilder.SectorSealingStatus{}, xerrors.Errorf("unknown SealStatusCode: %d", status.SectorID) - } + /* + status, err := p.sminer.WaitSeal(ctx, deal.SectorID) + if err != nil { + return sectorbuilder.SectorSealingStatus{}, err + } + + switch status.State { + case sealing_state.Sealed: + case sealing_state.Failed: + return sectorbuilder.SectorSealingStatus{}, xerrors.Errorf("sealing sector %d for deal %s (ref=%s) failed: %s", deal.SectorID, deal.ProposalCid, deal.Ref, status.SealErrorMsg) + case sealing_state.Pending: + return sectorbuilder.SectorSealingStatus{}, xerrors.Errorf("sector status was 'pending' after call to WaitSeal (for sector %d)", deal.SectorID) + case sealing_state.Sealing: + return sectorbuilder.SectorSealingStatus{}, xerrors.Errorf("sector status was 'wait' after call to WaitSeal (for sector %d)", deal.SectorID) + default: + return sectorbuilder.SectorSealingStatus{}, xerrors.Errorf("unknown SealStatusCode: %d", status.SectorID) + } + + return status, nil + */ - return status, nil } func (p *Provider) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal), error) { @@ -273,7 +281,7 @@ func (p *Provider) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal log.Warnf("Sending deal response failed: %s", err) } - if err := p.secst.SealSector(ctx, deal.SectorID); err != nil { + if err := p.sminer.SealSector(ctx, deal.SectorID); err != nil { return nil, xerrors.Errorf("sealing sector failed: %w", err) } diff --git a/chain/types/cbor_gen.go b/chain/types/cbor_gen.go index 9cf6ec913..ab63b28a1 100644 --- a/chain/types/cbor_gen.go +++ b/chain/types/cbor_gen.go @@ -5,7 +5,7 @@ import ( "io" "math" - "github.com/ipfs/go-cid" + cid "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" ) diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 0bcf19506..0c1aeb66e 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -134,7 +134,7 @@ func (sb *SectorBuilder) GeneratePoSt(sectorInfo SortedSectorInfo, challengeSeed var UserBytesForSectorSize = sectorbuilder.GetMaxUserBytesPerStagedSector -func VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address, ticket []byte, seed []byte, sectorID uint64, proof []byte, pieces []PublicPieceInfo) (bool, error) { +func VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address, ticket []byte, seed []byte, sectorID uint64, proof []byte) (bool, error) { var commRa, commDa, ticketa, seeda [32]byte copy(commRa[:], commR) copy(commDa[:], commD) @@ -142,7 +142,7 @@ func VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address copy(seeda[:], seed) proverIDa := addressToProverID(proverID) - return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, seeda, sectorID, proof, pieces) + return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, seeda, sectorID, proof, nil) } func NewSortedSectorInfo(sectors []SectorInfo) SortedSectorInfo { diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index a4a2f7c15..3c86bb6ef 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -1,19 +1,15 @@ package sectorbuilder_test import ( - "context" "io" "io/ioutil" "math/rand" "path/filepath" "testing" - "github.com/ipfs/go-datastore" - "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/lib/sectorbuilder" - "github.com/filecoin-project/lotus/storage/sector" ) const sectorSize = 1024 @@ -43,7 +39,7 @@ func TestSealAndVerify(t *testing.T) { sb, err := sectorbuilder.New(§orbuilder.SectorBuilderConfig{ SectorSize: sectorSize, - CacheDir:cache, + CacheDir: cache, SealedDir: sealed, StagedDir: staging, MetadataDir: metadata, @@ -53,31 +49,35 @@ func TestSealAndVerify(t *testing.T) { t.Fatal(err) } - // TODO: Consider fixing - store := sector.NewStore(sb, datastore.NewMapDatastore(), func(ctx context.Context) (*sectorbuilder.SealTicket, error) { - return §orbuilder.SealTicket{ - BlockHeight: 5, - TicketBytes: [32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2}, - }, nil - }) - - store.Service() - dlen := sectorbuilder.UserBytesForSectorSize(sectorSize) r := io.LimitReader(rand.New(rand.NewSource(42)), int64(dlen)) - sid, err := store.AddPiece("foo", dlen, r) + sid, err := sb.AddPiece("foo", dlen, r) if err != nil { t.Fatal(err) } - if err := store.SealSector(context.TODO(), sid); err != nil { + ticket := sectorbuilder.SealTicket{ + BlockHeight: 5, + TicketBytes: [32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2}, + } + + pco, err := sb.SealPreCommit(sid, ticket) + if err != nil { t.Fatal(err) } - ssinfo := <-store.Incoming() + seed := sectorbuilder.SealSeed{ + BlockHeight: 15, + TicketBytes: [32]byte{0, 9, 8, 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, 8}, + } - ok, err := sectorbuilder.VerifySeal(sectorSize, ssinfo.CommR[:], ssinfo.CommD[:], addr, ssinfo.Ticket.TicketBytes[:], ssinfo.SectorID, ssinfo.Proof) + sco, err := sb.SealCommit(sid, seed) + if err != nil { + t.Fatal(err) + } + + ok, err := sectorbuilder.VerifySeal(sectorSize, pco.CommR[:], pco.CommD[:], addr, ticket.TicketBytes[:], seed.TicketBytes[:], sid, sco.Proof) if err != nil { t.Fatal(err) } diff --git a/storage/miner.go b/storage/miner.go index 1ad4f3eea..bb3be8f8c 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -9,11 +9,8 @@ import ( logging "github.com/ipfs/go-log" "github.com/libp2p/go-libp2p-core/host" "github.com/pkg/errors" - "golang.org/x/xerrors" "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/events" "github.com/filecoin-project/lotus/chain/store" @@ -87,187 +84,12 @@ func (m *Miner) Run(ctx context.Context) error { m.events = events.NewEvents(ctx, m.api) - go m.handlePostingSealedSectors(ctx) go m.beginPosting(ctx) return nil } -func (m *Miner) commitUntrackedSectors(ctx context.Context) error { - sealed, err := m.secst.Commited() - if err != nil { - return err - } - - chainSectors, err := m.api.StateMinerSectors(ctx, m.maddr, nil) - if err != nil { - return err - } - - onchain := map[uint64]struct{}{} - for _, chainSector := range chainSectors { - onchain[chainSector.SectorID] = struct{}{} - } - - for _, s := range sealed { - if _, ok := onchain[s.SectorID]; ok { - continue - } - - log.Warnf("Missing commitment for sector %d, committing sector", s.SectorID) - - if err := m.commitSector(ctx, s); err != nil { - log.Error("Committing uncommitted sector failed: ", err) - } - } - return nil -} - -func (m *Miner) handlePostingSealedSectors(ctx context.Context) { - incoming := m.secst.Incoming() - defer m.secst.CloseIncoming(incoming) - - if err := m.commitUntrackedSectors(ctx); err != nil { - log.Error(err) - } - - for { - select { - case sinfo, ok := <-incoming: - if !ok { - // TODO: set some state variable so that this state can be - // visible via some status command - log.Warn("sealed sector channel closed, aborting process") - return - } - - if err := m.commitSector(ctx, sinfo); err != nil { - log.Errorf("failed to commit sector: %s", err) - continue - } - - case <-ctx.Done(): - log.Warn("exiting seal posting routine") - return - } - } -} - func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSealingStatus) error { - log.Info("committing sector") - - ssize, err := m.SectorSize(ctx) - if err != nil { - return xerrors.Errorf("failed to check out own sector size: %w", err) - } - - _ = ssize - - // TODO: 2 stage commit - /*deals, err := m.secst.DealsForCommit(sinfo.SectorID) - if err != nil { - return xerrors.Errorf("getting sector deals failed: %w", err) - } - */ - params := &actors.SectorPreCommitInfo{ - CommD: sinfo.CommD[:], - CommR: sinfo.CommR[:], - Epoch: sinfo.Ticket.BlockHeight, - - //DealIDs: deals, - SectorNumber: sinfo.SectorID, - } - enc, aerr := actors.SerializeParams(params) - if aerr != nil { - return errors.Wrap(aerr, "could not serialize commit sector parameters") - } - - msg := &types.Message{ - To: m.maddr, - From: m.worker, - Method: actors.MAMethods.PreCommitSector, - Params: enc, - Value: types.NewInt(0), // TODO: need to ensure sufficient collateral - GasLimit: types.NewInt(1000000 /* i dont know help */), - GasPrice: types.NewInt(1), - } - - smsg, err := m.api.MpoolPushMessage(ctx, msg) - if err != nil { - return errors.Wrap(err, "pushing message to mpool") - } - - go func() { - // TODO: maybe just mark this down in the datastore and handle it differently? This feels complicated to restart - mw, err := m.api.StateWaitMsg(ctx, smsg.Cid()) - if err != nil { - return - } - - randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay - - err = m.events.ChainAt(func(ts *types.TipSet, curH uint64) error { - go func() { - rand, err := m.api.ChainGetRandomness(ctx, ts, nil, ts.Height()-randHeight) - if err != nil { - log.Error(errors.Errorf("failed to get randomness for computing seal proof: %w", err)) - return - } - - // TODO: should this get scheduled to preserve proper resource consumption? - proof, err := m.secst.SealComputeProof(ctx, sinfo.SectorID, rand) - if err != nil { - log.Error(errors.Errorf("computing seal proof failed: %w", err)) - return - } - - params := &actors.SectorProveCommitInfo{ - Proof: proof, - SectorID: sinfo.SectorID, - //DealIDs: deals, - } - - enc, aerr := actors.SerializeParams(params) - if aerr != nil { - log.Errorf(errors.Wrap(aerr, "could not serialize commit sector parameters")) - return - } - - msg := &types.Message{ - To: m.maddr, - From: m.worker, - Method: actors.MAMethods.ProveCommitSector, - Params: enc, - Value: types.NewInt(0), // TODO: need to ensure sufficient collateral - GasLimit: types.NewInt(1000000 /* i dont know help */), - GasPrice: types.NewInt(1), - } - - smsg, err := m.api.MpoolPushMessage(ctx, msg) - if err != nil { - return errors.Wrap(err, "pushing message to mpool") - } - - // TODO: now wait for this to get included and handle errors? - _, err := m.api.StateWaitMsg(ctx, smsg.Cid()) - if err != nil { - log.Errorf("failed to wait for porep inclusion: %s", err) - return - } - - m.beginPosting(ctx) - }() - - return nil - }, func(ts *types.TipSet) error { - log.Warn("revert in interactive commit sector step") - return nil - }, 3, mw.TipSet.Height()+build.InteractivePoRepDelay) - if err != nil { - return - } - }() - - return nil + return m.SealSector(ctx, sinfo.SectorID) } func (m *Miner) runPreflightChecks(ctx context.Context) error { diff --git a/storage/sector/store.go b/storage/sector/store.go index 19460e8bb..3e498f052 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -31,7 +31,7 @@ type dealMapping struct { Committed bool } -type TicketFn func(context.Context) (*sectorbuilder.SealSeed, error) +type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error) // TODO: eventually handle sector storage here instead of in rust-sectorbuilder type Store struct { @@ -60,10 +60,6 @@ func NewStore(sb *sectorbuilder.SectorBuilder, ds dtypes.MetadataDS, tktFn Ticke } } -func (s *Store) Service() { - go s.service() -} - func (s *Store) restartSealing() { sectors, err := s.sb.GetAllStagedSectors() if err != nil { @@ -92,6 +88,15 @@ func (s *Store) restartSealing() { } } +func (s *Store) SectorStatus(sid uint64) (*sectorbuilder.SectorSealingStatus, error) { + status, err := s.sb.SealStatus(sid) + if err != nil { + return nil, err + } + + return &status, nil +} + func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64) (sectorID uint64, err error) { sectorID, err = s.sb.AddPiece(ref, size, r) if err != nil { @@ -190,35 +195,6 @@ func (s *Store) SealComputeProof(ctx context.Context, sectorID uint64, rand []by panic("TODO") } -func (s *Store) CloseIncoming(c <-chan sectorbuilder.SectorSealingStatus) { - s.waitingLk.Lock() - var at = -1 - for i, ch := range s.incoming { - if ch == c { - at = i - } - } - if at == -1 { - s.waitingLk.Unlock() - return - } - if len(s.incoming) > 1 { - last := len(s.incoming) - 1 - s.incoming[at] = s.incoming[last] - s.incoming[last] = nil - } - s.incoming = s.incoming[:len(s.incoming)-1] - s.waitingLk.Unlock() -} - -func (s *Store) Incoming() <-chan sectorbuilder.SectorSealingStatus { - ch := make(chan sectorbuilder.SectorSealingStatus, 8) - s.waitingLk.Lock() - s.incoming = append(s.incoming, ch) - s.waitingLk.Unlock() - return ch -} - func (s *Store) WaitSeal(ctx context.Context, sector uint64) (sectorbuilder.SectorSealingStatus, error) { s.waitingLk.Lock() watch, ok := s.waiting[sector] From 34998d936281ca6ecf0ac8fe9f7fc19fb5bbf69f Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Thu, 31 Oct 2019 11:46:53 -0700 Subject: [PATCH 008/114] add file i forgot --- storage/sealing.go | 141 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 storage/sealing.go diff --git a/storage/sealing.go b/storage/sealing.go new file mode 100644 index 000000000..eeeca0f64 --- /dev/null +++ b/storage/sealing.go @@ -0,0 +1,141 @@ +package storage + +import ( + "context" + + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/types" + cid "github.com/ipfs/go-cid" + "github.com/pkg/errors" + "golang.org/x/xerrors" +) + +func (m *Miner) SealSector(ctx context.Context, sid uint64) error { + log.Info("committing sector") + + ssize, err := m.SectorSize(ctx) + if err != nil { + return xerrors.Errorf("failed to check out own sector size: %w", err) + } + + _ = ssize + + sinfo, err := m.secst.SectorStatus(sid) + if err != nil { + return xerrors.Errorf("failed to check status for sector %d: %w", sid, err) + } + + params := &actors.SectorPreCommitInfo{ + CommD: sinfo.CommD[:], + CommR: sinfo.CommR[:], + Epoch: sinfo.Ticket.BlockHeight, + + //DealIDs: deals, + SectorNumber: sinfo.SectorID, + } + enc, aerr := actors.SerializeParams(params) + if aerr != nil { + return errors.Wrap(aerr, "could not serialize commit sector parameters") + } + + msg := &types.Message{ + To: m.maddr, + From: m.worker, + Method: actors.MAMethods.PreCommitSector, + Params: enc, + Value: types.NewInt(0), // TODO: need to ensure sufficient collateral + GasLimit: types.NewInt(1000000 /* i dont know help */), + GasPrice: types.NewInt(1), + } + + smsg, err := m.api.MpoolPushMessage(ctx, msg) + if err != nil { + return errors.Wrap(err, "pushing message to mpool") + } + + go m.waitForPreCommitMessage(context.TODO(), sinfo.SectorID, smsg.Cid()) + + // TODO: maybe return a wait channel? + return nil +} + +func (m *Miner) waitForPreCommitMessage(ctx context.Context, sid uint64, mcid cid.Cid) { + // would be ideal to just use the events.Called handler, but it wouldnt be able to handle individual message timeouts + mw, err := m.api.StateWaitMsg(ctx, mcid) + if err != nil { + return + } + + randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay + + err = m.events.ChainAt(func(ts *types.TipSet, curH uint64) error { + return m.scheduleComputeProof(ctx, sid, ts, randHeight) + }, func(ts *types.TipSet) error { + log.Warn("revert in interactive commit sector step") + return nil + }, 3, mw.TipSet.Height()+build.InteractivePoRepDelay) + if err != nil { + log.Warn("waitForPreCommitMessage ChainAt errored: ", err) + } +} + +func (m *Miner) scheduleComputeProof(ctx context.Context, sid uint64, ts *types.TipSet, rheight uint64) error { + go func() { + rand, err := m.api.ChainGetRandomness(ctx, ts, nil, int(ts.Height()-rheight)) + if err != nil { + log.Error(errors.Errorf("failed to get randomness for computing seal proof: %w", err)) + return + } + + proof, err := m.secst.SealComputeProof(ctx, sid, rand) + if err != nil { + log.Error(errors.Errorf("computing seal proof failed: %w", err)) + return + } + + params := &actors.SectorProveCommitInfo{ + Proof: proof, + SectorID: sid, + //DealIDs: deals, + } + + _ = params + enc, aerr := actors.SerializeParams(nil) + if aerr != nil { + log.Error(errors.Wrap(aerr, "could not serialize commit sector parameters")) + return + } + + msg := &types.Message{ + To: m.maddr, + From: m.worker, + Method: actors.MAMethods.ProveCommitSector, + Params: enc, + Value: types.NewInt(0), // TODO: need to ensure sufficient collateral + GasLimit: types.NewInt(1000000 /* i dont know help */), + GasPrice: types.NewInt(1), + } + + smsg, err := m.api.MpoolPushMessage(ctx, msg) + if err != nil { + log.Error(errors.Wrap(err, "pushing message to mpool")) + } + + // TODO: now wait for this to get included and handle errors? + mw, err := m.api.StateWaitMsg(ctx, smsg.Cid()) + if err != nil { + log.Errorf("failed to wait for porep inclusion: %s", err) + return + } + + if mw.Receipt.ExitCode != 0 { + log.Error("UNHANDLED: submitting sector proof failed") + return + } + + m.beginPosting(ctx) + }() + + return nil +} From ba937cf859dea578fcab3c97d42117e5de324064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 31 Oct 2019 20:03:26 +0100 Subject: [PATCH 009/114] Fix sectorbuilder.VerifySeal --- chain/deals/provider.go | 6 +++--- lib/sectorbuilder/sectorbuilder.go | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/chain/deals/provider.go b/chain/deals/provider.go index 132e3bf12..bf71e3460 100644 --- a/chain/deals/provider.go +++ b/chain/deals/provider.go @@ -42,7 +42,7 @@ type Provider struct { askLk sync.Mutex sminer *storage.Miner - full api.FullNode + full api.FullNode // TODO: Use a custom protocol or graphsync in the future // TODO: GC @@ -80,8 +80,8 @@ func NewProvider(ds dtypes.MetadataDS, sminer *storage.Miner, dag dtypes.Staging h := &Provider{ sminer: sminer, - dag: dag, - full: fullNode, + dag: dag, + full: fullNode, pricePerByteBlock: types.NewInt(3), // TODO: allow setting minPieceSize: 1, diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 0c1aeb66e..f17dd4121 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -142,7 +142,10 @@ func VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address copy(seeda[:], seed) proverIDa := addressToProverID(proverID) - return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, seeda, sectorID, proof, nil) + return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, seeda, sectorID, proof, []sectorbuilder.PublicPieceInfo{{ + Size: UserBytesForSectorSize(sectorSize), // TODO: Provide the real piece size? + CommP: commDa, + }}) } func NewSortedSectorInfo(sectors []SectorInfo) SortedSectorInfo { From 3cde267a2a28d8150a6cdd1330222a5194a83d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 31 Oct 2019 22:01:44 +0100 Subject: [PATCH 010/114] Move statestore to lib --- chain/deals/client.go | 3 +- chain/deals/provider.go | 3 +- chain/deals/state_store.go | 80 +++----------------------------- lib/statestore/store.go | 95 ++++++++++++++++++++++++++++++++++++++ node/impl/storminer.go | 2 +- 5 files changed, 107 insertions(+), 76 deletions(-) create mode 100644 lib/statestore/store.go diff --git a/chain/deals/client.go b/chain/deals/client.go index fa70dbe99..3ea36c2e7 100644 --- a/chain/deals/client.go +++ b/chain/deals/client.go @@ -2,6 +2,7 @@ package deals import ( "context" + "github.com/filecoin-project/lotus/lib/statestore" "github.com/filecoin-project/lotus/node/impl/full" "github.com/ipfs/go-cid" @@ -71,7 +72,7 @@ func NewClient(sm *stmgr.StateManager, chain *store.ChainStore, h host.Host, w * discovery: discovery, mpool: mpool, - deals: ClientStateStore{StateStore{ds: namespace.Wrap(ds, datastore.NewKey("/deals/client"))}}, + deals: ClientStateStore{statestore.New(namespace.Wrap(ds, datastore.NewKey("/deals/client")))}, conns: map[cid.Cid]inet.Stream{}, incoming: make(chan *ClientDeal, 16), diff --git a/chain/deals/provider.go b/chain/deals/provider.go index bf71e3460..aa47a45c5 100644 --- a/chain/deals/provider.go +++ b/chain/deals/provider.go @@ -2,6 +2,7 @@ package deals import ( "context" + "github.com/filecoin-project/lotus/lib/statestore" "sync" cid "github.com/ipfs/go-cid" @@ -95,7 +96,7 @@ func NewProvider(ds dtypes.MetadataDS, sminer *storage.Miner, dag dtypes.Staging actor: minerAddress, - deals: MinerStateStore{StateStore{ds: namespace.Wrap(ds, datastore.NewKey("/deals/client"))}}, + deals: MinerStateStore{statestore.New(namespace.Wrap(ds, datastore.NewKey("/deals/client")))}, ds: ds, } diff --git a/chain/deals/state_store.go b/chain/deals/state_store.go index cde6240be..b654816c6 100644 --- a/chain/deals/state_store.go +++ b/chain/deals/state_store.go @@ -2,77 +2,18 @@ package deals import ( "bytes" + "github.com/filecoin-project/lotus/lib/statestore" "github.com/filecoin-project/lotus/lib/cborrpc" "github.com/ipfs/go-cid" - "github.com/ipfs/go-datastore" - "github.com/ipfs/go-datastore/query" - "golang.org/x/xerrors" ) -type StateStore struct { - ds datastore.Datastore -} - -func (st *StateStore) Begin(i cid.Cid, state interface{}) error { - k := datastore.NewKey(i.String()) - has, err := st.ds.Has(k) - if err != nil { - return err - } - if has { - return xerrors.Errorf("Already tracking state for %s", i) - } - - b, err := cborrpc.Dump(state) - if err != nil { - return err - } - - return st.ds.Put(k, b) -} - -func (st *StateStore) End(i cid.Cid) error { - k := datastore.NewKey(i.String()) - has, err := st.ds.Has(k) - if err != nil { - return err - } - if !has { - return xerrors.Errorf("No state for %s", i) - } - return st.ds.Delete(k) -} - -func (st *StateStore) mutate(i cid.Cid, mutator func([]byte) ([]byte, error)) error { - k := datastore.NewKey(i.String()) - has, err := st.ds.Has(k) - if err != nil { - return err - } - if !has { - return xerrors.Errorf("No state for %s", i) - } - - cur, err := st.ds.Get(k) - if err != nil { - return err - } - - mutated, err := mutator(cur) - if err != nil { - return err - } - - return st.ds.Put(k, mutated) -} - type MinerStateStore struct { - StateStore + *statestore.StateStore } func (st *MinerStateStore) MutateMiner(i cid.Cid, mutator func(*MinerDeal) error) error { - return st.mutate(i, minerMutator(mutator)) + return st.Mutate(i, minerMutator(mutator)) } func minerMutator(m func(*MinerDeal) error) func([]byte) ([]byte, error) { @@ -92,11 +33,11 @@ func minerMutator(m func(*MinerDeal) error) func([]byte) ([]byte, error) { } type ClientStateStore struct { - StateStore + *statestore.StateStore } func (st *ClientStateStore) MutateClient(i cid.Cid, mutator func(*ClientDeal) error) error { - return st.mutate(i, clientMutator(mutator)) + return st.Mutate(i, clientMutator(mutator)) } func clientMutator(m func(*ClientDeal) error) func([]byte) ([]byte, error) { @@ -118,18 +59,11 @@ func clientMutator(m func(*ClientDeal) error) func([]byte) ([]byte, error) { func (st *ClientStateStore) ListClient() ([]ClientDeal, error) { var out []ClientDeal - res, err := st.ds.Query(query.Query{}) + l, err := st.List() if err != nil { return nil, err } - defer res.Close() - - for { - res, ok := res.NextSync() - if !ok { - break - } - + for _, res := range l { var deal ClientDeal err := cborrpc.ReadCborRPC(bytes.NewReader(res.Value), &deal) if err != nil { diff --git a/lib/statestore/store.go b/lib/statestore/store.go new file mode 100644 index 000000000..50c5eeb61 --- /dev/null +++ b/lib/statestore/store.go @@ -0,0 +1,95 @@ +package statestore + +import ( + "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/query" + "golang.org/x/xerrors" +) + +type StateStore struct { + ds datastore.Datastore +} + +func New(ds datastore.Datastore) *StateStore { + return &StateStore{ds:ds} +} + +func (st *StateStore) Begin(i cid.Cid, state interface{}) error { + k := datastore.NewKey(i.String()) + has, err := st.ds.Has(k) + if err != nil { + return err + } + if has { + return xerrors.Errorf("Already tracking state for %s", i) + } + + b, err := cborrpc.Dump(state) + if err != nil { + return err + } + + return st.ds.Put(k, b) +} + +func (st *StateStore) End(i cid.Cid) error { + k := datastore.NewKey(i.String()) + has, err := st.ds.Has(k) + if err != nil { + return err + } + if !has { + return xerrors.Errorf("No state for %s", i) + } + return st.ds.Delete(k) +} + +func (st *StateStore) Mutate(i cid.Cid, mutator func([]byte) ([]byte, error)) error { + k := datastore.NewKey(i.String()) + has, err := st.ds.Has(k) + if err != nil { + return err + } + if !has { + return xerrors.Errorf("No state for %s", i) + } + + cur, err := st.ds.Get(k) + if err != nil { + return err + } + + mutated, err := mutator(cur) + if err != nil { + return err + } + + return st.ds.Put(k, mutated) +} + +func (st *StateStore) List() ([]query.Entry, error) { + var out []query.Entry + + res, err := st.ds.Query(query.Query{}) + if err != nil { + return nil, err + } + defer res.Close() + + for { + res, ok := res.NextSync() + if !ok { + break + } + if res.Error != nil { + return nil, res.Error + } + + out = append(out, res.Entry) + } + + return out, nil +} + diff --git a/node/impl/storminer.go b/node/impl/storminer.go index c763dab5e..b8b101ec3 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -47,7 +47,7 @@ func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) error { return } - if err := sm.Sectors.SealSector(ctx, sectorId); err != nil { + if err := sm.Miner.SealSector(ctx, sectorId); err != nil { log.Error(err) return } From fc9091cc89eddc3ac586651805950f7cb82f3f28 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Thu, 31 Oct 2019 20:57:10 -0700 Subject: [PATCH 011/114] Get interactive porep sector sealing mostly working --- chain/actors/actor_storagemarket.go | 18 ++++++++++--- cmd/lotus-storage-miner/info.go | 40 +++++++++-------------------- cmd/lotus/daemon.go | 3 ++- extern/go-sectorbuilder | 2 +- go.sum | 1 + lib/sectorbuilder/sectorbuilder.go | 9 ++++--- node/builder.go | 1 - node/modules/services.go | 14 ---------- node/options.go | 3 ++- peermgr/peermgr.go | 4 ++- storage/sealing.go | 22 +++++++++++++--- storage/sector/store.go | 14 ++++++++-- 12 files changed, 70 insertions(+), 61 deletions(-) diff --git a/chain/actors/actor_storagemarket.go b/chain/actors/actor_storagemarket.go index 6eeeb7f99..cc2e7a96e 100644 --- a/chain/actors/actor_storagemarket.go +++ b/chain/actors/actor_storagemarket.go @@ -13,6 +13,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/sectorbuilder" ) type StorageMarketActor struct{} @@ -605,6 +606,7 @@ func (sma StorageMarketActor) ComputeDataCommitment(act *types.Actor, vmctx type return nil, aerrors.HandleExternalError(err, "loading deals amt") } + var pieces []sectorbuilder.PublicPieceInfo for _, deal := range params.DealIDs { var dealInfo OnChainDeal if err := deals.Get(deal, &dealInfo); err != nil { @@ -614,13 +616,21 @@ func (sma StorageMarketActor) ComputeDataCommitment(act *types.Actor, vmctx type return nil, aerrors.HandleExternalError(err, "getting deal info failed") } - _ = dealInfo + var commP [32]byte + copy(commP[:], dealInfo.Deal.Proposal.PieceRef) + + pieces = append(pieces, sectorbuilder.PublicPieceInfo{ + Size: dealInfo.Deal.Proposal.PieceSize, + CommP: commP, + }) } - // TODO: rust-fil-proofs-magic - var commDoutput [32]byte + commd, err := sectorbuilder.GenerateDataCommitment(params.SectorSize, pieces) + if err != nil { + return nil, aerrors.Absorb(err, 4, "failed to generate data commitment from pieces") + } - return commDoutput[:], nil + return commd[:], nil } /* diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 436fc4686..213204a99 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -6,7 +6,6 @@ import ( "gopkg.in/urfave/cli.v2" - sectorstate "github.com/filecoin-project/go-sectorbuilder/sealing_state" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" @@ -50,10 +49,13 @@ var infoCmd = &cli.Command{ return err } - fmt.Println("Sealed Sectors:\t", sinfo.SealedCount) - fmt.Println("Sealing Sectors:\t", sinfo.SealingCount) - fmt.Println("Pending Sectors:\t", sinfo.PendingCount) - fmt.Println("Failed Sectors:\t", sinfo.FailedCount) + /* + fmt.Println("Sealed Sectors:\t", sinfo.SealedCount) + fmt.Println("Sealing Sectors:\t", sinfo.SealingCount) + fmt.Println("Pending Sectors:\t", sinfo.PendingCount) + fmt.Println("Failed Sectors:\t", sinfo.FailedCount) + */ + fmt.Println(sinfo) // TODO: grab actr state / info // * Sector size @@ -63,22 +65,14 @@ var infoCmd = &cli.Command{ }, } -type SectorsInfo struct { - TotalCount int - SealingCount int - FailedCount int - SealedCount int - PendingCount int -} - -func sectorsInfo(ctx context.Context, napi api.StorageMiner) (*SectorsInfo, error) { +func sectorsInfo(ctx context.Context, napi api.StorageMiner) (map[string]int, error) { sectors, err := napi.SectorsList(ctx) if err != nil { return nil, err } - out := SectorsInfo{ - TotalCount: len(sectors), + out := map[string]int{ + "Total": len(sectors), } for _, s := range sectors { st, err := napi.SectorsStatus(ctx, s) @@ -86,18 +80,8 @@ func sectorsInfo(ctx context.Context, napi api.StorageMiner) (*SectorsInfo, erro return nil, err } - switch st.State { - case sectorstate.Sealed: - out.SealedCount++ - case sectorstate.Pending: - out.PendingCount++ - case sectorstate.Sealing: - out.SealingCount++ - case sectorstate.Failed: - out.FailedCount++ - case sectorstate.Unknown: - } + out[st.State.String()]++ } - return &out, nil + return out, nil } diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index c9b736c72..62b579eb1 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -4,9 +4,10 @@ package main import ( "context" - "github.com/filecoin-project/lotus/peermgr" "io/ioutil" + "github.com/filecoin-project/lotus/peermgr" + "github.com/multiformats/go-multiaddr" "golang.org/x/xerrors" "gopkg.in/urfave/cli.v2" diff --git a/extern/go-sectorbuilder b/extern/go-sectorbuilder index e8231db9d..06775780d 160000 --- a/extern/go-sectorbuilder +++ b/extern/go-sectorbuilder @@ -1 +1 @@ -Subproject commit e8231db9dc64e79f7049e25c538b77b88eef54dc +Subproject commit 06775780d8e4db7ba123a7c76073e10d7785b076 diff --git a/go.sum b/go.sum index 76f9b1a65..09d5a1111 100644 --- a/go.sum +++ b/go.sum @@ -749,6 +749,7 @@ golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index f17dd4121..bd57a7bda 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -142,10 +142,7 @@ func VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address copy(seeda[:], seed) proverIDa := addressToProverID(proverID) - return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, seeda, sectorID, proof, []sectorbuilder.PublicPieceInfo{{ - Size: UserBytesForSectorSize(sectorSize), // TODO: Provide the real piece size? - CommP: commDa, - }}) + return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, seeda, sectorID, proof) } func NewSortedSectorInfo(sectors []SectorInfo) SortedSectorInfo { @@ -170,6 +167,10 @@ func GeneratePieceCommitment(piece io.Reader, pieceSize uint64) (commP [CommLen] return commP, werr() } +func GenerateDataCommitment(ssize uint64, pieces []PublicPieceInfo) ([CommLen]byte, error) { + return sectorbuilder.GenerateDataCommitment(ssize, pieces) +} + func toReadableFile(r io.Reader, n int64) (*os.File, func() error, error) { f, ok := r.(*os.File) if ok { diff --git a/node/builder.go b/node/builder.go index 26b6bbd7f..ded10f3d6 100644 --- a/node/builder.go +++ b/node/builder.go @@ -242,7 +242,6 @@ func Online() Option { Override(new(*deals.Provider), deals.NewProvider), Override(HandleRetrievalKey, modules.HandleRetrieval), Override(HandleDealsKey, modules.HandleDeals), - Override(RunSectorServiceKey, modules.RunSectorService), Override(RegisterMinerKey, modules.RegisterMiner), ), ) diff --git a/node/modules/services.go b/node/modules/services.go index 3c38f4461..c5c3df125 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -15,7 +15,6 @@ import ( "github.com/filecoin-project/lotus/node/modules/helpers" "github.com/filecoin-project/lotus/peermgr" "github.com/filecoin-project/lotus/retrieval/discovery" - "github.com/filecoin-project/lotus/storage/sector" ) func RunHello(mctx helpers.MetricsCtx, lc fx.Lifecycle, h host.Host, svc *hello.Service) { @@ -79,19 +78,6 @@ func RunDealClient(mctx helpers.MetricsCtx, lc fx.Lifecycle, c *deals.Client) { }) } -func RunSectorService(lc fx.Lifecycle, secst *sector.Store) { - lc.Append(fx.Hook{ - OnStart: func(context.Context) error { - secst.Service() - return nil - }, - OnStop: func(context.Context) error { - secst.Stop() - return nil - }, - }) -} - func RetrievalResolver(l *discovery.Local) discovery.PeerResolver { return discovery.Multi(l) } diff --git a/node/options.go b/node/options.go index 58576a950..9c8a79710 100644 --- a/node/options.go +++ b/node/options.go @@ -1,8 +1,9 @@ package node import ( - "go.uber.org/fx" "reflect" + + "go.uber.org/fx" ) // Option is a functional option which can be used with the New function to diff --git a/peermgr/peermgr.go b/peermgr/peermgr.go index d8a0bea77..3c4053da1 100644 --- a/peermgr/peermgr.go +++ b/peermgr/peermgr.go @@ -2,10 +2,11 @@ package peermgr import ( "context" - "github.com/filecoin-project/lotus/node/modules/dtypes" "sync" "time" + "github.com/filecoin-project/lotus/node/modules/dtypes" + host "github.com/libp2p/go-libp2p-core/host" net "github.com/libp2p/go-libp2p-core/network" peer "github.com/libp2p/go-libp2p-core/peer" @@ -43,6 +44,7 @@ type PeerMgr struct { } func NewPeerMgr(h host.Host, dht *dht.IpfsDHT, bootstrap dtypes.BootstrapPeers) *PeerMgr { + bootstrap = nil pm := &PeerMgr{ h: h, dht: dht, diff --git a/storage/sealing.go b/storage/sealing.go index eeeca0f64..2a3d02d7f 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -2,6 +2,7 @@ package storage import ( "context" + "fmt" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" @@ -12,7 +13,7 @@ import ( ) func (m *Miner) SealSector(ctx context.Context, sid uint64) error { - log.Info("committing sector") + log.Info("committing sector: ", sid) ssize, err := m.SectorSize(ctx) if err != nil { @@ -21,6 +22,11 @@ func (m *Miner) SealSector(ctx context.Context, sid uint64) error { _ = ssize + log.Info("performing sector replication...") + if err := m.secst.SealPreCommit(ctx, sid); err != nil { + return xerrors.Errorf("seal pre commit failed: %w", err) + } + sinfo, err := m.secst.SectorStatus(sid) if err != nil { return xerrors.Errorf("failed to check status for sector %d: %w", sid, err) @@ -49,6 +55,7 @@ func (m *Miner) SealSector(ctx context.Context, sid uint64) error { GasPrice: types.NewInt(1), } + log.Info("submitting precommit for sector: ", sid) smsg, err := m.api.MpoolPushMessage(ctx, msg) if err != nil { return errors.Wrap(err, "pushing message to mpool") @@ -67,7 +74,13 @@ func (m *Miner) waitForPreCommitMessage(ctx context.Context, sid uint64, mcid ci return } + if mw.Receipt.ExitCode != 0 { + log.Error("sector precommit failed: ", mw.Receipt.ExitCode) + return + } + randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay + log.Infof("precommit for sector %d made it on chain, will start post computation at height %d", sid, randHeight) err = m.events.ChainAt(func(ts *types.TipSet, curH uint64) error { return m.scheduleComputeProof(ctx, sid, ts, randHeight) @@ -81,16 +94,17 @@ func (m *Miner) waitForPreCommitMessage(ctx context.Context, sid uint64, mcid ci } func (m *Miner) scheduleComputeProof(ctx context.Context, sid uint64, ts *types.TipSet, rheight uint64) error { + log.Info("scheduling post computation...") go func() { rand, err := m.api.ChainGetRandomness(ctx, ts, nil, int(ts.Height()-rheight)) if err != nil { - log.Error(errors.Errorf("failed to get randomness for computing seal proof: %w", err)) + log.Error(fmt.Errorf("failed to get randomness for computing seal proof: %w", err)) return } - proof, err := m.secst.SealComputeProof(ctx, sid, rand) + proof, err := m.secst.SealComputeProof(ctx, sid, rheight, rand) if err != nil { - log.Error(errors.Errorf("computing seal proof failed: %w", err)) + log.Error(fmt.Errorf("computing seal proof failed: %w", err)) return } diff --git a/storage/sector/store.go b/storage/sector/store.go index 3e498f052..414bf91ec 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -191,8 +191,18 @@ func (s *Store) SealPreCommit(ctx context.Context, sectorID uint64) error { return nil } -func (s *Store) SealComputeProof(ctx context.Context, sectorID uint64, rand []byte) ([]byte, error) { - panic("TODO") +func (s *Store) SealComputeProof(ctx context.Context, sectorID uint64, height uint64, rand []byte) ([]byte, error) { + var tick [32]byte + copy(tick[:], rand) + + sco, err := s.sb.SealCommit(sectorID, sectorbuilder.SealSeed{ + BlockHeight: height, + TicketBytes: tick, + }) + if err != nil { + return nil, err + } + return sco.Proof, nil } func (s *Store) WaitSeal(ctx context.Context, sector uint64) (sectorbuilder.SectorSealingStatus, error) { From 1583cf25938466082a4459dfa32ab3d901751d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 1 Nov 2019 11:05:48 +0100 Subject: [PATCH 012/114] Strip unused functionality from sectorstore --- lib/statestore/store.go | 3 +- storage/sector/store.go | 70 ++--------------------------------------- 2 files changed, 4 insertions(+), 69 deletions(-) diff --git a/lib/statestore/store.go b/lib/statestore/store.go index 50c5eeb61..bf884788a 100644 --- a/lib/statestore/store.go +++ b/lib/statestore/store.go @@ -13,7 +13,7 @@ type StateStore struct { } func New(ds datastore.Datastore) *StateStore { - return &StateStore{ds:ds} + return &StateStore{ds: ds} } func (st *StateStore) Begin(i cid.Cid, state interface{}) error { @@ -92,4 +92,3 @@ func (st *StateStore) List() ([]query.Entry, error) { return out, nil } - diff --git a/storage/sector/store.go b/storage/sector/store.go index 414bf91ec..855fe2c39 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -35,56 +35,18 @@ type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error) // TODO: eventually handle sector storage here instead of in rust-sectorbuilder type Store struct { - waitingLk sync.Mutex - sb *sectorbuilder.SectorBuilder tktFn TicketFn dealsLk sync.Mutex deals datastore.Datastore - - waiting map[uint64]chan struct{} - incoming []chan sectorbuilder.SectorSealingStatus - // TODO: outdated chan - - closeCh chan struct{} } func NewStore(sb *sectorbuilder.SectorBuilder, ds dtypes.MetadataDS, tktFn TicketFn) *Store { return &Store{ - sb: sb, - tktFn: tktFn, - deals: namespace.Wrap(ds, sectorDealsPrefix), - waiting: map[uint64]chan struct{}{}, - closeCh: make(chan struct{}), - } -} - -func (s *Store) restartSealing() { - sectors, err := s.sb.GetAllStagedSectors() - if err != nil { - return - } - - for _, sid := range sectors { - status, err := s.sb.SealStatus(sid) - if err != nil { - return - } - - if status.State != sealing_state.CommittingPaused { // TODO: Also handle PreCommit! - continue - } - - log.Infof("Sector %d is in paused state, resuming sealing", sid) - go func() { - // TODO: when we refactor wait-for-seal below, care about this output too - // (see SealSector below) - _, err := s.sb.ResumeSealCommit(sid) - if err != nil { - return - } - }() + sb: sb, + tktFn: tktFn, + deals: namespace.Wrap(ds, sectorDealsPrefix), } } @@ -103,13 +65,6 @@ func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64 return 0, err } - s.waitingLk.Lock() - _, exists := s.waiting[sectorID] - if !exists { // pieces can share sectors - s.waiting[sectorID] = make(chan struct{}) - } - s.waitingLk.Unlock() - s.dealsLk.Lock() defer s.dealsLk.Unlock() @@ -205,21 +160,6 @@ func (s *Store) SealComputeProof(ctx context.Context, sectorID uint64, height ui return sco.Proof, nil } -func (s *Store) WaitSeal(ctx context.Context, sector uint64) (sectorbuilder.SectorSealingStatus, error) { - s.waitingLk.Lock() - watch, ok := s.waiting[sector] - s.waitingLk.Unlock() - if ok { - select { - case <-watch: - case <-ctx.Done(): - return sectorbuilder.SectorSealingStatus{}, ctx.Err() - } - } - - return s.sb.SealStatus(sector) -} - func (s *Store) Commited() ([]sectorbuilder.SectorSealingStatus, error) { l, err := s.sb.GetAllStagedSectors() if err != nil { @@ -265,7 +205,3 @@ func (s *Store) RunPoSt(ctx context.Context, sectors []*api.SectorInfo, r []byte return s.sb.GeneratePoSt(ssi, seed, faults) } - -func (s *Store) Stop() { - close(s.closeCh) -} From 2343ebc5b81fae8b3c66f8143d7e0fa2bbff3347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 1 Nov 2019 12:07:05 +0100 Subject: [PATCH 013/114] statestore: Use reflect for mutators --- chain/deals/client.go | 12 ++++-- chain/deals/provider.go | 6 +-- chain/deals/state_store.go | 77 -------------------------------------- lib/statestore/store.go | 52 +++++++++++++++++++++---- 4 files changed, 55 insertions(+), 92 deletions(-) delete mode 100644 chain/deals/state_store.go diff --git a/chain/deals/client.go b/chain/deals/client.go index 3ea36c2e7..e89a9886f 100644 --- a/chain/deals/client.go +++ b/chain/deals/client.go @@ -46,7 +46,7 @@ type Client struct { discovery *discovery.Local mpool full.MpoolAPI - deals ClientStateStore + deals *statestore.StateStore conns map[cid.Cid]inet.Stream incoming chan *ClientDeal @@ -72,7 +72,7 @@ func NewClient(sm *stmgr.StateManager, chain *store.ChainStore, h host.Host, w * discovery: discovery, mpool: mpool, - deals: ClientStateStore{statestore.New(namespace.Wrap(ds, datastore.NewKey("/deals/client")))}, + deals: statestore.New(namespace.Wrap(ds, datastore.NewKey("/deals/client"))), conns: map[cid.Cid]inet.Stream{}, incoming: make(chan *ClientDeal, 16), @@ -130,7 +130,7 @@ func (c *Client) onIncoming(deal *ClientDeal) { func (c *Client) onUpdated(ctx context.Context, update clientDealUpdate) { log.Infof("Deal %s updated state to %d", update.id, update.newState) var deal ClientDeal - err := c.deals.MutateClient(update.id, func(d *ClientDeal) error { + err := c.deals.Mutate(update.id, func(d *ClientDeal) error { d.State = update.newState deal = *d return nil @@ -286,7 +286,11 @@ func (c *Client) QueryAsk(ctx context.Context, p peer.ID, a address.Address) (*t } func (c *Client) List() ([]ClientDeal, error) { - return c.deals.ListClient() + var out []ClientDeal + if err := c.deals.List(&out); err != nil { + return nil, err + } + return out, nil } func (c *Client) Stop() { diff --git a/chain/deals/provider.go b/chain/deals/provider.go index aa47a45c5..02966c05d 100644 --- a/chain/deals/provider.go +++ b/chain/deals/provider.go @@ -49,7 +49,7 @@ type Provider struct { // TODO: GC dag dtypes.StagingDAG - deals MinerStateStore + deals *statestore.StateStore ds dtypes.MetadataDS conns map[cid.Cid]inet.Stream @@ -96,7 +96,7 @@ func NewProvider(ds dtypes.MetadataDS, sminer *storage.Miner, dag dtypes.Staging actor: minerAddress, - deals: MinerStateStore{statestore.New(namespace.Wrap(ds, datastore.NewKey("/deals/client")))}, + deals: statestore.New(namespace.Wrap(ds, datastore.NewKey("/deals/client"))), ds: ds, } @@ -164,7 +164,7 @@ func (p *Provider) onUpdated(ctx context.Context, update minerDealUpdate) { return } var deal MinerDeal - err := p.deals.MutateMiner(update.id, func(d *MinerDeal) error { + err := p.deals.Mutate(update.id, func(d *MinerDeal) error { d.State = update.newState if update.mut != nil { update.mut(d) diff --git a/chain/deals/state_store.go b/chain/deals/state_store.go deleted file mode 100644 index b654816c6..000000000 --- a/chain/deals/state_store.go +++ /dev/null @@ -1,77 +0,0 @@ -package deals - -import ( - "bytes" - "github.com/filecoin-project/lotus/lib/statestore" - - "github.com/filecoin-project/lotus/lib/cborrpc" - "github.com/ipfs/go-cid" -) - -type MinerStateStore struct { - *statestore.StateStore -} - -func (st *MinerStateStore) MutateMiner(i cid.Cid, mutator func(*MinerDeal) error) error { - return st.Mutate(i, minerMutator(mutator)) -} - -func minerMutator(m func(*MinerDeal) error) func([]byte) ([]byte, error) { - return func(in []byte) ([]byte, error) { - deal := new(MinerDeal) - err := cborrpc.ReadCborRPC(bytes.NewReader(in), deal) - if err != nil { - return nil, err - } - - if err := m(deal); err != nil { - return nil, err - } - - return cborrpc.Dump(deal) - } -} - -type ClientStateStore struct { - *statestore.StateStore -} - -func (st *ClientStateStore) MutateClient(i cid.Cid, mutator func(*ClientDeal) error) error { - return st.Mutate(i, clientMutator(mutator)) -} - -func clientMutator(m func(*ClientDeal) error) func([]byte) ([]byte, error) { - return func(in []byte) ([]byte, error) { - deal := new(ClientDeal) - err := cborrpc.ReadCborRPC(bytes.NewReader(in), deal) - if err != nil { - return nil, err - } - - if err := m(deal); err != nil { - return nil, err - } - - return cborrpc.Dump(deal) - } -} - -func (st *ClientStateStore) ListClient() ([]ClientDeal, error) { - var out []ClientDeal - - l, err := st.List() - if err != nil { - return nil, err - } - for _, res := range l { - var deal ClientDeal - err := cborrpc.ReadCborRPC(bytes.NewReader(res.Value), &deal) - if err != nil { - return nil, err - } - - out = append(out, deal) - } - - return out, nil -} diff --git a/lib/statestore/store.go b/lib/statestore/store.go index bf884788a..10a4de9bc 100644 --- a/lib/statestore/store.go +++ b/lib/statestore/store.go @@ -1,11 +1,13 @@ package statestore import ( + "bytes" "github.com/filecoin-project/lotus/lib/cborrpc" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/query" "golang.org/x/xerrors" + "reflect" ) type StateStore struct { @@ -46,7 +48,33 @@ func (st *StateStore) End(i cid.Cid) error { return st.ds.Delete(k) } -func (st *StateStore) Mutate(i cid.Cid, mutator func([]byte) ([]byte, error)) error { +func cborMutator(mutator interface{}) func([]byte) ([]byte, error) { + rmut := reflect.ValueOf(mutator) + + return func(in []byte) ([]byte, error) { + state := reflect.New(rmut.Type().In(0).Elem()) + + err := cborrpc.ReadCborRPC(bytes.NewReader(in), state.Interface()) + if err != nil { + return nil, err + } + + out := rmut.Call([]reflect.Value{state}) + + if err := out[0].Interface().(error); err != nil { + return nil, err + } + + return cborrpc.Dump(state.Interface()) + } +} + +// mutator func(*T) error +func (st *StateStore) Mutate(i cid.Cid, mutator interface{}) error { + return st.mutate(i, cborMutator(mutator)) +} + +func (st *StateStore) mutate(i cid.Cid, mutator func([]byte) ([]byte, error)) error { k := datastore.NewKey(i.String()) has, err := st.ds.Has(k) if err != nil { @@ -69,26 +97,34 @@ func (st *StateStore) Mutate(i cid.Cid, mutator func([]byte) ([]byte, error)) er return st.ds.Put(k, mutated) } -func (st *StateStore) List() ([]query.Entry, error) { - var out []query.Entry - +// out: *[]T +func (st *StateStore) List(out interface{}) error { res, err := st.ds.Query(query.Query{}) if err != nil { - return nil, err + return err } defer res.Close() + outT := reflect.TypeOf(out).Elem().Elem() + rout := reflect.ValueOf(out) + for { res, ok := res.NextSync() if !ok { break } if res.Error != nil { - return nil, res.Error + return res.Error } - out = append(out, res.Entry) + elem := reflect.New(outT) + err := cborrpc.ReadCborRPC(bytes.NewReader(res.Value), elem.Interface()) + if err != nil { + return err + } + + rout.Set(reflect.Append(rout.Elem(), elem.Elem())) } - return out, nil + return nil } From 02c3be9099444669ddf781a3276b40475328ef72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 1 Nov 2019 12:14:32 +0100 Subject: [PATCH 014/114] statestore: More generic keys --- lib/statestore/store.go | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/statestore/store.go b/lib/statestore/store.go index 10a4de9bc..2fd4a4384 100644 --- a/lib/statestore/store.go +++ b/lib/statestore/store.go @@ -2,8 +2,8 @@ package statestore import ( "bytes" + "fmt" "github.com/filecoin-project/lotus/lib/cborrpc" - "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/query" "golang.org/x/xerrors" @@ -18,8 +18,19 @@ func New(ds datastore.Datastore) *StateStore { return &StateStore{ds: ds} } -func (st *StateStore) Begin(i cid.Cid, state interface{}) error { - k := datastore.NewKey(i.String()) +func toKey(k interface{}) datastore.Key { + switch t := k.(type) { + case uint64: + return datastore.NewKey(fmt.Sprint(t)) + case fmt.Stringer: + return datastore.NewKey(t.String()) + default: + panic("unexpected key type") + } +} + +func (st *StateStore) Begin(i interface{}, state interface{}) error { + k := toKey(i) has, err := st.ds.Has(k) if err != nil { return err @@ -36,8 +47,8 @@ func (st *StateStore) Begin(i cid.Cid, state interface{}) error { return st.ds.Put(k, b) } -func (st *StateStore) End(i cid.Cid) error { - k := datastore.NewKey(i.String()) +func (st *StateStore) End(i interface{}) error { + k := toKey(i) has, err := st.ds.Has(k) if err != nil { return err @@ -70,12 +81,12 @@ func cborMutator(mutator interface{}) func([]byte) ([]byte, error) { } // mutator func(*T) error -func (st *StateStore) Mutate(i cid.Cid, mutator interface{}) error { +func (st *StateStore) Mutate(i fmt.Stringer, mutator interface{}) error { return st.mutate(i, cborMutator(mutator)) } -func (st *StateStore) mutate(i cid.Cid, mutator func([]byte) ([]byte, error)) error { - k := datastore.NewKey(i.String()) +func (st *StateStore) mutate(i interface{}, mutator func([]byte) ([]byte, error)) error { + k := toKey(i) has, err := st.ds.Has(k) if err != nil { return err From 080a84970ccb6589f8c1ea2d5868c6150d06a20d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 1 Nov 2019 13:01:16 +0100 Subject: [PATCH 015/114] api: Split api files --- api/api_common.go | 52 +++++++++++++++++++++++++ api/{api.go => api_full.go} | 75 ------------------------------------- api/api_storage.go | 46 +++++++++++++++++++++++ 3 files changed, 98 insertions(+), 75 deletions(-) create mode 100644 api/api_common.go rename api/{api.go => api_full.go} (82%) create mode 100644 api/api_storage.go diff --git a/api/api_common.go b/api/api_common.go new file mode 100644 index 000000000..376aef86d --- /dev/null +++ b/api/api_common.go @@ -0,0 +1,52 @@ +package api + +import ( + "context" + "fmt" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + "github.com/filecoin-project/lotus/build" +) + +type Common interface { + // Auth + AuthVerify(ctx context.Context, token string) ([]Permission, error) + AuthNew(ctx context.Context, perms []Permission) ([]byte, error) + + // network + + NetConnectedness(context.Context, peer.ID) (network.Connectedness, error) + NetPeers(context.Context) ([]peer.AddrInfo, error) + NetConnect(context.Context, peer.AddrInfo) error + NetAddrsListen(context.Context) (peer.AddrInfo, error) + NetDisconnect(context.Context, peer.ID) error + + // ID returns peerID of libp2p node backing this API + ID(context.Context) (peer.ID, error) + + // Version provides information about API provider + Version(context.Context) (Version, error) +} + +// Version provides various build-time information +type Version struct { + Version string + + // APIVersion is a binary encoded semver version of the remote implementing + // this api + // + // See APIVersion in build/version.go + APIVersion uint32 + + // TODO: git commit / os / genesis cid? + + // Seconds + BlockDelay uint64 +} + +func (v Version) String() string { + vM, vm, vp := build.VersionInts(v.APIVersion) + return fmt.Sprintf("%s+api%d.%d.%d", v.Version, vM, vm, vp) +} \ No newline at end of file diff --git a/api/api.go b/api/api_full.go similarity index 82% rename from api/api.go rename to api/api_full.go index 635901ecb..e071a7066 100644 --- a/api/api.go +++ b/api/api_full.go @@ -2,46 +2,16 @@ package api import ( "context" - "fmt" - - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" "github.com/ipfs/go-cid" "github.com/ipfs/go-filestore" - cbor "github.com/ipfs/go-ipld-cbor" - "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" - "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/store" "github.com/filecoin-project/lotus/chain/types" ) -func init() { - cbor.RegisterCborType(SealedRef{}) -} - -type Common interface { - // Auth - AuthVerify(ctx context.Context, token string) ([]Permission, error) - AuthNew(ctx context.Context, perms []Permission) ([]byte, error) - - // network - - NetConnectedness(context.Context, peer.ID) (network.Connectedness, error) - NetPeers(context.Context) ([]peer.AddrInfo, error) - NetConnect(context.Context, peer.AddrInfo) error - NetAddrsListen(context.Context) (peer.AddrInfo, error) - NetDisconnect(context.Context, peer.ID) error - - // ID returns peerID of libp2p node backing this API - ID(context.Context) (peer.ID, error) - - // Version provides information about API provider - Version(context.Context) (Version, error) -} - // FullNode API is a low-level interface to the Filecoin network full node type FullNode interface { Common @@ -152,45 +122,6 @@ type FullNode interface { PaychVoucherSubmit(context.Context, address.Address, *types.SignedVoucher) (cid.Cid, error) } -// StorageMiner is a low-level interface to the Filecoin network storage miner node -type StorageMiner interface { - Common - - ActorAddress(context.Context) (address.Address, error) - - // Temp api for testing - StoreGarbageData(context.Context) error - - // Get the status of a given sector by ID - SectorsStatus(context.Context, uint64) (sectorbuilder.SectorSealingStatus, error) - - // List all staged sectors - SectorsList(context.Context) ([]uint64, error) - - SectorsRefs(context.Context) (map[string][]SealedRef, error) -} - -// Version provides various build-time information -type Version struct { - Version string - - // APIVersion is a binary encoded semver version of the remote implementing - // this api - // - // See APIVersion in build/version.go - APIVersion uint32 - - // TODO: git commit / os / genesis cid? - - // Seconds - BlockDelay uint64 -} - -func (v Version) String() string { - vM, vm, vp := build.VersionInts(v.APIVersion) - return fmt.Sprintf("%s+api%d.%d.%d", v.Version, vM, vm, vp) -} - type Import struct { Status filestore.Status Key cid.Cid @@ -275,12 +206,6 @@ type MinerPower struct { TotalPower types.BigInt } -type SealedRef struct { - Piece string - Offset uint64 - Size uint32 -} - type QueryOffer struct { Err string diff --git a/api/api_storage.go b/api/api_storage.go new file mode 100644 index 000000000..166f33b4a --- /dev/null +++ b/api/api_storage.go @@ -0,0 +1,46 @@ +package api + +import ( + "context" + + "github.com/filecoin-project/lotus/chain/address" + "github.com/filecoin-project/lotus/lib/sectorbuilder" +) + +type SectorState int + +const ( + Undefined SectorState = iota + + Empty // TODO: Is this useful + Packing // sector not in sealStore, and not on chain + + Unsealed // sealing / queued + PreCommitting // on chain pre-commit + PreCommitted // waiting for seed + Committing +) + +// StorageMiner is a low-level interface to the Filecoin network storage miner node +type StorageMiner interface { + Common + + ActorAddress(context.Context) (address.Address, error) + + // Temp api for testing + StoreGarbageData(context.Context) error + + // Get the status of a given sector by ID + SectorsStatus(context.Context, uint64) (sectorbuilder.SectorSealingStatus, error) + + // List all staged sectors + SectorsList(context.Context) ([]uint64, error) + + SectorsRefs(context.Context) (map[string][]SealedRef, error) +} + +type SealedRef struct { + Piece string + Offset uint64 + Size uint32 +} From 82344649d31b63f705d672212669d0068ce45229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 1 Nov 2019 14:58:48 +0100 Subject: [PATCH 016/114] Use state store for sectors --- api/api_common.go | 2 +- api/api_storage.go | 31 +++- chain/types/cbor_gen.go | 115 +++++++++++++ chain/types/tipset.go | 31 +++- gen/main.go | 11 ++ lib/statestore/store.go | 8 +- node/impl/storminer.go | 2 +- node/modules/storageminer.go | 1 + storage/cbor_gen.go | 319 +++++++++++++++++++++++++++++++++++ storage/miner.go | 39 +++-- storage/post.go | 12 +- storage/sealing.go | 236 +++++++++++--------------- storage/sector/store.go | 14 +- storage/sector_states.go | 183 ++++++++++++++++++++ 14 files changed, 830 insertions(+), 174 deletions(-) create mode 100644 storage/cbor_gen.go create mode 100644 storage/sector_states.go diff --git a/api/api_common.go b/api/api_common.go index 376aef86d..c83a4c260 100644 --- a/api/api_common.go +++ b/api/api_common.go @@ -49,4 +49,4 @@ type Version struct { func (v Version) String() string { vM, vm, vp := build.VersionInts(v.APIVersion) return fmt.Sprintf("%s+api%d.%d.%d", v.Version, vM, vm, vp) -} \ No newline at end of file +} diff --git a/api/api_storage.go b/api/api_storage.go index 166f33b4a..7a392455f 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -2,15 +2,17 @@ package api import ( "context" + "fmt" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/lib/sectorbuilder" ) -type SectorState int +// alias because cbor-gen doesn't like non-alias types +type SectorState = uint64 const ( - Undefined SectorState = iota + UndefinedSectorState SectorState = iota Empty // TODO: Is this useful Packing // sector not in sealStore, and not on chain @@ -19,8 +21,33 @@ const ( PreCommitting // on chain pre-commit PreCommitted // waiting for seed Committing + Proving + + SectorNoUpdate = UndefinedSectorState ) +func SectorStateStr(s SectorState) string { + switch s { + case UndefinedSectorState: + return "UndefinedSectorState" + case Empty: + return "Empty" + case Packing: + return "Packing" + case Unsealed: + return "Unsealed" + case PreCommitting: + return "PreCommitting" + case PreCommitted: + return "PreCommitted" + case Committing: + return "Committing" + case Proving: + return "Proving" + } + return fmt.Sprintf("", s) +} + // StorageMiner is a low-level interface to the Filecoin network storage miner node type StorageMiner interface { Common diff --git a/chain/types/cbor_gen.go b/chain/types/cbor_gen.go index ab63b28a1..cb9c85959 100644 --- a/chain/types/cbor_gen.go +++ b/chain/types/cbor_gen.go @@ -1470,3 +1470,118 @@ func (t *StorageAsk) UnmarshalCBOR(r io.Reader) error { t.SeqNo = extra return nil } + +func (t *ExpTipSet) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{131}); err != nil { + return err + } + + // t.t.Cids ([]cid.Cid) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Cids)))); err != nil { + return err + } + for _, v := range t.Cids { + if err := cbg.WriteCid(w, v); err != nil { + return xerrors.Errorf("failed writing cid field t.Cids: %w", err) + } + } + + // t.t.Blocks ([]*types.BlockHeader) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Blocks)))); err != nil { + return err + } + for _, v := range t.Blocks { + if err := v.MarshalCBOR(w); err != nil { + return err + } + } + + // t.t.Height (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.Height)); err != nil { + return err + } + return nil +} + +func (t *ExpTipSet) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 3 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.Cids ([]cid.Cid) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.Cids: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.Cids = make([]cid.Cid, extra) + } + for i := 0; i < int(extra); i++ { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("reading cid field t.Cids failed: %w", err) + } + t.Cids[i] = c + } + + // t.t.Blocks ([]*types.BlockHeader) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.Blocks: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.Blocks = make([]*BlockHeader, extra) + } + for i := 0; i < int(extra); i++ { + + var v BlockHeader + if err := v.UnmarshalCBOR(br); err != nil { + return err + } + + t.Blocks[i] = &v + } + + // t.t.Height (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Height = extra + return nil +} diff --git a/chain/types/tipset.go b/chain/types/tipset.go index 3733a6f09..0939fef1c 100644 --- a/chain/types/tipset.go +++ b/chain/types/tipset.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "io" "sort" "github.com/ipfs/go-cid" @@ -20,14 +21,14 @@ type TipSet struct { // why didnt i just export the fields? Because the struct has methods with the // same names already -type expTipSet struct { +type ExpTipSet struct { Cids []cid.Cid Blocks []*BlockHeader Height uint64 } func (ts *TipSet) MarshalJSON() ([]byte, error) { - return json.Marshal(expTipSet{ + return json.Marshal(ExpTipSet{ Cids: ts.cids, Blocks: ts.blks, Height: ts.height, @@ -35,7 +36,7 @@ func (ts *TipSet) MarshalJSON() ([]byte, error) { } func (ts *TipSet) UnmarshalJSON(b []byte) error { - var ets expTipSet + var ets ExpTipSet if err := json.Unmarshal(b, &ets); err != nil { return err } @@ -50,6 +51,30 @@ func (ts *TipSet) UnmarshalJSON(b []byte) error { return nil } +func (ts *TipSet) MarshalCBOR(w io.Writer) error { + return (&ExpTipSet{ + Cids: ts.cids, + Blocks: ts.blks, + Height: ts.height, + }).MarshalCBOR(w) +} + +func (ts *TipSet) UnmarshalCBOR(r io.Reader) error { + var ets ExpTipSet + if err := ets.UnmarshalCBOR(r); err != nil { + return err + } + + ots, err := NewTipSet(ets.Blocks) + if err != nil { + return err + } + + *ts = *ots + + return nil +} + func tipsetSortFunc(blks []*BlockHeader) func(i, j int) bool { return func(i, j int) bool { ti := blks[i].LastTicket() diff --git a/gen/main.go b/gen/main.go index a588dfadb..335aa0584 100644 --- a/gen/main.go +++ b/gen/main.go @@ -9,6 +9,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/deals" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/storage" ) func main() { @@ -26,6 +27,7 @@ func main() { types.BlockMsg{}, types.SignedStorageAsk{}, types.StorageAsk{}, + types.ExpTipSet{}, ) if err != nil { fmt.Println(err) @@ -109,4 +111,13 @@ func main() { fmt.Println(err) os.Exit(1) } + + err = gen.WriteTupleEncodersToFile("./storage/cbor_gen.go", "storage", + storage.SealTicket{}, + storage.SectorInfo{}, + ) + if err != nil { + fmt.Println(err) + os.Exit(1) + } } diff --git a/lib/statestore/store.go b/lib/statestore/store.go index 2fd4a4384..52734bd2b 100644 --- a/lib/statestore/store.go +++ b/lib/statestore/store.go @@ -3,11 +3,13 @@ package statestore import ( "bytes" "fmt" - "github.com/filecoin-project/lotus/lib/cborrpc" + "reflect" + "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/query" "golang.org/x/xerrors" - "reflect" + + "github.com/filecoin-project/lotus/lib/cborrpc" ) type StateStore struct { @@ -81,7 +83,7 @@ func cborMutator(mutator interface{}) func([]byte) ([]byte, error) { } // mutator func(*T) error -func (st *StateStore) Mutate(i fmt.Stringer, mutator interface{}) error { +func (st *StateStore) Mutate(i interface{}, mutator interface{}) error { return st.mutate(i, cborMutator(mutator)) } diff --git a/node/impl/storminer.go b/node/impl/storminer.go index b8b101ec3..d9ee34463 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -47,7 +47,7 @@ func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) error { return } - if err := sm.Miner.SealSector(ctx, sectorId); err != nil { + if err := sm.Miner.SealSector(context.TODO(), sectorId); err != nil { log.Error(err) return } diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 73d55c5d1..a7580f84c 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -90,6 +90,7 @@ func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api api.FullNode, h OnStart: func(context.Context) error { return sm.Run(ctx) }, + OnStop: sm.Stop, }) return sm, nil diff --git a/storage/cbor_gen.go b/storage/cbor_gen.go new file mode 100644 index 000000000..518db6692 --- /dev/null +++ b/storage/cbor_gen.go @@ -0,0 +1,319 @@ +package storage + +import ( + "fmt" + "github.com/filecoin-project/lotus/chain/types" + cbg "github.com/whyrusleeping/cbor-gen" + xerrors "golang.org/x/xerrors" + "io" +) + +/* This file was generated by github.com/whyrusleeping/cbor-gen */ + +var _ = xerrors.Errorf + +func (t *SealTicket) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{130}); err != nil { + return err + } + + // t.t.BlockHeight (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.BlockHeight)); err != nil { + return err + } + + // t.t.TicketBytes ([]uint8) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.TicketBytes)))); err != nil { + return err + } + if _, err := w.Write(t.TicketBytes); err != nil { + return err + } + return nil +} + +func (t *SealTicket) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 2 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.BlockHeight (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.BlockHeight = extra + // t.t.TicketBytes ([]uint8) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.TicketBytes: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.TicketBytes = make([]byte, extra) + if _, err := io.ReadFull(br, t.TicketBytes); err != nil { + return err + } + return nil +} + +func (t *SectorInfo) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{137}); err != nil { + return err + } + + // t.t.State (api.SectorState) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.State)); err != nil { + return err + } + + // t.t.SectorID (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.SectorID)); err != nil { + return err + } + + // t.t.CommD ([]uint8) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommD)))); err != nil { + return err + } + if _, err := w.Write(t.CommD); err != nil { + return err + } + + // t.t.CommR ([]uint8) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommR)))); err != nil { + return err + } + if _, err := w.Write(t.CommR); err != nil { + return err + } + + // t.t.Ticket (storage.SealTicket) + if err := t.Ticket.MarshalCBOR(w); err != nil { + return err + } + + // t.t.PreCommitMessage (cid.Cid) + + if t.PreCommitMessage == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.PreCommitMessage); err != nil { + return xerrors.Errorf("failed to write cid field t.PreCommitMessage: %w", err) + } + } + + // t.t.RandHeight (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.RandHeight)); err != nil { + return err + } + + // t.t.RandTs (types.TipSet) + if err := t.RandTs.MarshalCBOR(w); err != nil { + return err + } + + // t.t.CommitMessage (cid.Cid) + + if t.CommitMessage == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.CommitMessage); err != nil { + return xerrors.Errorf("failed to write cid field t.CommitMessage: %w", err) + } + } + + return nil +} + +func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 9 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.State (api.SectorState) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.State = extra + // t.t.SectorID (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.SectorID = extra + // t.t.CommD ([]uint8) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.CommD: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommD = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommD); err != nil { + return err + } + // t.t.CommR ([]uint8) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.CommR: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommR = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommR); err != nil { + return err + } + // t.t.Ticket (storage.SealTicket) + + { + + if err := t.Ticket.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.t.PreCommitMessage (cid.Cid) + + { + + pb, err := br.PeekByte() + if err != nil { + return err + } + if pb == cbg.CborNull[0] { + var nbuf [1]byte + if _, err := br.Read(nbuf[:]); err != nil { + return err + } + } else { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.PreCommitMessage: %w", err) + } + + t.PreCommitMessage = &c + } + + } + // t.t.RandHeight (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.RandHeight = extra + // t.t.RandTs (types.TipSet) + + { + + pb, err := br.PeekByte() + if err != nil { + return err + } + if pb == cbg.CborNull[0] { + var nbuf [1]byte + if _, err := br.Read(nbuf[:]); err != nil { + return err + } + } else { + t.RandTs = new(types.TipSet) + if err := t.RandTs.UnmarshalCBOR(br); err != nil { + return err + } + } + + } + // t.t.CommitMessage (cid.Cid) + + { + + pb, err := br.PeekByte() + if err != nil { + return err + } + if pb == cbg.CborNull[0] { + var nbuf [1]byte + if _, err := br.Read(nbuf[:]); err != nil { + return err + } + } else { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.CommitMessage: %w", err) + } + + t.CommitMessage = &c + } + + } + return nil +} diff --git a/storage/miner.go b/storage/miner.go index bb3be8f8c..18449a42c 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -2,6 +2,8 @@ package storage import ( "context" + "github.com/filecoin-project/lotus/lib/statestore" + "github.com/ipfs/go-datastore/namespace" "sync" "github.com/ipfs/go-cid" @@ -15,7 +17,6 @@ import ( "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/storage/sector" ) @@ -26,19 +27,23 @@ const PoStConfidence = 3 type Miner struct { api storageMinerApi events *events.Events + h host.Host + secst *sector.Store - secst *sector.Store - - maddr address.Address - + maddr address.Address worker address.Address - h host.Host - - ds datastore.Batching - - schedLk sync.Mutex + // PoSt + postLk sync.Mutex schedPost uint64 + + // Sealing + sectors *statestore.StateStore + + sectorIncoming chan *SectorInfo + sectorUpdated chan sectorUpdate + stop chan struct{} + stopped chan struct{} } type storageMinerApi interface { @@ -72,8 +77,9 @@ func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datasto maddr: addr, h: h, - ds: ds, secst: secst, + + sectors: statestore.New(namespace.Wrap(ds, datastore.NewKey("/sectors"))), }, nil } @@ -85,11 +91,18 @@ func (m *Miner) Run(ctx context.Context) error { m.events = events.NewEvents(ctx, m.api) go m.beginPosting(ctx) + go m.sectorStateLoop(ctx) return nil } -func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSealingStatus) error { - return m.SealSector(ctx, sinfo.SectorID) +func (m *Miner) Stop(ctx context.Context) error { + close(m.stop) + select { + case <-m.stopped: + return nil + case <-ctx.Done(): + return ctx.Err() + } } func (m *Miner) runPreflightChecks(ctx context.Context) error { diff --git a/storage/post.go b/storage/post.go index ee024acbb..9d3f892a7 100644 --- a/storage/post.go +++ b/storage/post.go @@ -30,10 +30,10 @@ func (m *Miner) beginPosting(ctx context.Context) { return } - m.schedLk.Lock() + m.postLk.Lock() if m.schedPost > 0 { log.Warnf("PoSts already running %d", m.schedPost) - m.schedLk.Unlock() + m.postLk.Unlock() return } @@ -42,7 +42,7 @@ func (m *Miner) beginPosting(ctx context.Context) { ppe, _ = actors.ProvingPeriodEnd(ppe, ts.Height()+1) m.schedPost = ppe - m.schedLk.Unlock() + m.postLk.Unlock() log.Infof("Scheduling post at height %d", ppe-build.PoStChallangeTime) err = m.events.ChainAt(m.computePost(m.schedPost), func(ts *types.TipSet) error { // Revert @@ -71,16 +71,16 @@ func (m *Miner) scheduleNextPost(ppe uint64) { ppe = headPPE } - m.schedLk.Lock() + m.postLk.Lock() if m.schedPost >= ppe { // this probably can't happen log.Errorw("PoSt already scheduled", "schedPost", m.schedPost, "ppe", ppe) - m.schedLk.Unlock() + m.postLk.Unlock() return } m.schedPost = ppe - m.schedLk.Unlock() + m.postLk.Unlock() log.Infow("scheduling PoSt", "post-height", ppe-build.PoStChallangeTime, "height", ts.Height(), "ppe", ppe, "proving-period", provingPeriod) diff --git a/storage/sealing.go b/storage/sealing.go index 2a3d02d7f..651dbf6ca 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -2,154 +2,120 @@ package storage import ( "context" - "fmt" - - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" cid "github.com/ipfs/go-cid" - "github.com/pkg/errors" - "golang.org/x/xerrors" ) -func (m *Miner) SealSector(ctx context.Context, sid uint64) error { - log.Info("committing sector: ", sid) - - ssize, err := m.SectorSize(ctx) - if err != nil { - return xerrors.Errorf("failed to check out own sector size: %w", err) - } - - _ = ssize - - log.Info("performing sector replication...") - if err := m.secst.SealPreCommit(ctx, sid); err != nil { - return xerrors.Errorf("seal pre commit failed: %w", err) - } - - sinfo, err := m.secst.SectorStatus(sid) - if err != nil { - return xerrors.Errorf("failed to check status for sector %d: %w", sid, err) - } - - params := &actors.SectorPreCommitInfo{ - CommD: sinfo.CommD[:], - CommR: sinfo.CommR[:], - Epoch: sinfo.Ticket.BlockHeight, - - //DealIDs: deals, - SectorNumber: sinfo.SectorID, - } - enc, aerr := actors.SerializeParams(params) - if aerr != nil { - return errors.Wrap(aerr, "could not serialize commit sector parameters") - } - - msg := &types.Message{ - To: m.maddr, - From: m.worker, - Method: actors.MAMethods.PreCommitSector, - Params: enc, - Value: types.NewInt(0), // TODO: need to ensure sufficient collateral - GasLimit: types.NewInt(1000000 /* i dont know help */), - GasPrice: types.NewInt(1), - } - - log.Info("submitting precommit for sector: ", sid) - smsg, err := m.api.MpoolPushMessage(ctx, msg) - if err != nil { - return errors.Wrap(err, "pushing message to mpool") - } - - go m.waitForPreCommitMessage(context.TODO(), sinfo.SectorID, smsg.Cid()) - - // TODO: maybe return a wait channel? - return nil +type SealTicket struct { + BlockHeight uint64 + TicketBytes []byte } -func (m *Miner) waitForPreCommitMessage(ctx context.Context, sid uint64, mcid cid.Cid) { - // would be ideal to just use the events.Called handler, but it wouldnt be able to handle individual message timeouts - mw, err := m.api.StateWaitMsg(ctx, mcid) - if err != nil { - return - } +type SectorInfo struct { + State api.SectorState + SectorID uint64 - if mw.Receipt.ExitCode != 0 { - log.Error("sector precommit failed: ", mw.Receipt.ExitCode) - return - } + // PreCommit + CommD []byte + CommR []byte + Ticket SealTicket - randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay - log.Infof("precommit for sector %d made it on chain, will start post computation at height %d", sid, randHeight) + PreCommitMessage *cid.Cid - err = m.events.ChainAt(func(ts *types.TipSet, curH uint64) error { - return m.scheduleComputeProof(ctx, sid, ts, randHeight) - }, func(ts *types.TipSet) error { - log.Warn("revert in interactive commit sector step") - return nil - }, 3, mw.TipSet.Height()+build.InteractivePoRepDelay) - if err != nil { - log.Warn("waitForPreCommitMessage ChainAt errored: ", err) - } + // PreCommitted + RandHeight uint64 + RandTs *types.TipSet + + // Committing + CommitMessage *cid.Cid } -func (m *Miner) scheduleComputeProof(ctx context.Context, sid uint64, ts *types.TipSet, rheight uint64) error { - log.Info("scheduling post computation...") +type sectorUpdate struct { + newState api.SectorState + id uint64 + err error + mut func(*SectorInfo) +} + +func (m *Miner) sectorStateLoop(ctx context.Context) { + // TODO: restore state + go func() { - rand, err := m.api.ChainGetRandomness(ctx, ts, nil, int(ts.Height()-rheight)) - if err != nil { - log.Error(fmt.Errorf("failed to get randomness for computing seal proof: %w", err)) - return - } + defer log.Warn("quitting deal provider loop") + defer close(m.stopped) - proof, err := m.secst.SealComputeProof(ctx, sid, rheight, rand) - if err != nil { - log.Error(fmt.Errorf("computing seal proof failed: %w", err)) - return + for { + select { + case sector := <-m.sectorIncoming: + m.onSectorIncoming(sector) + case update := <-m.sectorUpdated: + m.onSectorUpdated(ctx, update) + case <-m.stop: + return + } } - - params := &actors.SectorProveCommitInfo{ - Proof: proof, - SectorID: sid, - //DealIDs: deals, - } - - _ = params - enc, aerr := actors.SerializeParams(nil) - if aerr != nil { - log.Error(errors.Wrap(aerr, "could not serialize commit sector parameters")) - return - } - - msg := &types.Message{ - To: m.maddr, - From: m.worker, - Method: actors.MAMethods.ProveCommitSector, - Params: enc, - Value: types.NewInt(0), // TODO: need to ensure sufficient collateral - GasLimit: types.NewInt(1000000 /* i dont know help */), - GasPrice: types.NewInt(1), - } - - smsg, err := m.api.MpoolPushMessage(ctx, msg) - if err != nil { - log.Error(errors.Wrap(err, "pushing message to mpool")) - } - - // TODO: now wait for this to get included and handle errors? - mw, err := m.api.StateWaitMsg(ctx, smsg.Cid()) - if err != nil { - log.Errorf("failed to wait for porep inclusion: %s", err) - return - } - - if mw.Receipt.ExitCode != 0 { - log.Error("UNHANDLED: submitting sector proof failed") - return - } - - m.beginPosting(ctx) }() - - return nil +} + +func (m *Miner) onSectorIncoming(sector *SectorInfo) { + if err := m.sectors.Begin(sector.SectorID, sector); err != nil { + // We may have re-sent the proposal + log.Errorf("deal tracking failed: %s", err) + m.failSector(sector.SectorID, err) + return + } + + go func() { + m.sectorUpdated <- sectorUpdate{ + newState: api.Unsealed, + id: sector.SectorID, + } + }() +} + +func (m *Miner) onSectorUpdated(ctx context.Context, update sectorUpdate) { + log.Infof("Sector %s updated state to %s", update.id, api.SectorStateStr(update.newState)) + var sector SectorInfo + err := m.sectors.Mutate(update.id, func(s *SectorInfo) error { + s.State = update.newState + sector = *s + return nil + }) + if update.err != nil { + log.Errorf("deal %s failed: %s", update.id, update.err) + m.failSector(update.id, update.err) + return + } + if err != nil { + m.failSector(update.id, err) + return + } + + switch update.newState { + case api.Unsealed: + m.handle(ctx, sector, m.sealPreCommit, api.PreCommitting) + case api.PreCommitting: + m.handle(ctx, sector, m.preCommit, api.PreCommitted) + case api.PreCommitted: + m.handle(ctx, sector, m.preCommitted, api.SectorNoUpdate) + case api.Committing: + m.handle(ctx, sector, m.committing, api.Proving) + } +} + +func (m *Miner) failSector(id uint64, err error) { + panic(err) // todo: better error handling strategy +} + +func (m *Miner) SealSector(ctx context.Context, sid uint64) error { + select { + case m.sectorIncoming <- &SectorInfo{ + State: api.UndefinedSectorState, + SectorID: sid, + }: + return nil + case <-ctx.Done(): + return ctx.Err() + } } diff --git a/storage/sector/store.go b/storage/sector/store.go index 855fe2c39..52c45deef 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -131,19 +131,13 @@ func (s *Store) DealsForCommit(sectorID uint64) ([]uint64, error) { } } -func (s *Store) SealPreCommit(ctx context.Context, sectorID uint64) error { +func (s *Store) SealPreCommit(ctx context.Context, sectorID uint64) (sectorbuilder.SealPreCommitOutput, error) { tkt, err := s.tktFn(ctx) if err != nil { - return err + return sectorbuilder.SealPreCommitOutput{}, err } - // TODO: That's not async, is it? - // - If not then we probably can drop this wait-for-seal hack below - _, err = s.sb.SealPreCommit(sectorID, *tkt) - if err != nil { - return err - } - return nil + return s.sb.SealPreCommit(sectorID, *tkt) } func (s *Store) SealComputeProof(ctx context.Context, sectorID uint64, height uint64, rand []byte) ([]byte, error) { @@ -160,7 +154,7 @@ func (s *Store) SealComputeProof(ctx context.Context, sectorID uint64, height ui return sco.Proof, nil } -func (s *Store) Commited() ([]sectorbuilder.SectorSealingStatus, error) { +func (s *Store) Committed() ([]sectorbuilder.SectorSealingStatus, error) { l, err := s.sb.GetAllStagedSectors() if err != nil { return nil, err diff --git a/storage/sector_states.go b/storage/sector_states.go new file mode 100644 index 000000000..ce4a8b28c --- /dev/null +++ b/storage/sector_states.go @@ -0,0 +1,183 @@ +package storage + +import ( + "context" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/types" + "github.com/pkg/errors" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/api" +) + +type providerHandlerFunc func(ctx context.Context, deal SectorInfo) (func(*SectorInfo), error) + +func (m *Miner) handle(ctx context.Context, sector SectorInfo, cb providerHandlerFunc, next api.SectorState) { + go func() { + mut, err := cb(ctx, sector) + + if err == nil && next == api.SectorNoUpdate { + return + } + + select { + case m.sectorUpdated <- sectorUpdate{ + newState: next, + id: sector.SectorID, + err: err, + mut: mut, + }: + case <-m.stop: + } + }() +} + +func (m *Miner) sealPreCommit(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { + log.Infow("performing sector replication...", "sector", sector.SectorID) + sinfo, err := m.secst.SealPreCommit(ctx, sector.SectorID) + if err != nil { + return nil, xerrors.Errorf("seal pre commit failed: %w", err) + } + + return func(info *SectorInfo) { + info.CommD = sinfo.CommD[:] + info.CommR = sinfo.CommR[:] + info.Ticket = SealTicket{ + BlockHeight: sinfo.Ticket.BlockHeight, + TicketBytes: sinfo.Ticket.TicketBytes[:], + } + }, nil +} + +func (m *Miner) preCommit(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { + params := &actors.SectorPreCommitInfo{ + CommD: sector.CommD, + CommR: sector.CommR, + Epoch: sector.Ticket.BlockHeight, + + SectorNumber: sector.SectorID, + } + enc, aerr := actors.SerializeParams(params) + if aerr != nil { + return nil, xerrors.Errorf("could not serialize commit sector parameters: %w", aerr) + } + + msg := &types.Message{ + To: m.maddr, + From: m.worker, + Method: actors.MAMethods.PreCommitSector, + Params: enc, + Value: types.NewInt(0), // TODO: need to ensure sufficient collateral + GasLimit: types.NewInt(1000000 /* i dont know help */), + GasPrice: types.NewInt(1), + } + + log.Info("submitting precommit for sector: ", sector.SectorID) + smsg, err := m.api.MpoolPushMessage(ctx, msg) + if err != nil { + return nil, xerrors.Errorf("pushing message to mpool: %w", err) + } + + return func(info *SectorInfo) { + mcid := smsg.Cid() + info.PreCommitMessage = &mcid + }, nil +} + +func (m *Miner) preCommitted(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { + // would be ideal to just use the events.Called handler, but it wouldnt be able to handle individual message timeouts + mw, err := m.api.StateWaitMsg(ctx, *sector.PreCommitMessage) + if err != nil { + return nil, err + } + + if mw.Receipt.ExitCode != 0 { + log.Error("sector precommit failed: ", mw.Receipt.ExitCode) + return nil, err + } + + randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay + log.Infof("precommit for sector %d made it on chain, will start post computation at height %d", sector.SectorID, randHeight) + + err = m.events.ChainAt(func(ts *types.TipSet, curH uint64) error { + m.sectorUpdated <- sectorUpdate{ + newState: api.Committing, + id: sector.SectorID, + mut: func(info *SectorInfo) { + info.RandHeight = randHeight + info.RandTs = ts + }, + } + + return nil + }, func(ts *types.TipSet) error { + log.Warn("revert in interactive commit sector step") + return nil + }, 3, mw.TipSet.Height()+build.InteractivePoRepDelay) + if err != nil { + log.Warn("waitForPreCommitMessage ChainAt errored: ", err) + } + + return nil, nil +} + +func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { + log.Info("scheduling seal proof computation...") + + rand, err := m.api.ChainGetRandomness(ctx, sector.RandTs, nil, int(sector.RandTs.Height()-sector.RandHeight)) + if err != nil { + return nil, xerrors.Errorf("failed to get randomness for computing seal proof: %w", err) + } + + proof, err := m.secst.SealComputeProof(ctx, sector.SectorID, sector.RandHeight, rand) + if err != nil { + return nil, xerrors.Errorf("computing seal proof failed: %w", err) + } + + params := &actors.SectorProveCommitInfo{ + Proof: proof, + SectorID: sector.SectorID, + //DealIDs: deals, + } + + _ = params + enc, aerr := actors.SerializeParams(nil) + if aerr != nil { + return nil, xerrors.Errorf("could not serialize commit sector parameters: %w", aerr) + } + + msg := &types.Message{ + To: m.maddr, + From: m.worker, + Method: actors.MAMethods.ProveCommitSector, + Params: enc, + Value: types.NewInt(0), // TODO: need to ensure sufficient collateral + GasLimit: types.NewInt(1000000 /* i dont know help */), + GasPrice: types.NewInt(1), + } + + smsg, err := m.api.MpoolPushMessage(ctx, msg) + if err != nil { + log.Error(errors.Wrap(err, "pushing message to mpool")) + } + + // TODO: Separate state before this wait, so we persist message cid? + + mw, err := m.api.StateWaitMsg(ctx, smsg.Cid()) + if err != nil { + return nil, xerrors.Errorf("failed to wait for porep inclusion: %w", err) + } + + if mw.Receipt.ExitCode != 0 { + log.Error("UNHANDLED: submitting sector proof failed") + return nil, xerrors.New("UNHANDLED: submitting sector proof failed") + } + + m.beginPosting(ctx) + + return func(info *SectorInfo) { + mcid := smsg.Cid() + info.CommitMessage = &mcid + }, nil +} From a13dfcf96ba03f231f731f2ba996c0c437772ca7 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Fri, 1 Nov 2019 13:27:59 -0700 Subject: [PATCH 017/114] Add extra check sanity check for timing --- chain/actors/actor_miner.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index e18fda36c..a642beba0 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -308,6 +308,11 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC if !ok { return nil, aerrors.New(1, "no pre-commitment found for sector") } + + if us.SubmitHeight+build.InteractivePoRepDelay > vmctx.BlockHeight() { + return nil, aerrors.New(2, "too early for proof submission") + } + delete(self.PreCommittedSectors, uintToStringKey(params.SectorID)) // TODO: ensure normalization to ID address From 2fe1b5a538ad1a6369044d659c0891532dc543b4 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Fri, 1 Nov 2019 15:05:05 -0700 Subject: [PATCH 018/114] some cleanup --- storage/sealing.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/storage/sealing.go b/storage/sealing.go index 651dbf6ca..cb377172a 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -2,9 +2,11 @@ package storage import ( "context" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" cid "github.com/ipfs/go-cid" + xerrors "golang.org/x/xerrors" ) type SealTicket struct { @@ -67,9 +69,13 @@ func (m *Miner) onSectorIncoming(sector *SectorInfo) { } go func() { - m.sectorUpdated <- sectorUpdate{ + select { + case m.sectorUpdated <- sectorUpdate{ newState: api.Unsealed, id: sector.SectorID, + }: + case <-m.stop: + log.Warn("failed to send incoming sector update, miner shutting down") } }() } @@ -109,13 +115,14 @@ func (m *Miner) failSector(id uint64, err error) { } func (m *Miner) SealSector(ctx context.Context, sid uint64) error { - select { - case m.sectorIncoming <- &SectorInfo{ + si := &SectorInfo{ State: api.UndefinedSectorState, SectorID: sid, - }: + } + select { + case m.sectorIncoming <- si: return nil case <-ctx.Done(): - return ctx.Err() + return xerrors.Errorf("failed to submit sector for sealing, queue full: %w", ctx.Err()) } } From 1dcebece719b856e88d4477f2caf943e2839f60a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 1 Nov 2019 23:44:55 +0100 Subject: [PATCH 019/114] Some smaller fixes --- chain/actors/actor_miner.go | 2 +- chain/types/tipset.go | 5 +++++ lib/statestore/store.go | 4 ++-- lotuspond/front/src/StorageNode.js | 13 ++++++++----- storage/cbor_gen.go | 4 ++-- storage/miner.go | 5 +++++ storage/sealing.go | 10 ++++++++-- 7 files changed, 31 insertions(+), 12 deletions(-) diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index a642beba0..46ab1b00e 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -228,7 +228,7 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon } if params.Epoch >= vmctx.BlockHeight() { - return nil, aerrors.New(1, "sector commitment must be based off past randomness") + return nil, aerrors.Newf(1, "sector commitment must be based off past randomness (%d >= %d)", params.Epoch, vmctx.BlockHeight()) } if vmctx.BlockHeight()-params.Epoch > 1000 { diff --git a/chain/types/tipset.go b/chain/types/tipset.go index 0939fef1c..1836fe813 100644 --- a/chain/types/tipset.go +++ b/chain/types/tipset.go @@ -9,6 +9,7 @@ import ( "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log" + cbg "github.com/whyrusleeping/cbor-gen" ) var log = logging.Logger("types") @@ -52,6 +53,10 @@ func (ts *TipSet) UnmarshalJSON(b []byte) error { } func (ts *TipSet) MarshalCBOR(w io.Writer) error { + if ts == nil { + _, err := w.Write(cbg.CborNull) + return err + } return (&ExpTipSet{ Cids: ts.cids, Blocks: ts.blks, diff --git a/lib/statestore/store.go b/lib/statestore/store.go index 52734bd2b..f578c17e3 100644 --- a/lib/statestore/store.go +++ b/lib/statestore/store.go @@ -74,8 +74,8 @@ func cborMutator(mutator interface{}) func([]byte) ([]byte, error) { out := rmut.Call([]reflect.Value{state}) - if err := out[0].Interface().(error); err != nil { - return nil, err + if err := out[0].Interface(); err != nil { + return nil, err.(error) } return cborrpc.Dump(state.Interface()) diff --git a/lotuspond/front/src/StorageNode.js b/lotuspond/front/src/StorageNode.js index 741932db9..ef50c615d 100644 --- a/lotuspond/front/src/StorageNode.js +++ b/lotuspond/front/src/StorageNode.js @@ -9,12 +9,15 @@ const stateGettingToken = 'getting-token' let sealCodes = [ "Unknown", - "Pending", + "AcceptingPieces", + "Committed", + "Committing", + "CommittingPaused", "Failed", - "Sealing", - "Sealed", - "Paused", - "ReadyForSealing", + "FullyPacked", + "PreCommitted", + "PreCommitting", + "PreCommittingPaused", ] class StorageNode extends React.Component { diff --git a/storage/cbor_gen.go b/storage/cbor_gen.go index 518db6692..38e70c020 100644 --- a/storage/cbor_gen.go +++ b/storage/cbor_gen.go @@ -90,7 +90,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.t.State (api.SectorState) + // t.t.State (uint64) if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.State)); err != nil { return err } @@ -173,7 +173,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input had wrong number of fields") } - // t.t.State (api.SectorState) + // t.t.State (uint64) maj, extra, err = cbg.CborReadHeader(br) if err != nil { diff --git a/storage/miner.go b/storage/miner.go index 18449a42c..4cec6c94b 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -80,6 +80,11 @@ func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datasto secst: secst, sectors: statestore.New(namespace.Wrap(ds, datastore.NewKey("/sectors"))), + + sectorIncoming: make(chan *SectorInfo), + sectorUpdated: make(chan sectorUpdate), + stop: make(chan struct{}), + stopped: make(chan struct{}), }, nil } diff --git a/storage/sealing.go b/storage/sealing.go index cb377172a..d1883be3d 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -81,15 +81,18 @@ func (m *Miner) onSectorIncoming(sector *SectorInfo) { } func (m *Miner) onSectorUpdated(ctx context.Context, update sectorUpdate) { - log.Infof("Sector %s updated state to %s", update.id, api.SectorStateStr(update.newState)) + log.Infof("Sector %d updated state to %s", update.id, api.SectorStateStr(update.newState)) var sector SectorInfo err := m.sectors.Mutate(update.id, func(s *SectorInfo) error { s.State = update.newState + if update.mut != nil { + update.mut(s) + } sector = *s return nil }) if update.err != nil { - log.Errorf("deal %s failed: %s", update.id, update.err) + log.Errorf("sector %d failed: %s", update.id, update.err) m.failSector(update.id, update.err) return } @@ -111,10 +114,13 @@ func (m *Miner) onSectorUpdated(ctx context.Context, update sectorUpdate) { } func (m *Miner) failSector(id uint64, err error) { + log.Error(err) panic(err) // todo: better error handling strategy } func (m *Miner) SealSector(ctx context.Context, sid uint64) error { + log.Infof("Begin sealing sector %d", sid) + si := &SectorInfo{ State: api.UndefinedSectorState, SectorID: sid, From 3bc4a5dddf989b8e4fc2d88d06301d111eabea77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 2 Nov 2019 00:43:54 +0100 Subject: [PATCH 020/114] More progress on fixing storing garbage data --- build/params.go | 2 +- chain/actors/actor_miner.go | 8 +- chain/actors/cbor_gen.go | 109 +++++++++++++++++++++++++++ gen/main.go | 1 + node/impl/storminer.go | 29 +------- node/modules/storageminer.go | 2 +- storage/garbage.go | 140 +++++++++++++++++++++++++++++++++++ storage/miner.go | 1 + storage/sector_states.go | 10 ++- 9 files changed, 266 insertions(+), 36 deletions(-) create mode 100644 storage/garbage.go diff --git a/build/params.go b/build/params.go index f69fb05ef..ef55c01bd 100644 --- a/build/params.go +++ b/build/params.go @@ -37,7 +37,7 @@ const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours // Consensus / Network // Seconds -const BlockDelay = 10 +const BlockDelay = 2 // Seconds const AllowableClockDrift = BlockDelay * 2 diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index 46ab1b00e..010d32729 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -227,11 +227,11 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon return nil, err } - if params.Epoch >= vmctx.BlockHeight() { - return nil, aerrors.Newf(1, "sector commitment must be based off past randomness (%d >= %d)", params.Epoch, vmctx.BlockHeight()) + if params.Epoch >= vmctx.BlockHeight()+build.SealRandomnessLookback { + return nil, aerrors.Newf(1, "sector commitment must be based off past randomness (%d >= %d)", params.Epoch, vmctx.BlockHeight()+build.SealRandomnessLookback) } - if vmctx.BlockHeight()-params.Epoch > 1000 { + if vmctx.BlockHeight()-params.Epoch+build.SealRandomnessLookback > 1000 { return nil, aerrors.New(2, "sector commitment must be recent enough") } @@ -318,7 +318,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC // TODO: ensure normalization to ID address maddr := vmctx.Message().To - ticket, err := vmctx.GetRandomness(us.TicketEpoch) + ticket, err := vmctx.GetRandomness(us.TicketEpoch - build.SealRandomnessLookback) if err != nil { return nil, aerrors.Wrap(err, "failed to get ticket randomness") } diff --git a/chain/actors/cbor_gen.go b/chain/actors/cbor_gen.go index 63202da1a..03a59bd4a 100644 --- a/chain/actors/cbor_gen.go +++ b/chain/actors/cbor_gen.go @@ -3771,3 +3771,112 @@ func (t *ComputeDataCommitmentParams) UnmarshalCBOR(r io.Reader) error { t.SectorSize = extra return nil } + +func (t *SectorProveCommitInfo) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{131}); err != nil { + return err + } + + // t.t.Proof ([]uint8) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil { + return err + } + if _, err := w.Write(t.Proof); err != nil { + return err + } + + // t.t.SectorID (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.SectorID)); err != nil { + return err + } + + // t.t.DealIDs ([]uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { + return err + } + for _, v := range t.DealIDs { + if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { + return err + } + } + return nil +} + +func (t *SectorProveCommitInfo) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 3 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.Proof ([]uint8) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.Proof: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.Proof = make([]byte, extra) + if _, err := io.ReadFull(br, t.Proof); err != nil { + return err + } + // t.t.SectorID (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.SectorID = extra + // t.t.DealIDs ([]uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.DealIDs: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.DealIDs = make([]uint64, extra) + } + for i := 0; i < int(extra); i++ { + + maj, val, err := cbg.CborReadHeader(br) + if err != nil { + return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) + } + + if maj != cbg.MajUnsignedInt { + return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) + } + + t.DealIDs[i] = val + } + + return nil +} diff --git a/gen/main.go b/gen/main.go index 335aa0584..2d8d10e26 100644 --- a/gen/main.go +++ b/gen/main.go @@ -91,6 +91,7 @@ func main() { actors.ProcessStorageDealsPaymentParams{}, actors.OnChainDeal{}, actors.ComputeDataCommitmentParams{}, + actors.SectorProveCommitInfo{}, ) if err != nil { fmt.Println(err) diff --git a/node/impl/storminer.go b/node/impl/storminer.go index d9ee34463..e6bae6a22 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -2,9 +2,6 @@ package impl import ( "context" - "fmt" - "io" - "math/rand" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/address" @@ -12,8 +9,6 @@ import ( "github.com/filecoin-project/lotus/storage" "github.com/filecoin-project/lotus/storage/sector" "github.com/filecoin-project/lotus/storage/sectorblocks" - - "golang.org/x/xerrors" ) type StorageMinerAPI struct { @@ -25,6 +20,7 @@ type StorageMinerAPI struct { SectorBlocks *sectorblocks.SectorBlocks Miner *storage.Miner + Full api.FullNode } func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error) { @@ -32,28 +28,7 @@ func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error } func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) error { - ssize, err := sm.Miner.SectorSize(ctx) - if err != nil { - return xerrors.Errorf("failed to get miner sector size: %w", err) - } - go func() { - size := sectorbuilder.UserBytesForSectorSize(ssize) - - // TODO: create a deal - name := fmt.Sprintf("fake-file-%d", rand.Intn(100000000)) - sectorId, err := sm.Sectors.AddPiece(name, size, io.LimitReader(rand.New(rand.NewSource(42)), int64(size))) - if err != nil { - log.Error(err) - return - } - - if err := sm.Miner.SealSector(context.TODO(), sectorId); err != nil { - log.Error(err) - return - } - }() - - return err + return sm.Miner.StoreGarbageData(ctx) } func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid uint64) (sectorbuilder.SectorSealingStatus, error) { diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index a7580f84c..b95500305 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -184,7 +184,7 @@ func SealTicketGen(api api.FullNode) sector.TicketFn { } return §orbuilder.SealTicket{ - BlockHeight: ts.Height() - build.SealRandomnessLookback, + BlockHeight: ts.Height(), TicketBytes: tkt, }, nil } diff --git a/storage/garbage.go b/storage/garbage.go new file mode 100644 index 000000000..d1f396299 --- /dev/null +++ b/storage/garbage.go @@ -0,0 +1,140 @@ +package storage + +import ( + "bytes" + "context" + "fmt" + "io" + "math" + "math/rand" + + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/sectorbuilder" +) + +func (m *Miner) StoreGarbageData(_ context.Context) error { + ctx := context.TODO() + ssize, err := m.SectorSize(ctx) + if err != nil { + return xerrors.Errorf("failed to get miner sector size: %w", err) + } + go func() { + size := sectorbuilder.UserBytesForSectorSize(ssize) + + /*// Add market funds + smsg, err := m.api.MpoolPushMessage(ctx, &types.Message{ + To: actors.StorageMarketAddress, + From: m.worker, + Value: types.NewInt(size), + GasPrice: types.NewInt(0), + GasLimit: types.NewInt(1000000), + Method: actors.SMAMethods.AddBalance, + }) + if err != nil { + log.Error(err) + return + } + + r, err := m.api.StateWaitMsg(ctx, smsg.Cid()) + if err != nil { + log.Error(err) + return + } + + if r.Receipt.ExitCode != 0 { + log.Error(xerrors.Errorf("adding funds to storage miner market actor failed: exit %d", r.Receipt.ExitCode)) + return + }*/ + // Publish a deal + + // TODO: Maybe cache + commP, err := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), size) + if err != nil { + log.Error(err) + return + } + + sdp := actors.StorageDealProposal{ + PieceRef: commP[:], + PieceSize: size, + PieceSerialization: actors.SerializationUnixFSv0, + Client: m.worker, + Provider: m.worker, + ProposalExpiration: math.MaxUint64, + Duration: math.MaxUint64 / 2, // /2 because overflows + StoragePricePerEpoch: types.NewInt(0), + StorageCollateral: types.NewInt(0), + ProposerSignature: nil, + } + + if err := api.SignWith(ctx, m.api.WalletSign, m.worker, &sdp); err != nil { + log.Error(xerrors.Errorf("signing storage deal failed: ", err)) + return + } + + storageDeal := actors.StorageDeal{ + Proposal: sdp, + } + if err := api.SignWith(ctx, m.api.WalletSign, m.worker, &storageDeal); err != nil { + log.Error(xerrors.Errorf("signing storage deal failed: ", err)) + return + } + + params, err := actors.SerializeParams(&actors.PublishStorageDealsParams{ + Deals: []actors.StorageDeal{storageDeal}, + }) + if err != nil { + log.Error(xerrors.Errorf("serializing PublishStorageDeals params failed: ", err)) + } + + // TODO: We may want this to happen after fetching data + smsg, err := m.api.MpoolPushMessage(ctx, &types.Message{ + To: actors.StorageMarketAddress, + From: m.worker, + Value: types.NewInt(0), + GasPrice: types.NewInt(0), + GasLimit: types.NewInt(1000000), + Method: actors.SMAMethods.PublishStorageDeals, + Params: params, + }) + if err != nil { + log.Error(err) + return + } + r, err := m.api.StateWaitMsg(ctx, smsg.Cid()) + if err != nil { + log.Error(err) + return + } + if r.Receipt.ExitCode != 0 { + log.Error(xerrors.Errorf("publishing deal failed: exit %d", r.Receipt.ExitCode)) + } + var resp actors.PublishStorageDealResponse + if err := resp.UnmarshalCBOR(bytes.NewReader(r.Receipt.Return)); err != nil { + log.Error(err) + return + } + if len(resp.DealIDs) != 1 { + log.Error("got unexpected number of DealIDs from") + return + } + + name := fmt.Sprintf("fake-file-%d", rand.Intn(100000000)) + sectorId, err := m.secst.AddPiece(name, size, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), resp.DealIDs[0]) + if err != nil { + log.Error(err) + return + } + + if err := m.SealSector(context.TODO(), sectorId); err != nil { + log.Error(err) + return + } + }() + + return err +} diff --git a/storage/miner.go b/storage/miner.go index 4cec6c94b..ae93e78f5 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -67,6 +67,7 @@ type storageMinerApi interface { ChainGetTipSetByHeight(context.Context, uint64, *types.TipSet) (*types.TipSet, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) + WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) WalletBalance(context.Context, address.Address) (types.BigInt, error) WalletHas(context.Context, address.Address) (bool, error) } diff --git a/storage/sector_states.go b/storage/sector_states.go index ce4a8b28c..3e8a0f67a 100644 --- a/storage/sector_states.go +++ b/storage/sector_states.go @@ -135,14 +135,18 @@ func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*Sector return nil, xerrors.Errorf("computing seal proof failed: %w", err) } + deals, err := m.secst.DealsForCommit(sector.SectorID) + if err != nil { + return nil, err + } + params := &actors.SectorProveCommitInfo{ Proof: proof, SectorID: sector.SectorID, - //DealIDs: deals, + DealIDs: deals, } - _ = params - enc, aerr := actors.SerializeParams(nil) + enc, aerr := actors.SerializeParams(params) if aerr != nil { return nil, xerrors.Errorf("could not serialize commit sector parameters: %w", aerr) } From 68de42df8cc6336a67c85522e34365513000ab24 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Fri, 1 Nov 2019 23:30:06 -0700 Subject: [PATCH 021/114] increase actor error log verbosity --- chain/vm/vm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 38831043b..d090e5f8d 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -462,7 +462,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet, return nil, xerrors.Errorf("fatal error: %w", actorErr) } if actorErr != nil { - log.Warnf("[from=%s,n=%d,h=%d] Send actor error: %+v", msg.From, msg.Nonce, vm.blockHeight, actorErr) + log.Warnf("[from=%s,to=%s,n=%d,m=%d,h=%d] Send actor error: %+v", msg.From, msg.To, msg.Nonce, msg.Method, vm.blockHeight, actorErr) } var errcode uint8 From be8fe54ea3b4a24278a2111e9d7082e7b739d710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 2 Nov 2019 15:13:21 +0100 Subject: [PATCH 022/114] Set correct Provider addr in StoreGarbage --- chain/vm/invoker.go | 4 +++- node/impl/storminer.go | 2 +- storage/garbage.go | 2 +- storage/sector_states.go | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index decc590b7..3fa02d4c1 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -2,6 +2,7 @@ package vm import ( "bytes" + "encoding/hex" "fmt" "reflect" @@ -43,7 +44,8 @@ func (inv *invoker) Invoke(act *types.Actor, vmctx types.VMContext, method uint6 code, ok := inv.builtInCode[act.Code] if !ok { - return nil, aerrors.Newf(255, "no code for actor %s", act.Code) + log.Errorf("no code for actor %s", act.Code) + return nil, aerrors.Newf(255, "no code for actor %s(%d)(%s)", act.Code, method, hex.EncodeToString(params)) } if method >= uint64(len(code)) || code[method] == nil { return nil, aerrors.Newf(255, "no method %d on actor", method) diff --git a/node/impl/storminer.go b/node/impl/storminer.go index e6bae6a22..dbbee1ca1 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -20,7 +20,7 @@ type StorageMinerAPI struct { SectorBlocks *sectorblocks.SectorBlocks Miner *storage.Miner - Full api.FullNode + Full api.FullNode } func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error) { diff --git a/storage/garbage.go b/storage/garbage.go index d1f396299..24af346ec 100644 --- a/storage/garbage.go +++ b/storage/garbage.go @@ -63,7 +63,7 @@ func (m *Miner) StoreGarbageData(_ context.Context) error { PieceSize: size, PieceSerialization: actors.SerializationUnixFSv0, Client: m.worker, - Provider: m.worker, + Provider: m.maddr, ProposalExpiration: math.MaxUint64, Duration: math.MaxUint64 / 2, // /2 because overflows StoragePricePerEpoch: types.NewInt(0), diff --git a/storage/sector_states.go b/storage/sector_states.go index 3e8a0f67a..a3e28ddb0 100644 --- a/storage/sector_states.go +++ b/storage/sector_states.go @@ -143,7 +143,7 @@ func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*Sector params := &actors.SectorProveCommitInfo{ Proof: proof, SectorID: sector.SectorID, - DealIDs: deals, + DealIDs: deals, } enc, aerr := actors.SerializeParams(params) From c550e030b189b7752f6cb7fa57ce719b5d2bbbcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 2 Nov 2019 16:07:18 +0100 Subject: [PATCH 023/114] INTERACTIVE PROEP IS ALIVE --- chain/actors/actor_miner.go | 2 +- lib/sectorbuilder/sectorbuilder.go | 1 + lib/sectorbuilder/sectorbuilder_test.go | 2 +- storage/sector/store.go | 1 + storage/sector_states.go | 4 ++-- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index 010d32729..2ec36a253 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -344,7 +344,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC if ok, err := ValidatePoRep(maddr, mi.SectorSize, commD, us.CommR, ticket, params.Proof, seed, params.SectorID); err != nil { return nil, err } else if !ok { - return nil, aerrors.New(2, "bad proof!") + return nil, aerrors.Newf(2, "bad proof! (t:%x; s:%x(%d); p:%x)", ticket, seed, us.SubmitHeight+build.InteractivePoRepDelay, params.Proof) } // Note: There must exist a unique index in the miner's sector set for each diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index bd57a7bda..7d903b2c1 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -140,6 +140,7 @@ func VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address copy(commDa[:], commD) copy(ticketa[:], ticket) copy(seeda[:], seed) + seeda[31] = 0 // Temp Fr hack proverIDa := addressToProverID(proverID) return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, seeda, sectorID, proof) diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index 3c86bb6ef..acddfe305 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -69,7 +69,7 @@ func TestSealAndVerify(t *testing.T) { seed := sectorbuilder.SealSeed{ BlockHeight: 15, - TicketBytes: [32]byte{0, 9, 8, 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, 8}, + TicketBytes: [32]byte{0, 9, 8, 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, 0}, } sco, err := sb.SealCommit(sid, seed) diff --git a/storage/sector/store.go b/storage/sector/store.go index 52c45deef..d470a5239 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -143,6 +143,7 @@ func (s *Store) SealPreCommit(ctx context.Context, sectorID uint64) (sectorbuild func (s *Store) SealComputeProof(ctx context.Context, sectorID uint64, height uint64, rand []byte) ([]byte, error) { var tick [32]byte copy(tick[:], rand) + tick[31] = 0 sco, err := s.sb.SealCommit(sectorID, sectorbuilder.SealSeed{ BlockHeight: height, diff --git a/storage/sector_states.go b/storage/sector_states.go index a3e28ddb0..cbdc68a26 100644 --- a/storage/sector_states.go +++ b/storage/sector_states.go @@ -97,7 +97,7 @@ func (m *Miner) preCommitted(ctx context.Context, sector SectorInfo) (func(*Sect return nil, err } - randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay + randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay - 1 // -1 because of how the messages are applied log.Infof("precommit for sector %d made it on chain, will start post computation at height %d", sector.SectorID, randHeight) err = m.events.ChainAt(func(ts *types.TipSet, curH uint64) error { @@ -174,7 +174,7 @@ func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*Sector } if mw.Receipt.ExitCode != 0 { - log.Error("UNHANDLED: submitting sector proof failed") + log.Errorf("UNHANDLED: submitting sector proof failed (t:%x; s:%x(%d); p:%x)", sector.Ticket.TicketBytes, rand, sector.RandHeight, params.Proof) return nil, xerrors.New("UNHANDLED: submitting sector proof failed") } From 2a695611d5b4257552ddb92b3b9aa0998195825e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 3 Nov 2019 09:21:58 +0100 Subject: [PATCH 024/114] Update sectorbuilder --- extern/go-bls-sigs | 2 +- extern/go-sectorbuilder | 2 +- lib/sectorbuilder/sectorbuilder.go | 1 - lib/sectorbuilder/sectorbuilder_test.go | 4 ++-- storage/sector/store.go | 1 - 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/extern/go-bls-sigs b/extern/go-bls-sigs index 10fef3cbf..98479d3c7 160000 --- a/extern/go-bls-sigs +++ b/extern/go-bls-sigs @@ -1 +1 @@ -Subproject commit 10fef3cbfa8670d9e9cdffb0cd8dfd4f6f6fef07 +Subproject commit 98479d3c79620f18783da0c2c6a15f8b8eb4fa2e diff --git a/extern/go-sectorbuilder b/extern/go-sectorbuilder index 06775780d..e95a86c6d 160000 --- a/extern/go-sectorbuilder +++ b/extern/go-sectorbuilder @@ -1 +1 @@ -Subproject commit 06775780d8e4db7ba123a7c76073e10d7785b076 +Subproject commit e95a86c6dac7376dc78550f253ed002455553997 diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 7d903b2c1..bd57a7bda 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -140,7 +140,6 @@ func VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address copy(commDa[:], commD) copy(ticketa[:], ticket) copy(seeda[:], seed) - seeda[31] = 0 // Temp Fr hack proverIDa := addressToProverID(proverID) return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, seeda, sectorID, proof) diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index acddfe305..d17285776 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -15,7 +15,7 @@ import ( const sectorSize = 1024 func TestSealAndVerify(t *testing.T) { - t.Skip("this is slow") + //t.Skip("this is slow") build.SectorSizes = []uint64{sectorSize} if err := build.GetParams(true); err != nil { @@ -69,7 +69,7 @@ func TestSealAndVerify(t *testing.T) { seed := sectorbuilder.SealSeed{ BlockHeight: 15, - TicketBytes: [32]byte{0, 9, 8, 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, 0}, + TicketBytes: [32]byte{0, 9, 8, 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, }, } sco, err := sb.SealCommit(sid, seed) diff --git a/storage/sector/store.go b/storage/sector/store.go index d470a5239..52c45deef 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -143,7 +143,6 @@ func (s *Store) SealPreCommit(ctx context.Context, sectorID uint64) (sectorbuild func (s *Store) SealComputeProof(ctx context.Context, sectorID uint64, height uint64, rand []byte) ([]byte, error) { var tick [32]byte copy(tick[:], rand) - tick[31] = 0 sco, err := s.sb.SealCommit(sectorID, sectorbuilder.SealSeed{ BlockHeight: height, From 3ff9b2fab4fc257171b918ad5176f3445f8ceb59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 4 Nov 2019 13:20:01 +0100 Subject: [PATCH 025/114] pond: Pass os env --- README.md | 3 +++ lotuspond/spawn.go | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c3c710864..e40dd3038 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,9 @@ In order to run lotus, please do the following: - bzr (some go dependency needs this) - jq - pkg-config +- opencl-headers +- opencl-driver +- opencl-icd-loader 2. Clone this repo & `cd` into it diff --git a/lotuspond/spawn.go b/lotuspond/spawn.go index c79d736f7..b58e0e7db 100644 --- a/lotuspond/spawn.go +++ b/lotuspond/spawn.go @@ -49,7 +49,7 @@ func (api *api) Spawn() (nodeInfo, error) { cmd := exec.Command("./lotus", "daemon", "--bootstrap=false", genParam, "--api", fmt.Sprintf("%d", 2500+id)) cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile, mux.errpw) cmd.Stdout = io.MultiWriter(os.Stdout, logfile, mux.outpw) - cmd.Env = []string{"LOTUS_PATH=" + dir} + cmd.Env = append(os.Environ(), "LOTUS_PATH=" + dir) if err := cmd.Start(); err != nil { return nodeInfo{}, err } @@ -112,7 +112,7 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) { cmd := exec.Command("./lotus-storage-miner", initArgs...) cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile) cmd.Stdout = io.MultiWriter(os.Stdout, logfile) - cmd.Env = []string{"LOTUS_STORAGE_PATH=" + dir, "LOTUS_PATH=" + fullNodeRepo} + cmd.Env = append(os.Environ(), "LOTUS_STORAGE_PATH=" + dir, "LOTUS_PATH=" + fullNodeRepo) if err := cmd.Run(); err != nil { return nodeInfo{}, err } @@ -124,7 +124,7 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) { cmd = exec.Command("./lotus-storage-miner", "run", "--api", fmt.Sprintf("%d", 2500+id)) cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile, mux.errpw) cmd.Stdout = io.MultiWriter(os.Stdout, logfile, mux.outpw) - cmd.Env = []string{"LOTUS_STORAGE_PATH=" + dir, "LOTUS_PATH=" + fullNodeRepo} + cmd.Env = append(os.Environ(), "LOTUS_STORAGE_PATH=" + dir, "LOTUS_PATH=" + fullNodeRepo) if err := cmd.Start(); err != nil { return nodeInfo{}, err } From 13da5a596625319db2addefbeebab362b29d2053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 4 Nov 2019 17:47:08 +0100 Subject: [PATCH 026/114] Put WorkerThreads on sectorbuilder.Config --- cmd/lotus-storage-miner/run.go | 2 +- lib/sectorbuilder/sectorbuilder.go | 14 ++++++++------ lib/sectorbuilder/sectorbuilder_test.go | 11 +++++++---- lotuspond/spawn.go | 6 +++--- node/impl/storminer.go | 2 +- node/modules/storageminer.go | 17 ++++++++++++----- node/node_test.go | 2 +- 7 files changed, 33 insertions(+), 21 deletions(-) diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index d0806eb16..eff0cbe10 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -77,7 +77,7 @@ var runCmd = &cli.Command{ } return lr.SetAPIEndpoint(apima) }), - node.Override(new(*sectorbuilder.SectorBuilderConfig), modules.SectorBuilderConfig(storageRepoPath)), + node.Override(new(*sectorbuilder.Config), modules.SectorBuilderConfig(storageRepoPath)), node.Override(new(api.FullNode), nodeApi), ) if err != nil { diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index bd57a7bda..40e88ccc6 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -40,20 +40,22 @@ type SectorBuilder struct { handle unsafe.Pointer } -type SectorBuilderConfig struct { - SectorSize uint64 - Miner address.Address +type Config struct { + SectorSize uint64 + Miner address.Address + + WorkerThreads uint8 + CacheDir string SealedDir string StagedDir string MetadataDir string } -func New(cfg *SectorBuilderConfig) (*SectorBuilder, error) { +func New(cfg *Config) (*SectorBuilder, error) { proverId := addressToProverID(cfg.Miner) - nemWorkerThreads := uint8(5) // TODO: from config - sbp, err := sectorbuilder.InitSectorBuilder(cfg.SectorSize, 2, 0, cfg.MetadataDir, proverId, cfg.SealedDir, cfg.StagedDir, cfg.CacheDir, 16, nemWorkerThreads) + sbp, err := sectorbuilder.InitSectorBuilder(cfg.SectorSize, 2, 0, cfg.MetadataDir, proverId, cfg.SealedDir, cfg.StagedDir, cfg.CacheDir, 16, cfg.WorkerThreads) if err != nil { return nil, err } diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index d17285776..ad2d8ebc2 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -37,13 +37,16 @@ func TestSealAndVerify(t *testing.T) { sealed := filepath.Join(dir, "sealed") staging := filepath.Join(dir, "staging") - sb, err := sectorbuilder.New(§orbuilder.SectorBuilderConfig{ - SectorSize: sectorSize, + sb, err := sectorbuilder.New(§orbuilder.Config{ + SectorSize: sectorSize, + Miner: addr, + + WorkerThreads: 1, + CacheDir: cache, SealedDir: sealed, StagedDir: staging, MetadataDir: metadata, - Miner: addr, }) if err != nil { t.Fatal(err) @@ -69,7 +72,7 @@ func TestSealAndVerify(t *testing.T) { seed := sectorbuilder.SealSeed{ BlockHeight: 15, - TicketBytes: [32]byte{0, 9, 8, 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, }, + TicketBytes: [32]byte{0, 9, 8, 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}, } sco, err := sb.SealCommit(sid, seed) diff --git a/lotuspond/spawn.go b/lotuspond/spawn.go index b58e0e7db..eac9ea418 100644 --- a/lotuspond/spawn.go +++ b/lotuspond/spawn.go @@ -49,7 +49,7 @@ func (api *api) Spawn() (nodeInfo, error) { cmd := exec.Command("./lotus", "daemon", "--bootstrap=false", genParam, "--api", fmt.Sprintf("%d", 2500+id)) cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile, mux.errpw) cmd.Stdout = io.MultiWriter(os.Stdout, logfile, mux.outpw) - cmd.Env = append(os.Environ(), "LOTUS_PATH=" + dir) + cmd.Env = append(os.Environ(), "LOTUS_PATH="+dir) if err := cmd.Start(); err != nil { return nodeInfo{}, err } @@ -112,7 +112,7 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) { cmd := exec.Command("./lotus-storage-miner", initArgs...) cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile) cmd.Stdout = io.MultiWriter(os.Stdout, logfile) - cmd.Env = append(os.Environ(), "LOTUS_STORAGE_PATH=" + dir, "LOTUS_PATH=" + fullNodeRepo) + cmd.Env = append(os.Environ(), "LOTUS_STORAGE_PATH="+dir, "LOTUS_PATH="+fullNodeRepo) if err := cmd.Run(); err != nil { return nodeInfo{}, err } @@ -124,7 +124,7 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) { cmd = exec.Command("./lotus-storage-miner", "run", "--api", fmt.Sprintf("%d", 2500+id)) cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile, mux.errpw) cmd.Stdout = io.MultiWriter(os.Stdout, logfile, mux.outpw) - cmd.Env = append(os.Environ(), "LOTUS_STORAGE_PATH=" + dir, "LOTUS_PATH=" + fullNodeRepo) + cmd.Env = append(os.Environ(), "LOTUS_STORAGE_PATH="+dir, "LOTUS_PATH="+fullNodeRepo) if err := cmd.Start(); err != nil { return nodeInfo{}, err } diff --git a/node/impl/storminer.go b/node/impl/storminer.go index dbbee1ca1..b9efe9f2f 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -14,7 +14,7 @@ import ( type StorageMinerAPI struct { CommonAPI - SectorBuilderConfig *sectorbuilder.SectorBuilderConfig + SectorBuilderConfig *sectorbuilder.Config SectorBuilder *sectorbuilder.SectorBuilder Sectors *sector.Store SectorBlocks *sectorblocks.SectorBlocks diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index b95500305..26f70cdb6 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -2,6 +2,7 @@ package modules import ( "context" + "math" "path/filepath" "github.com/ipfs/go-bitswap" @@ -38,8 +39,8 @@ func minerAddrFromDS(ds dtypes.MetadataDS) (address.Address, error) { return address.NewFromBytes(maddrb) } -func SectorBuilderConfig(storagePath string) func(dtypes.MetadataDS, api.FullNode) (*sectorbuilder.SectorBuilderConfig, error) { - return func(ds dtypes.MetadataDS, api api.FullNode) (*sectorbuilder.SectorBuilderConfig, error) { +func SectorBuilderConfig(storagePath string, threads uint) func(dtypes.MetadataDS, api.FullNode) (*sectorbuilder.Config, error) { + return func(ds dtypes.MetadataDS, api api.FullNode) (*sectorbuilder.Config, error) { minerAddr, err := minerAddrFromDS(ds) if err != nil { return nil, err @@ -55,14 +56,20 @@ func SectorBuilderConfig(storagePath string) func(dtypes.MetadataDS, api.FullNod return nil, err } + if threads > math.MaxUint8 { + return nil, xerrors.Errorf("too many sectorbuilder threads specified: %d, max allowed: %d", threads, math.MaxUint8) + } + cache := filepath.Join(sp, "cache") metadata := filepath.Join(sp, "meta") sealed := filepath.Join(sp, "sealed") staging := filepath.Join(sp, "staging") - sb := §orbuilder.SectorBuilderConfig{ - Miner: minerAddr, - SectorSize: ssize, + sb := §orbuilder.Config{ + Miner: minerAddr, + SectorSize: ssize, + WorkerThreads: uint8(threads), + CacheDir: cache, MetadataDir: metadata, SealedDir: sealed, diff --git a/node/node_test.go b/node/node_test.go index 06f1fc1c6..e361bb5fa 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -93,7 +93,7 @@ func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, a node.Repo(r), node.Test(), - node.Override(new(*sectorbuilder.SectorBuilderConfig), modules.SectorBuilderConfig(secbpath)), + node.Override(new(*sectorbuilder.Config), modules.SectorBuilderConfig(secbpath)), node.Override(new(api.FullNode), tnd), ) require.NoError(t, err) From c76ce2a2eb4842a07f02f233ed43b8ad9292d5e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 4 Nov 2019 18:36:29 +0100 Subject: [PATCH 027/114] rate-limit some sectorbuilder ops --- cmd/lotus-storage-miner/run.go | 2 +- lib/sectorbuilder/sectorbuilder.go | 37 +++++++++++++++++++++++++++++- node/node_test.go | 2 +- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index eff0cbe10..1b2a53a80 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -77,7 +77,7 @@ var runCmd = &cli.Command{ } return lr.SetAPIEndpoint(apima) }), - node.Override(new(*sectorbuilder.Config), modules.SectorBuilderConfig(storageRepoPath)), + node.Override(new(*sectorbuilder.Config), modules.SectorBuilderConfig(storageRepoPath, 5)), // TODO: grab worker count from config node.Override(new(api.FullNode), nodeApi), ) if err != nil { diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 40e88ccc6..2e6c67ba6 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -8,12 +8,14 @@ import ( "unsafe" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" - logging "github.com/ipfs/go-log" + "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/address" ) +const PoStReservedWorkers = 1 + var log = logging.Logger("sectorbuilder") type SectorSealingStatus = sectorbuilder.SectorSealingStatus @@ -38,6 +40,8 @@ const CommLen = sectorbuilder.CommitmentBytesLen type SectorBuilder struct { handle unsafe.Pointer + + rateLimit chan struct{} } type Config struct { @@ -53,6 +57,10 @@ type Config struct { } func New(cfg *Config) (*SectorBuilder, error) { + if cfg.WorkerThreads <= PoStReservedWorkers { + return nil, xerrors.Errorf("minimum worker threads is %d, specified %d", PoStReservedWorkers + 1, cfg.WorkerThreads) + } + proverId := addressToProverID(cfg.Miner) sbp, err := sectorbuilder.InitSectorBuilder(cfg.SectorSize, 2, 0, cfg.MetadataDir, proverId, cfg.SealedDir, cfg.StagedDir, cfg.CacheDir, 16, cfg.WorkerThreads) @@ -62,9 +70,21 @@ func New(cfg *Config) (*SectorBuilder, error) { return &SectorBuilder{ handle: sbp, + rateLimit: make(chan struct{}, cfg.WorkerThreads - PoStReservedWorkers), }, nil } +func (sb *SectorBuilder) rlimit() func() { + if cap(sb.rateLimit) == len(sb.rateLimit) { + log.Warn("rate-limiting sectorbuilder call") + } + sb.rateLimit <- struct{}{} + + return func() { + <-sb.rateLimit + } +} + func addressToProverID(a address.Address) [32]byte { var proverId [32]byte copy(proverId[:], a.Payload()) @@ -81,6 +101,9 @@ func (sb *SectorBuilder) AddPiece(pieceKey string, pieceSize uint64, file io.Rea return 0, err } + ret := sb.rlimit() + defer ret() + sectorID, err := sectorbuilder.AddPieceFromFile(sb.handle, pieceKey, pieceSize, f) if err != nil { return 0, err @@ -91,18 +114,30 @@ func (sb *SectorBuilder) AddPiece(pieceKey string, pieceSize uint64, file io.Rea // TODO: should *really really* return an io.ReadCloser func (sb *SectorBuilder) ReadPieceFromSealedSector(pieceKey string) ([]byte, error) { + ret := sb.rlimit() + defer ret() + return sectorbuilder.ReadPieceFromSealedSector(sb.handle, pieceKey) } func (sb *SectorBuilder) SealPreCommit(sectorID uint64, ticket SealTicket) (SealPreCommitOutput, error) { + ret := sb.rlimit() + defer ret() + return sectorbuilder.SealPreCommit(sb.handle, sectorID, ticket) } func (sb *SectorBuilder) SealCommit(sectorID uint64, seed SealSeed) (SealCommitOutput, error) { + ret := sb.rlimit() + defer ret() + return sectorbuilder.SealCommit(sb.handle, sectorID, seed) } func (sb *SectorBuilder) ResumeSealCommit(sectorID uint64) (SealCommitOutput, error) { + ret := sb.rlimit() + defer ret() + return sectorbuilder.ResumeSealCommit(sb.handle, sectorID) } diff --git a/node/node_test.go b/node/node_test.go index e361bb5fa..60ffc59fc 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -93,7 +93,7 @@ func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, a node.Repo(r), node.Test(), - node.Override(new(*sectorbuilder.Config), modules.SectorBuilderConfig(secbpath)), + node.Override(new(*sectorbuilder.Config), modules.SectorBuilderConfig(secbpath, 2)), node.Override(new(api.FullNode), tnd), ) require.NoError(t, err) From 82be4cd77e47fd3e4b501e5bef0a997938a3bc64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 5 Nov 2019 14:15:21 +0100 Subject: [PATCH 028/114] Update go-sectorbuilder again --- extern/go-sectorbuilder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/go-sectorbuilder b/extern/go-sectorbuilder index e95a86c6d..2886db51e 160000 --- a/extern/go-sectorbuilder +++ b/extern/go-sectorbuilder @@ -1 +1 @@ -Subproject commit e95a86c6dac7376dc78550f253ed002455553997 +Subproject commit 2886db51e1b49d697d7ee87ea662e4545225acea From eb28c45c00844d963c8991046ac39f2881abdf6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 5 Nov 2019 15:03:59 +0100 Subject: [PATCH 029/114] events: Plumb context to callbacks --- chain/events/events.go | 6 ++-- chain/events/events_called.go | 3 +- chain/events/events_height.go | 9 ++++-- chain/events/events_test.go | 48 ++++++++++++++-------------- lib/sectorbuilder/sectorbuilder.go | 6 ++-- lotuspond/front/src/chain/methods.js | 9 +++--- storage/post.go | 10 +++--- storage/sector_states.go | 6 ++-- 8 files changed, 51 insertions(+), 46 deletions(-) diff --git a/chain/events/events.go b/chain/events/events.go index b9decb22f..18287dafe 100644 --- a/chain/events/events.go +++ b/chain/events/events.go @@ -18,8 +18,8 @@ import ( var log = logging.Logger("events") // `curH`-`ts.Height` = `confidence` -type HeightHandler func(ts *types.TipSet, curH uint64) error -type RevertHandler func(ts *types.TipSet) error +type HeightHandler func(ctx context.Context, ts *types.TipSet, curH uint64) error +type RevertHandler func(ctx context.Context, ts *types.TipSet) error type heightHandler struct { confidence int @@ -59,6 +59,7 @@ func NewEvents(ctx context.Context, api eventApi) *Events { heightEvents: heightEvents{ tsc: tsc, + ctx: ctx, gcConfidence: uint64(gcConfidence), heightTriggers: map[uint64]*heightHandler{}, @@ -69,6 +70,7 @@ func NewEvents(ctx context.Context, api eventApi) *Events { calledEvents: calledEvents{ cs: api, tsc: tsc, + ctx: ctx, gcConfidence: uint64(gcConfidence), confQueue: map[triggerH]map[msgH][]*queuedEvent{}, diff --git a/chain/events/events_called.go b/chain/events/events_called.go index 98ea04ec8..c51d9bef6 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -56,6 +56,7 @@ type queuedEvent struct { type calledEvents struct { cs eventApi tsc *tipSetCache + ctx context.Context gcConfidence uint64 lk sync.Mutex @@ -114,7 +115,7 @@ func (e *calledEvents) handleReverts(ts *types.TipSet) { trigger := e.triggers[event.trigger] - if err := trigger.revert(ts); err != nil { + if err := trigger.revert(e.ctx, ts); err != nil { log.Errorf("reverting chain trigger (call %s.%d() @H %d, called @ %d) failed: %s", event.msg.To, event.msg.Method, ts.Height(), triggerH, err) } } diff --git a/chain/events/events_height.go b/chain/events/events_height.go index 2805f38e2..751834de3 100644 --- a/chain/events/events_height.go +++ b/chain/events/events_height.go @@ -1,6 +1,7 @@ package events import ( + "context" "sync" "github.com/filecoin-project/lotus/chain/types" @@ -17,6 +18,8 @@ type heightEvents struct { htTriggerHeights map[triggerH][]triggerId htHeights map[msgH][]triggerId + + ctx context.Context } func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error { @@ -26,7 +29,7 @@ func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error { revert := func(h uint64, ts *types.TipSet) { for _, tid := range e.htHeights[h] { - err := e.heightTriggers[tid].revert(ts) + err := e.heightTriggers[tid].revert(e.ctx, ts) if err != nil { log.Errorf("reverting chain trigger (@H %d): %s", h, err) } @@ -74,7 +77,7 @@ func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error { return err } - if err := hnd.handle(incTs, h); err != nil { + if err := hnd.handle(e.ctx, incTs, h); err != nil { log.Errorf("chain trigger (@H %d, called @ %d) failed: %s", triggerH, ts.Height(), err) } } @@ -125,7 +128,7 @@ func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence } e.lk.Unlock() - if err := hnd(ts, bestH); err != nil { + if err := hnd(e.ctx, ts, bestH); err != nil { return err } e.lk.Lock() diff --git a/chain/events/events_test.go b/chain/events/events_test.go index f672bc5f6..d738edf86 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -183,12 +183,12 @@ func TestAt(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { require.Equal(t, 5, int(ts.Height())) require.Equal(t, 8, int(curH)) applied = true return nil - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil }, 3, 5) @@ -248,12 +248,12 @@ func TestAtNullTrigger(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { require.Equal(t, uint64(6), ts.Height()) require.Equal(t, 8, int(curH)) applied = true return nil - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil }, 3, 5) @@ -282,12 +282,12 @@ func TestAtNullConf(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { require.Equal(t, 5, int(ts.Height())) require.Equal(t, 8, int(curH)) applied = true return nil - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil }, 3, 5) @@ -323,12 +323,12 @@ func TestAtStart(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { require.Equal(t, 5, int(ts.Height())) require.Equal(t, 8, int(curH)) applied = true return nil - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil }, 3, 5) @@ -357,12 +357,12 @@ func TestAtStartConfidence(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { require.Equal(t, 5, int(ts.Height())) require.Equal(t, 11, int(curH)) applied = true return nil - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil }, 3, 5) @@ -385,16 +385,16 @@ func TestAtChained(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(ts *types.TipSet, curH uint64) error { - return events.ChainAt(func(ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { + return events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { require.Equal(t, 10, int(ts.Height())) applied = true return nil - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil }, 3, 10) - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil }, 3, 5) @@ -421,16 +421,16 @@ func TestAtChainedConfidence(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(ts *types.TipSet, curH uint64) error { - return events.ChainAt(func(ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { + return events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { require.Equal(t, 10, int(ts.Height())) applied = true return nil - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil }, 3, 10) - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil }, 3, 5) @@ -455,11 +455,11 @@ func TestAtChainedConfidenceNull(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { applied = true require.Equal(t, 6, int(ts.Height())) return nil - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil }, 3, 5) @@ -499,7 +499,7 @@ func TestCalled(t *testing.T) { appliedTs = ts appliedH = curH return more, nil - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil }, 3, 20, t0123, 5) @@ -693,7 +693,7 @@ func TestCalledTimeout(t *testing.T) { require.Equal(t, uint64(20), ts.Height()) require.Equal(t, uint64(23), curH) return false, nil - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { t.Fatal("revert on timeout") return nil }, 3, 20, t0123, 5) @@ -728,7 +728,7 @@ func TestCalledTimeout(t *testing.T) { require.Equal(t, uint64(20), ts.Height()) require.Equal(t, uint64(23), curH) return false, nil - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { t.Fatal("revert on timeout") return nil }, 3, 20, t0123, 5) @@ -774,7 +774,7 @@ func TestCalledOrder(t *testing.T) { } at++ return true, nil - }, func(ts *types.TipSet) error { + }, func(_ context.Context, ts *types.TipSet) error { switch at { case 2: require.Equal(t, uint64(4), ts.Height()) diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 2e6c67ba6..6aebc892b 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -58,7 +58,7 @@ type Config struct { func New(cfg *Config) (*SectorBuilder, error) { if cfg.WorkerThreads <= PoStReservedWorkers { - return nil, xerrors.Errorf("minimum worker threads is %d, specified %d", PoStReservedWorkers + 1, cfg.WorkerThreads) + return nil, xerrors.Errorf("minimum worker threads is %d, specified %d", PoStReservedWorkers+1, cfg.WorkerThreads) } proverId := addressToProverID(cfg.Miner) @@ -69,8 +69,8 @@ func New(cfg *Config) (*SectorBuilder, error) { } return &SectorBuilder{ - handle: sbp, - rateLimit: make(chan struct{}, cfg.WorkerThreads - PoStReservedWorkers), + handle: sbp, + rateLimit: make(chan struct{}, cfg.WorkerThreads-PoStReservedWorkers), }, nil } diff --git a/lotuspond/front/src/chain/methods.js b/lotuspond/front/src/chain/methods.js index b9e153ef7..172531c5a 100644 --- a/lotuspond/front/src/chain/methods.js +++ b/lotuspond/front/src/chain/methods.js @@ -34,8 +34,9 @@ export default { [code.miner]: [ "Send", "Constructor", - "CommitSector", - "SubmitPost", + "PreCommitSector", + "ProveCommitSector", + "SubmitPoSt", "SlashStorageFault", "GetCurrentProvingSet", "ArbitrateDeal", @@ -49,8 +50,8 @@ export default { "ChangeWorker", "IsSlashed", "IsLate", - "PaymentVerifyInclusion", - "PaymentVerifySector", + "DeclareFaults", + "SlashConsensusFault", ], [code.multisig]: [ "Send", diff --git a/storage/post.go b/storage/post.go index 9d3f892a7..4d3e8de1a 100644 --- a/storage/post.go +++ b/storage/post.go @@ -45,7 +45,7 @@ func (m *Miner) beginPosting(ctx context.Context) { m.postLk.Unlock() log.Infof("Scheduling post at height %d", ppe-build.PoStChallangeTime) - err = m.events.ChainAt(m.computePost(m.schedPost), func(ts *types.TipSet) error { // Revert + err = m.events.ChainAt(m.computePost(m.schedPost), func(ctx context.Context, ts *types.TipSet) error { // Revert // TODO: Cancel post log.Errorf("TODO: Cancel PoSt, re-run") return nil @@ -84,7 +84,7 @@ func (m *Miner) scheduleNextPost(ppe uint64) { log.Infow("scheduling PoSt", "post-height", ppe-build.PoStChallangeTime, "height", ts.Height(), "ppe", ppe, "proving-period", provingPeriod) - err = m.events.ChainAt(m.computePost(ppe), func(ts *types.TipSet) error { // Revert + err = m.events.ChainAt(m.computePost(ppe), func(ctx context.Context, ts *types.TipSet) error { // Revert // TODO: Cancel post log.Errorf("TODO: Cancel PoSt, re-run") return nil @@ -96,9 +96,9 @@ func (m *Miner) scheduleNextPost(ppe uint64) { } } -func (m *Miner) computePost(ppe uint64) func(ts *types.TipSet, curH uint64) error { +func (m *Miner) computePost(ppe uint64) func(ctx context.Context, ts *types.TipSet, curH uint64) error { called := 0 - return func(ts *types.TipSet, curH uint64) error { + return func(ctx context.Context, ts *types.TipSet, curH uint64) error { called++ if called > 1 { log.Errorw("BUG: computePost callback called again", "ppe", ppe, @@ -106,8 +106,6 @@ func (m *Miner) computePost(ppe uint64) func(ts *types.TipSet, curH uint64) erro return nil } - ctx := context.TODO() - sset, err := m.api.StateMinerProvingSet(ctx, m.maddr, ts) if err != nil { return xerrors.Errorf("failed to get proving set for miner: %w", err) diff --git a/storage/sector_states.go b/storage/sector_states.go index cbdc68a26..1122ea9a6 100644 --- a/storage/sector_states.go +++ b/storage/sector_states.go @@ -98,9 +98,9 @@ func (m *Miner) preCommitted(ctx context.Context, sector SectorInfo) (func(*Sect } randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay - 1 // -1 because of how the messages are applied - log.Infof("precommit for sector %d made it on chain, will start post computation at height %d", sector.SectorID, randHeight) + log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight) - err = m.events.ChainAt(func(ts *types.TipSet, curH uint64) error { + err = m.events.ChainAt(func(ctx context.Context, ts *types.TipSet, curH uint64) error { m.sectorUpdated <- sectorUpdate{ newState: api.Committing, id: sector.SectorID, @@ -111,7 +111,7 @@ func (m *Miner) preCommitted(ctx context.Context, sector SectorInfo) (func(*Sect } return nil - }, func(ts *types.TipSet) error { + }, func(ctx context.Context, ts *types.TipSet) error { log.Warn("revert in interactive commit sector step") return nil }, 3, mw.TipSet.Height()+build.InteractivePoRepDelay) From 4c4c2095a69d900293732fe21b95dc1f52a311b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 5 Nov 2019 15:36:44 +0100 Subject: [PATCH 030/114] events: Basic tracing --- chain/events/events_height.go | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/chain/events/events_height.go b/chain/events/events_height.go index 751834de3..3c03f7571 100644 --- a/chain/events/events_height.go +++ b/chain/events/events_height.go @@ -2,6 +2,7 @@ package events import ( "context" + "go.opencensus.io/trace" "sync" "github.com/filecoin-project/lotus/chain/types" @@ -23,13 +24,24 @@ type heightEvents struct { } func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error { + ctx, span := trace.StartSpan(e.ctx, "events.HeightHeadChange") + defer span.End() + span.AddAttributes(trace.Int64Attribute("endHeight", int64(app[0].Height()))) + span.AddAttributes(trace.Int64Attribute("reverts", int64(len(rev)))) + span.AddAttributes(trace.Int64Attribute("applies", int64(len(app)))) + for _, ts := range rev { // TODO: log error if h below gcconfidence // revert height-based triggers revert := func(h uint64, ts *types.TipSet) { for _, tid := range e.htHeights[h] { - err := e.heightTriggers[tid].revert(e.ctx, ts) + ctx, span := trace.StartSpan(ctx, "events.HeightRevert") + + err := e.heightTriggers[tid].revert(ctx, ts) + + span.End() + if err != nil { log.Errorf("reverting chain trigger (@H %d): %s", h, err) } @@ -77,7 +89,13 @@ func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error { return err } - if err := hnd.handle(e.ctx, incTs, h); err != nil { + ctx, span := trace.StartSpan(ctx, "events.HeightApply") + span.AddAttributes(trace.BoolAttribute("immediate", false)) + + err = hnd.handle(ctx, incTs, h) + span.End() + + if err != nil { log.Errorf("chain trigger (@H %d, called @ %d) failed: %s", triggerH, ts.Height(), err) } } @@ -128,9 +146,16 @@ func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence } e.lk.Unlock() - if err := hnd(e.ctx, ts, bestH); err != nil { + ctx, span := trace.StartSpan(e.ctx, "events.HeightApply") + span.AddAttributes(trace.BoolAttribute("immediate", true)) + + err = hnd(ctx, ts, bestH) + span.End() + + if err != nil { return err } + e.lk.Lock() bestH = e.tsc.best().Height() } From daabe470a44122867fd6928d3f590054b048f838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 5 Nov 2019 15:52:33 +0100 Subject: [PATCH 031/114] storageminer: tracing in computePost --- storage/post.go | 200 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 141 insertions(+), 59 deletions(-) diff --git a/storage/post.go b/storage/post.go index 4d3e8de1a..3fe45d24c 100644 --- a/storage/post.go +++ b/storage/post.go @@ -2,6 +2,8 @@ package storage import ( "context" + "github.com/ipfs/go-cid" + "go.opencensus.io/trace" "time" "golang.org/x/xerrors" @@ -96,6 +98,140 @@ func (m *Miner) scheduleNextPost(ppe uint64) { } } +type post struct { + m *Miner + + ppe uint64 + ts *types.TipSet + + // prep + sset []*api.SectorInfo + r []byte + + // run + proof []byte + + // commit + smsg cid.Cid +} + +func (p *post) doPost(ctx context.Context) error { + ctx, span := trace.StartSpan(ctx, "storage.computePost") + defer span.End() + + if err := p.preparePost(ctx); err != nil { + return err + } + + if err := p.runPost(ctx); err != nil { + return err + } + + if err := p.commitPost(ctx); err != nil { + return err + } + + if err := p.waitCommit(ctx); err != nil { + return err + } + + return nil +} + +func (p *post) preparePost(ctx context.Context) error { + ctx, span := trace.StartSpan(ctx, "storage.preparePost") + defer span.End() + + sset, err := p.m.api.StateMinerProvingSet(ctx, p.m.maddr, p.ts) + if err != nil { + return xerrors.Errorf("failed to get proving set for miner: %w", err) + } + p.sset = sset + + r, err := p.m.api.ChainGetRandomness(ctx, p.ts, nil, int(int64(p.ts.Height())-int64(p.ppe)+int64(build.PoStChallangeTime)+int64(build.PoStRandomnessLookback))) // TODO: review: check math + if err != nil { + return xerrors.Errorf("failed to get chain randomness for post (ts=%d; ppe=%d): %w", p.ts.Height(), p.ppe, err) + } + p.r = r + + return nil +} + +func (p *post) runPost(ctx context.Context) error { + ctx, span := trace.StartSpan(ctx, "storage.runPost") + defer span.End() + + log.Infow("running PoSt", "delayed-by", + int64(p.ts.Height())-(int64(p.ppe)-int64(build.PoStChallangeTime)), + "chain-random", p.r, "ppe", p.ppe, "height", p.ts.Height()) + + tsStart := time.Now() + var faults []uint64 // TODO + proof, err := p.m.secst.RunPoSt(ctx, p.sset, p.r, faults) + if err != nil { + return xerrors.Errorf("running post failed: %w", err) + } + elapsed := time.Since(tsStart) + + p.proof = proof + log.Infow("submitting PoSt", "pLen", len(proof), "elapsed", elapsed) + + return nil +} + +func (p *post) commitPost(ctx context.Context) error { + ctx, span := trace.StartSpan(ctx, "storage.commitPost") + defer span.End() + + 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) + } + + 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), + } + + 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 +} + +func (p *post) waitCommit(ctx context.Context) error { + ctx, span := trace.StartSpan(ctx, "storage.waitPost") + defer span.End() + + log.Infof("Waiting for post %s to appear on chain", p.smsg) + + // make sure it succeeds... + rec, err := p.m.api.StateWaitMsg(ctx, p.smsg) + if err != nil { + return err + } + if rec.Receipt.ExitCode != 0 { + log.Warnf("SubmitPoSt EXIT: %d", rec.Receipt.ExitCode) + // TODO: Do something + } + return nil +} + func (m *Miner) computePost(ppe uint64) func(ctx context.Context, ts *types.TipSet, curH uint64) error { called := 0 return func(ctx context.Context, ts *types.TipSet, curH uint64) error { @@ -106,68 +242,14 @@ func (m *Miner) computePost(ppe uint64) func(ctx context.Context, ts *types.TipS return nil } - sset, err := m.api.StateMinerProvingSet(ctx, m.maddr, ts) - if err != nil { - return xerrors.Errorf("failed to get proving set for miner: %w", err) - } - - r, err := m.api.ChainGetRandomness(ctx, ts, nil, int(int64(ts.Height())-int64(ppe)+int64(build.PoStChallangeTime)+int64(build.PoStRandomnessLookback))) // TODO: review: check math - if err != nil { - return xerrors.Errorf("failed to get chain randomness for post (ts=%d; ppe=%d): %w", ts.Height(), ppe, err) - } - - log.Infow("running PoSt", "delayed-by", - int64(ts.Height())-(int64(ppe)-int64(build.PoStChallangeTime)), - "chain-random", r, "ppe", ppe, "height", ts.Height()) - - tsStart := time.Now() - var faults []uint64 - proof, err := m.secst.RunPoSt(ctx, sset, r, faults) - if err != nil { - return xerrors.Errorf("running post failed: %w", err) - } - elapsed := time.Since(tsStart) - - log.Infow("submitting PoSt", "pLen", len(proof), "elapsed", elapsed) - - params := &actors.SubmitPoStParams{ - Proof: proof, - DoneSet: types.BitFieldFromSet(nil), - } - - enc, aerr := actors.SerializeParams(params) - if aerr != nil { - return xerrors.Errorf("could not serialize submit post parameters: %w", err) - } - - msg := &types.Message{ - To: m.maddr, - From: 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), - } - - log.Info("mpush") - - smsg, err := m.api.MpoolPushMessage(ctx, msg) - if err != nil { - return xerrors.Errorf("pushing message to mpool: %w", err) - } - - log.Infof("Waiting for post %s to appear on chain", smsg.Cid()) - - // make sure it succeeds... - rec, err := m.api.StateWaitMsg(ctx, smsg.Cid()) + err := (&post{ + m: m, + ppe: ppe, + ts: ts, + }).doPost(ctx) if err != nil { return err } - if rec.Receipt.ExitCode != 0 { - log.Warnf("SubmitPoSt EXIT: %d", rec.Receipt.ExitCode) - // TODO: Do something - } m.scheduleNextPost(ppe + build.ProvingPeriodDuration) return nil From 1f56bcf581c84f130acb622b30ee7891b00a7b63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 5 Nov 2019 17:15:52 +0100 Subject: [PATCH 032/114] Some param changes --- build/params.go | 5 ++++- chain/actors/actor_miner.go | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/build/params.go b/build/params.go index ef55c01bd..cd2fc738c 100644 --- a/build/params.go +++ b/build/params.go @@ -55,7 +55,7 @@ const Finality = 500 // Proofs // Blocks -const ProvingPeriodDuration = 60 +const ProvingPeriodDuration = 300 // PoStChallangeTime sets the window in which post computation should happen // Blocks @@ -71,6 +71,9 @@ const PoStRandomnessLookback = 1 // Blocks const SealRandomnessLookback = Finality +// Blocks +const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000 + // ///// // Mining diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index 2ec36a253..963a469e9 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -231,8 +231,8 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon return nil, aerrors.Newf(1, "sector commitment must be based off past randomness (%d >= %d)", params.Epoch, vmctx.BlockHeight()+build.SealRandomnessLookback) } - if vmctx.BlockHeight()-params.Epoch+build.SealRandomnessLookback > 1000 { - return nil, aerrors.New(2, "sector commitment must be recent enough") + if vmctx.BlockHeight()-params.Epoch+build.SealRandomnessLookback > build.SealRandomnessLookbackLimit { + return nil, aerrors.Newf(2, "sector commitment must be recent enough (was %d)", vmctx.BlockHeight()-params.Epoch+build.SealRandomnessLookback) } mi, err := loadMinerInfo(vmctx, self) From 6a802cc9dbcdab53d5bf9142665a2f04fe4ce9b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 5 Nov 2019 18:09:42 +0100 Subject: [PATCH 033/114] WIP fixing tests --- chain/gen/gen.go | 4 ++-- lib/sectorbuilder/sectorbuilder_test.go | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index b38f2c0df..6af8b9d4f 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -279,12 +279,12 @@ func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Ad } fts := store.NewFullTipSet(blks) - fmt.Println("Made a block: ", fts.TipSet().Cids()) + /*fmt.Println("Made a block: ", fts.TipSet().Cids()) if len(fts.TipSet().Cids()) > 1 { for _, b := range blks { fmt.Printf("block %s: %#v\n", b.Cid(), b.Header) } - } + }*/ return &MinedTipSet{ TipSet: fts, diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index ad2d8ebc2..819c52824 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -15,7 +15,9 @@ import ( const sectorSize = 1024 func TestSealAndVerify(t *testing.T) { - //t.Skip("this is slow") + t.Skip("this is slow") + //os.Setenv("BELLMAN_NO_GPU", "1") + build.SectorSizes = []uint64{sectorSize} if err := build.GetParams(true); err != nil { @@ -41,7 +43,7 @@ func TestSealAndVerify(t *testing.T) { SectorSize: sectorSize, Miner: addr, - WorkerThreads: 1, + WorkerThreads: 2, CacheDir: cache, SealedDir: sealed, From ebdaa3f0200dc583d6f6e1cfbb09718eb45c1691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 5 Nov 2019 18:33:58 +0100 Subject: [PATCH 034/114] Fix TestSyncBadTimestamp with low BlockDelay --- chain/sync_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chain/sync_test.go b/chain/sync_test.go index 24b8fbd10..d17b6e853 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/store" @@ -390,7 +391,7 @@ func TestSyncBadTimestamp(t *testing.T) { base := tu.g.CurTipset tu.g.Timestamper = func(pts *types.TipSet, tl int) uint64 { - return pts.MinTimestamp() + 2 + return pts.MinTimestamp() + (build.BlockDelay / 2) } fmt.Println("BASE: ", base.Cids()) From d1b1b6f79f1003d0b308b9da954acfbcf8a9a190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 5 Nov 2019 18:41:04 +0100 Subject: [PATCH 035/114] revert BlockDelay to 10s --- build/params.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/params.go b/build/params.go index cd2fc738c..22e1ece3c 100644 --- a/build/params.go +++ b/build/params.go @@ -37,7 +37,7 @@ const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours // Consensus / Network // Seconds -const BlockDelay = 2 +const BlockDelay = 10 // Seconds const AllowableClockDrift = BlockDelay * 2 From bcf9778b18f014bbf04bcc5581ba0747191885da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 5 Nov 2019 19:02:28 +0100 Subject: [PATCH 036/114] Update cbor-gen post-merge --- chain/actors/cbor_gen.go | 490 ++++++++++++++++++++++++++++++--------- chain/types/cbor_gen.go | 16 +- storage/cbor_gen.go | 63 ++--- 3 files changed, 426 insertions(+), 143 deletions(-) diff --git a/chain/actors/cbor_gen.go b/chain/actors/cbor_gen.go index 304722e45..073286eb3 100644 --- a/chain/actors/cbor_gen.go +++ b/chain/actors/cbor_gen.go @@ -197,24 +197,28 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{140}); err != nil { + if _, err := w.Write([]byte{139}); err != nil { return err } - // t.t.Info (cid.Cid) (struct) - - if err := cbg.WriteCid(w, t.Info); err != nil { - return xerrors.Errorf("failed to write cid field t.Info: %w", err) - } - - // t.t.DePledgedCollateral (types.BigInt) (struct) - if err := t.DePledgedCollateral.MarshalCBOR(w); err != nil { + // t.t.PreCommittedSectors (map[string]*actors.UnprovenSector) (map) + if err := cbg.CborWriteHeader(w, cbg.MajMap, uint64(len(t.PreCommittedSectors))); err != nil { return err } - // t.t.DePledgeTime (types.BigInt) (struct) - if err := t.DePledgeTime.MarshalCBOR(w); err != nil { - return err + for k, v := range t.PreCommittedSectors { + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil { + return err + } + if _, err := w.Write([]byte(k)); err != nil { + return err + } + + if err := v.MarshalCBOR(w); err != nil { + return err + } + } // t.t.Sectors (cid.Cid) (struct) @@ -229,6 +233,12 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { return xerrors.Errorf("failed to write cid field t.ProvingSet: %w", err) } + // t.t.Info (cid.Cid) (struct) + + if err := cbg.WriteCid(w, t.Info); err != nil { + return xerrors.Errorf("failed to write cid field t.Info: %w", err) + } + // t.t.CurrentFaultSet (types.BitField) (struct) if err := t.CurrentFaultSet.MarshalCBOR(w); err != nil { return err @@ -277,39 +287,62 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 12 { + if extra != 11 { return fmt.Errorf("cbor input had wrong number of fields") } - // t.t.Info (cid.Cid) (struct) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.Info: %w", err) - } - - t.Info = c + // t.t.PreCommittedSectors (map[string]*actors.UnprovenSector) (map) + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err } - // t.t.DePledgedCollateral (types.BigInt) (struct) - - { - - if err := t.DePledgedCollateral.UnmarshalCBOR(br); err != nil { - return err - } - + if maj != cbg.MajMap { + return fmt.Errorf("expected a map (major type 5)") + } + if extra > 4096 { + return fmt.Errorf("t.PreCommittedSectors: map too large") } - // t.t.DePledgeTime (types.BigInt) (struct) - { + t.PreCommittedSectors = make(map[string]*UnprovenSector, extra) - if err := t.DePledgeTime.UnmarshalCBOR(br); err != nil { - return err + for i, l := 0, int(extra); i < l; i++ { + + var k string + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + k = string(sval) } + var v *UnprovenSector + + { + + pb, err := br.PeekByte() + if err != nil { + return err + } + if pb == cbg.CborNull[0] { + var nbuf [1]byte + if _, err := br.Read(nbuf[:]); err != nil { + return err + } + } else { + v = new(UnprovenSector) + if err := v.UnmarshalCBOR(br); err != nil { + return err + } + } + + } + + t.PreCommittedSectors[k] = v + } // t.t.Sectors (cid.Cid) (struct) @@ -334,6 +367,18 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { t.ProvingSet = c + } + // t.t.Info (cid.Cid) (struct) + + { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Info: %w", err) + } + + t.Info = c + } // t.t.CurrentFaultSet (types.BitField) (struct) @@ -492,12 +537,12 @@ func (t *StorageMinerConstructorParams) UnmarshalCBOR(r io.Reader) error { return nil } -func (t *OnChainSealVerifyInfo) MarshalCBOR(w io.Writer) error { +func (t *SectorPreCommitInfo) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{134}); err != nil { + if _, err := w.Write([]byte{132}); err != nil { return err } @@ -522,24 +567,6 @@ func (t *OnChainSealVerifyInfo) MarshalCBOR(w io.Writer) error { return err } - // t.t.Proof ([]uint8) (slice) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil { - return err - } - if _, err := w.Write(t.Proof); err != nil { - return err - } - - // t.t.DealIDs ([]uint64) (slice) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { - return err - } - for _, v := range t.DealIDs { - if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { - return err - } - } - // t.t.SectorNumber (uint64) (uint64) if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorNumber))); err != nil { return err @@ -547,7 +574,7 @@ func (t *OnChainSealVerifyInfo) MarshalCBOR(w io.Writer) error { return nil } -func (t *OnChainSealVerifyInfo) UnmarshalCBOR(r io.Reader) error { +func (t *SectorPreCommitInfo) UnmarshalCBOR(r io.Reader) error { br := cbg.GetPeeker(r) maj, extra, err := cbg.CborReadHeader(br) @@ -558,7 +585,7 @@ func (t *OnChainSealVerifyInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 6 { + if extra != 4 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -606,53 +633,6 @@ func (t *OnChainSealVerifyInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("wrong type for uint64 field") } t.Epoch = uint64(extra) - // t.t.Proof ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if extra > 8192 { - return fmt.Errorf("t.Proof: array too large (%d)", extra) - } - - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.Proof = make([]byte, extra) - if _, err := io.ReadFull(br, t.Proof); err != nil { - return err - } - // t.t.DealIDs ([]uint64) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if extra > 8192 { - return fmt.Errorf("t.DealIDs: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.DealIDs = make([]uint64, extra) - } - for i := 0; i < int(extra); i++ { - - maj, val, err := cbg.CborReadHeader(br) - if err != nil { - return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) - } - - if maj != cbg.MajUnsignedInt { - return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) - } - - t.DealIDs[i] = val - } - // t.t.SectorNumber (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) @@ -666,6 +646,115 @@ func (t *OnChainSealVerifyInfo) UnmarshalCBOR(r io.Reader) error { return nil } +func (t *UnprovenSector) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{132}); err != nil { + return err + } + + // t.t.CommD ([]uint8) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommD)))); err != nil { + return err + } + if _, err := w.Write(t.CommD); err != nil { + return err + } + + // t.t.CommR ([]uint8) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommR)))); err != nil { + return err + } + if _, err := w.Write(t.CommR); err != nil { + return err + } + + // t.t.SubmitHeight (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SubmitHeight))); err != nil { + return err + } + + // t.t.TicketEpoch (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.TicketEpoch))); err != nil { + return err + } + return nil +} + +func (t *UnprovenSector) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 4 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.CommD ([]uint8) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.CommD: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommD = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommD); err != nil { + return err + } + // t.t.CommR ([]uint8) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.CommR: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommR = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommR); err != nil { + return err + } + // t.t.SubmitHeight (uint64) (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.SubmitHeight = uint64(extra) + // t.t.TicketEpoch (uint64) (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.TicketEpoch = uint64(extra) + return nil +} + func (t *MinerInfo) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) @@ -3598,3 +3687,196 @@ func (t *OnChainDeal) UnmarshalCBOR(r io.Reader) error { t.ActivationEpoch = uint64(extra) return nil } + +func (t *ComputeDataCommitmentParams) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{130}); err != nil { + return err + } + + // t.t.DealIDs ([]uint64) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { + return err + } + for _, v := range t.DealIDs { + if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { + return err + } + } + + // t.t.SectorSize (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorSize))); err != nil { + return err + } + return nil +} + +func (t *ComputeDataCommitmentParams) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 2 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.DealIDs ([]uint64) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.DealIDs: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.DealIDs = make([]uint64, extra) + } + for i := 0; i < int(extra); i++ { + + maj, val, err := cbg.CborReadHeader(br) + if err != nil { + return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) + } + + if maj != cbg.MajUnsignedInt { + return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) + } + + t.DealIDs[i] = val + } + + // t.t.SectorSize (uint64) (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.SectorSize = uint64(extra) + return nil +} + +func (t *SectorProveCommitInfo) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{131}); err != nil { + return err + } + + // t.t.Proof ([]uint8) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil { + return err + } + if _, err := w.Write(t.Proof); err != nil { + return err + } + + // t.t.SectorID (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorID))); err != nil { + return err + } + + // t.t.DealIDs ([]uint64) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { + return err + } + for _, v := range t.DealIDs { + if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { + return err + } + } + return nil +} + +func (t *SectorProveCommitInfo) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 3 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.Proof ([]uint8) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.Proof: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.Proof = make([]byte, extra) + if _, err := io.ReadFull(br, t.Proof); err != nil { + return err + } + // t.t.SectorID (uint64) (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.SectorID = uint64(extra) + // t.t.DealIDs ([]uint64) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.DealIDs: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.DealIDs = make([]uint64, extra) + } + for i := 0; i < int(extra); i++ { + + maj, val, err := cbg.CborReadHeader(br) + if err != nil { + return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) + } + + if maj != cbg.MajUnsignedInt { + return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) + } + + t.DealIDs[i] = val + } + + return nil +} diff --git a/chain/types/cbor_gen.go b/chain/types/cbor_gen.go index 2ac856520..fa3cddaf4 100644 --- a/chain/types/cbor_gen.go +++ b/chain/types/cbor_gen.go @@ -1480,7 +1480,7 @@ func (t *ExpTipSet) MarshalCBOR(w io.Writer) error { return err } - // t.t.Cids ([]cid.Cid) + // t.t.Cids ([]cid.Cid) (slice) if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Cids)))); err != nil { return err } @@ -1490,7 +1490,7 @@ func (t *ExpTipSet) MarshalCBOR(w io.Writer) error { } } - // t.t.Blocks ([]*types.BlockHeader) + // t.t.Blocks ([]*types.BlockHeader) (slice) if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Blocks)))); err != nil { return err } @@ -1500,8 +1500,8 @@ func (t *ExpTipSet) MarshalCBOR(w io.Writer) error { } } - // t.t.Height (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.Height)); err != nil { + // t.t.Height (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Height))); err != nil { return err } return nil @@ -1522,7 +1522,7 @@ func (t *ExpTipSet) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input had wrong number of fields") } - // t.t.Cids ([]cid.Cid) + // t.t.Cids ([]cid.Cid) (slice) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -1547,7 +1547,7 @@ func (t *ExpTipSet) UnmarshalCBOR(r io.Reader) error { t.Cids[i] = c } - // t.t.Blocks ([]*types.BlockHeader) + // t.t.Blocks ([]*types.BlockHeader) (slice) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -1573,7 +1573,7 @@ func (t *ExpTipSet) UnmarshalCBOR(r io.Reader) error { t.Blocks[i] = &v } - // t.t.Height (uint64) + // t.t.Height (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -1582,6 +1582,6 @@ func (t *ExpTipSet) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.Height = extra + t.Height = uint64(extra) return nil } diff --git a/storage/cbor_gen.go b/storage/cbor_gen.go index 38e70c020..74c5f93e6 100644 --- a/storage/cbor_gen.go +++ b/storage/cbor_gen.go @@ -2,10 +2,11 @@ package storage import ( "fmt" + "io" + "github.com/filecoin-project/lotus/chain/types" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" - "io" ) /* This file was generated by github.com/whyrusleeping/cbor-gen */ @@ -21,12 +22,12 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error { return err } - // t.t.BlockHeight (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.BlockHeight)); err != nil { + // t.t.BlockHeight (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { return err } - // t.t.TicketBytes ([]uint8) + // t.t.TicketBytes ([]uint8) (slice) if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.TicketBytes)))); err != nil { return err } @@ -51,7 +52,7 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input had wrong number of fields") } - // t.t.BlockHeight (uint64) + // t.t.BlockHeight (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -60,8 +61,8 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.BlockHeight = extra - // t.t.TicketBytes ([]uint8) + t.BlockHeight = uint64(extra) + // t.t.TicketBytes ([]uint8) (slice) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -90,17 +91,17 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.t.State (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.State)); err != nil { + // t.t.State (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.State))); err != nil { return err } - // t.t.SectorID (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.SectorID)); err != nil { + // t.t.SectorID (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorID))); err != nil { return err } - // t.t.CommD ([]uint8) + // t.t.CommD ([]uint8) (slice) if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommD)))); err != nil { return err } @@ -108,7 +109,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.t.CommR ([]uint8) + // t.t.CommR ([]uint8) (slice) if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommR)))); err != nil { return err } @@ -116,12 +117,12 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.t.Ticket (storage.SealTicket) + // t.t.Ticket (storage.SealTicket) (struct) if err := t.Ticket.MarshalCBOR(w); err != nil { return err } - // t.t.PreCommitMessage (cid.Cid) + // t.t.PreCommitMessage (cid.Cid) (struct) if t.PreCommitMessage == nil { if _, err := w.Write(cbg.CborNull); err != nil { @@ -133,17 +134,17 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { } } - // t.t.RandHeight (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.RandHeight)); err != nil { + // t.t.RandHeight (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.RandHeight))); err != nil { return err } - // t.t.RandTs (types.TipSet) + // t.t.RandTs (types.TipSet) (struct) if err := t.RandTs.MarshalCBOR(w); err != nil { return err } - // t.t.CommitMessage (cid.Cid) + // t.t.CommitMessage (cid.Cid) (struct) if t.CommitMessage == nil { if _, err := w.Write(cbg.CborNull); err != nil { @@ -173,7 +174,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input had wrong number of fields") } - // t.t.State (uint64) + // t.t.State (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -182,8 +183,8 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.State = extra - // t.t.SectorID (uint64) + t.State = uint64(extra) + // t.t.SectorID (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -192,8 +193,8 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.SectorID = extra - // t.t.CommD ([]uint8) + t.SectorID = uint64(extra) + // t.t.CommD ([]uint8) (slice) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -210,7 +211,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if _, err := io.ReadFull(br, t.CommD); err != nil { return err } - // t.t.CommR ([]uint8) + // t.t.CommR ([]uint8) (slice) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -227,7 +228,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if _, err := io.ReadFull(br, t.CommR); err != nil { return err } - // t.t.Ticket (storage.SealTicket) + // t.t.Ticket (storage.SealTicket) (struct) { @@ -236,7 +237,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { } } - // t.t.PreCommitMessage (cid.Cid) + // t.t.PreCommitMessage (cid.Cid) (struct) { @@ -260,7 +261,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { } } - // t.t.RandHeight (uint64) + // t.t.RandHeight (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -269,8 +270,8 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.RandHeight = extra - // t.t.RandTs (types.TipSet) + t.RandHeight = uint64(extra) + // t.t.RandTs (types.TipSet) (struct) { @@ -291,7 +292,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { } } - // t.t.CommitMessage (cid.Cid) + // t.t.CommitMessage (cid.Cid) (struct) { From 3020f7a203973bc0a33857016d953b7480c8f3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 5 Nov 2019 19:19:57 +0100 Subject: [PATCH 037/114] Fix statestore.List --- lib/statestore/store.go | 2 +- lib/statestore/store_test.go | 38 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 lib/statestore/store_test.go diff --git a/lib/statestore/store.go b/lib/statestore/store.go index f578c17e3..ca924d66e 100644 --- a/lib/statestore/store.go +++ b/lib/statestore/store.go @@ -136,7 +136,7 @@ func (st *StateStore) List(out interface{}) error { return err } - rout.Set(reflect.Append(rout.Elem(), elem.Elem())) + rout.Elem().Set(reflect.Append(rout.Elem(), elem.Elem())) } return nil diff --git a/lib/statestore/store_test.go b/lib/statestore/store_test.go new file mode 100644 index 000000000..667805b0c --- /dev/null +++ b/lib/statestore/store_test.go @@ -0,0 +1,38 @@ +package statestore + +import ( + "testing" + + "github.com/ipfs/go-datastore" + + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/cborrpc" +) + +func TestList(t *testing.T) { + ds := datastore.NewMapDatastore() + + e, err := cborrpc.Dump(types.NewInt(7)) + if err != nil { + t.Fatal(err) + } + + if err := ds.Put(datastore.NewKey("/2"), e); err != nil { + t.Fatal(err) + } + + st := &StateStore{ds:ds} + + var out []types.BigInt + if err := st.List(&out); err != nil { + t.Fatal(err) + } + + if len(out) != 1 { + t.Fatal("wrong len") + } + + if out[0].Int64() != 7 { + t.Fatal("wrong data") + } +} From 630134486da0308cfba429c7705e2734a819ba05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 5 Nov 2019 19:40:51 +0100 Subject: [PATCH 038/114] Mostly fix deals --- chain/deals/provider.go | 7 ++-- chain/deals/provider_states.go | 57 ++++++++---------------------- lib/jsonrpc/client.go | 4 +-- lib/sectorbuilder/mock.go | 2 +- lib/sectorbuilder/sectorbuilder.go | 4 +-- lib/statestore/store_test.go | 2 +- 6 files changed, 25 insertions(+), 51 deletions(-) diff --git a/chain/deals/provider.go b/chain/deals/provider.go index 02966c05d..18420fb14 100644 --- a/chain/deals/provider.go +++ b/chain/deals/provider.go @@ -2,7 +2,6 @@ package deals import ( "context" - "github.com/filecoin-project/lotus/lib/statestore" "sync" cid "github.com/ipfs/go-cid" @@ -17,8 +16,10 @@ import ( "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/statestore" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/storage" + "github.com/filecoin-project/lotus/storage/sectorblocks" ) type MinerDeal struct { @@ -42,6 +43,7 @@ type Provider struct { ask *types.SignedStorageAsk askLk sync.Mutex + secb *sectorblocks.SectorBlocks sminer *storage.Miner full api.FullNode @@ -69,7 +71,7 @@ type minerDealUpdate struct { mut func(*MinerDeal) } -func NewProvider(ds dtypes.MetadataDS, sminer *storage.Miner, dag dtypes.StagingDAG, fullNode api.FullNode) (*Provider, error) { +func NewProvider(ds dtypes.MetadataDS, sminer *storage.Miner, secb *sectorblocks.SectorBlocks, dag dtypes.StagingDAG, fullNode api.FullNode) (*Provider, error) { addr, err := ds.Get(datastore.NewKey("miner-address")) if err != nil { return nil, err @@ -83,6 +85,7 @@ func NewProvider(ds dtypes.MetadataDS, sminer *storage.Miner, dag dtypes.Staging sminer: sminer, dag: dag, full: fullNode, + secb: secb, pricePerByteBlock: types.NewInt(3), // TODO: allow setting minPieceSize: 1, diff --git a/chain/deals/provider_states.go b/chain/deals/provider_states.go index c43628d13..9f5964cab 100644 --- a/chain/deals/provider_states.go +++ b/chain/deals/provider_states.go @@ -13,7 +13,6 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/storage/sectorblocks" ) @@ -228,54 +227,26 @@ func (p *Provider) staged(ctx context.Context, deal MinerDeal) (func(*MinerDeal) if err != nil { return nil, err } - _ = pcid - /* - sectorID, err := p.sminer.AddUnixfsPiece(pcid, uf, deal.DealID) - if err != nil { - return nil, xerrors.Errorf("AddPiece failed: %s", err) - } - log.Warnf("New Sector: %d", sectorID) + sectorID, err := p.secb.AddUnixfsPiece(pcid, uf, deal.DealID) + if err != nil { + return nil, xerrors.Errorf("AddPiece failed: %s", err) + } + log.Warnf("New Sector: %d", sectorID) + + return func(deal *MinerDeal) { + deal.SectorID = sectorID + }, nil - return func(deal *MinerDeal) { - deal.SectorID = sectorID - }, nil - */ - panic("fixme") } // SEALING -func (p *Provider) waitSealed(ctx context.Context, deal MinerDeal) (sectorbuilder.SectorSealingStatus, error) { - panic("fixme") - - /* - status, err := p.sminer.WaitSeal(ctx, deal.SectorID) - if err != nil { - return sectorbuilder.SectorSealingStatus{}, err - } - - switch status.State { - case sealing_state.Sealed: - case sealing_state.Failed: - return sectorbuilder.SectorSealingStatus{}, xerrors.Errorf("sealing sector %d for deal %s (ref=%s) failed: %s", deal.SectorID, deal.ProposalCid, deal.Ref, status.SealErrorMsg) - case sealing_state.Pending: - return sectorbuilder.SectorSealingStatus{}, xerrors.Errorf("sector status was 'pending' after call to WaitSeal (for sector %d)", deal.SectorID) - case sealing_state.Sealing: - return sectorbuilder.SectorSealingStatus{}, xerrors.Errorf("sector status was 'wait' after call to WaitSeal (for sector %d)", deal.SectorID) - default: - return sectorbuilder.SectorSealingStatus{}, xerrors.Errorf("unknown SealStatusCode: %d", status.SectorID) - } - - return status, nil - */ - -} - func (p *Provider) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal), error) { err := p.sendSignedResponse(&Response{ State: api.DealSealing, Proposal: deal.ProposalCid, + // TODO: Send sector ID }) if err != nil { log.Warnf("Sending deal response failed: %s", err) @@ -284,11 +255,12 @@ func (p *Provider) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal if err := p.sminer.SealSector(ctx, deal.SectorID); err != nil { return nil, xerrors.Errorf("sealing sector failed: %w", err) } + // TODO: Let's not care after this point, for now at least, client can watch the chain - _, err = p.waitSealed(ctx, deal) + /*_, err = p.waitSealed(ctx, deal) if err != nil { return nil, err - } + }*/ // TODO: Spec doesn't say anything about inclusion proofs anywhere // Not sure what mechanisms prevents miner from storing data that isn't // clients' data @@ -297,13 +269,12 @@ func (p *Provider) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal } func (p *Provider) complete(ctx context.Context, deal MinerDeal) (func(*MinerDeal), error) { - // TODO: Add dealID to commtracker (probably before sealing) /*mcid, err := p.commt.WaitCommit(ctx, deal.Proposal.Provider, deal.SectorID) if err != nil { log.Warnf("Waiting for sector commitment message: %s", err) }*/ - panic("fixme") + //panic("fixme") /*err = p.sendSignedResponse(&Response{ State: api.DealComplete, diff --git a/lib/jsonrpc/client.go b/lib/jsonrpc/client.go index 81cf4ec0a..45b52c0e0 100644 --- a/lib/jsonrpc/client.go +++ b/lib/jsonrpc/client.go @@ -177,9 +177,9 @@ func (c *client) makeOutChan(ctx context.Context, ftyp reflect.Type, valOut int) front := buf.Front() bufLk.Unlock() - cases := []reflect.SelectCase{ + cases := []reflect.SelectCase{ { - Dir: reflect.SelectRecv, + Dir: reflect.SelectRecv, Chan: reflect.ValueOf(chCtx.Done()), }, { diff --git a/lib/sectorbuilder/mock.go b/lib/sectorbuilder/mock.go index 619ccb988..451757b17 100644 --- a/lib/sectorbuilder/mock.go +++ b/lib/sectorbuilder/mock.go @@ -32,7 +32,7 @@ func TempSectorbuilder(sectorSize uint64) (*SectorBuilder, func(), error) { CacheDir: cache, WorkerThreads: 2, - Miner: addr, + Miner: addr, }) if err != nil { return nil, nil, err diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index e773988e0..9484823b0 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -71,8 +71,8 @@ func New(cfg *Config) (*SectorBuilder, error) { } return &SectorBuilder{ - handle: sbp, - Miner: cfg.Miner, + handle: sbp, + Miner: cfg.Miner, rateLimit: make(chan struct{}, cfg.WorkerThreads-PoStReservedWorkers), }, nil } diff --git a/lib/statestore/store_test.go b/lib/statestore/store_test.go index 667805b0c..0d17ef20d 100644 --- a/lib/statestore/store_test.go +++ b/lib/statestore/store_test.go @@ -21,7 +21,7 @@ func TestList(t *testing.T) { t.Fatal(err) } - st := &StateStore{ds:ds} + st := &StateStore{ds: ds} var out []types.BigInt if err := st.List(&out); err != nil { From b447b6cf0ab35b80fc94f5000c2299ee5680cb50 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Tue, 5 Nov 2019 10:50:27 -0800 Subject: [PATCH 039/114] only trim zeros to the right of the decimal --- chain/types/bigint_test.go | 17 +++++++++++++++++ chain/types/fil.go | 5 ++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/chain/types/bigint_test.go b/chain/types/bigint_test.go index 7e2cd71f4..5209e7051 100644 --- a/chain/types/bigint_test.go +++ b/chain/types/bigint_test.go @@ -32,3 +32,20 @@ func TestBigIntSerializationRoundTrip(t *testing.T) { } } + +func TestFilRoundTrip(t *testing.T) { + testValues := []string{ + "0", "1", "1.001", "100.10001", "101100", "5000.01", "5000", + } + + for _, v := range testValues { + fval, err := ParseFIL(v) + if err != nil { + t.Fatal(err) + } + + if fval.String() != v { + t.Fatal("mismatch in values!", v, fval.String()) + } + } +} diff --git a/chain/types/fil.go b/chain/types/fil.go index f44336fb5..80de6ced3 100644 --- a/chain/types/fil.go +++ b/chain/types/fil.go @@ -12,7 +12,10 @@ type FIL BigInt func (f FIL) String() string { r := new(big.Rat).SetFrac(f.Int, big.NewInt(build.FilecoinPrecision)) - return strings.TrimRight(r.FloatString(18), "0.") + if r.Sign() == 0 { + return "0" + } + return strings.TrimRight(strings.TrimRight(r.FloatString(18), "0"), ".") } func (f FIL) Format(s fmt.State, ch rune) { From ba1e8c66684773ec8a6942d0edfa9bd434d7fc38 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Tue, 5 Nov 2019 13:10:20 -0800 Subject: [PATCH 040/114] add proper piece padding in AddPiece --- storage/sector/store.go | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/storage/sector/store.go b/storage/sector/store.go index 52c45deef..40192b49d 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "math" "sync" "github.com/filecoin-project/go-sectorbuilder/sealing_state" @@ -59,8 +60,33 @@ func (s *Store) SectorStatus(sid uint64) (*sectorbuilder.SectorSealingStatus, er return &status, nil } +func computePaddedSize(size uint64) uint64 { + // TODO: there is a better way to compute the log2 of an integer... i'm just lazy + logv := uint64(math.Log2(float64(size))) + + sectSize := uint64(1 << (logv + 1)) + bound := sectorbuilder.UserBytesForSectorSize(sectSize) + if size <= bound { + return bound + } + + return sectorbuilder.UserBytesForSectorSize(1 << (logv + 2)) +} + +type nullReader struct{} + +func (nr nullReader) Read(b []byte) (int, error) { + for i := range b { + b[i] = 0 + } + return len(b), nil +} + func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64) (sectorID uint64, err error) { - sectorID, err = s.sb.AddPiece(ref, size, r) + padSize := computePaddedSize(size) + + r = io.MultiReader(r, io.LimitReader(nullReader{}, int64(padSize-size))) + sectorID, err = s.sb.AddPiece(ref, padSize, r) if err != nil { return 0, err } From 87616e1c0322316a183d1362cad7f1053dbfe2f9 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Tue, 5 Nov 2019 15:57:46 -0800 Subject: [PATCH 041/114] use better math --- storage/sector/store.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/storage/sector/store.go b/storage/sector/store.go index 40192b49d..0112e3f4a 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -1,10 +1,11 @@ package sector import ( + "bytes" "context" "fmt" "io" - "math" + "math/bits" "sync" "github.com/filecoin-project/go-sectorbuilder/sealing_state" @@ -61,16 +62,15 @@ func (s *Store) SectorStatus(sid uint64) (*sectorbuilder.SectorSealingStatus, er } func computePaddedSize(size uint64) uint64 { - // TODO: there is a better way to compute the log2 of an integer... i'm just lazy - logv := uint64(math.Log2(float64(size))) + logv := 64 - bits.LeadingZeros64(size) - sectSize := uint64(1 << (logv + 1)) + sectSize := uint64(1 << logv) bound := sectorbuilder.UserBytesForSectorSize(sectSize) if size <= bound { return bound } - return sectorbuilder.UserBytesForSectorSize(1 << (logv + 2)) + return sectorbuilder.UserBytesForSectorSize(1 << (logv + 1)) } type nullReader struct{} From 1fc0971db07c17398389a2cd3496da6cdf242bad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 6 Nov 2019 13:03:36 +0100 Subject: [PATCH 042/114] sectorstore: test computePaddedSize --- storage/sector/store.go | 1 - storage/sector/store_test.go | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 storage/sector/store_test.go diff --git a/storage/sector/store.go b/storage/sector/store.go index 0112e3f4a..64260b9f9 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -1,7 +1,6 @@ package sector import ( - "bytes" "context" "fmt" "io" diff --git a/storage/sector/store_test.go b/storage/sector/store_test.go new file mode 100644 index 000000000..5d473ba18 --- /dev/null +++ b/storage/sector/store_test.go @@ -0,0 +1,12 @@ +package sector + +import ( + "gotest.tools/assert" + "testing" +) + +func TestComputePaddedSize(t *testing.T) { + assert.Equal(t, uint64(1040384), computePaddedSize(1000000)) + assert.Equal(t, uint64(1016), computePaddedSize(548)) + assert.Equal(t, uint64(4064), computePaddedSize(2048)) +} \ No newline at end of file From be58a51f9f673a8e6291d18cc4600d72b0fe57dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 6 Nov 2019 13:03:59 +0100 Subject: [PATCH 043/114] paramfetch: env var to not check param files each time --- build/paramfetch.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/paramfetch.go b/build/paramfetch.go index 39e6ffda6..5b1f4068d 100644 --- a/build/paramfetch.go +++ b/build/paramfetch.go @@ -91,6 +91,10 @@ func (ft *fetch) maybeFetchAsync(name string, info paramFile) { } func (ft *fetch) checkFile(path string, info paramFile) error { + if os.Getenv("TRUST_PARAMS") == "1" { + log.Warn("Assuming parameter files are ok. DO NOT USE IN PRODUCTION") + } + f, err := os.Open(path) if err != nil { return err From cb3965bcf506c27311efa99bf3fdcaa117e09d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 6 Nov 2019 13:04:33 +0100 Subject: [PATCH 044/114] Improve errors around deal handling --- chain/deals/client_utils.go | 2 +- chain/deals/provider.go | 2 +- chain/deals/provider_utils.go | 2 +- lib/sectorbuilder/sectorbuilder.go | 11 ++++++++++- storage/sealing.go | 2 +- storage/sector/store_test.go | 4 ++-- storage/sectorblocks/blocks.go | 13 +++++++------ 7 files changed, 23 insertions(+), 13 deletions(-) diff --git a/chain/deals/client_utils.go b/chain/deals/client_utils.go index 9c26f4268..8a68f1cdd 100644 --- a/chain/deals/client_utils.go +++ b/chain/deals/client_utils.go @@ -25,7 +25,7 @@ func (c *Client) failDeal(id cid.Cid, cerr error) { } // TODO: store in some sort of audit log - log.Errorf("deal %s failed: %s", id, cerr) + log.Errorf("deal %s failed: %+v", id, cerr) } func (c *Client) dataSize(ctx context.Context, data cid.Cid) (int64, error) { diff --git a/chain/deals/provider.go b/chain/deals/provider.go index 18420fb14..608432352 100644 --- a/chain/deals/provider.go +++ b/chain/deals/provider.go @@ -162,7 +162,7 @@ func (p *Provider) onIncoming(deal MinerDeal) { func (p *Provider) onUpdated(ctx context.Context, update minerDealUpdate) { log.Infof("Deal %s updated state to %d", update.id, update.newState) if update.err != nil { - log.Errorf("deal %s (newSt: %d) failed: %s", update.id, update.newState, update.err) + log.Errorf("deal %s (newSt: %d) failed: %+v", update.id, update.newState, update.err) p.failDeal(update.id, update.err) return } diff --git a/chain/deals/provider_utils.go b/chain/deals/provider_utils.go index 5931cefc9..547ff8c76 100644 --- a/chain/deals/provider_utils.go +++ b/chain/deals/provider_utils.go @@ -26,7 +26,7 @@ func (p *Provider) failDeal(id cid.Cid, cerr error) { cerr = xerrors.Errorf("unknown error (fail called at %s:%d)", f, l) } - log.Errorf("deal %s failed: %s", id, cerr) + log.Warnf("deal %s failed: %s", id, cerr) err := p.sendSignedResponse(&Response{ State: api.DealFailed, diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 9484823b0..58f37cf56 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -231,11 +231,20 @@ func toReadableFile(r io.Reader, n int64) (*os.File, func() error, error) { go func() { defer wait.Unlock() - _, werr = io.CopyN(w, r, n) + copied, werr := io.CopyN(w, r, n) + if werr != nil { + log.Warnf("toReadableFile: copy error: %+v", werr) + } err := w.Close() if werr == nil { werr = err + log.Warnf("toReadableFile: close error: %+v", err) + return + } + if copied != n { + log.Warnf("copied different amount than expected: %d != %d", copied, n) + werr = xerrors.Errorf("copied different amount than expected: %d != %d", copied, n) } }() diff --git a/storage/sealing.go b/storage/sealing.go index d1883be3d..625a35c1b 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -114,7 +114,7 @@ func (m *Miner) onSectorUpdated(ctx context.Context, update sectorUpdate) { } func (m *Miner) failSector(id uint64, err error) { - log.Error(err) + log.Errorf("sector %d error: %+v", id, err) panic(err) // todo: better error handling strategy } diff --git a/storage/sector/store_test.go b/storage/sector/store_test.go index 5d473ba18..a2e1d00ac 100644 --- a/storage/sector/store_test.go +++ b/storage/sector/store_test.go @@ -5,8 +5,8 @@ import ( "testing" ) -func TestComputePaddedSize(t *testing.T) { +func TestComputePaddedSize(t *testing.T) { assert.Equal(t, uint64(1040384), computePaddedSize(1000000)) assert.Equal(t, uint64(1016), computePaddedSize(548)) assert.Equal(t, uint64(4064), computePaddedSize(2048)) -} \ No newline at end of file +} diff --git a/storage/sectorblocks/blocks.go b/storage/sectorblocks/blocks.go index 28b864e7a..4f1049f23 100644 --- a/storage/sectorblocks/blocks.go +++ b/storage/sectorblocks/blocks.go @@ -11,6 +11,7 @@ import ( blockstore "github.com/ipfs/go-ipfs-blockstore" ipld "github.com/ipfs/go-ipld-format" "github.com/ipfs/go-unixfs" + "golang.org/x/xerrors" "sync" "github.com/ipfs/go-cid" @@ -89,13 +90,13 @@ func (st *SectorBlocks) writeRef(cid cid.Cid, pieceRef string, offset uint64, si err = nil } if err != nil { - return err + return xerrors.Errorf("getting existing refs: %w", err) } var refs []api.SealedRef if len(v) > 0 { if err := cbor.DecodeInto(v, &refs); err != nil { - return err + return xerrors.Errorf("decoding existing refs: %w", err) } } @@ -107,7 +108,7 @@ func (st *SectorBlocks) writeRef(cid cid.Cid, pieceRef string, offset uint64, si newRef, err := cbor.DumpObject(&refs) if err != nil { - return err + return xerrors.Errorf("serializing refs: %w", err) } return st.keys.Put(dshelp.CidToDsKey(cid), newRef) // TODO: batch somehow } @@ -128,20 +129,20 @@ func (r *refStorer) Read(p []byte) (n int, err error) { for { data, offset, nd, err := r.blockReader.ReadBlock(context.TODO()) if err != nil { - return 0, err + return 0, xerrors.Errorf("reading block: %w", err) } if len(data) == 0 { // TODO: batch // TODO: GC if err := r.intermediate.Put(nd); err != nil { - return 0, err + return 0, xerrors.Errorf("storing intermediate node: %w", err) } continue } if err := r.writeRef(nd.Cid(), r.pieceRef, offset, uint32(len(data))); err != nil { - return 0, err + return 0, xerrors.Errorf("writing ref: %w", err) } read := copy(p, data) From 40b1f918433fcf6efd5bc801cca0118112124952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 6 Nov 2019 13:22:08 +0100 Subject: [PATCH 045/114] fix sector block ref serialization --- api/api_storage.go | 6 +- api/cbor_gen.go | 142 +++++++++++++++++++++++++++++++++ gen/main.go | 2 + storage/sectorblocks/blocks.go | 47 +++++------ 4 files changed, 173 insertions(+), 24 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index 7a392455f..75fc55849 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -69,5 +69,9 @@ type StorageMiner interface { type SealedRef struct { Piece string Offset uint64 - Size uint32 + Size uint64 +} + +type SealedRefs struct { + Refs []SealedRef } diff --git a/api/cbor_gen.go b/api/cbor_gen.go index 6f71bbaed..0f968865b 100644 --- a/api/cbor_gen.go +++ b/api/cbor_gen.go @@ -127,3 +127,145 @@ func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) error { return nil } + +func (t *SealedRef) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{131}); err != nil { + return err + } + + // t.t.Piece (string) (string) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Piece)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.Piece)); err != nil { + return err + } + + // t.t.Offset (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Offset))); err != nil { + return err + } + + // t.t.Size (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Size))); err != nil { + return err + } + return nil +} + +func (t *SealedRef) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 3 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.Piece (string) (string) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.Piece = string(sval) + } + // t.t.Offset (uint64) (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Offset = uint64(extra) + // t.t.Size (uint64) (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Size = uint64(extra) + return nil +} + +func (t *SealedRefs) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{129}); err != nil { + return err + } + + // t.t.Refs ([]api.SealedRef) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Refs)))); err != nil { + return err + } + for _, v := range t.Refs { + if err := v.MarshalCBOR(w); err != nil { + return err + } + } + return nil +} + +func (t *SealedRefs) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 1 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.Refs ([]api.SealedRef) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.Refs: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.Refs = make([]SealedRef, extra) + } + for i := 0; i < int(extra); i++ { + + var v SealedRef + if err := v.UnmarshalCBOR(br); err != nil { + return err + } + + t.Refs[i] = v + } + + return nil +} diff --git a/gen/main.go b/gen/main.go index 1aac6ef06..296b7bbf4 100644 --- a/gen/main.go +++ b/gen/main.go @@ -48,6 +48,8 @@ func main() { err = gen.WriteTupleEncodersToFile("./api/cbor_gen.go", "api", api.PaymentInfo{}, + api.SealedRef{}, + api.SealedRefs{}, ) if err != nil { fmt.Println(err) diff --git a/storage/sectorblocks/blocks.go b/storage/sectorblocks/blocks.go index 4f1049f23..d8666b41c 100644 --- a/storage/sectorblocks/blocks.go +++ b/storage/sectorblocks/blocks.go @@ -1,25 +1,26 @@ package sectorblocks import ( + "bytes" "context" "errors" - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/lib/sectorbuilder" - "github.com/filecoin-project/lotus/node/modules/dtypes" - "github.com/ipfs/go-datastore/namespace" - "github.com/ipfs/go-datastore/query" - blockstore "github.com/ipfs/go-ipfs-blockstore" - ipld "github.com/ipfs/go-ipld-format" - "github.com/ipfs/go-unixfs" - "golang.org/x/xerrors" "sync" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/namespace" + "github.com/ipfs/go-datastore/query" + blockstore "github.com/ipfs/go-ipfs-blockstore" dshelp "github.com/ipfs/go-ipfs-ds-help" files "github.com/ipfs/go-ipfs-files" - cbor "github.com/ipfs/go-ipld-cbor" + ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-unixfs" + "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/sectorbuilder" + "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/storage/sector" ) @@ -74,14 +75,14 @@ type UnixfsReader interface { type refStorer struct { blockReader UnixfsReader - writeRef func(cid cid.Cid, pieceRef string, offset uint64, size uint32) error + writeRef func(cid cid.Cid, pieceRef string, offset uint64, size uint64) error intermediate blockstore.Blockstore pieceRef string remaining []byte } -func (st *SectorBlocks) writeRef(cid cid.Cid, pieceRef string, offset uint64, size uint32) error { +func (st *SectorBlocks) writeRef(cid cid.Cid, pieceRef string, offset uint64, size uint64) error { st.keyLk.Lock() // TODO: make this multithreaded defer st.keyLk.Unlock() @@ -93,20 +94,20 @@ func (st *SectorBlocks) writeRef(cid cid.Cid, pieceRef string, offset uint64, si return xerrors.Errorf("getting existing refs: %w", err) } - var refs []api.SealedRef + var refs api.SealedRefs if len(v) > 0 { - if err := cbor.DecodeInto(v, &refs); err != nil { + if err := cborrpc.ReadCborRPC(bytes.NewReader(v), &refs); err != nil { return xerrors.Errorf("decoding existing refs: %w", err) } } - refs = append(refs, api.SealedRef{ + refs.Refs = append(refs.Refs, api.SealedRef{ Piece: pieceRef, Offset: offset, Size: size, }) - newRef, err := cbor.DumpObject(&refs) + newRef, err := cborrpc.Dump(&refs) if err != nil { return xerrors.Errorf("serializing refs: %w", err) } @@ -141,7 +142,7 @@ func (r *refStorer) Read(p []byte) (n int, err error) { continue } - if err := r.writeRef(nd.Cid(), r.pieceRef, offset, uint32(len(data))); err != nil { + if err := r.writeRef(nd.Cid(), r.pieceRef, offset, uint64(len(data))); err != nil { return 0, xerrors.Errorf("writing ref: %w", err) } @@ -188,12 +189,12 @@ func (st *SectorBlocks) List() (map[cid.Cid][]api.SealedRef, error) { return nil, err } - var refs []api.SealedRef - if err := cbor.DecodeInto(ent.Value, &refs); err != nil { + var refs api.SealedRefs + if err := cborrpc.ReadCborRPC(bytes.NewReader(ent.Value), &refs); err != nil { return nil, err } - out[refCid] = refs + out[refCid] = refs.Refs } return out, nil @@ -208,12 +209,12 @@ func (st *SectorBlocks) GetRefs(k cid.Cid) ([]api.SealedRef, error) { // TODO: t return nil, err } - var refs []api.SealedRef - if err := cbor.DecodeInto(ent, &refs); err != nil { + var refs api.SealedRefs + if err := cborrpc.ReadCborRPC(bytes.NewReader(ent), &refs); err != nil { return nil, err } - return refs, nil + return refs.Refs, nil } func (st *SectorBlocks) GetSize(k cid.Cid) (uint64, error) { From 58229defcd5af18c8587250010860e7cefe5a750 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 6 Nov 2019 16:10:27 +0100 Subject: [PATCH 046/114] Fix faucet ip limiting to use X-Real-IP License: MIT Signed-off-by: Jakub Sztandera --- cmd/lotus-fountain/main.go | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index 6d590bb0c..bd8127683 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -3,6 +3,7 @@ package main import ( "context" "fmt" + "net" "net/http" "os" "strconv" @@ -24,7 +25,7 @@ import ( var log = logging.Logger("main") -var sendPerRequest = types.NewInt(500_000_000) +var sendPerRequest, _ = types.ParseFIL("0.005") func main() { logging.SetLogLevel("*", "INFO") @@ -104,7 +105,7 @@ var runCmd = &cli.Command{ TotalRate: time.Second, TotalBurst: 20, IPRate: 10 * time.Minute, - IPBurst: 1, + IPBurst: 2, WalletRate: 1 * time.Hour, WalletBurst: 1, }), @@ -151,7 +152,20 @@ func (h *handler) send(w http.ResponseWriter, r *http.Request) { } // Limit based on IP - limiter = h.limiter.GetIPLimiter(r.RemoteAddr) + + reqIP := r.Header.Get("X-Real-IP") + if reqIP == "" { + h, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + log.Errorf("could not get ip from: %s, err: %s", r.RemoteAddr, err) + } + reqIP = h + } + if i := net.ParseIP(reqIP); i != nil && i.IsLoopback() { + log.Errorf("rate limiting localhost: %s", reqIP) + } + + limiter = h.limiter.GetIPLimiter(reqIP) if !limiter.Allow() { http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests) return @@ -164,7 +178,7 @@ func (h *handler) send(w http.ResponseWriter, r *http.Request) { } smsg, err := h.api.MpoolPushMessage(h.ctx, &types.Message{ - Value: sendPerRequest, + Value: types.BigInt(sendPerRequest), From: h.from, To: to, @@ -229,7 +243,7 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) { } smsg, err := h.api.MpoolPushMessage(h.ctx, &types.Message{ - Value: sendPerRequest, + Value: types.BigInt(sendPerRequest), From: h.from, To: owner, From 2b57fd14f10aa9004b7bedbd3fae811ec63d21e7 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 6 Nov 2019 16:11:19 +0100 Subject: [PATCH 047/114] Fix temporal problems in bad block cache License: MIT Signed-off-by: Jakub Sztandera --- chain/sync.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/chain/sync.go b/chain/sync.go index dac2a79e5..8c438b0c0 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -2,6 +2,7 @@ package chain import ( "context" + "errors" "fmt" "sync" "time" @@ -379,7 +380,9 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet) for _, b := range fts.Blocks { if err := syncer.ValidateBlock(ctx, b); err != nil { - syncer.bad.Add(b.Cid()) + if !errors.Is(err, ErrTemporal) { + syncer.bad.Add(b.Cid()) + } return xerrors.Errorf("validating block %s: %w", b.Cid(), err) } @@ -444,6 +447,8 @@ func (syncer *Syncer) validateTickets(ctx context.Context, mworker address.Addre return nil } +var ErrTemporal = errors.New("temporal error") + // Should match up with 'Semantical Validation' in validation.md in the spec func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error { ctx, span := trace.StartSpan(ctx, "validateBlock") @@ -470,7 +475,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err } if h.Timestamp > uint64(time.Now().Unix()+build.AllowableClockDrift) { - return xerrors.Errorf("block was from the future") + return xerrors.Errorf("block was from the future: %w", ErrTemporal) } if h.Timestamp < baseTs.MinTimestamp()+uint64(build.BlockDelay*len(h.Tickets)) { From 68c2d4f58a1369a1ba72f42b8291783c228276f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 6 Nov 2019 18:38:42 +0100 Subject: [PATCH 048/114] deals: Set correct Refs --- chain/deals/cbor_gen.go | 37 ++++++++++++++++++++++++++++++--- chain/deals/client.go | 23 ++++++++++++-------- chain/deals/client_utils.go | 24 ++++++++++++++++----- chain/deals/provider.go | 11 +++------- chain/deals/provider_states.go | 8 +------ chain/deals/provider_utils.go | 9 ++++---- chain/deals/types.go | 8 ++++--- lib/padreader/padreader.go | 38 ++++++++++++++++++++++++++++++++++ node/impl/client/client.go | 1 - storage/sector/store.go | 27 +----------------------- storage/sectorblocks/blocks.go | 4 ++++ 11 files changed, 123 insertions(+), 67 deletions(-) create mode 100644 lib/padreader/padreader.go diff --git a/chain/deals/cbor_gen.go b/chain/deals/cbor_gen.go index ec46764f9..08edb9371 100644 --- a/chain/deals/cbor_gen.go +++ b/chain/deals/cbor_gen.go @@ -118,7 +118,7 @@ func (t *Proposal) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{129}); err != nil { + if _, err := w.Write([]byte{130}); err != nil { return err } @@ -126,6 +126,13 @@ func (t *Proposal) MarshalCBOR(w io.Writer) error { if err := t.DealProposal.MarshalCBOR(w); err != nil { return err } + + // t.t.Piece (cid.Cid) (struct) + + if err := cbg.WriteCid(w, t.Piece); err != nil { + return xerrors.Errorf("failed to write cid field t.Piece: %w", err) + } + return nil } @@ -140,7 +147,7 @@ func (t *Proposal) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 1 { + if extra != 2 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -148,9 +155,33 @@ func (t *Proposal) UnmarshalCBOR(r io.Reader) error { { - if err := t.DealProposal.UnmarshalCBOR(br); err != nil { + pb, err := br.PeekByte() + if err != nil { return err } + if pb == cbg.CborNull[0] { + var nbuf [1]byte + if _, err := br.Read(nbuf[:]); err != nil { + return err + } + } else { + t.DealProposal = new(actors.StorageDealProposal) + if err := t.DealProposal.UnmarshalCBOR(br); err != nil { + return err + } + } + + } + // t.t.Piece (cid.Cid) (struct) + + { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Piece: %w", err) + } + + t.Piece = c } return nil diff --git a/chain/deals/client.go b/chain/deals/client.go index e89a9886f..b99422e11 100644 --- a/chain/deals/client.go +++ b/chain/deals/client.go @@ -201,25 +201,25 @@ func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, erro } } - dataSize, err := c.dataSize(ctx, p.Data) + commP, pieceSize, err := c.commP(ctx, p.Data) - proposal := &actors.StorageDealProposal{ - PieceRef: p.Data.Bytes(), - PieceSize: uint64(dataSize), + dealProposal := &actors.StorageDealProposal{ + PieceRef: commP, + PieceSize: uint64(pieceSize), PieceSerialization: actors.SerializationUnixFSv0, Client: p.Client, Provider: p.ProviderAddress, ProposalExpiration: p.ProposalExpiration, Duration: p.Duration, StoragePricePerEpoch: p.PricePerEpoch, - StorageCollateral: types.NewInt(uint64(dataSize)), // TODO: real calc + StorageCollateral: types.NewInt(uint64(pieceSize)), // TODO: real calc } - if err := api.SignWith(ctx, c.w.Sign, p.Client, proposal); err != nil { + if err := api.SignWith(ctx, c.w.Sign, p.Client, dealProposal); err != nil { return cid.Undef, xerrors.Errorf("signing deal proposal failed: %w", err) } - proposalNd, err := cborrpc.AsIpld(proposal) + proposalNd, err := cborrpc.AsIpld(dealProposal) if err != nil { return cid.Undef, xerrors.Errorf("getting proposal node failed: %w", err) } @@ -230,6 +230,11 @@ func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, erro return cid.Undef, xerrors.Errorf("connecting to storage provider failed: %w", err) } + proposal := &Proposal{ + DealProposal: dealProposal, + Piece: p.Data, + } + if err := cborrpc.WriteCborRPC(s, proposal); err != nil { s.Reset() return cid.Undef, xerrors.Errorf("sending proposal to storage provider failed: %w", err) @@ -237,7 +242,7 @@ func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, erro deal := &ClientDeal{ ProposalCid: proposalNd.Cid(), - Proposal: *proposal, + Proposal: *dealProposal, State: api.DealUnknown, Miner: p.MinerID, @@ -247,7 +252,7 @@ func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, erro c.incoming <- deal return deal.ProposalCid, c.discovery.AddPeer(p.Data, discovery.RetrievalPeer{ - Address: proposal.Provider, + Address: dealProposal.Provider, ID: deal.Miner, }) } diff --git a/chain/deals/client_utils.go b/chain/deals/client_utils.go index 8a68f1cdd..135f696a7 100644 --- a/chain/deals/client_utils.go +++ b/chain/deals/client_utils.go @@ -10,6 +10,8 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/padreader" + "github.com/filecoin-project/lotus/lib/sectorbuilder" ) func (c *Client) failDeal(id cid.Cid, cerr error) { @@ -28,26 +30,38 @@ func (c *Client) failDeal(id cid.Cid, cerr error) { log.Errorf("deal %s failed: %+v", id, cerr) } -func (c *Client) dataSize(ctx context.Context, data cid.Cid) (int64, error) { +func (c *Client) commP(ctx context.Context, data cid.Cid) ([]byte, uint64, error) { root, err := c.dag.Get(ctx, data) if err != nil { log.Errorf("failed to get file root for deal: %s", err) - return 0, err + return nil, 0, err } n, err := unixfile.NewUnixfsFile(ctx, c.dag, root) if err != nil { log.Errorf("cannot open unixfs file: %s", err) - return 0, err + return nil, 0, err } uf, ok := n.(files.File) if !ok { // TODO: we probably got directory, how should we handle this in unixfs mode? - return 0, xerrors.New("unsupported unixfs type") + return nil, 0, xerrors.New("unsupported unixfs type") } - return uf.Size() + s, err := uf.Size() + if err != nil { + return nil, 0, err + } + + pr, psize := padreader.New(uf, uint64(s)) + + commp, err := sectorbuilder.GeneratePieceCommitment(pr, psize) + if err != nil { + return nil, 0, xerrors.Errorf("generating CommP: %w", err) + } + + return commp[:], psize, nil } func (c *Client) readStorageDealResp(deal ClientDeal) (*Response, error) { diff --git a/chain/deals/provider.go b/chain/deals/provider.go index 608432352..ecabc7d13 100644 --- a/chain/deals/provider.go +++ b/chain/deals/provider.go @@ -192,24 +192,19 @@ func (p *Provider) onUpdated(ctx context.Context, update minerDealUpdate) { } } -func (p *Provider) newDeal(s inet.Stream, proposal actors.StorageDealProposal) (MinerDeal, error) { +func (p *Provider) newDeal(s inet.Stream, proposal Proposal) (MinerDeal, error) { proposalNd, err := cborrpc.AsIpld(&proposal) if err != nil { return MinerDeal{}, err } - ref, err := cid.Cast(proposal.PieceRef) - if err != nil { - return MinerDeal{}, err - } - return MinerDeal{ Client: s.Conn().RemotePeer(), - Proposal: proposal, + Proposal: *proposal.DealProposal, ProposalCid: proposalNd.Cid(), State: api.DealUnknown, - Ref: ref, + Ref: proposal.Piece, s: s, }, nil diff --git a/chain/deals/provider_states.go b/chain/deals/provider_states.go index 9f5964cab..ea5c6c772 100644 --- a/chain/deals/provider_states.go +++ b/chain/deals/provider_states.go @@ -4,7 +4,6 @@ import ( "bytes" "context" - "github.com/ipfs/go-cid" "github.com/ipfs/go-merkledag" unixfile "github.com/ipfs/go-unixfs/file" "golang.org/x/xerrors" @@ -223,12 +222,7 @@ func (p *Provider) staged(ctx context.Context, deal MinerDeal) (func(*MinerDeal) return nil, xerrors.Errorf("deal.Proposal.PieceSize didn't match unixfs file size") } - pcid, err := cid.Cast(deal.Proposal.PieceRef) - if err != nil { - return nil, err - } - - sectorID, err := p.secb.AddUnixfsPiece(pcid, uf, deal.DealID) + sectorID, err := p.secb.AddUnixfsPiece(deal.Ref, uf, deal.DealID) if err != nil { return nil, xerrors.Errorf("AddPiece failed: %s", err) } diff --git a/chain/deals/provider_utils.go b/chain/deals/provider_utils.go index 547ff8c76..2ea5dc05e 100644 --- a/chain/deals/provider_utils.go +++ b/chain/deals/provider_utils.go @@ -5,7 +5,6 @@ import ( "runtime" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" @@ -45,21 +44,21 @@ func (p *Provider) failDeal(id cid.Cid, cerr error) { } } -func (p *Provider) readProposal(s inet.Stream) (proposal actors.StorageDealProposal, err error) { +func (p *Provider) readProposal(s inet.Stream) (proposal Proposal, err error) { if err := cborrpc.ReadCborRPC(s, &proposal); err != nil { log.Errorw("failed to read proposal message", "error", err) return proposal, err } - if err := proposal.Verify(); err != nil { + if err := proposal.DealProposal.Verify(); err != nil { return proposal, xerrors.Errorf("verifying StorageDealProposal: %w", err) } // TODO: Validate proposal maybe // (and signature, obviously) - if proposal.Provider != p.actor { - log.Errorf("proposal with wrong ProviderAddress: %s", proposal.Provider) + if proposal.DealProposal.Provider != p.actor { + log.Errorf("proposal with wrong ProviderAddress: %s", proposal.DealProposal.Provider) return proposal, err } diff --git a/chain/deals/types.go b/chain/deals/types.go index 27bf31a8b..2177517ab 100644 --- a/chain/deals/types.go +++ b/chain/deals/types.go @@ -8,11 +8,13 @@ import ( "github.com/ipfs/go-cid" ) -const DealProtocolID = "/fil/storage/mk/1.0.0" -const AskProtocolID = "/fil/storage/ask/1.0.0" +const DealProtocolID = "/fil/storage/mk/1.0.1" +const AskProtocolID = "/fil/storage/ask/1.0.1" type Proposal struct { - DealProposal actors.StorageDealProposal + DealProposal *actors.StorageDealProposal + + Piece cid.Cid // Used for retrieving from the client } type Response struct { diff --git a/lib/padreader/padreader.go b/lib/padreader/padreader.go new file mode 100644 index 000000000..135e35b57 --- /dev/null +++ b/lib/padreader/padreader.go @@ -0,0 +1,38 @@ +package padreader + +import ( + "io" + "math/bits" + + sectorbuilder "github.com/filecoin-project/go-sectorbuilder" +) + +func PaddedSize(size uint64) uint64 { + logv := 64 - bits.LeadingZeros64(size) + + sectSize := uint64(1 << logv) + bound := sectorbuilder.GetMaxUserBytesPerStagedSector(sectSize) + if size <= bound { + return bound + } + + return sectorbuilder.GetMaxUserBytesPerStagedSector(1 << (logv + 1)) +} + +type nullReader struct{} + +func (nr nullReader) Read(b []byte) (int, error) { + for i := range b { + b[i] = 0 + } + return len(b), nil +} + +func New(r io.Reader, size uint64) (io.Reader, uint64) { + padSize := PaddedSize(size) + + return io.MultiReader( + io.LimitReader(r, int64(size)), + io.LimitReader(nullReader{}, int64(padSize-size)), + ), padSize +} diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 85e9ca4f7..17ab26731 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -88,7 +88,6 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.A } c, err := a.DealClient.Start(ctx, proposal) - // TODO: send updated voucher with PaymentVerifySector for cheaper validation (validate the sector the miner sent us first!) return &c, err } diff --git a/storage/sector/store.go b/storage/sector/store.go index 64260b9f9..52c45deef 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "math/bits" "sync" "github.com/filecoin-project/go-sectorbuilder/sealing_state" @@ -60,32 +59,8 @@ func (s *Store) SectorStatus(sid uint64) (*sectorbuilder.SectorSealingStatus, er return &status, nil } -func computePaddedSize(size uint64) uint64 { - logv := 64 - bits.LeadingZeros64(size) - - sectSize := uint64(1 << logv) - bound := sectorbuilder.UserBytesForSectorSize(sectSize) - if size <= bound { - return bound - } - - return sectorbuilder.UserBytesForSectorSize(1 << (logv + 1)) -} - -type nullReader struct{} - -func (nr nullReader) Read(b []byte) (int, error) { - for i := range b { - b[i] = 0 - } - return len(b), nil -} - func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64) (sectorID uint64, err error) { - padSize := computePaddedSize(size) - - r = io.MultiReader(r, io.LimitReader(nullReader{}, int64(padSize-size))) - sectorID, err = s.sb.AddPiece(ref, padSize, r) + sectorID, err = s.sb.AddPiece(ref, size, r) if err != nil { return 0, err } diff --git a/storage/sectorblocks/blocks.go b/storage/sectorblocks/blocks.go index d8666b41c..d46ef9f1b 100644 --- a/storage/sectorblocks/blocks.go +++ b/storage/sectorblocks/blocks.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "errors" + "io" "sync" "github.com/ipfs/go-cid" @@ -130,6 +131,9 @@ func (r *refStorer) Read(p []byte) (n int, err error) { for { data, offset, nd, err := r.blockReader.ReadBlock(context.TODO()) if err != nil { + if err == io.EOF { + return 0, io.EOF + } return 0, xerrors.Errorf("reading block: %w", err) } From 37721b2a2207ccb6df6f36e25d02e1aa92e9f6c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 6 Nov 2019 20:00:04 +0100 Subject: [PATCH 049/114] Get some deals to work --- chain/deals/provider_states.go | 5 +++-- lotuspond/front/src/Client.js | 4 ++-- storage/sectorblocks/blocks.go | 5 ++++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/chain/deals/provider_states.go b/chain/deals/provider_states.go index ea5c6c772..5e5dbc273 100644 --- a/chain/deals/provider_states.go +++ b/chain/deals/provider_states.go @@ -12,6 +12,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/storage/sectorblocks" ) @@ -218,8 +219,8 @@ func (p *Provider) staged(ctx context.Context, deal MinerDeal) (func(*MinerDeal) if err != nil { return nil, xerrors.Errorf("getting unixfs file size: %w", err) } - if uint64(size) != deal.Proposal.PieceSize { - return nil, xerrors.Errorf("deal.Proposal.PieceSize didn't match unixfs file size") + if padreader.PaddedSize(uint64(size)) != deal.Proposal.PieceSize { + return nil, xerrors.Errorf("deal.Proposal.PieceSize didn't match padded unixfs file size") } sectorID, err := p.secb.AddUnixfsPiece(deal.Ref, uf, deal.DealID) diff --git a/lotuspond/front/src/Client.js b/lotuspond/front/src/Client.js index 37606223b..70aabfd6f 100644 --- a/lotuspond/front/src/Client.js +++ b/lotuspond/front/src/Client.js @@ -21,7 +21,7 @@ class Client extends React.Component { this.state = { miners: ["t0101"], - ask: {Price: "500000000"}, + ask: {Price: "1000000000"}, // 2x min default ask to account for bin packing (could also do the math correctly below, but..) kbs: 1, blocks: 12, @@ -52,7 +52,7 @@ class Client extends React.Component { update = (name) => (e) => this.setState({ [name]: e.target.value }); makeDeal = async () => { - let perBlk = this.state.ask.Price * this.state.kbs * 1000 / (1 << 30) + let perBlk = this.state.ask.Price * this.state.kbs * 1000 / (1 << 30) * 2 let file = await this.props.pondClient.call('Pond.CreateRandomFile', [this.state.kbs * 1000]) // 1024 won't fit in 1k blocks :( let cid = await this.props.client.call('Filecoin.ClientImport', [file]) diff --git a/storage/sectorblocks/blocks.go b/storage/sectorblocks/blocks.go index d46ef9f1b..1d1289def 100644 --- a/storage/sectorblocks/blocks.go +++ b/storage/sectorblocks/blocks.go @@ -20,6 +20,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/storage/sector" @@ -172,7 +173,9 @@ func (st *SectorBlocks) AddUnixfsPiece(ref cid.Cid, r UnixfsReader, dealID uint6 intermediate: st.intermediate, } - return st.Store.AddPiece(refst.pieceRef, uint64(size), refst, dealID) + pr, psize := padreader.New(r, uint64(size)) + + return st.Store.AddPiece(refst.pieceRef, psize, pr, dealID) } func (st *SectorBlocks) List() (map[cid.Cid][]api.SealedRef, error) { From b3fe304d823804056ecd0e1a2e5f468df3a940cc Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 6 Nov 2019 20:26:01 +0100 Subject: [PATCH 050/114] add is permanent License: MIT Signed-off-by: Jakub Sztandera --- chain/sync.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/chain/sync.go b/chain/sync.go index 8c438b0c0..55ac65719 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -369,6 +369,10 @@ func (syncer *Syncer) Sync(ctx context.Context, maybeHead *types.TipSet) error { return nil } +func isPermanent(err error) bool { + return !errors.Is(err, ErrTemporal) +} + func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet) error { ctx, span := trace.StartSpan(ctx, "validateTipSet") defer span.End() @@ -380,7 +384,7 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet) for _, b := range fts.Blocks { if err := syncer.ValidateBlock(ctx, b); err != nil { - if !errors.Is(err, ErrTemporal) { + if isPermanent(err) { syncer.bad.Add(b.Cid()) } return xerrors.Errorf("validating block %s: %w", b.Cid(), err) From 00114c21e5186b56b2ec5f20ab4991ac7011f444 Mon Sep 17 00:00:00 2001 From: shannonwells Date: Wed, 6 Nov 2019 11:36:40 -0800 Subject: [PATCH 051/114] fix linker failure for OpenCL lib --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index fcdf73642..c1106b210 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,6 +15,8 @@ commands: prepare: steps: - checkout + - run: sudo apt-get update + - run: sudo apt-get install ocl-icd-opencl-dev - run: git submodule sync - run: git submodule update --init download-params: From f7651f180b617ade834d9d9b83fb2f969ce97faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 00:09:48 +0100 Subject: [PATCH 052/114] Create filler deals --- build/paramfetch.go | 1 + build/params.go | 2 +- chain/deals/client_utils.go | 2 +- chain/deals/provider.go | 2 +- gen/main.go | 9 ++ lib/padreader/padreader_test.go | 12 +++ lib/sectorbuilder/sectorbuilder.go | 11 ++- storage/garbage.go | 153 +++++++++++++---------------- storage/sealing.go | 4 +- storage/sector/cbor_gen.go | 119 ++++++++++++++++++++++ storage/sector/store.go | 64 +++++++++--- storage/sector/store_test.go | 44 ++++++++- storage/sector_states.go | 28 +++++- 13 files changed, 343 insertions(+), 108 deletions(-) create mode 100644 lib/padreader/padreader_test.go create mode 100644 storage/sector/cbor_gen.go diff --git a/build/paramfetch.go b/build/paramfetch.go index 5b1f4068d..55dfd62bc 100644 --- a/build/paramfetch.go +++ b/build/paramfetch.go @@ -93,6 +93,7 @@ func (ft *fetch) maybeFetchAsync(name string, info paramFile) { func (ft *fetch) checkFile(path string, info paramFile) error { if os.Getenv("TRUST_PARAMS") == "1" { log.Warn("Assuming parameter files are ok. DO NOT USE IN PRODUCTION") + return nil } f, err := os.Open(path) diff --git a/build/params.go b/build/params.go index 22e1ece3c..cd2fc738c 100644 --- a/build/params.go +++ b/build/params.go @@ -37,7 +37,7 @@ const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours // Consensus / Network // Seconds -const BlockDelay = 10 +const BlockDelay = 2 // Seconds const AllowableClockDrift = BlockDelay * 2 diff --git a/chain/deals/client_utils.go b/chain/deals/client_utils.go index 135f696a7..7cdd77192 100644 --- a/chain/deals/client_utils.go +++ b/chain/deals/client_utils.go @@ -80,7 +80,7 @@ func (c *Client) readStorageDealResp(deal ClientDeal) (*Response, error) { // TODO: verify signature if resp.Response.Proposal != deal.ProposalCid { - return nil, xerrors.New("miner responded to a wrong proposal") + return nil, xerrors.Errorf("miner responded to a wrong proposal: %s != %s", resp.Response.Proposal, deal.ProposalCid) } return &resp.Response, nil diff --git a/chain/deals/provider.go b/chain/deals/provider.go index ecabc7d13..46726298c 100644 --- a/chain/deals/provider.go +++ b/chain/deals/provider.go @@ -88,7 +88,7 @@ func NewProvider(ds dtypes.MetadataDS, sminer *storage.Miner, secb *sectorblocks secb: secb, pricePerByteBlock: types.NewInt(3), // TODO: allow setting - minPieceSize: 1, + minPieceSize: 256, // TODO: allow setting (BUT KEEP MIN 256! (because of how we fill sectors up)) conns: map[cid.Cid]inet.Stream{}, diff --git a/gen/main.go b/gen/main.go index 296b7bbf4..4c0c2167a 100644 --- a/gen/main.go +++ b/gen/main.go @@ -13,6 +13,7 @@ import ( "github.com/filecoin-project/lotus/paych" "github.com/filecoin-project/lotus/retrieval" "github.com/filecoin-project/lotus/storage" + "github.com/filecoin-project/lotus/storage/sector" ) func main() { @@ -158,4 +159,12 @@ func main() { fmt.Println(err) os.Exit(1) } + + err = gen.WriteTupleEncodersToFile("./storage/sector/cbor_gen.go", "sector", + sector.DealMapping{}, + ) + if err != nil { + fmt.Println(err) + os.Exit(1) + } } diff --git a/lib/padreader/padreader_test.go b/lib/padreader/padreader_test.go new file mode 100644 index 000000000..bf8464806 --- /dev/null +++ b/lib/padreader/padreader_test.go @@ -0,0 +1,12 @@ +package padreader + +import ( + "gotest.tools/assert" + "testing" +) + +func TestComputePaddedSize(t *testing.T) { + assert.Equal(t, uint64(1040384), PaddedSize(1000000)) + assert.Equal(t, uint64(1016), PaddedSize(548)) + assert.Equal(t, uint64(4064), PaddedSize(2048)) +} diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 58f37cf56..7f09fa81b 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -40,6 +40,7 @@ const CommLen = sectorbuilder.CommitmentBytesLen type SectorBuilder struct { handle unsafe.Pointer + ssize uint64 Miner address.Address @@ -71,7 +72,9 @@ func New(cfg *Config) (*SectorBuilder, error) { } return &SectorBuilder{ - handle: sbp, + handle: sbp, + ssize: cfg.SectorSize, + Miner: cfg.Miner, rateLimit: make(chan struct{}, cfg.WorkerThreads-PoStReservedWorkers), }, nil @@ -172,6 +175,10 @@ func (sb *SectorBuilder) GeneratePoSt(sectorInfo SortedSectorInfo, challengeSeed return sectorbuilder.GeneratePoSt(sb.handle, sectorInfo, challengeSeed, faults) } +func (sb *SectorBuilder) SectorSize() uint64 { + return sb.ssize +} + var UserBytesForSectorSize = sectorbuilder.GetMaxUserBytesPerStagedSector func VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address, ticket []byte, seed []byte, sectorID uint64, proof []byte) (bool, error) { @@ -237,7 +244,7 @@ func toReadableFile(r io.Reader, n int64) (*os.File, func() error, error) { } err := w.Close() - if werr == nil { + if werr == nil && err != nil { werr = err log.Warnf("toReadableFile: close error: %+v", err) return diff --git a/storage/garbage.go b/storage/garbage.go index 24af346ec..8e3cf1a10 100644 --- a/storage/garbage.go +++ b/storage/garbage.go @@ -16,46 +16,13 @@ import ( "github.com/filecoin-project/lotus/lib/sectorbuilder" ) -func (m *Miner) StoreGarbageData(_ context.Context) error { - ctx := context.TODO() - ssize, err := m.SectorSize(ctx) - if err != nil { - return xerrors.Errorf("failed to get miner sector size: %w", err) - } - go func() { - size := sectorbuilder.UserBytesForSectorSize(ssize) - - /*// Add market funds - smsg, err := m.api.MpoolPushMessage(ctx, &types.Message{ - To: actors.StorageMarketAddress, - From: m.worker, - Value: types.NewInt(size), - GasPrice: types.NewInt(0), - GasLimit: types.NewInt(1000000), - Method: actors.SMAMethods.AddBalance, - }) - if err != nil { - log.Error(err) - return - } - - r, err := m.api.StateWaitMsg(ctx, smsg.Cid()) - if err != nil { - log.Error(err) - return - } - - if r.Receipt.ExitCode != 0 { - log.Error(xerrors.Errorf("adding funds to storage miner market actor failed: exit %d", r.Receipt.ExitCode)) - return - }*/ - // Publish a deal - - // TODO: Maybe cache +// TODO: expected sector ID +func (m *Miner) storeGarbage(ctx context.Context, sizes ...uint64) ([]uint64, error) { + deals := make([]actors.StorageDeal, len(sizes)) + for i, size := range sizes { commP, err := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), size) if err != nil { - log.Error(err) - return + return nil, err } sdp := actors.StorageDealProposal{ @@ -72,66 +39,86 @@ func (m *Miner) StoreGarbageData(_ context.Context) error { } if err := api.SignWith(ctx, m.api.WalletSign, m.worker, &sdp); err != nil { - log.Error(xerrors.Errorf("signing storage deal failed: ", err)) - return + return nil, xerrors.Errorf("signing storage deal failed: ", err) } storageDeal := actors.StorageDeal{ Proposal: sdp, } if err := api.SignWith(ctx, m.api.WalletSign, m.worker, &storageDeal); err != nil { - log.Error(xerrors.Errorf("signing storage deal failed: ", err)) - return + return nil, xerrors.Errorf("signing storage deal failed: ", err) } - params, err := actors.SerializeParams(&actors.PublishStorageDealsParams{ - Deals: []actors.StorageDeal{storageDeal}, - }) - if err != nil { - log.Error(xerrors.Errorf("serializing PublishStorageDeals params failed: ", err)) - } + deals[i] = storageDeal + } - // TODO: We may want this to happen after fetching data - smsg, err := m.api.MpoolPushMessage(ctx, &types.Message{ - To: actors.StorageMarketAddress, - From: m.worker, - Value: types.NewInt(0), - GasPrice: types.NewInt(0), - GasLimit: types.NewInt(1000000), - Method: actors.SMAMethods.PublishStorageDeals, - Params: params, - }) - if err != nil { - log.Error(err) - return - } - r, err := m.api.StateWaitMsg(ctx, smsg.Cid()) - if err != nil { - log.Error(err) - return - } - if r.Receipt.ExitCode != 0 { - log.Error(xerrors.Errorf("publishing deal failed: exit %d", r.Receipt.ExitCode)) - } - var resp actors.PublishStorageDealResponse - if err := resp.UnmarshalCBOR(bytes.NewReader(r.Receipt.Return)); err != nil { - log.Error(err) - return - } - if len(resp.DealIDs) != 1 { - log.Error("got unexpected number of DealIDs from") - return - } + params, aerr := actors.SerializeParams(&actors.PublishStorageDealsParams{ + Deals: deals, + }) + if aerr != nil { + return nil, xerrors.Errorf("serializing PublishStorageDeals params failed: ", aerr) + } + // TODO: We may want this to happen after fetching data + smsg, err := m.api.MpoolPushMessage(ctx, &types.Message{ + To: actors.StorageMarketAddress, + From: m.worker, + Value: types.NewInt(0), + GasPrice: types.NewInt(0), + GasLimit: types.NewInt(1000000), + Method: actors.SMAMethods.PublishStorageDeals, + Params: params, + }) + if err != nil { + return nil, err + } + r, err := m.api.StateWaitMsg(ctx, smsg.Cid()) + if err != nil { + return nil, err + } + if r.Receipt.ExitCode != 0 { + log.Error(xerrors.Errorf("publishing deal failed: exit %d", r.Receipt.ExitCode)) + } + var resp actors.PublishStorageDealResponse + if err := resp.UnmarshalCBOR(bytes.NewReader(r.Receipt.Return)); err != nil { + return nil, err + } + if len(resp.DealIDs) != len(sizes) { + return nil, xerrors.New("got unexpected number of DealIDs from PublishStorageDeals") + } + + sectorIDs := make([]uint64, len(sizes)) + + for i, size := range sizes { name := fmt.Sprintf("fake-file-%d", rand.Intn(100000000)) - sectorId, err := m.secst.AddPiece(name, size, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), resp.DealIDs[0]) + sectorID, err := m.secst.AddPiece(name, size, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), resp.DealIDs[i]) if err != nil { - log.Error(err) + return nil, err + } + + sectorIDs[i] = sectorID + } + + return sectorIDs, nil +} + +func (m *Miner) StoreGarbageData(_ context.Context) error { + ctx := context.TODO() + ssize, err := m.SectorSize(ctx) + if err != nil { + return xerrors.Errorf("failed to get miner sector size: %w", err) + } + go func() { + size := sectorbuilder.UserBytesForSectorSize(ssize) + + sids, err := m.storeGarbage(ctx, size) + if err != nil { + log.Errorf("%+v", err) return } - if err := m.SealSector(context.TODO(), sectorId); err != nil { - log.Error(err) + if err := m.SealSector(context.TODO(), sids[0]); err != nil { + log.Errorf("%+v", err) return } }() diff --git a/storage/sealing.go b/storage/sealing.go index 625a35c1b..637eb8da2 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -71,7 +71,7 @@ func (m *Miner) onSectorIncoming(sector *SectorInfo) { go func() { select { case m.sectorUpdated <- sectorUpdate{ - newState: api.Unsealed, + newState: api.Packing, id: sector.SectorID, }: case <-m.stop: @@ -102,6 +102,8 @@ func (m *Miner) onSectorUpdated(ctx context.Context, update sectorUpdate) { } switch update.newState { + case api.Packing: + m.handle(ctx, sector, m.finishPacking, api.Unsealed) case api.Unsealed: m.handle(ctx, sector, m.sealPreCommit, api.PreCommitting) case api.PreCommitting: diff --git a/storage/sector/cbor_gen.go b/storage/sector/cbor_gen.go new file mode 100644 index 000000000..11a2365f1 --- /dev/null +++ b/storage/sector/cbor_gen.go @@ -0,0 +1,119 @@ +package sector + +import ( + "fmt" + "io" + + cbg "github.com/whyrusleeping/cbor-gen" + xerrors "golang.org/x/xerrors" +) + +/* This file was generated by github.com/whyrusleeping/cbor-gen */ + +var _ = xerrors.Errorf + +func (t *DealMapping) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{131}); err != nil { + return err + } + + // t.t.DealIDs ([]uint64) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { + return err + } + for _, v := range t.DealIDs { + if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { + return err + } + } + + // t.t.Allocated (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Allocated))); err != nil { + return err + } + + // t.t.Committed (bool) (bool) + if err := cbg.WriteBool(w, t.Committed); err != nil { + return err + } + return nil +} + +func (t *DealMapping) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 3 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.DealIDs ([]uint64) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.DealIDs: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.DealIDs = make([]uint64, extra) + } + for i := 0; i < int(extra); i++ { + + maj, val, err := cbg.CborReadHeader(br) + if err != nil { + return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) + } + + if maj != cbg.MajUnsignedInt { + return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) + } + + t.DealIDs[i] = val + } + + // t.t.Allocated (uint64) (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Allocated = uint64(extra) + // t.t.Committed (bool) (bool) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajOther { + return fmt.Errorf("booleans must be major type 7") + } + switch extra { + case 20: + t.Committed = false + case 21: + t.Committed = true + default: + return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra) + } + return nil +} diff --git a/storage/sector/store.go b/storage/sector/store.go index 52c45deef..8b7f59d5c 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -1,33 +1,32 @@ package sector import ( + "bytes" "context" "fmt" "io" + "math/bits" "sync" "github.com/filecoin-project/go-sectorbuilder/sealing_state" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" - cbor "github.com/ipfs/go-ipld-cbor" logging "github.com/ipfs/go-log" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/lib/cborrpc" "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/node/modules/dtypes" ) -func init() { - cbor.RegisterCborType(dealMapping{}) -} - var log = logging.Logger("sectorstore") var sectorDealsPrefix = datastore.NewKey("/sectordeals") -type dealMapping struct { +type DealMapping struct { DealIDs []uint64 + Allocated uint64 Committed bool } @@ -70,10 +69,10 @@ func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64 k := datastore.NewKey(fmt.Sprint(sectorID)) e, err := s.deals.Get(k) - var deals dealMapping + var deals DealMapping switch err { case nil: - if err := cbor.DecodeInto(e, &deals); err != nil { + if err := cborrpc.ReadCborRPC(bytes.NewReader(e), &deals); err != nil { return 0, err } if deals.Committed { @@ -82,7 +81,9 @@ func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64 fallthrough case datastore.ErrNotFound: deals.DealIDs = append(deals.DealIDs, dealIDs...) - d, err := cbor.DumpObject(&deals) + deals.Allocated += size + + d, err := cborrpc.Dump(&deals) if err != nil { return 0, err } @@ -96,7 +97,40 @@ func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64 return sectorID, nil } -func (s *Store) DealsForCommit(sectorID uint64) ([]uint64, error) { +func (s *Store) PieceSizesToFill(sectorID uint64) ([]uint64, error) { + s.dealsLk.Lock() + defer s.dealsLk.Unlock() + + k := datastore.NewKey(fmt.Sprint(sectorID)) + e, err := s.deals.Get(k) + if err != nil { + return nil, err + } + var info DealMapping + if err := cborrpc.ReadCborRPC(bytes.NewReader(e), &info); err != nil { + return nil, err + } + if info.Allocated > s.sb.SectorSize() { + return nil, xerrors.Errorf("more data allocated in sector than should be able to fit: %d > %d", info.Allocated, s.sb.SectorSize()) + } + + return fillersFromRem(sectorbuilder.UserBytesForSectorSize(s.sb.SectorSize()) - info.Allocated) +} + +func fillersFromRem(toFill uint64) ([]uint64, error) { + toFill += toFill / 127 // convert to in-sector bytes for easier math + + out := make([]uint64, bits.OnesCount64(toFill)) + for i := range out { + next := bits.TrailingZeros64(toFill) + psize := uint64(1) << next + toFill ^= psize + out[i] = sectorbuilder.UserBytesForSectorSize(psize) + } + return out, nil +} + +func (s *Store) DealsForCommit(sectorID uint64, commit bool) ([]uint64, error) { s.dealsLk.Lock() defer s.dealsLk.Unlock() @@ -105,16 +139,20 @@ func (s *Store) DealsForCommit(sectorID uint64) ([]uint64, error) { switch err { case nil: - var deals dealMapping - if err := cbor.DecodeInto(e, &deals); err != nil { + var deals DealMapping + if err := cborrpc.ReadCborRPC(bytes.NewReader(e), &deals); err != nil { return nil, err } + if !commit { + return nil, nil + } + if deals.Committed { log.Errorf("getting deal IDs for sector %d: sector already marked as committed", sectorID) } deals.Committed = true - d, err := cbor.DumpObject(&deals) + d, err := cborrpc.Dump(&deals) if err != nil { return nil, err } diff --git a/storage/sector/store_test.go b/storage/sector/store_test.go index a2e1d00ac..613f2836b 100644 --- a/storage/sector/store_test.go +++ b/storage/sector/store_test.go @@ -1,12 +1,46 @@ package sector import ( - "gotest.tools/assert" "testing" + + "github.com/stretchr/testify/assert" + + "github.com/filecoin-project/lotus/lib/sectorbuilder" ) -func TestComputePaddedSize(t *testing.T) { - assert.Equal(t, uint64(1040384), computePaddedSize(1000000)) - assert.Equal(t, uint64(1016), computePaddedSize(548)) - assert.Equal(t, uint64(4064), computePaddedSize(2048)) +func testFill(t *testing.T, n uint64, exp []uint64) { + f, err := fillersFromRem(n) + assert.NoError(t, err) + assert.Equal(t, exp, f) + + var sum uint64 + for _, u := range f { + sum += u + } + assert.Equal(t, n, sum) +} + +func TestFillersFromRem(t *testing.T) { + for i := 8; i < 32; i++ { + // single + ub := sectorbuilder.UserBytesForSectorSize(uint64(1) << i) + testFill(t, ub, []uint64{ub}) + + // 2 + ub = sectorbuilder.UserBytesForSectorSize(uint64(5) << i) + ub1 := sectorbuilder.UserBytesForSectorSize(uint64(1) << i) + ub3 := sectorbuilder.UserBytesForSectorSize(uint64(4) << i) + testFill(t, ub, []uint64{ub1, ub3}) + + // 4 + ub = sectorbuilder.UserBytesForSectorSize(uint64(15) << i) + ub2 := sectorbuilder.UserBytesForSectorSize(uint64(2) << i) + ub4 := sectorbuilder.UserBytesForSectorSize(uint64(8) << i) + testFill(t, ub, []uint64{ub1, ub2, ub3, ub4}) + + // different 2 + ub = sectorbuilder.UserBytesForSectorSize(uint64(9) << i) + testFill(t, ub, []uint64{ub1, ub4}) + } + } diff --git a/storage/sector_states.go b/storage/sector_states.go index 1122ea9a6..b57a5e315 100644 --- a/storage/sector_states.go +++ b/storage/sector_states.go @@ -33,6 +33,32 @@ func (m *Miner) handle(ctx context.Context, sector SectorInfo, cb providerHandle }() } +func (m *Miner) finishPacking(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { + log.Infow("performing filling up rest of the sector...", "sector", sector.SectorID) + + fillerSizes, err := m.secst.PieceSizesToFill(sector.SectorID) + if err != nil { + return nil, err + } + + if len(fillerSizes) > 0 { + log.Warnf("Creating %d filler pieces for sector %d", len(fillerSizes), sector.SectorID) + } + + ids, err := m.storeGarbage(ctx, fillerSizes...) + if err != nil { + return nil, xerrors.Errorf("filling up the sector (%v): %w", fillerSizes, err) + } + + for _, id := range ids { + if id != sector.SectorID { + panic("todo: pass SectorID into storeGarbage") + } + } + + return nil, nil +} + func (m *Miner) sealPreCommit(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { log.Infow("performing sector replication...", "sector", sector.SectorID) sinfo, err := m.secst.SealPreCommit(ctx, sector.SectorID) @@ -135,7 +161,7 @@ func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*Sector return nil, xerrors.Errorf("computing seal proof failed: %w", err) } - deals, err := m.secst.DealsForCommit(sector.SectorID) + deals, err := m.secst.DealsForCommit(sector.SectorID, true) if err != nil { return nil, err } From d615b7242a1f9a987838d1967aa630fd44c75c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 00:19:50 +0100 Subject: [PATCH 053/114] mod tidy --- go.sum | 132 +-------------------------------------------------------- 1 file changed, 2 insertions(+), 130 deletions(-) diff --git a/go.sum b/go.sum index 5645c179e..d02fd9826 100644 --- a/go.sum +++ b/go.sum @@ -13,10 +13,8 @@ github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= -github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= @@ -30,8 +28,6 @@ github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= @@ -75,7 +71,6 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/filecoin-project/go-amt-ipld v0.0.0-20190919045431-3650716fff16 h1:NzojcJU1VbS6zdLG13JMYis/cQy/MrN3rxmZRq56jKA= @@ -88,35 +83,16 @@ github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 h1:EzDjxMg43q1tA2c0MV3tNbaontnHLplHyFF github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1/go.mod h1:0eHX/BVySxPc6SE2mZRoppGq7qcEagxdmQnA3dzork8= github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= -github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= -github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= -github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= -github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= -github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= -github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= -github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= -github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= -github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -126,29 +102,11 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= -github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= -github.com/golangci/go-tools v0.0.0-20190318055746-e32c54105b7c/go.mod h1:unzUULGw35sjyOYjUt0jMTXqHlZPpPc6e+xfO4cd6mM= -github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= -github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= -github.com/golangci/gofmt v0.0.0-20181222123516-0b8337e80d98/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.18.0/go.mod h1:kaqo8l0OZKYPtjNmG4z4HrWLgcYNIJ9B9q3LWri9uLg= -github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547/go.mod h1:0qUabqiIQgfmlAmulqxyiGkkyF6/tOGSnY2cnPVwrzU= -github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= -github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= -github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= @@ -163,7 +121,6 @@ github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= @@ -174,7 +131,6 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -291,8 +247,6 @@ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= @@ -300,13 +254,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/gotool v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -433,10 +382,8 @@ github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lucas-clemente/quic-go v0.11.2 h1:Mop0ac3zALaBR3wGs6j8OYe/tcFvFsxTUFMkE/7yUOI= github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= -github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNAI4vA= @@ -445,8 +392,8 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -454,7 +401,6 @@ github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -466,17 +412,9 @@ github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+ github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= -github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= @@ -504,30 +442,22 @@ github.com/multiformats/go-multihash v0.0.7/go.mod h1:XuKXPp8VHcTygube3OWZC+aZrA github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= -github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= -github.com/neelance/parallel v0.0.0-20160708114440-4de9ce63d14c/go.mod h1:eTBvSIlRgLo+CNFFQRQTwUGTZOEdvXIKeZS/xG+D2yU= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.9.0 h1:SZjF721BByVj8QH636/8S2DnX4n0Re3SteMmw3N+tzc= github.com/onsi/ginkgo v1.9.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.6.0 h1:8XTW0fcJZEq9q+Upcyws4JSGua2MFysCL5xkaSgHc+M= github.com/onsi/gomega v1.6.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -542,32 +472,16 @@ github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a h1:hjZfReYVLbqFkAtr github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v2.18.12+incompatible h1:1eaJvGomDnH74/5cF4CTmTbLHAriGFsTZppLXDX93OM= github.com/shirou/gopsutil v2.18.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/slimsag/godocmd v0.0.0-20161025000126-a1005ad29fe3/go.mod h1:AIBPxLCkKUFc2ZkjCXzs/Kk9OUhQLw/Zicdd0Rhqz2U= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= @@ -577,27 +491,17 @@ github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:s github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= -github.com/sourcegraph/ctxvfs v0.0.0-20180418081416-2b65f1b1ea81/go.mod h1:xIvvI5FiHLxhv8prbzVpaMHaaGPFPFQSuTcxC91ryOo= -github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= -github.com/sourcegraph/go-langserver v2.0.0+incompatible/go.mod h1:bBMjfpzEHd6ijPRoQ7f+knFfw+e8R+W158/MsqAy77c= -github.com/sourcegraph/jsonrpc2 v0.0.0-20190106185902-35a74f039c6a/go.mod h1:eESpbCslcLDs8j2D7IEdGVgul7xuk9odqDTaor30IUU= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -607,19 +511,14 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= 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/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ultraware/funlen v0.0.1/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= 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= -github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830 h1:8kxMKmKzXXL4Ru1nyhvdms/JjWt+3YLpvRb/bAjO/y0= github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -677,13 +576,11 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM= golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -693,11 +590,9 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180926154720-4dfa2610cdf3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -711,7 +606,6 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -726,7 +620,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20171026204733-164713f0dfce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -739,7 +632,6 @@ golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -747,15 +639,11 @@ golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= @@ -764,26 +652,17 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuA golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190121143147-24cd39ecf745/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190813142322-97f12d73768f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190909030654-5b82db07426d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -804,25 +683,22 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 h1:Ggy3mWN4l3PUFPfSG0YB3n5fVYggzysUmiUQ89SnX6Y= gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8/go.mod h1:cKXr3E0k4aosgycml1b5z33BVV6hai1Kh7uDgFOkbcs= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -836,7 +712,3 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= From e075eb163fea3ce88b1cc19a085884595bb7f8dc Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Tue, 5 Nov 2019 17:22:16 -0800 Subject: [PATCH 054/114] Add a test for the sectorstore --- storage/sector/store_test.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/storage/sector/store_test.go b/storage/sector/store_test.go index 613f2836b..cf7fe5e0b 100644 --- a/storage/sector/store_test.go +++ b/storage/sector/store_test.go @@ -1,11 +1,17 @@ package sector import ( + "context" + "fmt" + "io" + "math/rand" "testing" "github.com/stretchr/testify/assert" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/lib/sectorbuilder" + "github.com/ipfs/go-datastore" ) func testFill(t *testing.T, n uint64, exp []uint64) { @@ -44,3 +50,33 @@ func TestFillersFromRem(t *testing.T) { } } + +func TestSectorStore(t *testing.T) { + if err := build.GetParams(true); err != nil { + t.Fatal(err) + } + + sb, cleanup, err := sectorbuilder.TempSectorbuilder(1024) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + tktFn := func(context.Context) (*sectorbuilder.SealTicket, error) { + return §orbuilder.SealTicket{ + BlockHeight: 17, + TicketBytes: [32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2}, + }, nil + } + + ds := datastore.NewMapDatastore() + + store := NewStore(sb, ds, tktFn) + + pr := io.LimitReader(rand.New(rand.NewSource(17)), 300) + sid, err := store.AddPiece("a", 300, pr, 1) + if err != nil { + t.Fatal(err) + } + fmt.Println(sid) +} From 9863942fe231b3217d00475676145ad499107a8b Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Tue, 5 Nov 2019 22:26:50 -0800 Subject: [PATCH 055/114] WIP: trying to write a test to reproduce the storage deal error --- chain/deals/client.go | 2 +- cmd/lotus-storage-miner/run.go | 3 +-- lib/sectorbuilder/sectorbuilder_test.go | 2 +- node/impl/client/client.go | 23 ++++++++++++++++++----- node/modules/testing/genesis.go | 4 ++-- node/node_test.go | 19 +++++++++++++------ storage/miner.go | 3 ++- storage/post.go | 3 ++- storage/sector/store.go | 20 ++++++++++++++++++-- storage/sectorblocks/blocks.go | 9 +-------- 10 files changed, 59 insertions(+), 29 deletions(-) diff --git a/chain/deals/client.go b/chain/deals/client.go index b99422e11..a64a6abcc 100644 --- a/chain/deals/client.go +++ b/chain/deals/client.go @@ -2,6 +2,7 @@ package deals import ( "context" + "github.com/filecoin-project/lotus/lib/statestore" "github.com/filecoin-project/lotus/node/impl/full" @@ -226,7 +227,6 @@ func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, erro s, err := c.h.NewStream(ctx, p.MinerID, DealProtocolID) if err != nil { - s.Reset() return cid.Undef, xerrors.Errorf("connecting to storage provider failed: %w", err) } diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index 1b2a53a80..4142233fd 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -8,13 +8,12 @@ import ( "os/signal" "syscall" - "github.com/filecoin-project/lotus/build" - "github.com/multiformats/go-multiaddr" "golang.org/x/xerrors" "gopkg.in/urfave/cli.v2" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/auth" "github.com/filecoin-project/lotus/lib/jsonrpc" diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index 5ce934f04..28bbc4ebf 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -12,7 +12,7 @@ import ( const sectorSize = 1024 func TestSealAndVerify(t *testing.T) { - t.Skip("this is slow") + //t.Skip("this is slow") //os.Setenv("BELLMAN_NO_GPU", "1") build.SectorSizes = []uint64{sectorSize} diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 17ab26731..7128cbb22 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -58,7 +58,7 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.A // TODO: make this a param self, err := a.WalletDefaultAddress(ctx) if err != nil { - return nil, err + return nil, xerrors.Errorf("failed to get default address: %w", err) } // get miner peerID @@ -70,11 +70,15 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.A r, err := a.StateCall(ctx, msg, nil) if err != nil { - return nil, err + return nil, xerrors.Errorf("failed getting peer ID: %w", err) } + if r.ExitCode != 0 { + return nil, xerrors.Errorf("call to get peer ID for miner failed: exit code %d", r.ExitCode) + } + pid, err := peer.IDFromBytes(r.Return) if err != nil { - return nil, err + return nil, xerrors.Errorf("parsing peer ID wrong: %w", err) } proposal := deals.ClientDealProposal{ @@ -88,7 +92,12 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.A } c, err := a.DealClient.Start(ctx, proposal) - return &c, err + // TODO: send updated voucher with PaymentVerifySector for cheaper validation (validate the sector the miner sent us first!) + if err != nil { + return nil, xerrors.Errorf("failed to start deal: %w", err) + } + + return &c, nil } func (a *API) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) { @@ -177,7 +186,11 @@ func (a *API) ClientImport(ctx context.Context, path string) (cid.Cid, error) { return cid.Undef, err } - return nd.Cid(), bufferedDS.Commit() + if err := bufferedDS.Commit(); err != nil { + return cid.Undef, err + } + + return nd.Cid(), nil } func (a *API) ClientImportLocal(ctx context.Context, f io.Reader) (cid.Cid, error) { diff --git a/node/modules/testing/genesis.go b/node/modules/testing/genesis.go index b53e33319..6c81f68ba 100644 --- a/node/modules/testing/genesis.go +++ b/node/modules/testing/genesis.go @@ -25,7 +25,7 @@ import ( var glog = logging.Logger("genesis") -func MakeGenesisMem(out io.Writer) func(bs dtypes.ChainBlockstore, w *wallet.Wallet) modules.Genesis { +func MakeGenesisMem(out io.Writer, minerPid peer.ID) 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") @@ -38,7 +38,7 @@ func MakeGenesisMem(out io.Writer) func(bs dtypes.ChainBlockstore, w *wallet.Wal gmc := &gen.GenMinerCfg{ Owners: []address.Address{w}, Workers: []address.Address{w}, - PeerIDs: []peer.ID{"peerID 1"}, + PeerIDs: []peer.ID{minerPid}, } alloc := map[address.Address]types.BigInt{ w: types.FromFil(10000), diff --git a/node/node_test.go b/node/node_test.go index b035a7926..74833227b 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -31,15 +31,12 @@ import ( "github.com/filecoin-project/lotus/node/repo" ) -func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, act address.Address, tnd test.TestNode) test.TestStorageNode { +func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, act address.Address, pk crypto.PrivKey, tnd test.TestNode) test.TestStorageNode { r := repo.NewMemory(nil) lr, err := r.Lock(repo.RepoStorageMiner) require.NoError(t, err) - pk, _, err := crypto.GenerateEd25519Key(rand.Reader) - require.NoError(t, err) - ks, err := lr.KeyStore() require.NoError(t, err) @@ -115,12 +112,18 @@ func builder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []test.Te fulls := make([]test.TestNode, nFull) storers := make([]test.TestStorageNode, len(storage)) + pk, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + + minerPid, err := peer.IDFromPrivateKey(pk) + require.NoError(t, err) + var genbuf bytes.Buffer for i := 0; i < nFull; i++ { var genesis node.Option if i == 0 { - genesis = node.Override(new(modules.Genesis), modtest.MakeGenesisMem(&genbuf)) + genesis = node.Override(new(modules.Genesis), modtest.MakeGenesisMem(&genbuf, minerPid)) } else { genesis = node.Override(new(modules.Genesis), modules.LoadGenesis(genbuf.Bytes())) } @@ -171,7 +174,7 @@ func builder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []test.Te genMiner, err := address.NewFromString("t0101") require.NoError(t, err) - storers[i] = testStorageNode(ctx, t, wa, genMiner, f) + storers[i] = testStorageNode(ctx, t, wa, genMiner, pk, f) } if err := mn.LinkAll(); err != nil { @@ -221,3 +224,7 @@ func rpcBuilder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []test func TestAPIRPC(t *testing.T) { test.TestApis(t, rpcBuilder) } + +func TestAPIDealFlow(t *testing.T) { + test.TestDealFlow(t, builder) +} diff --git a/storage/miner.go b/storage/miner.go index ae93e78f5..72a6a0a8b 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -2,9 +2,10 @@ package storage import ( "context" + "sync" + "github.com/filecoin-project/lotus/lib/statestore" "github.com/ipfs/go-datastore/namespace" - "sync" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" diff --git a/storage/post.go b/storage/post.go index 3fe45d24c..ff21c48f7 100644 --- a/storage/post.go +++ b/storage/post.go @@ -2,9 +2,10 @@ package storage import ( "context" + "time" + "github.com/ipfs/go-cid" "go.opencensus.io/trace" - "time" "golang.org/x/xerrors" diff --git a/storage/sector/store.go b/storage/sector/store.go index 8b7f59d5c..453bb1c64 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -7,6 +7,7 @@ import ( "io" "math/bits" "sync" + "testing/iotest" "github.com/filecoin-project/go-sectorbuilder/sealing_state" "github.com/ipfs/go-datastore" @@ -59,9 +60,24 @@ func (s *Store) SectorStatus(sid uint64) (*sectorbuilder.SectorSealingStatus, er } func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64) (sectorID uint64, err error) { - sectorID, err = s.sb.AddPiece(ref, size, r) + padSize := computePaddedSize(size) + + buf := make([]byte, padSize) + r = iotest.NewReadLogger("UNIX FILE", r) + n, err := io.ReadFull(r, buf) if err != nil { - return 0, err + return 0, xerrors.Errorf("failed a bad thing: %w", err) + } + if uint64(n) != size { + panic("bad bad") + } + + bufr := bytes.NewReader(buf) + //r = io.MultiReader(r, io.LimitReader(nullReader{}, int64(padSize-size))) + + sectorID, err = s.sb.AddPiece(ref, padSize, bufr) + if err != nil { + return 0, xerrors.Errorf("sector store AddPiece call failed: %w", err) } s.dealsLk.Lock() diff --git a/storage/sectorblocks/blocks.go b/storage/sectorblocks/blocks.go index 1d1289def..d8666b41c 100644 --- a/storage/sectorblocks/blocks.go +++ b/storage/sectorblocks/blocks.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "errors" - "io" "sync" "github.com/ipfs/go-cid" @@ -20,7 +19,6 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/lib/cborrpc" - "github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/storage/sector" @@ -132,9 +130,6 @@ func (r *refStorer) Read(p []byte) (n int, err error) { for { data, offset, nd, err := r.blockReader.ReadBlock(context.TODO()) if err != nil { - if err == io.EOF { - return 0, io.EOF - } return 0, xerrors.Errorf("reading block: %w", err) } @@ -173,9 +168,7 @@ func (st *SectorBlocks) AddUnixfsPiece(ref cid.Cid, r UnixfsReader, dealID uint6 intermediate: st.intermediate, } - pr, psize := padreader.New(r, uint64(size)) - - return st.Store.AddPiece(refst.pieceRef, psize, pr, dealID) + return st.Store.AddPiece(refst.pieceRef, uint64(size), refst, dealID) } func (st *SectorBlocks) List() (map[cid.Cid][]api.SealedRef, error) { From a49b949dca11e2d4cb784ba47f7b74d27876764c Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 6 Nov 2019 08:10:44 -0800 Subject: [PATCH 056/114] add file i didnt add before --- api/test/deals.go | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 api/test/deals.go diff --git a/api/test/deals.go b/api/test/deals.go new file mode 100644 index 000000000..1afab2759 --- /dev/null +++ b/api/test/deals.go @@ -0,0 +1,69 @@ +package test + +import ( + "context" + "fmt" + "io" + "math/rand" + "testing" + "time" + + "github.com/filecoin-project/lotus/chain/address" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/node/impl" +) + +func TestDealFlow(t *testing.T, b APIBuilder) { + ctx := context.TODO() + n, sn := b(t, 1, []int{0}) + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + _ = miner + + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + addrinfo.Addrs = nil + + if err := miner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + time.Sleep(time.Second) + + r := io.LimitReader(rand.New(rand.NewSource(17)), 350) + fcid, err := client.ClientImportLocal(ctx, r) + if err != nil { + t.Fatal(err) + } + + maddr, err := address.NewFromString("t0101") + if err != nil { + t.Fatal(err) + } + + fmt.Println("FILE CID: ", fcid) + + go func() { + time.Sleep(time.Second) + fmt.Println("mining a block now") + if err := n[0].MineOne(ctx); err != nil { + t.Fatal(err) + } + fmt.Println("mined a block") + + time.Sleep(time.Second) + fmt.Println("mining a block now") + if err := n[0].MineOne(ctx); err != nil { + t.Fatal(err) + } + + }() + deal, err := client.ClientStartDeal(ctx, fcid, maddr, types.NewInt(1), 100) + if err != nil { + t.Fatal(err) + } + fmt.Println("Deal done!", deal) + + time.Sleep(time.Second * 10) +} From 7cb4148b186301eaa033d9cdfd6ca929b5e2d608 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 6 Nov 2019 09:21:37 -0800 Subject: [PATCH 057/114] storage miner node needs mocknet option --- api/test/deals.go | 1 - node/node_test.go | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/api/test/deals.go b/api/test/deals.go index 1afab2759..656986c91 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -24,7 +24,6 @@ func TestDealFlow(t *testing.T, b APIBuilder) { if err != nil { t.Fatal(err) } - addrinfo.Addrs = nil if err := miner.NetConnect(ctx, addrinfo); err != nil { t.Fatal(err) diff --git a/node/node_test.go b/node/node_test.go index 74833227b..1d8c20b03 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -31,7 +31,7 @@ import ( "github.com/filecoin-project/lotus/node/repo" ) -func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, act address.Address, pk crypto.PrivKey, tnd test.TestNode) test.TestStorageNode { +func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, act address.Address, pk crypto.PrivKey, tnd test.TestNode, mn mocknet.Mocknet) test.TestStorageNode { r := repo.NewMemory(nil) lr, err := r.Lock(repo.RepoStorageMiner) @@ -90,6 +90,8 @@ func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, a node.Repo(r), node.Test(), + node.MockHost(mn), + node.Override(new(*sectorbuilder.Config), modules.SectorBuilderConfig(secbpath, 2)), node.Override(new(api.FullNode), tnd), ) @@ -174,7 +176,7 @@ func builder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []test.Te genMiner, err := address.NewFromString("t0101") require.NoError(t, err) - storers[i] = testStorageNode(ctx, t, wa, genMiner, pk, f) + storers[i] = testStorageNode(ctx, t, wa, genMiner, pk, f, mn) } if err := mn.LinkAll(); err != nil { From 597dbe369cb3ac04de9b3963a97b3179b29f3a9e Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 6 Nov 2019 11:44:28 -0800 Subject: [PATCH 058/114] Add method to query latest deal state --- api/api_full.go | 2 ++ api/struct.go | 4 ++++ api/test/deals.go | 35 +++++++++++++++++++++-------------- chain/deals/client.go | 8 ++++++++ lib/statestore/store.go | 14 ++++++++++++++ node/impl/client/client.go | 16 ++++++++++++++++ 6 files changed, 65 insertions(+), 14 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index e071a7066..bab1002ab 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -2,6 +2,7 @@ package api import ( "context" + "github.com/ipfs/go-cid" "github.com/ipfs/go-filestore" "github.com/libp2p/go-libp2p-core/peer" @@ -73,6 +74,7 @@ type FullNode interface { // ClientImport imports file under the specified path into filestore ClientImport(ctx context.Context, path string) (cid.Cid, error) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.Address, epochPrice types.BigInt, blocksDuration uint64) (*cid.Cid, error) + ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error) ClientListDeals(ctx context.Context) ([]DealInfo, error) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) ClientFindData(ctx context.Context, root cid.Cid) ([]QueryOffer, error) // TODO: specify serialization mode we want (defaults to unixfs for now) diff --git a/api/struct.go b/api/struct.go index 6eefe41dc..437e37624 100644 --- a/api/struct.go +++ b/api/struct.go @@ -82,6 +82,7 @@ type FullNodeStruct struct { ClientHasLocal func(ctx context.Context, root cid.Cid) (bool, error) `perm:"write"` ClientFindData func(ctx context.Context, root cid.Cid) ([]QueryOffer, error) `perm:"read"` ClientStartDeal func(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) `perm:"admin"` + ClientGetDealInfo func(context.Context, cid.Cid) (*DealInfo, error) `perm:"read"` ClientListDeals func(ctx context.Context) ([]DealInfo, error) `perm:"write"` ClientRetrieve func(ctx context.Context, order RetrievalOrder, path string) error `perm:"admin"` ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"` @@ -193,6 +194,9 @@ func (c *FullNodeStruct) ClientFindData(ctx context.Context, root cid.Cid) ([]Qu func (c *FullNodeStruct) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) { return c.Internal.ClientStartDeal(ctx, data, miner, price, blocksDuration) } +func (c *FullNodeStruct) ClientGetDealInfo(ctx context.Context, deal cid.Cid) (*DealInfo, error) { + return c.Internal.ClientGetDealInfo(ctx, deal) +} func (c *FullNodeStruct) ClientListDeals(ctx context.Context) ([]DealInfo, error) { return c.Internal.ClientListDeals(ctx) diff --git a/api/test/deals.go b/api/test/deals.go index 656986c91..6db2f7331 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -8,17 +8,19 @@ import ( "testing" "time" + logging "github.com/ipfs/go-log" + "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/impl" ) func TestDealFlow(t *testing.T, b APIBuilder) { + logging.SetAllLoggers(logging.LevelInfo) ctx := context.TODO() n, sn := b(t, 1, []int{0}) client := n[0].FullNode.(*impl.FullNodeAPI) miner := sn[0] - _ = miner addrinfo, err := client.NetAddrsListen(ctx) if err != nil { @@ -44,24 +46,29 @@ func TestDealFlow(t *testing.T, b APIBuilder) { fmt.Println("FILE CID: ", fcid) go func() { - time.Sleep(time.Second) - fmt.Println("mining a block now") - if err := n[0].MineOne(ctx); err != nil { - t.Fatal(err) + for i := 0; i < 4; i++ { + time.Sleep(time.Second) + fmt.Println("mining a block now", i) + if err := n[0].MineOne(ctx); err != nil { + t.Fatal(err) + } } - fmt.Println("mined a block") - - time.Sleep(time.Second) - fmt.Println("mining a block now") - if err := n[0].MineOne(ctx); err != nil { - t.Fatal(err) - } - }() - deal, err := client.ClientStartDeal(ctx, fcid, maddr, types.NewInt(1), 100) + deal, err := client.ClientStartDeal(ctx, fcid, maddr, types.NewInt(200), 100) if err != nil { t.Fatal(err) } + + // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this + time.Sleep(time.Second) + for { + di, err := client.ClientGetDealInfo(ctx, *deal) + if err != nil { + t.Fatal(err) + } + fmt.Println("DEAL STATE: ", *deal, di.State) + time.Sleep(time.Second / 2) + } fmt.Println("Deal done!", deal) time.Sleep(time.Second * 10) diff --git a/chain/deals/client.go b/chain/deals/client.go index a64a6abcc..3fb982ecc 100644 --- a/chain/deals/client.go +++ b/chain/deals/client.go @@ -298,6 +298,14 @@ func (c *Client) List() ([]ClientDeal, error) { return out, nil } +func (c *Client) GetDeal(d cid.Cid) (*ClientDeal, error) { + var out ClientDeal + if err := c.deals.Get(d, &out); err != nil { + return nil, err + } + return &out, nil +} + func (c *Client) Stop() { close(c.stop) <-c.stopped diff --git a/lib/statestore/store.go b/lib/statestore/store.go index ca924d66e..80df4a078 100644 --- a/lib/statestore/store.go +++ b/lib/statestore/store.go @@ -7,6 +7,7 @@ import ( "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/query" + cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/lib/cborrpc" @@ -110,6 +111,19 @@ func (st *StateStore) mutate(i interface{}, mutator func([]byte) ([]byte, error) return st.ds.Put(k, mutated) } +func (st *StateStore) Get(i interface{}, out cbg.CBORUnmarshaler) error { + k := toKey(i) + val, err := st.ds.Get(k) + if err != nil { + if xerrors.Is(err, datastore.ErrNotFound) { + return xerrors.Errorf("No state for %s", i) + } + return err + } + + return out.UnmarshalCBOR(bytes.NewReader(val)) +} + // out: *[]T func (st *StateStore) List(out interface{}) error { res, err := st.ds.Query(query.Query{}) diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 7128cbb22..e4d8bd5d5 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -124,6 +124,22 @@ func (a *API) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) { return out, nil } +func (a *API) ClientGetDealInfo(ctx context.Context, d cid.Cid) (*api.DealInfo, error) { + v, err := a.DealClient.GetDeal(d) + if err != nil { + return nil, err + } + return &api.DealInfo{ + ProposalCid: v.ProposalCid, + State: v.State, + Provider: v.Proposal.Provider, + PieceRef: v.Proposal.PieceRef, + Size: v.Proposal.PieceSize, + PricePerEpoch: v.Proposal.StoragePricePerEpoch, + Duration: v.Proposal.Duration, + }, nil +} + func (a *API) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) { // TODO: check if we have the ENTIRE dag From 41d13b12a037a4d58b44c3d3f885f277e5600125 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 6 Nov 2019 12:39:07 -0800 Subject: [PATCH 059/114] test is getting close to passing --- api/test/deals.go | 16 +++++++++++----- storage/sector/store.go | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/api/test/deals.go b/api/test/deals.go index 6db2f7331..4b36daa09 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -10,6 +10,7 @@ import ( logging "github.com/ipfs/go-log" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/impl" @@ -54,7 +55,7 @@ func TestDealFlow(t *testing.T, b APIBuilder) { } } }() - deal, err := client.ClientStartDeal(ctx, fcid, maddr, types.NewInt(200), 100) + deal, err := client.ClientStartDeal(ctx, fcid, maddr, types.NewInt(400), 100) if err != nil { t.Fatal(err) } @@ -66,10 +67,15 @@ func TestDealFlow(t *testing.T, b APIBuilder) { if err != nil { t.Fatal(err) } - fmt.Println("DEAL STATE: ", *deal, di.State) + switch di.State { + case api.DealRejected: + t.Fatal("deal rejected") + case api.DealFailed: + t.Fatal("deal failed") + case api.DealComplete: + fmt.Println("COMPLETE", di) + break + } time.Sleep(time.Second / 2) } - fmt.Println("Deal done!", deal) - - time.Sleep(time.Second * 10) } diff --git a/storage/sector/store.go b/storage/sector/store.go index 453bb1c64..a3ae60544 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -59,6 +59,25 @@ func (s *Store) SectorStatus(sid uint64) (*sectorbuilder.SectorSealingStatus, er return &status, nil } +func computePaddedSize(size uint64) uint64 { + logv := 64 - bits.LeadingZeros64(size) + sectSize := uint64(1 << logv) + bound := sectorbuilder.UserBytesForSectorSize(sectSize) + if size <= bound { + return bound + } + return sectorbuilder.UserBytesForSectorSize(1 << (logv + 1)) +} + +type nullReader struct{} + +func (nr nullReader) Read(b []byte) (int, error) { + for i := range b { + b[i] = 0 + } + return len(b), nil +} + func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64) (sectorID uint64, err error) { padSize := computePaddedSize(size) From 480e7899ef8ffb5e4563860a30a7b6da0a8d574f Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 6 Nov 2019 12:54:40 -0800 Subject: [PATCH 060/114] fail test if deal errors --- api/test/deals.go | 3 +++ lib/sectorbuilder/sectorbuilder_test.go | 2 +- node/impl/client/client.go | 1 - 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/api/test/deals.go b/api/test/deals.go index 4b36daa09..ea5956458 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -72,10 +72,13 @@ func TestDealFlow(t *testing.T, b APIBuilder) { t.Fatal("deal rejected") case api.DealFailed: t.Fatal("deal failed") + case api.DealError: + t.Fatal("deal errored") case api.DealComplete: fmt.Println("COMPLETE", di) break } + fmt.Println("Deal state: ", di.State) time.Sleep(time.Second / 2) } } diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index 28bbc4ebf..5ce934f04 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -12,7 +12,7 @@ import ( const sectorSize = 1024 func TestSealAndVerify(t *testing.T) { - //t.Skip("this is slow") + t.Skip("this is slow") //os.Setenv("BELLMAN_NO_GPU", "1") build.SectorSizes = []uint64{sectorSize} diff --git a/node/impl/client/client.go b/node/impl/client/client.go index e4d8bd5d5..8856452f1 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -92,7 +92,6 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.A } c, err := a.DealClient.Start(ctx, proposal) - // TODO: send updated voucher with PaymentVerifySector for cheaper validation (validate the sector the miner sent us first!) if err != nil { return nil, xerrors.Errorf("failed to start deal: %w", err) } From 74ea4d71c5a9f48c1655a213f52e2044808285ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 00:47:48 +0100 Subject: [PATCH 061/114] post-rebase fixes --- storage/sector/store.go | 46 ++++------------------------------ storage/sectorblocks/blocks.go | 9 ++++++- 2 files changed, 13 insertions(+), 42 deletions(-) diff --git a/storage/sector/store.go b/storage/sector/store.go index a3ae60544..7f1159090 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -4,16 +4,14 @@ import ( "bytes" "context" "fmt" - "io" - "math/bits" - "sync" - "testing/iotest" - "github.com/filecoin-project/go-sectorbuilder/sealing_state" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" logging "github.com/ipfs/go-log" "golang.org/x/xerrors" + "io" + "math/bits" + "sync" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/lib/cborrpc" @@ -59,44 +57,10 @@ func (s *Store) SectorStatus(sid uint64) (*sectorbuilder.SectorSealingStatus, er return &status, nil } -func computePaddedSize(size uint64) uint64 { - logv := 64 - bits.LeadingZeros64(size) - sectSize := uint64(1 << logv) - bound := sectorbuilder.UserBytesForSectorSize(sectSize) - if size <= bound { - return bound - } - return sectorbuilder.UserBytesForSectorSize(1 << (logv + 1)) -} - -type nullReader struct{} - -func (nr nullReader) Read(b []byte) (int, error) { - for i := range b { - b[i] = 0 - } - return len(b), nil -} - func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64) (sectorID uint64, err error) { - padSize := computePaddedSize(size) - - buf := make([]byte, padSize) - r = iotest.NewReadLogger("UNIX FILE", r) - n, err := io.ReadFull(r, buf) + sectorID, err = s.sb.AddPiece(ref, size, r) if err != nil { - return 0, xerrors.Errorf("failed a bad thing: %w", err) - } - if uint64(n) != size { - panic("bad bad") - } - - bufr := bytes.NewReader(buf) - //r = io.MultiReader(r, io.LimitReader(nullReader{}, int64(padSize-size))) - - sectorID, err = s.sb.AddPiece(ref, padSize, bufr) - if err != nil { - return 0, xerrors.Errorf("sector store AddPiece call failed: %w", err) + return 0, err } s.dealsLk.Lock() diff --git a/storage/sectorblocks/blocks.go b/storage/sectorblocks/blocks.go index d8666b41c..1d1289def 100644 --- a/storage/sectorblocks/blocks.go +++ b/storage/sectorblocks/blocks.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "errors" + "io" "sync" "github.com/ipfs/go-cid" @@ -19,6 +20,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/storage/sector" @@ -130,6 +132,9 @@ func (r *refStorer) Read(p []byte) (n int, err error) { for { data, offset, nd, err := r.blockReader.ReadBlock(context.TODO()) if err != nil { + if err == io.EOF { + return 0, io.EOF + } return 0, xerrors.Errorf("reading block: %w", err) } @@ -168,7 +173,9 @@ func (st *SectorBlocks) AddUnixfsPiece(ref cid.Cid, r UnixfsReader, dealID uint6 intermediate: st.intermediate, } - return st.Store.AddPiece(refst.pieceRef, uint64(size), refst, dealID) + pr, psize := padreader.New(r, uint64(size)) + + return st.Store.AddPiece(refst.pieceRef, psize, pr, dealID) } func (st *SectorBlocks) List() (map[cid.Cid][]api.SealedRef, error) { From cfac6f32728c56e2a34df549aea6bc9f64fc4df1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 00:50:37 +0100 Subject: [PATCH 062/114] Fix TestSectorStore --- storage/sector/store_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/storage/sector/store_test.go b/storage/sector/store_test.go index cf7fe5e0b..78d7ccd0e 100644 --- a/storage/sector/store_test.go +++ b/storage/sector/store_test.go @@ -3,6 +3,7 @@ package sector import ( "context" "fmt" + "github.com/filecoin-project/lotus/lib/padreader" "io" "math/rand" "testing" @@ -74,7 +75,9 @@ func TestSectorStore(t *testing.T) { store := NewStore(sb, ds, tktFn) pr := io.LimitReader(rand.New(rand.NewSource(17)), 300) - sid, err := store.AddPiece("a", 300, pr, 1) + pr, n := padreader.New(pr, 300) + + sid, err := store.AddPiece("a", n, pr, 1) if err != nil { t.Fatal(err) } From d45544c90c92ee1c6b6f3a6d69924b1c70ba89fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 00:59:56 +0100 Subject: [PATCH 063/114] Correct proposal cid on provider side --- chain/deals/provider.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chain/deals/provider.go b/chain/deals/provider.go index 46726298c..f54b32cf5 100644 --- a/chain/deals/provider.go +++ b/chain/deals/provider.go @@ -193,7 +193,7 @@ func (p *Provider) onUpdated(ctx context.Context, update minerDealUpdate) { } func (p *Provider) newDeal(s inet.Stream, proposal Proposal) (MinerDeal, error) { - proposalNd, err := cborrpc.AsIpld(&proposal) + proposalNd, err := cborrpc.AsIpld(proposal.DealProposal) if err != nil { return MinerDeal{}, err } @@ -222,7 +222,7 @@ func (p *Provider) HandleStream(s inet.Stream) { deal, err := p.newDeal(s, proposal) if err != nil { - log.Error(err) + log.Errorf("%+v", err) s.Close() return } From 29778cd6533ede92bd9fae9ee0f212a87de5a55d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 01:18:06 +0100 Subject: [PATCH 064/114] Mostly fix TestDealFlow --- api/test/deals.go | 20 ++++++++++++++++---- api/types.go | 11 +++++++++++ chain/sub/incoming.go | 2 +- chain/sync.go | 4 ++-- miner/miner.go | 2 +- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/api/test/deals.go b/api/test/deals.go index ea5956458..050f1d0ee 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "math/rand" + "os" "testing" "time" @@ -17,6 +18,8 @@ import ( ) func TestDealFlow(t *testing.T, b APIBuilder) { + os.Setenv("BELLMAN_NO_GPU", "1") + logging.SetAllLoggers(logging.LevelInfo) ctx := context.TODO() n, sn := b(t, 1, []int{0}) @@ -46,10 +49,14 @@ func TestDealFlow(t *testing.T, b APIBuilder) { fmt.Println("FILE CID: ", fcid) + mine := true + done := make(chan struct{}) + go func() { - for i := 0; i < 4; i++ { + defer close(done) + for mine { time.Sleep(time.Second) - fmt.Println("mining a block now", i) + fmt.Println("mining a block now") if err := n[0].MineOne(ctx); err != nil { t.Fatal(err) } @@ -62,6 +69,7 @@ func TestDealFlow(t *testing.T, b APIBuilder) { // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this time.Sleep(time.Second) + loop: for { di, err := client.ClientGetDealInfo(ctx, *deal) if err != nil { @@ -76,9 +84,13 @@ func TestDealFlow(t *testing.T, b APIBuilder) { t.Fatal("deal errored") case api.DealComplete: fmt.Println("COMPLETE", di) - break + break loop } - fmt.Println("Deal state: ", di.State) + fmt.Println("Deal state: ", api.DealStates[di.State]) time.Sleep(time.Second / 2) } + + mine = false + fmt.Println("shutting down mining") + <-done } diff --git a/api/types.go b/api/types.go index 6a5153328..cd2717bbd 100644 --- a/api/types.go +++ b/api/types.go @@ -25,6 +25,17 @@ const ( DealNoUpdate = DealUnknown ) +var DealStates = []string{ + "DealUnknown", + "DealRejected", + "DealAccepted", + "DealStaged", + "DealSealing", + "DealFailed", + "DealComplete", + "DealError", +} + // TODO: check if this exists anywhere else type MultiaddrSlice []ma.Multiaddr diff --git a/chain/sub/incoming.go b/chain/sub/incoming.go index ddca848e9..5e6c31de1 100644 --- a/chain/sub/incoming.go +++ b/chain/sub/incoming.go @@ -44,7 +44,7 @@ func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *cha return } - log.Infow("new block over pubsub", "cid", blk.Header.Cid(), "source", msg.GetFrom()) + log.Debugw("new block over pubsub", "cid", blk.Header.Cid(), "source", msg.GetFrom()) s.InformNewBlock(msg.GetFrom(), &types.FullBlock{ Header: blk.Header, BlsMessages: bmsgs, diff --git a/chain/sync.go b/chain/sync.go index dac2a79e5..952b57a20 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -102,7 +102,7 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) { if from == syncer.self { // TODO: this is kindof a hack... - log.Info("got block from ourselves") + log.Debug("got block from ourselves") if err := syncer.Sync(ctx, fts.TipSet()); err != nil { log.Errorf("failed to sync our own block %s: %+v", fts.TipSet().Cids(), err) @@ -907,7 +907,7 @@ func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet) error } syncer.syncState.SetStage(api.StageSyncComplete) - log.Infow("new tipset", "height", ts.Height(), "tipset", types.LogCids(ts.Cids())) + log.Debugw("new tipset", "height", ts.Height(), "tipset", types.LogCids(ts.Cids())) return nil } diff --git a/miner/miner.go b/miner/miner.go index 9f7c44478..72ec090c7 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -230,7 +230,7 @@ func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error) } func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, error) { - log.Infow("attempting to mine a block", "tipset", types.LogCids(base.ts.Cids())) + log.Debugw("attempting to mine a block", "tipset", types.LogCids(base.ts.Cids())) ticket, err := m.scratchTicket(ctx, base) if err != nil { return nil, errors.Wrap(err, "scratching ticket failed") From 69d7a9910e28aec122913cfc3f4169455eb2796b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 01:32:10 +0100 Subject: [PATCH 065/114] deals: remove outdated comment --- chain/deals/provider_states.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/chain/deals/provider_states.go b/chain/deals/provider_states.go index 5e5dbc273..96279d7fb 100644 --- a/chain/deals/provider_states.go +++ b/chain/deals/provider_states.go @@ -256,9 +256,6 @@ func (p *Provider) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal if err != nil { return nil, err }*/ - // TODO: Spec doesn't say anything about inclusion proofs anywhere - // Not sure what mechanisms prevents miner from storing data that isn't - // clients' data return nil, nil } From 54722a0d3834a965b905b316b88bec6c00602a83 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 6 Nov 2019 23:57:10 -0800 Subject: [PATCH 066/114] WIP: fixing the tests by waiting for chain activity --- api/api_full.go | 1 + api/struct.go | 5 ++++ chain/deals/client.go | 3 +++ chain/deals/client_states.go | 46 ++++++++++++++++++++++++++++++++++ chain/deals/provider_states.go | 1 + chain/stmgr/utils.go | 20 +++++++++++++++ node/impl/full/state.go | 7 +++++- storage/sector_states.go | 3 +++ 8 files changed, 85 insertions(+), 1 deletion(-) diff --git a/api/api_full.go b/api/api_full.go index bab1002ab..27c07e65e 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -109,6 +109,7 @@ type FullNode interface { StateMarketBalance(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error) StateMarketParticipants(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error) StateMarketDeals(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) + StateMarketStorageDeal(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) PaychList(context.Context) ([]address.Address, error) diff --git a/api/struct.go b/api/struct.go index 437e37624..682e8f3e7 100644 --- a/api/struct.go +++ b/api/struct.go @@ -105,6 +105,7 @@ type FullNodeStruct struct { StateMarketBalance func(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error) `perm:"read"` StateMarketParticipants func(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error) `perm:"read"` StateMarketDeals func(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) `perm:"read"` + StateMarketStorageDeal func(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) `perm:"read"` PaychGet func(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) `perm:"sign"` PaychList func(context.Context) ([]address.Address, error) `perm:"read"` @@ -413,6 +414,10 @@ func (c *FullNodeStruct) StateMarketDeals(ctx context.Context, ts *types.TipSet) return c.Internal.StateMarketDeals(ctx, ts) } +func (c *FullNodeStruct) StateMarketStorageDeal(ctx context.Context, dealid uint64, ts *types.TipSet) (*actors.OnChainDeal, error) { + return c.Internal.StateMarketStorageDeal(ctx, dealid, ts) +} + func (c *FullNodeStruct) PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) { return c.Internal.PaychGet(ctx, from, to, ensureFunds) } diff --git a/chain/deals/client.go b/chain/deals/client.go index 3fb982ecc..4f9fdecc8 100644 --- a/chain/deals/client.go +++ b/chain/deals/client.go @@ -18,6 +18,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/address" + "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -34,6 +35,7 @@ type ClientDeal struct { Proposal actors.StorageDealProposal State api.DealState Miner peer.ID + DealID uint64 s inet.Stream } @@ -46,6 +48,7 @@ type Client struct { dag dtypes.ClientDAG discovery *discovery.Local mpool full.MpoolAPI + events *events.Events deals *statestore.StateStore conns map[cid.Cid]inet.Stream diff --git a/chain/deals/client_states.go b/chain/deals/client_states.go index bb30e8440..982c68090 100644 --- a/chain/deals/client_states.go +++ b/chain/deals/client_states.go @@ -8,6 +8,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/stmgr" + "github.com/filecoin-project/lotus/chain/types" ) type clientHandlerFunc func(ctx context.Context, deal ClientDeal) error @@ -126,6 +127,51 @@ func (c *Client) staged(ctx context.Context, deal ClientDeal) error { } func (c *Client) sealing(ctx context.Context, deal ClientDeal) error { + //func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHandler, confidence int, timeout uint64, actor address.Address, method uint64) error { + checkFunc := func(ts *types.TipSet) (done bool, more bool, err error) { + sd, err := stmgr.GetStorageDeal(ctx, c.stmgr, deal.DealID, ts) + if err != nil { + return false, false, xerrors.Errorf("failed to look up deal on chain: %w", err) + } + + if sd.ActivationEpoch > 0 { + // Deal is active already! + panic("handle me") + return true, false, nil + } + + return false, true, nil + } + + called := func(msg *types.Message, ts *types.TipSet, curH uint64) (bool, error) { + // To ask Magik: Does this trigger when the message in question is part of the parent state execution? Or just when its included in the block (aka, not executed) + // main thing i want to ensure is that ts.ParentState is the result of the execution of msg + + if msg == nil { + log.Error("timed out waiting for deal activation... what now?") + return false, nil + } + + // TODO: can check msg.Params to see if we should even bother checking the state + + sd, err := stmgr.GetStorageDeal(ctx, c.stmgr, deal.DealID, ts) + if err != nil { + return false, false, xerrors.Errorf("failed to look up deal on chain: %w", err) + } + + if sd.ActivationEpoch == 0 { + return true, nil + } + + // Deal is active! + panic("handle me") + + return false, nil + } + + if err := c.events.Called(checkFunc, handler, rev, 3, 100, actors.StorageMarketAddress, actors.SMAMethods.ActivateStorageDeals); err != nil { + return xerrors.Errorf("failed to set up called handler") + } resp, err := c.readStorageDealResp(deal) if err != nil { return err diff --git a/chain/deals/provider_states.go b/chain/deals/provider_states.go index 96279d7fb..a177bb1f1 100644 --- a/chain/deals/provider_states.go +++ b/chain/deals/provider_states.go @@ -247,6 +247,7 @@ func (p *Provider) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal log.Warnf("Sending deal response failed: %s", err) } + log.Info("About to seal sector!", deal.ProposalCid, deal.SectorID) if err := p.sminer.SealSector(ctx, deal.SectorID); err != nil { return nil, xerrors.Errorf("sealing sector failed: %w", err) } diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 1dff70bbd..ecd5acf87 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -193,6 +193,26 @@ func GetMinerSectorSize(ctx context.Context, sm *StateManager, ts *types.TipSet, return minfo.SectorSize, nil } +func GetStorageDeal(ctx context.Context, sm *StateManager, dealId uint64, ts *types.TipSet) (*actors.OnChainDeal, error) { + var state actors.StorageMarketState + if _, err := sm.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil { + return nil, err + } + + blks := amt.WrapBlockstore(sm.ChainStore().Blockstore()) + da, err := amt.LoadAMT(blks, state.Deals) + if err != nil { + return nil, err + } + + var ocd actors.OnChainDeal + if err := da.Get(dealId, &ocd); err != nil { + return nil, err + } + + return &ocd, nil +} + func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid) ([]*api.SectorInfo, error) { blks := amt.WrapBlockstore(bs) a, err := amt.LoadAMT(blks, ssc) diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 68a134246..5c9ee4050 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -3,9 +3,10 @@ package full import ( "bytes" "context" - "github.com/filecoin-project/go-amt-ipld" "strconv" + "github.com/filecoin-project/go-amt-ipld" + cid "github.com/ipfs/go-cid" "github.com/ipfs/go-hamt-ipld" "github.com/libp2p/go-libp2p-core/peer" @@ -279,3 +280,7 @@ func (a *StateAPI) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[ } return out, nil } + +func (a *StateAPI) StateMarketStorageDeal(ctx context.Context, dealId uint64, ts *types.TipSet) (*actors.OnChainDeal, error) { + return stmgr.GetStorageDeal(ctx, s.StateManager, dealId, ts) +} diff --git a/storage/sector_states.go b/storage/sector_states.go index b57a5e315..a2662eb35 100644 --- a/storage/sector_states.go +++ b/storage/sector_states.go @@ -2,6 +2,7 @@ package storage import ( "context" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" @@ -113,6 +114,7 @@ func (m *Miner) preCommit(ctx context.Context, sector SectorInfo) (func(*SectorI func (m *Miner) preCommitted(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { // would be ideal to just use the events.Called handler, but it wouldnt be able to handle individual message timeouts + log.Info("Sector precommitted: ", sector.SectorID) mw, err := m.api.StateWaitMsg(ctx, *sector.PreCommitMessage) if err != nil { return nil, err @@ -122,6 +124,7 @@ func (m *Miner) preCommitted(ctx context.Context, sector SectorInfo) (func(*Sect log.Error("sector precommit failed: ", mw.Receipt.ExitCode) return nil, err } + log.Info("precommit message landed on chain: ", sector.SectorID) randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay - 1 // -1 because of how the messages are applied log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight) From bdb1c877a91b625e417613047e4b0264f883bc7a Mon Sep 17 00:00:00 2001 From: wanghui Date: Thu, 7 Nov 2019 16:18:52 +0800 Subject: [PATCH 067/114] fix ask price typo --- cli/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/client.go b/cli/client.go index 7f9771a3d..f61be20f0 100644 --- a/cli/client.go +++ b/cli/client.go @@ -307,7 +307,7 @@ var clientQueryAskCmd = &cli.Command{ } fmt.Printf("Ask: %s\n", maddr) - fmt.Printf("Price per Byte: %s\n", types.FIL(ask.Ask.Price)) + fmt.Printf("Price per GigaByte: %s\n", types.FIL(ask.Ask.Price)) size := cctx.Int64("size") if size == 0 { From 6cc360e0f7f35aa9de30974b5e86e50feca9a5bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 10:02:29 +0100 Subject: [PATCH 068/114] events: Execute Called handlers in the correct tipset --- chain/events/events_called.go | 14 +++++++---- chain/events/events_test.go | 46 +++++++++++++++++------------------ 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/chain/events/events_called.go b/chain/events/events_called.go index c51d9bef6..94368214e 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -24,7 +24,7 @@ type triggerH = uint64 // `ts` is the tipset, in which the `msg` is included. // `curH`-`ts.Height` = `confidence` -type CalledHandler func(msg *types.Message, ts *types.TipSet, curH uint64) (bool, error) +type CalledHandler func(msg *types.Message, ts *types.TipSet, curH uint64) (more bool, err error) // CheckFunc is used for atomicity guarantees. If the condition the callbacks // wait for has already happened in tipset `ts` @@ -147,7 +147,11 @@ func (e *calledEvents) checkNewCalls(ts *types.TipSet) { func (e *calledEvents) queueForConfidence(triggerId uint64, msg *types.Message, ts *types.TipSet) { trigger := e.triggers[triggerId] - triggerH := ts.Height() + uint64(trigger.confidence) + + // messages are not applied in the tipset they are included in + appliedH := ts.Height() + 1 + + triggerH := appliedH + uint64(trigger.confidence) byOrigH, ok := e.confQueue[triggerH] if !ok { @@ -155,13 +159,13 @@ func (e *calledEvents) queueForConfidence(triggerId uint64, msg *types.Message, e.confQueue[triggerH] = byOrigH } - byOrigH[ts.Height()] = append(byOrigH[ts.Height()], &queuedEvent{ + byOrigH[appliedH] = append(byOrigH[appliedH], &queuedEvent{ trigger: triggerId, - h: ts.Height(), + h: appliedH, msg: msg, }) - e.revertQueue[ts.Height()] = append(e.revertQueue[ts.Height()], triggerH) // todo: dedupe? + e.revertQueue[appliedH] = append(e.revertQueue[appliedH], triggerH) } func (e *calledEvents) applyWithConfidence(ts *types.TipSet) { diff --git a/chain/events/events_test.go b/chain/events/events_test.go index d738edf86..27a3edf03 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -526,28 +526,28 @@ func TestCalled(t *testing.T) { // create additional block so we are above confidence threshold - fcs.advance(0, 1, nil) // H=9 (confidence=3, apply) + fcs.advance(0, 2, nil) // H=10 (confidence=3, apply) require.Equal(t, true, applied) require.Equal(t, false, reverted) applied = false - require.Equal(t, uint64(6), appliedTs.Height()) - require.Equal(t, "bafkqaajq", appliedTs.Blocks()[0].Messages.String()) - require.Equal(t, uint64(9), appliedH) + require.Equal(t, uint64(7), appliedTs.Height()) + require.Equal(t, "bafkqaaa", appliedTs.Blocks()[0].Messages.String()) + require.Equal(t, uint64(10), appliedH) require.Equal(t, t0123, appliedMsg.To) require.Equal(t, uint64(1), appliedMsg.Nonce) require.Equal(t, uint64(5), appliedMsg.Method) // revert some blocks, keep the message - fcs.advance(3, 1, nil) // H=7 (confidence=1) + fcs.advance(3, 1, nil) // H=8 (confidence=1) require.Equal(t, false, applied) require.Equal(t, false, reverted) // revert the message - fcs.advance(2, 1, nil) // H=6, we reverted ts with the msg + fcs.advance(2, 1, nil) // H=7, we reverted ts with the msg require.Equal(t, false, applied) require.Equal(t, true, reverted) @@ -561,7 +561,7 @@ func TestCalled(t *testing.T) { }, }) - fcs.advance(0, 4, map[int]cid.Cid{ // msg at H=7; H=10 (confidence=3) + fcs.advance(0, 5, map[int]cid.Cid{ // (confidence=3) 0: n2msg, }) @@ -569,16 +569,16 @@ func TestCalled(t *testing.T) { require.Equal(t, false, reverted) applied = false - require.Equal(t, uint64(7), appliedTs.Height()) - require.Equal(t, "bafkqaajr", appliedTs.Blocks()[0].Messages.String()) - require.Equal(t, uint64(10), appliedH) + require.Equal(t, uint64(9), appliedTs.Height()) + require.Equal(t, "bafkqaaa", appliedTs.Blocks()[0].Messages.String()) + require.Equal(t, uint64(12), appliedH) require.Equal(t, t0123, appliedMsg.To) require.Equal(t, uint64(2), appliedMsg.Nonce) require.Equal(t, uint64(5), appliedMsg.Method) // revert and apply at different height - fcs.advance(4, 5, map[int]cid.Cid{ // msg at H=8; H=11 (confidence=3) + fcs.advance(4, 6, map[int]cid.Cid{ // (confidence=3) 1: n2msg, }) @@ -590,16 +590,16 @@ func TestCalled(t *testing.T) { reverted = false applied = false - require.Equal(t, uint64(8), appliedTs.Height()) - require.Equal(t, "bafkqaajr", appliedTs.Blocks()[0].Messages.String()) - require.Equal(t, uint64(11), appliedH) + require.Equal(t, uint64(11), appliedTs.Height()) + require.Equal(t, "bafkqaaa", appliedTs.Blocks()[0].Messages.String()) + require.Equal(t, uint64(14), appliedH) require.Equal(t, t0123, appliedMsg.To) require.Equal(t, uint64(2), appliedMsg.Nonce) require.Equal(t, uint64(5), appliedMsg.Method) // call method again - fcs.advance(0, 4, map[int]cid.Cid{ // msg at H=12; H=15 + fcs.advance(0, 5, map[int]cid.Cid{ 0: n2msg, }) @@ -608,7 +608,7 @@ func TestCalled(t *testing.T) { applied = false // send and revert below confidence, then cross confidence - fcs.advance(0, 1, map[int]cid.Cid{ // msg at H=16; H=16 + fcs.advance(0, 2, map[int]cid.Cid{ 0: fcs.fakeMsgs(fakeMsg{ bmsgs: []*types.Message{ {To: t0123, From: t0123, Method: 5, Nonce: 3}, @@ -623,7 +623,7 @@ func TestCalled(t *testing.T) { // test timeout (it's set to 20 in the call to `events.Called` above) - fcs.advance(0, 6, nil) // H=25 + fcs.advance(0, 6, nil) require.Equal(t, false, applied) // not calling timeout as we received messages require.Equal(t, false, reverted) @@ -631,7 +631,7 @@ func TestCalled(t *testing.T) { // test unregistering with more more = false - fcs.advance(0, 4, map[int]cid.Cid{ // msg at H=26; H=29 + fcs.advance(0, 5, map[int]cid.Cid{ 0: fcs.fakeMsgs(fakeMsg{ bmsgs: []*types.Message{ {To: t0123, From: t0123, Method: 5, Nonce: 4}, // this signals we don't want more @@ -643,7 +643,7 @@ func TestCalled(t *testing.T) { require.Equal(t, false, reverted) applied = false - fcs.advance(0, 4, map[int]cid.Cid{ // msg at H=26; H=29 + fcs.advance(0, 5, map[int]cid.Cid{ 0: fcs.fakeMsgs(fakeMsg{ bmsgs: []*types.Message{ {To: t0123, From: t0123, Method: 5, Nonce: 5}, @@ -765,10 +765,10 @@ func TestCalledOrder(t *testing.T) { switch at { case 0: require.Equal(t, uint64(1), msg.Nonce) - require.Equal(t, uint64(3), ts.Height()) + require.Equal(t, uint64(4), ts.Height()) case 1: require.Equal(t, uint64(2), msg.Nonce) - require.Equal(t, uint64(4), ts.Height()) + require.Equal(t, uint64(5), ts.Height()) default: t.Fatal("apply should only get called twice, at: ", at) } @@ -777,9 +777,9 @@ func TestCalledOrder(t *testing.T) { }, func(_ context.Context, ts *types.TipSet) error { switch at { case 2: - require.Equal(t, uint64(4), ts.Height()) + require.Equal(t, uint64(5), ts.Height()) case 3: - require.Equal(t, uint64(3), ts.Height()) + require.Equal(t, uint64(4), ts.Height()) default: t.Fatal("revert should only get called twice, at: ", at) } From 12161fc60704697eb80b4778db9d80c0d5a2ce90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 10:06:06 +0100 Subject: [PATCH 069/114] deals: Finish client sealing state handler --- api/test/deals.go | 2 +- chain/deals/client.go | 6 ++-- chain/deals/client_states.go | 59 +++++++++++++++++++++++------------- node/impl/full/state.go | 2 +- 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/api/test/deals.go b/api/test/deals.go index 050f1d0ee..41dda8228 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -69,7 +69,7 @@ func TestDealFlow(t *testing.T, b APIBuilder) { // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this time.Sleep(time.Second) - loop: +loop: for { di, err := client.ClientGetDealInfo(ctx, *deal) if err != nil { diff --git a/chain/deals/client.go b/chain/deals/client.go index 4f9fdecc8..ddc0efb8b 100644 --- a/chain/deals/client.go +++ b/chain/deals/client.go @@ -66,7 +66,7 @@ type clientDealUpdate struct { err error } -func NewClient(sm *stmgr.StateManager, chain *store.ChainStore, h host.Host, w *wallet.Wallet, ds dtypes.MetadataDS, dag dtypes.ClientDAG, discovery *discovery.Local, mpool full.MpoolAPI) *Client { +func NewClient(sm *stmgr.StateManager, chain *store.ChainStore, h host.Host, w *wallet.Wallet, ds dtypes.MetadataDS, dag dtypes.ClientDAG, discovery *discovery.Local, mpool full.MpoolAPI, chainapi full.ChainAPI) *Client { c := &Client{ sm: sm, chain: chain, @@ -75,6 +75,7 @@ func NewClient(sm *stmgr.StateManager, chain *store.ChainStore, h host.Host, w * dag: dag, discovery: discovery, mpool: mpool, + events: events.NewEvents(context.TODO(), &chainapi), deals: statestore.New(namespace.Wrap(ds, datastore.NewKey("/deals/client"))), conns: map[cid.Cid]inet.Stream{}, @@ -157,7 +158,8 @@ func (c *Client) onUpdated(ctx context.Context, update clientDealUpdate) { case api.DealStaged: c.handle(ctx, deal, c.staged, api.DealSealing) case api.DealSealing: - c.handle(ctx, deal, c.sealing, api.DealComplete) + c.handle(ctx, deal, c.sealing, api.DealNoUpdate) + // TODO: DealComplete -> watch for faults, expiration, etc. } } diff --git a/chain/deals/client_states.go b/chain/deals/client_states.go index 982c68090..e1157ad1d 100644 --- a/chain/deals/client_states.go +++ b/chain/deals/client_states.go @@ -2,6 +2,7 @@ package deals import ( "context" + "github.com/filecoin-project/lotus/build" "golang.org/x/xerrors" @@ -19,6 +20,11 @@ func (c *Client) handle(ctx context.Context, deal ClientDeal, cb clientHandlerFu if err != nil { next = api.DealError } + + if err == nil && next == api.DealNoUpdate { + return + } + select { case c.updated <- clientDealUpdate{ newState: next, @@ -127,16 +133,25 @@ func (c *Client) staged(ctx context.Context, deal ClientDeal) error { } func (c *Client) sealing(ctx context.Context, deal ClientDeal) error { - //func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHandler, confidence int, timeout uint64, actor address.Address, method uint64) error { + + // TODO: disconnect + checkFunc := func(ts *types.TipSet) (done bool, more bool, err error) { - sd, err := stmgr.GetStorageDeal(ctx, c.stmgr, deal.DealID, ts) + sd, err := stmgr.GetStorageDeal(ctx, c.sm, deal.DealID, ts) if err != nil { + // TODO: This may be fine for some errors return false, false, xerrors.Errorf("failed to look up deal on chain: %w", err) } if sd.ActivationEpoch > 0 { - // Deal is active already! - panic("handle me") + select { + case c.updated <- clientDealUpdate{ + newState: api.DealComplete, + id: deal.ProposalCid, + }: + case <-c.stop: + } + return true, false, nil } @@ -144,8 +159,7 @@ func (c *Client) sealing(ctx context.Context, deal ClientDeal) error { } called := func(msg *types.Message, ts *types.TipSet, curH uint64) (bool, error) { - // To ask Magik: Does this trigger when the message in question is part of the parent state execution? Or just when its included in the block (aka, not executed) - // main thing i want to ensure is that ts.ParentState is the result of the execution of msg + // TODO: handle errors if msg == nil { log.Error("timed out waiting for deal activation... what now?") @@ -154,34 +168,37 @@ func (c *Client) sealing(ctx context.Context, deal ClientDeal) error { // TODO: can check msg.Params to see if we should even bother checking the state - sd, err := stmgr.GetStorageDeal(ctx, c.stmgr, deal.DealID, ts) + sd, err := stmgr.GetStorageDeal(ctx, c.sm, deal.DealID, ts) if err != nil { - return false, false, xerrors.Errorf("failed to look up deal on chain: %w", err) + return false, xerrors.Errorf("failed to look up deal on chain: %w", err) } if sd.ActivationEpoch == 0 { return true, nil } - // Deal is active! - panic("handle me") + log.Info("Storage deal %d activated at epoch %d", deal.DealID, sd.ActivationEpoch) + + select { + case c.updated <- clientDealUpdate{ + newState: api.DealComplete, + id: deal.ProposalCid, + }: + case <-c.stop: + } return false, nil } - if err := c.events.Called(checkFunc, handler, rev, 3, 100, actors.StorageMarketAddress, actors.SMAMethods.ActivateStorageDeals); err != nil { + revert := func(ctx context.Context, ts *types.TipSet) error { + log.Warn("deal activation reverted; TODO: actually handle this!") + // TODO: Just go back to DealSealing? + return nil + } + + if err := c.events.Called(checkFunc, called, revert, 3, build.SealRandomnessLookbackLimit, deal.Proposal.Provider, actors.MAMethods.ProveCommitSector); err != nil { return xerrors.Errorf("failed to set up called handler") } - resp, err := c.readStorageDealResp(deal) - if err != nil { - return err - } - - if resp.State != api.DealComplete { - return xerrors.Errorf("deal wasn't complete (State=%d)", resp.State) - } - - // TODO: look for the commit message on chain, negotiate better payment vouchers log.Info("DEAL COMPLETE!!") return nil diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 5c9ee4050..606e3416a 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -282,5 +282,5 @@ func (a *StateAPI) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[ } func (a *StateAPI) StateMarketStorageDeal(ctx context.Context, dealId uint64, ts *types.TipSet) (*actors.OnChainDeal, error) { - return stmgr.GetStorageDeal(ctx, s.StateManager, dealId, ts) + return stmgr.GetStorageDeal(ctx, a.StateManager, dealId, ts) } From f221c05a334b12363aca181479a74073aed0e2a2 Mon Sep 17 00:00:00 2001 From: wanghui Date: Thu, 7 Nov 2019 18:46:11 +0800 Subject: [PATCH 070/114] add sector size info --- cmd/lotus-storage-miner/info.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 436fc4686..287112494 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -37,6 +37,13 @@ var infoCmd = &cli.Command{ fmt.Printf("Miner: %s\n", maddr) + // Sector size + size, err := api.StateMinerSectorSize(ctx, maddr, nil) + if err != nil { + return err + } + fmt.Printf("Sector Size(Byte): %d\n", types.NewInt(size)) + pow, err := api.StateMinerPower(ctx, maddr, nil) if err != nil { return err @@ -56,7 +63,6 @@ var infoCmd = &cli.Command{ fmt.Println("Failed Sectors:\t", sinfo.FailedCount) // TODO: grab actr state / info - // * Sector size // * Sealed sectors (count / bytes) // * Power return nil From 08ff772cf41cd7746b2a3c05992cef6e011e6ec7 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 7 Nov 2019 19:33:44 +0800 Subject: [PATCH 071/114] Update cmd/lotus-storage-miner/info.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit update sector size format Co-Authored-By: Łukasz Magiera --- cmd/lotus-storage-miner/info.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 287112494..05946f807 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -42,7 +42,7 @@ var infoCmd = &cli.Command{ if err != nil { return err } - fmt.Printf("Sector Size(Byte): %d\n", types.NewInt(size)) + fmt.Printf("Sector Size: %dKiB\n", size / 1024) pow, err := api.StateMinerPower(ctx, maddr, nil) if err != nil { From be0d07e14303056c19fe1391ffda730664b8a687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 13:03:18 +0100 Subject: [PATCH 072/114] pass deal IDs in SectorPreCommitInfo --- api/test/deals.go | 2 +- chain/actors/actor_miner.go | 56 +++++---- chain/actors/cbor_gen.go | 232 +++++++++++++++--------------------- chain/deals/cbor_gen.go | 19 ++- gen/main.go | 2 +- storage/sector_states.go | 13 +- 6 files changed, 153 insertions(+), 171 deletions(-) diff --git a/api/test/deals.go b/api/test/deals.go index 41dda8228..3145f7c4a 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -21,7 +21,7 @@ func TestDealFlow(t *testing.T, b APIBuilder) { os.Setenv("BELLMAN_NO_GPU", "1") logging.SetAllLoggers(logging.LevelInfo) - ctx := context.TODO() + ctx := context.Background() n, sn := b(t, 1, []int{0}) client := n[0].FullNode.(*impl.FullNodeAPI) miner := sn[0] diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index 963a469e9..608cbd5df 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -24,7 +24,7 @@ type StorageMinerActor struct{} type StorageMinerActorState struct { // PreCommittedSectors is the set of sectors that have been committed to but not // yet had their proofs submitted - PreCommittedSectors map[string]*UnprovenSector + PreCommittedSectors map[string]*PreCommittedSector // All sectors this miner has committed. Sectors cid.Cid @@ -94,11 +94,9 @@ type MinerInfo struct { // SubsectorCount } -type UnprovenSector struct { - CommD []byte - CommR []byte - SubmitHeight uint64 - TicketEpoch uint64 +type PreCommittedSector struct { + Info SectorPreCommitInfo + ReceivedEpoch uint64 } type StorageMinerConstructorParams struct { @@ -108,6 +106,14 @@ type StorageMinerConstructorParams struct { PeerID peer.ID } +type SectorPreCommitInfo struct { + SectorNumber uint64 + + CommR []byte // TODO: Spec says CID + SealEpoch uint64 + DealIDs []uint64 +} + type maMethods struct { Constructor uint64 PreCommitSector uint64 @@ -212,14 +218,6 @@ func (sma StorageMinerActor) StorageMinerConstructor(act *types.Actor, vmctx typ return nil, nil } -type SectorPreCommitInfo struct { - CommD []byte // TODO: update proofs code - CommR []byte - - Epoch uint64 - SectorNumber uint64 -} - func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMContext, params *SectorPreCommitInfo) ([]byte, ActorError) { ctx := vmctx.Context() oldstate, self, err := loadState(vmctx) @@ -227,12 +225,12 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon return nil, err } - if params.Epoch >= vmctx.BlockHeight()+build.SealRandomnessLookback { - return nil, aerrors.Newf(1, "sector commitment must be based off past randomness (%d >= %d)", params.Epoch, vmctx.BlockHeight()+build.SealRandomnessLookback) + if params.SealEpoch >= vmctx.BlockHeight()+build.SealRandomnessLookback { + return nil, aerrors.Newf(1, "sector commitment must be based off past randomness (%d >= %d)", params.SealEpoch, vmctx.BlockHeight()+build.SealRandomnessLookback) } - if vmctx.BlockHeight()-params.Epoch+build.SealRandomnessLookback > build.SealRandomnessLookbackLimit { - return nil, aerrors.Newf(2, "sector commitment must be recent enough (was %d)", vmctx.BlockHeight()-params.Epoch+build.SealRandomnessLookback) + if vmctx.BlockHeight()-params.SealEpoch+build.SealRandomnessLookback > build.SealRandomnessLookbackLimit { + return nil, aerrors.Newf(2, "sector commitment must be recent enough (was %d)", vmctx.BlockHeight()-params.SealEpoch+build.SealRandomnessLookback) } mi, err := loadMinerInfo(vmctx, self) @@ -262,11 +260,9 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon return nil, aerrors.New(4, "not enough collateral") } - self.PreCommittedSectors[uintToStringKey(params.SectorNumber)] = &UnprovenSector{ - CommR: params.CommR, - CommD: params.CommD, - SubmitHeight: vmctx.BlockHeight(), - TicketEpoch: params.Epoch, + self.PreCommittedSectors[uintToStringKey(params.SectorNumber)] = &PreCommittedSector{ + Info: *params, + ReceivedEpoch: vmctx.BlockHeight(), } nstate, err := vmctx.Storage().Put(self) @@ -309,7 +305,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC return nil, aerrors.New(1, "no pre-commitment found for sector") } - if us.SubmitHeight+build.InteractivePoRepDelay > vmctx.BlockHeight() { + if us.ReceivedEpoch+build.InteractivePoRepDelay > vmctx.BlockHeight() { return nil, aerrors.New(2, "too early for proof submission") } @@ -318,12 +314,12 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC // TODO: ensure normalization to ID address maddr := vmctx.Message().To - ticket, err := vmctx.GetRandomness(us.TicketEpoch - build.SealRandomnessLookback) + ticket, err := vmctx.GetRandomness(us.Info.SealEpoch - build.SealRandomnessLookback) if err != nil { return nil, aerrors.Wrap(err, "failed to get ticket randomness") } - seed, err := vmctx.GetRandomness(us.SubmitHeight + build.InteractivePoRepDelay) + seed, err := vmctx.GetRandomness(us.ReceivedEpoch + build.InteractivePoRepDelay) if err != nil { return nil, aerrors.Wrap(err, "failed to get randomness for prove sector commitment") } @@ -341,16 +337,16 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC return nil, aerrors.Wrap(err, "failed to compute data commitment") } - if ok, err := ValidatePoRep(maddr, mi.SectorSize, commD, us.CommR, ticket, params.Proof, seed, params.SectorID); err != nil { + if ok, err := ValidatePoRep(maddr, mi.SectorSize, commD, us.Info.CommR, ticket, params.Proof, seed, params.SectorID); err != nil { return nil, err } else if !ok { - return nil, aerrors.Newf(2, "bad proof! (t:%x; s:%x(%d); p:%x)", ticket, seed, us.SubmitHeight+build.InteractivePoRepDelay, params.Proof) + return nil, aerrors.Newf(2, "bad proof! (t:%x; s:%x(%d); p:%x)", ticket, seed, us.ReceivedEpoch+build.InteractivePoRepDelay, params.Proof) } // Note: There must exist a unique index in the miner's sector set for each // sector ID. The `faults`, `recovered`, and `done` parameters of the // SubmitPoSt method express indices into this sector set. - nssroot, err := AddToSectorSet(ctx, vmctx.Storage(), self.Sectors, params.SectorID, us.CommR, us.CommD) + nssroot, err := AddToSectorSet(ctx, vmctx.Storage(), self.Sectors, params.SectorID, us.Info.CommR, commD) if err != nil { return nil, err } @@ -581,6 +577,8 @@ func AddToSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID u return cid.Undef, aerrors.HandleExternalError(err, "could not load sector set node") } + // TODO: Spec says to use SealCommitment, and construct commD from deals each time, + // but that would make SubmitPoSt way, way more expensive if err := ssr.Set(sectorID, [][]byte{commR, commD}); err != nil { return cid.Undef, aerrors.HandleExternalError(err, "failed to set commitment in sector set") } diff --git a/chain/actors/cbor_gen.go b/chain/actors/cbor_gen.go index 073286eb3..7b5aef2fb 100644 --- a/chain/actors/cbor_gen.go +++ b/chain/actors/cbor_gen.go @@ -201,7 +201,7 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { return err } - // t.t.PreCommittedSectors (map[string]*actors.UnprovenSector) (map) + // t.t.PreCommittedSectors (map[string]*actors.PreCommittedSector) (map) if err := cbg.CborWriteHeader(w, cbg.MajMap, uint64(len(t.PreCommittedSectors))); err != nil { return err } @@ -291,7 +291,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input had wrong number of fields") } - // t.t.PreCommittedSectors (map[string]*actors.UnprovenSector) (map) + // t.t.PreCommittedSectors (map[string]*actors.PreCommittedSector) (map) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -304,7 +304,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("t.PreCommittedSectors: map too large") } - t.PreCommittedSectors = make(map[string]*UnprovenSector, extra) + t.PreCommittedSectors = make(map[string]*PreCommittedSector, extra) for i, l := 0, int(extra); i < l; i++ { @@ -319,7 +319,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { k = string(sval) } - var v *UnprovenSector + var v *PreCommittedSector { @@ -333,7 +333,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error { return err } } else { - v = new(UnprovenSector) + v = new(PreCommittedSector) if err := v.UnmarshalCBOR(br); err != nil { return err } @@ -546,11 +546,8 @@ func (t *SectorPreCommitInfo) MarshalCBOR(w io.Writer) error { return err } - // t.t.CommD ([]uint8) (slice) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommD)))); err != nil { - return err - } - if _, err := w.Write(t.CommD); err != nil { + // t.t.SectorNumber (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorNumber))); err != nil { return err } @@ -562,15 +559,20 @@ func (t *SectorPreCommitInfo) MarshalCBOR(w io.Writer) error { return err } - // t.t.Epoch (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Epoch))); err != nil { + // t.t.SealEpoch (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SealEpoch))); err != nil { return err } - // t.t.SectorNumber (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorNumber))); err != nil { + // t.t.DealIDs ([]uint64) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { return err } + for _, v := range t.DealIDs { + if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { + return err + } + } return nil } @@ -589,50 +591,6 @@ func (t *SectorPreCommitInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input had wrong number of fields") } - // t.t.CommD ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if extra > 8192 { - return fmt.Errorf("t.CommD: array too large (%d)", extra) - } - - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.CommD = make([]byte, extra) - if _, err := io.ReadFull(br, t.CommD); err != nil { - return err - } - // t.t.CommR ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if extra > 8192 { - return fmt.Errorf("t.CommR: array too large (%d)", extra) - } - - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.CommR = make([]byte, extra) - if _, err := io.ReadFull(br, t.CommR); err != nil { - return err - } - // t.t.Epoch (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Epoch = uint64(extra) // t.t.SectorNumber (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) @@ -643,78 +601,6 @@ func (t *SectorPreCommitInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("wrong type for uint64 field") } t.SectorNumber = uint64(extra) - return nil -} - -func (t *UnprovenSector) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{132}); err != nil { - return err - } - - // t.t.CommD ([]uint8) (slice) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommD)))); err != nil { - return err - } - if _, err := w.Write(t.CommD); err != nil { - return err - } - - // t.t.CommR ([]uint8) (slice) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommR)))); err != nil { - return err - } - if _, err := w.Write(t.CommR); err != nil { - return err - } - - // t.t.SubmitHeight (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SubmitHeight))); err != nil { - return err - } - - // t.t.TicketEpoch (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.TicketEpoch))); err != nil { - return err - } - return nil -} - -func (t *UnprovenSector) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 4 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.t.CommD ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if extra > 8192 { - return fmt.Errorf("t.CommD: array too large (%d)", extra) - } - - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.CommD = make([]byte, extra) - if _, err := io.ReadFull(br, t.CommD); err != nil { - return err - } // t.t.CommR ([]uint8) (slice) maj, extra, err = cbg.CborReadHeader(br) @@ -732,7 +618,7 @@ func (t *UnprovenSector) UnmarshalCBOR(r io.Reader) error { if _, err := io.ReadFull(br, t.CommR); err != nil { return err } - // t.t.SubmitHeight (uint64) (uint64) + // t.t.SealEpoch (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -741,8 +627,86 @@ func (t *UnprovenSector) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.SubmitHeight = uint64(extra) - // t.t.TicketEpoch (uint64) (uint64) + t.SealEpoch = uint64(extra) + // t.t.DealIDs ([]uint64) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.DealIDs: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.DealIDs = make([]uint64, extra) + } + for i := 0; i < int(extra); i++ { + + maj, val, err := cbg.CborReadHeader(br) + if err != nil { + return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) + } + + if maj != cbg.MajUnsignedInt { + return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) + } + + t.DealIDs[i] = val + } + + return nil +} + +func (t *PreCommittedSector) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{130}); err != nil { + return err + } + + // t.t.Info (actors.SectorPreCommitInfo) (struct) + if err := t.Info.MarshalCBOR(w); err != nil { + return err + } + + // t.t.ReceivedEpoch (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ReceivedEpoch))); err != nil { + return err + } + return nil +} + +func (t *PreCommittedSector) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 2 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.Info (actors.SectorPreCommitInfo) (struct) + + { + + if err := t.Info.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.t.ReceivedEpoch (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -751,7 +715,7 @@ func (t *UnprovenSector) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.TicketEpoch = uint64(extra) + t.ReceivedEpoch = uint64(extra) return nil } diff --git a/chain/deals/cbor_gen.go b/chain/deals/cbor_gen.go index 08edb9371..585836a89 100644 --- a/chain/deals/cbor_gen.go +++ b/chain/deals/cbor_gen.go @@ -577,7 +577,7 @@ func (t *ClientDeal) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{132}); err != nil { + if _, err := w.Write([]byte{133}); err != nil { return err } @@ -604,6 +604,11 @@ func (t *ClientDeal) MarshalCBOR(w io.Writer) error { if _, err := w.Write([]byte(t.Miner)); err != nil { return err } + + // t.t.DealID (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.DealID))); err != nil { + return err + } return nil } @@ -618,7 +623,7 @@ func (t *ClientDeal) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 4 { + if extra != 5 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -663,6 +668,16 @@ func (t *ClientDeal) UnmarshalCBOR(r io.Reader) error { t.Miner = peer.ID(sval) } + // t.t.DealID (uint64) (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.DealID = uint64(extra) return nil } diff --git a/gen/main.go b/gen/main.go index 4c0c2167a..efe1af965 100644 --- a/gen/main.go +++ b/gen/main.go @@ -91,7 +91,7 @@ func main() { actors.StorageMinerActorState{}, actors.StorageMinerConstructorParams{}, actors.SectorPreCommitInfo{}, - actors.UnprovenSector{}, + actors.PreCommittedSector{}, actors.MinerInfo{}, actors.SubmitPoStParams{}, actors.PaymentVerifyParams{}, diff --git a/storage/sector_states.go b/storage/sector_states.go index a2662eb35..b52402c4f 100644 --- a/storage/sector_states.go +++ b/storage/sector_states.go @@ -78,12 +78,17 @@ func (m *Miner) sealPreCommit(ctx context.Context, sector SectorInfo) (func(*Sec } func (m *Miner) preCommit(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { - params := &actors.SectorPreCommitInfo{ - CommD: sector.CommD, - CommR: sector.CommR, - Epoch: sector.Ticket.BlockHeight, + deals, err := m.secst.DealsForCommit(sector.SectorID, false) + if err != nil { + return nil, err + } + params := &actors.SectorPreCommitInfo{ SectorNumber: sector.SectorID, + + CommR: sector.CommR, + SealEpoch: sector.Ticket.BlockHeight, + DealIDs: deals, } enc, aerr := actors.SerializeParams(params) if aerr != nil { From 66f8e348a21f24977b932401cf3aefbc0cfd6a4f Mon Sep 17 00:00:00 2001 From: wanghui Date: Thu, 7 Nov 2019 20:05:03 +0800 Subject: [PATCH 073/114] update size and unit --- cmd/lotus-storage-miner/info.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 05946f807..3ce7c0ff9 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -38,11 +38,13 @@ var infoCmd = &cli.Command{ fmt.Printf("Miner: %s\n", maddr) // Sector size - size, err := api.StateMinerSectorSize(ctx, maddr, nil) + sizeByte, err := api.StateMinerSectorSize(ctx, maddr, nil) if err != nil { return err } - fmt.Printf("Sector Size: %dKiB\n", size / 1024) + + size, unit := getSizeAndUnit(sizeByte) + fmt.Printf("Sector Size: %g %s\n", size, unit) pow, err := api.StateMinerPower(ctx, maddr, nil) if err != nil { @@ -69,6 +71,18 @@ var infoCmd = &cli.Command{ }, } +var Units = []string{"B", "KiB", "MiB", "GiB"} + +func getSizeAndUnit(size uint64) (float64, string) { + i := 0 + unitSize := float64(size) + for unitSize >= 1024 && i < len(Units) - 1 { + unitSize = unitSize / 1024 + i++ + } + return unitSize, Units[i] +} + type SectorsInfo struct { TotalCount int SealingCount int From eca55019236b955beec94c28d665407ef49da0a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 13:06:32 +0100 Subject: [PATCH 074/114] remove some outdated todos --- api/api_full.go | 2 +- chain/actors/actor_storagemarket.go | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 27c07e65e..d46fd25ba 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -77,7 +77,7 @@ type FullNode interface { ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error) ClientListDeals(ctx context.Context) ([]DealInfo, error) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) - ClientFindData(ctx context.Context, root cid.Cid) ([]QueryOffer, error) // TODO: specify serialization mode we want (defaults to unixfs for now) + ClientFindData(ctx context.Context, root cid.Cid) ([]QueryOffer, error) ClientRetrieve(ctx context.Context, order RetrievalOrder, path string) error ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) diff --git a/chain/actors/actor_storagemarket.go b/chain/actors/actor_storagemarket.go index cc2e7a96e..4e00e970a 100644 --- a/chain/actors/actor_storagemarket.go +++ b/chain/actors/actor_storagemarket.go @@ -436,7 +436,6 @@ func (sma StorageMarketActor) ActivateStorageDeals(act *types.Actor, vmctx types deals, err := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.Deals) if err != nil { - // TODO: kind of annoying that this can be caused by gas, otherwise could be fatal return nil, aerrors.HandleExternalError(err, "loading deals amt") } @@ -502,7 +501,6 @@ func (sma StorageMarketActor) ProcessStorageDealsPayment(act *types.Actor, vmctx deals, err := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.Deals) if err != nil { - // TODO: kind of annoying that this can be caused by gas, otherwise could be fatal return nil, aerrors.HandleExternalError(err, "loading deals amt") } @@ -602,7 +600,6 @@ func (sma StorageMarketActor) ComputeDataCommitment(act *types.Actor, vmctx type deals, err := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.Deals) if err != nil { - // TODO: kind of annoying that this can be caused by gas, otherwise could be fatal return nil, aerrors.HandleExternalError(err, "loading deals amt") } From 79c9fb719e0b4c893960d01314b6408becdb7279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 13:57:00 +0100 Subject: [PATCH 075/114] deals: disconnect early, rely on chain --- chain/deals/cbor_gen.go | 40 ++-------------------------------- chain/deals/client_states.go | 33 ++++------------------------ chain/deals/client_utils.go | 11 ++++++++++ chain/deals/provider_states.go | 26 ++++++---------------- chain/deals/provider_utils.go | 11 ++++++++++ chain/deals/types.go | 3 --- 6 files changed, 35 insertions(+), 89 deletions(-) diff --git a/chain/deals/cbor_gen.go b/chain/deals/cbor_gen.go index 585836a89..9bdf7163a 100644 --- a/chain/deals/cbor_gen.go +++ b/chain/deals/cbor_gen.go @@ -192,7 +192,7 @@ func (t *Response) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{134}); err != nil { + if _, err := w.Write([]byte{133}); err != nil { return err } @@ -232,18 +232,6 @@ func (t *Response) MarshalCBOR(w io.Writer) error { } } - // t.t.CommitMessage (cid.Cid) (struct) - - if t.CommitMessage == nil { - if _, err := w.Write(cbg.CborNull); err != nil { - return err - } - } else { - if err := cbg.WriteCid(w, *t.CommitMessage); err != nil { - return xerrors.Errorf("failed to write cid field t.CommitMessage: %w", err) - } - } - return nil } @@ -258,7 +246,7 @@ func (t *Response) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 6 { + if extra != 5 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -338,30 +326,6 @@ func (t *Response) UnmarshalCBOR(r io.Reader) error { t.PublishMessage = &c } - } - // t.t.CommitMessage (cid.Cid) (struct) - - { - - pb, err := br.PeekByte() - if err != nil { - return err - } - if pb == cbg.CborNull[0] { - var nbuf [1]byte - if _, err := br.Read(nbuf[:]); err != nil { - return err - } - } else { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.CommitMessage: %w", err) - } - - t.CommitMessage = &c - } - } return nil } diff --git a/chain/deals/client_states.go b/chain/deals/client_states.go index e1157ad1d..a4e87d862 100644 --- a/chain/deals/client_states.go +++ b/chain/deals/client_states.go @@ -41,6 +41,9 @@ func (c *Client) new(ctx context.Context, deal ClientDeal) error { if err != nil { return err } + if err := c.disconnect(deal); err != nil { + return err + } if resp.State != api.DealAccepted { return xerrors.Errorf("deal wasn't accepted (State=%d)", resp.State) @@ -102,40 +105,12 @@ func (c *Client) accepted(ctx context.Context, deal ClientDeal) error { } func (c *Client) staged(ctx context.Context, deal ClientDeal) error { - /* miner seals our data, hopefully */ - - resp, err := c.readStorageDealResp(deal) - if err != nil { - return err - } - - if resp.State != api.DealSealing { - return xerrors.Errorf("deal wasn't sealed (State=%d)", resp.State) - } - - log.Info("DEAL SEALED!") - - // TODO: want? - /*ssize, err := stmgr.GetMinerSectorSize(ctx, c.sm, nil, deal.Proposal.MinerAddress) - if err != nil { - return xerrors.Errorf("failed to get miner sector size: %w", err) - } - - ok, err := sectorbuilder.VerifyPieceInclusionProof(ssize, deal.Proposal.Size, deal.Proposal.CommP, resp.CommD, resp.PieceInclusionProof.ProofElements) - if err != nil { - return xerrors.Errorf("verifying piece inclusion proof in staged deal %s: %w", deal.ProposalCid, err) - } - if !ok { - return xerrors.Errorf("verifying piece inclusion proof in staged deal %s failed", deal.ProposalCid) - }*/ + // wait return nil } func (c *Client) sealing(ctx context.Context, deal ClientDeal) error { - - // TODO: disconnect - checkFunc := func(ts *types.TipSet) (done bool, more bool, err error) { sd, err := stmgr.GetStorageDeal(ctx, c.sm, deal.DealID, ts) if err != nil { diff --git a/chain/deals/client_utils.go b/chain/deals/client_utils.go index 7cdd77192..7f77dbe0a 100644 --- a/chain/deals/client_utils.go +++ b/chain/deals/client_utils.go @@ -85,3 +85,14 @@ func (c *Client) readStorageDealResp(deal ClientDeal) (*Response, error) { return &resp.Response, nil } + +func (c *Client) disconnect(deal ClientDeal) error { + s, ok := c.conns[deal.ProposalCid] + if !ok { + return nil + } + + err := s.Close() + delete(c.conns, deal.ProposalCid) + return err +} diff --git a/chain/deals/provider_states.go b/chain/deals/provider_states.go index a177bb1f1..468d45f4a 100644 --- a/chain/deals/provider_states.go +++ b/chain/deals/provider_states.go @@ -171,15 +171,20 @@ func (p *Provider) accept(ctx context.Context, deal MinerDeal) (func(*MinerDeal) log.Info("fetching data for a deal") mcid := smsg.Cid() err = p.sendSignedResponse(&Response{ - State: api.DealAccepted, - Message: "", + State: api.DealAccepted, + Proposal: deal.ProposalCid, PublishMessage: &mcid, + StorageDeal: &storageDeal, }) if err != nil { return nil, err } + if err := p.disconnect(deal); err != nil { + log.Warnf("closing client connection: %+v", err) + } + return func(deal *MinerDeal) { deal.DealID = resp.DealIDs[0] }, merkledag.FetchGraph(ctx, deal.Ref, p.dag) @@ -188,14 +193,6 @@ func (p *Provider) accept(ctx context.Context, deal MinerDeal) (func(*MinerDeal) // STAGED func (p *Provider) staged(ctx context.Context, deal MinerDeal) (func(*MinerDeal), error) { - err := p.sendSignedResponse(&Response{ - State: api.DealStaged, - Proposal: deal.ProposalCid, - }) - if err != nil { - log.Warnf("Sending deal response failed: %s", err) - } - root, err := p.dag.Get(ctx, deal.Ref) if err != nil { return nil, xerrors.Errorf("failed to get file root for deal: %s", err) @@ -238,15 +235,6 @@ func (p *Provider) staged(ctx context.Context, deal MinerDeal) (func(*MinerDeal) // SEALING func (p *Provider) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal), error) { - err := p.sendSignedResponse(&Response{ - State: api.DealSealing, - Proposal: deal.ProposalCid, - // TODO: Send sector ID - }) - if err != nil { - log.Warnf("Sending deal response failed: %s", err) - } - log.Info("About to seal sector!", deal.ProposalCid, deal.SectorID) if err := p.sminer.SealSector(ctx, deal.SectorID); err != nil { return nil, xerrors.Errorf("sealing sector failed: %w", err) diff --git a/chain/deals/provider_utils.go b/chain/deals/provider_utils.go index 2ea5dc05e..0a881d111 100644 --- a/chain/deals/provider_utils.go +++ b/chain/deals/provider_utils.go @@ -100,6 +100,17 @@ func (p *Provider) sendSignedResponse(resp *Response) error { return err } +func (p *Provider) disconnect(deal MinerDeal) error { + s, ok := p.conns[deal.ProposalCid] + if !ok { + return nil + } + + err := s.Close() + delete(p.conns, deal.ProposalCid) + return err +} + func (p *Provider) getWorker(miner address.Address) (address.Address, error) { getworker := &types.Message{ To: miner, diff --git a/chain/deals/types.go b/chain/deals/types.go index 2177517ab..4318aad39 100644 --- a/chain/deals/types.go +++ b/chain/deals/types.go @@ -27,9 +27,6 @@ type Response struct { // DealAccepted StorageDeal *actors.StorageDeal PublishMessage *cid.Cid - - // DealComplete - CommitMessage *cid.Cid } // TODO: Do we actually need this to be signed? From 8ec37e87283be0d737688ec638401a6423c860ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 14:29:43 +0100 Subject: [PATCH 076/114] deals: cleanup client state machine --- chain/deals/cbor_gen.go | 41 +++++++++++++- chain/deals/client.go | 6 +++ chain/deals/client_states.go | 101 +++++++++++++++++++++-------------- lib/cborrpc/rpc.go | 12 +++++ 4 files changed, 117 insertions(+), 43 deletions(-) diff --git a/chain/deals/cbor_gen.go b/chain/deals/cbor_gen.go index 9bdf7163a..c3be140ac 100644 --- a/chain/deals/cbor_gen.go +++ b/chain/deals/cbor_gen.go @@ -541,7 +541,7 @@ func (t *ClientDeal) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{133}); err != nil { + if _, err := w.Write([]byte{134}); err != nil { return err } @@ -573,6 +573,19 @@ func (t *ClientDeal) MarshalCBOR(w io.Writer) error { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.DealID))); err != nil { return err } + + // t.t.PublishMessage (cid.Cid) (struct) + + if t.PublishMessage == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.PublishMessage); err != nil { + return xerrors.Errorf("failed to write cid field t.PublishMessage: %w", err) + } + } + return nil } @@ -587,7 +600,7 @@ func (t *ClientDeal) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 5 { + if extra != 6 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -642,6 +655,30 @@ func (t *ClientDeal) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("wrong type for uint64 field") } t.DealID = uint64(extra) + // t.t.PublishMessage (cid.Cid) (struct) + + { + + pb, err := br.PeekByte() + if err != nil { + return err + } + if pb == cbg.CborNull[0] { + var nbuf [1]byte + if _, err := br.Read(nbuf[:]); err != nil { + return err + } + } else { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.PublishMessage: %w", err) + } + + t.PublishMessage = &c + } + + } return nil } diff --git a/chain/deals/client.go b/chain/deals/client.go index ddc0efb8b..a07c90827 100644 --- a/chain/deals/client.go +++ b/chain/deals/client.go @@ -37,6 +37,8 @@ type ClientDeal struct { Miner peer.ID DealID uint64 + PublishMessage *cid.Cid + s inet.Stream } @@ -64,6 +66,7 @@ type clientDealUpdate struct { newState api.DealState id cid.Cid err error + mut func(*ClientDeal) } func NewClient(sm *stmgr.StateManager, chain *store.ChainStore, h host.Host, w *wallet.Wallet, ds dtypes.MetadataDS, dag dtypes.ClientDAG, discovery *discovery.Local, mpool full.MpoolAPI, chainapi full.ChainAPI) *Client { @@ -137,6 +140,9 @@ func (c *Client) onUpdated(ctx context.Context, update clientDealUpdate) { var deal ClientDeal err := c.deals.Mutate(update.id, func(d *ClientDeal) error { d.State = update.newState + if update.mut != nil { + update.mut(d) + } deal = *d return nil }) diff --git a/chain/deals/client_states.go b/chain/deals/client_states.go index a4e87d862..d7264a700 100644 --- a/chain/deals/client_states.go +++ b/chain/deals/client_states.go @@ -1,8 +1,10 @@ package deals import ( + "bytes" "context" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/lib/cborrpc" "golang.org/x/xerrors" @@ -12,11 +14,11 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -type clientHandlerFunc func(ctx context.Context, deal ClientDeal) error +type clientHandlerFunc func(ctx context.Context, deal ClientDeal) (func(*ClientDeal), error) func (c *Client) handle(ctx context.Context, deal ClientDeal, cb clientHandlerFunc, next api.DealState) { go func() { - err := cb(ctx, deal) + mut, err := cb(ctx, deal) if err != nil { next = api.DealError } @@ -30,87 +32,104 @@ func (c *Client) handle(ctx context.Context, deal ClientDeal, cb clientHandlerFu newState: next, id: deal.ProposalCid, err: err, + mut: mut, }: case <-c.stop: } }() } -func (c *Client) new(ctx context.Context, deal ClientDeal) error { +func (c *Client) new(ctx context.Context, deal ClientDeal) (func(*ClientDeal), error) { resp, err := c.readStorageDealResp(deal) if err != nil { - return err + return nil, err } if err := c.disconnect(deal); err != nil { - return err + return nil, err } + /* data transfer happens */ if resp.State != api.DealAccepted { - return xerrors.Errorf("deal wasn't accepted (State=%d)", resp.State) + return nil, xerrors.Errorf("deal wasn't accepted (State=%d)", resp.State) } - // TODO: spec says it's optional - pubmsg, err := c.chain.GetMessage(*resp.PublishMessage) + return func(info *ClientDeal) { + info.PublishMessage = resp.PublishMessage + }, nil +} + +func (c *Client) accepted(ctx context.Context, deal ClientDeal) (func(*ClientDeal), error) { + log.Infow("DEAL ACCEPTED!") + + pubmsg, err := c.chain.GetMessage(*deal.PublishMessage) if err != nil { - return xerrors.Errorf("getting deal pubsish message: %w", err) + return nil, xerrors.Errorf("getting deal pubsish message: %w", err) } pw, err := stmgr.GetMinerWorker(ctx, c.sm, nil, deal.Proposal.Provider) if err != nil { - return xerrors.Errorf("getting miner worker failed: %w", err) + return nil, xerrors.Errorf("getting miner worker failed: %w", err) } if pubmsg.From != pw { - return xerrors.Errorf("deal wasn't published by storage provider: from=%s, provider=%s", pubmsg.From, deal.Proposal.Provider) + return nil, xerrors.Errorf("deal wasn't published by storage provider: from=%s, provider=%s", pubmsg.From, deal.Proposal.Provider) } if pubmsg.To != actors.StorageMarketAddress { - return xerrors.Errorf("deal publish message wasn't set to StorageMarket actor (to=%s)", pubmsg.To) + return nil, xerrors.Errorf("deal publish message wasn't set to StorageMarket actor (to=%s)", pubmsg.To) } if pubmsg.Method != actors.SMAMethods.PublishStorageDeals { - return xerrors.Errorf("deal publish message called incorrect method (method=%s)", pubmsg.Method) + return nil, xerrors.Errorf("deal publish message called incorrect method (method=%s)", pubmsg.Method) + } + + var params actors.PublishStorageDealsParams + if err := params.UnmarshalCBOR(bytes.NewReader(pubmsg.Params)); err != nil { + return nil, err + } + + dealIdx := -1 + for i, storageDeal := range params.Deals { + // TODO: make it less hacky + eq, err := cborrpc.Equals(&deal.Proposal, &storageDeal.Proposal) + if err != nil { + return nil, err + } + if eq { + dealIdx = i + } + } + + if dealIdx == -1 { + return nil, xerrors.Errorf("deal publish didn't contain our deal (message cid: %s)", deal.PublishMessage) } // TODO: timeout - _, ret, err := c.sm.WaitForMessage(ctx, *resp.PublishMessage) + _, ret, err := c.sm.WaitForMessage(ctx, *deal.PublishMessage) if err != nil { - return xerrors.Errorf("waiting for deal publish message: %w", err) + return nil, xerrors.Errorf("waiting for deal publish message: %w", err) } if ret.ExitCode != 0 { - return xerrors.Errorf("deal publish failed: exit=%d", ret.ExitCode) - } - // TODO: persist dealId - - log.Info("DEAL ACCEPTED!") - - return nil -} - -func (c *Client) accepted(ctx context.Context, deal ClientDeal) error { - /* data transfer happens */ - - resp, err := c.readStorageDealResp(deal) - if err != nil { - return err + return nil, xerrors.Errorf("deal publish failed: exit=%d", ret.ExitCode) } - if resp.State != api.DealStaged { - return xerrors.Errorf("deal wasn't staged (State=%d)", resp.State) + var res actors.PublishStorageDealResponse + if err := res.UnmarshalCBOR(bytes.NewReader(ret.Return)); err != nil { + return nil, err } - log.Info("DEAL STAGED!") - - return nil + return func(info *ClientDeal) { + info.DealID = res.DealIDs[dealIdx] + }, nil } -func (c *Client) staged(ctx context.Context, deal ClientDeal) error { - // wait +func (c *Client) staged(ctx context.Context, deal ClientDeal) (func(*ClientDeal), error) { + // TODO: Maybe wait for pre-commit - return nil + return nil, nil } -func (c *Client) sealing(ctx context.Context, deal ClientDeal) error { +func (c *Client) sealing(ctx context.Context, deal ClientDeal) (func(*ClientDeal), error) { checkFunc := func(ts *types.TipSet) (done bool, more bool, err error) { sd, err := stmgr.GetStorageDeal(ctx, c.sm, deal.DealID, ts) if err != nil { @@ -172,9 +191,9 @@ func (c *Client) sealing(ctx context.Context, deal ClientDeal) error { } if err := c.events.Called(checkFunc, called, revert, 3, build.SealRandomnessLookbackLimit, deal.Proposal.Provider, actors.MAMethods.ProveCommitSector); err != nil { - return xerrors.Errorf("failed to set up called handler") + return nil, xerrors.Errorf("failed to set up called handler") } log.Info("DEAL COMPLETE!!") - return nil + return nil, nil } diff --git a/lib/cborrpc/rpc.go b/lib/cborrpc/rpc.go index 901108457..aee6c5b19 100644 --- a/lib/cborrpc/rpc.go +++ b/lib/cborrpc/rpc.go @@ -66,3 +66,15 @@ func AsIpld(obj interface{}) (ipld.Node, error) { } return cbor.WrapObject(obj, math.MaxUint64, -1) } + +func Equals(a cbg.CBORMarshaler, b cbg.CBORMarshaler) (bool, error) { + ab, err := Dump(a) + if err != nil { + return false, err + } + bb, err := Dump(b) + if err != nil { + return false, err + } + return bytes.Equal(ab, bb), nil +} From 2588a6a7eb49f1dcd200f7957ff643cf4818fe8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 14:41:41 +0100 Subject: [PATCH 077/114] deals: check msg params in ProveCommitSector event handler --- chain/deals/client_states.go | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/chain/deals/client_states.go b/chain/deals/client_states.go index d7264a700..7ffd3e0ca 100644 --- a/chain/deals/client_states.go +++ b/chain/deals/client_states.go @@ -152,15 +152,41 @@ func (c *Client) sealing(ctx context.Context, deal ClientDeal) (func(*ClientDeal return false, true, nil } - called := func(msg *types.Message, ts *types.TipSet, curH uint64) (bool, error) { - // TODO: handle errors + called := func(msg *types.Message, ts *types.TipSet, curH uint64) (more bool, err error) { + defer func() { + if err != nil { + select { + case c.updated <- clientDealUpdate{ + newState: api.DealComplete, + id: deal.ProposalCid, + err: xerrors.Errorf("handling applied event: %w", err), + }: + case <-c.stop: + } + } + }() if msg == nil { log.Error("timed out waiting for deal activation... what now?") return false, nil } - // TODO: can check msg.Params to see if we should even bother checking the state + var params actors.SectorProveCommitInfo + if err := params.UnmarshalCBOR(bytes.NewReader(msg.Params)); err != nil { + return false, err + } + + var found bool + for _, dealID := range params.DealIDs { + if dealID == deal.DealID { + found = true + break + } + } + + if !found { + return true, nil + } sd, err := stmgr.GetStorageDeal(ctx, c.sm, deal.DealID, ts) if err != nil { @@ -171,7 +197,7 @@ func (c *Client) sealing(ctx context.Context, deal ClientDeal) (func(*ClientDeal return true, nil } - log.Info("Storage deal %d activated at epoch %d", deal.DealID, sd.ActivationEpoch) + log.Infof("Storage deal %d activated at epoch %d", deal.DealID, sd.ActivationEpoch) select { case c.updated <- clientDealUpdate{ From 58472afa3af1f603e3d6d981a526e67433895582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 15:09:11 +0100 Subject: [PATCH 078/114] deals: Verify network message signatures --- chain/deals/cbor_gen.go | 36 ++++++++++++++++++++++++++++++---- chain/deals/client.go | 3 +++ chain/deals/client_states.go | 1 - chain/deals/client_utils.go | 4 +++- chain/deals/provider_states.go | 24 +---------------------- chain/deals/provider_utils.go | 3 --- chain/deals/types.go | 10 ++++++++++ node/impl/client/client.go | 20 +++++-------------- 8 files changed, 54 insertions(+), 47 deletions(-) diff --git a/chain/deals/cbor_gen.go b/chain/deals/cbor_gen.go index c3be140ac..f5bb90d1a 100644 --- a/chain/deals/cbor_gen.go +++ b/chain/deals/cbor_gen.go @@ -404,7 +404,7 @@ func (t *ClientDealProposal) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{135}); err != nil { + if _, err := w.Write([]byte{136}); err != nil { return err } @@ -439,6 +439,11 @@ func (t *ClientDealProposal) MarshalCBOR(w io.Writer) error { return err } + // t.t.MinerWorker (address.Address) (struct) + if err := t.MinerWorker.MarshalCBOR(w); err != nil { + return err + } + // t.t.MinerID (peer.ID) (string) if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.MinerID)))); err != nil { return err @@ -460,7 +465,7 @@ func (t *ClientDealProposal) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 7 { + if extra != 8 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -522,6 +527,15 @@ func (t *ClientDealProposal) UnmarshalCBOR(r io.Reader) error { return err } + } + // t.t.MinerWorker (address.Address) (struct) + + { + + if err := t.MinerWorker.UnmarshalCBOR(br); err != nil { + return err + } + } // t.t.MinerID (peer.ID) (string) @@ -541,7 +555,7 @@ func (t *ClientDeal) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{134}); err != nil { + if _, err := w.Write([]byte{135}); err != nil { return err } @@ -569,6 +583,11 @@ func (t *ClientDeal) MarshalCBOR(w io.Writer) error { return err } + // t.t.MinerWorker (address.Address) (struct) + if err := t.MinerWorker.MarshalCBOR(w); err != nil { + return err + } + // t.t.DealID (uint64) (uint64) if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.DealID))); err != nil { return err @@ -600,7 +619,7 @@ func (t *ClientDeal) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 6 { + if extra != 7 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -645,6 +664,15 @@ func (t *ClientDeal) UnmarshalCBOR(r io.Reader) error { t.Miner = peer.ID(sval) } + // t.t.MinerWorker (address.Address) (struct) + + { + + if err := t.MinerWorker.UnmarshalCBOR(br); err != nil { + return err + } + + } // t.t.DealID (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) diff --git a/chain/deals/client.go b/chain/deals/client.go index a07c90827..9039737a0 100644 --- a/chain/deals/client.go +++ b/chain/deals/client.go @@ -35,6 +35,7 @@ type ClientDeal struct { Proposal actors.StorageDealProposal State api.DealState Miner peer.ID + MinerWorker address.Address DealID uint64 PublishMessage *cid.Cid @@ -178,6 +179,7 @@ type ClientDealProposal struct { ProviderAddress address.Address Client address.Address + MinerWorker address.Address MinerID peer.ID } @@ -256,6 +258,7 @@ func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, erro Proposal: *dealProposal, State: api.DealUnknown, Miner: p.MinerID, + MinerWorker: p.MinerWorker, s: s, } diff --git a/chain/deals/client_states.go b/chain/deals/client_states.go index 7ffd3e0ca..0dce44e3a 100644 --- a/chain/deals/client_states.go +++ b/chain/deals/client_states.go @@ -220,6 +220,5 @@ func (c *Client) sealing(ctx context.Context, deal ClientDeal) (func(*ClientDeal return nil, xerrors.Errorf("failed to set up called handler") } - log.Info("DEAL COMPLETE!!") return nil, nil } diff --git a/chain/deals/client_utils.go b/chain/deals/client_utils.go index 7f77dbe0a..d490d401b 100644 --- a/chain/deals/client_utils.go +++ b/chain/deals/client_utils.go @@ -77,7 +77,9 @@ func (c *Client) readStorageDealResp(deal ClientDeal) (*Response, error) { return nil, err } - // TODO: verify signature + if err := resp.Verify(deal.MinerWorker); err != nil { + return nil, xerrors.Errorf("verifying response signature failed", err) + } if resp.Response.Proposal != deal.ProposalCid { return nil, xerrors.Errorf("miner responded to a wrong proposal: %s != %s", resp.Response.Proposal, deal.ProposalCid) diff --git a/chain/deals/provider_states.go b/chain/deals/provider_states.go index 468d45f4a..7d94d93e2 100644 --- a/chain/deals/provider_states.go +++ b/chain/deals/provider_states.go @@ -85,7 +85,6 @@ func (p *Provider) accept(ctx context.Context, deal MinerDeal) (func(*MinerDeal) // TODO: check StorageCollateral - // TODO: minPrice := types.BigDiv(types.BigMul(p.ask.Ask.Price, types.NewInt(deal.Proposal.PieceSize)), types.NewInt(1<<30)) if deal.Proposal.StoragePricePerEpoch.LessThan(minPrice) { return nil, xerrors.Errorf("storage price per epoch less than asking price: %s < %s", deal.Proposal.StoragePricePerEpoch, minPrice) @@ -239,33 +238,12 @@ func (p *Provider) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal if err := p.sminer.SealSector(ctx, deal.SectorID); err != nil { return nil, xerrors.Errorf("sealing sector failed: %w", err) } - // TODO: Let's not care after this point, for now at least, client can watch the chain - - /*_, err = p.waitSealed(ctx, deal) - if err != nil { - return nil, err - }*/ return nil, nil } func (p *Provider) complete(ctx context.Context, deal MinerDeal) (func(*MinerDeal), error) { - /*mcid, err := p.commt.WaitCommit(ctx, deal.Proposal.Provider, deal.SectorID) - if err != nil { - log.Warnf("Waiting for sector commitment message: %s", err) - }*/ - - //panic("fixme") - - /*err = p.sendSignedResponse(&Response{ - State: api.DealComplete, - Proposal: deal.ProposalCid, - - CommitMessage: &mcid, - }) - if err != nil { - log.Warnf("Sending deal response failed: %s", err) - }*/ + // TODO: observe sector lifecycle, status, expiration.. return nil, nil } diff --git a/chain/deals/provider_utils.go b/chain/deals/provider_utils.go index 0a881d111..aaf8e2c49 100644 --- a/chain/deals/provider_utils.go +++ b/chain/deals/provider_utils.go @@ -54,9 +54,6 @@ func (p *Provider) readProposal(s inet.Stream) (proposal Proposal, err error) { return proposal, xerrors.Errorf("verifying StorageDealProposal: %w", err) } - // TODO: Validate proposal maybe - // (and signature, obviously) - if proposal.DealProposal.Provider != p.actor { log.Errorf("proposal with wrong ProviderAddress: %s", proposal.DealProposal.Provider) return proposal, err diff --git a/chain/deals/types.go b/chain/deals/types.go index 4318aad39..98b666f5c 100644 --- a/chain/deals/types.go +++ b/chain/deals/types.go @@ -5,6 +5,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/cborrpc" "github.com/ipfs/go-cid" ) @@ -36,6 +37,15 @@ type SignedResponse struct { Signature *types.Signature } +func (r *SignedResponse) Verify(addr address.Address) error { + b, err := cborrpc.Dump(&r.Response) + if err != nil { + return err + } + + return r.Signature.Verify(addr, b) +} + type AskRequest struct { Miner address.Address } diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 8856452f1..8f31df6cd 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -24,7 +24,6 @@ import ( "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/deals" "github.com/filecoin-project/lotus/chain/store" @@ -61,24 +60,14 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.A return nil, xerrors.Errorf("failed to get default address: %w", err) } - // get miner peerID - msg := &types.Message{ - To: miner, - From: miner, - Method: actors.MAMethods.GetPeerID, - } - - r, err := a.StateCall(ctx, msg, nil) + pid, err := a.StateMinerPeerID(ctx, miner, nil) if err != nil { return nil, xerrors.Errorf("failed getting peer ID: %w", err) } - if r.ExitCode != 0 { - return nil, xerrors.Errorf("call to get peer ID for miner failed: exit code %d", r.ExitCode) - } - pid, err := peer.IDFromBytes(r.Return) + mw, err := a.StateMinerWorker(ctx, miner, nil) if err != nil { - return nil, xerrors.Errorf("parsing peer ID wrong: %w", err) + return nil, xerrors.Errorf("failed getting miner worker: %w", err) } proposal := deals.ClientDealProposal{ @@ -86,8 +75,9 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.A PricePerEpoch: epochPrice, ProposalExpiration: math.MaxUint64, // TODO: set something reasonable Duration: blocksDuration, - ProviderAddress: miner, Client: self, + ProviderAddress: miner, + MinerWorker: mw, MinerID: pid, } From 3fbe0abb75db37c099895023884d4e8f9d399b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 15:11:39 +0100 Subject: [PATCH 079/114] cborrpc -> cborutil --- chain/blocksync.go | 10 +++++----- chain/deals/client.go | 10 +++++----- chain/deals/client_states.go | 4 ++-- chain/deals/client_utils.go | 4 ++-- chain/deals/provider.go | 4 ++-- chain/deals/provider_asks.go | 14 +++++++------- chain/deals/provider_utils.go | 8 ++++---- chain/deals/types.go | 4 ++-- chain/types/voucher.go | 2 +- lib/{cborrpc => cborutil}/rpc.go | 2 +- lib/statestore/store.go | 10 +++++----- lib/statestore/store_test.go | 4 ++-- node/hello/hello.go | 6 +++--- paych/store.go | 2 +- retrieval/client.go | 10 +++++----- retrieval/miner.go | 14 +++++++------- storage/sector/store.go | 12 ++++++------ storage/sectorblocks/blocks.go | 10 +++++----- 18 files changed, 65 insertions(+), 65 deletions(-) rename lib/{cborrpc => cborutil}/rpc.go (98%) diff --git a/chain/blocksync.go b/chain/blocksync.go index 8a9e629eb..71140f2e0 100644 --- a/chain/blocksync.go +++ b/chain/blocksync.go @@ -15,7 +15,7 @@ import ( "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" "github.com/filecoin-project/lotus/node/modules/dtypes" blocks "github.com/ipfs/go-block-format" @@ -93,7 +93,7 @@ func (bss *BlockSyncService) HandleStream(s inet.Stream) { defer s.Close() var req BlockSyncRequest - if err := cborrpc.ReadCborRPC(bufio.NewReader(s), &req); err != nil { + if err := cborutil.ReadCborRPC(bufio.NewReader(s), &req); err != nil { log.Errorf("failed to read block sync request: %s", err) return } @@ -105,7 +105,7 @@ func (bss *BlockSyncService) HandleStream(s inet.Stream) { return } - if err := cborrpc.WriteCborRPC(s, resp); err != nil { + if err := cborutil.WriteCborRPC(s, resp); err != nil { log.Error("failed to write back response for handle stream: ", err) return } @@ -401,12 +401,12 @@ func (bs *BlockSync) sendRequestToPeer(ctx context.Context, p peer.ID, req *Bloc return nil, err } - if err := cborrpc.WriteCborRPC(s, req); err != nil { + if err := cborutil.WriteCborRPC(s, req); err != nil { return nil, err } var res BlockSyncResponse - if err := cborrpc.ReadCborRPC(bufio.NewReader(s), &res); err != nil { + if err := cborutil.ReadCborRPC(bufio.NewReader(s), &res); err != nil { return nil, err } diff --git a/chain/deals/client.go b/chain/deals/client.go index 9039737a0..f1101b1e3 100644 --- a/chain/deals/client.go +++ b/chain/deals/client.go @@ -23,7 +23,7 @@ import ( "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/retrieval/discovery" ) @@ -233,7 +233,7 @@ func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, erro return cid.Undef, xerrors.Errorf("signing deal proposal failed: %w", err) } - proposalNd, err := cborrpc.AsIpld(dealProposal) + proposalNd, err := cborutil.AsIpld(dealProposal) if err != nil { return cid.Undef, xerrors.Errorf("getting proposal node failed: %w", err) } @@ -248,7 +248,7 @@ func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, erro Piece: p.Data, } - if err := cborrpc.WriteCborRPC(s, proposal); err != nil { + if err := cborutil.WriteCborRPC(s, proposal); err != nil { s.Reset() return cid.Undef, xerrors.Errorf("sending proposal to storage provider failed: %w", err) } @@ -280,12 +280,12 @@ func (c *Client) QueryAsk(ctx context.Context, p peer.ID, a address.Address) (*t req := &AskRequest{ Miner: a, } - if err := cborrpc.WriteCborRPC(s, req); err != nil { + if err := cborutil.WriteCborRPC(s, req); err != nil { return nil, xerrors.Errorf("failed to send ask request: %w", err) } var out AskResponse - if err := cborrpc.ReadCborRPC(s, &out); err != nil { + if err := cborutil.ReadCborRPC(s, &out); err != nil { return nil, xerrors.Errorf("failed to read ask response: %w", err) } diff --git a/chain/deals/client_states.go b/chain/deals/client_states.go index 0dce44e3a..5b4b7c78c 100644 --- a/chain/deals/client_states.go +++ b/chain/deals/client_states.go @@ -4,7 +4,7 @@ import ( "bytes" "context" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" "golang.org/x/xerrors" @@ -91,7 +91,7 @@ func (c *Client) accepted(ctx context.Context, deal ClientDeal) (func(*ClientDea dealIdx := -1 for i, storageDeal := range params.Deals { // TODO: make it less hacky - eq, err := cborrpc.Equals(&deal.Proposal, &storageDeal.Proposal) + eq, err := cborutil.Equals(&deal.Proposal, &storageDeal.Proposal) if err != nil { return nil, err } diff --git a/chain/deals/client_utils.go b/chain/deals/client_utils.go index d490d401b..e4c11eb58 100644 --- a/chain/deals/client_utils.go +++ b/chain/deals/client_utils.go @@ -9,7 +9,7 @@ import ( unixfile "github.com/ipfs/go-unixfs/file" "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" "github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/lib/sectorbuilder" ) @@ -72,7 +72,7 @@ func (c *Client) readStorageDealResp(deal ClientDeal) (*Response, error) { } var resp SignedResponse - if err := cborrpc.ReadCborRPC(s, &resp); err != nil { + if err := cborutil.ReadCborRPC(s, &resp); err != nil { log.Errorw("failed to read Response message", "error", err) return nil, err } diff --git a/chain/deals/provider.go b/chain/deals/provider.go index f54b32cf5..8430cf2f4 100644 --- a/chain/deals/provider.go +++ b/chain/deals/provider.go @@ -15,7 +15,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" "github.com/filecoin-project/lotus/lib/statestore" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/storage" @@ -193,7 +193,7 @@ func (p *Provider) onUpdated(ctx context.Context, update minerDealUpdate) { } func (p *Provider) newDeal(s inet.Stream, proposal Proposal) (MinerDeal, error) { - proposalNd, err := cborrpc.AsIpld(proposal.DealProposal) + proposalNd, err := cborutil.AsIpld(proposal.DealProposal) if err != nil { return MinerDeal{}, err } diff --git a/chain/deals/provider_asks.go b/chain/deals/provider_asks.go index 1b1960b97..1fc8e69ed 100644 --- a/chain/deals/provider_asks.go +++ b/chain/deals/provider_asks.go @@ -8,7 +8,7 @@ import ( "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" datastore "github.com/ipfs/go-datastore" inet "github.com/libp2p/go-libp2p-core/network" "golang.org/x/xerrors" @@ -54,14 +54,14 @@ func (p *Provider) getAsk(m address.Address) *types.SignedStorageAsk { func (p *Provider) HandleAskStream(s inet.Stream) { defer s.Close() var ar AskRequest - if err := cborrpc.ReadCborRPC(s, &ar); err != nil { + if err := cborutil.ReadCborRPC(s, &ar); err != nil { log.Errorf("failed to read AskRequest from incoming stream: %s", err) return } resp := p.processAskRequest(&ar) - if err := cborrpc.WriteCborRPC(s, resp); err != nil { + if err := cborutil.WriteCborRPC(s, resp); err != nil { log.Errorf("failed to write ask response: %s", err) return } @@ -98,7 +98,7 @@ func (p *Provider) loadAsk() error { } var ssa types.SignedStorageAsk - if err := cborrpc.ReadCborRPC(bytes.NewReader(askb), &ssa); err != nil { + if err := cborutil.ReadCborRPC(bytes.NewReader(askb), &ssa); err != nil { return err } @@ -107,7 +107,7 @@ func (p *Provider) loadAsk() error { } func (p *Provider) signAsk(a *types.StorageAsk) (*types.SignedStorageAsk, error) { - b, err := cborrpc.Dump(a) + b, err := cborutil.Dump(a) if err != nil { return nil, err } @@ -129,7 +129,7 @@ func (p *Provider) signAsk(a *types.StorageAsk) (*types.SignedStorageAsk, error) } func (p *Provider) saveAsk(a *types.SignedStorageAsk) error { - b, err := cborrpc.Dump(a) + b, err := cborutil.Dump(a) if err != nil { return err } @@ -150,7 +150,7 @@ func (c *Client) checkAskSignature(ask *types.SignedStorageAsk) error { return xerrors.Errorf("failed to get worker for miner in ask", err) } - sigb, err := cborrpc.Dump(ask.Ask) + sigb, err := cborutil.Dump(ask.Ask) if err != nil { return xerrors.Errorf("failed to re-serialize ask") } diff --git a/chain/deals/provider_utils.go b/chain/deals/provider_utils.go index aaf8e2c49..e14502287 100644 --- a/chain/deals/provider_utils.go +++ b/chain/deals/provider_utils.go @@ -8,7 +8,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" "github.com/ipfs/go-cid" inet "github.com/libp2p/go-libp2p-core/network" @@ -45,7 +45,7 @@ func (p *Provider) failDeal(id cid.Cid, cerr error) { } func (p *Provider) readProposal(s inet.Stream) (proposal Proposal, err error) { - if err := cborrpc.ReadCborRPC(s, &proposal); err != nil { + if err := cborutil.ReadCborRPC(s, &proposal); err != nil { log.Errorw("failed to read proposal message", "error", err) return proposal, err } @@ -68,7 +68,7 @@ func (p *Provider) sendSignedResponse(resp *Response) error { return xerrors.New("couldn't send response: not connected") } - msg, err := cborrpc.Dump(resp) + msg, err := cborutil.Dump(resp) if err != nil { return xerrors.Errorf("serializing response: %w", err) } @@ -88,7 +88,7 @@ func (p *Provider) sendSignedResponse(resp *Response) error { Signature: sig, } - err = cborrpc.WriteCborRPC(s, signedResponse) + err = cborutil.WriteCborRPC(s, signedResponse) if err != nil { // Assume client disconnected s.Close() diff --git a/chain/deals/types.go b/chain/deals/types.go index 98b666f5c..63e2e45ec 100644 --- a/chain/deals/types.go +++ b/chain/deals/types.go @@ -5,7 +5,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" "github.com/ipfs/go-cid" ) @@ -38,7 +38,7 @@ type SignedResponse struct { } func (r *SignedResponse) Verify(addr address.Address) error { - b, err := cborrpc.Dump(&r.Response) + b, err := cborutil.Dump(&r.Response) if err != nil { return err } diff --git a/chain/types/voucher.go b/chain/types/voucher.go index 1cb68406c..1a510d07e 100644 --- a/chain/types/voucher.go +++ b/chain/types/voucher.go @@ -5,7 +5,7 @@ import ( "encoding/base64" "github.com/filecoin-project/lotus/chain/address" - cborrpc "github.com/filecoin-project/lotus/lib/cborrpc" + cborrpc "github.com/filecoin-project/lotus/lib/cborutil" cbor "github.com/ipfs/go-ipld-cbor" ) diff --git a/lib/cborrpc/rpc.go b/lib/cborutil/rpc.go similarity index 98% rename from lib/cborrpc/rpc.go rename to lib/cborutil/rpc.go index aee6c5b19..06af9a156 100644 --- a/lib/cborrpc/rpc.go +++ b/lib/cborutil/rpc.go @@ -1,4 +1,4 @@ -package cborrpc +package cborutil import ( "bytes" diff --git a/lib/statestore/store.go b/lib/statestore/store.go index 80df4a078..c32c3ff22 100644 --- a/lib/statestore/store.go +++ b/lib/statestore/store.go @@ -10,7 +10,7 @@ import ( cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" ) type StateStore struct { @@ -42,7 +42,7 @@ func (st *StateStore) Begin(i interface{}, state interface{}) error { return xerrors.Errorf("Already tracking state for %s", i) } - b, err := cborrpc.Dump(state) + b, err := cborutil.Dump(state) if err != nil { return err } @@ -68,7 +68,7 @@ func cborMutator(mutator interface{}) func([]byte) ([]byte, error) { return func(in []byte) ([]byte, error) { state := reflect.New(rmut.Type().In(0).Elem()) - err := cborrpc.ReadCborRPC(bytes.NewReader(in), state.Interface()) + err := cborutil.ReadCborRPC(bytes.NewReader(in), state.Interface()) if err != nil { return nil, err } @@ -79,7 +79,7 @@ func cborMutator(mutator interface{}) func([]byte) ([]byte, error) { return nil, err.(error) } - return cborrpc.Dump(state.Interface()) + return cborutil.Dump(state.Interface()) } } @@ -145,7 +145,7 @@ func (st *StateStore) List(out interface{}) error { } elem := reflect.New(outT) - err := cborrpc.ReadCborRPC(bytes.NewReader(res.Value), elem.Interface()) + err := cborutil.ReadCborRPC(bytes.NewReader(res.Value), elem.Interface()) if err != nil { return err } diff --git a/lib/statestore/store_test.go b/lib/statestore/store_test.go index 0d17ef20d..91724bbf8 100644 --- a/lib/statestore/store_test.go +++ b/lib/statestore/store_test.go @@ -6,13 +6,13 @@ import ( "github.com/ipfs/go-datastore" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" ) func TestList(t *testing.T) { ds := datastore.NewMapDatastore() - e, err := cborrpc.Dump(types.NewInt(7)) + e, err := cborutil.Dump(types.NewInt(7)) if err != nil { t.Fatal(err) } diff --git a/node/hello/hello.go b/node/hello/hello.go index ef37fae38..90af18923 100644 --- a/node/hello/hello.go +++ b/node/hello/hello.go @@ -16,7 +16,7 @@ import ( "github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" "github.com/filecoin-project/lotus/peermgr" ) @@ -66,7 +66,7 @@ func (hs *Service) HandleStream(s inet.Stream) { defer s.Close() var hmsg Message - if err := cborrpc.ReadCborRPC(s, &hmsg); err != nil { + if err := cborutil.ReadCborRPC(s, &hmsg); err != nil { log.Infow("failed to read hello message", "error", err) return } @@ -120,7 +120,7 @@ func (hs *Service) SayHello(ctx context.Context, pid peer.ID) error { fmt.Println("SENDING HELLO MESSAGE: ", hts.Cids(), hts.Height()) fmt.Println("hello message genesis: ", gen.Cid()) - if err := cborrpc.WriteCborRPC(s, hmsg); err != nil { + if err := cborutil.WriteCborRPC(s, hmsg); err != nil { return err } diff --git a/paych/store.go b/paych/store.go index 105b87103..f08969630 100644 --- a/paych/store.go +++ b/paych/store.go @@ -14,7 +14,7 @@ import ( "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" - cborrpc "github.com/filecoin-project/lotus/lib/cborrpc" + cborrpc "github.com/filecoin-project/lotus/lib/cborutil" "github.com/filecoin-project/lotus/node/modules/dtypes" ) diff --git a/retrieval/client.go b/retrieval/client.go index 23e7daa09..8936fbafb 100644 --- a/retrieval/client.go +++ b/retrieval/client.go @@ -17,7 +17,7 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" payapi "github.com/filecoin-project/lotus/node/impl/paych" "github.com/filecoin-project/lotus/paych" "github.com/filecoin-project/lotus/retrieval/discovery" @@ -44,7 +44,7 @@ func (c *Client) Query(ctx context.Context, p discovery.RetrievalPeer, data cid. } defer s.Close() - err = cborrpc.WriteCborRPC(s, &Query{ + err = cborutil.WriteCborRPC(s, &Query{ Piece: data, }) if err != nil { @@ -172,12 +172,12 @@ func (cst *clientStream) doOneExchange(ctx context.Context, toFetch uint64, out }, } - if err := cborrpc.WriteCborRPC(cst.stream, deal); err != nil { + if err := cborutil.WriteCborRPC(cst.stream, deal); err != nil { return err } var resp DealResponse - if err := cborrpc.ReadCborRPC(cst.peeker, &resp); err != nil { + if err := cborutil.ReadCborRPC(cst.peeker, &resp); err != nil { log.Error(err) return err } @@ -209,7 +209,7 @@ func (cst *clientStream) fetchBlocks(toFetch uint64, out io.Writer) error { log.Infof("block %d of %d", i+1, blocksToFetch) var block Block - if err := cborrpc.ReadCborRPC(cst.peeker, &block); err != nil { + if err := cborutil.ReadCborRPC(cst.peeker, &block); err != nil { return xerrors.Errorf("reading fetchBlock response: %w", err) } diff --git a/retrieval/miner.go b/retrieval/miner.go index 4a7bd967e..1792880de 100644 --- a/retrieval/miner.go +++ b/retrieval/miner.go @@ -15,7 +15,7 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" "github.com/filecoin-project/lotus/storage/sectorblocks" ) @@ -42,7 +42,7 @@ func NewMiner(sblks *sectorblocks.SectorBlocks, full api.FullNode) *Miner { func writeErr(stream network.Stream, err error) { log.Errorf("Retrieval deal error: %s", err) - _ = cborrpc.WriteCborRPC(stream, &DealResponse{ + _ = cborutil.WriteCborRPC(stream, &DealResponse{ Status: Error, Message: err.Error(), }) @@ -52,7 +52,7 @@ func (m *Miner) HandleQueryStream(stream network.Stream) { defer stream.Close() var query Query - if err := cborrpc.ReadCborRPC(stream, &query); err != nil { + if err := cborutil.ReadCborRPC(stream, &query); err != nil { writeErr(stream, err) return } @@ -74,7 +74,7 @@ func (m *Miner) HandleQueryStream(stream network.Stream) { answer.Size = uint64(size) // TODO: verify on intermediate } - if err := cborrpc.WriteCborRPC(stream, answer); err != nil { + if err := cborutil.WriteCborRPC(stream, answer); err != nil { log.Errorf("Retrieval query: WriteCborRPC: %s", err) return } @@ -114,7 +114,7 @@ func (m *Miner) HandleDealStream(stream network.Stream) { func (hnd *handlerDeal) handleNext() (bool, error) { var deal DealProposal - if err := cborrpc.ReadCborRPC(hnd.stream, &deal); err != nil { + if err := cborutil.ReadCborRPC(hnd.stream, &deal); err != nil { if err == io.EOF { // client sent all deals err = nil } @@ -203,7 +203,7 @@ func (hnd *handlerDeal) accept(deal DealProposal) error { resp := &DealResponse{ Status: Accepted, } - if err := cborrpc.WriteCborRPC(hnd.stream, resp); err != nil { + if err := cborutil.WriteCborRPC(hnd.stream, resp); err != nil { log.Errorf("Retrieval query: Write Accepted resp: %s", err) return err } @@ -231,7 +231,7 @@ func (hnd *handlerDeal) accept(deal DealProposal) error { Data: nd.RawData(), } - if err := cborrpc.WriteCborRPC(hnd.stream, block); err != nil { + if err := cborutil.WriteCborRPC(hnd.stream, block); err != nil { return err } diff --git a/storage/sector/store.go b/storage/sector/store.go index 7f1159090..47bd5af13 100644 --- a/storage/sector/store.go +++ b/storage/sector/store.go @@ -14,7 +14,7 @@ import ( "sync" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -71,7 +71,7 @@ func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64 var deals DealMapping switch err { case nil: - if err := cborrpc.ReadCborRPC(bytes.NewReader(e), &deals); err != nil { + if err := cborutil.ReadCborRPC(bytes.NewReader(e), &deals); err != nil { return 0, err } if deals.Committed { @@ -82,7 +82,7 @@ func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64 deals.DealIDs = append(deals.DealIDs, dealIDs...) deals.Allocated += size - d, err := cborrpc.Dump(&deals) + d, err := cborutil.Dump(&deals) if err != nil { return 0, err } @@ -106,7 +106,7 @@ func (s *Store) PieceSizesToFill(sectorID uint64) ([]uint64, error) { return nil, err } var info DealMapping - if err := cborrpc.ReadCborRPC(bytes.NewReader(e), &info); err != nil { + if err := cborutil.ReadCborRPC(bytes.NewReader(e), &info); err != nil { return nil, err } if info.Allocated > s.sb.SectorSize() { @@ -139,7 +139,7 @@ func (s *Store) DealsForCommit(sectorID uint64, commit bool) ([]uint64, error) { switch err { case nil: var deals DealMapping - if err := cborrpc.ReadCborRPC(bytes.NewReader(e), &deals); err != nil { + if err := cborutil.ReadCborRPC(bytes.NewReader(e), &deals); err != nil { return nil, err } if !commit { @@ -151,7 +151,7 @@ func (s *Store) DealsForCommit(sectorID uint64, commit bool) ([]uint64, error) { } deals.Committed = true - d, err := cborrpc.Dump(&deals) + d, err := cborutil.Dump(&deals) if err != nil { return nil, err } diff --git a/storage/sectorblocks/blocks.go b/storage/sectorblocks/blocks.go index 1d1289def..9f40742d3 100644 --- a/storage/sectorblocks/blocks.go +++ b/storage/sectorblocks/blocks.go @@ -19,7 +19,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/lib/cborrpc" + "github.com/filecoin-project/lotus/lib/cborutil" "github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/node/modules/dtypes" @@ -98,7 +98,7 @@ func (st *SectorBlocks) writeRef(cid cid.Cid, pieceRef string, offset uint64, si var refs api.SealedRefs if len(v) > 0 { - if err := cborrpc.ReadCborRPC(bytes.NewReader(v), &refs); err != nil { + if err := cborutil.ReadCborRPC(bytes.NewReader(v), &refs); err != nil { return xerrors.Errorf("decoding existing refs: %w", err) } } @@ -109,7 +109,7 @@ func (st *SectorBlocks) writeRef(cid cid.Cid, pieceRef string, offset uint64, si Size: size, }) - newRef, err := cborrpc.Dump(&refs) + newRef, err := cborutil.Dump(&refs) if err != nil { return xerrors.Errorf("serializing refs: %w", err) } @@ -197,7 +197,7 @@ func (st *SectorBlocks) List() (map[cid.Cid][]api.SealedRef, error) { } var refs api.SealedRefs - if err := cborrpc.ReadCborRPC(bytes.NewReader(ent.Value), &refs); err != nil { + if err := cborutil.ReadCborRPC(bytes.NewReader(ent.Value), &refs); err != nil { return nil, err } @@ -217,7 +217,7 @@ func (st *SectorBlocks) GetRefs(k cid.Cid) ([]api.SealedRef, error) { // TODO: t } var refs api.SealedRefs - if err := cborrpc.ReadCborRPC(bytes.NewReader(ent), &refs); err != nil { + if err := cborutil.ReadCborRPC(bytes.NewReader(ent), &refs); err != nil { return nil, err } From 15492697734f634d3c9f39bdd20bb716ba19d5db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 15:45:53 +0100 Subject: [PATCH 080/114] Make multiple deals per almost work --- lib/statestore/store.go | 8 ++++++-- storage/sealing.go | 9 +++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/statestore/store.go b/lib/statestore/store.go index c32c3ff22..994938223 100644 --- a/lib/statestore/store.go +++ b/lib/statestore/store.go @@ -39,7 +39,7 @@ func (st *StateStore) Begin(i interface{}, state interface{}) error { return err } if has { - return xerrors.Errorf("Already tracking state for %s", i) + return xerrors.Errorf("already tracking state for %v", i) } b, err := cborutil.Dump(state) @@ -111,12 +111,16 @@ func (st *StateStore) mutate(i interface{}, mutator func([]byte) ([]byte, error) return st.ds.Put(k, mutated) } +func (st *StateStore) Has(i interface{}) (bool, error) { + return st.ds.Has(toKey(i)) +} + func (st *StateStore) Get(i interface{}, out cbg.CBORUnmarshaler) error { k := toKey(i) val, err := st.ds.Get(k) if err != nil { if xerrors.Is(err, datastore.ErrNotFound) { - return xerrors.Errorf("No state for %s", i) + return xerrors.Errorf("No state for %s: %w", i, err) } return err } diff --git a/storage/sealing.go b/storage/sealing.go index 637eb8da2..a2723680d 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -61,6 +61,15 @@ func (m *Miner) sectorStateLoop(ctx context.Context) { } func (m *Miner) onSectorIncoming(sector *SectorInfo) { + has, err := m.sectors.Has(sector.SectorID) + if err != nil { + return + } + if has { + log.Warnf("SealSector called more than once for sector %d", sector.SectorID) + return + } + if err := m.sectors.Begin(sector.SectorID, sector); err != nil { // We may have re-sent the proposal log.Errorf("deal tracking failed: %s", err) From e5f90371c7e27b068af2285134e7d1976b3e7242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 16:19:07 +0100 Subject: [PATCH 081/114] update go-sectorbuilder --- extern/go-sectorbuilder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/go-sectorbuilder b/extern/go-sectorbuilder index 2886db51e..181742fdd 160000 --- a/extern/go-sectorbuilder +++ b/extern/go-sectorbuilder @@ -1 +1 @@ -Subproject commit 2886db51e1b49d697d7ee87ea662e4545225acea +Subproject commit 181742fdd08f74f1c9de54fca0f5658706039bc0 From 3e39d6e4453b8a4a7d5b8b14d150e1bafa4c0ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 17:39:27 +0100 Subject: [PATCH 082/114] sectorbuilder: use standalone methods --- lib/sectorbuilder/files.go | 88 ++++++++++++ lib/sectorbuilder/mock.go | 9 +- lib/sectorbuilder/sectorbuilder.go | 173 ++++++++++++++++-------- lib/sectorbuilder/sectorbuilder_test.go | 35 +++-- 4 files changed, 230 insertions(+), 75 deletions(-) create mode 100644 lib/sectorbuilder/files.go diff --git a/lib/sectorbuilder/files.go b/lib/sectorbuilder/files.go new file mode 100644 index 000000000..c0af2b6a7 --- /dev/null +++ b/lib/sectorbuilder/files.go @@ -0,0 +1,88 @@ +package sectorbuilder + +import ( + "fmt" + "io" + "os" + "path/filepath" + "sync" + + "golang.org/x/xerrors" +) + +func (sb *SectorBuilder) sectorName(sectorID uint64) string { + return fmt.Sprintf("s-%s-%d", sb.Miner, sectorID) +} + +func (sb *SectorBuilder) stagedSectorPath(sectorID uint64) string { + return filepath.Join(sb.stagedDir, sb.sectorName(sectorID)) +} + +func (sb *SectorBuilder) stagedSectorFile(sectorID uint64) (*os.File, error) { + return os.OpenFile(sb.stagedSectorPath(sectorID), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) +} + +func (sb *SectorBuilder) sealedSectorPath(sectorID uint64) (string, error) { + path := filepath.Join(sb.sealedDir, sb.sectorName(sectorID)) + + e, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644) + if err != nil { + return "", err + } + + return path, e.Close() +} + +func (sb *SectorBuilder) sectorCacheDir(sectorID uint64) (string, error) { + dir := filepath.Join(sb.cacheDir, sb.sectorName(sectorID)) + + err := os.Mkdir(dir, 0755) + if os.IsExist(err) { + err = nil + } + + return dir, err +} + +func toReadableFile(r io.Reader, n int64) (*os.File, func() error, error) { + f, ok := r.(*os.File) + if ok { + return f, func() error { return nil }, nil + } + + var w *os.File + + f, w, err := os.Pipe() + if err != nil { + return nil, nil, err + } + + var wait sync.Mutex + var werr error + + wait.Lock() + go func() { + defer wait.Unlock() + + copied, werr := io.CopyN(w, r, n) + if werr != nil { + log.Warnf("toReadableFile: copy error: %+v", werr) + } + + err := w.Close() + if werr == nil && err != nil { + werr = err + log.Warnf("toReadableFile: close error: %+v", err) + return + } + if copied != n { + log.Warnf("copied different amount than expected: %d != %d", copied, n) + werr = xerrors.Errorf("copied different amount than expected: %d != %d", copied, n) + } + }() + + return f, func() error { + wait.Lock() + return werr + }, nil +} diff --git a/lib/sectorbuilder/mock.go b/lib/sectorbuilder/mock.go index 451757b17..1433d6a2d 100644 --- a/lib/sectorbuilder/mock.go +++ b/lib/sectorbuilder/mock.go @@ -24,8 +24,15 @@ func TempSectorbuilder(sectorSize uint64) (*SectorBuilder, func(), error) { staging := filepath.Join(dir, "staging") cache := filepath.Join(dir, "cache") + for _, dir := range []string{metadata, sealed, staging, cache} { + if err := os.Mkdir(dir, 0755); err != nil { + return nil, nil, err + } + } + sb, err := New(&Config{ - SectorSize: sectorSize, + SectorSize: sectorSize, + SealedDir: sealed, StagedDir: staging, MetadataDir: metadata, diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 7f09fa81b..9944429ec 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -2,9 +2,7 @@ package sectorbuilder import ( "io" - "os" "sort" - "sync" "unsafe" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" @@ -15,6 +13,7 @@ import ( ) const PoStReservedWorkers = 1 +const PoRepProofPartitions = 2 var log = logging.Logger("sectorbuilder") @@ -36,6 +35,8 @@ type SealCommitOutput = sectorbuilder.SealCommitOutput type PublicPieceInfo = sectorbuilder.PublicPieceInfo +type RawSealPreCommitOutput = sectorbuilder.RawSealPreCommitOutput + const CommLen = sectorbuilder.CommitmentBytesLen type SectorBuilder struct { @@ -44,6 +45,10 @@ type SectorBuilder struct { Miner address.Address + stagedDir string + sealedDir string + cacheDir string + rateLimit chan struct{} } @@ -66,7 +71,7 @@ func New(cfg *Config) (*SectorBuilder, error) { proverId := addressToProverID(cfg.Miner) - sbp, err := sectorbuilder.InitSectorBuilder(cfg.SectorSize, 2, 0, cfg.MetadataDir, proverId, cfg.SealedDir, cfg.StagedDir, cfg.CacheDir, 16, cfg.WorkerThreads) + sbp, err := sectorbuilder.InitSectorBuilder(cfg.SectorSize, PoRepProofPartitions, 0, cfg.MetadataDir, proverId, cfg.SealedDir, cfg.StagedDir, cfg.CacheDir, 16, cfg.WorkerThreads) if err != nil { return nil, err } @@ -75,6 +80,10 @@ func New(cfg *Config) (*SectorBuilder, error) { handle: sbp, ssize: cfg.SectorSize, + stagedDir: cfg.StagedDir, + sealedDir: cfg.SealedDir, + cacheDir: cfg.CacheDir, + Miner: cfg.Miner, rateLimit: make(chan struct{}, cfg.WorkerThreads-PoStReservedWorkers), }, nil @@ -101,21 +110,44 @@ func (sb *SectorBuilder) Destroy() { sectorbuilder.DestroySectorBuilder(sb.handle) } -func (sb *SectorBuilder) AddPiece(pieceKey string, pieceSize uint64, file io.Reader) (uint64, error) { +func (sb *SectorBuilder) AcquireSectorId() (uint64, error) { + return sectorbuilder.AcquireSectorId(sb.handle) +} + +func (sb *SectorBuilder) AddPiece(pieceSize uint64, sectorId uint64, file io.Reader) (PublicPieceInfo, error) { f, werr, err := toReadableFile(file, int64(pieceSize)) if err != nil { - return 0, err + return PublicPieceInfo{}, err } ret := sb.rlimit() defer ret() - sectorID, err := sectorbuilder.AddPieceFromFile(sb.handle, pieceKey, pieceSize, f) + stagedFile, err := sb.stagedSectorFile(sectorId) if err != nil { - return 0, err + return PublicPieceInfo{}, err } - return sectorID, werr() + writeUnpadded, commP, err := sectorbuilder.StandaloneWriteWithoutAlignment(f, pieceSize, stagedFile) + if err != nil { + return PublicPieceInfo{}, err + } + if writeUnpadded != pieceSize { + return PublicPieceInfo{}, xerrors.Errorf("writeUnpadded != pieceSize: %d != %d", writeUnpadded, pieceSize) + } + + if err := stagedFile.Close(); err != nil { + return PublicPieceInfo{}, err + } + + if err := f.Close(); err != nil { + return PublicPieceInfo{}, err + } + + return PublicPieceInfo{ + Size: pieceSize, + CommP: commP, + }, werr() } // TODO: should *really really* return an io.ReadCloser @@ -126,25 +158,89 @@ func (sb *SectorBuilder) ReadPieceFromSealedSector(pieceKey string) ([]byte, err return sectorbuilder.ReadPieceFromSealedSector(sb.handle, pieceKey) } -func (sb *SectorBuilder) SealPreCommit(sectorID uint64, ticket SealTicket) (SealPreCommitOutput, error) { +func (sb *SectorBuilder) SealPreCommit(sectorID uint64, ticket SealTicket, pieces []PublicPieceInfo) (RawSealPreCommitOutput, error) { ret := sb.rlimit() defer ret() - return sectorbuilder.SealPreCommit(sb.handle, sectorID, ticket) + cacheDir, err := sb.sectorCacheDir(sectorID) + if err != nil { + return RawSealPreCommitOutput{}, err + } + + sealedPath, err := sb.sealedSectorPath(sectorID) + if err != nil { + return RawSealPreCommitOutput{}, err + } + + return sectorbuilder.StandaloneSealPreCommit( + sb.ssize, + PoRepProofPartitions, + cacheDir, + sb.stagedSectorPath(sectorID), + sealedPath, + sectorID, + addressToProverID(sb.Miner), + ticket.TicketBytes, + pieces, + ) } -func (sb *SectorBuilder) SealCommit(sectorID uint64, seed SealSeed) (SealCommitOutput, error) { +func (sb *SectorBuilder) SealCommit(sectorID uint64, ticket SealTicket, seed SealSeed, pieces []PublicPieceInfo, pieceKeys []string, rspco RawSealPreCommitOutput) (proof []byte, err error) { ret := sb.rlimit() defer ret() - return sectorbuilder.SealCommit(sb.handle, sectorID, seed) -} + cacheDir, err := sb.sectorCacheDir(sectorID) + if err != nil { + return nil, err + } -func (sb *SectorBuilder) ResumeSealCommit(sectorID uint64) (SealCommitOutput, error) { - ret := sb.rlimit() - defer ret() + proof, err = sectorbuilder.StandaloneSealCommit( + sb.ssize, + PoRepProofPartitions, + cacheDir, + sectorID, + addressToProverID(sb.Miner), + ticket.TicketBytes, + seed.TicketBytes, + pieces, + rspco, + ) + if err != nil { + return nil, xerrors.Errorf("StandaloneSealCommit: %w", err) + } - return sectorbuilder.ResumeSealCommit(sb.handle, sectorID) + pmeta := make([]sectorbuilder.PieceMetadata, len(pieces)) + for i, piece := range pieces { + pmeta[i] = sectorbuilder.PieceMetadata{ + Key: pieceKeys[i], + Size: piece.Size, + CommP: piece.CommP, + } + } + + sealedPath, err := sb.sealedSectorPath(sectorID) + if err != nil { + return nil, err + } + + err = sectorbuilder.ImportSealedSector( + sb.handle, + sectorID, + cacheDir, + sealedPath, + ticket, + seed, + rspco.CommR, + rspco.CommD, + rspco.CommC, + rspco.CommRLast, + proof, + pmeta, + ) + if err != nil { + return nil, xerrors.Errorf("ImportSealedSector: %w", err) + } + return proof, nil } func (sb *SectorBuilder) SealStatus(sector uint64) (SectorSealingStatus, error) { @@ -217,46 +313,3 @@ func GeneratePieceCommitment(piece io.Reader, pieceSize uint64) (commP [CommLen] func GenerateDataCommitment(ssize uint64, pieces []PublicPieceInfo) ([CommLen]byte, error) { return sectorbuilder.GenerateDataCommitment(ssize, pieces) } - -func toReadableFile(r io.Reader, n int64) (*os.File, func() error, error) { - f, ok := r.(*os.File) - if ok { - return f, func() error { return nil }, nil - } - - var w *os.File - - f, w, err := os.Pipe() - if err != nil { - return nil, nil, err - } - - var wait sync.Mutex - var werr error - - wait.Lock() - go func() { - defer wait.Unlock() - - copied, werr := io.CopyN(w, r, n) - if werr != nil { - log.Warnf("toReadableFile: copy error: %+v", werr) - } - - err := w.Close() - if werr == nil && err != nil { - werr = err - log.Warnf("toReadableFile: close error: %+v", err) - return - } - if copied != n { - log.Warnf("copied different amount than expected: %d != %d", copied, n) - werr = xerrors.Errorf("copied different amount than expected: %d != %d", copied, n) - } - }() - - return f, func() error { - wait.Lock() - return werr - }, nil -} diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index 5ce934f04..c83f2c97b 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -3,6 +3,7 @@ package sectorbuilder_test import ( "io" "math/rand" + "os" "testing" "github.com/filecoin-project/lotus/build" @@ -12,27 +13,33 @@ import ( const sectorSize = 1024 func TestSealAndVerify(t *testing.T) { - t.Skip("this is slow") - //os.Setenv("BELLMAN_NO_GPU", "1") + //t.Skip("this is slow") + os.Setenv("BELLMAN_NO_GPU", "1") build.SectorSizes = []uint64{sectorSize} if err := build.GetParams(true); err != nil { - t.Fatal(err) + t.Fatalf("%+v", err) } sb, cleanup, err := sectorbuilder.TempSectorbuilder(sectorSize) if err != nil { - t.Fatal(err) + t.Fatalf("%+v", err) } - defer cleanup() + _ = cleanup + //defer cleanup() dlen := sectorbuilder.UserBytesForSectorSize(sectorSize) - r := io.LimitReader(rand.New(rand.NewSource(42)), int64(dlen)) - sid, err := sb.AddPiece("foo", dlen, r) + sid, err := sb.AcquireSectorId() if err != nil { - t.Fatal(err) + t.Fatalf("%+v", err) + } + + r := io.LimitReader(rand.New(rand.NewSource(42)), int64(dlen)) + ppi, err := sb.AddPiece(dlen, sid, r) + if err != nil { + t.Fatalf("%+v", err) } ticket := sectorbuilder.SealTicket{ @@ -40,9 +47,9 @@ func TestSealAndVerify(t *testing.T) { TicketBytes: [32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2}, } - pco, err := sb.SealPreCommit(sid, ticket) + pco, err := sb.SealPreCommit(sid, ticket, []sectorbuilder.PublicPieceInfo{ppi}) if err != nil { - t.Fatal(err) + t.Fatalf("%+v", err) } seed := sectorbuilder.SealSeed{ @@ -50,14 +57,14 @@ func TestSealAndVerify(t *testing.T) { TicketBytes: [32]byte{0, 9, 8, 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}, } - sco, err := sb.SealCommit(sid, seed) + proof, err := sb.SealCommit(sid, ticket, seed, []sectorbuilder.PublicPieceInfo{ppi}, []string{"foo"}, pco) if err != nil { - t.Fatal(err) + t.Fatalf("%+v", err) } - ok, err := sectorbuilder.VerifySeal(sectorSize, pco.CommR[:], pco.CommD[:], sb.Miner, ticket.TicketBytes[:], seed.TicketBytes[:], sid, sco.Proof) + ok, err := sectorbuilder.VerifySeal(sectorSize, pco.CommR[:], pco.CommD[:], sb.Miner, ticket.TicketBytes[:], seed.TicketBytes[:], sid, proof) if err != nil { - t.Fatal(err) + t.Fatalf("%+v", err) } if !ok { From 69b4bd9fb40376e2f7edf2490d95c4aab42ed5f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 17:43:59 +0100 Subject: [PATCH 083/114] sectorbuilder: Also test PoSt --- lib/sectorbuilder/sectorbuilder_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index c83f2c97b..1b4933656 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -70,4 +70,24 @@ func TestSealAndVerify(t *testing.T) { if !ok { t.Fatal("proof failed to validate") } + + 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: sid, + CommR: pco.CommR, + }}) + + postProof, err := sb.GeneratePoSt(ssi, cSeed, []uint64{}) + if err != nil { + t.Fatalf("%+v", err) + } + + ok, err = sectorbuilder.VerifyPost(sb.SectorSize(), ssi, cSeed, postProof, []uint64{}) + if err != nil { + t.Fatalf("%+v", err) + } + if !ok { + t.Fatal("bad post") + } } From 2d26a4edf7a488376065245d929bfde163e01cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 19:22:59 +0100 Subject: [PATCH 084/114] Sector storage refactor --- chain/deals/provider_states.go | 8 +- gen/main.go | 10 +- node/builder.go | 4 +- node/impl/storminer.go | 2 - node/modules/storageminer.go | 7 +- storage/garbage.go | 34 +-- storage/miner.go | 15 +- storage/post.go | 22 +- storage/sealing.go | 104 +++++++- storage/sealing_utils.go | 20 ++ .../store_test.go => sealing_utils_test.go} | 41 +-- storage/sector/cbor_gen.go | 119 --------- storage/sector/store.go | 238 ------------------ storage/sector_states.go | 62 +++-- storage/sectorblocks/blocks.go | 12 +- 15 files changed, 213 insertions(+), 485 deletions(-) create mode 100644 storage/sealing_utils.go rename storage/{sector/store_test.go => sealing_utils_test.go} (55%) delete mode 100644 storage/sector/cbor_gen.go delete mode 100644 storage/sector/store.go diff --git a/chain/deals/provider_states.go b/chain/deals/provider_states.go index 7d94d93e2..00546202d 100644 --- a/chain/deals/provider_states.go +++ b/chain/deals/provider_states.go @@ -219,7 +219,7 @@ func (p *Provider) staged(ctx context.Context, deal MinerDeal) (func(*MinerDeal) return nil, xerrors.Errorf("deal.Proposal.PieceSize didn't match padded unixfs file size") } - sectorID, err := p.secb.AddUnixfsPiece(deal.Ref, uf, deal.DealID) + sectorID, err := p.secb.AddUnixfsPiece(ctx, deal.Ref, uf, deal.DealID) if err != nil { return nil, xerrors.Errorf("AddPiece failed: %s", err) } @@ -228,16 +228,12 @@ func (p *Provider) staged(ctx context.Context, deal MinerDeal) (func(*MinerDeal) return func(deal *MinerDeal) { deal.SectorID = sectorID }, nil - } // SEALING func (p *Provider) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal), error) { - log.Info("About to seal sector!", deal.ProposalCid, deal.SectorID) - if err := p.sminer.SealSector(ctx, deal.SectorID); err != nil { - return nil, xerrors.Errorf("sealing sector failed: %w", err) - } + // TODO: consider waiting for seal to happen return nil, nil } diff --git a/gen/main.go b/gen/main.go index efe1af965..2c9292283 100644 --- a/gen/main.go +++ b/gen/main.go @@ -13,7 +13,6 @@ import ( "github.com/filecoin-project/lotus/paych" "github.com/filecoin-project/lotus/retrieval" "github.com/filecoin-project/lotus/storage" - "github.com/filecoin-project/lotus/storage/sector" ) func main() { @@ -153,18 +152,11 @@ func main() { err = gen.WriteTupleEncodersToFile("./storage/cbor_gen.go", "storage", storage.SealTicket{}, + storage.Piece{}, storage.SectorInfo{}, ) if err != nil { fmt.Println(err) os.Exit(1) } - - err = gen.WriteTupleEncodersToFile("./storage/sector/cbor_gen.go", "sector", - sector.DealMapping{}, - ) - if err != nil { - fmt.Println(err) - os.Exit(1) - } } diff --git a/node/builder.go b/node/builder.go index 145a92fe1..cf999ea4b 100644 --- a/node/builder.go +++ b/node/builder.go @@ -41,7 +41,6 @@ import ( "github.com/filecoin-project/lotus/retrieval" "github.com/filecoin-project/lotus/retrieval/discovery" "github.com/filecoin-project/lotus/storage" - "github.com/filecoin-project/lotus/storage/sector" "github.com/filecoin-project/lotus/storage/sectorblocks" ) @@ -229,9 +228,8 @@ func Online() Option { // Storage miner ApplyIf(func(s *Settings) bool { return s.nodeType == repo.RepoStorageMiner }, Override(new(*sectorbuilder.SectorBuilder), sectorbuilder.New), - Override(new(*sector.Store), sector.NewStore), Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks), - Override(new(sector.TicketFn), modules.SealTicketGen), + Override(new(storage.TicketFn), modules.SealTicketGen), Override(new(*storage.Miner), modules.StorageMiner), Override(new(dtypes.StagingDAG), modules.StagingDAG), diff --git a/node/impl/storminer.go b/node/impl/storminer.go index b9efe9f2f..e7b081ea6 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -7,7 +7,6 @@ import ( "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/storage" - "github.com/filecoin-project/lotus/storage/sector" "github.com/filecoin-project/lotus/storage/sectorblocks" ) @@ -16,7 +15,6 @@ type StorageMinerAPI struct { SectorBuilderConfig *sectorbuilder.Config SectorBuilder *sectorbuilder.SectorBuilder - Sectors *sector.Store SectorBlocks *sectorblocks.SectorBlocks Miner *storage.Miner diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 5a9ea4d75..3c827c550 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -28,7 +28,6 @@ import ( "github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/retrieval" "github.com/filecoin-project/lotus/storage" - "github.com/filecoin-project/lotus/storage/sector" ) func minerAddrFromDS(ds dtypes.MetadataDS) (address.Address, error) { @@ -81,13 +80,13 @@ func SectorBuilderConfig(storagePath string, threads uint) func(dtypes.MetadataD } } -func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api api.FullNode, h host.Host, ds dtypes.MetadataDS, secst *sector.Store) (*storage.Miner, error) { +func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api api.FullNode, h host.Host, ds dtypes.MetadataDS, sb *sectorbuilder.SectorBuilder, tktFn storage.TicketFn) (*storage.Miner, error) { maddr, err := minerAddrFromDS(ds) if err != nil { return nil, err } - sm, err := storage.NewMiner(api, maddr, h, ds, secst) + sm, err := storage.NewMiner(api, maddr, h, ds, sb, tktFn) if err != nil { return nil, err } @@ -177,7 +176,7 @@ func RegisterMiner(lc fx.Lifecycle, ds dtypes.MetadataDS, api api.FullNode) erro return nil } -func SealTicketGen(api api.FullNode) sector.TicketFn { +func SealTicketGen(api api.FullNode) storage.TicketFn { return func(ctx context.Context) (*sectorbuilder.SealTicket, error) { ts, err := api.ChainHead(ctx) if err != nil { diff --git a/storage/garbage.go b/storage/garbage.go index 8e3cf1a10..8a2dd7a22 100644 --- a/storage/garbage.go +++ b/storage/garbage.go @@ -17,7 +17,7 @@ import ( ) // TODO: expected sector ID -func (m *Miner) storeGarbage(ctx context.Context, sizes ...uint64) ([]uint64, error) { +func (m *Miner) storeGarbage(ctx context.Context, sectorID uint64, sizes ...uint64) ([]Piece, error) { deals := make([]actors.StorageDeal, len(sizes)) for i, size := range sizes { commP, err := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), size) @@ -87,41 +87,47 @@ func (m *Miner) storeGarbage(ctx context.Context, sizes ...uint64) ([]uint64, er return nil, xerrors.New("got unexpected number of DealIDs from PublishStorageDeals") } - sectorIDs := make([]uint64, len(sizes)) + out := make([]Piece, len(sizes)) for i, size := range sizes { name := fmt.Sprintf("fake-file-%d", rand.Intn(100000000)) - sectorID, err := m.secst.AddPiece(name, size, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), resp.DealIDs[i]) + ppi, err := m.sb.AddPiece(size, sectorID, io.LimitReader(rand.New(rand.NewSource(42)), int64(size))) if err != nil { return nil, err } - sectorIDs[i] = sectorID + out[i] = Piece{ + DealID: resp.DealIDs[i], + Ref: name, + Size: ppi.Size, + CommP: ppi.CommP[:], + } } - return sectorIDs, nil + return out, nil } func (m *Miner) StoreGarbageData(_ context.Context) error { ctx := context.TODO() - ssize, err := m.SectorSize(ctx) - if err != nil { - return xerrors.Errorf("failed to get miner sector size: %w", err) - } go func() { - size := sectorbuilder.UserBytesForSectorSize(ssize) + size := sectorbuilder.UserBytesForSectorSize(m.sb.SectorSize()) - sids, err := m.storeGarbage(ctx, size) + sid, err := m.sb.AcquireSectorId() if err != nil { log.Errorf("%+v", err) return } - if err := m.SealSector(context.TODO(), sids[0]); err != nil { + pieces, err := m.storeGarbage(ctx, sid, size) + if err != nil { + log.Errorf("%+v", err) + return + } + + if err := m.newSector(context.TODO(), sid, pieces[0].DealID, pieces[0].Ref, pieces[0].ppi()); err != nil { log.Errorf("%+v", err) return } }() - - return err + return nil } diff --git a/storage/miner.go b/storage/miner.go index 72a6a0a8b..c3ddcc8e5 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -2,6 +2,7 @@ package storage import ( "context" + "github.com/filecoin-project/lotus/lib/sectorbuilder" "sync" "github.com/filecoin-project/lotus/lib/statestore" @@ -18,7 +19,6 @@ import ( "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/storage/sector" ) var log = logging.Logger("storageminer") @@ -29,7 +29,6 @@ type Miner struct { api storageMinerApi events *events.Events h host.Host - secst *sector.Store maddr address.Address worker address.Address @@ -39,7 +38,9 @@ type Miner struct { schedPost uint64 // Sealing + sb *sectorbuilder.SectorBuilder sectors *statestore.StateStore + tktFn TicketFn sectorIncoming chan *SectorInfo sectorUpdated chan sectorUpdate @@ -73,13 +74,14 @@ type storageMinerApi interface { WalletHas(context.Context, address.Address) (bool, error) } -func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datastore.Batching, secst *sector.Store) (*Miner, error) { +func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datastore.Batching, sb *sectorbuilder.SectorBuilder, tktFn TicketFn) (*Miner, error) { return &Miner{ api: api, maddr: addr, h: h, - secst: secst, + sb: sb, + tktFn: tktFn, sectors: statestore.New(namespace.Wrap(ds, datastore.NewKey("/sectors"))), @@ -132,8 +134,3 @@ func (m *Miner) runPreflightChecks(ctx context.Context) error { log.Infof("starting up miner %s, worker addr %s", m.maddr, m.worker) return nil } - -func (m *Miner) SectorSize(ctx context.Context) (uint64, error) { - // TODO: cache this - return m.api.StateMinerSectorSize(ctx, m.maddr, nil) -} diff --git a/storage/post.go b/storage/post.go index ff21c48f7..0f4c74f38 100644 --- a/storage/post.go +++ b/storage/post.go @@ -2,6 +2,7 @@ package storage import ( "context" + "github.com/filecoin-project/lotus/lib/sectorbuilder" "time" "github.com/ipfs/go-cid" @@ -158,6 +159,21 @@ func (p *post) preparePost(ctx context.Context) error { return nil } +func (p *post) sortedSectorInfo() sectorbuilder.SortedSectorInfo { + sbsi := make([]sectorbuilder.SectorInfo, len(p.sset)) + for k, sector := range p.sset { + var commR [sectorbuilder.CommLen]byte + copy(commR[:], sector.CommR) + + sbsi[k] = sectorbuilder.SectorInfo{ + SectorID: sector.SectorID, + CommR: commR, + } + } + + return sectorbuilder.NewSortedSectorInfo(sbsi) +} + func (p *post) runPost(ctx context.Context) error { ctx, span := trace.StartSpan(ctx, "storage.runPost") defer span.End() @@ -168,7 +184,11 @@ func (p *post) runPost(ctx context.Context) error { tsStart := time.Now() var faults []uint64 // TODO - proof, err := p.m.secst.RunPoSt(ctx, p.sset, p.r, faults) + + var seed [32]byte + copy(seed[:], p.r) + + proof, err := p.m.sb.GeneratePoSt(p.sortedSectorInfo(), seed, faults) if err != nil { return xerrors.Errorf("running post failed: %w", err) } diff --git a/storage/sealing.go b/storage/sealing.go index a2723680d..4000d46fe 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -2,25 +2,56 @@ package storage import ( "context" + "io" - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/types" cid "github.com/ipfs/go-cid" xerrors "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/lib/sectorbuilder" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types" ) +type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error) + type SealTicket struct { BlockHeight uint64 TicketBytes []byte } +func (t *SealTicket) sb() sectorbuilder.SealTicket { + out := sectorbuilder.SealTicket{BlockHeight: t.BlockHeight} + copy(out.TicketBytes[:], t.TicketBytes) + return out +} + +type Piece struct { + DealID uint64 + Ref string + + Size uint64 + CommP []byte +} + +func (p *Piece) ppi() (out sectorbuilder.PublicPieceInfo) { + out.Size = p.Size + copy(out.CommP[:], p.CommP) + return out +} + type SectorInfo struct { State api.SectorState SectorID uint64 + // Packing + + Pieces []Piece + // PreCommit - CommD []byte - CommR []byte + CommC []byte + CommD []byte + CommR []byte + CommRLast []byte Ticket SealTicket PreCommitMessage *cid.Cid @@ -40,6 +71,41 @@ type sectorUpdate struct { mut func(*SectorInfo) } +func (t *SectorInfo) pieceInfos() []sectorbuilder.PublicPieceInfo { + out := make([]sectorbuilder.PublicPieceInfo, len(t.Pieces)) + for i, piece := range t.Pieces { + out[i] = piece.ppi() + } + return out +} + +func (t *SectorInfo) deals() []uint64 { + out := make([]uint64, len(t.Pieces)) + for i, piece := range t.Pieces { + out[i] = piece.DealID + } + return out +} + +func (t *SectorInfo) refs() []string { + out := make([]string, len(t.Pieces)) + for i, piece := range t.Pieces { + out[i] = piece.Ref + } + return out +} + +func (t *SectorInfo) rspco() sectorbuilder.RawSealPreCommitOutput { + var out sectorbuilder.RawSealPreCommitOutput + + copy(out.CommC[:], t.CommC) + copy(out.CommD[:], t.CommD) + copy(out.CommR[:], t.CommR) + copy(out.CommRLast[:], t.CommRLast) + + return out +} + func (m *Miner) sectorStateLoop(ctx context.Context) { // TODO: restore state @@ -66,7 +132,7 @@ func (m *Miner) onSectorIncoming(sector *SectorInfo) { return } if has { - log.Warnf("SealSector called more than once for sector %d", sector.SectorID) + log.Warnf("SealPiece called more than once for sector %d", sector.SectorID) return } @@ -129,12 +195,36 @@ func (m *Miner) failSector(id uint64, err error) { panic(err) // todo: better error handling strategy } -func (m *Miner) SealSector(ctx context.Context, sid uint64) error { - log.Infof("Begin sealing sector %d", sid) +func (m *Miner) SealPiece(ctx context.Context, ref string, size uint64, r io.Reader, dealID uint64) (uint64, error) { + log.Infof("Seal piece for deal %d", dealID) + sid, err := m.sb.AcquireSectorId() // TODO: Put more than one thing in a sector + if err != nil { + return 0, xerrors.Errorf("acquiring sector ID: %w", err) + } + + ppi, err := m.sb.AddPiece(size, sid, r) + if err != nil { + return 0, xerrors.Errorf("adding piece to sector: %w", err) + } + + return sid, m.newSector(ctx, sid, dealID, ref, ppi) +} + +func (m *Miner) newSector(ctx context.Context, sid uint64, dealID uint64, ref string, ppi sectorbuilder.PublicPieceInfo) error { si := &SectorInfo{ State: api.UndefinedSectorState, SectorID: sid, + + Pieces: []Piece{ + { + DealID: dealID, + Ref:ref, + + Size: ppi.Size, + CommP: ppi.CommP[:], + }, + }, } select { case m.sectorIncoming <- si: diff --git a/storage/sealing_utils.go b/storage/sealing_utils.go new file mode 100644 index 000000000..17d83abbf --- /dev/null +++ b/storage/sealing_utils.go @@ -0,0 +1,20 @@ +package storage + +import ( + "math/bits" + + "github.com/filecoin-project/lotus/lib/sectorbuilder" +) + +func fillersFromRem(toFill uint64) ([]uint64, error) { + toFill += toFill / 127 // convert to in-sector bytes for easier math + + out := make([]uint64, bits.OnesCount64(toFill)) + for i := range out { + next := bits.TrailingZeros64(toFill) + psize := uint64(1) << next + toFill ^= psize + out[i] = sectorbuilder.UserBytesForSectorSize(psize) + } + return out, nil +} diff --git a/storage/sector/store_test.go b/storage/sealing_utils_test.go similarity index 55% rename from storage/sector/store_test.go rename to storage/sealing_utils_test.go index 78d7ccd0e..6a975e664 100644 --- a/storage/sector/store_test.go +++ b/storage/sealing_utils_test.go @@ -1,18 +1,11 @@ -package sector +package storage import ( - "context" - "fmt" - "github.com/filecoin-project/lotus/lib/padreader" - "io" - "math/rand" "testing" "github.com/stretchr/testify/assert" - "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/lib/sectorbuilder" - "github.com/ipfs/go-datastore" ) func testFill(t *testing.T, n uint64, exp []uint64) { @@ -51,35 +44,3 @@ func TestFillersFromRem(t *testing.T) { } } - -func TestSectorStore(t *testing.T) { - if err := build.GetParams(true); err != nil { - t.Fatal(err) - } - - sb, cleanup, err := sectorbuilder.TempSectorbuilder(1024) - if err != nil { - t.Fatal(err) - } - defer cleanup() - - tktFn := func(context.Context) (*sectorbuilder.SealTicket, error) { - return §orbuilder.SealTicket{ - BlockHeight: 17, - TicketBytes: [32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2}, - }, nil - } - - ds := datastore.NewMapDatastore() - - store := NewStore(sb, ds, tktFn) - - pr := io.LimitReader(rand.New(rand.NewSource(17)), 300) - pr, n := padreader.New(pr, 300) - - sid, err := store.AddPiece("a", n, pr, 1) - if err != nil { - t.Fatal(err) - } - fmt.Println(sid) -} diff --git a/storage/sector/cbor_gen.go b/storage/sector/cbor_gen.go deleted file mode 100644 index 11a2365f1..000000000 --- a/storage/sector/cbor_gen.go +++ /dev/null @@ -1,119 +0,0 @@ -package sector - -import ( - "fmt" - "io" - - cbg "github.com/whyrusleeping/cbor-gen" - xerrors "golang.org/x/xerrors" -) - -/* This file was generated by github.com/whyrusleeping/cbor-gen */ - -var _ = xerrors.Errorf - -func (t *DealMapping) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{131}); err != nil { - return err - } - - // t.t.DealIDs ([]uint64) (slice) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { - return err - } - for _, v := range t.DealIDs { - if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { - return err - } - } - - // t.t.Allocated (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Allocated))); err != nil { - return err - } - - // t.t.Committed (bool) (bool) - if err := cbg.WriteBool(w, t.Committed); err != nil { - return err - } - return nil -} - -func (t *DealMapping) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 3 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.t.DealIDs ([]uint64) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if extra > 8192 { - return fmt.Errorf("t.DealIDs: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.DealIDs = make([]uint64, extra) - } - for i := 0; i < int(extra); i++ { - - maj, val, err := cbg.CborReadHeader(br) - if err != nil { - return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) - } - - if maj != cbg.MajUnsignedInt { - return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) - } - - t.DealIDs[i] = val - } - - // t.t.Allocated (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Allocated = uint64(extra) - // t.t.Committed (bool) (bool) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajOther { - return fmt.Errorf("booleans must be major type 7") - } - switch extra { - case 20: - t.Committed = false - case 21: - t.Committed = true - default: - return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra) - } - return nil -} diff --git a/storage/sector/store.go b/storage/sector/store.go deleted file mode 100644 index 47bd5af13..000000000 --- a/storage/sector/store.go +++ /dev/null @@ -1,238 +0,0 @@ -package sector - -import ( - "bytes" - "context" - "fmt" - "github.com/filecoin-project/go-sectorbuilder/sealing_state" - "github.com/ipfs/go-datastore" - "github.com/ipfs/go-datastore/namespace" - logging "github.com/ipfs/go-log" - "golang.org/x/xerrors" - "io" - "math/bits" - "sync" - - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/lib/cborutil" - "github.com/filecoin-project/lotus/lib/sectorbuilder" - "github.com/filecoin-project/lotus/node/modules/dtypes" -) - -var log = logging.Logger("sectorstore") - -var sectorDealsPrefix = datastore.NewKey("/sectordeals") - -type DealMapping struct { - DealIDs []uint64 - Allocated uint64 - Committed bool -} - -type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error) - -// TODO: eventually handle sector storage here instead of in rust-sectorbuilder -type Store struct { - sb *sectorbuilder.SectorBuilder - tktFn TicketFn - - dealsLk sync.Mutex - deals datastore.Datastore -} - -func NewStore(sb *sectorbuilder.SectorBuilder, ds dtypes.MetadataDS, tktFn TicketFn) *Store { - return &Store{ - sb: sb, - tktFn: tktFn, - deals: namespace.Wrap(ds, sectorDealsPrefix), - } -} - -func (s *Store) SectorStatus(sid uint64) (*sectorbuilder.SectorSealingStatus, error) { - status, err := s.sb.SealStatus(sid) - if err != nil { - return nil, err - } - - return &status, nil -} - -func (s *Store) AddPiece(ref string, size uint64, r io.Reader, dealIDs ...uint64) (sectorID uint64, err error) { - sectorID, err = s.sb.AddPiece(ref, size, r) - if err != nil { - return 0, err - } - - s.dealsLk.Lock() - defer s.dealsLk.Unlock() - - k := datastore.NewKey(fmt.Sprint(sectorID)) - e, err := s.deals.Get(k) - var deals DealMapping - switch err { - case nil: - if err := cborutil.ReadCborRPC(bytes.NewReader(e), &deals); err != nil { - return 0, err - } - if deals.Committed { - return 0, xerrors.Errorf("sector %d already committed", sectorID) - } - fallthrough - case datastore.ErrNotFound: - deals.DealIDs = append(deals.DealIDs, dealIDs...) - deals.Allocated += size - - d, err := cborutil.Dump(&deals) - if err != nil { - return 0, err - } - if err := s.deals.Put(k, d); err != nil { - return 0, err - } - default: - return 0, err - } - - return sectorID, nil -} - -func (s *Store) PieceSizesToFill(sectorID uint64) ([]uint64, error) { - s.dealsLk.Lock() - defer s.dealsLk.Unlock() - - k := datastore.NewKey(fmt.Sprint(sectorID)) - e, err := s.deals.Get(k) - if err != nil { - return nil, err - } - var info DealMapping - if err := cborutil.ReadCborRPC(bytes.NewReader(e), &info); err != nil { - return nil, err - } - if info.Allocated > s.sb.SectorSize() { - return nil, xerrors.Errorf("more data allocated in sector than should be able to fit: %d > %d", info.Allocated, s.sb.SectorSize()) - } - - return fillersFromRem(sectorbuilder.UserBytesForSectorSize(s.sb.SectorSize()) - info.Allocated) -} - -func fillersFromRem(toFill uint64) ([]uint64, error) { - toFill += toFill / 127 // convert to in-sector bytes for easier math - - out := make([]uint64, bits.OnesCount64(toFill)) - for i := range out { - next := bits.TrailingZeros64(toFill) - psize := uint64(1) << next - toFill ^= psize - out[i] = sectorbuilder.UserBytesForSectorSize(psize) - } - return out, nil -} - -func (s *Store) DealsForCommit(sectorID uint64, commit bool) ([]uint64, error) { - s.dealsLk.Lock() - defer s.dealsLk.Unlock() - - k := datastore.NewKey(fmt.Sprint(sectorID)) - e, err := s.deals.Get(k) - - switch err { - case nil: - var deals DealMapping - if err := cborutil.ReadCborRPC(bytes.NewReader(e), &deals); err != nil { - return nil, err - } - if !commit { - return nil, nil - } - - if deals.Committed { - log.Errorf("getting deal IDs for sector %d: sector already marked as committed", sectorID) - } - - deals.Committed = true - d, err := cborutil.Dump(&deals) - if err != nil { - return nil, err - } - if err := s.deals.Put(k, d); err != nil { - return nil, err - } - - return deals.DealIDs, nil - case datastore.ErrNotFound: - log.Errorf("getting deal IDs for sector %d failed: %s", err) - return []uint64{}, nil - default: - return nil, err - } -} - -func (s *Store) SealPreCommit(ctx context.Context, sectorID uint64) (sectorbuilder.SealPreCommitOutput, error) { - tkt, err := s.tktFn(ctx) - if err != nil { - return sectorbuilder.SealPreCommitOutput{}, err - } - - return s.sb.SealPreCommit(sectorID, *tkt) -} - -func (s *Store) SealComputeProof(ctx context.Context, sectorID uint64, height uint64, rand []byte) ([]byte, error) { - var tick [32]byte - copy(tick[:], rand) - - sco, err := s.sb.SealCommit(sectorID, sectorbuilder.SealSeed{ - BlockHeight: height, - TicketBytes: tick, - }) - if err != nil { - return nil, err - } - return sco.Proof, nil -} - -func (s *Store) Committed() ([]sectorbuilder.SectorSealingStatus, error) { - l, err := s.sb.GetAllStagedSectors() - if err != nil { - return nil, err - } - - out := make([]sectorbuilder.SectorSealingStatus, 0) - for _, sid := range l { - status, err := s.sb.SealStatus(sid) - if err != nil { - return nil, err - } - - if status.State != sealing_state.Committed { - continue - } - out = append(out, status) - } - - return out, nil -} - -func (s *Store) RunPoSt(ctx context.Context, sectors []*api.SectorInfo, r []byte, faults []uint64) ([]byte, error) { - sbsi := make([]sectorbuilder.SectorInfo, len(sectors)) - for k, sector := range sectors { - var commR [sectorbuilder.CommLen]byte - if copy(commR[:], sector.CommR) != sectorbuilder.CommLen { - return nil, xerrors.Errorf("commR too short, %d bytes", len(sector.CommR)) - } - - sbsi[k] = sectorbuilder.SectorInfo{ - SectorID: sector.SectorID, - CommR: commR, - } - } - - ssi := sectorbuilder.NewSortedSectorInfo(sbsi) - - var seed [sectorbuilder.CommLen]byte - if copy(seed[:], r) != sectorbuilder.CommLen { - return nil, xerrors.Errorf("random seed too short, %d bytes", len(r)) - } - - return s.sb.GeneratePoSt(ssi, seed, faults) -} diff --git a/storage/sector_states.go b/storage/sector_states.go index b52402c4f..ded491192 100644 --- a/storage/sector_states.go +++ b/storage/sector_states.go @@ -2,6 +2,7 @@ package storage import ( "context" + "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" @@ -37,7 +38,16 @@ func (m *Miner) handle(ctx context.Context, sector SectorInfo, cb providerHandle func (m *Miner) finishPacking(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { log.Infow("performing filling up rest of the sector...", "sector", sector.SectorID) - fillerSizes, err := m.secst.PieceSizesToFill(sector.SectorID) + var allocated uint64 + for _, piece := range sector.Pieces { + allocated += piece.Size + } + + if allocated > m.sb.SectorSize() { + return nil, xerrors.Errorf("too much data in sector: %d > %d", allocated, m.sb.SectorSize()) + } + + fillerSizes, err := fillersFromRem(m.sb.SectorSize() - allocated) if err != nil { return nil, err } @@ -46,49 +56,47 @@ func (m *Miner) finishPacking(ctx context.Context, sector SectorInfo) (func(*Sec log.Warnf("Creating %d filler pieces for sector %d", len(fillerSizes), sector.SectorID) } - ids, err := m.storeGarbage(ctx, fillerSizes...) + pieces, err := m.storeGarbage(ctx, sector.SectorID, fillerSizes...) if err != nil { return nil, xerrors.Errorf("filling up the sector (%v): %w", fillerSizes, err) } - for _, id := range ids { - if id != sector.SectorID { - panic("todo: pass SectorID into storeGarbage") - } - } - - return nil, nil + return func(info *SectorInfo) { + info.Pieces = append(info.Pieces, pieces...) + }, nil } func (m *Miner) sealPreCommit(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { log.Infow("performing sector replication...", "sector", sector.SectorID) - sinfo, err := m.secst.SealPreCommit(ctx, sector.SectorID) + ticket, err := m.tktFn(ctx) + if err != nil { + return nil, err + } + + rspco, err := m.sb.SealPreCommit(sector.SectorID, *ticket, sector.pieceInfos()) if err != nil { return nil, xerrors.Errorf("seal pre commit failed: %w", err) } return func(info *SectorInfo) { - info.CommD = sinfo.CommD[:] - info.CommR = sinfo.CommR[:] + info.CommC = rspco.CommC[:] + info.CommD = rspco.CommD[:] + info.CommR = rspco.CommR[:] + info.CommRLast = rspco.CommRLast[:] info.Ticket = SealTicket{ - BlockHeight: sinfo.Ticket.BlockHeight, - TicketBytes: sinfo.Ticket.TicketBytes[:], + BlockHeight: ticket.BlockHeight, + TicketBytes: ticket.TicketBytes[:], } }, nil } func (m *Miner) preCommit(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { - deals, err := m.secst.DealsForCommit(sector.SectorID, false) - if err != nil { - return nil, err - } - params := &actors.SectorPreCommitInfo{ SectorNumber: sector.SectorID, CommR: sector.CommR, SealEpoch: sector.Ticket.BlockHeight, - DealIDs: deals, + DealIDs: sector.deals(), } enc, aerr := actors.SerializeParams(params) if aerr != nil { @@ -164,20 +172,20 @@ func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*Sector return nil, xerrors.Errorf("failed to get randomness for computing seal proof: %w", err) } - proof, err := m.secst.SealComputeProof(ctx, sector.SectorID, sector.RandHeight, rand) + seed := sectorbuilder.SealSeed{ + BlockHeight: sector.RandHeight, + } + copy(seed.TicketBytes[:], rand) + + proof, err := m.sb.SealCommit(sector.SectorID, sector.Ticket.sb(), seed, sector.pieceInfos(), sector.refs(), sector.rspco()) if err != nil { return nil, xerrors.Errorf("computing seal proof failed: %w", err) } - deals, err := m.secst.DealsForCommit(sector.SectorID, true) - if err != nil { - return nil, err - } - params := &actors.SectorProveCommitInfo{ Proof: proof, SectorID: sector.SectorID, - DealIDs: deals, + DealIDs: sector.deals(), } enc, aerr := actors.SerializeParams(params) diff --git a/storage/sectorblocks/blocks.go b/storage/sectorblocks/blocks.go index 9f40742d3..e1f64ae3e 100644 --- a/storage/sectorblocks/blocks.go +++ b/storage/sectorblocks/blocks.go @@ -23,7 +23,7 @@ import ( "github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/node/modules/dtypes" - "github.com/filecoin-project/lotus/storage/sector" + "github.com/filecoin-project/lotus/storage" ) type SealSerialization uint8 @@ -38,7 +38,7 @@ var imBlocksPrefix = datastore.NewKey("/intermediate") var ErrNotFound = errors.New("not found") type SectorBlocks struct { - *sector.Store + *storage.Miner intermediate blockstore.Blockstore // holds intermediate nodes TODO: consider combining with the staging blockstore @@ -47,9 +47,9 @@ type SectorBlocks struct { keyLk sync.Mutex } -func NewSectorBlocks(sectst *sector.Store, ds dtypes.MetadataDS, sb *sectorbuilder.SectorBuilder) *SectorBlocks { +func NewSectorBlocks(miner *storage.Miner, ds dtypes.MetadataDS, sb *sectorbuilder.SectorBuilder) *SectorBlocks { sbc := &SectorBlocks{ - Store: sectst, + Miner: miner, intermediate: blockstore.NewBlockstore(namespace.Wrap(ds, imBlocksPrefix)), @@ -160,7 +160,7 @@ func (r *refStorer) Read(p []byte) (n int, err error) { } } -func (st *SectorBlocks) AddUnixfsPiece(ref cid.Cid, r UnixfsReader, dealID uint64) (sectorID uint64, err error) { +func (st *SectorBlocks) AddUnixfsPiece(ctx context.Context, ref cid.Cid, r UnixfsReader, dealID uint64) (sectorID uint64, err error) { size, err := r.Size() if err != nil { return 0, err @@ -175,7 +175,7 @@ func (st *SectorBlocks) AddUnixfsPiece(ref cid.Cid, r UnixfsReader, dealID uint6 pr, psize := padreader.New(r, uint64(size)) - return st.Store.AddPiece(refst.pieceRef, psize, pr, dealID) + return st.Miner.SealPiece(ctx, refst.pieceRef, psize, pr, dealID) } func (st *SectorBlocks) List() (map[cid.Cid][]api.SealedRef, error) { From 68adf519c7fed001541d160236f5458893f4ebc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 19:27:23 +0100 Subject: [PATCH 085/114] cbor-gen --- storage/cbor_gen.go | 192 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 2 deletions(-) diff --git a/storage/cbor_gen.go b/storage/cbor_gen.go index 74c5f93e6..c84a32590 100644 --- a/storage/cbor_gen.go +++ b/storage/cbor_gen.go @@ -82,12 +82,114 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) error { return nil } +func (t *Piece) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{132}); err != nil { + return err + } + + // t.t.DealID (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.DealID))); err != nil { + return err + } + + // t.t.Ref (string) (string) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Ref)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.Ref)); err != nil { + return err + } + + // t.t.Size (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Size))); err != nil { + return err + } + + // t.t.CommP ([]uint8) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommP)))); err != nil { + return err + } + if _, err := w.Write(t.CommP); err != nil { + return err + } + return nil +} + +func (t *Piece) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 4 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.DealID (uint64) (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.DealID = uint64(extra) + // t.t.Ref (string) (string) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.Ref = string(sval) + } + // t.t.Size (uint64) (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Size = uint64(extra) + // t.t.CommP ([]uint8) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.CommP: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommP = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommP); err != nil { + return err + } + return nil +} + func (t *SectorInfo) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{137}); err != nil { + if _, err := w.Write([]byte{140}); err != nil { return err } @@ -101,6 +203,24 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } + // t.t.Pieces ([]storage.Piece) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Pieces)))); err != nil { + return err + } + for _, v := range t.Pieces { + if err := v.MarshalCBOR(w); err != nil { + return err + } + } + + // t.t.CommC ([]uint8) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommC)))); err != nil { + return err + } + if _, err := w.Write(t.CommC); err != nil { + return err + } + // t.t.CommD ([]uint8) (slice) if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommD)))); err != nil { return err @@ -117,6 +237,14 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } + // t.t.CommRLast ([]uint8) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommRLast)))); err != nil { + return err + } + if _, err := w.Write(t.CommRLast); err != nil { + return err + } + // t.t.Ticket (storage.SealTicket) (struct) if err := t.Ticket.MarshalCBOR(w); err != nil { return err @@ -170,7 +298,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 9 { + if extra != 12 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -194,6 +322,49 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("wrong type for uint64 field") } t.SectorID = uint64(extra) + // t.t.Pieces ([]storage.Piece) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.Pieces: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.Pieces = make([]Piece, extra) + } + for i := 0; i < int(extra); i++ { + + var v Piece + if err := v.UnmarshalCBOR(br); err != nil { + return err + } + + t.Pieces[i] = v + } + + // t.t.CommC ([]uint8) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.CommC: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommC = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommC); err != nil { + return err + } // t.t.CommD ([]uint8) (slice) maj, extra, err = cbg.CborReadHeader(br) @@ -228,6 +399,23 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if _, err := io.ReadFull(br, t.CommR); err != nil { return err } + // t.t.CommRLast ([]uint8) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.CommRLast: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommRLast = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommRLast); err != nil { + return err + } // t.t.Ticket (storage.SealTicket) (struct) { From 58c21b4a5e4c03669af7f99436f60025ccbfde67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 19:33:46 +0100 Subject: [PATCH 086/114] sectorbuilder: Always create directories --- lib/sectorbuilder/mock.go | 6 ------ lib/sectorbuilder/sectorbuilder.go | 10 ++++++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/sectorbuilder/mock.go b/lib/sectorbuilder/mock.go index 1433d6a2d..20ec4ac51 100644 --- a/lib/sectorbuilder/mock.go +++ b/lib/sectorbuilder/mock.go @@ -24,12 +24,6 @@ func TempSectorbuilder(sectorSize uint64) (*SectorBuilder, func(), error) { staging := filepath.Join(dir, "staging") cache := filepath.Join(dir, "cache") - for _, dir := range []string{metadata, sealed, staging, cache} { - if err := os.Mkdir(dir, 0755); err != nil { - return nil, nil, err - } - } - sb, err := New(&Config{ SectorSize: sectorSize, diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 9944429ec..98e0dcfd1 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -2,6 +2,7 @@ package sectorbuilder import ( "io" + "os" "sort" "unsafe" @@ -71,6 +72,15 @@ func New(cfg *Config) (*SectorBuilder, error) { proverId := addressToProverID(cfg.Miner) + for _, dir := range []string{cfg.StagedDir, cfg.SealedDir, cfg.CacheDir, cfg.MetadataDir} { + if err := os.Mkdir(dir, 0755); err != nil { + if os.IsExist(err) { + continue + } + return nil, err + } + } + sbp, err := sectorbuilder.InitSectorBuilder(cfg.SectorSize, PoRepProofPartitions, 0, cfg.MetadataDir, proverId, cfg.SealedDir, cfg.StagedDir, cfg.CacheDir, 16, cfg.WorkerThreads) if err != nil { return nil, err From f40eb8a521260fbd4d892905dade3fd195f76da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 19:43:15 +0100 Subject: [PATCH 087/114] More post-refactor fixes --- api/test/deals.go | 5 ++++- storage/miner.go | 6 +++--- storage/sealing.go | 14 +++++++------- storage/sector_states.go | 8 +++++--- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/api/test/deals.go b/api/test/deals.go index 3145f7c4a..8e8f37388 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -12,6 +12,7 @@ import ( logging "github.com/ipfs/go-log" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/impl" @@ -20,6 +21,8 @@ import ( func TestDealFlow(t *testing.T, b APIBuilder) { os.Setenv("BELLMAN_NO_GPU", "1") + build.SectorSizes = []uint64{1024} + logging.SetAllLoggers(logging.LevelInfo) ctx := context.Background() n, sn := b(t, 1, []int{0}) @@ -36,7 +39,7 @@ func TestDealFlow(t *testing.T, b APIBuilder) { } time.Sleep(time.Second) - r := io.LimitReader(rand.New(rand.NewSource(17)), 350) + r := io.LimitReader(rand.New(rand.NewSource(17)), 257) fcid, err := client.ClientImportLocal(ctx, r) if err != nil { t.Fatal(err) diff --git a/storage/miner.go b/storage/miner.go index c3ddcc8e5..eab867a43 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -38,9 +38,9 @@ type Miner struct { schedPost uint64 // Sealing - sb *sectorbuilder.SectorBuilder + sb *sectorbuilder.SectorBuilder sectors *statestore.StateStore - tktFn TicketFn + tktFn TicketFn sectorIncoming chan *SectorInfo sectorUpdated chan sectorUpdate @@ -80,7 +80,7 @@ func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datasto maddr: addr, h: h, - sb: sb, + sb: sb, tktFn: tktFn, sectors: statestore.New(namespace.Wrap(ds, datastore.NewKey("/sectors"))), diff --git a/storage/sealing.go b/storage/sealing.go index 4000d46fe..461728840 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -7,9 +7,9 @@ import ( cid "github.com/ipfs/go-cid" xerrors "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/sectorbuilder" ) type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error) @@ -27,9 +27,9 @@ func (t *SealTicket) sb() sectorbuilder.SealTicket { type Piece struct { DealID uint64 - Ref string + Ref string - Size uint64 + Size uint64 CommP []byte } @@ -52,7 +52,7 @@ type SectorInfo struct { CommD []byte CommR []byte CommRLast []byte - Ticket SealTicket + Ticket SealTicket PreCommitMessage *cid.Cid @@ -219,10 +219,10 @@ func (m *Miner) newSector(ctx context.Context, sid uint64, dealID uint64, ref st Pieces: []Piece{ { DealID: dealID, - Ref:ref, + Ref: ref, - Size: ppi.Size, - CommP: ppi.CommP[:], + Size: ppi.Size, + CommP: ppi.CommP[:], }, }, } diff --git a/storage/sector_states.go b/storage/sector_states.go index ded491192..dcf473b3b 100644 --- a/storage/sector_states.go +++ b/storage/sector_states.go @@ -43,11 +43,13 @@ func (m *Miner) finishPacking(ctx context.Context, sector SectorInfo) (func(*Sec allocated += piece.Size } - if allocated > m.sb.SectorSize() { - return nil, xerrors.Errorf("too much data in sector: %d > %d", allocated, m.sb.SectorSize()) + ubytes := sectorbuilder.UserBytesForSectorSize(m.sb.SectorSize()) + + if allocated > ubytes { + return nil, xerrors.Errorf("too much data in sector: %d > %d", allocated, ubytes) } - fillerSizes, err := fillersFromRem(m.sb.SectorSize() - allocated) + fillerSizes, err := fillersFromRem(ubytes - allocated) if err != nil { return nil, err } From f6a49ab9f97960ccf797fad35deb9018c74c0586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 20:54:24 +0100 Subject: [PATCH 088/114] Wip fixing a thing --- api/test/deals.go | 7 ++----- lib/sectorbuilder/files.go | 4 ++-- lib/sectorbuilder/sectorbuilder.go | 20 ++++++++++++++++++-- storage/garbage.go | 4 ++++ 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/api/test/deals.go b/api/test/deals.go index 8e8f37388..9312f5f13 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -12,7 +12,6 @@ import ( logging "github.com/ipfs/go-log" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/impl" @@ -21,8 +20,6 @@ import ( func TestDealFlow(t *testing.T, b APIBuilder) { os.Setenv("BELLMAN_NO_GPU", "1") - build.SectorSizes = []uint64{1024} - logging.SetAllLoggers(logging.LevelInfo) ctx := context.Background() n, sn := b(t, 1, []int{0}) @@ -39,7 +36,7 @@ func TestDealFlow(t *testing.T, b APIBuilder) { } time.Sleep(time.Second) - r := io.LimitReader(rand.New(rand.NewSource(17)), 257) + r := io.LimitReader(rand.New(rand.NewSource(17)), 9000000) fcid, err := client.ClientImportLocal(ctx, r) if err != nil { t.Fatal(err) @@ -65,7 +62,7 @@ func TestDealFlow(t *testing.T, b APIBuilder) { } } }() - deal, err := client.ClientStartDeal(ctx, fcid, maddr, types.NewInt(400), 100) + deal, err := client.ClientStartDeal(ctx, fcid, maddr, types.NewInt(40000000), 100) if err != nil { t.Fatal(err) } diff --git a/lib/sectorbuilder/files.go b/lib/sectorbuilder/files.go index c0af2b6a7..8a4500523 100644 --- a/lib/sectorbuilder/files.go +++ b/lib/sectorbuilder/files.go @@ -19,13 +19,13 @@ func (sb *SectorBuilder) stagedSectorPath(sectorID uint64) string { } func (sb *SectorBuilder) stagedSectorFile(sectorID uint64) (*os.File, error) { - return os.OpenFile(sb.stagedSectorPath(sectorID), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) + return os.OpenFile(sb.stagedSectorPath(sectorID), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) } func (sb *SectorBuilder) sealedSectorPath(sectorID uint64) (string, error) { path := filepath.Join(sb.sealedDir, sb.sectorName(sectorID)) - e, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644) + e, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644) if err != nil { return "", err } diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 98e0dcfd1..d886db2d6 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -182,17 +182,33 @@ func (sb *SectorBuilder) SealPreCommit(sectorID uint64, ticket SealTicket, piece return RawSealPreCommitOutput{}, err } - return sectorbuilder.StandaloneSealPreCommit( + var sum uint64 + for _, piece := range pieces { + sum += piece.Size + } + ussize := UserBytesForSectorSize(sb.ssize) + if sum != ussize { + return RawSealPreCommitOutput{}, xerrors.Errorf("aggregated piece sizes don't match sector size: %d != %d (%d)", sum, ussize, int64(ussize - sum)) + } + + stagedPath := sb.stagedSectorPath(sectorID) + + rspco, err := sectorbuilder.StandaloneSealPreCommit( sb.ssize, PoRepProofPartitions, cacheDir, - sb.stagedSectorPath(sectorID), + stagedPath, sealedPath, sectorID, addressToProverID(sb.Miner), ticket.TicketBytes, pieces, ) + if err != nil { + return RawSealPreCommitOutput{}, xerrors.Errorf("presealing sector %d (%s): %w", sectorID, stagedPath, err) + } + + return rspco, nil } func (sb *SectorBuilder) SealCommit(sectorID uint64, ticket SealTicket, seed SealSeed, pieces []PublicPieceInfo, pieceKeys []string, rspco RawSealPreCommitOutput) (proof []byte, err error) { diff --git a/storage/garbage.go b/storage/garbage.go index 8a2dd7a22..fda297f9c 100644 --- a/storage/garbage.go +++ b/storage/garbage.go @@ -18,6 +18,10 @@ import ( // TODO: expected sector ID func (m *Miner) storeGarbage(ctx context.Context, sectorID uint64, sizes ...uint64) ([]Piece, error) { + if len(sizes) == 0 { + return nil, nil + } + deals := make([]actors.StorageDeal, len(sizes)) for i, size := range sizes { commP, err := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), size) From 34846c538ee91120644c34b3290d324c4629fdbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 7 Nov 2019 21:40:46 +0100 Subject: [PATCH 089/114] sectorbuilder: Use StandaloneWriteWithAlignment --- api/test/deals.go | 2 +- lib/sectorbuilder/files.go | 2 +- lib/sectorbuilder/sectorbuilder.go | 10 +++++----- lib/sectorbuilder/sectorbuilder_test.go | 2 +- storage/garbage.go | 9 +++++---- storage/sealing.go | 10 +++++++++- storage/sector_states.go | 2 +- 7 files changed, 23 insertions(+), 14 deletions(-) diff --git a/api/test/deals.go b/api/test/deals.go index 9312f5f13..cb3002459 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -36,7 +36,7 @@ func TestDealFlow(t *testing.T, b APIBuilder) { } time.Sleep(time.Second) - r := io.LimitReader(rand.New(rand.NewSource(17)), 9000000) + r := io.LimitReader(rand.New(rand.NewSource(17)), 1000) fcid, err := client.ClientImportLocal(ctx, r) if err != nil { t.Fatal(err) diff --git a/lib/sectorbuilder/files.go b/lib/sectorbuilder/files.go index 8a4500523..51b748f50 100644 --- a/lib/sectorbuilder/files.go +++ b/lib/sectorbuilder/files.go @@ -19,7 +19,7 @@ func (sb *SectorBuilder) stagedSectorPath(sectorID uint64) string { } func (sb *SectorBuilder) stagedSectorFile(sectorID uint64) (*os.File, error) { - return os.OpenFile(sb.stagedSectorPath(sectorID), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) + return os.OpenFile(sb.stagedSectorPath(sectorID), os.O_RDWR|os.O_CREATE, 0644) } func (sb *SectorBuilder) sealedSectorPath(sectorID uint64) (string, error) { diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index d886db2d6..cc9bcdeea 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -124,7 +124,7 @@ func (sb *SectorBuilder) AcquireSectorId() (uint64, error) { return sectorbuilder.AcquireSectorId(sb.handle) } -func (sb *SectorBuilder) AddPiece(pieceSize uint64, sectorId uint64, file io.Reader) (PublicPieceInfo, error) { +func (sb *SectorBuilder) AddPiece(pieceSize uint64, sectorId uint64, file io.Reader, existingPieceSizes []uint64) (PublicPieceInfo, error) { f, werr, err := toReadableFile(file, int64(pieceSize)) if err != nil { return PublicPieceInfo{}, err @@ -138,13 +138,13 @@ func (sb *SectorBuilder) AddPiece(pieceSize uint64, sectorId uint64, file io.Rea return PublicPieceInfo{}, err } - writeUnpadded, commP, err := sectorbuilder.StandaloneWriteWithoutAlignment(f, pieceSize, stagedFile) + _, _, commP, err := sectorbuilder.StandaloneWriteWithAlignment(f, pieceSize, stagedFile, existingPieceSizes) if err != nil { return PublicPieceInfo{}, err } - if writeUnpadded != pieceSize { + /*if writeUnpadded != pieceSize { return PublicPieceInfo{}, xerrors.Errorf("writeUnpadded != pieceSize: %d != %d", writeUnpadded, pieceSize) - } + }*/ if err := stagedFile.Close(); err != nil { return PublicPieceInfo{}, err @@ -188,7 +188,7 @@ func (sb *SectorBuilder) SealPreCommit(sectorID uint64, ticket SealTicket, piece } ussize := UserBytesForSectorSize(sb.ssize) if sum != ussize { - return RawSealPreCommitOutput{}, xerrors.Errorf("aggregated piece sizes don't match sector size: %d != %d (%d)", sum, ussize, int64(ussize - sum)) + return RawSealPreCommitOutput{}, xerrors.Errorf("aggregated piece sizes don't match sector size: %d != %d (%d)", sum, ussize, int64(ussize-sum)) } stagedPath := sb.stagedSectorPath(sectorID) diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index 1b4933656..0e399be66 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -37,7 +37,7 @@ func TestSealAndVerify(t *testing.T) { } r := io.LimitReader(rand.New(rand.NewSource(42)), int64(dlen)) - ppi, err := sb.AddPiece(dlen, sid, r) + ppi, err := sb.AddPiece(dlen, sid, r, []uint64{}) if err != nil { t.Fatalf("%+v", err) } diff --git a/storage/garbage.go b/storage/garbage.go index fda297f9c..28e33e77d 100644 --- a/storage/garbage.go +++ b/storage/garbage.go @@ -16,8 +16,7 @@ import ( "github.com/filecoin-project/lotus/lib/sectorbuilder" ) -// TODO: expected sector ID -func (m *Miner) storeGarbage(ctx context.Context, sectorID uint64, sizes ...uint64) ([]Piece, error) { +func (m *Miner) storeGarbage(ctx context.Context, sectorID uint64, existingPieceSizes []uint64, sizes ...uint64) ([]Piece, error) { if len(sizes) == 0 { return nil, nil } @@ -95,11 +94,13 @@ func (m *Miner) storeGarbage(ctx context.Context, sectorID uint64, sizes ...uint for i, size := range sizes { name := fmt.Sprintf("fake-file-%d", rand.Intn(100000000)) - ppi, err := m.sb.AddPiece(size, sectorID, io.LimitReader(rand.New(rand.NewSource(42)), int64(size))) + ppi, err := m.sb.AddPiece(size, sectorID, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), existingPieceSizes) if err != nil { return nil, err } + existingPieceSizes = append(existingPieceSizes, size) + out[i] = Piece{ DealID: resp.DealIDs[i], Ref: name, @@ -122,7 +123,7 @@ func (m *Miner) StoreGarbageData(_ context.Context) error { return } - pieces, err := m.storeGarbage(ctx, sid, size) + pieces, err := m.storeGarbage(ctx, sid, []uint64{}, size) if err != nil { log.Errorf("%+v", err) return diff --git a/storage/sealing.go b/storage/sealing.go index 461728840..de9586326 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -95,6 +95,14 @@ func (t *SectorInfo) refs() []string { return out } +func (t *SectorInfo) existingPieces() []uint64 { + out := make([]uint64, len(t.Pieces)) + for i, piece := range t.Pieces { + out[i] = piece.Size + } + return out +} + func (t *SectorInfo) rspco() sectorbuilder.RawSealPreCommitOutput { var out sectorbuilder.RawSealPreCommitOutput @@ -203,7 +211,7 @@ func (m *Miner) SealPiece(ctx context.Context, ref string, size uint64, r io.Rea return 0, xerrors.Errorf("acquiring sector ID: %w", err) } - ppi, err := m.sb.AddPiece(size, sid, r) + ppi, err := m.sb.AddPiece(size, sid, r, []uint64{}) if err != nil { return 0, xerrors.Errorf("adding piece to sector: %w", err) } diff --git a/storage/sector_states.go b/storage/sector_states.go index dcf473b3b..a567f4e65 100644 --- a/storage/sector_states.go +++ b/storage/sector_states.go @@ -58,7 +58,7 @@ func (m *Miner) finishPacking(ctx context.Context, sector SectorInfo) (func(*Sec log.Warnf("Creating %d filler pieces for sector %d", len(fillerSizes), sector.SectorID) } - pieces, err := m.storeGarbage(ctx, sector.SectorID, fillerSizes...) + pieces, err := m.storeGarbage(ctx, sector.SectorID, sector.existingPieces(), fillerSizes...) if err != nil { return nil, xerrors.Errorf("filling up the sector (%v): %w", fillerSizes, err) } From af2789c3d88b2198c90cc5d67677d8fbf0490c5d Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Thu, 7 Nov 2019 14:55:24 -0800 Subject: [PATCH 090/114] fix non-deterministic map serialization --- chain/actors/actor_miner.go | 4 +- chain/actors/actor_storagemarket.go | 6 ++- chain/actors/cbor_gen.go | 65 ++++++++++++++++++----------- chain/deals/client_states.go | 2 + chain/sync.go | 11 +++++ go.mod | 2 +- go.sum | 2 + 7 files changed, 64 insertions(+), 28 deletions(-) diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index 608cbd5df..d1e4ad4d3 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -305,7 +305,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC return nil, aerrors.New(1, "no pre-commitment found for sector") } - if us.ReceivedEpoch+build.InteractivePoRepDelay > vmctx.BlockHeight() { + if us.ReceivedEpoch+build.InteractivePoRepDelay >= vmctx.BlockHeight() { return nil, aerrors.New(2, "too early for proof submission") } @@ -340,7 +340,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC if ok, err := ValidatePoRep(maddr, mi.SectorSize, commD, us.Info.CommR, ticket, params.Proof, seed, params.SectorID); err != nil { return nil, err } else if !ok { - return nil, aerrors.Newf(2, "bad proof! (t:%x; s:%x(%d); p:%x)", ticket, seed, us.ReceivedEpoch+build.InteractivePoRepDelay, params.Proof) + return nil, aerrors.Newf(2, "porep proof was invalid (t:%x; s:%x(%d); p:%x)", ticket, seed, us.ReceivedEpoch+build.InteractivePoRepDelay, params.Proof) } // Note: There must exist a unique index in the miner's sector set for each diff --git a/chain/actors/actor_storagemarket.go b/chain/actors/actor_storagemarket.go index 4e00e970a..6fb07be3f 100644 --- a/chain/actors/actor_storagemarket.go +++ b/chain/actors/actor_storagemarket.go @@ -613,6 +613,10 @@ func (sma StorageMarketActor) ComputeDataCommitment(act *types.Actor, vmctx type return nil, aerrors.HandleExternalError(err, "getting deal info failed") } + if dealInfo.Deal.Proposal.Provider != vmctx.Message().From { + return nil, aerrors.New(4, "referenced deal was not from caller") + } + var commP [32]byte copy(commP[:], dealInfo.Deal.Proposal.PieceRef) @@ -624,7 +628,7 @@ func (sma StorageMarketActor) ComputeDataCommitment(act *types.Actor, vmctx type commd, err := sectorbuilder.GenerateDataCommitment(params.SectorSize, pieces) if err != nil { - return nil, aerrors.Absorb(err, 4, "failed to generate data commitment from pieces") + return nil, aerrors.Absorb(err, 5, "failed to generate data commitment from pieces") } return commd[:], nil diff --git a/chain/actors/cbor_gen.go b/chain/actors/cbor_gen.go index 7b5aef2fb..fbb289fd2 100644 --- a/chain/actors/cbor_gen.go +++ b/chain/actors/cbor_gen.go @@ -3,6 +3,7 @@ package actors import ( "fmt" "io" + "sort" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" @@ -202,23 +203,31 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { } // t.t.PreCommittedSectors (map[string]*actors.PreCommittedSector) (map) - if err := cbg.CborWriteHeader(w, cbg.MajMap, uint64(len(t.PreCommittedSectors))); err != nil { - return err - } - - for k, v := range t.PreCommittedSectors { - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil { - return err - } - if _, err := w.Write([]byte(k)); err != nil { + { + if err := cbg.CborWriteHeader(w, cbg.MajMap, uint64(len(t.PreCommittedSectors))); err != nil { return err } - if err := v.MarshalCBOR(w); err != nil { - return err + keys := make([]string, 0, len(t.PreCommittedSectors)) + for k := range t.PreCommittedSectors { + keys = append(keys, k) } + sort.Strings(keys) + for _, k := range keys { + v := t.PreCommittedSectors[k] + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil { + return err + } + if _, err := w.Write([]byte(k)); err != nil { + return err + } + + if err := v.MarshalCBOR(w); err != nil { + return err + } + + } } // t.t.Sectors (cid.Cid) (struct) @@ -1902,23 +1911,31 @@ func (t *PaymentChannelActorState) MarshalCBOR(w io.Writer) error { } // t.t.LaneStates (map[string]*actors.LaneState) (map) - if err := cbg.CborWriteHeader(w, cbg.MajMap, uint64(len(t.LaneStates))); err != nil { - return err - } - - for k, v := range t.LaneStates { - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil { - return err - } - if _, err := w.Write([]byte(k)); err != nil { + { + if err := cbg.CborWriteHeader(w, cbg.MajMap, uint64(len(t.LaneStates))); err != nil { return err } - if err := v.MarshalCBOR(w); err != nil { - return err + keys := make([]string, 0, len(t.LaneStates)) + for k := range t.LaneStates { + keys = append(keys, k) } + sort.Strings(keys) + for _, k := range keys { + v := t.LaneStates[k] + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil { + return err + } + if _, err := w.Write([]byte(k)); err != nil { + return err + } + + if err := v.MarshalCBOR(w); err != nil { + return err + } + + } } return nil } diff --git a/chain/deals/client_states.go b/chain/deals/client_states.go index 5b4b7c78c..26ac0ce68 100644 --- a/chain/deals/client_states.go +++ b/chain/deals/client_states.go @@ -3,6 +3,7 @@ package deals import ( "bytes" "context" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/lib/cborutil" @@ -97,6 +98,7 @@ func (c *Client) accepted(ctx context.Context, deal ClientDeal) (func(*ClientDea } if eq { dealIdx = i + break } } diff --git a/chain/sync.go b/chain/sync.go index 952b57a20..edaabc2a0 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -462,6 +462,17 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err } if stateroot != h.ParentStateRoot { + msgs, err := syncer.store.MessagesForTipset(baseTs) + if err != nil { + log.Error("failed to load messages for tipset during tipset state mismatch error: ", err) + } else { + log.Warn("Messages for tipset with mismatching state:") + for i, m := range msgs { + mm := m.VMMessage() + log.Warnf("Message[%d]: from=%s to=%s method=%d params=%x", i, mm.From, mm.To, mm.Method, mm.Params) + } + } + return xerrors.Errorf("parent state root did not match computed state (%s != %s)", stateroot, h.ParentStateRoot) } diff --git a/go.mod b/go.mod index da117bec0..8e62267a7 100644 --- a/go.mod +++ b/go.mod @@ -73,7 +73,7 @@ require ( github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a github.com/stretchr/testify v1.4.0 github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba - github.com/whyrusleeping/cbor-gen v0.0.0-20191104210213-4418c8842f0f + github.com/whyrusleeping/cbor-gen v0.0.0-20191107223350-6fdade89d679 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d go.opencensus.io v0.22.0 diff --git a/go.sum b/go.sum index d02fd9826..665d7d4be 100644 --- a/go.sum +++ b/go.sum @@ -530,6 +530,8 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20190910031516-c1cbffdb01bb/go.mod h1:x github.com/whyrusleeping/cbor-gen v0.0.0-20190917003517-d78d67427694/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20191104210213-4418c8842f0f h1:+GFA37QICd1Axd2n9uzjtvPjxJJI5PU78vpvam+hI4U= github.com/whyrusleeping/cbor-gen v0.0.0-20191104210213-4418c8842f0f/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= +github.com/whyrusleeping/cbor-gen v0.0.0-20191107223350-6fdade89d679 h1:ct50KYdZHcdOnTAuSgppw5MZKTa3RA63FX28m0l9Aeg= +github.com/whyrusleeping/cbor-gen v0.0.0-20191107223350-6fdade89d679/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= From eae0b84b801e85b066978c46444432c46ebe816b Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Thu, 7 Nov 2019 17:45:45 -0800 Subject: [PATCH 091/114] Add command to list client deals --- cli/client.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/cli/client.go b/cli/client.go index 2ac4b3db3..283de413e 100644 --- a/cli/client.go +++ b/cli/client.go @@ -2,14 +2,17 @@ package cli import ( "fmt" + "os" "path/filepath" "strconv" + "text/tabwriter" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" "golang.org/x/xerrors" "gopkg.in/urfave/cli.v2" + lapi "github.com/filecoin-project/lotus/api" actors "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" @@ -25,6 +28,7 @@ var clientCmd = &cli.Command{ clientFindCmd, clientRetrieveCmd, clientQueryAskCmd, + clientListDeals, }, } @@ -326,3 +330,28 @@ var clientQueryAskCmd = &cli.Command{ return nil }, } + +var clientListDeals = &cli.Command{ + Name: "list-deals", + Usage: "List storage market deals", + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + deals, err := api.ClientListDeals(ctx) + if err != nil { + return err + } + + w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0) + fmt.Fprintf(w, "DealCid\tProvider\tState\tPieceRef\tSize\tPrice\tDuration\n") + for _, d := range deals { + fmt.Fprintf(w, "%s\t%s\t%s\t%x\t%d\t%s\t%d\n", d.ProposalCid, d.Provider, lapi.DealStates[d.State], d.PieceRef, d.Size, d.PricePerEpoch, d.Duration) + } + return w.Flush() + }, +} From 721786da1048736023e499d0f57d4644d6f6c7c9 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Thu, 7 Nov 2019 22:06:08 -0800 Subject: [PATCH 092/114] add a flag to allow only fetching verifying keys --- cli/params.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cli/params.go b/cli/params.go index 6f6017ca3..9e8183b8a 100644 --- a/cli/params.go +++ b/cli/params.go @@ -9,8 +9,14 @@ import ( var fetchParamCmd = &cli.Command{ Name: "fetch-params", Usage: "Fetch proving parameters", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "only-verify-keys", + Usage: "only download the verify keys", + }, + }, Action: func(cctx *cli.Context) error { - if err := build.GetParams(true); err != nil { + if err := build.GetParams(!cctx.Bool("only-verify-keys")); err != nil { return xerrors.Errorf("fetching proof parameters: %w", err) } From 2560c091da716dc521403ed98d38fe7d33573b25 Mon Sep 17 00:00:00 2001 From: wanghui Date: Fri, 8 Nov 2019 16:40:02 +0800 Subject: [PATCH 093/114] make long number param readable --- build/params.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/params.go b/build/params.go index e810ff45f..aaa7b475e 100644 --- a/build/params.go +++ b/build/params.go @@ -84,14 +84,14 @@ const CollateralPrecision = 1000 // ///// // Devnet settings -const TotalFilecoin = 2000000000 -const MiningRewardTotal = 1400000000 +const TotalFilecoin = 2_000_000_000 +const MiningRewardTotal = 1_400_000_000 const InitialRewardStr = "153856861913558700202" var InitialReward *big.Int -const FilecoinPrecision = 1000000000000000000 +const FilecoinPrecision = 1_000_000_000_000_000_000 // six years // Blocks From e226071c2036d679bceaf68c170c8a78b78ba5a5 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Fri, 8 Nov 2019 08:43:23 -0800 Subject: [PATCH 094/114] disable GPU by default --- cmd/lotus-storage-miner/run.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index 4142233fd..c8a10baac 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -31,12 +31,20 @@ var runCmd = &cli.Command{ Name: "api", Value: "2345", }, + &cli.BoolFlag{ + Name: "enable-gpu-proving", + Usage: "Enable use of GPU for mining operations", + }, }, Action: func(cctx *cli.Context) error { if err := build.GetParams(true); err != nil { return xerrors.Errorf("fetching proof parameters: %w", err) } + if !cctx.Bool("enable-gpu-proving") { + os.Setenv("BELLMAN_NO_GPU", "true") + } + nodeApi, ncloser, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err From be2e58a2fb47f4586a6141d9664086d05a45cb6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 18:15:38 +0100 Subject: [PATCH 095/114] Simple market fund manager --- api/api_full.go | 3 ++ api/struct.go | 6 +++ chain/deals/client.go | 45 ++++---------------- chain/deals/provider.go | 2 +- chain/deals/provider_states.go | 41 ++---------------- chain/market/fundmgr.go | 78 ++++++++++++++++++++++++++++++++++ node/builder.go | 2 + node/impl/full.go | 2 + node/impl/market/market.go | 21 +++++++++ 9 files changed, 125 insertions(+), 75 deletions(-) create mode 100644 chain/market/fundmgr.go create mode 100644 node/impl/market/market.go diff --git a/api/api_full.go b/api/api_full.go index d46fd25ba..ecafaadc1 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -111,6 +111,9 @@ type FullNode interface { StateMarketDeals(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) StateMarketStorageDeal(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) + MarketEnsureAvailable(context.Context, address.Address, types.BigInt) error + // MarketFreeBalance + PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) PaychList(context.Context) ([]address.Address, error) PaychStatus(context.Context, address.Address) (*PaychStatus, error) diff --git a/api/struct.go b/api/struct.go index 682e8f3e7..2845e05c7 100644 --- a/api/struct.go +++ b/api/struct.go @@ -107,6 +107,8 @@ type FullNodeStruct struct { StateMarketDeals func(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) `perm:"read"` StateMarketStorageDeal func(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) `perm:"read"` + MarketEnsureAvailable func(context.Context, address.Address, types.BigInt) error `perm:"sign"` + PaychGet func(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) `perm:"sign"` PaychList func(context.Context) ([]address.Address, error) `perm:"read"` PaychStatus func(context.Context, address.Address) (*PaychStatus, error) `perm:"read"` @@ -418,6 +420,10 @@ func (c *FullNodeStruct) StateMarketStorageDeal(ctx context.Context, dealid uint return c.Internal.StateMarketStorageDeal(ctx, dealid, ts) } +func (c *FullNodeStruct) MarketEnsureAvailable(ctx context.Context, addr address.Address, amt types.BigInt) error { + return c.Internal.MarketEnsureAvailable(ctx, addr, amt) +} + func (c *FullNodeStruct) PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) { return c.Internal.PaychGet(ctx, from, to, ensureFunds) } diff --git a/chain/deals/client.go b/chain/deals/client.go index f1101b1e3..eb96be154 100644 --- a/chain/deals/client.go +++ b/chain/deals/client.go @@ -3,9 +3,6 @@ package deals import ( "context" - "github.com/filecoin-project/lotus/lib/statestore" - "github.com/filecoin-project/lotus/node/impl/full" - "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" @@ -19,11 +16,14 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/events" + "github.com/filecoin-project/lotus/chain/market" "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/chain/wallet" "github.com/filecoin-project/lotus/lib/cborutil" + "github.com/filecoin-project/lotus/lib/statestore" + "github.com/filecoin-project/lotus/node/impl/full" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/retrieval/discovery" ) @@ -50,8 +50,8 @@ type Client struct { w *wallet.Wallet dag dtypes.ClientDAG discovery *discovery.Local - mpool full.MpoolAPI events *events.Events + fm *market.FundMgr deals *statestore.StateStore conns map[cid.Cid]inet.Stream @@ -70,7 +70,7 @@ type clientDealUpdate struct { mut func(*ClientDeal) } -func NewClient(sm *stmgr.StateManager, chain *store.ChainStore, h host.Host, w *wallet.Wallet, ds dtypes.MetadataDS, dag dtypes.ClientDAG, discovery *discovery.Local, mpool full.MpoolAPI, chainapi full.ChainAPI) *Client { +func NewClient(sm *stmgr.StateManager, chain *store.ChainStore, h host.Host, w *wallet.Wallet, ds dtypes.MetadataDS, dag dtypes.ClientDAG, discovery *discovery.Local, fm *market.FundMgr, chainapi full.ChainAPI) *Client { c := &Client{ sm: sm, chain: chain, @@ -78,7 +78,7 @@ func NewClient(sm *stmgr.StateManager, chain *store.ChainStore, h host.Host, w * w: w, dag: dag, discovery: discovery, - mpool: mpool, + fm: fm, events: events.NewEvents(context.TODO(), &chainapi), deals: statestore.New(namespace.Wrap(ds, datastore.NewKey("/deals/client"))), @@ -137,7 +137,7 @@ func (c *Client) onIncoming(deal *ClientDeal) { } func (c *Client) onUpdated(ctx context.Context, update clientDealUpdate) { - log.Infof("Deal %s updated state to %d", update.id, update.newState) + log.Infof("Client deal %s updated state to %s", update.id, api.DealStates[update.newState]) var deal ClientDeal err := c.deals.Mutate(update.id, func(d *ClientDeal) error { d.State = update.newState @@ -184,35 +184,8 @@ type ClientDealProposal struct { } func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, error) { - // check market funds - clientMarketBalance, err := c.sm.MarketBalance(ctx, p.Client, nil) - if err != nil { - return cid.Undef, xerrors.Errorf("getting client market balance failed: %w", err) - } - - if clientMarketBalance.Available.LessThan(types.BigMul(p.PricePerEpoch, types.NewInt(p.Duration))) { - // TODO: move to a smarter market funds manager - - smsg, err := c.mpool.MpoolPushMessage(ctx, &types.Message{ - To: actors.StorageMarketAddress, - From: p.Client, - Value: types.BigMul(p.PricePerEpoch, types.NewInt(p.Duration)), - GasPrice: types.NewInt(0), - GasLimit: types.NewInt(1000000), - Method: actors.SMAMethods.AddBalance, - }) - if err != nil { - return cid.Undef, err - } - - _, r, err := c.sm.WaitForMessage(ctx, smsg.Cid()) - if err != nil { - return cid.Undef, err - } - - if r.ExitCode != 0 { - return cid.Undef, xerrors.Errorf("adding funds to storage miner market actor failed: exit %d", r.ExitCode) - } + if err := c.fm.EnsureAvailable(ctx, p.Client, types.BigMul(p.PricePerEpoch, types.NewInt(p.Duration))); err != nil { + return cid.Undef, xerrors.Errorf("adding market funds failed: %w", err) } commP, pieceSize, err := c.commP(ctx, p.Data) diff --git a/chain/deals/provider.go b/chain/deals/provider.go index 8430cf2f4..2c8978170 100644 --- a/chain/deals/provider.go +++ b/chain/deals/provider.go @@ -160,7 +160,7 @@ func (p *Provider) onIncoming(deal MinerDeal) { } func (p *Provider) onUpdated(ctx context.Context, update minerDealUpdate) { - log.Infof("Deal %s updated state to %d", update.id, update.newState) + log.Infof("Deal %s updated state to %s", update.id, api.DealStates[update.newState]) if update.err != nil { log.Errorf("deal %s (newSt: %d) failed: %+v", update.id, update.newState, update.err) p.failDeal(update.id, update.err) diff --git a/chain/deals/provider_states.go b/chain/deals/provider_states.go index 00546202d..35f339502 100644 --- a/chain/deals/provider_states.go +++ b/chain/deals/provider_states.go @@ -10,7 +10,6 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/storage/sectorblocks" @@ -39,33 +38,6 @@ func (p *Provider) handle(ctx context.Context, deal MinerDeal, cb providerHandle } // ACCEPTED - -func (p *Provider) addMarketFunds(ctx context.Context, worker address.Address, deal MinerDeal) error { - log.Info("Adding market funds for storage collateral") - smsg, err := p.full.MpoolPushMessage(ctx, &types.Message{ - To: actors.StorageMarketAddress, - From: worker, - Value: deal.Proposal.StorageCollateral, - GasPrice: types.NewInt(0), - GasLimit: types.NewInt(1000000), - Method: actors.SMAMethods.AddBalance, - }) - if err != nil { - return err - } - - r, err := p.full.StateWaitMsg(ctx, smsg.Cid()) - if err != nil { - return err - } - - if r.Receipt.ExitCode != 0 { - return xerrors.Errorf("adding funds to storage miner market actor failed: exit %d", r.Receipt.ExitCode) - } - - return nil -} - func (p *Provider) accept(ctx context.Context, deal MinerDeal) (func(*MinerDeal), error) { switch deal.Proposal.PieceSerialization { //case SerializationRaw: @@ -111,16 +83,9 @@ func (p *Provider) accept(ctx context.Context, deal MinerDeal) (func(*MinerDeal) return nil, err } - providerMarketBalance, err := p.full.StateMarketBalance(ctx, waddr, nil) - if err != nil { - return nil, xerrors.Errorf("getting provider market balance failed: %w", err) - } - - // TODO: this needs to be atomic - if providerMarketBalance.Available.LessThan(deal.Proposal.StorageCollateral) { - if err := p.addMarketFunds(ctx, waddr, deal); err != nil { - return nil, err - } + // TODO: check StorageCollateral (may be too large (or too small)) + if err := p.full.MarketEnsureAvailable(ctx, waddr, deal.Proposal.StorageCollateral); err != nil { + return nil, err } log.Info("publishing deal") diff --git a/chain/market/fundmgr.go b/chain/market/fundmgr.go new file mode 100644 index 000000000..05716a428 --- /dev/null +++ b/chain/market/fundmgr.go @@ -0,0 +1,78 @@ +package market + +import ( + "context" + "sync" + + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/address" + "github.com/filecoin-project/lotus/chain/stmgr" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/node/impl/full" +) + +type FundMgr struct { + sm *stmgr.StateManager + mpool full.MpoolAPI + + lk sync.Mutex + available map[address.Address]types.BigInt +} + +func NewFundMgr(sm *stmgr.StateManager, mpool full.MpoolAPI) *FundMgr { + return &FundMgr{ + sm: sm, + mpool: mpool, + + available: map[address.Address]types.BigInt{}, + } +} + +func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr address.Address, amt types.BigInt) error { + fm.lk.Lock() + avail, ok := fm.available[addr] + if !ok { + bal, err := fm.sm.MarketBalance(ctx, addr, nil) + if err != nil { + fm.lk.Unlock() + return err + } + + avail = bal.Available + } + + toAdd := types.NewInt(0) + avail = types.BigSub(avail, amt) + if avail.LessThan(types.NewInt(0)) { + // TODO: some rules around adding more to avoid doing stuff on-chain + // all the time + toAdd = types.BigSub(toAdd, avail) + avail = types.NewInt(0) + } + fm.available[addr] = avail + fm.lk.Unlock() + + smsg, err := fm.mpool.MpoolPushMessage(ctx, &types.Message{ + To: actors.StorageMarketAddress, + From: addr, + Value: toAdd, + GasPrice: types.NewInt(0), + GasLimit: types.NewInt(1000000), + Method: actors.SMAMethods.AddBalance, + }) + if err != nil { + return err + } + + _, r, err := fm.sm.WaitForMessage(ctx, smsg.Cid()) + if err != nil { + return err + } + + if r.ExitCode != 0 { + return xerrors.Errorf("adding funds to storage miner market actor failed: exit %d", r.ExitCode) + } + return nil +} diff --git a/node/builder.go b/node/builder.go index cf999ea4b..147366db8 100644 --- a/node/builder.go +++ b/node/builder.go @@ -3,6 +3,7 @@ package node import ( "context" "errors" + "github.com/filecoin-project/lotus/chain/market" "time" blockstore "github.com/ipfs/go-ipfs-blockstore" @@ -221,6 +222,7 @@ 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), ), diff --git a/node/impl/full.go b/node/impl/full.go index 41c0730bf..6ce7fa91e 100644 --- a/node/impl/full.go +++ b/node/impl/full.go @@ -2,6 +2,7 @@ package impl import ( "context" + "github.com/filecoin-project/lotus/node/impl/market" "github.com/filecoin-project/lotus/node/impl/client" "github.com/filecoin-project/lotus/node/impl/paych" @@ -21,6 +22,7 @@ type FullNodeAPI struct { full.ChainAPI client.API full.MpoolAPI + market.MarketAPI paych.PaychAPI full.StateAPI full.WalletAPI diff --git a/node/impl/market/market.go b/node/impl/market/market.go new file mode 100644 index 000000000..3e7724e43 --- /dev/null +++ b/node/impl/market/market.go @@ -0,0 +1,21 @@ +package market + +import ( + "context" + + "go.uber.org/fx" + + "github.com/filecoin-project/lotus/chain/address" + "github.com/filecoin-project/lotus/chain/market" + "github.com/filecoin-project/lotus/chain/types" +) + +type MarketAPI struct { + fx.In + + FMgr *market.FundMgr +} + +func (a *MarketAPI) MarketEnsureAvailable(ctx context.Context, addr address.Address, amt types.BigInt) error { + return a.FMgr.EnsureAvailable(ctx, addr, amt) +} From 071f05fa955a068a227a862de83b00054a445b08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 19:15:13 +0100 Subject: [PATCH 096/114] Storage miner API improvements --- api/api_full.go | 6 +- api/api_storage.go | 21 ++++- api/struct.go | 22 +++-- build/version.go | 4 +- chain/stmgr/utils.go | 10 +-- cmd/lotus-storage-miner/info.go | 15 ++-- cmd/lotus-storage-miner/sectors.go | 8 +- gen/main.go | 1 + lib/sectorbuilder/sectorbuilder.go | 4 + node/impl/full/state.go | 4 +- node/impl/storminer.go | 43 +++++++++- storage/cbor_gen.go | 130 ++++++++++++++++++++++------- storage/miner.go | 4 +- storage/post.go | 4 +- storage/sealing.go | 18 +++- storage/sealing_utils.go | 14 ++++ storage/sector_states.go | 28 +++---- 17 files changed, 247 insertions(+), 89 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index ecafaadc1..057dca8cb 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -95,8 +95,8 @@ type FullNode interface { StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error) - StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*SectorInfo, error) - StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*SectorInfo, error) + StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) + StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) StateMinerPower(context.Context, address.Address, *types.TipSet) (MinerPower, error) StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) StateMinerPeerID(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) @@ -164,7 +164,7 @@ type Message struct { Message *types.Message } -type SectorInfo struct { +type ChainSectorInfo struct { SectorID uint64 CommD []byte CommR []byte diff --git a/api/api_storage.go b/api/api_storage.go index 75fc55849..299449662 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -58,12 +58,31 @@ type StorageMiner interface { StoreGarbageData(context.Context) error // Get the status of a given sector by ID - SectorsStatus(context.Context, uint64) (sectorbuilder.SectorSealingStatus, error) + SectorsStatus(context.Context, uint64) (SectorInfo, error) // List all staged sectors SectorsList(context.Context) ([]uint64, error) SectorsRefs(context.Context) (map[string][]SealedRef, error) + + WorkerStats(context.Context) (WorkerStats, error) +} + +type WorkerStats struct { + Free int + Reserved int // for PoSt + Total int +} + +type SectorInfo struct { + SectorID uint64 + State SectorState + CommD []byte + CommR []byte + Proof []byte + Deals []uint64 + Ticket sectorbuilder.SealTicket + Seed sectorbuilder.SealSeed } type SealedRef struct { diff --git a/api/struct.go b/api/struct.go index 2845e05c7..8d14af1d2 100644 --- a/api/struct.go +++ b/api/struct.go @@ -3,7 +3,6 @@ package api import ( "context" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" @@ -87,8 +86,8 @@ type FullNodeStruct struct { ClientRetrieve func(ctx context.Context, order RetrievalOrder, path string) error `perm:"admin"` ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"` - StateMinerSectors func(context.Context, address.Address, *types.TipSet) ([]*SectorInfo, error) `perm:"read"` - StateMinerProvingSet func(context.Context, address.Address, *types.TipSet) ([]*SectorInfo, error) `perm:"read"` + StateMinerSectors func(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) `perm:"read"` + StateMinerProvingSet func(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) `perm:"read"` StateMinerPower func(context.Context, address.Address, *types.TipSet) (MinerPower, error) `perm:"read"` StateMinerWorker func(context.Context, address.Address, *types.TipSet) (address.Address, error) `perm:"read"` StateMinerPeerID func(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) `perm:"read"` @@ -133,10 +132,11 @@ type StorageMinerStruct struct { StoreGarbageData func(context.Context) error `perm:"write"` - SectorsStatus func(context.Context, uint64) (sectorbuilder.SectorSealingStatus, error) `perm:"read"` - SectorsList func(context.Context) ([]uint64, error) `perm:"read"` + SectorsStatus func(context.Context, uint64) (SectorInfo, error) `perm:"read"` + SectorsList func(context.Context) ([]uint64, error) `perm:"read"` + SectorsRefs func(context.Context) (map[string][]SealedRef, error) `perm:"read"` - SectorsRefs func(context.Context) (map[string][]SealedRef, error) `perm:"read"` + WorkerStats func(context.Context) (WorkerStats, error) `perm:"read"` } } @@ -345,11 +345,11 @@ func (c *FullNodeStruct) SyncSubmitBlock(ctx context.Context, blk *types.BlockMs return c.Internal.SyncSubmitBlock(ctx, blk) } -func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*SectorInfo, error) { +func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*ChainSectorInfo, error) { return c.Internal.StateMinerSectors(ctx, addr, ts) } -func (c *FullNodeStruct) StateMinerProvingSet(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*SectorInfo, error) { +func (c *FullNodeStruct) StateMinerProvingSet(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*ChainSectorInfo, error) { return c.Internal.StateMinerProvingSet(ctx, addr, ts) } @@ -481,7 +481,7 @@ func (c *StorageMinerStruct) StoreGarbageData(ctx context.Context) error { } // Get the status of a given sector by ID -func (c *StorageMinerStruct) SectorsStatus(ctx context.Context, sid uint64) (sectorbuilder.SectorSealingStatus, error) { +func (c *StorageMinerStruct) SectorsStatus(ctx context.Context, sid uint64) (SectorInfo, error) { return c.Internal.SectorsStatus(ctx, sid) } @@ -494,6 +494,10 @@ func (c *StorageMinerStruct) SectorsRefs(ctx context.Context) (map[string][]Seal return c.Internal.SectorsRefs(ctx) } +func (c *StorageMinerStruct) WorkerStats(ctx context.Context) (WorkerStats, error) { + return c.Internal.WorkerStats(ctx) +} + var _ Common = &CommonStruct{} var _ FullNode = &FullNodeStruct{} var _ StorageMiner = &StorageMinerStruct{} diff --git a/build/version.go b/build/version.go index 33109762d..abc715b48 100644 --- a/build/version.go +++ b/build/version.go @@ -1,7 +1,7 @@ package build // Version is the local build version, set by build system -const Version = "0.0.0" +const Version = "0.7.0" // APIVersion is a hex semver version of the rpc api exposed // @@ -12,7 +12,7 @@ const Version = "0.0.0" // R R H // |\vv/| // vv vv -const APIVersion = 0x000001 +const APIVersion = 0x000701 const ( MajorMask = 0xff0000 diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index ecd5acf87..7a89ab8d5 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -157,7 +157,7 @@ func GetMinerProvingPeriodEnd(ctx context.Context, sm *StateManager, ts *types.T return mas.ProvingPeriodEnd, nil } -func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.SectorInfo, error) { +func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.ChainSectorInfo, error) { var mas actors.StorageMinerActorState _, err := sm.LoadActorState(ctx, maddr, &mas, ts) if err != nil { @@ -167,7 +167,7 @@ func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet, return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.ProvingSet) } -func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.SectorInfo, error) { +func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.ChainSectorInfo, error) { var mas actors.StorageMinerActorState _, err := sm.LoadActorState(ctx, maddr, &mas, ts) if err != nil { @@ -213,20 +213,20 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealId uint64, ts *ty return &ocd, nil } -func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid) ([]*api.SectorInfo, error) { +func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid) ([]*api.ChainSectorInfo, error) { blks := amt.WrapBlockstore(bs) a, err := amt.LoadAMT(blks, ssc) if err != nil { return nil, err } - var sset []*api.SectorInfo + var sset []*api.ChainSectorInfo if err := a.ForEach(func(i uint64, v *cbg.Deferred) error { var comms [][]byte if err := cbor.DecodeInto(v.Raw, &comms); err != nil { return err } - sset = append(sset, &api.SectorInfo{ + sset = append(sset, &api.ChainSectorInfo{ SectorID: i, CommR: comms[0], CommD: comms[1], diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 213204a99..00864ed58 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -44,17 +44,18 @@ var infoCmd = &cli.Command{ percI := types.BigDiv(types.BigMul(pow.MinerPower, types.NewInt(1000)), pow.TotalPower) fmt.Printf("Power: %s / %s (%0.2f%%)\n", pow.MinerPower, pow.TotalPower, float64(percI.Int64())/1000*100) + // TODO: indicate whether the post worker is in use + wstat, err := nodeApi.WorkerStats(ctx) + if err != nil { + return err + } + fmt.Printf("Worker use: %d / %d (+%d)", wstat.Total-wstat.Reserved-wstat.Free, wstat.Total, wstat.Reserved) + sinfo, err := sectorsInfo(ctx, nodeApi) if err != nil { return err } - /* - fmt.Println("Sealed Sectors:\t", sinfo.SealedCount) - fmt.Println("Sealing Sectors:\t", sinfo.SealingCount) - fmt.Println("Pending Sectors:\t", sinfo.PendingCount) - fmt.Println("Failed Sectors:\t", sinfo.FailedCount) - */ fmt.Println(sinfo) // TODO: grab actr state / info @@ -80,7 +81,7 @@ func sectorsInfo(ctx context.Context, napi api.StorageMiner) (map[string]int, er return nil, err } - out[st.State.String()]++ + out[api.SectorStateStr(st.State)]++ } return out, nil diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index d49384619..b9075e443 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "github.com/filecoin-project/lotus/api" "strconv" "gopkg.in/urfave/cli.v2" @@ -60,14 +61,15 @@ var sectorsStatusCmd = &cli.Command{ } fmt.Printf("SectorID:\t%d\n", status.SectorID) - fmt.Printf("Status:\t%s\n", status.State.String()) - fmt.Printf("SealErrorMsg:\t%q\n", status.SealErrorMsg) + fmt.Printf("Status:\t%s\n", api.SectorStateStr(status.State)) fmt.Printf("CommD:\t\t%x\n", status.CommD) fmt.Printf("CommR:\t\t%x\n", status.CommR) fmt.Printf("Ticket:\t\t%x\n", status.Ticket.TicketBytes) fmt.Printf("TicketH:\t\t%d\n", status.Ticket.BlockHeight) + fmt.Printf("Seed:\t\t%x\n", status.Seed.TicketBytes) + fmt.Printf("SeedH:\t\t%d\n", status.Seed.BlockHeight) fmt.Printf("Proof:\t\t%x\n", status.Proof) - fmt.Printf("Pieces:\t\t%v\n", status.Pieces) + fmt.Printf("Deals:\t\t%v\n", status.Deals) return nil }, } diff --git a/gen/main.go b/gen/main.go index 2c9292283..b2b0140e7 100644 --- a/gen/main.go +++ b/gen/main.go @@ -152,6 +152,7 @@ func main() { err = gen.WriteTupleEncodersToFile("./storage/cbor_gen.go", "storage", storage.SealTicket{}, + storage.SealSeed{}, storage.Piece{}, storage.SectorInfo{}, ) diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index cc9bcdeea..27b804015 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -110,6 +110,10 @@ func (sb *SectorBuilder) rlimit() func() { } } +func (sb *SectorBuilder) WorkerStats() (free, reserved, total int) { + return cap(sb.rateLimit) - len(sb.rateLimit), PoStReservedWorkers, cap(sb.rateLimit) + PoStReservedWorkers +} + func addressToProverID(a address.Address) [32]byte { var proverId [32]byte copy(proverId[:], a.Payload()) diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 606e3416a..93bc973c1 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -38,11 +38,11 @@ type StateAPI struct { Chain *store.ChainStore } -func (a *StateAPI) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.SectorInfo, error) { +func (a *StateAPI) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) { return stmgr.GetMinerSectorSet(ctx, a.StateManager, ts, addr) } -func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.SectorInfo, error) { +func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) { return stmgr.GetMinerProvingSet(ctx, a.StateManager, ts, addr) } diff --git a/node/impl/storminer.go b/node/impl/storminer.go index e7b081ea6..49c807412 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -21,6 +21,15 @@ type StorageMinerAPI struct { Full api.FullNode } +func (sm *StorageMinerAPI) WorkerStats(context.Context) (api.WorkerStats, error) { + free, reserved, total := sm.SectorBuilder.WorkerStats() + return api.WorkerStats{ + Free: free, + Reserved: reserved, + Total: total, + }, nil +} + func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error) { return sm.SectorBuilderConfig.Miner, nil } @@ -29,13 +38,41 @@ func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) error { return sm.Miner.StoreGarbageData(ctx) } -func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid uint64) (sectorbuilder.SectorSealingStatus, error) { - return sm.SectorBuilder.SealStatus(sid) +func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid uint64) (api.SectorInfo, error) { + info, err := sm.Miner.GetSectorInfo(sid) + if err != nil { + return api.SectorInfo{}, err + } + + deals := make([]uint64, len(info.Pieces)) + for i, piece := range info.Pieces { + deals[i] = piece.DealID + } + + return api.SectorInfo{ + SectorID: sid, + State: info.State, + CommD: info.CommD, + CommR: info.CommR, + Proof: info.Proof, + Deals: deals, + Ticket: info.Ticket.SB(), + Seed: info.Seed.SB(), + }, nil } // List all staged sectors func (sm *StorageMinerAPI) SectorsList(context.Context) ([]uint64, error) { - return sm.SectorBuilder.GetAllStagedSectors() + sectors, err := sm.Miner.ListSectors() + if err != nil { + return nil, err + } + + out := make([]uint64, len(sectors)) + for i, sector := range sectors { + out[i] = sector.SectorID + } + return out, nil } func (sm *StorageMinerAPI) SectorsRefs(context.Context) (map[string][]api.SealedRef, error) { diff --git a/storage/cbor_gen.go b/storage/cbor_gen.go index c84a32590..623cd31a9 100644 --- a/storage/cbor_gen.go +++ b/storage/cbor_gen.go @@ -4,7 +4,6 @@ import ( "fmt" "io" - "github.com/filecoin-project/lotus/chain/types" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" ) @@ -82,6 +81,75 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) error { return nil } +func (t *SealSeed) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{130}); err != nil { + return err + } + + // t.t.BlockHeight (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { + return err + } + + // t.t.TicketBytes ([]uint8) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.TicketBytes)))); err != nil { + return err + } + if _, err := w.Write(t.TicketBytes); err != nil { + return err + } + return nil +} + +func (t *SealSeed) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 2 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.BlockHeight (uint64) (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.BlockHeight = uint64(extra) + // t.t.TicketBytes ([]uint8) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.TicketBytes: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.TicketBytes = make([]byte, extra) + if _, err := io.ReadFull(br, t.TicketBytes); err != nil { + return err + } + return nil +} + func (t *Piece) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) @@ -245,6 +313,14 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } + // t.t.Proof ([]uint8) (slice) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil { + return err + } + if _, err := w.Write(t.Proof); err != nil { + return err + } + // t.t.Ticket (storage.SealTicket) (struct) if err := t.Ticket.MarshalCBOR(w); err != nil { return err @@ -262,13 +338,8 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { } } - // t.t.RandHeight (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.RandHeight))); err != nil { - return err - } - - // t.t.RandTs (types.TipSet) (struct) - if err := t.RandTs.MarshalCBOR(w); err != nil { + // t.t.Seed (storage.SealSeed) (struct) + if err := t.Seed.MarshalCBOR(w); err != nil { return err } @@ -416,6 +487,23 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if _, err := io.ReadFull(br, t.CommRLast); err != nil { return err } + // t.t.Proof ([]uint8) (slice) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.Proof: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.Proof = make([]byte, extra) + if _, err := io.ReadFull(br, t.Proof); err != nil { + return err + } // t.t.Ticket (storage.SealTicket) (struct) { @@ -449,35 +537,13 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { } } - // t.t.RandHeight (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.RandHeight = uint64(extra) - // t.t.RandTs (types.TipSet) (struct) + // t.t.Seed (storage.SealSeed) (struct) { - pb, err := br.PeekByte() - if err != nil { + if err := t.Seed.UnmarshalCBOR(br); err != nil { return err } - if pb == cbg.CborNull[0] { - var nbuf [1]byte - if _, err := br.Read(nbuf[:]); err != nil { - return err - } - } else { - t.RandTs = new(types.TipSet) - if err := t.RandTs.UnmarshalCBOR(br); err != nil { - return err - } - } } // t.t.CommitMessage (cid.Cid) (struct) diff --git a/storage/miner.go b/storage/miner.go index eab867a43..c956fd115 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -56,8 +56,8 @@ type storageMinerApi interface { StateCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) StateMinerProvingPeriodEnd(context.Context, address.Address, *types.TipSet) (uint64, error) - StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.SectorInfo, error) - StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.SectorInfo, error) + StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) + StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error) StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) diff --git a/storage/post.go b/storage/post.go index 0f4c74f38..13a635c0d 100644 --- a/storage/post.go +++ b/storage/post.go @@ -107,7 +107,7 @@ type post struct { ts *types.TipSet // prep - sset []*api.SectorInfo + sset []*api.ChainSectorInfo r []byte // run @@ -277,7 +277,7 @@ func (m *Miner) computePost(ppe uint64) func(ctx context.Context, ts *types.TipS } } -func sectorIdList(si []*api.SectorInfo) []uint64 { +func sectorIdList(si []*api.ChainSectorInfo) []uint64 { out := make([]uint64, len(si)) for i, s := range si { out[i] = s.SectorID diff --git a/storage/sealing.go b/storage/sealing.go index de9586326..232ddf5c4 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -8,7 +8,6 @@ import ( xerrors "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/sectorbuilder" ) @@ -19,12 +18,23 @@ type SealTicket struct { TicketBytes []byte } -func (t *SealTicket) sb() sectorbuilder.SealTicket { +func (t *SealTicket) SB() sectorbuilder.SealTicket { out := sectorbuilder.SealTicket{BlockHeight: t.BlockHeight} copy(out.TicketBytes[:], t.TicketBytes) return out } +type SealSeed struct { + BlockHeight uint64 + TicketBytes []byte +} + +func (t *SealSeed) SB() sectorbuilder.SealSeed { + out := sectorbuilder.SealSeed{BlockHeight: t.BlockHeight} + copy(out.TicketBytes[:], t.TicketBytes) + return out +} + type Piece struct { DealID uint64 Ref string @@ -52,13 +62,13 @@ type SectorInfo struct { CommD []byte CommR []byte CommRLast []byte + Proof []byte Ticket SealTicket PreCommitMessage *cid.Cid // PreCommitted - RandHeight uint64 - RandTs *types.TipSet + Seed SealSeed // Committing CommitMessage *cid.Cid diff --git a/storage/sealing_utils.go b/storage/sealing_utils.go index 17d83abbf..26591e0ac 100644 --- a/storage/sealing_utils.go +++ b/storage/sealing_utils.go @@ -18,3 +18,17 @@ func fillersFromRem(toFill uint64) ([]uint64, error) { } return out, nil } + +func (m *Miner) ListSectors() ([]SectorInfo, error) { + var sectors []SectorInfo + if err := m.sectors.List(§ors); err != nil { + return nil, err + } + return sectors, nil +} + +func (m *Miner) GetSectorInfo(sid uint64) (SectorInfo, error) { + var out SectorInfo + err := m.sectors.Get(sid, &out) + return out, err +} diff --git a/storage/sector_states.go b/storage/sector_states.go index a567f4e65..f94b06072 100644 --- a/storage/sector_states.go +++ b/storage/sector_states.go @@ -145,12 +145,19 @@ func (m *Miner) preCommitted(ctx context.Context, sector SectorInfo) (func(*Sect log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight) err = m.events.ChainAt(func(ctx context.Context, ts *types.TipSet, curH uint64) error { + rand, err := m.api.ChainGetRandomness(ctx, ts, nil, int(ts.Height()-randHeight)) + if err != nil { + return xerrors.Errorf("failed to get randomness for computing seal proof: %w", err) + } + m.sectorUpdated <- sectorUpdate{ newState: api.Committing, id: sector.SectorID, mut: func(info *SectorInfo) { - info.RandHeight = randHeight - info.RandTs = ts + info.Seed = SealSeed{ + BlockHeight: randHeight, + TicketBytes: rand, + } }, } @@ -169,21 +176,13 @@ func (m *Miner) preCommitted(ctx context.Context, sector SectorInfo) (func(*Sect func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*SectorInfo), error) { log.Info("scheduling seal proof computation...") - rand, err := m.api.ChainGetRandomness(ctx, sector.RandTs, nil, int(sector.RandTs.Height()-sector.RandHeight)) - if err != nil { - return nil, xerrors.Errorf("failed to get randomness for computing seal proof: %w", err) - } - - seed := sectorbuilder.SealSeed{ - BlockHeight: sector.RandHeight, - } - copy(seed.TicketBytes[:], rand) - - proof, err := m.sb.SealCommit(sector.SectorID, sector.Ticket.sb(), seed, sector.pieceInfos(), sector.refs(), sector.rspco()) + proof, err := m.sb.SealCommit(sector.SectorID, sector.Ticket.SB(), sector.Seed.SB(), sector.pieceInfos(), sector.refs(), sector.rspco()) if err != nil { return nil, xerrors.Errorf("computing seal proof failed: %w", err) } + // TODO: Consider splitting states and persist proof for faster recovery + params := &actors.SectorProveCommitInfo{ Proof: proof, SectorID: sector.SectorID, @@ -218,7 +217,7 @@ func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*Sector } if mw.Receipt.ExitCode != 0 { - log.Errorf("UNHANDLED: submitting sector proof failed (t:%x; s:%x(%d); p:%x)", sector.Ticket.TicketBytes, rand, sector.RandHeight, params.Proof) + log.Errorf("UNHANDLED: submitting sector proof failed (t:%x; s:%x(%d); p:%x)", sector.Ticket.TicketBytes, sector.Seed.TicketBytes, sector.Seed.BlockHeight, params.Proof) return nil, xerrors.New("UNHANDLED: submitting sector proof failed") } @@ -227,5 +226,6 @@ func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*Sector return func(info *SectorInfo) { mcid := smsg.Cid() info.CommitMessage = &mcid + info.Proof = proof }, nil } From 77dbb6765144229adbdb01bd9eb4c1e541a2b03a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 19:26:04 +0100 Subject: [PATCH 097/114] pond: Update sealing status ids --- lotuspond/front/src/StorageNode.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lotuspond/front/src/StorageNode.js b/lotuspond/front/src/StorageNode.js index ef50c615d..c07abc590 100644 --- a/lotuspond/front/src/StorageNode.js +++ b/lotuspond/front/src/StorageNode.js @@ -8,16 +8,14 @@ const stateConnecting = 'connecting' const stateGettingToken = 'getting-token' let sealCodes = [ - "Unknown", - "AcceptingPieces", - "Committed", - "Committing", - "CommittingPaused", - "Failed", - "FullyPacked", - "PreCommitted", + "Undefined", + "Empty", + "Packing", + "Unsealed", "PreCommitting", - "PreCommittingPaused", + "PreCommitted", + "Committing", + "Proving", ] class StorageNode extends React.Component { From c729cabef156fdd6e9085e41ee0566b3e1e580d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 19:49:36 +0100 Subject: [PATCH 098/114] keep track of last used sector id across restarts --- lib/sectorbuilder/mock.go | 7 ++- lib/sectorbuilder/sectorbuilder.go | 60 ++++++++++++++++++++++--- lib/sectorbuilder/sectorbuilder_test.go | 41 +++++++++++++++-- 3 files changed, 98 insertions(+), 10 deletions(-) diff --git a/lib/sectorbuilder/mock.go b/lib/sectorbuilder/mock.go index 20ec4ac51..58db95d09 100644 --- a/lib/sectorbuilder/mock.go +++ b/lib/sectorbuilder/mock.go @@ -6,9 +6,10 @@ import ( "path/filepath" "github.com/filecoin-project/lotus/chain/address" + "github.com/filecoin-project/lotus/node/modules/dtypes" ) -func TempSectorbuilder(sectorSize uint64) (*SectorBuilder, func(), error) { +func TempSectorbuilder(sectorSize uint64, ds dtypes.MetadataDS) (*SectorBuilder, func(), error) { dir, err := ioutil.TempDir("", "sbtest") if err != nil { return nil, nil, err @@ -34,12 +35,14 @@ func TempSectorbuilder(sectorSize uint64) (*SectorBuilder, func(), error) { WorkerThreads: 2, Miner: addr, - }) + }, ds, nil) if err != nil { return nil, nil, err } return sb, func() { + sb.Destroy() + if err := os.RemoveAll(dir); err != nil { log.Warn("failed to clean up temp sectorbuilder: ", err) } diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 27b804015..bdc8d5a66 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -1,21 +1,30 @@ package sectorbuilder import ( + "context" + "fmt" "io" "os" "sort" + "strconv" + "sync" "unsafe" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/ipfs/go-datastore" logging "github.com/ipfs/go-log" + "go.uber.org/fx" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/address" + "github.com/filecoin-project/lotus/node/modules/dtypes" ) const PoStReservedWorkers = 1 const PoRepProofPartitions = 2 +var lastSectorIdKey = datastore.NewKey("/sectorbuilder/last") + var log = logging.Logger("sectorbuilder") type SectorSealingStatus = sectorbuilder.SectorSealingStatus @@ -42,6 +51,9 @@ const CommLen = sectorbuilder.CommitmentBytesLen type SectorBuilder struct { handle unsafe.Pointer + ds dtypes.MetadataDS + idLk sync.Mutex + ssize uint64 Miner address.Address @@ -65,7 +77,7 @@ type Config struct { MetadataDir string } -func New(cfg *Config) (*SectorBuilder, error) { +func New(cfg *Config, ds dtypes.MetadataDS, lc fx.Lifecycle) (*SectorBuilder, error) { if cfg.WorkerThreads <= PoStReservedWorkers { return nil, xerrors.Errorf("minimum worker threads is %d, specified %d", PoStReservedWorkers+1, cfg.WorkerThreads) } @@ -81,13 +93,29 @@ func New(cfg *Config) (*SectorBuilder, error) { } } - sbp, err := sectorbuilder.InitSectorBuilder(cfg.SectorSize, PoRepProofPartitions, 0, cfg.MetadataDir, proverId, cfg.SealedDir, cfg.StagedDir, cfg.CacheDir, 16, cfg.WorkerThreads) + var lastUsedID uint64 + b, err := ds.Get(lastSectorIdKey) + switch err { + case nil: + i, err := strconv.ParseInt(string(b), 10, 64) + if err != nil { + return nil, err + } + lastUsedID = uint64(i) + case datastore.ErrNotFound: + default: + return nil, err + } + + sbp, err := sectorbuilder.InitSectorBuilder(cfg.SectorSize, PoRepProofPartitions, lastUsedID, cfg.MetadataDir, proverId, cfg.SealedDir, cfg.StagedDir, cfg.CacheDir, 16, cfg.WorkerThreads) if err != nil { return nil, err } - return &SectorBuilder{ + sb := &SectorBuilder{ handle: sbp, + ds: ds, + ssize: cfg.SectorSize, stagedDir: cfg.StagedDir, @@ -96,7 +124,18 @@ func New(cfg *Config) (*SectorBuilder, error) { Miner: cfg.Miner, rateLimit: make(chan struct{}, cfg.WorkerThreads-PoStReservedWorkers), - }, nil + } + + if lc != nil { + lc.Append(fx.Hook{ + OnStop: func(context.Context) error { + sb.Destroy() + return nil + }, + }) + } + + return sb, nil } func (sb *SectorBuilder) rlimit() func() { @@ -125,7 +164,18 @@ func (sb *SectorBuilder) Destroy() { } func (sb *SectorBuilder) AcquireSectorId() (uint64, error) { - return sectorbuilder.AcquireSectorId(sb.handle) + sb.idLk.Lock() + defer sb.idLk.Unlock() + + id, err := sectorbuilder.AcquireSectorId(sb.handle) + if err != nil { + return 0, err + } + err = sb.ds.Put(lastSectorIdKey, []byte(fmt.Sprint(id))) + if err != nil { + return 0, err + } + return id, nil } func (sb *SectorBuilder) AddPiece(pieceSize uint64, sectorId uint64, file io.Reader, existingPieceSizes []uint64) (PublicPieceInfo, error) { diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index 0e399be66..138cd939c 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -6,6 +6,10 @@ import ( "os" "testing" + "github.com/ipfs/go-datastore" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/lib/sectorbuilder" ) @@ -22,12 +26,11 @@ func TestSealAndVerify(t *testing.T) { t.Fatalf("%+v", err) } - sb, cleanup, err := sectorbuilder.TempSectorbuilder(sectorSize) + sb, cleanup, err := sectorbuilder.TempSectorbuilder(sectorSize, datastore.NewMapDatastore()) if err != nil { t.Fatalf("%+v", err) } - _ = cleanup - //defer cleanup() + defer cleanup() dlen := sectorbuilder.UserBytesForSectorSize(sectorSize) @@ -91,3 +94,35 @@ func TestSealAndVerify(t *testing.T) { t.Fatal("bad post") } } + +func TestAcquireID(t *testing.T) { + ds := datastore.NewMapDatastore() + + sb, cleanup, err := sectorbuilder.TempSectorbuilder(sectorSize, ds) + if err != nil { + t.Fatalf("%+v", err) + } + + assertAcquire := func(expect uint64) { + id, err := sb.AcquireSectorId() + require.NoError(t, err) + assert.Equal(t, expect, id) + } + + assertAcquire(1) + assertAcquire(2) + assertAcquire(3) + + cleanup() + + sb, cleanup, err = sectorbuilder.TempSectorbuilder(sectorSize, ds) + if err != nil { + t.Fatalf("%+v", err) + } + + assertAcquire(4) + assertAcquire(5) + assertAcquire(6) + + cleanup() +} From 61505b68022dd89ac0ebf403bee3ad4796b34dcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 19:55:23 +0100 Subject: [PATCH 099/114] Use the same dir in TestAcquireID --- lib/sectorbuilder/mock.go | 23 ++++++++++++++--------- lib/sectorbuilder/sectorbuilder_test.go | 17 +++++++++++++---- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/lib/sectorbuilder/mock.go b/lib/sectorbuilder/mock.go index 58db95d09..481b982b4 100644 --- a/lib/sectorbuilder/mock.go +++ b/lib/sectorbuilder/mock.go @@ -15,9 +15,20 @@ func TempSectorbuilder(sectorSize uint64, ds dtypes.MetadataDS) (*SectorBuilder, return nil, nil, err } + sb, err := TempSectorbuilderDir(dir, sectorSize, ds) + return sb, func() { + sb.Destroy() + + if err := os.RemoveAll(dir); err != nil { + log.Warn("failed to clean up temp sectorbuilder: ", err) + } + }, err +} + +func TempSectorbuilderDir(dir string, sectorSize uint64, ds dtypes.MetadataDS) (*SectorBuilder, error) { addr, err := address.NewFromString("t3vfxagwiegrywptkbmyohqqbfzd7xzbryjydmxso4hfhgsnv6apddyihltsbiikjf3lm7x2myiaxhuc77capq") if err != nil { - return nil, nil, err + return nil, err } metadata := filepath.Join(dir, "meta") @@ -37,14 +48,8 @@ func TempSectorbuilder(sectorSize uint64, ds dtypes.MetadataDS) (*SectorBuilder, Miner: addr, }, ds, nil) if err != nil { - return nil, nil, err + return nil, err } - return sb, func() { - sb.Destroy() - - if err := os.RemoveAll(dir); err != nil { - log.Warn("failed to clean up temp sectorbuilder: ", err) - } - }, nil + return sb, nil } diff --git a/lib/sectorbuilder/sectorbuilder_test.go b/lib/sectorbuilder/sectorbuilder_test.go index 138cd939c..e02368913 100644 --- a/lib/sectorbuilder/sectorbuilder_test.go +++ b/lib/sectorbuilder/sectorbuilder_test.go @@ -2,6 +2,7 @@ package sectorbuilder_test import ( "io" + "io/ioutil" "math/rand" "os" "testing" @@ -98,7 +99,12 @@ func TestSealAndVerify(t *testing.T) { func TestAcquireID(t *testing.T) { ds := datastore.NewMapDatastore() - sb, cleanup, err := sectorbuilder.TempSectorbuilder(sectorSize, ds) + dir, err := ioutil.TempDir("", "sbtest") + if err != nil { + t.Fatal(err) + } + + sb, err := sectorbuilder.TempSectorbuilderDir(dir, sectorSize, ds) if err != nil { t.Fatalf("%+v", err) } @@ -113,9 +119,9 @@ func TestAcquireID(t *testing.T) { assertAcquire(2) assertAcquire(3) - cleanup() + sb.Destroy() - sb, cleanup, err = sectorbuilder.TempSectorbuilder(sectorSize, ds) + sb, err = sectorbuilder.TempSectorbuilderDir(dir, sectorSize, ds) if err != nil { t.Fatalf("%+v", err) } @@ -124,5 +130,8 @@ func TestAcquireID(t *testing.T) { assertAcquire(5) assertAcquire(6) - cleanup() + sb.Destroy() + if err := os.RemoveAll(dir); err != nil { + t.Error(err) + } } From 703781765985afcc117b56e5e6336e3e28f2c11a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 20:22:58 +0100 Subject: [PATCH 100/114] mod tidy --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index 665d7d4be..7e29dcdf1 100644 --- a/go.sum +++ b/go.sum @@ -528,8 +528,6 @@ github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba h1:X4n8JG2e2 github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba/go.mod h1:CHQnYnQUEPydYCwuy8lmTHfGmdw9TKrhWV0xLx8l0oM= github.com/whyrusleeping/cbor-gen v0.0.0-20190910031516-c1cbffdb01bb/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20190917003517-d78d67427694/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= -github.com/whyrusleeping/cbor-gen v0.0.0-20191104210213-4418c8842f0f h1:+GFA37QICd1Axd2n9uzjtvPjxJJI5PU78vpvam+hI4U= -github.com/whyrusleeping/cbor-gen v0.0.0-20191104210213-4418c8842f0f/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20191107223350-6fdade89d679 h1:ct50KYdZHcdOnTAuSgppw5MZKTa3RA63FX28m0l9Aeg= github.com/whyrusleeping/cbor-gen v0.0.0-20191107223350-6fdade89d679/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= From 2c66e20a1e30d55a1bf5fc874dfb407add038865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 20:55:03 +0100 Subject: [PATCH 101/114] padreader: Some more testcases --- lib/padreader/padreader_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/padreader/padreader_test.go b/lib/padreader/padreader_test.go index bf8464806..551393b4e 100644 --- a/lib/padreader/padreader_test.go +++ b/lib/padreader/padreader_test.go @@ -7,6 +7,12 @@ import ( func TestComputePaddedSize(t *testing.T) { assert.Equal(t, uint64(1040384), PaddedSize(1000000)) + assert.Equal(t, uint64(1016), PaddedSize(548)) + assert.Equal(t, uint64(1016), PaddedSize(1015)) + assert.Equal(t, uint64(1016), PaddedSize(1016)) + assert.Equal(t, uint64(2032), PaddedSize(1017)) + + assert.Equal(t, uint64(2032), PaddedSize(1024)) assert.Equal(t, uint64(4064), PaddedSize(2048)) } From ca56299076e9c18a99b6ed6421d0358135a7f229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 21:11:36 +0100 Subject: [PATCH 102/114] circle: force cache refresh --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c1106b210..4f4acb5bb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,14 +24,14 @@ commands: - restore_cache: name: Restore parameters cache keys: - - 'v2-lotus-params-{{ checksum "build/proof-params/parameters.json" }}' - - 'v2-lotus-params-' + - 'v15-lotus-params-{{ checksum "build/proof-params/parameters.json" }}' + - 'v15-lotus-params-' paths: - /var/tmp/filecoin-proof-parameters/ - run: ./lotus fetch-params - save_cache: name: Save parameters cache - key: 'v2-lotus-params-{{ checksum "build/proof-params/parameters.json" }}' + key: 'v15-lotus-params-{{ checksum "build/proof-params/parameters.json" }}' paths: - /var/tmp/filecoin-proof-parameters/ From 8c39486736f45df54ef9487bb945d36b265b53c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 21:11:56 +0100 Subject: [PATCH 103/114] some import fixes --- chain/deals/client_states.go | 5 ++--- chain/events/events_height.go | 3 ++- chain/market/fundmgr.go | 1 + cmd/lotus-storage-miner/sectors.go | 2 +- node/builder.go | 2 +- node/impl/full.go | 8 ++++---- storage/miner.go | 7 +++---- storage/post.go | 3 +-- storage/sector_states.go | 8 ++++---- 9 files changed, 19 insertions(+), 20 deletions(-) diff --git a/chain/deals/client_states.go b/chain/deals/client_states.go index 26ac0ce68..678305c95 100644 --- a/chain/deals/client_states.go +++ b/chain/deals/client_states.go @@ -4,15 +4,14 @@ import ( "bytes" "context" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/lib/cborutil" - "golang.org/x/xerrors" "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/stmgr" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/cborutil" ) type clientHandlerFunc func(ctx context.Context, deal ClientDeal) (func(*ClientDeal), error) diff --git a/chain/events/events_height.go b/chain/events/events_height.go index 3c03f7571..524efd0d5 100644 --- a/chain/events/events_height.go +++ b/chain/events/events_height.go @@ -2,9 +2,10 @@ package events import ( "context" - "go.opencensus.io/trace" "sync" + "go.opencensus.io/trace" + "github.com/filecoin-project/lotus/chain/types" ) diff --git a/chain/market/fundmgr.go b/chain/market/fundmgr.go index 05716a428..9f8068ae2 100644 --- a/chain/market/fundmgr.go +++ b/chain/market/fundmgr.go @@ -52,6 +52,7 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr address.Address, am avail = types.NewInt(0) } fm.available[addr] = avail + fm.lk.Unlock() smsg, err := fm.mpool.MpoolPushMessage(ctx, &types.Message{ diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index b9075e443..627e11c14 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -2,11 +2,11 @@ package main import ( "fmt" - "github.com/filecoin-project/lotus/api" "strconv" "gopkg.in/urfave/cli.v2" + "github.com/filecoin-project/lotus/api" lcli "github.com/filecoin-project/lotus/cli" ) diff --git a/node/builder.go b/node/builder.go index 147366db8..0956a67c1 100644 --- a/node/builder.go +++ b/node/builder.go @@ -3,7 +3,6 @@ package node import ( "context" "errors" - "github.com/filecoin-project/lotus/chain/market" "time" blockstore "github.com/ipfs/go-ipfs-blockstore" @@ -21,6 +20,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain/deals" + "github.com/filecoin-project/lotus/chain/market" "github.com/filecoin-project/lotus/chain/metrics" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/store" diff --git a/node/impl/full.go b/node/impl/full.go index 6ce7fa91e..76cdc5de4 100644 --- a/node/impl/full.go +++ b/node/impl/full.go @@ -2,13 +2,13 @@ package impl import ( "context" - "github.com/filecoin-project/lotus/node/impl/market" - - "github.com/filecoin-project/lotus/node/impl/client" - "github.com/filecoin-project/lotus/node/impl/paych" logging "github.com/ipfs/go-log" + "github.com/filecoin-project/lotus/node/impl/client" + "github.com/filecoin-project/lotus/node/impl/market" + "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" diff --git a/storage/miner.go b/storage/miner.go index c956fd115..5cc8d37ed 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -2,14 +2,11 @@ package storage import ( "context" - "github.com/filecoin-project/lotus/lib/sectorbuilder" "sync" - "github.com/filecoin-project/lotus/lib/statestore" - "github.com/ipfs/go-datastore/namespace" - "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/namespace" logging "github.com/ipfs/go-log" "github.com/libp2p/go-libp2p-core/host" "github.com/pkg/errors" @@ -19,6 +16,8 @@ import ( "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/sectorbuilder" + "github.com/filecoin-project/lotus/lib/statestore" ) var log = logging.Logger("storageminer") diff --git a/storage/post.go b/storage/post.go index 13a635c0d..ad1050dfb 100644 --- a/storage/post.go +++ b/storage/post.go @@ -2,18 +2,17 @@ package storage import ( "context" - "github.com/filecoin-project/lotus/lib/sectorbuilder" "time" "github.com/ipfs/go-cid" "go.opencensus.io/trace" - "golang.org/x/xerrors" "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/types" + "github.com/filecoin-project/lotus/lib/sectorbuilder" ) func (m *Miner) beginPosting(ctx context.Context) { diff --git a/storage/sector_states.go b/storage/sector_states.go index f94b06072..d91e3cead 100644 --- a/storage/sector_states.go +++ b/storage/sector_states.go @@ -2,15 +2,15 @@ package storage import ( "context" - "github.com/filecoin-project/lotus/lib/sectorbuilder" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/types" "github.com/pkg/errors" "golang.org/x/xerrors" "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/types" + "github.com/filecoin-project/lotus/lib/sectorbuilder" ) type providerHandlerFunc func(ctx context.Context, deal SectorInfo) (func(*SectorInfo), error) From aaa073bdf8312a7bbfa6c492e4e4e2113220b567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 21:18:16 +0100 Subject: [PATCH 104/114] deals: Inactive deal in client.sealing is an error --- chain/deals/client_states.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/deals/client_states.go b/chain/deals/client_states.go index 678305c95..c01d0f430 100644 --- a/chain/deals/client_states.go +++ b/chain/deals/client_states.go @@ -195,7 +195,7 @@ func (c *Client) sealing(ctx context.Context, deal ClientDeal) (func(*ClientDeal } if sd.ActivationEpoch == 0 { - return true, nil + return false, xerrors.Errorf("deal wasn't active: deal=%d, parentState=%s, h=%d", deal.DealID, ts.ParentState(), ts.Height()) } log.Infof("Storage deal %d activated at epoch %d", deal.DealID, sd.ActivationEpoch) From f3ae7eb7a3bd2f68ddcf512eb24336012f31e1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 21:25:02 +0100 Subject: [PATCH 105/114] events: Test 2 block tipsets with duplicated message --- chain/events/events_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/chain/events/events_test.go b/chain/events/events_test.go index 27a3edf03..4c5177e1e 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -46,11 +46,24 @@ func (fcs *fakeCS) ChainGetTipSetByHeight(context.Context, uint64, *types.TipSet func makeTs(t *testing.T, h uint64, msgcid cid.Cid) *types.TipSet { a, _ := address.NewFromString("t00") + b, _ := address.NewFromString("t02") ts, err := types.NewTipSet([]*types.BlockHeader{ { Height: h, Miner: a, + Tickets: []*types.Ticket{{[]byte{byte(h % 2)}}}, + + ParentStateRoot: dummyCid, + Messages: msgcid, + ParentMessageReceipts: dummyCid, + }, + { + Height: h, + Miner: b, + + Tickets: []*types.Ticket{{[]byte{byte((h + 1) % 2)}}}, + ParentStateRoot: dummyCid, Messages: msgcid, ParentMessageReceipts: dummyCid, @@ -494,6 +507,7 @@ func TestCalled(t *testing.T) { err = events.Called(func(ts *types.TipSet) (d bool, m bool, e error) { return false, true, nil }, func(msg *types.Message, ts *types.TipSet, curH uint64) (bool, error) { + require.Equal(t, false, applied) applied = true appliedMsg = msg appliedTs = ts From 3d360167df46291c7e4ef5caada9452ba45fd63d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 21:30:50 +0100 Subject: [PATCH 106/114] sectorbuilder: Call destroy in DI module --- lib/sectorbuilder/mock.go | 2 +- lib/sectorbuilder/sectorbuilder.go | 16 +--------------- node/builder.go | 2 +- node/modules/storageminer.go | 16 ++++++++++++++++ 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/lib/sectorbuilder/mock.go b/lib/sectorbuilder/mock.go index 481b982b4..e9661ada1 100644 --- a/lib/sectorbuilder/mock.go +++ b/lib/sectorbuilder/mock.go @@ -46,7 +46,7 @@ func TempSectorbuilderDir(dir string, sectorSize uint64, ds dtypes.MetadataDS) ( WorkerThreads: 2, Miner: addr, - }, ds, nil) + }, ds) if err != nil { return nil, err } diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index bdc8d5a66..9c2b24af2 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -1,7 +1,6 @@ package sectorbuilder import ( - "context" "fmt" "io" "os" @@ -13,7 +12,6 @@ import ( sectorbuilder "github.com/filecoin-project/go-sectorbuilder" "github.com/ipfs/go-datastore" logging "github.com/ipfs/go-log" - "go.uber.org/fx" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/address" @@ -77,7 +75,7 @@ type Config struct { MetadataDir string } -func New(cfg *Config, ds dtypes.MetadataDS, lc fx.Lifecycle) (*SectorBuilder, error) { +func New(cfg *Config, ds dtypes.MetadataDS) (*SectorBuilder, error) { if cfg.WorkerThreads <= PoStReservedWorkers { return nil, xerrors.Errorf("minimum worker threads is %d, specified %d", PoStReservedWorkers+1, cfg.WorkerThreads) } @@ -126,15 +124,6 @@ func New(cfg *Config, ds dtypes.MetadataDS, lc fx.Lifecycle) (*SectorBuilder, er rateLimit: make(chan struct{}, cfg.WorkerThreads-PoStReservedWorkers), } - if lc != nil { - lc.Append(fx.Hook{ - OnStop: func(context.Context) error { - sb.Destroy() - return nil - }, - }) - } - return sb, nil } @@ -196,9 +185,6 @@ func (sb *SectorBuilder) AddPiece(pieceSize uint64, sectorId uint64, file io.Rea if err != nil { return PublicPieceInfo{}, err } - /*if writeUnpadded != pieceSize { - return PublicPieceInfo{}, xerrors.Errorf("writeUnpadded != pieceSize: %d != %d", writeUnpadded, pieceSize) - }*/ if err := stagedFile.Close(); err != nil { return PublicPieceInfo{}, err diff --git a/node/builder.go b/node/builder.go index 0956a67c1..da37bb95f 100644 --- a/node/builder.go +++ b/node/builder.go @@ -230,7 +230,7 @@ func Online() Option { // Storage miner ApplyIf(func(s *Settings) bool { return s.nodeType == repo.RepoStorageMiner }, Override(new(*sectorbuilder.SectorBuilder), sectorbuilder.New), - Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks), + Override(new(*sectorblocks.SectorBlocks), modules.SectorBuilder), Override(new(storage.TicketFn), modules.SealTicketGen), Override(new(*storage.Miner), modules.StorageMiner), diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 3c827c550..0c97710cb 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -176,6 +176,22 @@ func RegisterMiner(lc fx.Lifecycle, ds dtypes.MetadataDS, api api.FullNode) erro return nil } +func SectorBuilder(lc fx.Lifecycle, cfg *sectorbuilder.Config, ds dtypes.MetadataDS) (*sectorbuilder.SectorBuilder, error) { + sb, err := sectorbuilder.New(cfg, ds) + if err != nil { + return nil, err + } + + lc.Append(fx.Hook{ + OnStop: func(context.Context) error { + sb.Destroy() + return nil + }, + }) + + return sb, nil +} + func SealTicketGen(api api.FullNode) storage.TicketFn { return func(ctx context.Context) (*sectorbuilder.SealTicket, error) { ts, err := api.ChainHead(ctx) From d87d8a6db64a9f28a2b84dacffebe11d5e2cf28f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 21:31:48 +0100 Subject: [PATCH 107/114] peermgr: Undisable bootstrap --- peermgr/peermgr.go | 1 - 1 file changed, 1 deletion(-) diff --git a/peermgr/peermgr.go b/peermgr/peermgr.go index 3c4053da1..4ad64a5a1 100644 --- a/peermgr/peermgr.go +++ b/peermgr/peermgr.go @@ -44,7 +44,6 @@ type PeerMgr struct { } func NewPeerMgr(h host.Host, dht *dht.IpfsDHT, bootstrap dtypes.BootstrapPeers) *PeerMgr { - bootstrap = nil pm := &PeerMgr{ h: h, dht: dht, From f89f6e50e33cb2598194e1a6c53c6f56b080e768 Mon Sep 17 00:00:00 2001 From: Friedel Ziegelmayer Date: Fri, 8 Nov 2019 21:39:40 +0100 Subject: [PATCH 108/114] use bigger circleci machines --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fcdf73642..73ed4dd7d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,6 +6,7 @@ executors: golang: docker: - image: circleci/golang:1.13 + resource_class: 2xlarge commands: install-deps: @@ -155,7 +156,7 @@ jobs: workflows: - version: 2 + version: 2.1 ci: jobs: - lint-changes: From 44a512aa20ce5cce1ef601f0b58964b4343777a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 21:46:47 +0100 Subject: [PATCH 109/114] Update go-sectorbuilder with gpu fixes --- extern/go-sectorbuilder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/go-sectorbuilder b/extern/go-sectorbuilder index 181742fdd..e198d9050 160000 --- a/extern/go-sectorbuilder +++ b/extern/go-sectorbuilder @@ -1 +1 @@ -Subproject commit 181742fdd08f74f1c9de54fca0f5658706039bc0 +Subproject commit e198d9050b5dde6c19bef3593506597afe00b6cb From fa67ccb5f35129c7431470722a85ddbd8adca5bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Nov 2019 22:00:01 +0100 Subject: [PATCH 110/114] Fix storageminer sectorblocks constructor --- node/builder.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/builder.go b/node/builder.go index da37bb95f..183472dbc 100644 --- a/node/builder.go +++ b/node/builder.go @@ -229,8 +229,8 @@ func Online() Option { // Storage miner ApplyIf(func(s *Settings) bool { return s.nodeType == repo.RepoStorageMiner }, - Override(new(*sectorbuilder.SectorBuilder), sectorbuilder.New), - Override(new(*sectorblocks.SectorBlocks), modules.SectorBuilder), + Override(new(*sectorbuilder.SectorBuilder), modules.SectorBuilder), + Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks), Override(new(storage.TicketFn), modules.SealTicketGen), Override(new(*storage.Miner), modules.StorageMiner), From aaacfd15cd635c828f1b31adffdd6fc9977577bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 9 Nov 2019 00:06:07 +0100 Subject: [PATCH 111/114] Add comments to fillersFromRem --- node/impl/storminer.go | 2 +- storage/garbage.go | 8 +++++--- storage/sealing_utils.go | 25 ++++++++++++++++++++++++- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 49c807412..f339fd66a 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -35,7 +35,7 @@ func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error } func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) error { - return sm.Miner.StoreGarbageData(ctx) + return sm.Miner.StoreGarbageData() } func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid uint64) (api.SectorInfo, error) { diff --git a/storage/garbage.go b/storage/garbage.go index 28e33e77d..f61ff50cc 100644 --- a/storage/garbage.go +++ b/storage/garbage.go @@ -62,7 +62,6 @@ func (m *Miner) storeGarbage(ctx context.Context, sectorID uint64, existingPiece return nil, xerrors.Errorf("serializing PublishStorageDeals params failed: ", aerr) } - // TODO: We may want this to happen after fetching data smsg, err := m.api.MpoolPushMessage(ctx, &types.Message{ To: actors.StorageMarketAddress, From: m.worker, @@ -112,9 +111,12 @@ func (m *Miner) storeGarbage(ctx context.Context, sectorID uint64, existingPiece return out, nil } -func (m *Miner) StoreGarbageData(_ context.Context) error { - ctx := context.TODO() +func (m *Miner) StoreGarbageData() error { go func() { + ctx := context.TODO() // we can't use the context from command which invokes + // this, as we run everything here async, and it's cancelled when the + // command exits + size := sectorbuilder.UserBytesForSectorSize(m.sb.SectorSize()) sid, err := m.sb.AcquireSectorId() diff --git a/storage/sealing_utils.go b/storage/sealing_utils.go index 26591e0ac..d8d5225bb 100644 --- a/storage/sealing_utils.go +++ b/storage/sealing_utils.go @@ -7,13 +7,36 @@ import ( ) func fillersFromRem(toFill uint64) ([]uint64, error) { - toFill += toFill / 127 // convert to in-sector bytes for easier math + // Convert to in-sector bytes for easier math: + // + // Sector size to user bytes ratio is constant, e.g. for 1024B we have 1016B + // of user-usable data. + // + // (1024/1016 = 128/127) + // + // Given that we can get sector size by simply adding 1/127 of the user + // bytes + // + // (we convert to sector bytes as they are nice round binary numbers) + toFill += toFill / 127 + + // We need to fill the sector with pieces that are powers of 2. Conveniently + // computers store numbers in binary, which means we can look at 1s to get + // all the piece sizes we need to fill the sector. It also means that number + // of pieces is the number of 1s in the number of remaining bytes to fill out := make([]uint64, bits.OnesCount64(toFill)) for i := range out { + // Extract the next lowest non-zero bit next := bits.TrailingZeros64(toFill) psize := uint64(1) << next + // e.g: if the number is 0b010100, psize will be 0b000100 + + // set that bit to 0 by XORing it, so the next iteration looks at the + // next bit toFill ^= psize + + // Add the piece size to the list of pieces we need to create out[i] = sectorbuilder.UserBytesForSectorSize(psize) } return out, nil From 5de600909efede3d4c59a0db36493609701d4e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 9 Nov 2019 00:15:25 +0100 Subject: [PATCH 112/114] Make preparePost more readable Co-Authored-By: Whyrusleeping --- storage/post.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/storage/post.go b/storage/post.go index ad1050dfb..468a010a5 100644 --- a/storage/post.go +++ b/storage/post.go @@ -149,7 +149,9 @@ func (p *post) preparePost(ctx context.Context) error { } p.sset = sset - r, err := p.m.api.ChainGetRandomness(ctx, p.ts, nil, int(int64(p.ts.Height())-int64(p.ppe)+int64(build.PoStChallangeTime)+int64(build.PoStRandomnessLookback))) // TODO: review: check math + // Compute how many blocks back we have to look from the given tipset for the PoSt challenge + challengeLookback := int((int64(p.ts.Height())-int64(p.ppe))+int64(build.PoStChallangeTime)+int64(build.PoStRandomnessLookback)) + r, err := p.m.api.ChainGetRandomness(ctx, p.ts, nil, challengeLookback) if err != nil { return xerrors.Errorf("failed to get chain randomness for post (ts=%d; ppe=%d): %w", p.ts.Height(), p.ppe, err) } From ed64e52e3a5919cc6b3ed6bf982292eff8402ecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 9 Nov 2019 00:20:42 +0100 Subject: [PATCH 113/114] sectorbuilder: apply some review suggestions --- cmd/lotus-storage-miner/info.go | 2 +- lib/sectorbuilder/sectorbuilder.go | 10 +++++----- storage/post.go | 4 +++- storage/sealing.go | 5 +++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 54184a63c..074540faf 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -78,7 +78,7 @@ var Units = []string{"B", "KiB", "MiB", "GiB", "TiB"} func sizeStr(size uint64) string { i := 0 unitSize := float64(size) - for unitSize >= 1024 && i < len(Units) - 1 { + for unitSize >= 1024 && i < len(Units)-1 { unitSize = unitSize / 1024 i++ } diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 9c2b24af2..35f37ac2d 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -49,10 +49,10 @@ const CommLen = sectorbuilder.CommitmentBytesLen type SectorBuilder struct { handle unsafe.Pointer - ds dtypes.MetadataDS - idLk sync.Mutex + ds dtypes.MetadataDS + idLk sync.Mutex - ssize uint64 + ssize uint64 Miner address.Address @@ -112,9 +112,9 @@ func New(cfg *Config, ds dtypes.MetadataDS) (*SectorBuilder, error) { sb := &SectorBuilder{ handle: sbp, - ds: ds, + ds: ds, - ssize: cfg.SectorSize, + ssize: cfg.SectorSize, stagedDir: cfg.StagedDir, sealedDir: cfg.SealedDir, diff --git a/storage/post.go b/storage/post.go index ad1050dfb..3d6ac56b3 100644 --- a/storage/post.go +++ b/storage/post.go @@ -149,7 +149,9 @@ func (p *post) preparePost(ctx context.Context) error { } p.sset = sset - r, err := p.m.api.ChainGetRandomness(ctx, p.ts, nil, int(int64(p.ts.Height())-int64(p.ppe)+int64(build.PoStChallangeTime)+int64(build.PoStRandomnessLookback))) // TODO: review: check math + // Compute how many blocks back we have to look from the given tipset for the PoSt challenge + challengeLookback := int((int64(p.ts.Height()) - int64(p.ppe)) + int64(build.PoStChallangeTime) + int64(build.PoStRandomnessLookback)) + r, err := p.m.api.ChainGetRandomness(ctx, p.ts, nil, challengeLookback) if err != nil { return xerrors.Errorf("failed to get chain randomness for post (ts=%d; ppe=%d): %w", p.ts.Height(), p.ppe, err) } diff --git a/storage/sealing.go b/storage/sealing.go index 232ddf5c4..bffb878b8 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -205,12 +205,14 @@ func (m *Miner) onSectorUpdated(ctx context.Context, update sectorUpdate) { m.handle(ctx, sector, m.preCommitted, api.SectorNoUpdate) case api.Committing: m.handle(ctx, sector, m.committing, api.Proving) + case api.SectorNoUpdate: // noop + default: + log.Error("unexpected sector update state: %d", update.newState) } } func (m *Miner) failSector(id uint64, err error) { log.Errorf("sector %d error: %+v", id, err) - panic(err) // todo: better error handling strategy } func (m *Miner) SealPiece(ctx context.Context, ref string, size uint64, r io.Reader, dealID uint64) (uint64, error) { @@ -231,7 +233,6 @@ func (m *Miner) SealPiece(ctx context.Context, ref string, size uint64, r io.Rea func (m *Miner) newSector(ctx context.Context, sid uint64, dealID uint64, ref string, ppi sectorbuilder.PublicPieceInfo) error { si := &SectorInfo{ - State: api.UndefinedSectorState, SectorID: sid, Pieces: []Piece{ From 47b54206157935af70304ec79f35405ef70c2182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 9 Nov 2019 00:26:53 +0100 Subject: [PATCH 114/114] Revert BlockDelay to 10s --- build/params.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/params.go b/build/params.go index 2fb892379..41d832b5c 100644 --- a/build/params.go +++ b/build/params.go @@ -37,7 +37,7 @@ const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours // Consensus / Network // Seconds -const BlockDelay = 2 +const BlockDelay = 10 // Seconds const AllowableClockDrift = BlockDelay * 2