From e6768a4b252846bc227c23b6a9631873853cce38 Mon Sep 17 00:00:00 2001 From: simlecode <69969590+simlecode@users.noreply.github.com> Date: Thu, 8 Jun 2023 16:50:31 +0800 Subject: [PATCH] feat: import deals --- Makefile | 8 + api/impl/venus_market.go | 26 +- cli/storage-deals.go | 118 +- cli/testdata/boost_deal_query_result.json | 144 ++ cli/testdata/lotus_miner_query_result.json | 158 ++ cli/util.go | 214 +++ cli/util_test.go | 39 + ...73\347\272\277\350\256\242\345\215\225.md" | 65 - ...01\347\247\273\350\256\242\345\215\225.md" | 132 ++ go.mod | 4 +- go.sum | 4 +- models/badger/storage_deal.go | 10 + models/badger/storage_deal_test.go | 14 + models/mysql/storage_deal.go | 13 + models/repo/repo.go | 1 + storageprovider/storage_provider.go | 73 +- storageprovider/storageprovider_test.go | 299 ---- storageprovider/testdata/import_deal.json | 1365 ----------------- 18 files changed, 879 insertions(+), 1808 deletions(-) create mode 100644 cli/testdata/boost_deal_query_result.json create mode 100644 cli/testdata/lotus_miner_query_result.json create mode 100644 cli/util_test.go delete mode 100644 "docs/zh/\345\246\202\344\275\225\350\277\201\347\247\273\347\246\273\347\272\277\350\256\242\345\215\225.md" create mode 100644 "docs/zh/\350\277\201\347\247\273\350\256\242\345\215\225.md" delete mode 100644 storageprovider/storageprovider_test.go delete mode 100644 storageprovider/testdata/import_deal.json diff --git a/Makefile b/Makefile index b3922a02..2a32f1e4 100644 --- a/Makefile +++ b/Makefile @@ -62,6 +62,14 @@ build: $(BUILD_DEPS) go build -o ./droplet-client $(GOFLAGS) ./cmd/droplet-client go build -o ./droplet $(GOFLAGS) ./cmd/droplet +droplet: $(BUILD_DEPS) + rm -f droplet + go build -o ./droplet $(GOFLAGS) ./cmd/droplet + +droplet-client: $(BUILD_DEPS) + rm -f droplet-client + go build -o ./droplet-client $(GOFLAGS) ./cmd/droplet-client + add-debug-flag: GOFLAGS+=-gcflags="all=-N -l" diff --git a/api/impl/venus_market.go b/api/impl/venus_market.go index 981b5d44..84e833be 100644 --- a/api/impl/venus_market.go +++ b/api/impl/venus_market.go @@ -18,6 +18,7 @@ import ( "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-fil-markets/stores" "github.com/filecoin-project/go-state-types/abi" + "github.com/hashicorp/go-multierror" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" "github.com/libp2p/go-libp2p/core/host" @@ -1204,11 +1205,28 @@ func (m *MarketNodeImpl) RemovePieceStorage(_ context.Context, name string) erro return m.Config.RemovePieceStorage(name) } -func (m *MarketNodeImpl) OfflineDealImport(ctx context.Context, deal types.MinerDeal) error { - if err := jwtclient.CheckPermissionByMiner(ctx, m.AuthClient, deal.Proposal.Provider); err != nil { - return err +func (m *MarketNodeImpl) DealsImport(ctx context.Context, deals []*types.MinerDeal) error { + if len(deals) == 0 { + return nil + } + + addrDeals := make(map[address.Address][]*types.MinerDeal) + for _, deal := range deals { + addrDeals[deal.Proposal.Provider] = append(addrDeals[deal.Proposal.Provider], deal) } - return m.StorageProvider.ImportOfflineDeal(ctx, deal) + + var errs *multierror.Error + valid := make(map[address.Address][]*types.MinerDeal, len(addrDeals)) + for addr, d := range addrDeals { + if err := jwtclient.CheckPermissionByMiner(ctx, m.AuthClient, addr); err != nil { + errs = multierror.Append(errs, err) + continue + } + valid[addr] = d + } + errs = multierror.Append(errs, m.StorageProvider.ImportDeals(ctx, valid)) + + return errs.ErrorOrNil() } func (m *MarketNodeImpl) Version(_ context.Context) (vTypes.Version, error) { diff --git a/cli/storage-deals.go b/cli/storage-deals.go index 55ced79a..3723f5b9 100644 --- a/cli/storage-deals.go +++ b/cli/storage-deals.go @@ -44,7 +44,7 @@ var storageDealsCmds = &cli.Command{ Subcommands: []*cli.Command{ dealsImportDataCmd, dealsBatchImportDataCmd, - importOfflineDealCmd, + importDealCmd, dealsListCmd, updateStorageDealStateCmd, dealsPendingPublish, @@ -199,18 +199,29 @@ basdefxxx,baefaxxx }, } -var importOfflineDealCmd = &cli.Command{ - Name: "import-offlinedeal", - Usage: "Manually import offline deal", - ArgsUsage: "", +var importDealCmd = &cli.Command{ + Name: "import-deal", + Usage: "Manually import lotus-miner or boost deals", + ArgsUsage: "", Flags: []cli.Flag{ - // verbose - &cli.BoolFlag{ - Name: "verbose", - Usage: "Print verbose output", - Aliases: []string{ - "v", - }, + &cli.StringFlag{ + Name: "from", + Usage: "Where the order comes from, lotus-miner or boost", + Value: "lotus-miner", + }, + &cli.StringSliceFlag{ + Name: "car-dirs", + Usage: "directory of car files", + }, + &cli.Uint64SliceFlag{ + Name: "states", + Usage: ` +What status deal is expected to be imported, default import StorageDealActive and StorageDealWaitingForData deal. +use './droplet storage deal states' to show all states. +part states: +7 StorageDealActive +18 StorageDealWaitingForData +`, }, }, Action: func(cctx *cli.Context) error { @@ -220,6 +231,12 @@ var importOfflineDealCmd = &cli.Command{ } defer closer() + fapi, fcloser, err := NewFullNode(cctx) + if err != nil { + return err + } + defer fcloser() + ctx := DaemonContext(cctx) if cctx.Args().Len() < 1 { @@ -227,38 +244,69 @@ var importOfflineDealCmd = &cli.Command{ } fpath := cctx.Args().Get(0) - - dealbyte, err := ioutil.ReadFile(fpath) + data, err := ioutil.ReadFile(fpath) if err != nil { - return fmt.Errorf("read deal file(%s) fail %w", fpath, err) + return fmt.Errorf("read deal file(%s) failed: %v", fpath, err) } - - data := []market.MinerDeal{} - err = json.Unmarshal(dealbyte, &data) - if err != nil { - return fmt.Errorf("parse deal file(%s) fail %w", fpath, err) + var r result + if err := json.Unmarshal(data, &r); err != nil { + return err } - totalCount := len(data) - importedCount := 0 - - // if verbose, print the deal info + expectStates := map[uint64]struct{}{ + storagemarket.StorageDealWaitingForData: {}, + storagemarket.StorageDealActive: {}, + } + if cctx.IsSet("states") { + expectStates = make(map[uint64]struct{}) + for _, v := range cctx.Uint64Slice("states") { + expectStates[v] = struct{}{} + } + } - for i := 0; i < totalCount; i++ { - err := api.OfflineDealImport(ctx, data[i]) - if err != nil { - if cctx.Bool("verbose") { - fmt.Printf("( %d / %d ) %s : fail : %v\n", i+1, totalCount, data[i].ProposalCid, err) + getMinerPeer := getMinerPeerFunc(ctx, fapi) + getPayloadSize := getPayloadSizeFunc(cctx.StringSlice("car-dirs")) + deals := make([]*market.MinerDeal, 0) + if cctx.String("from") == "boost" { + for _, deal := range r.BoostResult.Deals.Deals { + d, err := deal.minerDeal() + if err != nil { + fmt.Printf("parse %s deal failed: %v\n", deal.SignedProposalCid, err) + continue } - } else { - importedCount++ - if cctx.Bool("verbose") { - fmt.Printf("( %d / %d ) %s : success\n", i+1, totalCount, data[i].ProposalCid) + if _, ok := expectStates[d.State]; !ok { + continue + } + d.Miner = getMinerPeer(d.Proposal.Provider) + + if d.PayloadSize == 0 { + d.PayloadSize = getPayloadSize(d.Proposal.PieceCID) + d.Ref.RawBlockSize = d.PayloadSize + if d.PayloadSize == 0 { + fmt.Printf("deal %s payload size %d\n", deal.SignedProposalCid, d.PayloadSize) + continue + } + } + deals = append(deals, d) + } + } else if cctx.String("from") == "lotus-miner" { + for _, d := range r.Result { + if _, ok := expectStates[d.State]; ok { + d.PayloadSize = d.Ref.RawBlockSize + d.PieceStatus = market.Undefine + if d.SlashEpoch == 0 { + d.SlashEpoch = -1 + } + deals = append(deals, d) } } + } else { + return fmt.Errorf("the value of --from can only be 'lotus-miner' or 'boost' ") } - - fmt.Printf("import %d deals, %d deal success , %d deal fail .\n", totalCount, importedCount, totalCount-importedCount) + if err := api.DealsImport(ctx, deals); err != nil { + return fmt.Errorf("\nimport deals failed: %v", err) + } + fmt.Printf("import %d deals success\n", len(deals)) return nil }, diff --git a/cli/testdata/boost_deal_query_result.json b/cli/testdata/boost_deal_query_result.json new file mode 100644 index 00000000..93301bb4 --- /dev/null +++ b/cli/testdata/boost_deal_query_result.json @@ -0,0 +1,144 @@ +{ + "data": { + "deals": { + "totalCount": 2, + "deals": [{ + "ID": "1b4b8f7e-6b55-4f71-93d7-be1b46ea00c6", + "ClientAddress": "f3uxq6uf56zkfiwuyqal272lxn7wjr5to7qhzd7x5u43zjt53bv4osiockngso4itca7onyucapwh2kn3kxgjq", + "ProviderAddress": "f020523", + "CreatedAt": "2023-06-07T15:45:40.164474+08:00", + "PieceCid": "baga6ea4seaqp77vrfncm4kdvsls3zg4idxmeow63yxa52p47tswtolxdhdcosmq", + "PieceSize": { + "__typename": "BigInt", + "n": "16777216" + }, + "IsVerified": false, + "ProposalLabel": "bafybeihcume7lo6p3dauy4bk2c47k2ays7xr2dm3wgxnsdftygfqmpyoka", + "ProviderCollateral": { + "__typename": "BigInt", + "n": "0" + }, + "ClientCollateral": { + "__typename": "BigInt", + "n": "0" + }, + "StoragePricePerEpoch": { + "__typename": "BigInt", + "n": "0" + }, + "StartEpoch": { + "__typename": "BigInt", + "n": "632345" + }, + "EndEpoch": { + "__typename": "BigInt", + "n": "1150745" + }, + "ClientPeerID": "12D3KooWAQZaLb11Ljk9xisShhCgFQNQFPEA1Lnb3APifu2aFPAS", + "DealDataRoot": "bafybeihcume7lo6p3dauy4bk2c47k2ays7xr2dm3wgxnsdftygfqmpyoka", + "SignedProposalCid": "bafyreih7qaddtjxu66khjohckd3gkp42p3x5i2fhw5xjw325rnb7wvje7q", + "InboundFilePath": "", + "ChainDealID": { + "__typename": "BigInt", + "n": "0" + }, + "PublishCid": "", + "IsOffline": true, + "Transfer": { + "Type": "", + "Size": { + "__typename": "BigInt", + "n": "0" + } + }, + "IsTransferStalled": false, + "Checkpoint": "Accepted", + "Err": "", + "Sector": { + "ID": { + "__typename": "BigInt", + "n": "0" + }, + "Offset": { + "__typename": "BigInt", + "n": "0" + }, + "Length": { + "__typename": "BigInt", + "n": "0" + } + }, + "Message": "Awaiting Offline Data Import" + }, + { + "ID": "602e4ad9-5a0f-42b8-afac-af90c93c2719", + "ClientAddress": "f3uxq6uf56zkfiwuyqal272lxn7wjr5to7qhzd7x5u43zjt53bv4osiockngso4itca7onyucapwh2kn3kxgjq", + "ProviderAddress": "f020523", + "CreatedAt": "2023-06-07T15:45:11.478651+08:00", + "PieceCid": "baga6ea4seaqp77vrfncm4kdvsls3zg4idxmeow63yxa52p47tswtolxdhdcosmq", + "PieceSize": { + "__typename": "BigInt", + "n": "16777216" + }, + "IsVerified": false, + "ProposalLabel": "bafybeihcume7lo6p3dauy4bk2c47k2ays7xr2dm3wgxnsdftygfqmpyoka", + "ProviderCollateral": { + "__typename": "BigInt", + "n": "0" + }, + "ClientCollateral": { + "__typename": "BigInt", + "n": "0" + }, + "StoragePricePerEpoch": { + "__typename": "BigInt", + "n": "0" + }, + "StartEpoch": { + "__typename": "BigInt", + "n": "632344" + }, + "EndEpoch": { + "__typename": "BigInt", + "n": "1150744" + }, + "ClientPeerID": "12D3KooWAQZaLb11Ljk9xisShhCgFQNQFPEA1Lnb3APifu2aFPAS", + "DealDataRoot": "bafybeihcume7lo6p3dauy4bk2c47k2ays7xr2dm3wgxnsdftygfqmpyoka", + "SignedProposalCid": "bafyreics2zkltd4puxyksgiequszv2qvy3zvw7hlko6nnb23tdxhylv4iy", + "InboundFilePath": "", + "ChainDealID": { + "__typename": "BigInt", + "n": "0" + }, + "PublishCid": "", + "IsOffline": true, + "Transfer": { + "Type": "", + "Size": { + "__typename": "BigInt", + "n": "0" + } + }, + "IsTransferStalled": false, + "Checkpoint": "Accepted", + "Err": "", + "Sector": { + "ID": { + "__typename": "BigInt", + "n": "0" + }, + "Offset": { + "__typename": "BigInt", + "n": "0" + }, + "Length": { + "__typename": "BigInt", + "n": "0" + } + }, + "Message": "Awaiting Offline Data Import" + } + ] + } + } +} \ No newline at end of file diff --git a/cli/testdata/lotus_miner_query_result.json b/cli/testdata/lotus_miner_query_result.json new file mode 100644 index 00000000..1059230f --- /dev/null +++ b/cli/testdata/lotus_miner_query_result.json @@ -0,0 +1,158 @@ +{ + "jsonrpc": "2.0", + "result": [{ + "Proposal": { + "PieceCID": { + "/": "baga6ea4seaqp2gxiw4a5hrerykjpti7bzm6n6oc236jbkdykctwgthcmpqnjqhy" + }, + "PieceSize": 16777216, + "VerifiedDeal": false, + "Client": "f3wivhkdivcxj5zp2l4wjkzon232s52smnd5m3na66ujl5nel75jggguhgaa3zbhjo3as4epf5ytxl6ly3qoha", + "Provider": "f020523", + "Label": "uAXASIDsH7LfFV_4X1aEm-9rWbsculXCLOFM3o5VlGvaq_SzJ", + "StartEpoch": 649604, + "EndEpoch": 1171644, + "StoragePricePerEpoch": "0", + "ProviderCollateral": "0", + "ClientCollateral": "0" + }, + "ClientSignature": { + "Type": 2, + "Data": "ta1aI6Iz4AqOrE4sBBfuFQxlgN4TM5dKbMuHlmlNkvTb8wU6jA/fTOouJW6Cy8A0GYPSZymP+18WSW1yt4r0g9etFr7KASVN9/78wzFJ48bbrYV2WWYzt6pnXrG9sgMy" + }, + "ProposalCid": { + "/": "bafyreiaskbu5kx3qje5fvgsymtlogitaiwx6quksv57rppw33ogw2gwz3a" + }, + "AddFundsCid": null, + "PublishCid": null, + "Miner": "12D3KooWRvjAQRVTUH4WnYCL8Gq8LocavMjgcuPWKcc5oJxA4erz", + "Client": "12D3KooWAwmur3HdnS2pGMgXtM8wkGByquyuajoRmjb1SENNbeio", + "State": 18, + "PiecePath": "", + "MetadataPath": "", + "SlashEpoch": 0, + "FastRetrieval": true, + "Message": "", + "FundsReserved": "0", + "Ref": { + "TransferType": "manual", + "Root": { + "/": "bafybeib3a7wlprkx7yl5lijg7pnnm3whf2kxbczykm32hflfdl3kv7jmze" + }, + "PieceCid": { + "/": "baga6ea4seaqp2gxiw4a5hrerykjpti7bzm6n6oc236jbkdykctwgthcmpqnjqhy" + }, + "PieceSize": 16646144, + "RawBlockSize": 10241347 + }, + "AvailableForRetrieval": false, + "DealID": 0, + "CreationTime": "2023-06-07T15:35:19.485691+08:00", + "TransferChannelId": null, + "SectorNumber": 0, + "InboundCAR": "" + }, { + "Proposal": { + "PieceCID": { + "/": "baga6ea4seaqd65rktwpqdoc52ga5vt4tyydvdph6wflp6njs73verpundawicoa" + }, + "PieceSize": 16777216, + "VerifiedDeal": false, + "Client": "f3wivhkdivcxj5zp2l4wjkzon232s52smnd5m3na66ujl5nel75jggguhgaa3zbhjo3as4epf5ytxl6ly3qoha", + "Provider": "f020523", + "Label": "uAXASIFb4y384Cke03LGnMVpNn-ZV83oUaro4soRsfvw3rKx0", + "StartEpoch": 649604, + "EndEpoch": 1171644, + "StoragePricePerEpoch": "0", + "ProviderCollateral": "0", + "ClientCollateral": "0" + }, + "ClientSignature": { + "Type": 2, + "Data": "qFgZWscttskyN/rvNsU+D64sT2/bhLcphQiZnkPoyBlCsmjAWAzrK1N2D7ANDcs1Gema1Mu4JyljwZbG7BIWwOgbGdHk9YaEEt4NkLkSvDgr7genkUwPIBh9IssMJxbB" + }, + "ProposalCid": { + "/": "bafyreibavnnp5yql7m3df5ufdooxx22uzytctcqlo6rvddhccks5gzhjoe" + }, + "AddFundsCid": null, + "PublishCid": null, + "Miner": "12D3KooWRvjAQRVTUH4WnYCL8Gq8LocavMjgcuPWKcc5oJxA4erz", + "Client": "12D3KooWAwmur3HdnS2pGMgXtM8wkGByquyuajoRmjb1SENNbeio", + "State": 18, + "PiecePath": "", + "MetadataPath": "", + "SlashEpoch": 0, + "FastRetrieval": true, + "Message": "", + "FundsReserved": "0", + "Ref": { + "TransferType": "manual", + "Root": { + "/": "bafybeicw7dfx6oaki62nzmnhgfne3h7gkxzxufdkxi4lfbdmp36dplfmoq" + }, + "PieceCid": { + "/": "baga6ea4seaqd65rktwpqdoc52ga5vt4tyydvdph6wflp6njs73verpundawicoa" + }, + "PieceSize": 16646144, + "RawBlockSize": 10241347 + }, + "AvailableForRetrieval": false, + "DealID": 0, + "CreationTime": "2023-06-07T15:35:17.735562+08:00", + "TransferChannelId": null, + "SectorNumber": 0, + "InboundCAR": "" + }, { + "Proposal": { + "PieceCID": { + "/": "baga6ea4seaqnbsxmgpdt2kddech6ekvh5rxc7fqedbfi4ght7ct2nks5kphowcy" + }, + "PieceSize": 16777216, + "VerifiedDeal": false, + "Client": "f3wivhkdivcxj5zp2l4wjkzon232s52smnd5m3na66ujl5nel75jggguhgaa3zbhjo3as4epf5ytxl6ly3qoha", + "Provider": "f020523", + "Label": "uAXASIPKr8XKZYBzQdDigba8ASqYzuFYtZYsF03OthB_Xa313", + "StartEpoch": 649604, + "EndEpoch": 1171644, + "StoragePricePerEpoch": "0", + "ProviderCollateral": "0", + "ClientCollateral": "0" + }, + "ClientSignature": { + "Type": 2, + "Data": "oKwMdEvsghaHsd1YQQIYPB9MPGgjbH6IUOWFiToIMIfyyQyYpKKsgdIK9ZueJ7pnBOOa//PVWsyAFaGcznMBK6TDIh8OeJmkB1K5ENoTLFq7AZnF+SLMkGP1MkR98SVu" + }, + "ProposalCid": { + "/": "bafyreibkd4co27mn5p2bebkyviqkl5mueyoc6rip7h7f5irwg67hqejpaa" + }, + "AddFundsCid": null, + "PublishCid": null, + "Miner": "12D3KooWRvjAQRVTUH4WnYCL8Gq8LocavMjgcuPWKcc5oJxA4erz", + "Client": "12D3KooWAwmur3HdnS2pGMgXtM8wkGByquyuajoRmjb1SENNbeio", + "State": 18, + "PiecePath": "", + "MetadataPath": "", + "SlashEpoch": 0, + "FastRetrieval": true, + "Message": "", + "FundsReserved": "0", + "Ref": { + "TransferType": "manual", + "Root": { + "/": "bafybeihsvpyxfgladtihiofanwxqasvggo4fmllfrmc5g45nqqp5o235o4" + }, + "PieceCid": { + "/": "baga6ea4seaqnbsxmgpdt2kddech6ekvh5rxc7fqedbfi4ght7ct2nks5kphowcy" + }, + "PieceSize": 16646144, + "RawBlockSize": 10241347 + }, + "AvailableForRetrieval": false, + "DealID": 0, + "CreationTime": "2023-06-07T15:35:18.345022+08:00", + "TransferChannelId": null, + "SectorNumber": 0, + "InboundCAR": "" + }], + "id": 0 +} \ No newline at end of file diff --git a/cli/util.go b/cli/util.go index a01da9d5..21fff2ba 100644 --- a/cli/util.go +++ b/cli/util.go @@ -2,28 +2,39 @@ package cli import ( "context" + "encoding/json" "fmt" "io" "io/ioutil" "os" "os/signal" "path" + "path/filepath" "sort" "strconv" "strings" "syscall" + "time" "github.com/docker/go-units" "github.com/fatih/color" "github.com/howeyc/gopass" + "github.com/ipfs/go-cid" "github.com/ipfs/go-cidutil/cidenc" + "github.com/libp2p/go-libp2p/core/peer" "github.com/mitchellh/go-homedir" "github.com/multiformats/go-multibase" "github.com/urfave/cli/v2" "github.com/filecoin-project/go-address" datatransfer "github.com/filecoin-project/go-data-transfer" + "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-jsonrpc" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/builtin/v9/market" + "github.com/filecoin-project/go-state-types/crypto" + cbg "github.com/whyrusleeping/cbor-gen" "github.com/ipfs-force-community/droplet/v2/cli/tablewriter" "github.com/ipfs-force-community/droplet/v2/config" @@ -32,6 +43,7 @@ import ( v1api "github.com/filecoin-project/venus/venus-shared/api/chain/v1" clientapi "github.com/filecoin-project/venus/venus-shared/api/market/client" marketapi "github.com/filecoin-project/venus/venus-shared/api/market/v1" + shared "github.com/filecoin-project/venus/venus-shared/types" types "github.com/filecoin-project/venus/venus-shared/types/market" ) @@ -342,3 +354,205 @@ func shouldAddress(s string, checkEmpty bool, allowActor bool) (address.Address, return address.NewFromString(s) } + +type result struct { + // lotus-miner query deals result + Result []*types.MinerDeal `json:"result"` + + // boost query deals result + BoostResult struct { + Deals struct { + TotalCount int `json:"totalCount"` + Deals []boostDeal `json:"deals"` + } `json:"deals"` + } `json:"data"` +} + +type bigInt big.Int + +func (bi *bigInt) UnmarshalJSON(data []byte) error { + type internal struct { + N string `json:"n"` + } + + var t internal + if err := json.Unmarshal(data, &t); err != nil { + return err + } + + i := big.NewInt(0) + if t.N != "0" { + n, err := strconv.ParseUint(t.N, 10, 64) + if err != nil { + return err + } + i = big.NewIntUnsigned(n) + } + *bi = bigInt(i) + + return nil +} + +type transfer struct { + Type string + Size bigInt +} + +type sector struct { + ID bigInt + Offset bigInt + Length bigInt +} + +type boostDeal struct { + ID string + ClientAddress string + ProviderAddress string + CreatedAt string + PieceCid string + PieceSize bigInt + IsVerified bool + ProposalLabel string + ProviderCollateral bigInt + ClientCollateral bigInt + StoragePricePerEpoch bigInt + StartEpoch bigInt + EndEpoch bigInt + ClientPeerID string + DealDataRoot string + SignedProposalCid string + InboundFilePath string + ChainDealID bigInt + PublishCid string + IsOffline bool + Transfer transfer + Checkpoint string + Err string + Sector sector + Message string +} + +func (d *boostDeal) minerDeal() (deal *types.MinerDeal, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("%v", r) + } + }() + + label, err := shared.NewLabelFromString(d.ProposalLabel) + if err != nil { + return nil, err + } + clientPeerID, err := peer.Decode(d.ClientPeerID) + if err != nil { + return nil, err + } + createAt, err := time.Parse(time.RFC3339, d.CreatedAt) + if err != nil { + return nil, err + } + pieceCID := shared.MustParseCid(d.PieceCid) + + deal = &types.MinerDeal{ + ClientDealProposal: market.ClientDealProposal{ + Proposal: market.DealProposal{ + PieceCID: pieceCID, + PieceSize: abi.PaddedPieceSize(d.PieceSize.Int64()), + VerifiedDeal: d.IsVerified, + Client: shared.MustParseAddress(d.ClientAddress), + Provider: shared.MustParseAddress(d.ProviderAddress), + Label: label, + StartEpoch: abi.ChainEpoch(d.StartEpoch.Int64()), + EndEpoch: abi.ChainEpoch(d.EndEpoch.Int64()), + StoragePricePerEpoch: big.Int(d.StoragePricePerEpoch), + ProviderCollateral: big.Int(d.ProviderCollateral), + ClientCollateral: big.Int(d.ClientCollateral), + }, + // todo: query response not include Signature + ClientSignature: crypto.Signature{}, + }, + ProposalCid: shared.MustParseCid(d.SignedProposalCid), + Client: clientPeerID, + PiecePath: "", + PayloadSize: uint64(d.Transfer.Size.Int64()), + MetadataPath: "", + FastRetrieval: true, + Message: d.Err, + Ref: &storagemarket.DataRef{ + TransferType: d.Transfer.Type, + Root: shared.MustParseCid(d.DealDataRoot), + PieceCid: &pieceCID, + PieceSize: abi.UnpaddedPieceSize(d.PieceSize.Int64()), + }, + AvailableForRetrieval: false, + DealID: abi.DealID(d.ChainDealID.Int64()), + CreationTime: cbg.CborTime(createAt), + SectorNumber: abi.SectorNumber(d.Sector.ID.Int64()), + Offset: abi.PaddedPieceSize(d.Sector.Offset.Int64()), + TimeStamp: types.TimeStamp{ + CreatedAt: uint64(createAt.Unix()), + UpdatedAt: uint64(time.Now().Unix()), + }, + SlashEpoch: -1, + // AddFundsCid: , + // FundsReserved: , + // TransferChannelID: , + } + if d.IsOffline { + deal.Ref.TransferType = storagemarket.TTManual + } + + if len(d.PublishCid) != 0 { + publicCID := shared.MustParseCid(d.PublishCid) + deal.PublishCid = &publicCID + } + + switch d.Checkpoint { + // https://github.com/filecoin-project/boost/blob/main/gql/resolver.go#L546 + case "Accepted": + if d.Message == "Awaiting Offline Data Import" { + deal.State = storagemarket.StorageDealWaitingForData + deal.PieceStatus = types.Undefine + } + // https://github.com/filecoin-project/boost/blob/main/gql/resolver.go#L583 + case "Complete": + if strings.Contains(d.Message, string(types.Proving)) { + deal.State = storagemarket.StorageDealActive + deal.PieceStatus = types.Proving + } + } + + return deal, nil +} + +func getMinerPeerFunc(ctx context.Context, fapi v1api.FullNode) func(miner address.Address) peer.ID { + minersPeer := make(map[address.Address]peer.ID) + + return func(miner address.Address) peer.ID { + id, ok := minersPeer[miner] + if !ok { + minerInfo, err := fapi.StateMinerInfo(ctx, miner, shared.EmptyTSK) + if err == nil && minerInfo.PeerId != nil { + id = *minerInfo.PeerId + minersPeer[miner] = *minerInfo.PeerId + } + } + return id + } +} + +func getPayloadSizeFunc(dirs []string) func(pieceCID cid.Cid) uint64 { + sizes := make(map[cid.Cid]uint64) + + return func(pieceCID cid.Cid) uint64 { + piece := pieceCID.String() + for _, dir := range dirs { + fi, err := os.Stat(filepath.Join(dir, piece)) + if err == nil { + sizes[pieceCID] = uint64(fi.Size()) + } + } + + return sizes[pieceCID] + } +} diff --git a/cli/util_test.go b/cli/util_test.go new file mode 100644 index 00000000..08d7a2bb --- /dev/null +++ b/cli/util_test.go @@ -0,0 +1,39 @@ +package cli + +import ( + "encoding/json" + "fmt" + "os" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestUnmarshalBoostDeal(t *testing.T) { + data, err := os.ReadFile("./testdata/boost_deal_query_result.json") + assert.NoError(t, err) + + var r result + assert.NoError(t, json.Unmarshal(data, &r)) + assert.Equal(t, 2, r.BoostResult.Deals.TotalCount) + assert.Len(t, r.BoostResult.Deals.Deals, 2) + fmt.Printf("%+v\n", r.BoostResult.Deals) + + deal := r.BoostResult.Deals.Deals[0] + assert.Equal(t, "Awaiting Offline Data Import", deal.Message) + createAt, err := time.Parse(time.RFC3339, deal.CreatedAt) + assert.NoError(t, err) + fmt.Println("create at", createAt) + + data, err = os.ReadFile("./testdata/lotus_miner_query_result.json") + assert.NoError(t, err) + + var r2 result + assert.NoError(t, json.Unmarshal(data, &r2)) + assert.Len(t, r2.Result, 3) + assert.Equal(t, uint64(18), r2.Result[0].State) + for i, deal := range r2.Result { + fmt.Printf("i: %d, deal: %+v\n", i, deal) + } +} diff --git "a/docs/zh/\345\246\202\344\275\225\350\277\201\347\247\273\347\246\273\347\272\277\350\256\242\345\215\225.md" "b/docs/zh/\345\246\202\344\275\225\350\277\201\347\247\273\347\246\273\347\272\277\350\256\242\345\215\225.md" deleted file mode 100644 index 242d36aa..00000000 --- "a/docs/zh/\345\246\202\344\275\225\350\277\201\347\247\273\347\246\273\347\272\277\350\256\242\345\215\225.md" +++ /dev/null @@ -1,65 +0,0 @@ -# 如何迁移离线订单 - -从`lotus` 迁移到`venus`的时候,需要迁移已完成封装证明的订单和还没开始进行封装的离线订单。 -本文档主要介绍该过程中离线订单的迁移。 - -## 前置条件 - -要完成离线订单的迁移,需要满足以下两个条件: -- 已经拥有一套带有`market`组件的`venus`链服务 -- 已经将矿工账号迁入`venus`链服务 - -## 从`lotus-miner`导出离线订单 - -迄至2022年7月,`lotus-miner`尚未提供直接导出订单详细信息的命令行工具,所以订单的导出需要用户直接访问`lotus-miner`的rpc服务接口来完成。 -可参考以下使用curl导出lotus-miner的离线订单的示例: - -```bash -curl http://127.0.0.1:2345/rpc/v0 -X POST \ --H "Content-Type: application/json" \ --H "Authorization: Bearer " \ --d '{"method": "Filecoin.MarketListIncompleteDeals","params":[], "id": 0}' -``` - -执行完命令后,你可能得到如下结果: - -``` -{"jsonrpc":"2.0","result":[{"Proposal":{"PieceCID":{"/":"baga6ea4seaqcrddjqzqavqipgljq6jn3bmbnhzw5yucdmoqoji3tni6kisjqini"},"PieceSize":128,"VerifiedDeal":false,"Client":"t3r3nyp4sitvilwc5wggvrsyoqmue3zgliqsqzqxri5up2fmlx2e5xeltxv4qbokjj6qrdgz3t7zdwygogpjaa","Provider":"t01000","Label":"uAVUAHOi_meaYr-eUqOadpea1i-ivleeahOaVsOaNrgo","StartEpoch":173482,"EndEpoch":694737,"StoragePricePerEpoch":"0", -...... -":"bafkqahhix6m6ngfp46kkrzu5uxtllc7iv6k6pgue42k3bzunvyfa"},"PieceCid":{"/":"baga6ea4seaqcrddjqzqavqipgljq6jn3bmbnhzw5yucdmoqoji3tni6kisjqini"},"PieceSize":127,"RawBlockSize":0},"AvailableForRetrieval":false,"DealID":0,"CreationTime":"2022-08-03T10:35:09.774748628+08:00","TransferChannelId":null,"SectorNumber":0,"InboundCAR":""}],"id":0} -``` - -其中,`result`中的每一项都是一个订单的详细信息。每个订单中的`State`字段表征了当前订单的状态,如果`State`=18,表示当前订单处于`StorageDealWaitingForData`的状态,也就是离线订单暂时停留的一个状态,可以手动地将离线订单抽离出来,也可以将所有的订单都保留直接通过`droplet`导入,它会排除掉非离线订单。
-将要导入的订单信息保存到一个json文件中,就算是完成了离线订单导出。 - - -## 将离线订单导入到`droplet` - -开始导入离线订单之前,先确认矿工账号是否在`venus`链服务中,如果不在,需要将矿工账号迁入`venus`链服务。 - -```bash -./droplet actor list -``` - -确定完矿工之后,在`droplet`中可以直接通过命令导入离线订单: - -```bash -./droplet storage-deals import-offlinedeal -``` - -可以得到类似以下的结果: - - $ ./droplet storage-deals import-offlinedeal offline-deals.json - import 4 deals, 1 deal success , 3 deal fail . - -加上`--verbose`(`-v`)标志,可以获取更加详细的执行信息: - - - $./droplet storage-deals import-offlinedeal --verbose - ( 1 / 4 ) bafyreieb5uzq26rrvpp6cue34tuyz6xfrdgydxsul3u2fyez7wrnohoaye : fail : deal state StorageDealError not match StorageDealWaitingForData - ( 2 / 4 ) bafyreiergjl22fk5kfvxd3yopby62veeejhesuxzbmhsnoo7tp3mam6zzu : success - ( 3 / 4 ) bafyreig75z2tw2wz5qpign2r4773wugl6gf5fezo32dvucqnz3ftfajilu : fail : deal state StorageDealError not match StorageDealWaitingForData - ( 4 / 4 ) bafyreihdbazwk2zahpmpdhykyqrax6m5rkz472gvhfixfg5hse5ao4s6gq : fail : deal state StorageDealError not match StorageDealWaitingForData - import 4 deals, 1 deal success , 3 deal fail . - -至此,就已经完成了离线订单的导入。 diff --git "a/docs/zh/\350\277\201\347\247\273\350\256\242\345\215\225.md" "b/docs/zh/\350\277\201\347\247\273\350\256\242\345\215\225.md" new file mode 100644 index 00000000..6a83c03d --- /dev/null +++ "b/docs/zh/\350\277\201\347\247\273\350\256\242\345\215\225.md" @@ -0,0 +1,132 @@ +# 迁移订单 + +从 `lotus` 迁移到 `venus` 的时候,需要迁移已完成封装证明的订单和还在 `StorageDealWaitingForData` 状态的订单。 +本文档主要介绍如何从 `lotus-miner` 和 `boost` 迁移订单到 `droplet`。 + +## 前置条件 + +要完成订单的迁移,需要满足以下两个条件: +- 已经拥有一套带有 `droplet` 组件的 `venus` 链服务 +- 已经将矿工账号迁入 `venus` 链服务 + +## 从 lotus-miner 迁移订单 + +### 从 lotus-miner 导出订单 + +通过接口导出订单,参考以下示例: + +> `TOKEN` 是 `lotus-miner` 的 token,可以通过命令生成:`lotus-miner auth api-info --perm=admin` + +```bash +curl http://127.0.0.1:2345/rpc/v0 -X POST \ +-H "Content-Type: application/json" \ +-H "Authorization: Bearer " \ +-d '{"method": "Filecoin.MarketListIncompleteDeals","params":[], "id": 0}' > lotus_miner_deals.json +``` + +执行完命令后,你可能得到如下结果: + +``` +{"jsonrpc":"2.0","result":[{"Proposal":{"PieceCID":{"/":"baga6ea4seaqcrddjqzqavqipgljq6jn3bmbnhzw5yucdmoqoji3tni6kisjqini"},"PieceSize":128,"VerifiedDeal":false,"Client":"t3r3nyp4sitvilwc5wggvrsyoqmue3zgliqsqzqxri5up2fmlx2e5xeltxv4qbokjj6qrdgz3t7zdwygogpjaa","Provider":"t01000","Label":"uAVUAHOi_meaYr-eUqOadpea1i-ivleeahOaVsOaNrgo","StartEpoch":173482,"EndEpoch":694737,"StoragePricePerEpoch":"0", +...... +":"bafkqahhix6m6ngfp46kkrzu5uxtllc7iv6k6pgue42k3bzunvyfa"},"PieceCid":{"/":"baga6ea4seaqcrddjqzqavqipgljq6jn3bmbnhzw5yucdmoqoji3tni6kisjqini"},"PieceSize":127,"RawBlockSize":0},"AvailableForRetrieval":false,"DealID":0,"CreationTime":"2022-08-03T10:35:09.774748628+08:00","TransferChannelId":null,"SectorNumber":0,"InboundCAR":""}],"id":0} +``` + +其中,`result` 中的每一项都是一个订单的详细信息。每个订单中的 `State` 字段表征了当前订单的状态,如果 `State` = 18,表示当前订单处于 `StorageDealWaitingForData` 的状态。 + +### 将订单导入到 `droplet` + +开始导入订单之前,先确认矿工账号是否在 `venus` 链服务中,如果不在,需要将矿工账号迁入 `venus` 链服务。 + +```bash +./droplet actor list +``` + +确定完矿工之后,在 `droplet` 中可以直接通过命令导入订单: + +```bash +./droplet storage deal import-deal lotus_miner_deals.json + +# 结果 +import 2 deals success +``` + +## 从 boost 迁移订单 + +### 从 boost 导出订单 + +boost 支持两种发单协议,暂且称之为新老协议,用户发单时两种协议可能都使用到了,所以需要分两步导出订单。 + +#### 导出老协议订单 + +通过接口导出订单,此次导出和从 `lotus-miner` 导出订单很类似,参考例子: + +> `TOKEN` 是 `boost` 生成的 token,可以通过命令 `./boostd auth create-token --perm admin` 生成。 + +```bash +curl http://127.0.0.1:1288/rpc/v0 -X POST \ +-H "Content-Type: application/json" \ +-H "Authorization: Bearer " \ +-d '{"method": "Filecoin.MarketListIncompleteDeals","params":[], "id": 0}' > boost_old_deals.json +``` + +#### 导出新协议订单 + +1. 先确定有多少订单 + +```bash +curl -X POST -H "Content-Type: application/json" -d '{"query":"query { dealsCount() }"}' http://localhost:8080/graphql/query | jq + +# 结果 + +{ + "data": { + "dealsCount": 2 + } +} +``` + +返回结果中 `dealsCount` 的值就是现有订单数量。 + +2. 导出全部订单 + +> 下面查询中 `limit` 字段的值是 10000000,最多获取到 10000000 条订单,需要大于现有的订单数量。 + +```bash +curl -X POST \ +-H "Content-Type: application/json" \ +-d '{"query":"query { deals(limit: 10000000) { totalCount deals { ID ClientAddress ProviderAddress CreatedAt PieceCid PieceSize IsVerified ProposalLabel ProviderCollateral ClientCollateral StoragePricePerEpoch StartEpoch EndEpoch ClientPeerID DealDataRoot SignedProposalCid InboundFilePath ChainDealID PublishCid IsOffline Transfer { Type Size } IsTransferStalled Checkpoint Err Sector { ID Offset Length } Message } } }"}' \ +http://localhost:8080/graphql/query | jq > boost_deals.json +``` + +### 导入订单 + +开始导入订单之前,先确认矿工账号是否在 `venus` 链服务中,如果不在,需要将矿工账号迁入 `venus` 链服务。 + +```bash +./droplet actor list +``` + +1. 导入老协议订单 + +```bash +./droplet storage deal import-deal boost_old_deals.json + +# 结果 +import 2 deals success +``` + +2. 导入新协议订单 + +```bash +./droplet storage deal import-deal --from boost boost_deals.json + +# 结果 +import 3 deals success +``` + +> --car-dirs 指定car文件的目录,可以设置多个:--car-dirs /tmp/cars --car-dirs /tmp/cars2,程序会根据 piece cid 来获取订单 payload size + +> payload size 在生成索引的时候会用到 + +如果导入过程遇到 `deal bafyreih7qaddtjxu66khjohckd3gkp42p3x5i2fhw5xjw325rnb7wvje7q payload size 0`,则说明有的订单的 `payload size` 是 `0`,这样的订单不会导入。可以通过设置 `--car-dirs`,让程序根据 `piece cid` 去获取 `payload size` 来解决这个问题。 diff --git a/go.mod b/go.mod index 8ed3eafd..7f373d78 100644 --- a/go.mod +++ b/go.mod @@ -30,11 +30,12 @@ require ( github.com/filecoin-project/go-statestore v0.2.0 github.com/filecoin-project/specs-actors/v2 v2.3.6 github.com/filecoin-project/specs-actors/v7 v7.0.1 - github.com/filecoin-project/venus v1.11.2-0.20230607091503-26f810cf09b9 + github.com/filecoin-project/venus v1.11.2-0.20230609030445-d8ba39cc8a85 github.com/golang/mock v1.6.0 github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.8.0 github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e + github.com/hashicorp/go-multierror v1.1.1 github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef github.com/ipfs-force-community/metrics v1.0.1-0.20220824061112-ac916bacf2ea github.com/ipfs-force-community/sophon-auth v1.11.1-0.20230607031351-bc57c2b78f44 @@ -169,7 +170,6 @@ require ( github.com/gorilla/websocket v1.5.0 // indirect github.com/hannahhoward/cbor-gen-for v0.0.0-20200817222906-ea96cece81f1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect diff --git a/go.sum b/go.sum index 95f31399..24f46fcb 100644 --- a/go.sum +++ b/go.sum @@ -468,8 +468,8 @@ github.com/filecoin-project/storetheindex v0.4.30-0.20221114113647-683091f8e893 github.com/filecoin-project/storetheindex v0.4.30-0.20221114113647-683091f8e893/go.mod h1:S7590oDimBvXMUtzWsBXoshu9HtYKwtXl47zAK9rcP8= github.com/filecoin-project/test-vectors/schema v0.0.5/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E= github.com/filecoin-project/venus v1.2.4/go.mod h1:hJULXHGAnWuq5S5KRtPkwbT8DqgM9II7NwyNU7t59D0= -github.com/filecoin-project/venus v1.11.2-0.20230607091503-26f810cf09b9 h1:Zw0TrPNELEnN+Ylu2R6nv+01RG4Gubn0r+x50qP5Ems= -github.com/filecoin-project/venus v1.11.2-0.20230607091503-26f810cf09b9/go.mod h1:2Q7xc4lWRFxK40NicPERVnZLemUnE8umWVFGotSq50s= +github.com/filecoin-project/venus v1.11.2-0.20230609030445-d8ba39cc8a85 h1:l6rRiKdnZ+daoljPROXh/XmPX/Ef7QzyVogkdM8OZHM= +github.com/filecoin-project/venus v1.11.2-0.20230609030445-d8ba39cc8a85/go.mod h1:2Q7xc4lWRFxK40NicPERVnZLemUnE8umWVFGotSq50s= github.com/filecoin-project/venus-auth v1.3.2/go.mod h1:m5Jog2GYxztwP7w3m/iJdv/V1/bTcAVU9rm/CbhxRQU= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= diff --git a/models/badger/storage_deal.go b/models/badger/storage_deal.go index 2eb7c82c..3b3ee383 100644 --- a/models/badger/storage_deal.go +++ b/models/badger/storage_deal.go @@ -26,6 +26,16 @@ func NewStorageDealRepo(ds StorageDealsDS) repo.StorageDealRepo { return &storageDealRepo{ds} } +func (sdr *storageDealRepo) CreateDeals(ctx context.Context, storageDeals []*types.MinerDeal) error { + for _, storageDeal := range storageDeals { + if err := sdr.SaveDeal(ctx, storageDeal); err != nil { + return err + } + } + + return nil +} + func (sdr *storageDealRepo) SaveDeal(ctx context.Context, storageDeal *types.MinerDeal) error { storageDeal.TimeStamp = makeRefreshedTimeStamp(&storageDeal.TimeStamp) b, err := cborrpc.Dump(storageDeal) diff --git a/models/badger/storage_deal_test.go b/models/badger/storage_deal_test.go index f3f20384..92c19e0a 100644 --- a/models/badger/storage_deal_test.go +++ b/models/badger/storage_deal_test.go @@ -40,6 +40,20 @@ func prepareStorageDealTest(t *testing.T) (context.Context, repo.StorageDealRepo return ctx, r, dealCases } +func TestCreateStorageDeals(t *testing.T) { + ctx, r, dealCases := prepareStorageDealTest(t) + + deals := make([]*markettypes.MinerDeal, 0, len(dealCases)) + for i := range dealCases { + deals = append(deals, &dealCases[i]) + } + assert.NoError(t, r.CreateDeals(ctx, deals)) + + ret, err := r.ListDeal(ctx, &markettypes.StorageDealQueryParams{Page: markettypes.Page{Limit: 11}}) + assert.NoError(t, err) + assert.Len(t, ret, 10) +} + func TestSaveStorageDeal(t *testing.T) { ctx, r, dealCases := prepareStorageDealTest(t) diff --git a/models/mysql/storage_deal.go b/models/mysql/storage_deal.go index f9e491ca..58a735cd 100644 --- a/models/mysql/storage_deal.go +++ b/models/mysql/storage_deal.go @@ -302,6 +302,19 @@ func NewStorageDealRepo(db *gorm.DB) repo.StorageDealRepo { return &storageDealRepo{db} } +func (sdr *storageDealRepo) CreateDeals(ctx context.Context, deals []*types.MinerDeal) error { + storageDeals := make([]*storageDeal, 0, len(deals)) + for _, deal := range deals { + storageDeal := fromStorageDeal(deal) + storageDeal.TimeStampOrm.Refresh() + storageDeals = append(storageDeals, storageDeal) + } + + return sdr.WithContext(ctx).Clauses( + clause.OnConflict{Columns: []clause.Column{{Name: "proposal_cid"}}, UpdateAll: true}). + CreateInBatches(storageDeals, 100).Error +} + func (sdr *storageDealRepo) SaveDeal(ctx context.Context, storageDeal *types.MinerDeal) error { deal := fromStorageDeal(storageDeal) deal.TimeStampOrm.Refresh() diff --git a/models/repo/repo.go b/models/repo/repo.go index 15e1f44f..cb273781 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -28,6 +28,7 @@ type FundRepo interface { } type StorageDealRepo interface { + CreateDeals(ctx context.Context, deals []*types.MinerDeal) error SaveDeal(ctx context.Context, StorageDeal *types.MinerDeal) error UpdateDealStatus(ctx context.Context, proposalCid cid.Cid, status storagemarket.StorageDealStatus, pieceState types.PieceStatus) error diff --git a/storageprovider/storage_provider.go b/storageprovider/storage_provider.go index 73b72e4d..20595ae1 100644 --- a/storageprovider/storage_provider.go +++ b/storageprovider/storage_provider.go @@ -9,6 +9,7 @@ import ( "os" "time" + "github.com/hashicorp/go-multierror" "github.com/ipfs-force-community/metrics" "go.uber.org/fx" @@ -118,8 +119,8 @@ type StorageProvider interface { // ImportPublishedDeal manually import published deals to storage deals ImportPublishedDeal(ctx context.Context, deal types.MinerDeal) error - // ImportOfflineDeal manually import offline deals to storage deals - ImportOfflineDeal(ctx context.Context, deal types.MinerDeal) error + // ImportDeals manually import deals to storage deals + ImportDeals(ctx context.Context, deal map[address.Address][]*types.MinerDeal) error // SubscribeToEvents listens for events that happen related to storage deals on a provider SubscribeToEvents(subscriber ProviderSubscriber) shared.Unsubscribe @@ -633,48 +634,48 @@ func (p *StorageProviderImpl) ImportPublishedDeal(ctx context.Context, deal type return p.dealStore.SaveDeal(ctx, improtDeal) } -// ImportPublishedDeal manually import published deals for an storage deal -func (p *StorageProviderImpl) ImportOfflineDeal(ctx context.Context, deal types.MinerDeal) error { - // check deal state - if deal.State != storagemarket.StorageDealWaitingForData { - return fmt.Errorf("deal state %s not match %s", storagemarket.DealStates[deal.State], storagemarket.DealStates[storagemarket.StorageDealWaitingForData]) - } - - // check transfer type - if deal.Ref.TransferType != storagemarket.TTManual { - return fmt.Errorf("transfer type %s not match %s", deal.Ref.TransferType, storagemarket.TTManual) - } - - // check if miner exit - if !p.minerMgr.Has(ctx, deal.Proposal.Provider) { - return fmt.Errorf("miner %s not support", deal.Proposal.Provider) - } - - // check if local exit the deal - if _, err := p.dealStore.GetDeal(ctx, deal.ProposalCid); err == nil { - return fmt.Errorf("deal exist proposal cid %s id %d", deal.ProposalCid, deal.DealID) - } else if !errors.Is(err, repo.ErrNotFound) { - return err - } - - // check client signature +// ImportDeals manually import deals +func (p *StorageProviderImpl) ImportDeals(ctx context.Context, deals map[address.Address][]*types.MinerDeal) error { tok, _, err := p.spn.GetChainHead(ctx) if err != nil { - p.eventPublisher.Publish(storagemarket.ProviderEventNodeErrored, &deal) return fmt.Errorf("node error getting most recent state id: %w", err) } - if err := providerutils.VerifyProposal(ctx, deal.ClientDealProposal, tok, p.spn.VerifySignature); err != nil { - p.eventPublisher.Publish(storagemarket.ProviderEventNodeErrored, &deal) - return fmt.Errorf("verifying StorageDealProposal: %w", err) - } + var errs *multierror.Error + for provider, d := range deals { + pendingDeals := make([]*types.MinerDeal, 0, len(d)) - err = p.dealStore.SaveDeal(ctx, &deal) - if err != nil { - return fmt.Errorf("save miner deal to database %w", err) + if !p.minerMgr.Has(ctx, provider) { + errs = multierror.Append(errs, fmt.Errorf("miner %s not support", provider)) + continue + } + + for _, deal := range d { + _, err := p.dealStore.GetDeal(ctx, deal.ProposalCid) + if err == nil { + errs = multierror.Append(errs, fmt.Errorf("deal exist: %s", deal.ProposalCid)) + } else if !errors.Is(err, repo.ErrNotFound) { + return err + } + + // todo: The ClientSignature of the boost deal cannot be obtained currently + if len(deal.ClientDealProposal.ClientSignature.Data) != 0 { + err := providerutils.VerifyProposal(ctx, deal.ClientDealProposal, tok, p.spn.VerifySignature) + if err != nil { + errs = multierror.Append(errs, fmt.Errorf("verify %s proposal failed: %v", deal.ProposalCid, err)) + continue + } + } + pendingDeals = append(pendingDeals, deal) + } + + err = p.dealStore.CreateDeals(ctx, pendingDeals) + if err != nil { + return fmt.Errorf("save miner %s deal to database %v", provider, err) + } } - return nil + return errs.ErrorOrNil() } // AddStorageCollateral adds storage collateral diff --git a/storageprovider/storageprovider_test.go b/storageprovider/storageprovider_test.go deleted file mode 100644 index 95157295..00000000 --- a/storageprovider/storageprovider_test.go +++ /dev/null @@ -1,299 +0,0 @@ -package storageprovider - -import ( - "context" - _ "embed" - "encoding/json" - "fmt" - "sync" - "testing" - - "github.com/ipfs/go-cid" - "github.com/stretchr/testify/assert" - "go.uber.org/fx/fxtest" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-fil-markets/filestore" - "github.com/filecoin-project/go-fil-markets/shared" - "github.com/filecoin-project/go-fil-markets/storagemarket" - "github.com/filecoin-project/go-fil-markets/storagemarket/network" - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/go-state-types/crypto" - "github.com/filecoin-project/go-state-types/exitcode" - - "github.com/ipfs-force-community/droplet/v2/config" - "github.com/ipfs-force-community/droplet/v2/minermgr" - "github.com/ipfs-force-community/droplet/v2/models" - network2 "github.com/ipfs-force-community/droplet/v2/network" - "github.com/ipfs-force-community/droplet/v2/piecestorage" - - vCrypto "github.com/filecoin-project/venus/pkg/crypto" - _ "github.com/filecoin-project/venus/pkg/crypto/bls" - _ "github.com/filecoin-project/venus/pkg/crypto/secp" - "github.com/filecoin-project/venus/venus-shared/api/chain/v1/mock" - "github.com/filecoin-project/venus/venus-shared/types" - marketypes "github.com/filecoin-project/venus/venus-shared/types/market" -) - -//go:embed testdata/import_deal.json -var importDataJsonString []byte - -type publishdealCase struct { - Proposal *marketypes.MinerDeal - Result bool -} - -type importOfflineDealResult int - -const ( - success importOfflineDealResult = iota - dealExists - minerNotFound - signatureInvalid - dealStatusInvalid - transferTypeInvalid -) - -type offlinedealCase struct { - Proposal *marketypes.MinerDeal - Result importOfflineDealResult -} - -type testGroud struct { - DealsOnChain map[abi.DealID]types.MarketDeal - PublishDealCases []*publishdealCase - OfflineDealCase []*offlinedealCase -} - -func TestStorageProviderImpl_ImportPublishedDeal(t *testing.T) { - provider := setup(t) - ctx := context.Background() - - var testGround testGroud - err := json.Unmarshal(importDataJsonString, &testGround) - if err != nil { - t.Error(err) - } - for _, c := range testGround.PublishDealCases { - err = provider.ImportPublishedDeal(ctx, *c.Proposal) - assert.Equal(t, c.Result, err == nil, "ProposalCid: %v, err: %v", c.Proposal.ProposalCid, err) - } -} - -func TestStorageProviderImpl_ImportOfflineDeal(t *testing.T) { - provider := setup(t) - ctx := context.Background() - - var testGround testGroud - err := json.Unmarshal(importDataJsonString, &testGround) - if err != nil { - t.Error(err) - } - for _, c := range testGround.OfflineDealCase { - err = provider.ImportOfflineDeal(ctx, *c.Proposal) - switch c.Result { - case success: - assert.NoError(t, err) - t.Log("Success") - case dealExists: - assert.Contains(t, err.Error(), "deal exist") - t.Logf("DealExists: %v", err) - case minerNotFound: - assert.Contains(t, err.Error(), fmt.Sprintf("miner %s not support", c.Proposal.Proposal.Provider.String())) - t.Logf("MinerNotFound: %v", err) - case signatureInvalid: - assert.Contains(t, err.Error(), "verifying StorageDealProposal") - t.Logf("SignatureInvalid: %v", err) - case dealStatusInvalid: - assert.Contains(t, err.Error(), "deal state") - t.Logf("DealStatusInvalid: %v", err) - case transferTypeInvalid: - assert.Contains(t, err.Error(), "transfer type") - t.Logf("TransferTypeInvalid: %v", err) - } - } -} - -func setup(t *testing.T) StorageProvider { - lc := fxtest.NewLifecycle(t) - ctx := context.Background() - spn := newMockProviderNode() - - var testGround testGroud - err := json.Unmarshal(importDataJsonString, &testGround) - if err != nil { - t.Error(err) - } - - for did, c := range testGround.DealsOnChain { - spn.addDeal(ctx, did, c) - } - - r := models.NewInMemoryRepo(t) - ask, _ := NewStorageAsk(spn, r, spn) - h, err := network2.MockHost(ctx) - if err != nil { - t.Error(err) - } - dt, err := network2.MockDataTransfer(ctx, h) - if err != nil { - t.Error(err) - } - - psManager, err := piecestorage.NewPieceStorageManager(&config.PieceStorage{}) - assert.Nil(t, err) - psManager.AddMemPieceStorage(piecestorage.NewMemPieceStore("", nil)) - addrMgr := mockAddrMgr{} - - // todo how to mock dagstore - tf := func(address.Address) (filestore.FileStore, error) { - transferPath := config.DefaultMarketConfig.MustHomePath() - store, err := filestore.NewLocalFileStore(filestore.OsPath(transferPath)) - if err != nil { - return nil, err - } - return store, nil - } - provider, err := NewStorageProvider(ctx, lc, ask, h, tf, psManager, dt, spn, nil, r, addrMgr, nil, nil, NewEventPublishAdapter(r)) - if err != nil { - t.Error(err) - } - return provider -} - -type mockAddrMgr struct{} - -var _ minermgr.IMinerMgr = (*mockAddrMgr)(nil) - -func (m mockAddrMgr) Has(ctx context.Context, addr address.Address) bool { - return addr.String() == "t01043" || addr.String() == "t010938" -} - -func (m mockAddrMgr) ActorList(ctx context.Context) ([]marketypes.User, error) { - //TODO implement me - panic("implement me") -} - -func (m mockAddrMgr) ActorUpsert(_ context.Context, _ marketypes.User) (bool, error) { - panic("implement me") -} - -func (m mockAddrMgr) ActorDelete(_ context.Context, _ address.Address) error { - panic("implement me") -} - -type mockProviderNode struct { - mock.MockFullNode - dataLk sync.Mutex - data map[abi.DealID]types.MarketDeal - head *types.TipSet -} - -var _ StorageProviderNode = (*mockProviderNode)(nil) - -func newMockProviderNode() *mockProviderNode { - return &mockProviderNode{ - MockFullNode: mock.MockFullNode{}, - dataLk: sync.Mutex{}, - data: make(map[abi.DealID]types.MarketDeal), - head: nil, - } -} - -func (m *mockProviderNode) addDeal(ctx context.Context, dealID abi.DealID, deal types.MarketDeal) { - m.dataLk.Lock() - defer m.dataLk.Unlock() - m.data[dealID] = deal -} - -func (m *mockProviderNode) StateMarketStorageDeal(ctx context.Context, dealID abi.DealID, tsk types.TipSetKey) (*types.MarketDeal, error) { - m.dataLk.Lock() - defer m.dataLk.Unlock() - if marketDeal, ok := m.data[dealID]; ok { - return &marketDeal, nil - } - return nil, fmt.Errorf("unable to find deal %d", dealID) -} - -func (m *mockProviderNode) GetChainHead(ctx context.Context) (shared.TipSetToken, abi.ChainEpoch, error) { - head, err := m.ChainHead(ctx) - if err != nil { - return nil, 0, err - } - - return head.Key().Bytes(), head.Height(), nil -} - -func (m *mockProviderNode) VerifySignature(ctx context.Context, signature crypto.Signature, signer address.Address, plaintext []byte, tok shared.TipSetToken) (bool, error) { - err := vCrypto.Verify(&signature, signer, plaintext) - return err == nil, err -} - -func (m *mockProviderNode) ChainHead(ctx context.Context) (*types.TipSet, error) { - return m.head, nil -} - -func (m *mockProviderNode) Sign(ctx context.Context, data interface{}) (*crypto.Signature, error) { - // TODO implement me - panic("implement me") -} - -func (m *mockProviderNode) SignWithGivenMiner(mAddr address.Address) network.ResigningFunc { - // TODO implement me - panic("implement me") -} - -func (m *mockProviderNode) AddFunds(ctx context.Context, addr address.Address, amount abi.TokenAmount) (cid.Cid, error) { - // TODO implement me - panic("implement me") -} - -func (m *mockProviderNode) ReserveFunds(ctx context.Context, wallet, addr address.Address, amt abi.TokenAmount) (cid.Cid, error) { - // TODO implement me - panic("implement me") -} - -func (m *mockProviderNode) ReleaseFunds(ctx context.Context, addr address.Address, amt abi.TokenAmount) error { - // TODO implement me - panic("implement me") -} - -func (m *mockProviderNode) GetBalance(ctx context.Context, addr address.Address, tok shared.TipSetToken) (storagemarket.Balance, error) { - // TODO implement me - panic("implement me") -} - -func (m *mockProviderNode) WaitForMessage(ctx context.Context, mcid cid.Cid, onCompletion func(exitcode.ExitCode, []byte, cid.Cid, error) error) error { - // TODO implement me - panic("implement me") -} - -func (m *mockProviderNode) DealProviderCollateralBounds(ctx context.Context, provider address.Address, size abi.PaddedPieceSize, isVerified bool) (abi.TokenAmount, abi.TokenAmount, error) { - // TODO implement me - panic("implement me") -} - -func (m *mockProviderNode) PublishDeals(ctx context.Context, deal marketypes.MinerDeal) (cid.Cid, error) { - // TODO implement me - panic("implement me") -} - -func (m *mockProviderNode) WaitForPublishDeals(ctx context.Context, mcid cid.Cid, proposal types.DealProposal) (*storagemarket.PublishDealsWaitResult, error) { - //TODO implement me - panic("implement me") -} - -func (m *mockProviderNode) GetMinerWorkerAddress(ctx context.Context, addr address.Address, tok shared.TipSetToken) (address.Address, error) { - // TODO implement me - panic("implement me") -} - -func (m *mockProviderNode) GetDataCap(ctx context.Context, addr address.Address, tok shared.TipSetToken) (*abi.StoragePower, error) { - // TODO implement me - panic("implement me") -} - -func (m *mockProviderNode) GetProofType(ctx context.Context, addr address.Address, tok shared.TipSetToken) (abi.RegisteredSealProof, error) { - // TODO implement me - panic("implement me") -} diff --git a/storageprovider/testdata/import_deal.json b/storageprovider/testdata/import_deal.json deleted file mode 100644 index 2dd87db9..00000000 --- a/storageprovider/testdata/import_deal.json +++ /dev/null @@ -1,1365 +0,0 @@ -{ - "DealsOnChain": { - "2927": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqc2eglek7x4wr5zlfvgdhxyir63b7arckn2qanmioavu4rmn4f2pa" - }, - "PieceSize": 512, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAVWg5AIgjonvGOXDFu/VMFAqXh7W0YBgJS0DWbT5UeoGt+1NXXU", - "StartEpoch": 38719, - "EndEpoch": 561138, - "StoragePricePerEpoch": "4768371", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "State": { - "SectorStartEpoch": 0, - "LastUpdatedEpoch": 0, - "SlashEpoch": 0 - } - }, - "2945": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqfljcgp3vmrydptut4ngegccq6dqqcecqdmlebyxuhzsobznuh2li" - }, - "PieceSize": 4096, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAVWg5AIgb1556KkZAHn5fSGPL+Ge2mrYuLTrL3GesNrDwBbwC0o", - "StartEpoch": 40805, - "EndEpoch": 564018, - "StoragePricePerEpoch": "38146972", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "State": { - "SectorStartEpoch": 0, - "LastUpdatedEpoch": 0, - "SlashEpoch": 0 - } - }, - "3041": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqggbyhlyx6psykhb4u45co5yupldi7lwyx2b6vwszq2sgdtcvvkbi" - }, - "PieceSize": 268435456, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAXCg5AIg8XTLzo5XXEBqw2gBj8pvfJczBTuRMv+b+f5fFIXvg6E", - "StartEpoch": 52913, - "EndEpoch": 575538, - "StoragePricePerEpoch": "2500000000000", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "State": { - "SectorStartEpoch": 0, - "LastUpdatedEpoch": 0, - "SlashEpoch": 0 - } - }, - "3043": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqmzanhx32z5bui32q6oex7gwel5sxzpwpozaye2i6ggdgcx3ypgpq" - }, - "PieceSize": 67108864, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAXCg5AIgoXIDf0ewLF32+a8/A0GQHc7mwxBsxcZZKJyQf9BzsO4", - "StartEpoch": 61890, - "EndEpoch": 1116978, - "StoragePricePerEpoch": "625000000000", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "State": { - "SectorStartEpoch": 0, - "LastUpdatedEpoch": 0, - "SlashEpoch": 0 - } - }, - "3045": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqnxaqz3vx63uvn2yctsj2r6ywfctdoutsvhempq2zjapeu5aztydy" - }, - "PieceSize": 134217728, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAXCg5AIgPRl6/280d+qDS3CvkqG4yjxrTlslnVai0vK2QGHPn5w", - "StartEpoch": 70690, - "EndEpoch": 592818, - "StoragePricePerEpoch": "1250000000000", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "State": { - "SectorStartEpoch": 0, - "LastUpdatedEpoch": 0, - "SlashEpoch": 0 - } - }, - "3068": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqnxaqz3vx63uvn2yctsj2r6ywfctdoutsvhempq2zjapeu5aztydy" - }, - "PieceSize": 134217728, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01087", - "Label": "mAXCg5AIgPRl6/280d+qDS3CvkqG4yjxrTlslnVai0vK2QGHPn5w", - "StartEpoch": 95593, - "EndEpoch": 617332, - "StoragePricePerEpoch": "1250000000000", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "State": { - "SectorStartEpoch": 0, - "LastUpdatedEpoch": 0, - "SlashEpoch": 0 - } - }, - "3074": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqlgver3hs7wgnugaa44noqfhb4d2uzzpjbe6525pdpjtiujojlgdy" - }, - "PieceSize": 4096, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01087", - "Label": "mAVWg5AIg7xjA2StduKMyfboSXPRNYqjT2BvCFIXSR5OpXCKhCAQ", - "StartEpoch": 122022, - "EndEpoch": 643252, - "StoragePricePerEpoch": "38146", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "State": { - "SectorStartEpoch": 0, - "LastUpdatedEpoch": 0, - "SlashEpoch": 0 - } - }, - "3075": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqcjpecsmsbhgoqha2ndnwydspo4ytkxsmklauwk4mxyuqwtkejipa" - }, - "PieceSize": 32768, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01087", - "Label": "mAVWg5AIg+GPyU8uwmEXqWdkEyWnRZ/lsj8DZ3KlXRcLLWk/k8/8", - "StartEpoch": 125108, - "EndEpoch": 646132, - "StoragePricePerEpoch": "305175", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "State": { - "SectorStartEpoch": 0, - "LastUpdatedEpoch": 0, - "SlashEpoch": 0 - } - } - }, - "PublishDealCases": [ - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqpgm43ngtkpxau6ro47hojfn7auwbuszn7t742mkvvqr7tflyeuii" - }, - "PieceSize": 256, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAVWg5AIgkuCD5PQexo8Zz3tjRRATbaJe/LW9xskb8c4V03xIECI", - "StartEpoch": 52906, - "EndEpoch": 578418, - "StoragePricePerEpoch": "2384185", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "IqUnPJFKW7cw06IRqlwa+WO5jpdRU+nhoWITiEswBy9vN4EcYCPXYd3bXxcweE4WP72hUHCuKWP7PtqJP11GCgE=" - }, - "ProposalCid": { - "/": "bafyreibhxmoyvmrup2ihk3j4qfedmw7dbow2hzflhfpkrnjn5mtpog6rqy" - }, - "AddFundsCid": null, - "PublishCid": null, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 10, - "PiecePath": "", - "PayloadSize": 0, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "piece size less than minimum required size: 256 \u003c 512", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafk2bzacecjoba7e6qpmndyzz55wgriqcnw2exx4ww64nsi36hhblu34jaice" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": false, - "DealID": 0, - "CreationTime": "2022-02-15T14:16:08.914622409+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": false - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqpgm43ngtkpxau6ro47hojfn7auwbuszn7t742mkvvqr7tflyeuii" - }, - "PieceSize": 256, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAVWg5AIgkuCD5PQexo8Zz3tjRRATbaJe/LW9xskb8c4V03xIECI", - "StartEpoch": 52890, - "EndEpoch": 1093938, - "StoragePricePerEpoch": "2384185", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "jGl7mUr1u0FLUfPUd1Fq48bsVqZTS04hELtwCxddVEZ3B5X9a8AMk4cXWMaLp3yP1LKsQMYNsbWu3e6enbDx1AE=" - }, - "ProposalCid": { - "/": "bafyreibw4kozb2wdlo3hccrmpgifexodlvvjevygngiuaomnzp3u2wgm2y" - }, - "AddFundsCid": null, - "PublishCid": null, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 10, - "PiecePath": "", - "PayloadSize": 0, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "incorrect provider for deal", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafk2bzacecjoba7e6qpmndyzz55wgriqcnw2exx4ww64nsi36hhblu34jaice" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": false, - "DealID": 0, - "CreationTime": "2022-02-15T14:08:13.91119198+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": false - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqggbyhlyx6psykhb4u45co5yupldi7lwyx2b6vwszq2sgdtcvvkbi" - }, - "PieceSize": 268435456, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAXCg5AIg8XTLzo5XXEBqw2gBj8pvfJczBTuRMv+b+f5fFIXvg6E", - "StartEpoch": 52913, - "EndEpoch": 575538, - "StoragePricePerEpoch": "2500000000000", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "7klHmvR2RrF5JblnwmPS3PNuld1UZRuIldqEeNjDsmtNeQbLdIcfp7cUUq3RwlfkBcBAsMLxbvZVb9xp3/5kHwE=" - }, - "ProposalCid": { - "/": "bafyreicrpph5nkwcq266hgdfolokgoqfvb3kn7eeakvylaisgm77yoc35e" - }, - "AddFundsCid": null, - "PublishCid": { - "/": "bafk4bzacibn356s5uop5rdqchqh7rhhgnzowx5xrwbjzwonje5vymthaq3n72cmprmpp6g67rdd7lfsx2asc24coqk7t5hpqyw7idnjr65i6trbm" - }, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 7, - "PiecePath": "", - "PayloadSize": 133793255, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "ProposalCid not match the calculated result", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafykbzacedyxjs6orzlvyqdkynuadd6kn56jomyfhoitf7437h7f6fef56b2c" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": true, - "DealID": 3041, - "CreationTime": "2022-02-15T14:19:57.197297369+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": false - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqlgver3hs7wgnugaa44noqfhb4d2uzzpjbe6525pdpjtiujojlgdy" - }, - "PieceSize": 4096, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01087", - "Label": "mAVWg5AIg7xjA2StduKMyfboSXPRNYqjT2BvCFIXSR5OpXCKhCAQ", - "StartEpoch": 122022, - "EndEpoch": 643252, - "StoragePricePerEpoch": "38146", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "xhklZHMzFrDBBqw+1i55OssHWtLBSfGSg8ChYrOJzgIX8PQqW8WUaMWergeWR48gk99niVe+GVDaeaIHupRMaQA=" - }, - "ProposalCid": { - "/": "bafyreidwjblgyhs2wehz76s74dn5atn5ck3gamkahm6ag5mrpzhzfinrim" - }, - "AddFundsCid": null, - "PublishCid": { - "/": "bafk4bzacicp2ze4nt62sw7wr3siesfr76g35mtjt2dfnkqj72gkebc6hqc5z6yczvnghdbdpgvf6cc66tlrbtjjudzchm5tden6hxjxonx3lfcks" - }, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 7, - "PiecePath": "", - "PayloadSize": 3431, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafk2bzacedxrrqgzfno3rizspw5bexhujvrkru6ydpbbjbosi6j2sxbcueeai" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": true, - "DealID": 3074, - "CreationTime": "2022-03-11T14:14:15.88109691+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": false - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqfljcgp3vmrydptut4ngegccq6dqqcecqdmlebyxuhzsobznuh2li" - }, - "PieceSize": 4096, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAVWg5AIgb1556KkZAHn5fSGPL+Ge2mrYuLTrL3GesNrDwBbwC0o", - "StartEpoch": 40805, - "EndEpoch": 564018, - "StoragePricePerEpoch": "38146972", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "l0dRk4LaShO/RJP2i/VyYbiHM1a+R+KcyIP0OKa5uS8EgzFvgiylqaMpoJAPSQt1mNeF1kRwZVn9eRHXrzJmQAA=" - }, - "ProposalCid": { - "/": "bafyreidymcdkr6cwa4gtop2ele5u3nrpwfwthv47qv5cbt7wzr5w7vxzee" - }, - "AddFundsCid": null, - "PublishCid": { - "/": "bafk4bzacib5mcqgazmachesc344dc2ihml2g6d7yhgmkjb5377jfijg3pblg4f43kmbaqctpt27jeiqlcn3kotimiiomqq67knv6nqorvk5ytcij" - }, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 7, - "PiecePath": "", - "PayloadSize": 3227, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "ProposalCid not match the calculated result", - "Root": { - "/": "bafk2bzacebxv46pivemqa6pzpuqy6l7bt3ngvwfywtvs64m6wdnmhqaw6afuu" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": true, - "DealID": 2945, - "CreationTime": "2022-02-11T09:25:54.087539616+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": false - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqmv6lt2ndrwtd5yzidaqntblijcen276alhzhspp46vpkzfefzoci" - }, - "PieceSize": 32768, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAVWg5AIgTGPmE+dTIXoUTvFR544TMGdcIAiTXnFavVUEGx9Scdo", - "StartEpoch": 52876, - "EndEpoch": 575538, - "StoragePricePerEpoch": "305175781", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "MnU0sLXF+4MWlGc96aLrY6iOmI7VnffeQ0QzCfAWjsVTzWqlnlQSt7Onwg66H3LqQ7tszmCRgLkmWIANZ7tYSQA=" - }, - "ProposalCid": { - "/": "bafyreieittcv3ehxkb4uhmccvaphlwp2ctvmbqwvbgbpf3zvtcecgemspe" - }, - "AddFundsCid": null, - "PublishCid": null, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 10, - "PiecePath": "", - "PayloadSize": 0, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "incorrect provider for deal", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafk2bzacebgghzqt45jsc6quj3yvdz4ocmygoxbabcjv44k2xvkqigy7kjy5u" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": false, - "DealID": 0, - "CreationTime": "2022-02-15T14:01:07.028322874+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": false - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqnxaqz3vx63uvn2yctsj2r6ywfctdoutsvhempq2zjapeu5aztydy" - }, - "PieceSize": 134217728, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAXCg5AIgPRl6/280d+qDS3CvkqG4yjxrTlslnVai0vK2QGHPn5w", - "StartEpoch": 70690, - "EndEpoch": 592818, - "StoragePricePerEpoch": "1250000000000", - "ProviderCollateral": "10", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "RfXhxzigbEBth7zphyxS9zz8mtgDzh8Gi+hrjVWTHVVzO8bduzJgrGfJ3hoWksWHdLnbGbqmBlFmywbsbqVglgE=" - }, - "ProposalCid": { - "/": "bafyreif72iiuzzn3ktycmikwph6o3zzswwdgh27qkzvtmndnnly52n6de4" - }, - "AddFundsCid": null, - "PublishCid": { - "/": "bafk4bzacib4lc7v6qdihmtukx74nkfz6aelzya6mmshaoaw7lfjlmt4v26b3w47t7mwgjl6qi5i46yiyp6vcl4vhhfj2rrxczvumr6mag6hx6qxt" - }, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 7, - "PiecePath": "", - "PayloadSize": 129813315, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafykbzacea6rs6x7n42hp2udjnyk7evbxdfdy22olmsz2vvc2lzlmqdbz6pzy" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": true, - "DealID": 3045, - "CreationTime": "2022-02-21T18:28:03.930184575+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": false - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqnxaqz3vx63uvn2yctsj2r6ywfctdoutsvhempq2zjapeu5aztydy" - }, - "PieceSize": 134217728, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAXCg5AIgPRl6/280d+qDS3CvkqG4yjxrTlslnVai0vK2QGHPn5w", - "StartEpoch": 70690, - "EndEpoch": 592818, - "StoragePricePerEpoch": "1250000000000", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "RfXhxzigbEBth7zphyxS9zz8mtgDzh8Gi+hrjVWTHVVzO8bduzJgrGfJ3hoWksWHdLnbGbqmBlFmywbsbqVglgE=" - }, - "ProposalCid": { - "/": "bafy2bzaceaqshyk4davgz3bwqcgpe4n7yeepfeyof7zg4hlvojr67fahwewds" - }, - "AddFundsCid": null, - "PublishCid": { - "/": "bafk4bzacib4lc7v6qdihmtukx74nkfz6aelzya6mmshaoaw7lfjlmt4v26b3w47t7mwgjl6qi5i46yiyp6vcl4vhhfj2rrxczvumr6mag6hx6qxt" - }, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 7, - "PiecePath": "", - "PayloadSize": 129813315, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafykbzacea6rs6x7n42hp2udjnyk7evbxdfdy22olmsz2vvc2lzlmqdbz6pzy" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": true, - "DealID": 3045, - "CreationTime": "2022-02-21T18:28:03.930184575+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": true - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqnxaqz3vx63uvn2yctsj2r6ywfctdoutsvhempq2zjapeu5aztydy" - }, - "PieceSize": 134217728, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAXCg5AIgPRl6/280d+qDS3CvkqG4yjxrTlslnVai0vK2QGHPn5w", - "StartEpoch": 70690, - "EndEpoch": 592818, - "StoragePricePerEpoch": "1250000000000", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "RfXhxzigbEBth7zphyxS9zz8mtgDzh8Gi+hrjVWTHVVzO8bduzJgrGfJ3hoWksWHdLnbGbqmBlFmywbsbqVglgE=" - }, - "ProposalCid": { - "/": "bafyreif72iiuzzn3ktycmikwph6o3zzswwdgh27qkzvtmndnnly52n6de4" - }, - "AddFundsCid": null, - "PublishCid": { - "/": "bafk4bzacib4lc7v6qdihmtukx74nkfz6aelzya6mmshaoaw7lfjlmt4v26b3w47t7mwgjl6qi5i46yiyp6vcl4vhhfj2rrxczvumr6mag6hx6qxt" - }, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 7, - "PiecePath": "", - "PayloadSize": 129813315, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafykbzacea6rs6x7n42hp2udjnyk7evbxdfdy22olmsz2vvc2lzlmqdbz6pzy" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": true, - "DealID": 3045, - "CreationTime": "2022-02-21T18:28:03.930184575+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": false - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqc2eglek7x4wr5zlfvgdhxyir63b7arckn2qanmioavu4rmn4f2pa" - }, - "PieceSize": 512, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAVWg5AIgjonvGOXDFu/VMFAqXh7W0YBgJS0DWbT5UeoGt+1NXXU", - "StartEpoch": 38719, - "EndEpoch": 561138, - "StoragePricePerEpoch": "4768371", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "649YuoiHKzbYBBl1KWQS17fbCPpYNHNHH6A0RkeI2tQllTLuJ4rSulQcgd1ebJ78SmUtHnr3H5DP6jeGtNnpiwE=" - }, - "ProposalCid": { - "/": "bafy2bzacedsqg4x2dcl65xxthgwfxjrrcuke5jq2kokerzf4hfzt2i53qqleo" - }, - "AddFundsCid": null, - "PublishCid": { - "/": "bafk4bzacibcgcax4n6zmxkus3rxsgeilmflnjodyzpsamjmtnemmwbecj4g5yrdxsp3eu2pcdcd5fvc3aoznacfcw4qyuiusoc2j35jpe6es7cp3" - }, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 7, - "PiecePath": "", - "PayloadSize": 450, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafk2bzacechit3yy4xbrn36vgbicuxq623iyaybffubvtnhzkhvann7njvoxk" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": true, - "DealID": 2927, - "CreationTime": "2022-02-10T16:03:15.87859049+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": true - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqnxaqz3vx63uvn2yctsj2r6ywfctdoutsvhempq2zjapeu5aztydy" - }, - "PieceSize": 134217728, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01087", - "Label": "mAXCg5AIgPRl6/280d+qDS3CvkqG4yjxrTlslnVai0vK2QGHPn5w", - "StartEpoch": 95593, - "EndEpoch": 617332, - "StoragePricePerEpoch": "1250000000000", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "gPCmLewjUFV5w+Wtay0pQqJkU61g0pbLb1ppifkU4cUs9R9qqmlYqpXRzuMT9QgikIbqJH7GaZzLno+tG8R5igA=" - }, - "ProposalCid": { - "/": "bafyreig3mslo2ueoijwg6qadyklcc5frn5iyuq3q7asoojv53myavfjogq" - }, - "AddFundsCid": null, - "PublishCid": { - "/": "bafk4bzacicmxblltncpzjcri7tmlz53ycwcjmdn6rywvxf4obqkesnwijjjmnydsswegdulimkj6bbklfiuczililila26letiyfmdxyqmzaqs6o" - }, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 7, - "PiecePath": "", - "PayloadSize": 129813315, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafykbzacea6rs6x7n42hp2udjnyk7evbxdfdy22olmsz2vvc2lzlmqdbz6pzy" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": true, - "DealID": 3068, - "CreationTime": "2022-03-02T09:59:39.722058551+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": false - }, - { - "Proposal": { - "Proposal": { - "PieceSize": 67108864, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAXCg5AIgoXIDf0ewLF32+a8/A0GQHc7mwxBsxcZZKJyQf9BzsO4", - "StartEpoch": 61890, - "EndEpoch": 1116978, - "StoragePricePerEpoch": "625000000000", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "e2AgUg/ZdtRbBkkloFUOiOxCL/cGShFQwtDTr00juj1UnDyL+CXt6OBTpzTJ+vYOHIXXDstMuTfsHSI95+5C3gA=" - }, - "ProposalCid": { - "/": "bafyreigqd5mpklvmjncom6m2hmejsi5ckbe2ziaemxubsvdwrngolz6zcq" - }, - "AddFundsCid": null, - "PublishCid": { - "/": "bafk4bzacibrwh2u77bwdrankiywtzcvgqzjxrsng6vlhf5jzahg3q25jlpf7zuylvyp4cf7xlmw3lfmvbc5cx62gjn7wpyzcwk3vdk4wksgk3e4w" - }, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 7, - "PiecePath": "", - "PayloadSize": 60159769, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafykbzacecqxea37i6ycyxpw7gxt6a2bsao45zwdcbwmlrszfcoja76qooyo4" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": true, - "DealID": 3043, - "CreationTime": "2022-02-18T17:08:19.931886316+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": false - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqmzanhx32z5bui32q6oex7gwel5sxzpwpozaye2i6ggdgcx3ypgpq" - }, - "PieceSize": 67108864, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAXCg5AIgoXIDf0ewLF32+a8/A0GQHc7mwxBsxcZZKJyQf9BzsO4", - "StartEpoch": 61890, - "EndEpoch": 1116978, - "StoragePricePerEpoch": "625000000000", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "e2AgUg/ZdtRbBkkloFUOiOxCL/cGShFQwtDTr00juj1UnDyL+CXt6OBTpzTJ+vYOHIXXDstMuTfsHSI95+5C3gA=" - }, - "ProposalCid": { - "/": "bafy2bzaceacwprasdjntthip6omsnleagdflps5o6gml4yohuv376urag75ks" - }, - "AddFundsCid": null, - "PublishCid": { - "/": "bafk4bzacibrwh2u77bwdrankiywtzcvgqzjxrsng6vlhf5jzahg3q25jlpf7zuylvyp4cf7xlmw3lfmvbc5cx62gjn7wpyzcwk3vdk4wksgk3e4w" - }, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 7, - "PiecePath": "", - "PayloadSize": 60159769, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafykbzacecqxea37i6ycyxpw7gxt6a2bsao45zwdcbwmlrszfcoja76qooyo4" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": true, - "DealID": 3043, - "CreationTime": "2022-02-18T17:08:19.931886316+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": true - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqpgm43ngtkpxau6ro47hojfn7auwbuszn7t742mkvvqr7tflyeuii" - }, - "PieceSize": 256, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01043", - "Label": "mAVWg5AIgkuCD5PQexo8Zz3tjRRATbaJe/LW9xskb8c4V03xIECI", - "StartEpoch": 52903, - "EndEpoch": 633138, - "StoragePricePerEpoch": "2384185", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "PGwEogLU9tiGuZo5fdlJ5EwNxY4bUzHSGtDDlQ7ngtBrHcztIPH8FFbsZMbgROns1lGpMubTAktcMeMhi5MiCwE=" - }, - "ProposalCid": { - "/": "bafyreigywnqcwyr645vl6amzlr7l2tvcysj3maoqn6nnle3y4djradc4ze" - }, - "AddFundsCid": null, - "PublishCid": null, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 10, - "PiecePath": "", - "PayloadSize": 0, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "piece size less than minimum required size: 256 \u003c 512", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafk2bzacecjoba7e6qpmndyzz55wgriqcnw2exx4ww64nsi36hhblu34jaice" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": false, - "DealID": 0, - "CreationTime": "2022-02-15T14:14:56.277521465+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": false - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqcjpecsmsbhgoqha2ndnwydspo4ytkxsmklauwk4mxyuqwtkejipa" - }, - "PieceSize": 32768, - "VerifiedDeal": false, - "Client": "t16qnfduxzpneb2m3rbdasvhgk7rmmo32zpiypkaq", - "Provider": "t01087", - "Label": "mAVWg5AIg+GPyU8uwmEXqWdkEyWnRZ/lsj8DZ3KlXRcLLWk/k8/8", - "StartEpoch": 125108, - "EndEpoch": 646132, - "StoragePricePerEpoch": "305175", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 1, - "Data": "hYtNYe/LL2Ym+1xWsb91R2B45TyoB3WdBkpEvs1thpFHZ1Z53VVjwC+vMfzoPFEtDJxZyU5JUfI67Y5wLzhGAgE=" - }, - "ProposalCid": { - "/": "bafyreiht65hvxicoxpywtxjvigfxkjvvcbmsgqray32z4v7pr7web6uv7u" - }, - "AddFundsCid": null, - "PublishCid": { - "/": "bafk4bzacid6zrmxvzx4hu7vbe7v3njo7w7zby3bul37dfw3wpi6in6zfqrxy6ek6kd4twybejn7mhit5jbktlz3iwys5byhumacdqqkpuoqtvhg4" - }, - "Miner": "12D3KooWJXLLG3KQjSrWcaKVzssBLyEViJ1ZV34E7Hac4KRhKe5X", - "Client": "12D3KooWQDUVEXkVcpG13oexqhiVEqvhMvZPk8D91cmSjS5oCyqz", - "State": 7, - "PiecePath": "", - "PayloadSize": 22607, - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "", - "Root": { - "/": "bafk2bzaced4gh4stzoyjqrpklhmqjslj2ft7s3epydm5zkkxixbmwwsp4tz76" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": true, - "DealID": 3075, - "CreationTime": "2022-03-12T15:57:26.994488075+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "Offset": 0, - "PieceStatus": "", - "InboundCAR": "" - }, - "Result": false - } - ], - "OfflineDealCase": [ - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqd4gagvqgwo5ovankj2h5mmbkuj5555dqnk5ssaiwwfghwjoqu2iq" - }, - "PieceSize": 262144, - "VerifiedDeal": false, - "Client": "t3qowfyibovqc536f7i4u5gg3ysdjz6ly3fpepp5drwjcjvfbxnmcnzvqncx5rouramm3yseykv5hs5giugbya", - "Provider": "t010938", - "Label": "mAVWg5AIgtAc8lilWsrhuJaPxzQHEn5rAgSK2bhMAPuEf2bJUkMU", - "StartEpoch": 1070870, - "EndEpoch": 1973048, - "StoragePricePerEpoch": "400", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 2, - "Data": "joDHvKISwYJOLOJfZnzGqrBVFrZa0q9oYHONYMiTJWu9FiXXJj4P3Ssh5dXSqc6fDNlZMtC3LbDn00+mr2tJGTPKWjUK0WBqLURbZaTex9IoFxV2+7BP/6DmENBlJRuJ" - }, - "ProposalCid": { - "/": "bafyreia27jiyc7gft3wbfimqnh7mb366mdpt53u2jwn56zvxp4uhgufhh4" - }, - "AddFundsCid": null, - "PublishCid": null, - "Miner": "12D3KooWGDYDyqXFxMDjhM4ucrczRetiqmdYWhmh1vrsWZPCCRus", - "Client": "12D3KooWFvu3ZkMWjjbiZDRcEMGfNzCG55xgn7xpNdDxJPpUpdRf", - "State": 18, - "PiecePath": "", - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "manual", - "Root": { - "/": "bafk2bzacec2aopewffllfodoewr7dtibyspzvqebek3g4eyah3qr7wnsksimk" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": false, - "DealID": 0, - "CreationTime": "2022-06-22T20:36:00.735505548+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "InboundCAR": "" - }, - "Result": 0 - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqd4gagvqgwo5ovankj2h5mmbkuj5555dqnk5ssaiwwfghwjoqu2iq" - }, - "PieceSize": 262144, - "VerifiedDeal": false, - "Client": "t3qowfyibovqc536f7i4u5gg3ysdjz6ly3fpepp5drwjcjvfbxnmcnzvqncx5rouramm3yseykv5hs5giugbya", - "Provider": "t010938", - "Label": "mAVWg5AIgtAc8lilWsrhuJaPxzQHEn5rAgSK2bhMAPuEf2bJUkMU", - "StartEpoch": 1070870, - "EndEpoch": 1973048, - "StoragePricePerEpoch": "400", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 2, - "Data": "joDHvKISwYJOLOJfZnzGqrBVFrZa0q9oYHONYMiTJWu9FiXXJj4P3Ssh5dXSqc6fDNlZMtC3LbDn00+mr2tJGTPKWjUK0WBqLURbZaTex9IoFxV2+7BP/6DmENBlJRuJ" - }, - "ProposalCid": { - "/": "bafyreia27jiyc7gft3wbfimqnh7mb366mdpt53u2jwn56zvxp4uhgufhh4" - }, - "AddFundsCid": null, - "PublishCid": null, - "Miner": "12D3KooWGDYDyqXFxMDjhM4ucrczRetiqmdYWhmh1vrsWZPCCRus", - "Client": "12D3KooWFvu3ZkMWjjbiZDRcEMGfNzCG55xgn7xpNdDxJPpUpdRf", - "State": 18, - "PiecePath": "", - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "manual", - "Root": { - "/": "bafk2bzacec2aopewffllfodoewr7dtibyspzvqebek3g4eyah3qr7wnsksimk" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": false, - "DealID": 0, - "CreationTime": "2022-06-22T20:36:00.735505548+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "InboundCAR": "" - }, - "Result": 1 - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqd4gagvqgwo5ovankj2h5mmbkuj5555dqnk5ssaiwwfghwjoqu2iq" - }, - "PieceSize": 262144, - "VerifiedDeal": false, - "Client": "t3qowfyibovqc536f7i4u5gg3ysdjz6ly3fpepp5drwjcjvfbxnmcnzvqncx5rouramm3yseykv5hs5giugbya", - "Provider": "t010900", - "Label": "mAVWg5AIgtAc8lilWsrhuJaPxzQHEn5rAgSK2bhMAPuEf2bJUkMU", - "StartEpoch": 1070870, - "EndEpoch": 1973048, - "StoragePricePerEpoch": "400", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 2, - "Data": "joDHvKISwYJOLOJfZnzGqrBVFrZa0q9oYHONYMiTJWu9FiXXJj4P3Ssh5dXSqc6fDNlZMtC3LbDn00+mr2tJGTPKWjUK0WBqLURbZaTex9IoFxV2+7BP/6DmENBlJRuJ" - }, - "ProposalCid": { - "/": "bafyreia27jiyc7gft3wbfimqnh7mb366mdpt53u2jwn56zvxp4uhgufhh4" - }, - "AddFundsCid": null, - "PublishCid": null, - "Miner": "12D3KooWGDYDyqXFxMDjhM4ucrczRetiqmdYWhmh1vrsWZPCCRus", - "Client": "12D3KooWFvu3ZkMWjjbiZDRcEMGfNzCG55xgn7xpNdDxJPpUpdRf", - "State": 18, - "PiecePath": "", - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "manual", - "Root": { - "/": "bafk2bzacec2aopewffllfodoewr7dtibyspzvqebek3g4eyah3qr7wnsksimk" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": false, - "DealID": 0, - "CreationTime": "2022-06-22T20:36:00.735505548+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "InboundCAR": "" - }, - "Result": 2 - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqpaybnutz33gwus55lmccyi5eallzthyspepj66y67v7wn4ol2may" - }, - "PieceSize": 262144, - "VerifiedDeal": false, - "Client": "t3qowfyibovqc536f7i4u5gg3ysdjz6ly3fpepp5drwjcjvfbxnmcnzvqncx5rouramm3yseykv5hs5giugbya", - "Provider": "t010938", - "Label": "mAVWg5AIg4/5UnA6LvP+WgzytIrf7/Ad9TzmRj+RRMqJeKeEo1rk", - "StartEpoch": 1070870, - "EndEpoch": 1973048, - "StoragePricePerEpoch": "400", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 2, - "Data": "jFsi/PihQTf9OTDJerR8lDGZDOd1NRLJfHKDCdjtBbX9MFvEF1aJ132zIcbc8H0hBVVro7rqGgUmBKz525C5Ean4mahYEViQpjsdKoPmaRJkyoCfMILj2Vdf9dLJMwt9" - }, - "ProposalCid": { - "/": "bafyreia4ajjjrmijya6a4t4f264klvmw7entvasdfgsf5ffbh33y47cdym" - }, - "AddFundsCid": null, - "PublishCid": null, - "Miner": "12D3KooWGDYDyqXFxMDjhM4ucrczRetiqmdYWhmh1vrsWZPCCRus", - "Client": "12D3KooWFvu3ZkMWjjbiZDRcEMGfNzCG55xgn7xpNdDxJPpUpdRf", - "State": 18, - "PiecePath": "", - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "manual", - "Root": { - "/": "bafk2bzacedr74ve4b2f3z74wqm6k2ivx7p6ao7kphgiy7zcrgkrf4kpbfdlls" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": false, - "DealID": 0, - "CreationTime": "2022-06-23T09:45:00.952230255+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "InboundCAR": "" - }, - "Result": 3 - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqo5tmnkyzfmv6n5dwvwxiux5untnadv4t2u57ia35lrqxplof66my" - }, - "PieceSize": 262144, - "VerifiedDeal": false, - "Client": "t3qowfyibovqc536f7i4u5gg3ysdjz6ly3fpepp5drwjcjvfbxnmcnzvqncx5rouramm3yseykv5hs5giugbya", - "Provider": "t010938", - "Label": "mAVWg5AIgTQ7fDo7Bb+erCVsZDBPyRmF7elpru9PxcotqJVCwf3o", - "StartEpoch": 1070870, - "EndEpoch": 1973048, - "StoragePricePerEpoch": "400", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 2, - "Data": "sJuxcknWPKrP/6SvmjIUt5htTuE5tc385GB+Nu9lgXA9mXpmsM0Rt55XxWKI1svwBtiuLwgk9othDHqteXUTdwb89AgxvPVHT3ejRxLIsKQZAye1jnwJjne5Q1Cn8QjB" - }, - "ProposalCid": { - "/": "bafyreia2235wrw2bww24iiiu4gzda7egfysrydoguderjdstagmmfpwmqq" - }, - "AddFundsCid": null, - "PublishCid": null, - "Miner": "12D3KooWGDYDyqXFxMDjhM4ucrczRetiqmdYWhmh1vrsWZPCCRus", - "Client": "12D3KooWFvu3ZkMWjjbiZDRcEMGfNzCG55xgn7xpNdDxJPpUpdRf", - "State": 26, - "PiecePath": "", - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "error transferring data: deal data transfer failed: data transfer channel 12D3KooWFvu3ZkMWjjbiZDRcEMGfNzCG55xgn7xpNdDxJPpUpdRf-12D3KooWGDYDyqXFxMDjhM4ucrczRetiqmdYWhmh1vrsWZPCCRus-1656321261393666392 failed to transfer data: channel 12D3KooWFvu3ZkMWjjbiZDRcEMGfNzCG55xgn7xpNdDxJPpUpdRf-12D3KooWGDYDyqXFxMDjhM4ucrczRetiqmdYWhmh1vrsWZPCCRus-1656321261393666392: graphsync request failed to complete: request failed - content not found", - "FundsReserved": "0", - "Ref": { - "TransferType": "manual", - "Root": { - "/": "bafk2bzacebgq5xyor3aw7z5lbfnrsdat6jdgc632ljv3xu7rokfwujkqwb7xu" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": false, - "DealID": 0, - "CreationTime": "2022-06-23T03:12:00.211905693+08:00", - "TransferChannelId": { - "Initiator": "12D3KooWFvu3ZkMWjjbiZDRcEMGfNzCG55xgn7xpNdDxJPpUpdRf", - "Responder": "12D3KooWGDYDyqXFxMDjhM4ucrczRetiqmdYWhmh1vrsWZPCCRus", - "ID": 1656321261393666392 - }, - "SectorNumber": 0, - "InboundCAR": "" - }, - "Result": 4 - }, - { - "Proposal": { - "Proposal": { - "PieceCID": { - "/": "baga6ea4seaqd4gagvqgwo5ovankj2h5mmbkuj5555dqnk5ssaiwwfghwjoqu2iq" - }, - "PieceSize": 262144, - "VerifiedDeal": false, - "Client": "t3qowfyibovqc536f7i4u5gg3ysdjz6ly3fpepp5drwjcjvfbxnmcnzvqncx5rouramm3yseykv5hs5giugbya", - "Provider": "t010938", - "Label": "mAVWg5AIgtAc8lilWsrhuJaPxzQHEn5rAgSK2bhMAPuEf2bJUkMU", - "StartEpoch": 1070870, - "EndEpoch": 1973048, - "StoragePricePerEpoch": "400", - "ProviderCollateral": "0", - "ClientCollateral": "0" - }, - "ClientSignature": { - "Type": 2, - "Data": "joDHvKISwYJOLOJfZnzGqrBVFrZa0q9oYHONYMiTJWu9FiXXJj4P3Ssh5dXSqc6fDNlZMtC3LbDn00+mr2tJGTPKWjUK0WBqLURbZaTex9IoFxV2+7BP/6DmENBlJRuJ" - }, - "ProposalCid": { - "/": "bafyreia27jiyc7gft3wbfimqnh7mb366mdpt53u2jwn56zvxp4uhgufhh4" - }, - "AddFundsCid": null, - "PublishCid": null, - "Miner": "12D3KooWGDYDyqXFxMDjhM4ucrczRetiqmdYWhmh1vrsWZPCCRus", - "Client": "12D3KooWFvu3ZkMWjjbiZDRcEMGfNzCG55xgn7xpNdDxJPpUpdRf", - "State": 18, - "PiecePath": "", - "MetadataPath": "", - "SlashEpoch": 0, - "FastRetrieval": true, - "Message": "", - "FundsReserved": "0", - "Ref": { - "TransferType": "graphsync", - "Root": { - "/": "bafk2bzacec2aopewffllfodoewr7dtibyspzvqebek3g4eyah3qr7wnsksimk" - }, - "PieceCid": null, - "PieceSize": 0, - "RawBlockSize": 0 - }, - "AvailableForRetrieval": false, - "DealID": 0, - "CreationTime": "2022-06-22T20:36:00.735505548+08:00", - "TransferChannelId": null, - "SectorNumber": 0, - "InboundCAR": "" - }, - "Result": 5 - } - ] -}