From fe5b32026ac725167e38208576eb23d5333475ff Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Thu, 8 Oct 2020 15:19:39 -0400 Subject: [PATCH] Add some new endpoints for querying Msig info --- api/api_full.go | 15 +++++++++++++ api/apistruct/struct.go | 5 +++++ documentation/en/api-methods.md | 32 +++++++++++++++++++++++++++ node/impl/full/state.go | 38 +++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+) diff --git a/api/api_full.go b/api/api_full.go index b6ae77f77..601b14660 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -418,6 +418,9 @@ type FullNode interface { // MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) + // MsigGetLockedBalance returns the locked balance of an msig at a vien epoch. + // The return may be greater than the multisig actor's actual balance. + MsigGetVestingSchedule(context.Context, address.Address, types.TipSetKey) (MsigVesting, error) // MsigGetVested returns the amount of FIL that vested in a multisig in a certain period. // It takes the following params: , , MsigGetVested(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error) @@ -871,3 +874,15 @@ type Fault struct { Miner address.Address Epoch abi.ChainEpoch } + +var EmptyVesting = MsigVesting{ + InitialBalance: types.EmptyInt, + StartEpoch: -1, + UnlockDuration: -1, +} + +type MsigVesting struct { + InitialBalance abi.TokenAmount + StartEpoch abi.ChainEpoch + UnlockDuration abi.ChainEpoch +} diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index a09700eb9..1a3ddda58 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -212,6 +212,7 @@ type FullNodeStruct struct { StateNetworkVersion func(context.Context, types.TipSetKey) (stnetwork.Version, error) `perm:"read"` MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"` + MsigGetVestingSchedule func(context.Context, address.Address, types.TipSetKey) (api.MsigVesting, error) `perm:"read"` MsigGetVested func(context.Context, address.Address, types.TipSetKey, 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"` MsigPropose func(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"` @@ -933,6 +934,10 @@ func (c *FullNodeStruct) MsigGetAvailableBalance(ctx context.Context, a address. return c.Internal.MsigGetAvailableBalance(ctx, a, tsk) } +func (c *FullNodeStruct) MsigGetVestingSchedule(ctx context.Context, a address.Address, tsk types.TipSetKey) (api.MsigVesting, error) { + return c.Internal.MsigGetVestingSchedule(ctx, a, tsk) +} + func (c *FullNodeStruct) MsigGetVested(ctx context.Context, a address.Address, sTsk types.TipSetKey, eTsk types.TipSetKey) (types.BigInt, error) { return c.Internal.MsigGetVested(ctx, a, sTsk, eTsk) } diff --git a/documentation/en/api-methods.md b/documentation/en/api-methods.md index a6ad1ecb2..8a288a4bf 100644 --- a/documentation/en/api-methods.md +++ b/documentation/en/api-methods.md @@ -87,6 +87,7 @@ * [MsigCreate](#MsigCreate) * [MsigGetAvailableBalance](#MsigGetAvailableBalance) * [MsigGetVested](#MsigGetVested) + * [MsigGetVestingSchedule](#MsigGetVestingSchedule) * [MsigPropose](#MsigPropose) * [MsigSwapApprove](#MsigSwapApprove) * [MsigSwapCancel](#MsigSwapCancel) @@ -2143,6 +2144,37 @@ Inputs: Response: `"0"` +### MsigGetVestingSchedule +MsigGetLockedBalance returns the locked balance of an msig at a vien epoch. +The return may be greater than the multisig actor's actual balance. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "InitialBalance": "0", + "StartEpoch": 10101, + "UnlockDuration": 10101 +} +``` + ### MsigPropose MsigPropose proposes a multisig message It takes the following params: , , , diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 7d654985a..56dfc0a14 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -820,6 +820,44 @@ func (a *StateAPI) MsigGetAvailableBalance(ctx context.Context, addr address.Add return types.BigSub(act.Balance, locked), nil } +func (a *StateAPI) MsigGetVestingSchedule(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MsigVesting, error) { + ts, err := a.Chain.GetTipSetFromKey(tsk) + if err != nil { + return api.EmptyVesting, xerrors.Errorf("loading tipset %s: %w", tsk, err) + } + + act, err := a.StateManager.LoadActor(ctx, addr, ts) + if err != nil { + return api.EmptyVesting, xerrors.Errorf("failed to load multisig actor: %w", err) + } + + msas, err := multisig.Load(a.Chain.Store(ctx), act) + if err != nil { + return api.EmptyVesting, xerrors.Errorf("failed to load multisig actor state: %w", err) + } + + ib, err := msas.InitialBalance() + if err != nil { + return api.EmptyVesting, xerrors.Errorf("failed to load multisig initial balance: %w", err) + } + + se, err := msas.StartEpoch() + if err != nil { + return api.EmptyVesting, xerrors.Errorf("failed to load multisig start epoch: %w", err) + } + + ud, err := msas.UnlockDuration() + if err != nil { + return api.EmptyVesting, xerrors.Errorf("failed to load multisig unlock duration: %w", err) + } + + return api.MsigVesting{ + InitialBalance: ib, + StartEpoch: se, + UnlockDuration: ud, + }, nil +} + func (a *StateAPI) MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) { startTs, err := a.Chain.GetTipSetFromKey(start) if err != nil {