From 73a265b2a448f1d3a326cf7b61ef8c62562bfe3a Mon Sep 17 00:00:00 2001 From: Sumit Vekariya Date: Sun, 25 May 2025 17:18:47 +0530 Subject: [PATCH 1/4] fix(state): display DealIDs from market actor for sectors The 'lotus state sector' command was showing empty DealIDs for sectors that actually contain deals. This occurred because for actors v13+, deal IDs are stored in the market actor's ProviderSectors HAMT, not in the sector's DeprecatedDealIDs field. This fix: - Adds dual DealIDs display showing both deprecated and market sources - Retrieves deal IDs from market actor's ProviderSectors HAMT for v13+ - Maintains backward compatibility with older network versions - Provides clear labeling of data sources - Handles errors gracefully with informative messages Resolves issue where sectors containing deals incorrectly showed 'DealIDs: []' instead of the actual deal IDs. Example output after fix: DealIDs (deprecated): [] DealIDs (market): [84864966] --- cli/state.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/cli/state.go b/cli/state.go index d55b21fe2dc..16500f6418d 100644 --- a/cli/state.go +++ b/cli/state.go @@ -37,7 +37,9 @@ import ( "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build/buildconstants" "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/consensus" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/stmgr" @@ -1527,6 +1529,22 @@ var StateSectorCmd = &cli.Command{ } fmt.Println() + // Display DealIDs - try both deprecated field and new ProviderSectors method + dealIDs := si.DeprecatedDealIDs + fmt.Printf("DealIDs (deprecated): %v\n", dealIDs) + + // For actors v13+, try to get deal IDs from market actor's ProviderSectors HAMT + if nv >= network.Version13 { + marketDealIDs, err := getMarketDealIDs(ctx, api, maddr, abi.SectorNumber(sid), ts.Key()) + if err != nil { + fmt.Printf("DealIDs (market): error retrieving from market actor: %v\n", err) + } else if len(marketDealIDs) > 0 { + fmt.Printf("DealIDs (market): %v\n", marketDealIDs) + } else { + fmt.Printf("DealIDs (market): []\n") + } + } + sp, err := api.StateSectorPartition(ctx, maddr, abi.SectorNumber(sid), ts.Key()) if err != nil { return err @@ -1729,3 +1747,57 @@ var StateSysActorCIDsCmd = &cli.Command{ return tw.Flush() }, } + +func getMarketDealIDs(ctx context.Context, api v0api.FullNode, maddr address.Address, sid abi.SectorNumber, tsKey types.TipSetKey) ([]abi.DealID, error) { + // Convert miner address to ID address to get the actor ID + minerID, err := api.StateLookupID(ctx, maddr, tsKey) + if err != nil { + return nil, xerrors.Errorf("failed to lookup miner ID: %w", err) + } + + // Get the market actor + marketActor, err := api.StateGetActor(ctx, market.Address, tsKey) + if err != nil { + return nil, xerrors.Errorf("failed to get market actor: %w", err) + } + + // Load the market state + store := adt.WrapStore(ctx, cbor.NewCborStore(blockstore.NewAPIBlockstore(api))) + marketState, err := market.Load(store, marketActor) + if err != nil { + return nil, xerrors.Errorf("failed to load market state: %w", err) + } + + // Get the ProviderSectors interface + providerSectors, err := marketState.ProviderSectors() + if err != nil { + return nil, xerrors.Errorf("failed to get provider sectors: %w", err) + } + + // Extract the actor ID from the ID address + id, err := address.IDFromAddress(minerID) + if err != nil { + return nil, xerrors.Errorf("failed to extract actor ID from address: %w", err) + } + actorID := abi.ActorID(id) + + // Get the sector deal IDs for this miner + sectorDealIDs, found, err := providerSectors.Get(actorID) + if err != nil { + return nil, xerrors.Errorf("failed to get sector deal IDs for miner %s: %w", maddr, err) + } + if !found { + return []abi.DealID{}, nil + } + + // Get the deal IDs for the specific sector + dealIDs, found, err := sectorDealIDs.Get(sid) + if err != nil { + return nil, xerrors.Errorf("failed to get deal IDs for sector %d: %w", sid, err) + } + if !found { + return []abi.DealID{}, nil + } + + return dealIDs, nil +} From d01dc72b25d842d3af3a9ea2beb35d8674e9e815 Mon Sep 17 00:00:00 2001 From: Sumit Vekariya Date: Sun, 25 May 2025 17:24:57 +0530 Subject: [PATCH 2/4] refactor(state): break getMarketDealIDs into smaller helper functions Improve code readability and maintainability by refactoring the getMarketDealIDs function into three focused helper functions: - getMinerActorID: Handles miner address to actor ID conversion - loadMarketState: Manages market actor state loading - extractSectorDealIDs: Extracts deal IDs from ProviderSectors HAMT Each function now has a single responsibility, making the code easier to understand, test, and maintain. --- cli/state.go | 53 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/cli/state.go b/cli/state.go index 16500f6418d..e0cb46b1830 100644 --- a/cli/state.go +++ b/cli/state.go @@ -1748,13 +1748,48 @@ var StateSysActorCIDsCmd = &cli.Command{ }, } +// getMarketDealIDs retrieves deal IDs for a sector from the market actor's ProviderSectors HAMT func getMarketDealIDs(ctx context.Context, api v0api.FullNode, maddr address.Address, sid abi.SectorNumber, tsKey types.TipSetKey) ([]abi.DealID, error) { - // Convert miner address to ID address to get the actor ID + // Convert miner address to actor ID + actorID, err := getMinerActorID(ctx, api, maddr, tsKey) + if err != nil { + return nil, err + } + + // Load market state + marketState, err := loadMarketState(ctx, api, tsKey) + if err != nil { + return nil, err + } + + // Extract deal IDs from ProviderSectors HAMT + dealIDs, err := extractSectorDealIDs(marketState, actorID, sid) + if err != nil { + return nil, err + } + + return dealIDs, nil +} + +// getMinerActorID converts a miner address to its actor ID +func getMinerActorID(ctx context.Context, api v0api.FullNode, maddr address.Address, tsKey types.TipSetKey) (abi.ActorID, error) { + // Convert miner address to ID address minerID, err := api.StateLookupID(ctx, maddr, tsKey) if err != nil { - return nil, xerrors.Errorf("failed to lookup miner ID: %w", err) + return 0, xerrors.Errorf("failed to lookup miner ID: %w", err) } + // Extract the actor ID from the ID address + id, err := address.IDFromAddress(minerID) + if err != nil { + return 0, xerrors.Errorf("failed to extract actor ID from address: %w", err) + } + + return abi.ActorID(id), nil +} + +// loadMarketState loads the market actor state +func loadMarketState(ctx context.Context, api v0api.FullNode, tsKey types.TipSetKey) (market.State, error) { // Get the market actor marketActor, err := api.StateGetActor(ctx, market.Address, tsKey) if err != nil { @@ -1768,23 +1803,21 @@ func getMarketDealIDs(ctx context.Context, api v0api.FullNode, maddr address.Add return nil, xerrors.Errorf("failed to load market state: %w", err) } + return marketState, nil +} + +// extractSectorDealIDs extracts deal IDs for a specific sector from the ProviderSectors HAMT +func extractSectorDealIDs(marketState market.State, actorID abi.ActorID, sid abi.SectorNumber) ([]abi.DealID, error) { // Get the ProviderSectors interface providerSectors, err := marketState.ProviderSectors() if err != nil { return nil, xerrors.Errorf("failed to get provider sectors: %w", err) } - // Extract the actor ID from the ID address - id, err := address.IDFromAddress(minerID) - if err != nil { - return nil, xerrors.Errorf("failed to extract actor ID from address: %w", err) - } - actorID := abi.ActorID(id) - // Get the sector deal IDs for this miner sectorDealIDs, found, err := providerSectors.Get(actorID) if err != nil { - return nil, xerrors.Errorf("failed to get sector deal IDs for miner %s: %w", maddr, err) + return nil, xerrors.Errorf("failed to get sector deal IDs for actor %d: %w", actorID, err) } if !found { return []abi.DealID{}, nil From 6de4d29780d215bbe30c202b91a9fa848d2523b5 Mon Sep 17 00:00:00 2001 From: Sumit Vekariya Date: Sun, 25 May 2025 23:16:47 +0530 Subject: [PATCH 3/4] docs: add changelog entry for DealIDs fix in lotus state sector command --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13000a5fa07..005e34212b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ > * [CHANGELOG_1.2x.md](./documentation/changelog/CHANGELOG_1.2x.md) - v1.20.0 to v1.29.2 # UNRELEASED +- fix(cli): fix `lotus state sector` command to display DealIDs correctly post-FIP-0076 by querying market actor's ProviderSectors HAMT while maintaining backward compatibility with DeprecatedDealIDs field - chore(deps): bump filecoin-ffi for fvm@v4.7 which adds Logs and IpldOps to debug FVM execution traces ([filecoin-project/lotus#13029](https://github.com/filecoin-project/lotus/pull/13029)) - chore: return `method not supported` via Gateway when /v2 isn't supported by the backend ([filecoin-project/lotus#13121](https://github.com/filecoin-project/lotus/pull/13121)) - chore: disable F3 participation via gateway ([filecoin-project/lotus#13123](https://github.com/filecoin-project/lotus/pull/13123) From 7f2a7b7179dd75b5e379ac78e2af1f9caca04d58 Mon Sep 17 00:00:00 2001 From: Sumit Vekariya Date: Mon, 26 May 2025 09:01:20 +0530 Subject: [PATCH 4/4] fix: address PR review feedback from rvagg --- CHANGELOG.md | 2 +- cli/state.go | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 005e34212b7..6a0b70c4ed2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ > * [CHANGELOG_1.2x.md](./documentation/changelog/CHANGELOG_1.2x.md) - v1.20.0 to v1.29.2 # UNRELEASED -- fix(cli): fix `lotus state sector` command to display DealIDs correctly post-FIP-0076 by querying market actor's ProviderSectors HAMT while maintaining backward compatibility with DeprecatedDealIDs field +- fix(cli): fix `lotus state sector` command to display DealIDs correctly post-FIP-0076 by querying market actor's ProviderSectors HAMT while maintaining backward compatibility with DeprecatedDealIDs field ([filecoin-project/lotus#13140](https://github.com/filecoin-project/lotus/pull/13140)) - chore(deps): bump filecoin-ffi for fvm@v4.7 which adds Logs and IpldOps to debug FVM execution traces ([filecoin-project/lotus#13029](https://github.com/filecoin-project/lotus/pull/13029)) - chore: return `method not supported` via Gateway when /v2 isn't supported by the backend ([filecoin-project/lotus#13121](https://github.com/filecoin-project/lotus/pull/13121)) - chore: disable F3 participation via gateway ([filecoin-project/lotus#13123](https://github.com/filecoin-project/lotus/pull/13123) diff --git a/cli/state.go b/cli/state.go index e0cb46b1830..23fb1eb9967 100644 --- a/cli/state.go +++ b/cli/state.go @@ -1533,8 +1533,8 @@ var StateSectorCmd = &cli.Command{ dealIDs := si.DeprecatedDealIDs fmt.Printf("DealIDs (deprecated): %v\n", dealIDs) - // For actors v13+, try to get deal IDs from market actor's ProviderSectors HAMT - if nv >= network.Version13 { + // Deals were moved into market actor's ProviderSectors in NV22 / Actors v13 + if nv >= network.Version22 { marketDealIDs, err := getMarketDealIDs(ctx, api, maddr, abi.SectorNumber(sid), ts.Key()) if err != nil { fmt.Printf("DealIDs (market): error retrieving from market actor: %v\n", err) @@ -1824,13 +1824,9 @@ func extractSectorDealIDs(marketState market.State, actorID abi.ActorID, sid abi } // Get the deal IDs for the specific sector - dealIDs, found, err := sectorDealIDs.Get(sid) + dealIDs, _, err := sectorDealIDs.Get(sid) if err != nil { return nil, xerrors.Errorf("failed to get deal IDs for sector %d: %w", sid, err) } - if !found { - return []abi.DealID{}, nil - } - return dealIDs, nil }