diff --git a/.gitignore b/.gitignore index fd51881b788..23eca7e42dd 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ /lotus-gateway /lotus-pcr /lotus-wallet +/lotus-keygen /bench.json /lotuspond/front/node_modules /lotuspond/front/build diff --git a/Makefile b/Makefile index ef61583762b..aa7575698a8 100644 --- a/Makefile +++ b/Makefile @@ -204,6 +204,12 @@ lotus-wallet: .PHONY: lotus-wallet BINS+=lotus-wallet +lotus-keygen: + rm -f lotus-keygen + go build -o lotus-keygen ./cmd/lotus-keygen +.PHONY: lotus-keygen +BINS+=lotus-keygen + testground: go build -tags testground -o /dev/null ./cmd/lotus .PHONY: testground diff --git a/api/api_full.go b/api/api_full.go index 1edebc4a644..b91ecd3e79b 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -519,6 +519,8 @@ type FullNode interface { MarketReserveFunds(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error) // MarketReleaseFunds releases funds reserved by MarketReserveFunds MarketReleaseFunds(ctx context.Context, addr address.Address, amt types.BigInt) error + // MarketWithdraw withdraws unlocked funds from the market actor + MarketWithdraw(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) // MethodGroup: Paych // The Paych methods are for interacting with and managing payment channels @@ -592,6 +594,9 @@ type DealInfo struct { CreationTime time.Time Verified bool + + TransferChannelID *datatransfer.ChannelID + DataTransfer *DataTransferChannel } type MsgLookup struct { diff --git a/api/api_storage.go b/api/api_storage.go index a0600a5f42c..85eb03115f9 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -43,6 +43,12 @@ type StorageMiner interface { // List all staged sectors SectorsList(context.Context) ([]abi.SectorNumber, error) + // Get summary info of sectors + SectorsSummary(ctx context.Context) (map[SectorState]int, error) + + // List sectors in particular states + SectorsListInStates(context.Context, []SectorState) ([]abi.SectorNumber, error) + SectorsRefs(context.Context) (map[string][]SealedRef, error) // SectorStartSealing can be called on sectors in Empty or WaitDeals states @@ -106,6 +112,10 @@ type StorageMiner interface { DealsSetConsiderOfflineStorageDeals(context.Context, bool) error DealsConsiderOfflineRetrievalDeals(context.Context) (bool, error) DealsSetConsiderOfflineRetrievalDeals(context.Context, bool) error + DealsConsiderVerifiedStorageDeals(context.Context) (bool, error) + DealsSetConsiderVerifiedStorageDeals(context.Context, bool) error + DealsConsiderUnverifiedStorageDeals(context.Context) (bool, error) + DealsSetConsiderUnverifiedStorageDeals(context.Context, bool) error StorageAddLocal(ctx context.Context, path string) error diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index cca498bf528..6d84675ef26 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -246,6 +246,7 @@ type FullNodeStruct struct { MarketReserveFunds func(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error) `perm:"sign"` MarketReleaseFunds func(ctx context.Context, addr address.Address, amt types.BigInt) error `perm:"sign"` + MarketWithdraw func(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) `perm:"sign"` PaychGet func(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) `perm:"sign"` PaychGetWaitReady func(context.Context, cid.Cid) (address.Address, error) `perm:"sign"` @@ -301,6 +302,8 @@ type StorageMinerStruct struct { SectorsStatus func(ctx context.Context, sid abi.SectorNumber, showOnChainInfo bool) (api.SectorInfo, error) `perm:"read"` SectorsList func(context.Context) ([]abi.SectorNumber, error) `perm:"read"` + SectorsListInStates func(context.Context, []api.SectorState) ([]abi.SectorNumber, error) `perm:"read"` + SectorsSummary func(ctx context.Context) (map[api.SectorState]int, error) `perm:"read"` SectorsRefs func(context.Context) (map[string][]api.SealedRef, error) `perm:"read"` SectorStartSealing func(context.Context, abi.SectorNumber) error `perm:"write"` SectorSetSealDelay func(context.Context, time.Duration) error `perm:"write"` @@ -343,18 +346,22 @@ type StorageMinerStruct struct { StorageLock func(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error `perm:"admin"` StorageTryLock func(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) `perm:"admin"` - DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` - DealsList func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"` - DealsConsiderOnlineStorageDeals func(context.Context) (bool, error) `perm:"read"` - DealsSetConsiderOnlineStorageDeals func(context.Context, bool) error `perm:"admin"` - DealsConsiderOnlineRetrievalDeals func(context.Context) (bool, error) `perm:"read"` - DealsSetConsiderOnlineRetrievalDeals func(context.Context, bool) error `perm:"admin"` - DealsConsiderOfflineStorageDeals func(context.Context) (bool, error) `perm:"read"` - DealsSetConsiderOfflineStorageDeals func(context.Context, bool) error `perm:"admin"` - DealsConsiderOfflineRetrievalDeals func(context.Context) (bool, error) `perm:"read"` - DealsSetConsiderOfflineRetrievalDeals func(context.Context, bool) error `perm:"admin"` - DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"read"` - DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"admin"` + DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` + DealsList func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"` + DealsConsiderOnlineStorageDeals func(context.Context) (bool, error) `perm:"read"` + DealsSetConsiderOnlineStorageDeals func(context.Context, bool) error `perm:"admin"` + DealsConsiderOnlineRetrievalDeals func(context.Context) (bool, error) `perm:"read"` + DealsSetConsiderOnlineRetrievalDeals func(context.Context, bool) error `perm:"admin"` + DealsConsiderOfflineStorageDeals func(context.Context) (bool, error) `perm:"read"` + DealsSetConsiderOfflineStorageDeals func(context.Context, bool) error `perm:"admin"` + DealsConsiderOfflineRetrievalDeals func(context.Context) (bool, error) `perm:"read"` + DealsSetConsiderOfflineRetrievalDeals func(context.Context, bool) error `perm:"admin"` + DealsConsiderVerifiedStorageDeals func(context.Context) (bool, error) `perm:"read"` + DealsSetConsiderVerifiedStorageDeals func(context.Context, bool) error `perm:"admin"` + DealsConsiderUnverifiedStorageDeals func(context.Context) (bool, error) `perm:"read"` + DealsSetConsiderUnverifiedStorageDeals func(context.Context, bool) error `perm:"admin"` + DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"read"` + DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"admin"` StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"` @@ -1149,6 +1156,10 @@ func (c *FullNodeStruct) MarketReleaseFunds(ctx context.Context, addr address.Ad return c.Internal.MarketReleaseFunds(ctx, addr, amt) } +func (c *FullNodeStruct) MarketWithdraw(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) { + return c.Internal.MarketWithdraw(ctx, wallet, addr, amt) +} + func (c *FullNodeStruct) PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) { return c.Internal.PaychGet(ctx, from, to, amt) } @@ -1249,6 +1260,14 @@ func (c *StorageMinerStruct) SectorsList(ctx context.Context) ([]abi.SectorNumbe return c.Internal.SectorsList(ctx) } +func (c *StorageMinerStruct) SectorsListInStates(ctx context.Context, states []api.SectorState) ([]abi.SectorNumber, error) { + return c.Internal.SectorsListInStates(ctx, states) +} + +func (c *StorageMinerStruct) SectorsSummary(ctx context.Context) (map[api.SectorState]int, error) { + return c.Internal.SectorsSummary(ctx) +} + func (c *StorageMinerStruct) SectorsRefs(ctx context.Context) (map[string][]api.SealedRef, error) { return c.Internal.SectorsRefs(ctx) } @@ -1497,6 +1516,22 @@ func (c *StorageMinerStruct) DealsSetConsiderOfflineRetrievalDeals(ctx context.C return c.Internal.DealsSetConsiderOfflineRetrievalDeals(ctx, b) } +func (c *StorageMinerStruct) DealsConsiderVerifiedStorageDeals(ctx context.Context) (bool, error) { + return c.Internal.DealsConsiderVerifiedStorageDeals(ctx) +} + +func (c *StorageMinerStruct) DealsSetConsiderVerifiedStorageDeals(ctx context.Context, b bool) error { + return c.Internal.DealsSetConsiderVerifiedStorageDeals(ctx, b) +} + +func (c *StorageMinerStruct) DealsConsiderUnverifiedStorageDeals(ctx context.Context) (bool, error) { + return c.Internal.DealsConsiderUnverifiedStorageDeals(ctx) +} + +func (c *StorageMinerStruct) DealsSetConsiderUnverifiedStorageDeals(ctx context.Context, b bool) error { + return c.Internal.DealsSetConsiderUnverifiedStorageDeals(ctx, b) +} + func (c *StorageMinerStruct) StorageAddLocal(ctx context.Context, path string) error { return c.Internal.StorageAddLocal(ctx, path) } diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index 074b6a78760..7d3ac4bcf75 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -237,6 +237,10 @@ func init() { addExample(map[abi.SectorNumber]string{ 123: "can't acquire read lock", }) + addExample(map[api.SectorState]int{ + api.SectorState(sealing.Proving): 120, + }) + addExample([]abi.SectorNumber{123, 124}) // worker specific addExample(storiface.AcquireMove) diff --git a/api/types.go b/api/types.go index 1318c7f43f5..28141b83a3f 100644 --- a/api/types.go +++ b/api/types.go @@ -6,7 +6,6 @@ import ( datatransfer "github.com/filecoin-project/go-data-transfer" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/build" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" @@ -51,19 +50,6 @@ type MessageSendSpec struct { MaxFee abi.TokenAmount } -var DefaultMessageSendSpec = MessageSendSpec{ - // MaxFee of 0.1FIL - MaxFee: abi.NewTokenAmount(int64(build.FilecoinPrecision) / 10), -} - -func (ms *MessageSendSpec) Get() MessageSendSpec { - if ms == nil { - return DefaultMessageSendSpec - } - - return *ms -} - type DataTransferChannel struct { TransferID datatransfer.TransferID Status datatransfer.Status diff --git a/chain/events/events.go b/chain/events/events.go index dcdf6c16245..1dcf634231c 100644 --- a/chain/events/events.go +++ b/chain/events/events.go @@ -20,8 +20,10 @@ import ( var log = logging.Logger("events") // HeightHandler `curH`-`ts.Height` = `confidence` -type HeightHandler func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error -type RevertHandler func(ctx context.Context, ts *types.TipSet) error +type ( + HeightHandler func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error + RevertHandler func(ctx context.Context, ts *types.TipSet) error +) type heightHandler struct { confidence int @@ -48,7 +50,7 @@ type Events struct { tsc *tipSetCache lk sync.Mutex - ready sync.WaitGroup + ready chan struct{} readyOnce sync.Once heightEvents @@ -76,15 +78,16 @@ func NewEvents(ctx context.Context, api eventAPI) *Events { }, hcEvents: newHCEvents(ctx, api, tsc, uint64(gcConfidence)), + ready: make(chan struct{}), } - e.ready.Add(1) - go e.listenHeadChanges(ctx) - e.ready.Wait() - - // TODO: cleanup/gc goroutine + // Wait for the first tipset to be seen or bail if shutting down + select { + case <-e.ready: + case <-ctx.Done(): + } return e } @@ -111,13 +114,21 @@ func (e *Events) listenHeadChangesOnce(ctx context.Context) error { notifs, err := e.api.ChainNotify(ctx) if err != nil { - // TODO: retry + // Retry is handled by caller return xerrors.Errorf("listenHeadChanges ChainNotify call failed: %w", err) } - cur, ok := <-notifs // TODO: timeout? - if !ok { - return xerrors.Errorf("notification channel closed") + var cur []*api.HeadChange + var ok bool + + // Wait for first tipset or bail + select { + case cur, ok = <-notifs: + if !ok { + return xerrors.Errorf("notification channel closed") + } + case <-ctx.Done(): + return ctx.Err() } if len(cur) != 1 { @@ -134,8 +145,8 @@ func (e *Events) listenHeadChangesOnce(ctx context.Context) error { e.readyOnce.Do(func() { e.lastTs = cur[0].Val - - e.ready.Done() + // Signal that we have seen first tipset + close(e.ready) }) for notif := range notifs { diff --git a/chain/events/events_height.go b/chain/events/events_height.go index c8dd905d9b1..1fcff9e68f1 100644 --- a/chain/events/events_height.go +++ b/chain/events/events_height.go @@ -153,6 +153,7 @@ func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence best, err := e.tsc.best() if err != nil { + e.lk.Unlock() return xerrors.Errorf("error getting best tipset: %w", err) } @@ -177,6 +178,7 @@ func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence e.lk.Lock() best, err = e.tsc.best() if err != nil { + e.lk.Unlock() return xerrors.Errorf("error getting best tipset: %w", err) } bestH = best.Height() diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index 806882a15f5..5fae5e262d2 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -181,7 +181,20 @@ func ComputeMinRBF(curPrem abi.TokenAmount) abi.TokenAmount { return types.BigAdd(minPrice, types.NewInt(1)) } -func CapGasFee(mff dtypes.DefaultMaxFeeFunc, msg *types.Message, maxFee abi.TokenAmount) { +func CapGasFee(mff dtypes.DefaultMaxFeeFunc, msg *types.Message, sendSepc *api.MessageSendSpec) { + var maxFee abi.TokenAmount + if sendSepc != nil { + maxFee = sendSepc.MaxFee + } + if maxFee.Int == nil || maxFee.Equals(big.Zero()) { + mf, err := mff() + if err != nil { + log.Errorf("failed to get default max gas fee: %+v", err) + mf = big.Zero() + } + maxFee = mf + } + if maxFee.Equals(big.Zero()) { mf, err := mff() if err != nil { @@ -858,7 +871,7 @@ func (mp *MessagePool) PushUntrusted(m *types.SignedMessage) (cid.Cid, error) { }() mp.curTsLk.Lock() - publish, err := mp.addTs(m, mp.curTs, false, true) + publish, err := mp.addTs(m, mp.curTs, true, true) if err != nil { mp.curTsLk.Unlock() return cid.Undef, err diff --git a/chain/messagepool/repub.go b/chain/messagepool/repub.go index cdd169e1d38..5fa68aa539c 100644 --- a/chain/messagepool/repub.go +++ b/chain/messagepool/repub.go @@ -100,7 +100,7 @@ loop: // check the baseFee lower bound -- only republish messages that can be included in the chain // within the next 20 blocks. for _, m := range chain.msgs { - if !allowNegativeChains(ts.Height()) && m.Message.GasFeeCap.LessThan(baseFeeLowerBound) { + if m.Message.GasFeeCap.LessThan(baseFeeLowerBound) { chain.Invalidate() continue loop } @@ -115,7 +115,7 @@ loop: // we can't fit the current chain but there is gas to spare // trim it and push it down - chain.Trim(gasLimit, mp, baseFee, true) + chain.Trim(gasLimit, mp, baseFee) for j := i; j < len(chains)-1; j++ { if chains[j].Before(chains[j+1]) { break diff --git a/chain/messagepool/selection.go b/chain/messagepool/selection.go index 8f33a63644c..17f784d47a1 100644 --- a/chain/messagepool/selection.go +++ b/chain/messagepool/selection.go @@ -10,7 +10,6 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-state-types/abi" tbig "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/lotus/build" @@ -23,12 +22,6 @@ var bigBlockGasLimit = big.NewInt(build.BlockGasLimit) var MaxBlockMessages = 16000 -// this is *temporary* mutilation until we have implemented uncapped miner penalties -- it will go -// away in the next fork. -func allowNegativeChains(epoch abi.ChainEpoch) bool { - return epoch < build.UpgradeBreezeHeight+5 -} - const MaxBlocks = 15 type msgChain struct { @@ -121,7 +114,7 @@ func (mp *MessagePool) selectMessagesOptimal(curTs, ts *types.TipSet, tq float64 return chains[i].Before(chains[j]) }) - if !allowNegativeChains(curTs.Height()) && len(chains) != 0 && chains[0].gasPerf < 0 { + if len(chains) != 0 && chains[0].gasPerf < 0 { log.Warnw("all messages in mpool have non-positive gas performance", "bestGasPerf", chains[0].gasPerf) return result, nil } @@ -174,7 +167,7 @@ func (mp *MessagePool) selectMessagesOptimal(curTs, ts *types.TipSet, tq float64 last := len(chains) for i, chain := range chains { // did we run out of performing chains? - if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 { + if chain.gasPerf < 0 { break } @@ -240,7 +233,7 @@ tailLoop: for gasLimit >= minGas && last < len(chains) { // trim if necessary if chains[last].gasLimit > gasLimit { - chains[last].Trim(gasLimit, mp, baseFee, allowNegativeChains(curTs.Height())) + chains[last].Trim(gasLimit, mp, baseFee) } // push down if it hasn't been invalidated @@ -266,7 +259,7 @@ tailLoop: } // if gasPerf < 0 we have no more profitable chains - if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 { + if chain.gasPerf < 0 { break tailLoop } @@ -307,7 +300,7 @@ tailLoop: } // dependencies fit, just trim it - chain.Trim(gasLimit-depGasLimit, mp, baseFee, allowNegativeChains(curTs.Height())) + chain.Trim(gasLimit-depGasLimit, mp, baseFee) last += i continue tailLoop } @@ -340,7 +333,7 @@ tailLoop: } // is it negative? - if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 { + if chain.gasPerf < 0 { continue } @@ -362,7 +355,7 @@ tailLoop: // do they fit as is? if it doesn't, trim to make it fit if possible if chainGasLimit > gasLimit { - chain.Trim(gasLimit-depGasLimit, mp, baseFee, allowNegativeChains(curTs.Height())) + chain.Trim(gasLimit-depGasLimit, mp, baseFee) if !chain.valid { continue @@ -445,7 +438,7 @@ func (mp *MessagePool) selectMessagesGreedy(curTs, ts *types.TipSet) ([]*types.S return chains[i].Before(chains[j]) }) - if !allowNegativeChains(curTs.Height()) && len(chains) != 0 && chains[0].gasPerf < 0 { + if len(chains) != 0 && chains[0].gasPerf < 0 { log.Warnw("all messages in mpool have non-positive gas performance", "bestGasPerf", chains[0].gasPerf) return result, nil } @@ -456,7 +449,7 @@ func (mp *MessagePool) selectMessagesGreedy(curTs, ts *types.TipSet) ([]*types.S last := len(chains) for i, chain := range chains { // did we run out of performing chains? - if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 { + if chain.gasPerf < 0 { break } @@ -485,7 +478,7 @@ func (mp *MessagePool) selectMessagesGreedy(curTs, ts *types.TipSet) ([]*types.S tailLoop: for gasLimit >= minGas && last < len(chains) { // trim - chains[last].Trim(gasLimit, mp, baseFee, allowNegativeChains(curTs.Height())) + chains[last].Trim(gasLimit, mp, baseFee) // push down if it hasn't been invalidated if chains[last].valid { @@ -505,7 +498,7 @@ tailLoop: } // if gasPerf < 0 we have no more profitable chains - if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 { + if chain.gasPerf < 0 { break tailLoop } @@ -567,7 +560,7 @@ func (mp *MessagePool) selectPriorityMessages(pending map[address.Address]map[ui return chains[i].Before(chains[j]) }) - if !allowNegativeChains(ts.Height()) && len(chains) != 0 && chains[0].gasPerf < 0 { + if len(chains) != 0 && chains[0].gasPerf < 0 { log.Warnw("all priority messages in mpool have negative gas performance", "bestGasPerf", chains[0].gasPerf) return nil, gasLimit } @@ -575,7 +568,7 @@ func (mp *MessagePool) selectPriorityMessages(pending map[address.Address]map[ui // 3. Merge chains until the block limit, as long as they have non-negative gas performance last := len(chains) for i, chain := range chains { - if !allowNegativeChains(ts.Height()) && chain.gasPerf < 0 { + if chain.gasPerf < 0 { break } @@ -593,7 +586,7 @@ func (mp *MessagePool) selectPriorityMessages(pending map[address.Address]map[ui tailLoop: for gasLimit >= minGas && last < len(chains) { // trim, discarding negative performing messages - chains[last].Trim(gasLimit, mp, baseFee, allowNegativeChains(ts.Height())) + chains[last].Trim(gasLimit, mp, baseFee) // push down if it hasn't been invalidated if chains[last].valid { @@ -613,7 +606,7 @@ tailLoop: } // if gasPerf < 0 we have no more profitable chains - if !allowNegativeChains(ts.Height()) && chain.gasPerf < 0 { + if chain.gasPerf < 0 { break tailLoop } @@ -689,6 +682,10 @@ func (*MessagePool) getGasReward(msg *types.SignedMessage, baseFee types.BigInt) } gasReward := tbig.Mul(maxPremium, types.NewInt(uint64(msg.Message.GasLimit))) + if gasReward.Sign() == -1 { + // penalty multiplier + gasReward = tbig.Mul(gasReward, types.NewInt(3)) + } return gasReward.Int } @@ -764,9 +761,6 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6 balance = new(big.Int).Sub(balance, required) value := m.Message.Value.Int - if balance.Cmp(value) < 0 { - break - } balance = new(big.Int).Sub(balance, value) gasReward := mp.getGasReward(m, baseFee) @@ -870,9 +864,9 @@ func (mc *msgChain) Before(other *msgChain) bool { (mc.gasPerf == other.gasPerf && mc.gasReward.Cmp(other.gasReward) > 0) } -func (mc *msgChain) Trim(gasLimit int64, mp *MessagePool, baseFee types.BigInt, allowNegative bool) { +func (mc *msgChain) Trim(gasLimit int64, mp *MessagePool, baseFee types.BigInt) { i := len(mc.msgs) - 1 - for i >= 0 && (mc.gasLimit > gasLimit || (!allowNegative && mc.gasPerf < 0)) { + for i >= 0 && (mc.gasLimit > gasLimit || mc.gasPerf < 0) { gasReward := mp.getGasReward(mc.msgs[i], baseFee) mc.gasReward = new(big.Int).Sub(mc.gasReward, gasReward) mc.gasLimit -= mc.msgs[i].Message.GasLimit diff --git a/chain/messagepool/selection_test.go b/chain/messagepool/selection_test.go index 08cf286c8d8..fb3de7683ce 100644 --- a/chain/messagepool/selection_test.go +++ b/chain/messagepool/selection_test.go @@ -736,8 +736,6 @@ func TestPriorityMessageSelection2(t *testing.T) { } func TestPriorityMessageSelection3(t *testing.T) { - t.Skip("reenable after removing allow negative") - mp, tma := makeTestMpool() // the actors @@ -1241,6 +1239,9 @@ func TestCompetitiveMessageSelectionExp(t *testing.T) { } func TestCompetitiveMessageSelectionZipf(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode") + } var capacityBoost, rewardBoost, tqReward float64 seeds := []int64{1947, 1976, 2020, 2100, 10000, 143324, 432432, 131, 32, 45} for _, seed := range seeds { @@ -1268,9 +1269,9 @@ func TestGasReward(t *testing.T) { GasReward int64 }{ {Premium: 100, FeeCap: 200, BaseFee: 100, GasReward: 100}, - {Premium: 100, FeeCap: 200, BaseFee: 210, GasReward: -10}, + {Premium: 100, FeeCap: 200, BaseFee: 210, GasReward: -10 * 3}, {Premium: 200, FeeCap: 250, BaseFee: 210, GasReward: 40}, - {Premium: 200, FeeCap: 250, BaseFee: 2000, GasReward: -1750}, + {Premium: 200, FeeCap: 250, BaseFee: 2000, GasReward: -1750 * 3}, } mp := new(MessagePool) diff --git a/chain/sub/incoming.go b/chain/sub/incoming.go index f161bca574c..eeaa9af72f5 100644 --- a/chain/sub/incoming.go +++ b/chain/sub/incoming.go @@ -97,6 +97,10 @@ func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *cha log.Warnw("Slow msg fetch", "cid", blk.Header.Cid(), "source", msg.GetFrom(), "msgfetch", took) } if delay := build.Clock.Now().Unix() - int64(blk.Header.Timestamp); delay > 5 { + _ = stats.RecordWithTags(ctx, + []tag.Mutator{tag.Insert(metrics.MinerID, blk.Header.Miner.String())}, + metrics.BlockDelay.M(delay), + ) log.Warnf("Received block with large delay %d from miner %s", delay, blk.Header.Miner) } diff --git a/cli/client.go b/cli/client.go index c3cde8bc39d..129ede94b74 100644 --- a/cli/client.go +++ b/cli/client.go @@ -1429,6 +1429,7 @@ var clientQueryAskCmd = &cli.Command{ afmt.Printf("Price per GiB: %s\n", types.FIL(ask.Price)) afmt.Printf("Verified Price per GiB: %s\n", types.FIL(ask.VerifiedPrice)) afmt.Printf("Max Piece size: %s\n", types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize)))) + afmt.Printf("Min Piece size: %s\n", types.SizeStr(types.NewInt(uint64(ask.MinPieceSize)))) size := cctx.Int64("size") if size == 0 { @@ -1524,7 +1525,7 @@ var clientListDeals = &cli.Command{ } } - return outputStorageDeals(ctx, cctx.App.Writer, api, localDeals, cctx.Bool("verbose"), cctx.Bool("color"), showFailed) + return outputStorageDeals(ctx, cctx.App.Writer, api, localDeals, verbose, color, showFailed) }, } @@ -1566,7 +1567,7 @@ func outputStorageDeals(ctx context.Context, out io.Writer, full lapi.FullNode, if verbose { w := tabwriter.NewWriter(out, 2, 4, 2, ' ', 0) - fmt.Fprintf(w, "Created\tDealCid\tDealId\tProvider\tState\tOn Chain?\tSlashed?\tPieceCID\tSize\tPrice\tDuration\tVerified\tMessage\n") + fmt.Fprintf(w, "Created\tDealCid\tDealId\tProvider\tState\tOn Chain?\tSlashed?\tPieceCID\tSize\tPrice\tDuration\tTransferChannelID\tTransferStatus\tVerified\tMessage\n") for _, d := range deals { onChain := "N" if d.OnChainDealState.SectorStartEpoch != -1 { @@ -1579,7 +1580,37 @@ func outputStorageDeals(ctx context.Context, out io.Writer, full lapi.FullNode, } price := types.FIL(types.BigMul(d.LocalDeal.PricePerEpoch, types.NewInt(d.LocalDeal.Duration))) - fmt.Fprintf(w, "%s\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\t%v\t%s\n", d.LocalDeal.CreationTime.Format(time.Stamp), d.LocalDeal.ProposalCid, d.LocalDeal.DealID, d.LocalDeal.Provider, dealStateString(color, d.LocalDeal.State), onChain, slashed, d.LocalDeal.PieceCID, types.SizeStr(types.NewInt(d.LocalDeal.Size)), price, d.LocalDeal.Duration, d.LocalDeal.Verified, d.LocalDeal.Message) + transferChannelID := "" + if d.LocalDeal.TransferChannelID != nil { + transferChannelID = d.LocalDeal.TransferChannelID.String() + } + transferStatus := "" + if d.LocalDeal.DataTransfer != nil { + transferStatus = datatransfer.Statuses[d.LocalDeal.DataTransfer.Status] + // TODO: Include the transferred percentage once this bug is fixed: + // https://github.com/ipfs/go-graphsync/issues/126 + //fmt.Printf("transferred: %d / size: %d\n", d.LocalDeal.DataTransfer.Transferred, d.LocalDeal.Size) + //if d.LocalDeal.Size > 0 { + // pct := (100 * d.LocalDeal.DataTransfer.Transferred) / d.LocalDeal.Size + // transferPct = fmt.Sprintf("%d%%", pct) + //} + } + fmt.Fprintf(w, "%s\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\t%s\t%s\t%v\t%s\n", + d.LocalDeal.CreationTime.Format(time.Stamp), + d.LocalDeal.ProposalCid, + d.LocalDeal.DealID, + d.LocalDeal.Provider, + dealStateString(color, d.LocalDeal.State), + onChain, + slashed, + d.LocalDeal.PieceCID, + types.SizeStr(types.NewInt(d.LocalDeal.Size)), + price, + d.LocalDeal.Duration, + transferChannelID, + transferStatus, + d.LocalDeal.Verified, + d.LocalDeal.Message) } return w.Flush() } diff --git a/cli/mpool.go b/cli/mpool.go index fe36c0c7d41..a84865547e0 100644 --- a/cli/mpool.go +++ b/cli/mpool.go @@ -49,6 +49,14 @@ var mpoolPending = &cli.Command{ Name: "cids", Usage: "only print cids of messages in output", }, + &cli.StringFlag{ + Name: "to", + Usage: "return messages to a given address", + }, + &cli.StringFlag{ + Name: "from", + Usage: "return messages from a given address", + }, }, Action: func(cctx *cli.Context) error { api, closer, err := GetFullNodeAPI(cctx) @@ -59,6 +67,23 @@ var mpoolPending = &cli.Command{ ctx := ReqContext(cctx) + var toa, froma address.Address + if tos := cctx.String("to"); tos != "" { + a, err := address.NewFromString(tos) + if err != nil { + return fmt.Errorf("given 'to' address %q was invalid: %w", tos, err) + } + toa = a + } + + if froms := cctx.String("from"); froms != "" { + a, err := address.NewFromString(froms) + if err != nil { + return fmt.Errorf("given 'from' address %q was invalid: %w", froms, err) + } + froma = a + } + var filter map[address.Address]struct{} if cctx.Bool("local") { filter = map[address.Address]struct{}{} @@ -85,6 +110,13 @@ var mpoolPending = &cli.Command{ } } + if toa != address.Undef && msg.Message.To != toa { + continue + } + if froma != address.Undef && msg.Message.From != froma { + continue + } + if cctx.Bool("cids") { fmt.Println(msg.Cid()) } else { @@ -446,7 +478,7 @@ var mpoolReplaceCmd = &cli.Command{ return abi.TokenAmount(config.DefaultDefaultMaxFee), nil } - messagepool.CapGasFee(mff, &msg, mss.Get().MaxFee) + messagepool.CapGasFee(mff, &msg, mss) } else { if cctx.IsSet("gas-limit") { msg.GasLimit = cctx.Int64("gas-limit") diff --git a/cli/wallet.go b/cli/wallet.go index f6368cbfa44..e9b8e6ece3e 100644 --- a/cli/wallet.go +++ b/cli/wallet.go @@ -16,11 +16,8 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" - "github.com/filecoin-project/specs-actors/actors/builtin/market" - "github.com/filecoin-project/specs-actors/v2/actors/builtin" - "github.com/filecoin-project/lotus/chain/actors" - types "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/tablewriter" ) @@ -585,27 +582,13 @@ var walletMarketWithdraw = &cli.Command{ return xerrors.Errorf("zero unlocked funds available to withdraw") } - params, err := actors.SerializeParams(&market.WithdrawBalanceParams{ - ProviderOrClientAddress: addr, - Amount: amt, - }) - if err != nil { - return xerrors.Errorf("serializing params: %w", err) - } - fmt.Printf("Submitting WithdrawBalance message for amount %s for address %s\n", types.FIL(amt), from.String()) - smsg, err := api.MpoolPushMessage(ctx, &types.Message{ - To: builtin.StorageMarketActorAddr, - From: from, - Value: types.NewInt(0), - Method: builtin.MethodsMarket.WithdrawBalance, - Params: params, - }, nil) + smsg, err := api.MarketWithdraw(ctx, from, addr, amt) if err != nil { - return xerrors.Errorf("submitting WithdrawBalance message: %w", err) + return xerrors.Errorf("fund manager withdraw error: %w", err) } - fmt.Printf("WithdrawBalance message cid: %s\n", smsg.Cid()) + fmt.Printf("WithdrawBalance message cid: %s\n", smsg) return nil }, diff --git a/cmd/lotus-keygen/main.go b/cmd/lotus-keygen/main.go index d296cb5da70..ebf981e8b7a 100644 --- a/cmd/lotus-keygen/main.go +++ b/cmd/lotus-keygen/main.go @@ -22,6 +22,11 @@ func main() { Value: "bls", Usage: "specify key type to generate (bls or secp256k1)", }, + &cli.StringFlag{ + Name: "out", + Aliases: []string{"o"}, + Usage: "specify key file name to generate", + }, } app.Action = func(cctx *cli.Context) error { memks := wallet.NewMemKeyStore() @@ -50,7 +55,11 @@ func main() { return err } - fi, err := os.Create(fmt.Sprintf("%s.key", kaddr)) + outFile := fmt.Sprintf("%s.key", kaddr) + if cctx.IsSet("out") { + outFile = fmt.Sprintf("%s.key", cctx.String("out")) + } + fi, err := os.Create(outFile) if err != nil { return err } diff --git a/cmd/lotus-shed/cid.go b/cmd/lotus-shed/cid.go index 7839ec601ab..d3bd2c3c9fa 100644 --- a/cmd/lotus-shed/cid.go +++ b/cmd/lotus-shed/cid.go @@ -5,44 +5,78 @@ import ( "encoding/hex" "fmt" - "github.com/urfave/cli/v2" - + "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" mh "github.com/multiformats/go-multihash" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" ) var cidCmd = &cli.Command{ - Name: "cid", + Name: "cid", + Usage: "Cid command", Subcommands: cli.Commands{ cidIdCmd, }, } var cidIdCmd = &cli.Command{ - Name: "id", - Usage: "create identity CID from hex or base64 data", + Name: "id", + Usage: "Create identity CID from hex or base64 data", + ArgsUsage: "[data]", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "encoding", + Value: "base64", + Usage: "specify input encoding to parse", + }, + &cli.StringFlag{ + Name: "codec", + Value: "id", + Usage: "multicodec-packed content types: abi or id", + }, + }, Action: func(cctx *cli.Context) error { if !cctx.Args().Present() { return fmt.Errorf("must specify data") } - dec, err := hex.DecodeString(cctx.Args().First()) - if err != nil { - dec, err = base64.StdEncoding.DecodeString(cctx.Args().First()) + var dec []byte + switch cctx.String("encoding") { + case "base64": + data, err := base64.StdEncoding.DecodeString(cctx.Args().First()) if err != nil { - return err + return xerrors.Errorf("decoding base64 value: %w", err) } - + dec = data + case "hex": + data, err := hex.DecodeString(cctx.Args().First()) + if err != nil { + return xerrors.Errorf("decoding hex value: %w", err) + } + dec = data + default: + return xerrors.Errorf("unrecognized encoding: %s", cctx.String("encoding")) } - builder := cid.V1Builder{Codec: cid.Raw, MhType: mh.IDENTITY} - - c, err := builder.Sum(dec) - if err != nil { - return err + switch cctx.String("codec") { + case "abi": + aCid, err := abi.CidBuilder.Sum(dec) + if err != nil { + return xerrors.Errorf("cidBuilder abi: %w", err) + } + fmt.Println(aCid) + case "id": + builder := cid.V1Builder{Codec: cid.Raw, MhType: mh.IDENTITY} + rCid, err := builder.Sum(dec) + if err != nil { + return xerrors.Errorf("cidBuilder raw: %w", err) + } + fmt.Println(rCid) + default: + return xerrors.Errorf("unrecognized codec: %s", cctx.String("codec")) } - fmt.Println(c) return nil }, } diff --git a/cmd/lotus-shed/sr2-dealstats-rollup.go b/cmd/lotus-shed/sr2-dealstats-rollup.go index e0673013ee5..a2c6d03d936 100644 --- a/cmd/lotus-shed/sr2-dealstats-rollup.go +++ b/cmd/lotus-shed/sr2-dealstats-rollup.go @@ -34,12 +34,14 @@ type competitionTotalOutput struct { Payload competitionTotal `json:"payload"` } type competitionTotal struct { - UniqueCids int `json:"total_unique_cids"` - UniqueProviders int `json:"total_unique_providers"` - UniqueProjects int `json:"total_unique_projects"` - UniqueClients int `json:"total_unique_clients"` - TotalDeals int `json:"total_num_deals"` - TotalBytes int64 `json:"total_stored_data_size"` + UniqueCids int `json:"total_unique_cids"` + UniqueProviders int `json:"total_unique_providers"` + UniqueProjects int `json:"total_unique_projects"` + UniqueClients int `json:"total_unique_clients"` + TotalDeals int `json:"total_num_deals"` + TotalBytes int64 `json:"total_stored_data_size"` + FilplusTotalDeals int `json:"filplus_total_num_deals"` + FilplusTotalBytes int64 `json:"filplus_total_stored_data_size"` seenProject map[string]bool seenClient map[address.Address]bool @@ -245,11 +247,13 @@ var rollupDealStatsCmd = &cli.Command{ for dealID, dealInfo := range deals { - // Counting no-longer-active deals as per Pooja's request - // // https://github.com/filecoin-project/specs-actors/blob/v0.9.9/actors/builtin/market/deal.go#L81-L85 - // if d.State.SectorStartEpoch < 0 { - // continue - // } + // Only count deals that have properly started, not past/future ones + // https://github.com/filecoin-project/specs-actors/blob/v0.9.9/actors/builtin/market/deal.go#L81-L85 + // Bail on 0 as well in case SectorStartEpoch is uninitialized due to some bug + if dealInfo.State.SectorStartEpoch <= 0 || + dealInfo.State.SectorStartEpoch > head.Height() { + continue + } clientAddr, found := resolvedWallets[dealInfo.Proposal.Client] if !found { @@ -269,14 +273,23 @@ var rollupDealStatsCmd = &cli.Command{ unfilteredGrandTotals.seenPieceCid[dealInfo.Proposal.PieceCID] = true unfilteredGrandTotals.TotalDeals++ + if dealInfo.Proposal.VerifiedDeal { + unfilteredGrandTotals.FilplusTotalDeals++ + unfilteredGrandTotals.FilplusTotalBytes += int64(dealInfo.Proposal.PieceSize) + } + + // perl -E 'say scalar gmtime ( 166560 * 30 + 1598306400 )' + // Wed Oct 21 18:00:00 2020 + if dealInfo.Proposal.StartEpoch <= 166560 { + continue + } + projID, projKnown := knownAddrMap[clientAddr] if !projKnown { continue } grandTotals.seenProject[projID] = true - grandTotals.seenClient[clientAddr] = true - projStatEntry, ok := projStats[projID] if !ok { projStatEntry = &projectAggregateStats{ @@ -288,6 +301,11 @@ var rollupDealStatsCmd = &cli.Command{ projStats[projID] = projStatEntry } + if projStatEntry.cidDeals[dealInfo.Proposal.PieceCID] >= 10 { + continue + } + + grandTotals.seenClient[clientAddr] = true clientStatEntry, ok := projStatEntry.ClientStats[clientAddr.String()] if !ok { clientStatEntry = &clientAggregateStats{ @@ -314,6 +332,11 @@ var rollupDealStatsCmd = &cli.Command{ projStatEntry.NumDeals++ clientStatEntry.NumDeals++ + if dealInfo.Proposal.VerifiedDeal { + grandTotals.FilplusTotalDeals++ + grandTotals.FilplusTotalBytes += int64(dealInfo.Proposal.PieceSize) + } + payloadCid := "unknown" if c, err := cid.Parse(dealInfo.Proposal.Label); err == nil { payloadCid = c.String() diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 7bedd2b94a7..ed74da96bf1 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -327,22 +327,18 @@ func init() { } func sectorsInfo(ctx context.Context, napi api.StorageMiner) error { - sectors, err := napi.SectorsList(ctx) + summary, err := napi.SectorsSummary(ctx) if err != nil { return err } - buckets := map[sealing.SectorState]int{ - "Total": len(sectors), - } - for _, s := range sectors { - st, err := napi.SectorsStatus(ctx, s, false) - if err != nil { - return err - } - - buckets[sealing.SectorState(st.State)]++ + buckets := make(map[sealing.SectorState]int) + var total int + for s, c := range summary { + buckets[sealing.SectorState(s)] = c + total += c } + buckets["Total"] = total var sorted []stateMeta for state, i := range buckets { diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 15a3c8b649d..1e5057f5dd1 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -114,6 +114,16 @@ var storageDealSelectionResetCmd = &cli.Command{ return err } + err = smapi.DealsSetConsiderVerifiedStorageDeals(lcli.DaemonContext(cctx), true) + if err != nil { + return err + } + + err = smapi.DealsSetConsiderUnverifiedStorageDeals(lcli.DaemonContext(cctx), true) + if err != nil { + return err + } + return nil }, } @@ -128,6 +138,12 @@ var storageDealSelectionRejectCmd = &cli.Command{ &cli.BoolFlag{ Name: "offline", }, + &cli.BoolFlag{ + Name: "verified", + }, + &cli.BoolFlag{ + Name: "unverified", + }, }, Action: func(cctx *cli.Context) error { smapi, closer, err := lcli.GetStorageMinerAPI(cctx) @@ -150,6 +166,20 @@ var storageDealSelectionRejectCmd = &cli.Command{ } } + if cctx.Bool("verified") { + err = smapi.DealsSetConsiderVerifiedStorageDeals(lcli.DaemonContext(cctx), false) + if err != nil { + return err + } + } + + if cctx.Bool("unverified") { + err = smapi.DealsSetConsiderUnverifiedStorageDeals(lcli.DaemonContext(cctx), false) + if err != nil { + return err + } + } + return nil }, } @@ -421,7 +451,7 @@ func outputStorageDeals(out io.Writer, deals []storagemarket.MinerDeal, verbose w := tabwriter.NewWriter(out, 2, 4, 2, ' ', 0) if verbose { - _, _ = fmt.Fprintf(w, "Creation\tProposalCid\tDealId\tState\tClient\tSize\tPrice\tDuration\tMessage\n") + _, _ = fmt.Fprintf(w, "Creation\tProposalCid\tDealId\tState\tClient\tSize\tPrice\tDuration\tTransferChannelID\tMessage\n") } else { _, _ = fmt.Fprintf(w, "ProposalCid\tDealId\tState\tClient\tSize\tPrice\tDuration\n") } @@ -440,6 +470,11 @@ func outputStorageDeals(out io.Writer, deals []storagemarket.MinerDeal, verbose _, _ = fmt.Fprintf(w, "%s\t%d\t%s\t%s\t%s\t%s\t%s", propcid, deal.DealID, storagemarket.DealStates[deal.State], deal.Proposal.Client, units.BytesSize(float64(deal.Proposal.PieceSize)), fil, deal.Proposal.Duration()) if verbose { + tchid := "" + if deal.TransferChannelId != nil { + tchid = deal.TransferChannelId.String() + } + _, _ = fmt.Fprintf(w, "\t%s", tchid) _, _ = fmt.Fprintf(w, "\t%s", deal.Message) } diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index 37eb062845b..1c3e4858cfa 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -164,6 +164,10 @@ var sectorsListCmd = &cli.Command{ Name: "seal-time", Usage: "display how long it took for the sector to be sealed", }, + &cli.StringFlag{ + Name: "states", + Usage: "filter sectors by a comma-separated list of states", + }, }, Action: func(cctx *cli.Context) error { color.NoColor = !cctx.Bool("color") @@ -182,7 +186,22 @@ var sectorsListCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) - list, err := nodeApi.SectorsList(ctx) + var list []abi.SectorNumber + + showRemoved := cctx.Bool("show-removed") + states := cctx.String("states") + if len(states) == 0 { + list, err = nodeApi.SectorsList(ctx) + } else { + showRemoved = true + sList := strings.Split(states, ",") + ss := make([]api.SectorState, len(sList)) + for i := range sList { + ss[i] = api.SectorState(sList[i]) + } + list, err = nodeApi.SectorsListInStates(ctx, ss) + } + if err != nil { return err } @@ -244,7 +263,7 @@ var sectorsListCmd = &cli.Command{ continue } - if cctx.Bool("show-removed") || st.State != api.SectorState(sealing.Removed) { + if showRemoved || st.State != api.SectorState(sealing.Removed) { _, inSSet := commitedIDs[s] _, inASet := activeIDs[s] diff --git a/documentation/en/api-methods-miner.md b/documentation/en/api-methods-miner.md index 9bad3d424d1..0a6f8ec2715 100644 --- a/documentation/en/api-methods-miner.md +++ b/documentation/en/api-methods-miner.md @@ -20,6 +20,8 @@ * [DealsConsiderOfflineStorageDeals](#DealsConsiderOfflineStorageDeals) * [DealsConsiderOnlineRetrievalDeals](#DealsConsiderOnlineRetrievalDeals) * [DealsConsiderOnlineStorageDeals](#DealsConsiderOnlineStorageDeals) + * [DealsConsiderUnverifiedStorageDeals](#DealsConsiderUnverifiedStorageDeals) + * [DealsConsiderVerifiedStorageDeals](#DealsConsiderVerifiedStorageDeals) * [DealsImportData](#DealsImportData) * [DealsList](#DealsList) * [DealsPieceCidBlocklist](#DealsPieceCidBlocklist) @@ -27,6 +29,8 @@ * [DealsSetConsiderOfflineStorageDeals](#DealsSetConsiderOfflineStorageDeals) * [DealsSetConsiderOnlineRetrievalDeals](#DealsSetConsiderOnlineRetrievalDeals) * [DealsSetConsiderOnlineStorageDeals](#DealsSetConsiderOnlineStorageDeals) + * [DealsSetConsiderUnverifiedStorageDeals](#DealsSetConsiderUnverifiedStorageDeals) + * [DealsSetConsiderVerifiedStorageDeals](#DealsSetConsiderVerifiedStorageDeals) * [DealsSetPieceCidBlocklist](#DealsSetPieceCidBlocklist) * [I](#I) * [ID](#ID) @@ -97,8 +101,10 @@ * [SectorStartSealing](#SectorStartSealing) * [Sectors](#Sectors) * [SectorsList](#SectorsList) + * [SectorsListInStates](#SectorsListInStates) * [SectorsRefs](#SectorsRefs) * [SectorsStatus](#SectorsStatus) + * [SectorsSummary](#SectorsSummary) * [SectorsUpdate](#SectorsUpdate) * [Storage](#Storage) * [StorageAddLocal](#StorageAddLocal) @@ -320,6 +326,24 @@ Inputs: `null` Response: `true` +### DealsConsiderUnverifiedStorageDeals +There are not yet any comments for this method. + +Perms: read + +Inputs: `null` + +Response: `true` + +### DealsConsiderVerifiedStorageDeals +There are not yet any comments for this method. + +Perms: read + +Inputs: `null` + +Response: `true` + ### DealsImportData There are not yet any comments for this method. @@ -411,6 +435,34 @@ Inputs: Response: `{}` +### DealsSetConsiderUnverifiedStorageDeals +There are not yet any comments for this method. + +Perms: admin + +Inputs: +```json +[ + true +] +``` + +Response: `{}` + +### DealsSetConsiderVerifiedStorageDeals +There are not yet any comments for this method. + +Perms: admin + +Inputs: +```json +[ + true +] +``` + +Response: `{}` + ### DealsSetPieceCidBlocklist There are not yet any comments for this method. @@ -1494,7 +1546,34 @@ Perms: read Inputs: `null` -Response: `null` +Response: +```json +[ + 123, + 124 +] +``` + +### SectorsListInStates +List sectors in particular states + + +Perms: read + +Inputs: +```json +[ + null +] +``` + +Response: +```json +[ + 123, + 124 +] +``` ### SectorsRefs There are not yet any comments for this method. @@ -1564,6 +1643,21 @@ Response: } ``` +### SectorsSummary +Get summary info of sectors + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Proving": 120 +} +``` + ### SectorsUpdate There are not yet any comments for this method. diff --git a/documentation/en/api-methods.md b/documentation/en/api-methods.md index 04998b27e4d..9f46460f105 100644 --- a/documentation/en/api-methods.md +++ b/documentation/en/api-methods.md @@ -70,6 +70,7 @@ * [Market](#Market) * [MarketReleaseFunds](#MarketReleaseFunds) * [MarketReserveFunds](#MarketReserveFunds) + * [MarketWithdraw](#MarketWithdraw) * [Miner](#Miner) * [MinerCreateBlock](#MinerCreateBlock) * [MinerGetBaseInfo](#MinerGetBaseInfo) @@ -1033,7 +1034,25 @@ Response: "Duration": 42, "DealID": 5432, "CreationTime": "0001-01-01T00:00:00Z", - "Verified": true + "Verified": true, + "TransferChannelID": { + "Initiator": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Responder": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "ID": 3 + }, + "DataTransfer": { + "TransferID": 3, + "Status": 1, + "BaseCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "IsInitiator": true, + "IsSender": true, + "Voucher": "string value", + "Message": "string value", + "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Transferred": 42 + } } ``` @@ -1085,7 +1104,25 @@ Response: "Duration": 42, "DealID": 5432, "CreationTime": "0001-01-01T00:00:00Z", - "Verified": true + "Verified": true, + "TransferChannelID": { + "Initiator": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Responder": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "ID": 3 + }, + "DataTransfer": { + "TransferID": 3, + "Status": 1, + "BaseCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "IsInitiator": true, + "IsSender": true, + "Voucher": "string value", + "Message": "string value", + "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Transferred": 42 + } } ``` @@ -1636,6 +1673,28 @@ Response: `{}` MarketReserveFunds reserves funds for a deal +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "0" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MarketWithdraw +MarketWithdraw withdraws unlocked funds from the market actor + + Perms: sign Inputs: diff --git a/extern/sector-storage/sealtasks/task.go b/extern/sector-storage/sealtasks/task.go index 4174373a6cf..8dd14ca34c2 100644 --- a/extern/sector-storage/sealtasks/task.go +++ b/extern/sector-storage/sealtasks/task.go @@ -29,18 +29,18 @@ var order = map[TaskType]int{ } var shortNames = map[TaskType]string{ - TTAddPiece: "AP ", + TTAddPiece: "AP", TTPreCommit1: "PC1", TTPreCommit2: "PC2", - TTCommit1: "C1 ", - TTCommit2: "C2 ", + TTCommit1: "C1", + TTCommit2: "C2", TTFinalize: "FIN", TTFetch: "GET", TTUnseal: "UNS", - TTReadUnsealed: "RD ", + TTReadUnsealed: "RD", } func (a TaskType) MuchLess(b TaskType) (bool, bool) { diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index bf66c1bb5cd..4388a2ffbee 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -3,6 +3,7 @@ package stores import ( "context" "encoding/json" + "io" "io/ioutil" "math/bits" "mime" @@ -22,12 +23,13 @@ import ( "github.com/filecoin-project/specs-storage/storage" "github.com/hashicorp/go-multierror" - files "github.com/ipfs/go-ipfs-files" "golang.org/x/xerrors" ) var FetchTempSubdir = "fetching" +var CopyBuf = 1 << 20 + type Remote struct { local *Local index SectorIndex @@ -276,7 +278,16 @@ func (r *Remote) fetch(ctx context.Context, url, outname string) error { case "application/x-tar": return tarutil.ExtractTar(resp.Body, outname) case "application/octet-stream": - return files.WriteTo(files.NewReaderFile(resp.Body), outname) + f, err := os.Create(outname) + if err != nil { + return err + } + _, err = io.CopyBuffer(f, resp.Body, make([]byte, CopyBuf)) + if err != nil { + f.Close() // nolint + return err + } + return f.Close() default: return xerrors.Errorf("unknown content type: '%s'", mediatype) } diff --git a/extern/storage-sealing/garbage.go b/extern/storage-sealing/garbage.go index c3b282d79a5..185bebe3560 100644 --- a/extern/storage-sealing/garbage.go +++ b/extern/storage-sealing/garbage.go @@ -38,7 +38,7 @@ func (m *Sealing) PledgeSector() error { } if cfg.MaxSealingSectors > 0 { - if m.stats.curSealing() > cfg.MaxSealingSectors { + if m.stats.curSealing() >= cfg.MaxSealingSectors { return xerrors.Errorf("too many sectors sealing (curSealing: %d, max: %d)", m.stats.curSealing(), cfg.MaxSealingSectors) } } diff --git a/go.mod b/go.mod index 801042f71f4..e6bc14a1bc7 100644 --- a/go.mod +++ b/go.mod @@ -31,9 +31,9 @@ require ( github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-commp-utils v0.0.0-20201119054358-b88f7a96a434 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 - github.com/filecoin-project/go-data-transfer v1.2.2 + github.com/filecoin-project/go-data-transfer v1.2.3 github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a - github.com/filecoin-project/go-fil-markets v1.0.9 + github.com/filecoin-project/go-fil-markets v1.0.10 github.com/filecoin-project/go-jsonrpc v0.1.2 github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 diff --git a/go.sum b/go.sum index 3d8dad54bde..644904013cf 100644 --- a/go.sum +++ b/go.sum @@ -255,8 +255,8 @@ github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMX github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-data-transfer v1.0.1 h1:5sYKDbstyDsdJpVP4UGUW6+BgCNfgnH8hQgf0E3ZAno= github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= -github.com/filecoin-project/go-data-transfer v1.2.2 h1:zBeUNqSXgYbHqyl3mnwQU5GdOM1h0ecbqc6yvqmHsCQ= -github.com/filecoin-project/go-data-transfer v1.2.2/go.mod h1:ZAH51JZFR8NZC4FPiDPG+swjgui0q6zTMJbztc6pHhY= +github.com/filecoin-project/go-data-transfer v1.2.3 h1:rM/HgGOOMsKvmeQjY7CVR3v7Orxf04LJSSczSpGlhg4= +github.com/filecoin-project/go-data-transfer v1.2.3/go.mod h1:ZAH51JZFR8NZC4FPiDPG+swjgui0q6zTMJbztc6pHhY= github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f h1:GxJzR3oRIMTPtpZ0b7QF8FKPK6/iPAc7trhlL5k/g+s= @@ -264,8 +264,8 @@ github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a h1:hyJ+pUm/4U4RdEZBlg6k8Ma4rDiuvqyGpoICXAxwsTg= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.0.9 h1:bGWo6xoXV9zMPYgbplQDtUREogDuKPiSY1CYwxV5cOY= -github.com/filecoin-project/go-fil-markets v1.0.9/go.mod h1:uOikzYK7aNbSWMczCp6Ru257ML4PplLRBfDk/NAOgaY= +github.com/filecoin-project/go-fil-markets v1.0.10 h1:1QunPsgApTLNXVlaXoPMxyrMtOsMLPOQq3RUjGRmgVI= +github.com/filecoin-project/go-fil-markets v1.0.10/go.mod h1:tcXby9CsTNuHu19dH05YZ5pNDsoYcQXSrbkxzVeMJrY= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= diff --git a/metrics/metrics.go b/metrics/metrics.go index 9f0cad27f76..996fa95b90c 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -19,6 +19,7 @@ var ( Version, _ = tag.NewKey("version") Commit, _ = tag.NewKey("commit") PeerID, _ = tag.NewKey("peer_id") + MinerID, _ = tag.NewKey("miner_id") FailureType, _ = tag.NewKey("failure_type") Local, _ = tag.NewKey("local") MessageFrom, _ = tag.NewKey("message_from") @@ -44,6 +45,7 @@ var ( BlockValidationFailure = stats.Int64("block/failure", "Counter for block validation failures", stats.UnitDimensionless) BlockValidationSuccess = stats.Int64("block/success", "Counter for block validation successes", stats.UnitDimensionless) BlockValidationDurationMilliseconds = stats.Float64("block/validation_ms", "Duration for Block Validation in ms", stats.UnitMilliseconds) + BlockDelay = stats.Int64("block/delay", "Delay of accepted blocks, where delay is >5s", stats.UnitMilliseconds) PeerCount = stats.Int64("peer/count", "Current number of FIL peers", stats.UnitDimensionless) PubsubPublishMessage = stats.Int64("pubsub/published", "Counter for total published messages", stats.UnitDimensionless) PubsubDeliverMessage = stats.Int64("pubsub/delivered", "Counter for total delivered messages", stats.UnitDimensionless) @@ -94,6 +96,24 @@ var ( Measure: BlockValidationDurationMilliseconds, Aggregation: defaultMillisecondsDistribution, } + BlockDelayView = &view.View{ + Measure: BlockDelay, + TagKeys: []tag.Key{MinerID}, + Aggregation: func() *view.Aggregation { + var bounds []float64 + for i := 5; i < 29; i++ { // 5-29s, step 1s + bounds = append(bounds, float64(i*1000)) + } + for i := 30; i < 60; i += 2 { // 30-58s, step 2s + bounds = append(bounds, float64(i*1000)) + } + for i := 60; i <= 300; i += 10 { // 60-300s, step 10s + bounds = append(bounds, float64(i*1000)) + } + bounds = append(bounds, 600*1000) // final cutoff at 10m + return view.Distribution(bounds...) + }(), + } MessagePublishedView = &view.View{ Measure: MessagePublished, Aggregation: view.Count(), @@ -168,6 +188,7 @@ var DefaultViews = append([]*view.View{ BlockValidationFailureView, BlockValidationSuccessView, BlockValidationDurationView, + BlockDelayView, MessagePublishedView, MessageReceivedView, MessageValidationFailureView, diff --git a/node/builder.go b/node/builder.go index 70ce981ad04..8ee9b367440 100644 --- a/node/builder.go +++ b/node/builder.go @@ -395,6 +395,10 @@ func Online() Option { Override(new(dtypes.SetConsiderOfflineStorageDealsConfigFunc), modules.NewSetConsideringOfflineStorageDealsFunc), Override(new(dtypes.ConsiderOfflineRetrievalDealsConfigFunc), modules.NewConsiderOfflineRetrievalDealsConfigFunc), Override(new(dtypes.SetConsiderOfflineRetrievalDealsConfigFunc), modules.NewSetConsiderOfflineRetrievalDealsConfigFunc), + Override(new(dtypes.ConsiderVerifiedStorageDealsConfigFunc), modules.NewConsiderVerifiedStorageDealsConfigFunc), + Override(new(dtypes.SetConsiderVerifiedStorageDealsConfigFunc), modules.NewSetConsideringVerifiedStorageDealsFunc), + Override(new(dtypes.ConsiderUnverifiedStorageDealsConfigFunc), modules.NewConsiderUnverifiedStorageDealsConfigFunc), + Override(new(dtypes.SetConsiderUnverifiedStorageDealsConfigFunc), modules.NewSetConsideringUnverifiedStorageDealsFunc), Override(new(dtypes.SetSealingConfigFunc), modules.NewSetSealConfigFunc), Override(new(dtypes.GetSealingConfigFunc), modules.NewGetSealConfigFunc), Override(new(dtypes.SetExpectedSealDurationFunc), modules.NewSetExpectedSealDurationFunc), diff --git a/node/config/def.go b/node/config/def.go index d857b1c078a..68371c3842a 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -40,12 +40,14 @@ type StorageMiner struct { } type DealmakingConfig struct { - ConsiderOnlineStorageDeals bool - ConsiderOfflineStorageDeals bool - ConsiderOnlineRetrievalDeals bool - ConsiderOfflineRetrievalDeals bool - PieceCidBlocklist []cid.Cid - ExpectedSealDuration Duration + ConsiderOnlineStorageDeals bool + ConsiderOfflineStorageDeals bool + ConsiderOnlineRetrievalDeals bool + ConsiderOfflineRetrievalDeals bool + ConsiderVerifiedStorageDeals bool + ConsiderUnverifiedStorageDeals bool + PieceCidBlocklist []cid.Cid + ExpectedSealDuration Duration Filter string RetrievalFilter string @@ -195,11 +197,13 @@ func DefaultStorageMiner() *StorageMiner { }, Dealmaking: DealmakingConfig{ - ConsiderOnlineStorageDeals: true, - ConsiderOfflineStorageDeals: true, - ConsiderOnlineRetrievalDeals: true, - ConsiderOfflineRetrievalDeals: true, - PieceCidBlocklist: []cid.Cid{}, + ConsiderOnlineStorageDeals: true, + ConsiderOfflineStorageDeals: true, + ConsiderOnlineRetrievalDeals: true, + ConsiderOfflineRetrievalDeals: true, + ConsiderVerifiedStorageDeals: true, + ConsiderUnverifiedStorageDeals: true, + PieceCidBlocklist: []cid.Cid{}, // TODO: It'd be nice to set this based on sector size ExpectedSealDuration: Duration(time.Hour * 24), }, diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 7ecdbc86941..e90a31a80c9 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -184,55 +184,57 @@ func (a *API) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) { return nil, err } + // Get a map of transfer ID => DataTransfer + dataTransfersByID, err := a.transfersByID(ctx) + if err != nil { + return nil, err + } + out := make([]api.DealInfo, len(deals)) for k, v := range deals { - out[k] = api.DealInfo{ - ProposalCid: v.ProposalCid, - DataRef: v.DataRef, - State: v.State, - Message: v.Message, - Provider: v.Proposal.Provider, - - PieceCID: v.Proposal.PieceCID, - Size: uint64(v.Proposal.PieceSize.Unpadded()), - - PricePerEpoch: v.Proposal.StoragePricePerEpoch, - Duration: uint64(v.Proposal.Duration()), - DealID: v.DealID, - CreationTime: v.CreationTime.Time(), - Verified: v.Proposal.VerifiedDeal, + // Find the data transfer associated with this deal + var transferCh *api.DataTransferChannel + if v.TransferChannelID != nil { + if ch, ok := dataTransfersByID[*v.TransferChannelID]; ok { + transferCh = &ch + } } + + out[k] = a.newDealInfoWithTransfer(transferCh, v) } return out, nil } +func (a *API) transfersByID(ctx context.Context) (map[datatransfer.ChannelID]api.DataTransferChannel, error) { + inProgressChannels, err := a.DataTransfer.InProgressChannels(ctx) + if err != nil { + return nil, err + } + + dataTransfersByID := make(map[datatransfer.ChannelID]api.DataTransferChannel, len(inProgressChannels)) + for id, channelState := range inProgressChannels { + ch := api.NewDataTransferChannel(a.Host.ID(), channelState) + dataTransfersByID[id] = ch + } + return dataTransfersByID, nil +} + func (a *API) ClientGetDealInfo(ctx context.Context, d cid.Cid) (*api.DealInfo, error) { v, err := a.SMDealClient.GetLocalDeal(ctx, d) if err != nil { return nil, err } - return &api.DealInfo{ - ProposalCid: v.ProposalCid, - State: v.State, - Message: v.Message, - Provider: v.Proposal.Provider, - PieceCID: v.Proposal.PieceCID, - Size: uint64(v.Proposal.PieceSize.Unpadded()), - PricePerEpoch: v.Proposal.StoragePricePerEpoch, - Duration: uint64(v.Proposal.Duration()), - DealID: v.DealID, - CreationTime: v.CreationTime.Time(), - Verified: v.Proposal.VerifiedDeal, - }, nil + di := a.newDealInfo(ctx, v) + return &di, nil } func (a *API) ClientGetDealUpdates(ctx context.Context) (<-chan api.DealInfo, error) { updates := make(chan api.DealInfo) unsub := a.SMDealClient.SubscribeToEvents(func(_ storagemarket.ClientEvent, deal storagemarket.ClientDeal) { - updates <- newDealInfo(deal) + updates <- a.newDealInfo(ctx, deal) }) go func() { @@ -243,6 +245,41 @@ func (a *API) ClientGetDealUpdates(ctx context.Context) (<-chan api.DealInfo, er return updates, nil } +func (a *API) newDealInfo(ctx context.Context, v storagemarket.ClientDeal) api.DealInfo { + // Find the data transfer associated with this deal + var transferCh *api.DataTransferChannel + if v.TransferChannelID != nil { + state, err := a.DataTransfer.ChannelState(ctx, *v.TransferChannelID) + + // Note: If there was an error just ignore it, as the data transfer may + // be not found if it's no longer active + if err == nil { + ch := api.NewDataTransferChannel(a.Host.ID(), state) + transferCh = &ch + } + } + return a.newDealInfoWithTransfer(transferCh, v) +} + +func (a *API) newDealInfoWithTransfer(transferCh *api.DataTransferChannel, v storagemarket.ClientDeal) api.DealInfo { + return api.DealInfo{ + ProposalCid: v.ProposalCid, + DataRef: v.DataRef, + State: v.State, + Message: v.Message, + Provider: v.Proposal.Provider, + PieceCID: v.Proposal.PieceCID, + Size: uint64(v.Proposal.PieceSize.Unpadded()), + PricePerEpoch: v.Proposal.StoragePricePerEpoch, + Duration: uint64(v.Proposal.Duration()), + DealID: v.DealID, + CreationTime: v.CreationTime.Time(), + Verified: v.Proposal.VerifiedDeal, + TransferChannelID: v.TransferChannelID, + DataTransfer: transferCh, + } +} + func (a *API) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) { // TODO: check if we have the ENTIRE dag @@ -876,23 +913,6 @@ func (a *API) ClientCancelDataTransfer(ctx context.Context, transferID datatrans return a.DataTransfer.CloseDataTransferChannel(ctx, datatransfer.ChannelID{Initiator: otherPeer, Responder: selfPeer, ID: transferID}) } -func newDealInfo(v storagemarket.ClientDeal) api.DealInfo { - return api.DealInfo{ - ProposalCid: v.ProposalCid, - DataRef: v.DataRef, - State: v.State, - Message: v.Message, - Provider: v.Proposal.Provider, - PieceCID: v.Proposal.PieceCID, - Size: uint64(v.Proposal.PieceSize.Unpadded()), - PricePerEpoch: v.Proposal.StoragePricePerEpoch, - Duration: uint64(v.Proposal.Duration()), - DealID: v.DealID, - CreationTime: v.CreationTime.Time(), - Verified: v.Proposal.VerifiedDeal, - } -} - func (a *API) ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error { return a.Retrieval.TryRestartInsufficientFunds(paymentChannel) } diff --git a/node/impl/full/gas.go b/node/impl/full/gas.go index 13c344599d2..189512a65aa 100644 --- a/node/impl/full/gas.go +++ b/node/impl/full/gas.go @@ -301,7 +301,7 @@ func (m *GasModule) GasEstimateMessageGas(ctx context.Context, msg *types.Messag msg.GasFeeCap = feeCap } - messagepool.CapGasFee(m.GetMaxFee, msg, spec.Get().MaxFee) + messagepool.CapGasFee(m.GetMaxFee, msg, spec) return msg, nil } diff --git a/node/impl/market/market.go b/node/impl/market/market.go index 9e75a4db7ce..e7fccc9ba6e 100644 --- a/node/impl/market/market.go +++ b/node/impl/market/market.go @@ -5,10 +5,11 @@ import ( "go.uber.org/fx" + "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/chain/market" "github.com/filecoin-project/lotus/chain/types" - "github.com/ipfs/go-cid" ) type MarketAPI struct { @@ -24,3 +25,7 @@ func (a *MarketAPI) MarketReserveFunds(ctx context.Context, wallet address.Addre func (a *MarketAPI) MarketReleaseFunds(ctx context.Context, addr address.Address, amt types.BigInt) error { return a.FMgr.Release(addr, amt) } + +func (a *MarketAPI) MarketWithdraw(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) { + return a.FMgr.Withdraw(ctx, wallet, addr, amt) +} diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 85d76f35413..7c13283616f 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -61,20 +61,24 @@ type StorageMinerAPI struct { DS dtypes.MetadataDS - ConsiderOnlineStorageDealsConfigFunc dtypes.ConsiderOnlineStorageDealsConfigFunc - SetConsiderOnlineStorageDealsConfigFunc dtypes.SetConsiderOnlineStorageDealsConfigFunc - ConsiderOnlineRetrievalDealsConfigFunc dtypes.ConsiderOnlineRetrievalDealsConfigFunc - SetConsiderOnlineRetrievalDealsConfigFunc dtypes.SetConsiderOnlineRetrievalDealsConfigFunc - StorageDealPieceCidBlocklistConfigFunc dtypes.StorageDealPieceCidBlocklistConfigFunc - SetStorageDealPieceCidBlocklistConfigFunc dtypes.SetStorageDealPieceCidBlocklistConfigFunc - ConsiderOfflineStorageDealsConfigFunc dtypes.ConsiderOfflineStorageDealsConfigFunc - SetConsiderOfflineStorageDealsConfigFunc dtypes.SetConsiderOfflineStorageDealsConfigFunc - ConsiderOfflineRetrievalDealsConfigFunc dtypes.ConsiderOfflineRetrievalDealsConfigFunc - SetConsiderOfflineRetrievalDealsConfigFunc dtypes.SetConsiderOfflineRetrievalDealsConfigFunc - SetSealingConfigFunc dtypes.SetSealingConfigFunc - GetSealingConfigFunc dtypes.GetSealingConfigFunc - GetExpectedSealDurationFunc dtypes.GetExpectedSealDurationFunc - SetExpectedSealDurationFunc dtypes.SetExpectedSealDurationFunc + ConsiderOnlineStorageDealsConfigFunc dtypes.ConsiderOnlineStorageDealsConfigFunc + SetConsiderOnlineStorageDealsConfigFunc dtypes.SetConsiderOnlineStorageDealsConfigFunc + ConsiderOnlineRetrievalDealsConfigFunc dtypes.ConsiderOnlineRetrievalDealsConfigFunc + SetConsiderOnlineRetrievalDealsConfigFunc dtypes.SetConsiderOnlineRetrievalDealsConfigFunc + StorageDealPieceCidBlocklistConfigFunc dtypes.StorageDealPieceCidBlocklistConfigFunc + SetStorageDealPieceCidBlocklistConfigFunc dtypes.SetStorageDealPieceCidBlocklistConfigFunc + ConsiderOfflineStorageDealsConfigFunc dtypes.ConsiderOfflineStorageDealsConfigFunc + SetConsiderOfflineStorageDealsConfigFunc dtypes.SetConsiderOfflineStorageDealsConfigFunc + ConsiderOfflineRetrievalDealsConfigFunc dtypes.ConsiderOfflineRetrievalDealsConfigFunc + SetConsiderOfflineRetrievalDealsConfigFunc dtypes.SetConsiderOfflineRetrievalDealsConfigFunc + ConsiderVerifiedStorageDealsConfigFunc dtypes.ConsiderVerifiedStorageDealsConfigFunc + SetConsiderVerifiedStorageDealsConfigFunc dtypes.SetConsiderVerifiedStorageDealsConfigFunc + ConsiderUnverifiedStorageDealsConfigFunc dtypes.ConsiderUnverifiedStorageDealsConfigFunc + SetConsiderUnverifiedStorageDealsConfigFunc dtypes.SetConsiderUnverifiedStorageDealsConfigFunc + SetSealingConfigFunc dtypes.SetSealingConfigFunc + GetSealingConfigFunc dtypes.GetSealingConfigFunc + GetExpectedSealDurationFunc dtypes.GetExpectedSealDurationFunc + SetExpectedSealDurationFunc dtypes.SetExpectedSealDurationFunc } func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) { @@ -218,6 +222,49 @@ func (sm *StorageMinerAPI) SectorsList(context.Context) ([]abi.SectorNumber, err return out, nil } +func (sm *StorageMinerAPI) SectorsListInStates(ctx context.Context, states []api.SectorState) ([]abi.SectorNumber, error) { + filterStates := make(map[sealing.SectorState]struct{}) + for _, state := range states { + st := sealing.SectorState(state) + if _, ok := sealing.ExistSectorStateList[st]; !ok { + continue + } + filterStates[st] = struct{}{} + } + + var sns []abi.SectorNumber + if len(filterStates) == 0 { + return sns, nil + } + + sectors, err := sm.Miner.ListSectors() + if err != nil { + return nil, err + } + + for i := range sectors { + if _, ok := filterStates[sectors[i].State]; ok { + sns = append(sns, sectors[i].SectorNumber) + } + } + return sns, nil +} + +func (sm *StorageMinerAPI) SectorsSummary(ctx context.Context) (map[api.SectorState]int, error) { + sectors, err := sm.Miner.ListSectors() + if err != nil { + return nil, err + } + + out := make(map[api.SectorState]int) + for i := range sectors { + state := api.SectorState(sectors[i].State) + out[state]++ + } + + return out, nil +} + func (sm *StorageMinerAPI) StorageLocal(ctx context.Context) (map[stores.ID]string, error) { return sm.StorageMgr.StorageLocal(ctx) } @@ -482,6 +529,22 @@ func (sm *StorageMinerAPI) DealsSetConsiderOfflineRetrievalDeals(ctx context.Con return sm.SetConsiderOfflineRetrievalDealsConfigFunc(b) } +func (sm *StorageMinerAPI) DealsConsiderVerifiedStorageDeals(ctx context.Context) (bool, error) { + return sm.ConsiderVerifiedStorageDealsConfigFunc() +} + +func (sm *StorageMinerAPI) DealsSetConsiderVerifiedStorageDeals(ctx context.Context, b bool) error { + return sm.SetConsiderVerifiedStorageDealsConfigFunc(b) +} + +func (sm *StorageMinerAPI) DealsConsiderUnverifiedStorageDeals(ctx context.Context) (bool, error) { + return sm.ConsiderUnverifiedStorageDealsConfigFunc() +} + +func (sm *StorageMinerAPI) DealsSetConsiderUnverifiedStorageDeals(ctx context.Context, b bool) error { + return sm.SetConsiderUnverifiedStorageDealsConfigFunc(b) +} + func (sm *StorageMinerAPI) DealsGetExpectedSealDurationFunc(ctx context.Context) (time.Duration, error) { return sm.GetExpectedSealDurationFunc() } diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index 1ef157b7ed2..16af48add62 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -58,6 +58,22 @@ type ConsiderOfflineRetrievalDealsConfigFunc func() (bool, error) // disable or enable retrieval deal acceptance. type SetConsiderOfflineRetrievalDealsConfigFunc func(bool) error +// ConsiderVerifiedStorageDealsConfigFunc is a function which reads from miner +// config to determine if the user has disabled verified storage deals (or not). +type ConsiderVerifiedStorageDealsConfigFunc func() (bool, error) + +// SetConsiderVerifiedStorageDealsConfigFunc is a function which is used to +// disable or enable verified storage deal acceptance. +type SetConsiderVerifiedStorageDealsConfigFunc func(bool) error + +// ConsiderUnverifiedStorageDealsConfigFunc is a function which reads from miner +// config to determine if the user has disabled unverified storage deals (or not). +type ConsiderUnverifiedStorageDealsConfigFunc func() (bool, error) + +// SetConsiderUnverifiedStorageDealsConfigFunc is a function which is used to +// disable or enable unverified storage deal acceptance. +type SetConsiderUnverifiedStorageDealsConfigFunc func(bool) error + // SetSealingDelay sets how long a sector waits for more deals before sealing begins. type SetSealingConfigFunc func(sealiface.Config) error diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index cc6f3346d8e..30f84aeaff8 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -461,11 +461,15 @@ func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.Metadat func BasicDealFilter(user dtypes.StorageDealFilter) func(onlineOk dtypes.ConsiderOnlineStorageDealsConfigFunc, offlineOk dtypes.ConsiderOfflineStorageDealsConfigFunc, + verifiedOk dtypes.ConsiderVerifiedStorageDealsConfigFunc, + unverifiedOk dtypes.ConsiderUnverifiedStorageDealsConfigFunc, blocklistFunc dtypes.StorageDealPieceCidBlocklistConfigFunc, expectedSealTimeFunc dtypes.GetExpectedSealDurationFunc, spn storagemarket.StorageProviderNode) dtypes.StorageDealFilter { return func(onlineOk dtypes.ConsiderOnlineStorageDealsConfigFunc, offlineOk dtypes.ConsiderOfflineStorageDealsConfigFunc, + verifiedOk dtypes.ConsiderVerifiedStorageDealsConfigFunc, + unverifiedOk dtypes.ConsiderUnverifiedStorageDealsConfigFunc, blocklistFunc dtypes.StorageDealPieceCidBlocklistConfigFunc, expectedSealTimeFunc dtypes.GetExpectedSealDurationFunc, spn storagemarket.StorageProviderNode) dtypes.StorageDealFilter { @@ -491,6 +495,26 @@ func BasicDealFilter(user dtypes.StorageDealFilter) func(onlineOk dtypes.Conside return false, "miner is not accepting offline storage deals", nil } + b, err = verifiedOk() + if err != nil { + return false, "miner error", err + } + + if deal.Proposal.VerifiedDeal && !b { + log.Warnf("verified storage deal consideration disabled; rejecting storage deal proposal from client: %s", deal.Client.String()) + return false, "miner is not accepting verified storage deals", nil + } + + b, err = unverifiedOk() + if err != nil { + return false, "miner error", err + } + + if !deal.Proposal.VerifiedDeal && !b { + log.Warnf("unverified storage deal consideration disabled; rejecting storage deal proposal from client: %s", deal.Client.String()) + return false, "miner is not accepting unverified storage deals", nil + } + blocklist, err := blocklistFunc() if err != nil { return false, "miner error", err @@ -737,6 +761,42 @@ func NewSetConsiderOfflineRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.Se }, nil } +func NewConsiderVerifiedStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.ConsiderVerifiedStorageDealsConfigFunc, error) { + return func() (out bool, err error) { + err = readCfg(r, func(cfg *config.StorageMiner) { + out = cfg.Dealmaking.ConsiderVerifiedStorageDeals + }) + return + }, nil +} + +func NewSetConsideringVerifiedStorageDealsFunc(r repo.LockedRepo) (dtypes.SetConsiderVerifiedStorageDealsConfigFunc, error) { + return func(b bool) (err error) { + err = mutateCfg(r, func(cfg *config.StorageMiner) { + cfg.Dealmaking.ConsiderVerifiedStorageDeals = b + }) + return + }, nil +} + +func NewConsiderUnverifiedStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.ConsiderUnverifiedStorageDealsConfigFunc, error) { + return func() (out bool, err error) { + err = readCfg(r, func(cfg *config.StorageMiner) { + out = cfg.Dealmaking.ConsiderUnverifiedStorageDeals + }) + return + }, nil +} + +func NewSetConsideringUnverifiedStorageDealsFunc(r repo.LockedRepo) (dtypes.SetConsiderUnverifiedStorageDealsConfigFunc, error) { + return func(b bool) (err error) { + err = mutateCfg(r, func(cfg *config.StorageMiner) { + cfg.Dealmaking.ConsiderUnverifiedStorageDeals = b + }) + return + }, nil +} + func NewSetSealConfigFunc(r repo.LockedRepo) (dtypes.SetSealingConfigFunc, error) { return func(cfg sealiface.Config) (err error) { err = mutateCfg(r, func(c *config.StorageMiner) { diff --git a/storage/addresses.go b/storage/addresses.go index 1abc8a8399b..5da8643cd93 100644 --- a/storage/addresses.go +++ b/storage/addresses.go @@ -71,7 +71,8 @@ func pickAddress(ctx context.Context, a addrSelectApi, mi miner.MinerInfo, goodF for _, addr := range addrs { if addr.Protocol() != address.ID { - addr, err := a.StateLookupID(ctx, addr, types.EmptyTSK) + var err error + addr, err = a.StateLookupID(ctx, addr, types.EmptyTSK) if err != nil { log.Warnw("looking up control address", "address", addr, "error", err) continue diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index cbc07cf774d..346ffc38d87 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -812,7 +812,7 @@ func (s *WindowPoStScheduler) setSender(ctx context.Context, msg *types.Message, return msg.RequiredFunds(), nil } - messagepool.CapGasFee(mff, msg, big.Min(big.Sub(avail, msg.Value), msg.RequiredFunds())) + messagepool.CapGasFee(mff, msg, &api.MessageSendSpec{MaxFee: big.Min(big.Sub(avail, msg.Value), msg.RequiredFunds())}) } return nil } diff --git a/testplans/lotus-soup/go.mod b/testplans/lotus-soup/go.mod index 97d0d25e8c3..4fc8f9adca9 100644 --- a/testplans/lotus-soup/go.mod +++ b/testplans/lotus-soup/go.mod @@ -8,11 +8,11 @@ require ( github.com/davecgh/go-spew v1.1.1 github.com/drand/drand v1.2.1 github.com/filecoin-project/go-address v0.0.5-0.20201103152444-f2023ef3f5bb - github.com/filecoin-project/go-fil-markets v1.0.9 + github.com/filecoin-project/go-fil-markets v1.0.10 github.com/filecoin-project/go-jsonrpc v0.1.2 github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/lotus v1.2.3-0.20201203180119-b13226bc2f8a + github.com/filecoin-project/lotus v1.2.3-rc1 github.com/filecoin-project/specs-actors v0.9.13 github.com/google/uuid v1.1.2 github.com/gorilla/mux v1.7.4 diff --git a/testplans/lotus-soup/go.sum b/testplans/lotus-soup/go.sum index 4985a2a7215..ccade75511a 100644 --- a/testplans/lotus-soup/go.sum +++ b/testplans/lotus-soup/go.sum @@ -253,26 +253,20 @@ github.com/filecoin-project/go-commp-utils v0.0.0-20201119054358-b88f7a96a434/go github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= -github.com/filecoin-project/go-data-transfer v1.2.0 h1:LM+K+J+y9t8e3gYskJHWDlyHJsF6aaxoHOP+HIiVE1U= -github.com/filecoin-project/go-data-transfer v1.2.0/go.mod h1:ZAH51JZFR8NZC4FPiDPG+swjgui0q6zTMJbztc6pHhY= -github.com/filecoin-project/go-data-transfer v1.2.2 h1:zBeUNqSXgYbHqyl3mnwQU5GdOM1h0ecbqc6yvqmHsCQ= -github.com/filecoin-project/go-data-transfer v1.2.2/go.mod h1:ZAH51JZFR8NZC4FPiDPG+swjgui0q6zTMJbztc6pHhY= +github.com/filecoin-project/go-data-transfer v1.2.3 h1:rM/HgGOOMsKvmeQjY7CVR3v7Orxf04LJSSczSpGlhg4= +github.com/filecoin-project/go-data-transfer v1.2.3/go.mod h1:ZAH51JZFR8NZC4FPiDPG+swjgui0q6zTMJbztc6pHhY= github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a h1:hyJ+pUm/4U4RdEZBlg6k8Ma4rDiuvqyGpoICXAxwsTg= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.0.6 h1:JTZBMKJ19YpK/vQfE0rHvjELy83NeGor5d4dBnoIlK0= -github.com/filecoin-project/go-fil-markets v1.0.6/go.mod h1:iVYc+VrHIP15F5COkHNM6ndTwKSJ7qPrHSKCfFUnve4= -github.com/filecoin-project/go-fil-markets v1.0.9 h1:bGWo6xoXV9zMPYgbplQDtUREogDuKPiSY1CYwxV5cOY= -github.com/filecoin-project/go-fil-markets v1.0.9/go.mod h1:uOikzYK7aNbSWMczCp6Ru257ML4PplLRBfDk/NAOgaY= +github.com/filecoin-project/go-fil-markets v1.0.10 h1:1QunPsgApTLNXVlaXoPMxyrMtOsMLPOQq3RUjGRmgVI= +github.com/filecoin-project/go-fil-markets v1.0.10/go.mod h1:tcXby9CsTNuHu19dH05YZ5pNDsoYcQXSrbkxzVeMJrY= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0/go.mod h1:7aWZdaQ1b16BVoQUYR+eEvrDCGJoPLxFpDynFjYfBjI= -github.com/filecoin-project/go-jsonrpc v0.1.2-0.20201116213214-f4b2d34247f0 h1:kCIWv46+RUz45DfQdBTaYOmduwN/iH4dghYDTcyCgg4= -github.com/filecoin-project/go-jsonrpc v0.1.2-0.20201116213214-f4b2d34247f0/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4= github.com/filecoin-project/go-jsonrpc v0.1.2 h1:MTebUawBHLxxY9gDi1WXuGc89TWIDmsgoDqeZSk9KRw= github.com/filecoin-project/go-jsonrpc v0.1.2/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4= github.com/filecoin-project/go-multistore v0.0.3 h1:vaRBY4YiA2UZFPK57RNuewypB8u0DzzQwqsL0XarpnI= @@ -292,10 +286,8 @@ github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIi github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= -github.com/filecoin-project/lotus v1.2.2-0.20201124170156-a63ef1dcd549 h1:UARzSYIqLp3iWll5jvKou7FlmWLEOXaD7oSn7v2weFw= -github.com/filecoin-project/lotus v1.2.2-0.20201124170156-a63ef1dcd549/go.mod h1:FmonhOzKsTw8ZskZ5+KmnQ8ItfmDU9LKd+do1RQeUtc= -github.com/filecoin-project/lotus v1.2.3-0.20201203180119-b13226bc2f8a h1:6MFggvhF8lYDv52YkA1I+SSA+uqDTjKegJIt7/0Akik= -github.com/filecoin-project/lotus v1.2.3-0.20201203180119-b13226bc2f8a/go.mod h1:B0WNVsbj9RNHD7bKc/xhZ/MVsex+9A/XGLJ5wUYZfHA= +github.com/filecoin-project/lotus v1.2.3-rc1 h1:sIkyKT54lozAUGl70C/aYn33/zEGtEfkR5yG59VNgPw= +github.com/filecoin-project/lotus v1.2.3-rc1/go.mod h1:7unujOylpjY33Vhq+/RHRKzGUvWk8I3XIHlSN7LwLoA= github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4= github.com/filecoin-project/specs-actors v0.9.12/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= github.com/filecoin-project/specs-actors v0.9.13 h1:rUEOQouefi9fuVY/2HOroROJlZbOzWYXXeIh41KF2M4= @@ -580,7 +572,6 @@ github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28 github.com/ipfs/go-graphsync v0.1.0/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE= github.com/ipfs/go-graphsync v0.4.2/go.mod h1:/VmbZTUdUMTbNkgzAiCEucIIAU3BkLE2cZrDCVUhyi0= github.com/ipfs/go-graphsync v0.4.3/go.mod h1:mPOwDYv128gf8gxPFgXnz4fNrSYPsWyqisJ7ych+XDY= -github.com/ipfs/go-graphsync v0.5.0 h1:iaByvxq88Ys1KcaQzTS1wmRhNsNEo3SaUiSGqTSbGmM= github.com/ipfs/go-graphsync v0.5.0/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= github.com/ipfs/go-graphsync v0.5.1 h1:4fXBRvRKicTgTmCFMmEua/H5jvmAOLgU9Z7PCPWt2ec= github.com/ipfs/go-graphsync v0.5.1/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk=