From 691bd9f442c80bbf0cce178e265706a90c2520ce Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Thu, 17 Sep 2020 00:32:10 -0700 Subject: [PATCH] feat(markets): complete markets conversion complete markets conversion to using chain/actors types, also replacing DealProposal/DealState interfaces with structs --- api/api_full.go | 2 +- api/api_storage.go | 4 +- api/apistruct/struct.go | 8 +- chain/actors/builtin/market/market.go | 40 +++++-- chain/actors/builtin/market/v0.go | 144 +++++++++++++++++--------- chain/events/state/predicates.go | 19 ++-- chain/events/state/predicates_test.go | 14 +-- chain/gen/gen.go | 9 +- chain/stmgr/stmgr.go | 20 ++++ chain/stmgr/utils.go | 22 ++-- cli/client.go | 8 +- extern/storage-sealing/sealing.go | 2 +- go.mod | 2 +- go.sum | 4 + markets/storageadapter/client.go | 23 ---- markets/storageadapter/provider.go | 22 ---- markets/utils/converters.go | 8 -- node/impl/full/gas.go | 10 +- node/impl/full/state.go | 95 ++++++++--------- node/impl/storminer.go | 30 +++++- storage/adapter_storage_miner.go | 5 +- 21 files changed, 269 insertions(+), 222 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index b472febe0..f565ad543 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -19,8 +19,8 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" - "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/specs-actors/actors/builtin/paych" "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" "github.com/filecoin-project/specs-actors/actors/runtime/proof" diff --git a/api/api_storage.go b/api/api_storage.go index 37bef2d6c..824772181 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -71,7 +71,7 @@ type StorageMiner interface { stores.SectorIndex MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error - MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error) + MarketListDeals(ctx context.Context) ([]MarketDeal, error) MarketListRetrievalDeals(ctx context.Context) ([]retrievalmarket.ProviderDealState, error) MarketGetDealUpdates(ctx context.Context) (<-chan storagemarket.MinerDeal, error) MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error) @@ -83,7 +83,7 @@ type StorageMiner interface { MarketDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error) DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error - DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) + DealsList(ctx context.Context) ([]MarketDeal, error) DealsConsiderOnlineStorageDeals(context.Context) (bool, error) DealsSetConsiderOnlineStorageDeals(context.Context, bool) error DealsConsiderOnlineRetrievalDeals(context.Context) (bool, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 26f7a8708..8bf8f1997 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -251,7 +251,7 @@ type StorageMinerStruct struct { MiningBase func(context.Context) (*types.TipSet, error) `perm:"read"` MarketImportDealData func(context.Context, cid.Cid, string) error `perm:"write"` - MarketListDeals func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` + MarketListDeals func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"` MarketListRetrievalDeals func(ctx context.Context) ([]retrievalmarket.ProviderDealState, error) `perm:"read"` MarketGetDealUpdates func(ctx context.Context) (<-chan storagemarket.MinerDeal, error) `perm:"read"` MarketListIncompleteDeals func(ctx context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"` @@ -296,7 +296,7 @@ type StorageMinerStruct struct { StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"` DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` - DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` + DealsList func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"` DealsConsiderOnlineStorageDeals func(context.Context) (bool, error) `perm:"read"` DealsSetConsiderOnlineStorageDeals func(context.Context, bool) error `perm:"admin"` DealsConsiderOnlineRetrievalDeals func(context.Context) (bool, error) `perm:"read"` @@ -1128,7 +1128,7 @@ func (c *StorageMinerStruct) MarketImportDealData(ctx context.Context, propcid c return c.Internal.MarketImportDealData(ctx, propcid, path) } -func (c *StorageMinerStruct) MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error) { +func (c *StorageMinerStruct) MarketListDeals(ctx context.Context) ([]api.MarketDeal, error) { return c.Internal.MarketListDeals(ctx) } @@ -1172,7 +1172,7 @@ func (c *StorageMinerStruct) DealsImportData(ctx context.Context, dealPropCid ci return c.Internal.DealsImportData(ctx, dealPropCid, file) } -func (c *StorageMinerStruct) DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) { +func (c *StorageMinerStruct) DealsList(ctx context.Context) ([]api.MarketDeal, error) { return c.Internal.DealsList(ctx) } diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index 051c46dbe..73c2528d0 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -7,6 +7,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" v0builtin "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/ipfs/go-cid" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" @@ -43,26 +44,39 @@ type State interface { } type BalanceTable interface { + ForEach(cb func(address.Address, abi.TokenAmount) error) error Get(key address.Address) (abi.TokenAmount, error) } type DealStates interface { - GetDeal(key abi.DealID) (DealState, error) + Get(id abi.DealID) (*DealState, bool, error) Diff(DealStates) (*DealStateChanges, error) } type DealProposals interface { + ForEach(cb func(id abi.DealID, dp DealProposal) error) error + Get(id abi.DealID) (*DealProposal, bool, error) Diff(DealProposals) (*DealProposalChanges, error) } -type DealState interface { - SectorStartEpoch() abi.ChainEpoch - SlashEpoch() abi.ChainEpoch - LastUpdatedEpoch() abi.ChainEpoch - Equals(DealState) bool +type DealState struct { + SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector + LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated + SlashEpoch abi.ChainEpoch // -1 if deal never slashed } -type DealProposal interface { +type DealProposal struct { + PieceCID cid.Cid + PieceSize abi.PaddedPieceSize + VerifiedDeal bool + Client address.Address + Provider address.Address + Label string + StartEpoch abi.ChainEpoch + EndEpoch abi.ChainEpoch + StoragePricePerEpoch abi.TokenAmount + ProviderCollateral abi.TokenAmount + ClientCollateral abi.TokenAmount } type DealStateChanges struct { @@ -79,8 +93,8 @@ type DealIDState struct { // DealStateChange is a change in deal state from -> to type DealStateChange struct { ID abi.DealID - From DealState - To DealState + From *DealState + To *DealState } type DealProposalChanges struct { @@ -92,3 +106,11 @@ type ProposalIDState struct { ID abi.DealID Proposal DealProposal } + +func EmptyDealState() *DealState { + return &DealState{ + SectorStartEpoch: -1, + SlashEpoch: -1, + LastUpdatedEpoch: -1, + } +} diff --git a/chain/actors/builtin/market/v0.go b/chain/actors/builtin/market/v0.go index 8f0aa0594..92ebb59ba 100644 --- a/chain/actors/builtin/market/v0.go +++ b/chain/actors/builtin/market/v0.go @@ -72,11 +72,19 @@ func (s *v0State) Proposals() (DealProposals, error) { } func (s *v0State) EscrowTable() (BalanceTable, error) { - return v0adt.AsBalanceTable(s.store, s.State.EscrowTable) + bt, err := v0adt.AsBalanceTable(s.store, s.State.EscrowTable) + if err != nil { + return nil, err + } + return &v0BalanceTable{bt}, nil } func (s *v0State) LockedTable() (BalanceTable, error) { - return v0adt.AsBalanceTable(s.store, s.State.LockedTable) + bt, err := v0adt.AsBalanceTable(s.store, s.State.LockedTable) + if err != nil { + return nil, err + } + return &v0BalanceTable{bt}, nil } func (s *v0State) VerifyDealsForActivation( @@ -85,20 +93,37 @@ func (s *v0State) VerifyDealsForActivation( return market.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) } +type v0BalanceTable struct { + *v0adt.BalanceTable +} + +func (bt *v0BalanceTable) ForEach(cb func(address.Address, abi.TokenAmount) error) error { + asMap := (*v0adt.Map)(bt.BalanceTable) + var ta abi.TokenAmount + return asMap.ForEach(&ta, func(key string) error { + a, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(a, ta) + }) +} + type v0DealStates struct { adt.Array } -func (s *v0DealStates) GetDeal(dealID abi.DealID) (DealState, error) { - var deal market.DealState - found, err := s.Array.Get(uint64(dealID), &deal) +func (s *v0DealStates) Get(dealID abi.DealID) (*DealState, bool, error) { + var v0deal market.DealState + found, err := s.Array.Get(uint64(dealID), &v0deal) if err != nil { - return nil, err + return nil, false, err } if !found { - return nil, nil + return nil, false, nil } - return &v0DealState{deal}, nil + deal := fromV0DealState(v0deal) + return &deal, true, nil } func (s *v0DealStates) Diff(other DealStates) (*DealStateChanges, error) { @@ -108,7 +133,7 @@ func (s *v0DealStates) Diff(other DealStates) (*DealStateChanges, error) { return nil, errors.New("cannot compare deal states across versions") } results := new(DealStateChanges) - if err := adt.DiffAdtArray(s, v0other, &v0MarketStatesDiffer{results}); err != nil { + if err := adt.DiffAdtArray(s.Array, v0other.Array, &v0MarketStatesDiffer{results}); err != nil { return nil, fmt.Errorf("diffing deal states: %w", err) } @@ -120,61 +145,50 @@ type v0MarketStatesDiffer struct { } func (d *v0MarketStatesDiffer) Add(key uint64, val *typegen.Deferred) error { - ds := new(v0DealState) - err := ds.UnmarshalCBOR(bytes.NewReader(val.Raw)) + v0ds := new(market.DealState) + err := v0ds.UnmarshalCBOR(bytes.NewReader(val.Raw)) if err != nil { return err } - d.Results.Added = append(d.Results.Added, DealIDState{abi.DealID(key), ds}) + d.Results.Added = append(d.Results.Added, DealIDState{abi.DealID(key), fromV0DealState(*v0ds)}) return nil } func (d *v0MarketStatesDiffer) Modify(key uint64, from, to *typegen.Deferred) error { - dsFrom := new(v0DealState) - if err := dsFrom.UnmarshalCBOR(bytes.NewReader(from.Raw)); err != nil { + v0dsFrom := new(market.DealState) + if err := v0dsFrom.UnmarshalCBOR(bytes.NewReader(from.Raw)); err != nil { return err } - dsTo := new(v0DealState) - if err := dsTo.UnmarshalCBOR(bytes.NewReader(to.Raw)); err != nil { + v0dsTo := new(market.DealState) + if err := v0dsTo.UnmarshalCBOR(bytes.NewReader(to.Raw)); err != nil { return err } - if *dsFrom != *dsTo { - d.Results.Modified = append(d.Results.Modified, DealStateChange{abi.DealID(key), dsFrom, dsTo}) + if *v0dsFrom != *v0dsTo { + dsFrom := fromV0DealState(*v0dsFrom) + dsTo := fromV0DealState(*v0dsTo) + d.Results.Modified = append(d.Results.Modified, DealStateChange{abi.DealID(key), &dsFrom, &dsTo}) } return nil } func (d *v0MarketStatesDiffer) Remove(key uint64, val *typegen.Deferred) error { - ds := new(v0DealState) - err := ds.UnmarshalCBOR(bytes.NewReader(val.Raw)) + v0ds := new(market.DealState) + err := v0ds.UnmarshalCBOR(bytes.NewReader(val.Raw)) if err != nil { return err } - d.Results.Removed = append(d.Results.Removed, DealIDState{abi.DealID(key), ds}) + d.Results.Removed = append(d.Results.Removed, DealIDState{abi.DealID(key), fromV0DealState(*v0ds)}) return nil } -type v0DealState struct { - market.DealState -} - -func (ds *v0DealState) SectorStartEpoch() abi.ChainEpoch { - return ds.DealState.SectorStartEpoch -} - -func (ds *v0DealState) SlashEpoch() abi.ChainEpoch { - return ds.DealState.SlashEpoch -} - -func (ds *v0DealState) LastUpdatedEpoch() abi.ChainEpoch { - return ds.DealState.LastUpdatedEpoch -} - -func (ds *v0DealState) Equals(other DealState) bool { - v0other, ok := other.(*v0DealState) - return ok && *ds == *v0other +func fromV0DealState(v0 market.DealState) DealState { + return DealState{ + SectorStartEpoch: v0.SectorStartEpoch, + SlashEpoch: v0.SlashEpoch, + LastUpdatedEpoch: v0.LastUpdatedEpoch, + } } type v0DealProposals struct { @@ -188,28 +202,60 @@ func (s *v0DealProposals) Diff(other DealProposals) (*DealProposalChanges, error return nil, errors.New("cannot compare deal proposals across versions") } results := new(DealProposalChanges) - if err := adt.DiffAdtArray(s, v0other, &v0MarketProposalsDiffer{results}); err != nil { + if err := adt.DiffAdtArray(s.Array, v0other.Array, &v0MarketProposalsDiffer{results}); err != nil { return nil, fmt.Errorf("diffing deal proposals: %w", err) } return results, nil } +func (s *v0DealProposals) Get(dealID abi.DealID) (*DealProposal, bool, error) { + var v0proposal market.DealProposal + found, err := s.Array.Get(uint64(dealID), &v0proposal) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + proposal := fromV0DealProposal(v0proposal) + return &proposal, true, nil +} + +func (s *v0DealProposals) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { + var v0dp market.DealProposal + return s.Array.ForEach(&v0dp, func(idx int64) error { + return cb(abi.DealID(idx), fromV0DealProposal(v0dp)) + }) +} + type v0MarketProposalsDiffer struct { Results *DealProposalChanges } -type v0DealProposal struct { - market.DealProposal +func fromV0DealProposal(v0 market.DealProposal) DealProposal { + return DealProposal{ + PieceCID: v0.PieceCID, + PieceSize: v0.PieceSize, + VerifiedDeal: v0.VerifiedDeal, + Client: v0.Client, + Provider: v0.Provider, + Label: v0.Label, + StartEpoch: v0.StartEpoch, + EndEpoch: v0.EndEpoch, + StoragePricePerEpoch: v0.StoragePricePerEpoch, + ProviderCollateral: v0.ProviderCollateral, + ClientCollateral: v0.ClientCollateral, + } } func (d *v0MarketProposalsDiffer) Add(key uint64, val *typegen.Deferred) error { - dp := new(v0DealProposal) - err := dp.UnmarshalCBOR(bytes.NewReader(val.Raw)) + v0dp := new(market.DealProposal) + err := v0dp.UnmarshalCBOR(bytes.NewReader(val.Raw)) if err != nil { return err } - d.Results.Added = append(d.Results.Added, ProposalIDState{abi.DealID(key), dp}) + d.Results.Added = append(d.Results.Added, ProposalIDState{abi.DealID(key), fromV0DealProposal(*v0dp)}) return nil } @@ -219,11 +265,11 @@ func (d *v0MarketProposalsDiffer) Modify(key uint64, from, to *typegen.Deferred) } func (d *v0MarketProposalsDiffer) Remove(key uint64, val *typegen.Deferred) error { - dp := new(v0DealProposal) - err := dp.UnmarshalCBOR(bytes.NewReader(val.Raw)) + v0dp := new(market.DealProposal) + err := v0dp.UnmarshalCBOR(bytes.NewReader(val.Raw)) if err != nil { return err } - d.Results.Removed = append(d.Results.Removed, ProposalIDState{abi.DealID(key), dp}) + d.Results.Removed = append(d.Results.Removed, ProposalIDState{abi.DealID(key), fromV0DealProposal(*v0dp)}) return nil } diff --git a/chain/events/state/predicates.go b/chain/events/state/predicates.go index 3e515e6a4..7a7609823 100644 --- a/chain/events/state/predicates.go +++ b/chain/events/state/predicates.go @@ -212,14 +212,7 @@ func (sp *StatePredicates) OnDealStateAmtChanged() DiffDealStatesFunc { } // ChangedDeals is a set of changes to deal state -type ChangedDeals map[abi.DealID]DealStateChange - -// DealStateChange is a change in deal state from -> to -type DealStateChange struct { - ID abi.DealID - From market.DealState - To market.DealState -} +type ChangedDeals map[abi.DealID]market.DealStateChange // DealStateChangedForIDs detects changes in the deal state AMT for the given deal IDs func (sp *StatePredicates) DealStateChangedForIDs(dealIds []abi.DealID) DiffDealStatesFunc { @@ -228,20 +221,20 @@ func (sp *StatePredicates) DealStateChangedForIDs(dealIds []abi.DealID) DiffDeal for _, dealID := range dealIds { // If the deal has been removed, we just set it to nil - oldDeal, err := oldDealStates.GetDeal(dealID) + oldDeal, oldFound, err := oldDealStates.Get(dealID) if err != nil { return false, nil, err } - newDeal, err := newDealStates.GetDeal(dealID) + newDeal, newFound, err := newDealStates.Get(dealID) if err != nil { return false, nil, err } - existenceChanged := (oldDeal == nil) != (newDeal == nil) - valueChanged := (oldDeal != nil && newDeal != nil) && !oldDeal.Equals(newDeal) + existenceChanged := oldFound != newFound + valueChanged := (oldFound && newFound) && *oldDeal != *newDeal if existenceChanged || valueChanged { - changedDeals[dealID] = DealStateChange{dealID, oldDeal, newDeal} + changedDeals[dealID] = market.DealStateChange{ID: dealID, From: oldDeal, To: newDeal} } } if len(changedDeals) > 0 { diff --git a/chain/events/state/predicates_test.go b/chain/events/state/predicates_test.go index 25f25334d..6541aa3b4 100644 --- a/chain/events/state/predicates_test.go +++ b/chain/events/state/predicates_test.go @@ -208,11 +208,11 @@ func TestMarketPredicates(t *testing.T) { require.Contains(t, changedDealIDs, abi.DealID(1)) require.Contains(t, changedDealIDs, abi.DealID(2)) deal1 := changedDealIDs[abi.DealID(1)] - if deal1.From.LastUpdatedEpoch() != 2 || deal1.To.LastUpdatedEpoch() != 3 { + if deal1.From.LastUpdatedEpoch != 2 || deal1.To.LastUpdatedEpoch != 3 { t.Fatal("Unexpected change to LastUpdatedEpoch") } deal2 := changedDealIDs[abi.DealID(2)] - if deal2.From.LastUpdatedEpoch() != 5 || deal2.To != nil { + if deal2.From.LastUpdatedEpoch != 5 || deal2.To != nil { t.Fatal("Expected To to be nil") } @@ -273,8 +273,8 @@ func TestMarketPredicates(t *testing.T) { require.Len(t, changedDeals.Modified, 1) require.Equal(t, abi.DealID(1), changedDeals.Modified[0].ID) - require.True(t, dealEquality(*newDeal1, changedDeals.Modified[0].To)) - require.True(t, dealEquality(*oldDeal1, changedDeals.Modified[0].From)) + require.True(t, dealEquality(*newDeal1, *changedDeals.Modified[0].To)) + require.True(t, dealEquality(*oldDeal1, *changedDeals.Modified[0].From)) require.Equal(t, abi.DealID(2), changedDeals.Removed[0].ID) }) @@ -624,7 +624,7 @@ func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiratio } func dealEquality(expected v0market.DealState, actual market.DealState) bool { - return expected.LastUpdatedEpoch == actual.LastUpdatedEpoch() && - expected.SectorStartEpoch == actual.SectorStartEpoch() && - expected.SlashEpoch == actual.SlashEpoch() + return expected.LastUpdatedEpoch == actual.LastUpdatedEpoch && + expected.SectorStartEpoch == actual.SectorStartEpoch && + expected.SlashEpoch == actual.SlashEpoch } diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 4cae19082..4163f0b2d 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -489,13 +489,16 @@ func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticke // ResyncBankerNonce is used for dealing with messages made when // simulating forks func (cg *ChainGen) ResyncBankerNonce(ts *types.TipSet) error { - var act types.Actor - err := cg.sm.WithParentState(ts, cg.sm.WithActor(cg.banker, stmgr.GetActor(&act))) + st, err := cg.sm.ParentState(ts) + if err != nil { + return err + } + act, err := st.GetActor(cg.banker) if err != nil { return err } - cg.bankerNonce = act.Nonce + return nil } diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 18c67b5f0..2a6737e2c 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -1175,3 +1175,23 @@ func (sm *StateManager) GetPaychState(ctx context.Context, addr address.Address, } return act, actState, nil } + +func (sm *StateManager) GetMarketState(ctx context.Context, ts *types.TipSet) (market.State, error) { + st, err := sm.ParentState(ts) + if err != nil { + return nil, err + } + + // TODO maybe there needs to be code here to differentiate address based on ts height? + addr := builtin.StorageMarketActorAddr + act, err := st.GetActor(addr) + if err != nil { + return nil, err + } + + actState, err := market.Load(sm.cs.Store(ctx), act) + if err != nil { + return nil, err + } + return actState, nil +} diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index afd790a74..38b66c512 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -34,7 +34,6 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors/adt" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -318,40 +317,35 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealID abi.DealID, ts return nil, xerrors.Errorf("failed to load market actor state: %w", err) } - store := sm.ChainStore().Store(ctx) - - da, err := adt.AsArray(store, state.Proposals) + proposals, err := state.Proposals() if err != nil { return nil, err } - var dp market.DealProposal - if found, err := da.Get(uint64(dealID), &dp); err != nil { + proposal, found, err := proposals.Get(dealID) + + if err != nil { return nil, err } else if !found { return nil, xerrors.Errorf("deal %d not found", dealID) } - sa, err := market.AsDealStateArray(store, state.States) + states, err := state.States() if err != nil { return nil, err } - st, found, err := sa.Get(dealID) + st, found, err := states.Get(dealID) if err != nil { return nil, err } if !found { - st = &market.DealState{ - SectorStartEpoch: -1, - LastUpdatedEpoch: -1, - SlashEpoch: -1, - } + st = market.EmptyDealState() } return &api.MarketDeal{ - Proposal: dp, + Proposal: *proposal, State: *st, }, nil } diff --git a/cli/client.go b/cli/client.go index e68f98791..eda5ffae8 100644 --- a/cli/client.go +++ b/cli/client.go @@ -29,13 +29,13 @@ import ( "github.com/filecoin-project/go-multistore" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/lotus/api" lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/tablewriter" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" ) var CidBaseFlag = cli.StringFlag{ @@ -1045,11 +1045,7 @@ func dealFromDealInfo(ctx context.Context, full api.FullNode, head *types.TipSet if v.DealID == 0 { return deal{ LocalDeal: v, - OnChainDealState: market.DealState{ - SectorStartEpoch: -1, - LastUpdatedEpoch: -1, - SlashEpoch: -1, - }, + OnChainDealState: *market.EmptyDealState() } } diff --git a/extern/storage-sealing/sealing.go b/extern/storage-sealing/sealing.go index 0fe754217..e9a98fec9 100644 --- a/extern/storage-sealing/sealing.go +++ b/extern/storage-sealing/sealing.go @@ -25,9 +25,9 @@ import ( "github.com/filecoin-project/go-state-types/crypto" statemachine "github.com/filecoin-project/go-statemachine" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" - "github.com/filecoin-project/specs-actors/actors/builtin/market" ) const SectorStorePrefix = "/sectors" diff --git a/go.mod b/go.mod index 65c2addb8..0397ff275 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v0.6.3 github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f - github.com/filecoin-project/go-fil-markets v0.6.1-0.20200911011457-2959ccca6a3c + github.com/filecoin-project/go-fil-markets v0.6.1-0.20200917052354-ee0af754c6e9 github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52 github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 diff --git a/go.sum b/go.sum index b6b724767..3d012da92 100644 --- a/go.sum +++ b/go.sum @@ -228,6 +228,10 @@ github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f h1 github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-markets v0.6.1-0.20200911011457-2959ccca6a3c h1:YGoyYmELQ0LHwDj/WcOvY3oYt+3iM0wdrAhqJQUAIy4= github.com/filecoin-project/go-fil-markets v0.6.1-0.20200911011457-2959ccca6a3c/go.mod h1:PLr9svZxsnHkae1Ky7+66g7fP9AlneVxIVu+oSMq56A= +github.com/filecoin-project/go-fil-markets v0.6.1-0.20200917050751-2af52e9606c6 h1:k97Z2JP3WpDVGU/7Bz3RtnqrYtn9X428Ps8OkoFq61I= +github.com/filecoin-project/go-fil-markets v0.6.1-0.20200917050751-2af52e9606c6/go.mod h1:PLr9svZxsnHkae1Ky7+66g7fP9AlneVxIVu+oSMq56A= +github.com/filecoin-project/go-fil-markets v0.6.1-0.20200917052354-ee0af754c6e9 h1:SnCUC9wHDId9TtV8PsQp8q1OOsi+NOLOwitIDnAgUa4= +github.com/filecoin-project/go-fil-markets v0.6.1-0.20200917052354-ee0af754c6e9/go.mod h1:PLr9svZxsnHkae1Ky7+66g7fP9AlneVxIVu+oSMq56A= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 0c9e66eda..781715903 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -98,29 +98,6 @@ func (c *ClientNodeAdapter) VerifySignature(ctx context.Context, sig crypto.Sign return err == nil, err } -func (c *ClientNodeAdapter) ListClientDeals(ctx context.Context, addr address.Address, encodedTs shared.TipSetToken) ([]storagemarket.StorageDeal, error) { - tsk, err := types.TipSetKeyFromBytes(encodedTs) - if err != nil { - return nil, err - } - - allDeals, err := c.StateMarketDeals(ctx, tsk) - if err != nil { - return nil, err - } - - var out []storagemarket.StorageDeal - - for _, deal := range allDeals { - storageDeal := utils.FromOnChainDeal(deal.Proposal, deal.State) - if storageDeal.Client == addr { - out = append(out, storageDeal) - } - } - - return out, nil -} - // Adds funds with the StorageMinerActor for a storage participant. Used by both providers and clients. func (c *ClientNodeAdapter) AddFunds(ctx context.Context, addr address.Address, amount abi.TokenAmount) (cid.Cid, error) { // (Provider Node API) diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go index 22d6c1e1d..98935b30a 100644 --- a/markets/storageadapter/provider.go +++ b/markets/storageadapter/provider.go @@ -142,28 +142,6 @@ func (n *ProviderNodeAdapter) VerifySignature(ctx context.Context, sig crypto.Si return err == nil, err } -func (n *ProviderNodeAdapter) ListProviderDeals(ctx context.Context, addr address.Address, encodedTs shared.TipSetToken) ([]storagemarket.StorageDeal, error) { - tsk, err := types.TipSetKeyFromBytes(encodedTs) - if err != nil { - return nil, err - } - allDeals, err := n.StateMarketDeals(ctx, tsk) - if err != nil { - return nil, err - } - - var out []storagemarket.StorageDeal - - for _, deal := range allDeals { - sharedDeal := utils.FromOnChainDeal(deal.Proposal, deal.State) - if sharedDeal.Provider == addr { - out = append(out, sharedDeal) - } - } - - return out, nil -} - func (n *ProviderNodeAdapter) GetMinerWorkerAddress(ctx context.Context, miner address.Address, tok shared.TipSetToken) (address.Address, error) { tsk, err := types.TipSetKeyFromBytes(tok) if err != nil { diff --git a/markets/utils/converters.go b/markets/utils/converters.go index 05472801d..4a3d21140 100644 --- a/markets/utils/converters.go +++ b/markets/utils/converters.go @@ -4,7 +4,6 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/specs-actors/actors/builtin/market" peer "github.com/libp2p/go-libp2p-core/peer" "github.com/multiformats/go-multiaddr" @@ -31,13 +30,6 @@ func NewStorageProviderInfo(address address.Address, miner address.Address, sect } } -func FromOnChainDeal(prop market.DealProposal, state market.DealState) storagemarket.StorageDeal { - return storagemarket.StorageDeal{ - DealProposal: prop, - DealState: state, - } -} - func ToSharedBalance(bal api.MarketBalance) storagemarket.Balance { return storagemarket.Balance{ Locked: bal.Locked, diff --git a/node/impl/full/gas.go b/node/impl/full/gas.go index 536bef360..b207a1f6d 100644 --- a/node/impl/full/gas.go +++ b/node/impl/full/gas.go @@ -166,8 +166,14 @@ func (a *GasAPI) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message, } // Special case for PaymentChannel collect, which is deleting actor - var act types.Actor - err = a.Stmgr.WithParentState(ts, a.Stmgr.WithActor(msg.To, stmgr.GetActor(&act))) + st, err := a.Stmgr.ParentState(ts) + if err != nil { + _ = err + // somewhat ignore it as it can happen and we just want to detect + // an existing PaymentChannel actor + return res.MsgRct.GasUsed, nil + } + act, err := st.GetActor(msg.To) if err != nil { _ = err // somewhat ignore it as it can happen and we just want to detect diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 1b29a93a9..241561a9f 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -4,10 +4,10 @@ import ( "bytes" "context" "errors" - "fmt" - "github.com/filecoin-project/go-state-types/network" "strconv" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/go-state-types/dline" cid "github.com/ipfs/go-cid" @@ -28,6 +28,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/util/smoothing" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/actors/builtin/power" @@ -42,7 +43,6 @@ import ( "github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/lib/bufbstore" "github.com/filecoin-project/lotus/node/modules/dtypes" - "github.com/filecoin-project/lotus/chain/actors/builtin/market" ) var errBreakForeach = errors.New("break") @@ -259,8 +259,8 @@ func (a *StateAPI) StateMinerPower(ctx context.Context, addr address.Address, ts } return &api.MinerPower{ - MinerPower: m, - TotalPower: net, + MinerPower: m, + TotalPower: net, HasMinPower: hmp, }, nil } @@ -489,37 +489,31 @@ func (a *StateAPI) StateMarketBalance(ctx context.Context, addr address.Address, func (a *StateAPI) StateMarketParticipants(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketBalance, error) { out := map[string]api.MarketBalance{} - var state market.State ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - if _, err := a.StateManager.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts); err != nil { - return nil, err - } - store := a.StateManager.ChainStore().Store(ctx) - escrow, err := adt.AsMap(store, state.EscrowTable) + + state, err := a.StateManager.GetMarketState(ctx, ts) if err != nil { return nil, err } - locked, err := adt.AsMap(store, state.LockedTable) + escrow, err := state.EscrowTable() + if err != nil { + return nil, err + } + locked, err := state.LockedTable() if err != nil { return nil, err } - var es, lk abi.TokenAmount - err = escrow.ForEach(&es, func(k string) error { - a, err := address.NewFromBytes([]byte(k)) + err = escrow.ForEach(func(a address.Address, es abi.TokenAmount) error { + + lk, err := locked.Get(a) if err != nil { return err } - if found, err := locked.Get(abi.AddrKey(a), &lk); err != nil { - return err - } else if !found { - return fmt.Errorf("locked funds not found") - } - out[a.String()] = api.MarketBalance{ Escrow: es, Locked: lk, @@ -535,37 +529,36 @@ func (a *StateAPI) StateMarketParticipants(ctx context.Context, tsk types.TipSet func (a *StateAPI) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketDeal, error) { out := map[string]api.MarketDeal{} - var state market.State ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - if _, err := a.StateManager.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts); err != nil { - return nil, err - } - store := a.StateManager.ChainStore().Store(ctx) - da, err := adt.AsArray(store, state.Proposals) + state, err := a.StateManager.GetMarketState(ctx, ts) if err != nil { return nil, err } - sa, err := adt.AsArray(store, state.States) + da, err := state.Proposals() if err != nil { return nil, err } - var d market.DealProposal - if err := da.ForEach(&d, func(i int64) error { - var s market.DealState - if found, err := sa.Get(uint64(i), &s); err != nil { + sa, err := state.States() + if err != nil { + return nil, err + } + + if err := da.ForEach(func(dealID abi.DealID, d market.DealProposal) error { + s, found, err := sa.Get(dealID) + if err != nil { return xerrors.Errorf("failed to get state for deal in proposals array: %w", err) } else if !found { - s.SectorStartEpoch = -1 + s = market.EmptyDealState() } - out[strconv.FormatInt(i, 10)] = api.MarketDeal{ + out[strconv.FormatInt(int64(dealID), 10)] = api.MarketDeal{ Proposal: d, - State: s, + State: *s, } return nil }); err != nil { @@ -872,10 +865,10 @@ func (a *StateAPI) StateMinerPreCommitDepositForPower(ctx context.Context, maddr var sectorWeight abi.StoragePower if act, err := state.GetActor(market.Address); err != nil { return types.EmptyInt, xerrors.Errorf("loading miner actor %s: %w", maddr, err) - } else s, err := market.Load(store, act); err != nil { + } else if s, err := market.Load(store, act); err != nil { return types.EmptyInt, xerrors.Errorf("loading market actor state %s: %w", maddr, err) } else if w, vw, err := s.VerifyDealsForActivation(maddr, pci.DealIDs, ts.Height(), pci.Expiration); err != nil { - return types.EmptyInt, xerrors.Errorf("verifying deals for activation: %w", err) + return types.EmptyInt, xerrors.Errorf("verifying deals for activation: %w", err) } else { // NB: not exactly accurate, but should always lead us to *over* estimate, not under duration := pci.Expiration - ts.Height() @@ -887,9 +880,9 @@ func (a *StateAPI) StateMinerPreCommitDepositForPower(ctx context.Context, maddr var powerSmoothed smoothing.FilterEstimate if act, err := state.GetActor(power.Address); err != nil { return types.EmptyInt, xerrors.Errorf("loading miner actor: %w", err) - } else s, err := power.Load(store, act); err != nil { + } else if s, err := power.Load(store, act); err != nil { return types.EmptyInt, xerrors.Errorf("loading power actor state: %w", err) - } else p, err := s.TotalPowerSmoothed(); err != nil { + } else if p, err := s.TotalPowerSmoothed(); err != nil { return types.EmptyInt, xerrors.Errorf("failed to determine total power: %w", err) } else { powerSmoothed = p @@ -898,9 +891,9 @@ func (a *StateAPI) StateMinerPreCommitDepositForPower(ctx context.Context, maddr var rewardSmoothed smoothing.FilterEstimate if act, err := state.GetActor(reward.Address); err != nil { return types.EmptyInt, xerrors.Errorf("loading miner actor: %w", err) - } else s, err := reward.Load(store, act); err != nil { + } else if s, err := reward.Load(store, act); err != nil { return types.EmptyInt, xerrors.Errorf("loading reward actor state: %w", err) - } else r, err := s.RewardSmoothed(); err != nil { + } else if r, err := s.RewardSmoothed(); err != nil { return types.EmptyInt, xerrors.Errorf("failed to determine total reward: %w", err) } else { rewardSmoothed = r @@ -934,10 +927,10 @@ func (a *StateAPI) StateMinerInitialPledgeCollateral(ctx context.Context, maddr var sectorWeight abi.StoragePower if act, err := state.GetActor(market.Address); err != nil { return types.EmptyInt, xerrors.Errorf("loading miner actor %s: %w", maddr, err) - } else s, err := market.Load(store, act); err != nil { + } else if s, err := market.Load(store, act); err != nil { return types.EmptyInt, xerrors.Errorf("loading market actor state %s: %w", maddr, err) } else if w, vw, err := s.VerifyDealsForActivation(maddr, pci.DealIDs, ts.Height(), pci.Expiration); err != nil { - return types.EmptyInt, xerrors.Errorf("verifying deals for activation: %w", err) + return types.EmptyInt, xerrors.Errorf("verifying deals for activation: %w", err) } else { // NB: not exactly accurate, but should always lead us to *over* estimate, not under duration := pci.Expiration - ts.Height() @@ -947,16 +940,16 @@ func (a *StateAPI) StateMinerInitialPledgeCollateral(ctx context.Context, maddr } var ( - powerSmoothed smoothing.FilterEstimate + powerSmoothed smoothing.FilterEstimate pledgeCollerateral abi.TokenAmount ) if act, err := state.GetActor(power.Address); err != nil { return types.EmptyInt, xerrors.Errorf("loading miner actor: %w", err) - } else s, err := power.Load(store, act); err != nil { + } else if s, err := power.Load(store, act); err != nil { return types.EmptyInt, xerrors.Errorf("loading power actor state: %w", err) - } else p, err := s.TotalPowerSmoothed(); err != nil { + } else if p, err := s.TotalPowerSmoothed(); err != nil { return types.EmptyInt, xerrors.Errorf("failed to determine total power: %w", err) - } else c, err := s.TotalLocked(); err != nil { + } else if c, err := s.TotalLocked(); err != nil { return types.EmptyInt, xerrors.Errorf("failed to determine pledge collateral: %w", err) } else { powerSmoothed = p @@ -965,15 +958,15 @@ func (a *StateAPI) StateMinerInitialPledgeCollateral(ctx context.Context, maddr var ( rewardSmoothed smoothing.FilterEstimate - baselinePower abi.StoragePower + baselinePower abi.StoragePower ) if act, err := state.GetActor(reward.Address); err != nil { return types.EmptyInt, xerrors.Errorf("loading miner actor: %w", err) - } else s, err := reward.Load(store, act); err != nil { + } else if s, err := reward.Load(store, act); err != nil { return types.EmptyInt, xerrors.Errorf("loading reward actor state: %w", err) - } else r, err := s.RewardSmoothed(); err != nil { + } else if r, err := s.RewardSmoothed(); err != nil { return types.EmptyInt, xerrors.Errorf("failed to determine total reward: %w", err) - } else p, err := s.BaselinePower(); err != nil { + } else if p, err := s.BaselinePower(); err != nil { return types.EmptyInt, xerrors.Errorf("failed to determine baseline power: %w", err) } else { rewardSmoothed = r diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 6eedc9f54..89dd7c2c2 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -305,8 +305,30 @@ func (sm *StorageMinerAPI) MarketImportDealData(ctx context.Context, propCid cid return sm.StorageProvider.ImportDataForDeal(ctx, propCid, fi) } -func (sm *StorageMinerAPI) MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error) { - return sm.StorageProvider.ListDeals(ctx) +func (sm *StorageMinerAPI) listDeals(ctx context.Context) ([]api.MarketDeal, error) { + ts, err := sm.Full.ChainHead(ctx) + if err != nil { + return nil, err + } + tsk := ts.Key() + allDeals, err := sm.Full.StateMarketDeals(ctx, tsk) + if err != nil { + return nil, err + } + + var out []api.MarketDeal + + for _, deal := range allDeals { + if deal.Proposal.Provider == sm.Miner.Address() { + out = append(out, deal) + } + } + + return out, nil +} + +func (sm *StorageMinerAPI) MarketListDeals(ctx context.Context) ([]api.MarketDeal, error) { + return sm.StorageProvider.listDeals(ctx) } func (sm *StorageMinerAPI) MarketListRetrievalDeals(ctx context.Context) ([]retrievalmarket.ProviderDealState, error) { @@ -395,8 +417,8 @@ func (sm *StorageMinerAPI) MarketDataTransferUpdates(ctx context.Context) (<-cha return channels, nil } -func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) { - return sm.StorageProvider.ListDeals(ctx) +func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]api.MarketDeal, error) { + return sm.listDeals(ctx) } func (sm *StorageMinerAPI) RetrievalDealsList(ctx context.Context) (map[retrievalmarket.ProviderDealIdentifier]retrievalmarket.ProviderDealState, error) { diff --git a/storage/adapter_storage_miner.go b/storage/adapter_storage_miner.go index 8b64789ad..7dced4331 100644 --- a/storage/adapter_storage_miner.go +++ b/storage/adapter_storage_miner.go @@ -15,12 +15,13 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/market" + v0market "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -136,7 +137,7 @@ func (s SealingAPIAdapter) StateComputeDataCommitment(ctx context.Context, maddr return cid.Undef, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err) } - ccparams, err := actors.SerializeParams(&market.ComputeDataCommitmentParams{ + ccparams, err := actors.SerializeParams(&v0market.ComputeDataCommitmentParams{ DealIDs: deals, SectorType: sectorType, })