From 5454aebf13a563ddb55a5790e29b91190e0f7b22 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 17 Nov 2021 15:39:45 +0200 Subject: [PATCH] CLI tools for the DAGStore inverted index (#7361) * cli commands for dagstore * address comments from Dirk * rename inverted index to piece index --- api/api_storage.go | 8 +- api/proxy_gen.go | 28 ++++- build/openrpc/full.json.gz | Bin 25453 -> 25456 bytes build/openrpc/miner.json.gz | Bin 10575 -> 10721 bytes build/openrpc/worker.json.gz | Bin 2713 -> 2710 bytes cmd/lotus-miner/dagstore.go | 148 ++++++++++++++++++----- documentation/en/api-v0-methods-miner.md | 31 ++++- documentation/en/cli-lotus-miner.md | 30 +++++ node/impl/storminer.go | 51 ++++++++ 9 files changed, 261 insertions(+), 35 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index fc2f58a26..21c2d9688 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -212,7 +212,13 @@ type StorageMiner interface { // IndexerAnnounceDeal informs indexer nodes that a new deal was received, // so they can download its index - IndexerAnnounceDeal(ctx context.Context, proposalCid cid.Cid) error + IndexerAnnounceDeal(ctx context.Context, proposalCid cid.Cid) error //perm:admin + + // DagstorePieceIndexSize returns the size of the piece index. + DagstorePieceIndexSize(ctx context.Context) (int64, error) //perm:admin + + // DagstoreLookupPieces returns information about shards that contain the given CID. + DagstoreLookupPieces(ctx context.Context, cid cid.Cid) ([]DagstoreShardInfo, error) //perm:admin // RuntimeSubsystems returns the subsystems that are enabled // in this instance. diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 0ce7ee8dd..06b3a1662 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -623,6 +623,10 @@ type StorageMinerStruct struct { DagstoreListShards func(p0 context.Context) ([]DagstoreShardInfo, error) `perm:"read"` + DagstoreLookupPieces func(p0 context.Context, p1 cid.Cid) ([]DagstoreShardInfo, error) `perm:"admin"` + + DagstorePieceIndexSize func(p0 context.Context) (int64, error) `perm:"admin"` + DagstoreRecoverShard func(p0 context.Context, p1 string) error `perm:"write"` DealsConsiderOfflineRetrievalDeals func(p0 context.Context) (bool, error) `perm:"admin"` @@ -657,7 +661,7 @@ type StorageMinerStruct struct { DealsSetPieceCidBlocklist func(p0 context.Context, p1 []cid.Cid) error `perm:"admin"` - IndexerAnnounceDeal func(p0 context.Context, p1 cid.Cid) error `` + IndexerAnnounceDeal func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` MarketCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` @@ -3694,6 +3698,28 @@ func (s *StorageMinerStub) DagstoreListShards(p0 context.Context) ([]DagstoreSha return *new([]DagstoreShardInfo), ErrNotSupported } +func (s *StorageMinerStruct) DagstoreLookupPieces(p0 context.Context, p1 cid.Cid) ([]DagstoreShardInfo, error) { + if s.Internal.DagstoreLookupPieces == nil { + return *new([]DagstoreShardInfo), ErrNotSupported + } + return s.Internal.DagstoreLookupPieces(p0, p1) +} + +func (s *StorageMinerStub) DagstoreLookupPieces(p0 context.Context, p1 cid.Cid) ([]DagstoreShardInfo, error) { + return *new([]DagstoreShardInfo), ErrNotSupported +} + +func (s *StorageMinerStruct) DagstorePieceIndexSize(p0 context.Context) (int64, error) { + if s.Internal.DagstorePieceIndexSize == nil { + return 0, ErrNotSupported + } + return s.Internal.DagstorePieceIndexSize(p0) +} + +func (s *StorageMinerStub) DagstorePieceIndexSize(p0 context.Context) (int64, error) { + return 0, ErrNotSupported +} + func (s *StorageMinerStruct) DagstoreRecoverShard(p0 context.Context, p1 string) error { if s.Internal.DagstoreRecoverShard == nil { return ErrNotSupported diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 68f5e80cc46d1aa9137e152e97f358580a4ad40f..810bd301719b6fe2a459c9dcb7daf53915232e0f 100644 GIT binary patch literal 25456 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%0Augxt&?M1iRc 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 NCFpmx-ai-63yZp4YW^JV7KdRsFxzcG>^ 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 AhX4Qo delta 1865 zcmV-P2e$Z@6`2*V`T~DGoStZz@<8MlMg}f8hBzdqDu5w}=wQIPy9^z~#Kqts8ZiSb zkg!r5`VC@yk=<)ya)T2WuC{NjB`LqC>42~|u1aSgidE@XQ1;kRkwO|XG@Cfus9g82 z0YwOBlbcsWjpO28s`#TF4*O^BfFY<2S=|<*osB~^I9ub^cZh#m%k+MGpl$<*E)Pue z7FtQ`ums{#Ho_^Uq!MAtW?*K{KUCw(;Ku&C}Lt2|S>Txb!>3b76=R zGQ_6ouUYvuVI$+PpXqsP@qbai84#!ez)l$HE&zZ9Jzg(iWiYhA4~G&|wXqGeOKT3y zn(41PcGj_T-(r7f`>Z&2Ua}!KjF_6FI6t%aFhti}76JABN^vh~&M5Z9oNgt3Q^ed7 zr;w>s#WDPgOEvFG1Ap{L+(7&0%Ms%Ou0irZ*t7Jrg;NDD_%nD{2r&AHFZF}moZG6Pwqi_F+oB#36Fc2m96ZmZZ$eddpF6JZoXZ>uZG?=^xn6a)@v8Xv@4><(lDBZG{xXMTEv5F#Gyb}T^5+a zrj~@HqV_$E!qSY_t-$Xh?n?3+xk}qjZk!W#12J06L0o-Pvs8RH@(MXj`ia}b4S6rR z`zO%RxKc7@gDH|-wYB3;lQIQxf4aqHb`35N31686V!rohf%->2i&^M;TPwA^g!O7| zr?BTPtk&wMG4+zLUJ~y0lJG;XEPjTYeoVurCMt`TWI$uTe|d2jMZn?!s2eGcdnWNM zW<_^h9MWdF&?fp_jWvqgP>f5XmRneg(hQVFN=e-7aQ(zU%K6c_&}N9O=p*E6^x}hc;qjX2 zA*z48(8W1*q#?*niLot!n;ogeJ;z#%8tCpsMBN3To41ZVJStae=Wklp{6^;mkG1tx zOW4zSoH30DC3MJ4p-Tstf1*R0*5o8%`hQr%q(<&|h11f0y`tBer&;FyWs6*T5UXWZ3NuX*Zah1OfCqkG*IOu*voe zU1id_*?gvl!Gv;?Agf-G)(g_NjG50$4sj-UE+4+DV&;zdz8hT{f5XV%1GP5H?Q9?B zcIq7NuG!`;K-;_$zdg8D$GJMr?OB{VYn7ZZ*AD$k!20Q-gm@zvqJ`De8WAvIXq!PW zBX&C7Q^&%cu-{#Xg?pdosZ$>{il|YM-?e{PvaCPM1j6gL_Q#`?oQxtaF5}Sc{^vliSJYI?6~C6WW0U!qvM39;!F)EOI^Om z5|oXW*-y5eR~u1|t#V7+*or932~~SRV*33fn|vYRyVL5ElH-Yg5czNs`94F9PEnR> zGZ0rhL>YDyf4#z@RI^jir!MmBXC z=hQKL;*#QjTaR0^LsXx~sh_)4dQDi)EVlT4r(Uajx`|Ib?d_MU_H6%5{s2tuJy*|6 z;U<@Ce_Q9&K|*&gfhjGD1b288)frGWilPKlh&YY_DZxQ>-dY1)Dm?&0ENYFb5IzS=Sm9Ic{VX zXETRw>JLTKPburClp1Otw^}8qSz=o@gqbl_fAJD+?jFivUR-4f#EWYfA-jaDt-N2a zY^aj*Ek)68yW2TkJC5$CLbgk`o&QOw`gcG<8LH%*u23mUlV5YP*XF*`{THiW($&D_ z_Jc$LQ`ALj3<3}lfLQdDP9hO77Czg1rN+LqWYlr1bBd?ayXpS|00960-M9-cS$Y5f DQt7=m diff --git a/cmd/lotus-miner/dagstore.go b/cmd/lotus-miner/dagstore.go index 6522b02dc..c79906b78 100644 --- a/cmd/lotus-miner/dagstore.go +++ b/cmd/lotus-miner/dagstore.go @@ -4,7 +4,9 @@ import ( "fmt" "os" + "github.com/dustin/go-humanize" "github.com/fatih/color" + "github.com/ipfs/go-cid" "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/api" @@ -21,6 +23,8 @@ var dagstoreCmd = &cli.Command{ dagstoreRecoverShardCmd, dagstoreInitializeAllCmd, dagstoreGcCmd, + dagstorePieceIndexSizeCmd, + dagstoreLookupPiecesCmd, }, } @@ -52,38 +56,7 @@ var dagstoreListShardsCmd = &cli.Command{ return err } - if len(shards) == 0 { - return nil - } - - tw := tablewriter.New( - tablewriter.Col("Key"), - tablewriter.Col("State"), - tablewriter.Col("Error"), - ) - - colors := map[string]color.Attribute{ - "ShardStateAvailable": color.FgGreen, - "ShardStateServing": color.FgBlue, - "ShardStateErrored": color.FgRed, - "ShardStateNew": color.FgYellow, - } - - for _, s := range shards { - m := map[string]interface{}{ - "Key": s.Key, - "State": func() string { - if c, ok := colors[s.State]; ok { - return color.New(c).Sprint(s.State) - } - return s.State - }(), - "Error": s.Error, - } - tw.Write(m) - } - - return tw.Flush(os.Stdout) + return printTableShards(shards) }, } @@ -265,3 +238,114 @@ var dagstoreGcCmd = &cli.Command{ return nil }, } + +func printTableShards(shards []api.DagstoreShardInfo) error { + if len(shards) == 0 { + return nil + } + + tw := tablewriter.New( + tablewriter.Col("Key"), + tablewriter.Col("State"), + tablewriter.Col("Error"), + ) + + colors := map[string]color.Attribute{ + "ShardStateAvailable": color.FgGreen, + "ShardStateServing": color.FgBlue, + "ShardStateErrored": color.FgRed, + "ShardStateNew": color.FgYellow, + } + + for _, s := range shards { + m := map[string]interface{}{ + "Key": s.Key, + "State": func() string { + if c, ok := colors[s.State]; ok { + return color.New(c).Sprint(s.State) + } + return s.State + }(), + "Error": s.Error, + } + tw.Write(m) + } + return tw.Flush(os.Stdout) +} + +var dagstorePieceIndexSizeCmd = &cli.Command{ + Name: "piece-index-size", + Usage: "Inspect the dagstore piece index size", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "color", + Usage: "use color in display output", + DefaultText: "depends on output being a TTY", + }, + }, + Action: func(cctx *cli.Context) error { + if cctx.IsSet("color") { + color.NoColor = !cctx.Bool("color") + } + + marketsApi, closer, err := lcli.GetMarketsAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := lcli.ReqContext(cctx) + + size, err := marketsApi.DagstorePieceIndexSize(ctx) + if err != nil { + return err + } + + fmt.Println(humanize.Bytes(uint64(size))) + + return nil + }, +} + +var dagstoreLookupPiecesCmd = &cli.Command{ + Name: "lookup-pieces", + Usage: "Lookup pieces that a given CID belongs to", + ArgsUsage: "", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "color", + Usage: "use color in display output", + DefaultText: "depends on output being a TTY", + }, + }, + Action: func(cctx *cli.Context) error { + if cctx.IsSet("color") { + color.NoColor = !cctx.Bool("color") + } + + if cctx.NArg() != 1 { + return fmt.Errorf("must provide a CID") + } + + cidStr := cctx.Args().First() + cid, err := cid.Parse(cidStr) + if err != nil { + return fmt.Errorf("invalid CID: %w", err) + } + + marketsApi, closer, err := lcli.GetMarketsAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := lcli.ReqContext(cctx) + + shards, err := marketsApi.DagstoreLookupPieces(ctx, cid) + if err != nil { + return err + } + + return printTableShards(shards) + }, +} diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index c44c312b6..24b032636 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -23,6 +23,8 @@ * [DagstoreInitializeAll](#DagstoreInitializeAll) * [DagstoreInitializeShard](#DagstoreInitializeShard) * [DagstoreListShards](#DagstoreListShards) + * [DagstoreLookupPieces](#DagstoreLookupPieces) + * [DagstorePieceIndexSize](#DagstorePieceIndexSize) * [DagstoreRecoverShard](#DagstoreRecoverShard) * [Deals](#Deals) * [DealsConsiderOfflineRetrievalDeals](#DealsConsiderOfflineRetrievalDeals) @@ -444,6 +446,33 @@ Inputs: `null` Response: `null` +### DagstoreLookupPieces +DagstoreLookupPieces returns information about shards that contain the given CID. + + +Perms: admin + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `null` + +### DagstorePieceIndexSize +DagstorePieceIndexSize returns the size of the piece index. + + +Perms: admin + +Inputs: `null` + +Response: `9` + ### DagstoreRecoverShard DagstoreRecoverShard attempts to recover a failed shard. @@ -673,7 +702,7 @@ IndexerAnnounceDeal informs indexer nodes that a new deal was received, so they can download its index -Perms: +Perms: admin Inputs: ```json diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index 62d2d2a16..acf79adc4 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -1036,6 +1036,8 @@ COMMANDS: recover-shard Attempt to recover a shard in errored state initialize-all Initialize all uninitialized shards, streaming results as they're produced; only shards for unsealed pieces are initialized by default gc Garbage collect the dagstore + piece-index-size Inspect the dagstore piece index size + lookup-pieces Lookup pieces that a given CID belongs to help, h Shows a list of commands or help for one command OPTIONS: @@ -1115,6 +1117,34 @@ OPTIONS: ``` +### lotus-miner dagstore piece-index-size +``` +NAME: + lotus-miner dagstore piece-index-size - Inspect the dagstore piece index size + +USAGE: + lotus-miner dagstore piece-index-size [command options] [arguments...] + +OPTIONS: + --color use color in display output (default: depends on output being a TTY) + --help, -h show help (default: false) + +``` + +### lotus-miner dagstore lookup-pieces +``` +NAME: + lotus-miner dagstore lookup-pieces - Lookup pieces that a given CID belongs to + +USAGE: + lotus-miner dagstore lookup-pieces [command options] + +OPTIONS: + --color use color in display output (default: depends on output being a TTY) + --help, -h show help (default: false) + +``` + ## lotus-miner index ``` NAME: diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 692d3b6d9..4a34eac85 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -836,6 +836,57 @@ func (sm *StorageMinerAPI) IndexerAnnounceDeal(ctx context.Context, proposalCid return sm.StorageProvider.AnnounceDealToIndexer(ctx, proposalCid) } +func (sm *StorageMinerAPI) DagstorePieceIndexSize(ctx context.Context) (int64, error) { + if sm.DAGStore == nil { + return 0, fmt.Errorf("dagstore not available on this node") + } + + res, err := sm.DAGStore.TopLevelIndex.Size() + if err != nil { + return 0, fmt.Errorf("failed to get dagstore piece index size: %w", err) + } + + return res, nil +} + +func (sm *StorageMinerAPI) DagstoreLookupPieces(ctx context.Context, cid cid.Cid) ([]api.DagstoreShardInfo, error) { + if sm.DAGStore == nil { + return nil, fmt.Errorf("dagstore not available on this node") + } + + keys, err := sm.DAGStore.TopLevelIndex.GetShardsForMultihash(cid.Hash()) + if err != nil { + return nil, err + } + + var ret []api.DagstoreShardInfo + + for _, k := range keys { + shard, err := sm.DAGStore.GetShardInfo(k) + if err != nil { + return nil, err + } + + ret = append(ret, api.DagstoreShardInfo{ + Key: k.String(), + State: shard.ShardState.String(), + Error: func() string { + if shard.Error == nil { + return "" + } + return shard.Error.Error() + }(), + }) + } + + // order by key. + sort.SliceStable(ret, func(i, j int) bool { + return ret[i].Key < ret[j].Key + }) + + return ret, nil +} + func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]api.MarketDeal, error) { return sm.listDeals(ctx) }