From 729c052f6411551b6aa73b58b8c8051b107dcd4a Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Thu, 30 Jul 2020 00:55:37 -0400 Subject: [PATCH] Update specs-actors, support deal provider collateral bounds --- api/api_full.go | 3 +++ api/apistruct/struct.go | 5 ++++ go.mod | 4 +-- go.sum | 4 +++ markets/storageadapter/client.go | 4 +++ markets/storageadapter/provider.go | 4 +++ node/impl/full/state.go | 39 ++++++++++++++++++++++++++++++ 7 files changed, 61 insertions(+), 2 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 10388e105..42f0cff27 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -329,6 +329,9 @@ type FullNode interface { // Returns nil if there is no entry in the data cap table for the // address. StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*verifreg.DataCap, error) + // StateDealProviderCollateralBounds returns the min and max collateral a storage provider + // can issue. It takes the deal size and verified status as parameters. + StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (abi.TokenAmount, abi.TokenAmount, error) // MethodGroup: Msig // The Msig methods are used to interact with multisig wallets on the diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 9aa2a4963..a3824dc7a 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -167,6 +167,7 @@ type FullNodeStruct struct { StateListMessages func(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"` StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"` StateVerifiedClientStatus func(context.Context, address.Address, types.TipSetKey) (*verifreg.DataCap, error) `perm:"read"` + StateDealProviderCollateralBounds func(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (abi.TokenAmount, abi.TokenAmount, error) `perm:"read"` MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"` MsigCreate func(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error) `perm:"sign"` @@ -746,6 +747,10 @@ func (c *FullNodeStruct) StateVerifiedClientStatus(ctx context.Context, addr add return c.Internal.StateVerifiedClientStatus(ctx, addr, tsk) } +func (c *FullNodeStruct) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (abi.TokenAmount, abi.TokenAmount, error) { + return c.Internal.StateDealProviderCollateralBounds(ctx, size, verified, tsk) +} + func (c *FullNodeStruct) MsigGetAvailableBalance(ctx context.Context, a address.Address, tsk types.TipSetKey) (types.BigInt, error) { return c.Internal.MsigGetAvailableBalance(ctx, a, tsk) } diff --git a/go.mod b/go.mod index 30ce41e35..f0a21a4d5 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/filecoin-project/chain-validation v0.0.6-0.20200728204507-037308fa7af2 github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200716204036-cddc56607e1d github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef - github.com/filecoin-project/go-bitfield v0.1.1 + github.com/filecoin-project/go-bitfield v0.1.2 github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v0.5.1 @@ -30,7 +30,7 @@ require ( github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/sector-storage v0.0.0-20200727112136-9377cb376d25 - github.com/filecoin-project/specs-actors v0.8.1-0.20200728182452-1476088f645b + github.com/filecoin-project/specs-actors v0.8.2 github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea github.com/filecoin-project/storage-fsm v0.0.0-20200728185042-33f96f051f20 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index d653c940a..b39a6e3f8 100644 --- a/go.sum +++ b/go.sum @@ -235,6 +235,8 @@ github.com/filecoin-project/go-bitfield v0.0.4-0.20200703174658-f4a5758051a1 h1: github.com/filecoin-project/go-bitfield v0.0.4-0.20200703174658-f4a5758051a1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= github.com/filecoin-project/go-bitfield v0.1.1 h1:ioLGippGXLS93uBMbpSwVPD7h2Oz1FYq/WPYDfT7W/A= github.com/filecoin-project/go-bitfield v0.1.1/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= +github.com/filecoin-project/go-bitfield v0.1.2 h1:TjLregCoyP1/5lm7WCM0axyV1myIHwbjGa21skuu5tk= +github.com/filecoin-project/go-bitfield v0.1.2/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= @@ -277,6 +279,8 @@ github.com/filecoin-project/specs-actors v0.7.3-0.20200716231407-60a2ae96d2e6/go github.com/filecoin-project/specs-actors v0.8.1-0.20200720115956-cd051eabf328/go.mod h1:0+CxQ5Jeii3522irTvhKRDpr4GG1bj5Erq3p/d38DzY= github.com/filecoin-project/specs-actors v0.8.1-0.20200728182452-1476088f645b h1:Tr34QNdGYMT2ghM6o1H1bMziTw/nWd/B2Um2A3vWp2c= github.com/filecoin-project/specs-actors v0.8.1-0.20200728182452-1476088f645b/go.mod h1:U1qnlL3MjJnE6n3MTUUVhlmpJodx+fo26cC0aiL1jeo= +github.com/filecoin-project/specs-actors v0.8.2 h1:fpAPOPqWqmzJCWHpm6P1XDRSpQrxyY5Pzh5H3doYs7Q= +github.com/filecoin-project/specs-actors v0.8.2/go.mod h1:Q3ACV5kBLvqPaYbthc/J1lGMJ5OwogmD9pzdtPRMdCw= github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea h1:iixjULRQFPn7Q9KlIqfwLJnlAXO10bbkI+xy5GKGdLY= github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 38c8d5a4e..f5cb43251 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -238,6 +238,10 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor return res.IDs[dealIdx], nil } +func (c *ClientNodeAdapter) DealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, isVerified bool) (abi.TokenAmount, abi.TokenAmount, error) { + return c.StateDealProviderCollateralBounds(ctx, size, isVerified, types.EmptyTSK) +} + func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider address.Address, dealId abi.DealID, cb storagemarket.DealSectorCommittedCallback) error { checkFunc := func(ts *types.TipSet) (done bool, more bool, err error) { sd, err := stmgr.GetStorageDeal(ctx, c.StateManager, dealId, ts) diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go index 86419df42..cad4e70e5 100644 --- a/markets/storageadapter/provider.go +++ b/markets/storageadapter/provider.go @@ -228,6 +228,10 @@ func (n *ProviderNodeAdapter) LocatePieceForDealWithinSector(ctx context.Context return uint64(best.SectorID), uint64(best.Offset.Unpadded()), uint64(best.Size), nil } +func (n *ProviderNodeAdapter) DealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, isVerified bool) (abi.TokenAmount, abi.TokenAmount, error) { + return n.StateDealProviderCollateralBounds(ctx, size, isVerified, types.EmptyTSK) +} + func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider address.Address, dealID abi.DealID, cb storagemarket.DealSectorCommittedCallback) error { checkFunc := func(ts *types.TipSet) (done bool, more bool, err error) { sd, err := n.StateMarketStorageDeal(ctx, dealID, ts.Key()) diff --git a/node/impl/full/state.go b/node/impl/full/state.go index f6cc6550d..c4228a90b 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -1146,3 +1146,42 @@ func (a *StateAPI) StateVerifiedClientStatus(ctx context.Context, addr address.A return &dcap, nil } + +var dealProviderCollateralNum = types.NewInt(110) +var dealProviderCollateralDen = types.NewInt(100) + +// StateDealProviderCollateralBounds returns the min and max collateral a storage provider +// can issue. It takes the deal size and verified status as parameters. +func (a *StateAPI) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (abi.TokenAmount, abi.TokenAmount, error) { + ts, err := a.Chain.GetTipSetFromKey(tsk) + if err != nil { + return big.Zero(), big.Zero(), xerrors.Errorf("loading tipset %s: %w", tsk, err) + } + + var powerState power.State + var rewardState reward.State + + err = a.StateManager.WithParentStateTsk(ts.Key(), func(state *state.StateTree) error { + if err := a.StateManager.WithActor(builtin.StoragePowerActorAddr, a.StateManager.WithActorState(ctx, &powerState))(state); err != nil { + return xerrors.Errorf("getting power state: %w", err) + } + + if err := a.StateManager.WithActor(builtin.RewardActorAddr, a.StateManager.WithActorState(ctx, &rewardState))(state); err != nil { + return xerrors.Errorf("getting reward state: %w", err) + } + + return nil + }) + + if err != nil { + return big.Zero(), big.Zero(), xerrors.Errorf("getting power and reward actor states: %w") + } + + circ, err := a.StateManager.CirculatingSupply(ctx, ts) + if err != nil { + return big.Zero(), big.Zero(), xerrors.Errorf("getting total circulating supply: %w") + } + + min, max := market.DealProviderCollateralBounds(size, verified, powerState.ThisEpochQualityAdjPower, rewardState.ThisEpochBaselinePower, circ) + return types.BigDiv(types.BigMul(min, dealProviderCollateralNum), dealProviderCollateralDen), max, nil +}