Merge pull request #3590 from filecoin-project/asr/multisig
Multisig API additions
This commit is contained in:
commit
9e9856bb45
@ -397,6 +397,9 @@ type FullNode interface {
|
|||||||
|
|
||||||
// MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent
|
// 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)
|
MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||||
|
// MsigGetVested returns the amount of FIL that vested in a multisig in a certain period.
|
||||||
|
// It takes the following params: <multisig address>, <start epoch>, <end epoch>
|
||||||
|
MsigGetVested(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error)
|
||||||
// MsigCreate creates a multisig wallet
|
// MsigCreate creates a multisig wallet
|
||||||
// It takes the following params: <required number of senders>, <approving addresses>, <unlock duration>
|
// It takes the following params: <required number of senders>, <approving addresses>, <unlock duration>
|
||||||
//<initial balance>, <sender address of the create msg>, <gas price>
|
//<initial balance>, <sender address of the create msg>, <gas price>
|
||||||
@ -413,17 +416,29 @@ type FullNode interface {
|
|||||||
// It takes the following params: <multisig address>, <proposed message ID>, <recipient address>, <value to transfer>,
|
// It takes the following params: <multisig address>, <proposed message ID>, <recipient address>, <value to transfer>,
|
||||||
// <sender address of the cancel msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
// <sender address of the cancel msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||||
MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
||||||
|
// MsigAddPropose proposes adding a signer in the multisig
|
||||||
|
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||||
|
// <new signer>, <whether the number of required signers should be increased>
|
||||||
|
MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error)
|
||||||
|
// MsigAddApprove approves a previously proposed AddSigner message
|
||||||
|
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||||
|
// <proposer address>, <new signer>, <whether the number of required signers should be increased>
|
||||||
|
MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error)
|
||||||
|
// MsigAddCancel cancels a previously proposed AddSigner message
|
||||||
|
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||||
|
// <new signer>, <whether the number of required signers should be increased>
|
||||||
|
MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (cid.Cid, error)
|
||||||
// MsigSwapPropose proposes swapping 2 signers in the multisig
|
// MsigSwapPropose proposes swapping 2 signers in the multisig
|
||||||
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||||
// <old signer> <new signer>
|
// <old signer>, <new signer>
|
||||||
MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error)
|
MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error)
|
||||||
// MsigSwapApprove approves a previously proposed SwapSigner
|
// MsigSwapApprove approves a previously proposed SwapSigner
|
||||||
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||||
// <proposer address>, <old signer> <new signer>
|
// <proposer address>, <old signer>, <new signer>
|
||||||
MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error)
|
MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error)
|
||||||
// MsigSwapCancel cancels a previously proposed SwapSigner message
|
// MsigSwapCancel cancels a previously proposed SwapSigner message
|
||||||
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||||
// <old signer> <new signer>
|
// <old signer>, <new signer>
|
||||||
MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error)
|
MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error)
|
||||||
|
|
||||||
MarketEnsureAvailable(context.Context, address.Address, address.Address, types.BigInt) (cid.Cid, error)
|
MarketEnsureAvailable(context.Context, address.Address, address.Address, types.BigInt) (cid.Cid, error)
|
||||||
|
@ -201,10 +201,14 @@ type FullNodeStruct struct {
|
|||||||
StateCirculatingSupply func(context.Context, types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
|
StateCirculatingSupply func(context.Context, types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
|
||||||
|
|
||||||
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, 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"`
|
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"`
|
MsigPropose func(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
||||||
MsigApprove func(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
MsigApprove func(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
||||||
MsigCancel func(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
MsigCancel func(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
||||||
|
MsigAddPropose func(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error) `perm:"sign"`
|
||||||
|
MsigAddApprove func(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error) `perm:"sign"`
|
||||||
|
MsigAddCancel func(context.Context, address.Address, address.Address, uint64, address.Address, bool) (cid.Cid, error) `perm:"sign"`
|
||||||
MsigSwapPropose func(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
|
MsigSwapPropose func(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
|
||||||
MsigSwapApprove func(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
|
MsigSwapApprove func(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
|
||||||
MsigSwapCancel func(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
|
MsigSwapCancel func(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
|
||||||
@ -882,6 +886,10 @@ func (c *FullNodeStruct) MsigGetAvailableBalance(ctx context.Context, a address.
|
|||||||
return c.Internal.MsigGetAvailableBalance(ctx, a, tsk)
|
return c.Internal.MsigGetAvailableBalance(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)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) MsigCreate(ctx context.Context, req uint64, addrs []address.Address, duration abi.ChainEpoch, val types.BigInt, src address.Address, gp types.BigInt) (cid.Cid, error) {
|
func (c *FullNodeStruct) MsigCreate(ctx context.Context, req uint64, addrs []address.Address, duration abi.ChainEpoch, val types.BigInt, src address.Address, gp types.BigInt) (cid.Cid, error) {
|
||||||
return c.Internal.MsigCreate(ctx, req, addrs, duration, val, src, gp)
|
return c.Internal.MsigCreate(ctx, req, addrs, duration, val, src, gp)
|
||||||
}
|
}
|
||||||
@ -898,6 +906,18 @@ func (c *FullNodeStruct) MsigCancel(ctx context.Context, msig address.Address, t
|
|||||||
return c.Internal.MsigCancel(ctx, msig, txID, to, amt, src, method, params)
|
return c.Internal.MsigCancel(ctx, msig, txID, to, amt, src, method, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) MsigAddPropose(ctx context.Context, msig address.Address, src address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||||
|
return c.Internal.MsigAddPropose(ctx, msig, src, newAdd, inc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||||
|
return c.Internal.MsigAddApprove(ctx, msig, src, txID, proposer, newAdd, inc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||||
|
return c.Internal.MsigAddCancel(ctx, msig, src, txID, newAdd, inc)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
func (c *FullNodeStruct) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||||
return c.Internal.MsigSwapPropose(ctx, msig, src, oldAdd, newAdd)
|
return c.Internal.MsigSwapPropose(ctx, msig, src, oldAdd, newAdd)
|
||||||
}
|
}
|
||||||
|
300
cli/multisig.go
300
cli/multisig.go
@ -37,9 +37,13 @@ var multisigCmd = &cli.Command{
|
|||||||
msigInspectCmd,
|
msigInspectCmd,
|
||||||
msigProposeCmd,
|
msigProposeCmd,
|
||||||
msigApproveCmd,
|
msigApproveCmd,
|
||||||
|
msigAddProposeCmd,
|
||||||
|
msigAddApproveCmd,
|
||||||
|
msigAddCancelCmd,
|
||||||
msigSwapProposeCmd,
|
msigSwapProposeCmd,
|
||||||
msigSwapApproveCmd,
|
msigSwapApproveCmd,
|
||||||
msigSwapCancelCmd,
|
msigSwapCancelCmd,
|
||||||
|
msigVestedCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,6 +510,236 @@ var msigApproveCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var msigAddProposeCmd = &cli.Command{
|
||||||
|
Name: "add-propose",
|
||||||
|
Usage: "Propose to add a signer",
|
||||||
|
ArgsUsage: "[multisigAddress signer]",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "increase-threshold",
|
||||||
|
Usage: "whether the number of required signers should be increased",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "from",
|
||||||
|
Usage: "account to send the propose message from",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() != 2 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("must pass multisig address and signer address"))
|
||||||
|
}
|
||||||
|
|
||||||
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
addr, err := address.NewFromString(cctx.Args().Get(1))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var from address.Address
|
||||||
|
if cctx.IsSet("from") {
|
||||||
|
f, err := address.NewFromString(cctx.String("from"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
from = f
|
||||||
|
} else {
|
||||||
|
defaddr, err := api.WalletDefaultAddress(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
from = defaddr
|
||||||
|
}
|
||||||
|
|
||||||
|
msgCid, err := api.MsigAddPropose(ctx, msig, from, addr, cctx.Bool("increase-threshold"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("sent add proposal in message: ", msgCid)
|
||||||
|
|
||||||
|
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if wait.Receipt.ExitCode != 0 {
|
||||||
|
return fmt.Errorf("add proposal returned exit %d", wait.Receipt.ExitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var msigAddApproveCmd = &cli.Command{
|
||||||
|
Name: "add-approve",
|
||||||
|
Usage: "Approve a message to add a signer",
|
||||||
|
ArgsUsage: "[multisigAddress proposerAddress txId newAddress increaseThreshold]",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "from",
|
||||||
|
Usage: "account to send the approve message from",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() != 5 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, proposer address, transaction id, new signer address, whether to increase threshold"))
|
||||||
|
}
|
||||||
|
|
||||||
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
prop, err := address.NewFromString(cctx.Args().Get(1))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
txid, err := strconv.ParseUint(cctx.Args().Get(2), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newAdd, err := address.NewFromString(cctx.Args().Get(3))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
inc, err := strconv.ParseBool(cctx.Args().Get(4))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var from address.Address
|
||||||
|
if cctx.IsSet("from") {
|
||||||
|
f, err := address.NewFromString(cctx.String("from"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
from = f
|
||||||
|
} else {
|
||||||
|
defaddr, err := api.WalletDefaultAddress(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
from = defaddr
|
||||||
|
}
|
||||||
|
|
||||||
|
msgCid, err := api.MsigAddApprove(ctx, msig, from, txid, prop, newAdd, inc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("sent add approval in message: ", msgCid)
|
||||||
|
|
||||||
|
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if wait.Receipt.ExitCode != 0 {
|
||||||
|
return fmt.Errorf("add approval returned exit %d", wait.Receipt.ExitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var msigAddCancelCmd = &cli.Command{
|
||||||
|
Name: "add-cancel",
|
||||||
|
Usage: "Cancel a message to add a signer",
|
||||||
|
ArgsUsage: "[multisigAddress txId newAddress increaseThreshold]",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "from",
|
||||||
|
Usage: "account to send the approve message from",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() != 4 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, transaction id, new signer address, whether to increase threshold"))
|
||||||
|
}
|
||||||
|
|
||||||
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
txid, err := strconv.ParseUint(cctx.Args().Get(1), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newAdd, err := address.NewFromString(cctx.Args().Get(2))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
inc, err := strconv.ParseBool(cctx.Args().Get(3))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var from address.Address
|
||||||
|
if cctx.IsSet("from") {
|
||||||
|
f, err := address.NewFromString(cctx.String("from"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
from = f
|
||||||
|
} else {
|
||||||
|
defaddr, err := api.WalletDefaultAddress(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
from = defaddr
|
||||||
|
}
|
||||||
|
|
||||||
|
msgCid, err := api.MsigAddCancel(ctx, msig, from, txid, newAdd, inc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("sent add cancellation in message: ", msgCid)
|
||||||
|
|
||||||
|
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if wait.Receipt.ExitCode != 0 {
|
||||||
|
return fmt.Errorf("add cancellation returned exit %d", wait.Receipt.ExitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
var msigSwapProposeCmd = &cli.Command{
|
var msigSwapProposeCmd = &cli.Command{
|
||||||
Name: "swap-propose",
|
Name: "swap-propose",
|
||||||
Usage: "Propose to swap signers",
|
Usage: "Propose to swap signers",
|
||||||
@ -722,7 +956,7 @@ var msigSwapCancelCmd = &cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("sent swap approval in message: ", msgCid)
|
fmt.Println("sent swap cancellation in message: ", msgCid)
|
||||||
|
|
||||||
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
|
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -730,9 +964,71 @@ var msigSwapCancelCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if wait.Receipt.ExitCode != 0 {
|
if wait.Receipt.ExitCode != 0 {
|
||||||
return fmt.Errorf("swap approval returned exit %d", wait.Receipt.ExitCode)
|
return fmt.Errorf("swap cancellation returned exit %d", wait.Receipt.ExitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var msigVestedCmd = &cli.Command{
|
||||||
|
Name: "vested",
|
||||||
|
Usage: "Gets the amount vested in an msig between two epochs",
|
||||||
|
ArgsUsage: "[multisigAddress]",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.Int64Flag{
|
||||||
|
Name: "start-epoch",
|
||||||
|
Usage: "start epoch to measure vesting from",
|
||||||
|
Value: 0,
|
||||||
|
},
|
||||||
|
&cli.Int64Flag{
|
||||||
|
Name: "end-epoch",
|
||||||
|
Usage: "end epoch to stop measure vesting at",
|
||||||
|
Value: -1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() != 1 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("must pass multisig address"))
|
||||||
|
}
|
||||||
|
|
||||||
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
start, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Int64("start-epoch")), types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var end *types.TipSet
|
||||||
|
if cctx.Int64("end-epoch") < 0 {
|
||||||
|
end, err = LoadTipSet(ctx, cctx, api)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
end, err = api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Int64("end-epoch")), types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret, err := api.MsigGetVested(ctx, msig, start.Key(), end.Key())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Vested: %s between %d and %d\n", types.FIL(ret), start.Height(), end.Height())
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -75,10 +75,14 @@
|
|||||||
* [MpoolSetConfig](#MpoolSetConfig)
|
* [MpoolSetConfig](#MpoolSetConfig)
|
||||||
* [MpoolSub](#MpoolSub)
|
* [MpoolSub](#MpoolSub)
|
||||||
* [Msig](#Msig)
|
* [Msig](#Msig)
|
||||||
|
* [MsigAddApprove](#MsigAddApprove)
|
||||||
|
* [MsigAddCancel](#MsigAddCancel)
|
||||||
|
* [MsigAddPropose](#MsigAddPropose)
|
||||||
* [MsigApprove](#MsigApprove)
|
* [MsigApprove](#MsigApprove)
|
||||||
* [MsigCancel](#MsigCancel)
|
* [MsigCancel](#MsigCancel)
|
||||||
* [MsigCreate](#MsigCreate)
|
* [MsigCreate](#MsigCreate)
|
||||||
* [MsigGetAvailableBalance](#MsigGetAvailableBalance)
|
* [MsigGetAvailableBalance](#MsigGetAvailableBalance)
|
||||||
|
* [MsigGetVested](#MsigGetVested)
|
||||||
* [MsigPropose](#MsigPropose)
|
* [MsigPropose](#MsigPropose)
|
||||||
* [MsigSwapApprove](#MsigSwapApprove)
|
* [MsigSwapApprove](#MsigSwapApprove)
|
||||||
* [MsigSwapCancel](#MsigSwapCancel)
|
* [MsigSwapCancel](#MsigSwapCancel)
|
||||||
@ -1839,6 +1843,84 @@ The Msig methods are used to interact with multisig wallets on the
|
|||||||
filecoin network
|
filecoin network
|
||||||
|
|
||||||
|
|
||||||
|
### MsigAddApprove
|
||||||
|
MsigAddApprove approves a previously proposed AddSigner message
|
||||||
|
It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||||
|
<proposer address>, <new signer>, <whether the number of required signers should be increased>
|
||||||
|
|
||||||
|
|
||||||
|
Perms: sign
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"t01234",
|
||||||
|
"t01234",
|
||||||
|
42,
|
||||||
|
"t01234",
|
||||||
|
"t01234",
|
||||||
|
true
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### MsigAddCancel
|
||||||
|
MsigAddCancel cancels a previously proposed AddSigner message
|
||||||
|
It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||||
|
<new signer>, <whether the number of required signers should be increased>
|
||||||
|
|
||||||
|
|
||||||
|
Perms: sign
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"t01234",
|
||||||
|
"t01234",
|
||||||
|
42,
|
||||||
|
"t01234",
|
||||||
|
true
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### MsigAddPropose
|
||||||
|
MsigAddPropose proposes adding a signer in the multisig
|
||||||
|
It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||||
|
<new signer>, <whether the number of required signers should be increased>
|
||||||
|
|
||||||
|
|
||||||
|
Perms: sign
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"t01234",
|
||||||
|
"t01234",
|
||||||
|
"t01234",
|
||||||
|
true
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### MsigApprove
|
### MsigApprove
|
||||||
MsigApprove approves a previously-proposed multisig message
|
MsigApprove approves a previously-proposed multisig message
|
||||||
It takes the following params: <multisig address>, <proposed message ID>, <proposer address>, <recipient address>, <value to transfer>,
|
It takes the following params: <multisig address>, <proposed message ID>, <proposer address>, <recipient address>, <value to transfer>,
|
||||||
@ -1946,6 +2028,38 @@ Inputs:
|
|||||||
|
|
||||||
Response: `"0"`
|
Response: `"0"`
|
||||||
|
|
||||||
|
### MsigGetVested
|
||||||
|
MsigGetVested returns the amount of FIL that vested in a multisig in a certain period.
|
||||||
|
It takes the following params: <multisig address>, <start epoch>, <end epoch>
|
||||||
|
|
||||||
|
|
||||||
|
Perms: read
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"t01234",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response: `"0"`
|
||||||
|
|
||||||
### MsigPropose
|
### MsigPropose
|
||||||
MsigPropose proposes a multisig message
|
MsigPropose proposes a multisig message
|
||||||
It takes the following params: <multisig address>, <recipient address>, <value to transfer>,
|
It takes the following params: <multisig address>, <recipient address>, <value to transfer>,
|
||||||
@ -1976,7 +2090,7 @@ Response:
|
|||||||
### MsigSwapApprove
|
### MsigSwapApprove
|
||||||
MsigSwapApprove approves a previously proposed SwapSigner
|
MsigSwapApprove approves a previously proposed SwapSigner
|
||||||
It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||||
<proposer address>, <old signer> <new signer>
|
<proposer address>, <old signer>, <new signer>
|
||||||
|
|
||||||
|
|
||||||
Perms: sign
|
Perms: sign
|
||||||
@ -2003,7 +2117,7 @@ Response:
|
|||||||
### MsigSwapCancel
|
### MsigSwapCancel
|
||||||
MsigSwapCancel cancels a previously proposed SwapSigner message
|
MsigSwapCancel cancels a previously proposed SwapSigner message
|
||||||
It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||||
<old signer> <new signer>
|
<old signer>, <new signer>
|
||||||
|
|
||||||
|
|
||||||
Perms: sign
|
Perms: sign
|
||||||
@ -2029,7 +2143,7 @@ Response:
|
|||||||
### MsigSwapPropose
|
### MsigSwapPropose
|
||||||
MsigSwapPropose proposes swapping 2 signers in the multisig
|
MsigSwapPropose proposes swapping 2 signers in the multisig
|
||||||
It takes the following params: <multisig address>, <sender address of the propose msg>,
|
It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||||
<old signer> <new signer>
|
<old signer>, <new signer>
|
||||||
|
|
||||||
|
|
||||||
Perms: sign
|
Perms: sign
|
||||||
|
@ -130,6 +130,33 @@ func (a *MsigAPI) MsigPropose(ctx context.Context, msig address.Address, to addr
|
|||||||
return smsg.Cid(), nil
|
return smsg.Cid(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *MsigAPI) MsigAddPropose(ctx context.Context, msig address.Address, src address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||||
|
enc, actErr := serializeAddParams(newAdd, inc)
|
||||||
|
if actErr != nil {
|
||||||
|
return cid.Undef, actErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.MsigPropose(ctx, msig, msig, big.Zero(), src, uint64(builtin.MethodsMultisig.AddSigner), enc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *MsigAPI) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||||
|
enc, actErr := serializeAddParams(newAdd, inc)
|
||||||
|
if actErr != nil {
|
||||||
|
return cid.Undef, actErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.MsigApprove(ctx, msig, txID, proposer, msig, big.Zero(), src, uint64(builtin.MethodsMultisig.AddSigner), enc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *MsigAPI) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||||
|
enc, actErr := serializeAddParams(newAdd, inc)
|
||||||
|
if actErr != nil {
|
||||||
|
return cid.Undef, actErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(builtin.MethodsMultisig.AddSigner), enc)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *MsigAPI) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
func (a *MsigAPI) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||||
enc, actErr := serializeSwapParams(oldAdd, newAdd)
|
enc, actErr := serializeSwapParams(oldAdd, newAdd)
|
||||||
if actErr != nil {
|
if actErr != nil {
|
||||||
@ -244,6 +271,18 @@ func (a *MsigAPI) msigApproveOrCancel(ctx context.Context, operation api.MsigPro
|
|||||||
return smsg.Cid(), nil
|
return smsg.Cid(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func serializeAddParams(new address.Address, inc bool) ([]byte, error) {
|
||||||
|
enc, actErr := actors.SerializeParams(&samsig.AddSignerParams{
|
||||||
|
Signer: new,
|
||||||
|
Increase: inc,
|
||||||
|
})
|
||||||
|
if actErr != nil {
|
||||||
|
return nil, actErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return enc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func serializeSwapParams(old address.Address, new address.Address) ([]byte, error) {
|
func serializeSwapParams(old address.Address, new address.Address) ([]byte, error) {
|
||||||
enc, actErr := actors.SerializeParams(&samsig.SwapSignerParams{
|
enc, actErr := actors.SerializeParams(&samsig.SwapSignerParams{
|
||||||
From: old,
|
From: old,
|
||||||
|
@ -886,6 +886,48 @@ func (a *StateAPI) MsigGetAvailableBalance(ctx context.Context, addr address.Add
|
|||||||
return types.BigSub(act.Balance, minBalance), nil
|
return types.BigSub(act.Balance, minBalance), 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 {
|
||||||
|
return types.EmptyInt, xerrors.Errorf("loading start tipset %s: %w", start, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
endTs, err := a.Chain.GetTipSetFromKey(end)
|
||||||
|
if err != nil {
|
||||||
|
return types.EmptyInt, xerrors.Errorf("loading end tipset %s: %w", end, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if startTs.Height() > endTs.Height() {
|
||||||
|
return types.EmptyInt, xerrors.Errorf("start tipset %d is after end tipset %d", startTs.Height(), endTs.Height())
|
||||||
|
} else if startTs.Height() == endTs.Height() {
|
||||||
|
return big.Zero(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var mst samsig.State
|
||||||
|
act, err := a.StateManager.LoadActorState(ctx, addr, &mst, endTs)
|
||||||
|
if err != nil {
|
||||||
|
return types.EmptyInt, xerrors.Errorf("failed to load multisig actor state at end epoch: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if act.Code != builtin.MultisigActorCodeID {
|
||||||
|
return types.EmptyInt, fmt.Errorf("given actor was not a multisig")
|
||||||
|
}
|
||||||
|
|
||||||
|
if mst.UnlockDuration == 0 ||
|
||||||
|
mst.InitialBalance.IsZero() ||
|
||||||
|
mst.StartEpoch+mst.UnlockDuration <= startTs.Height() ||
|
||||||
|
mst.StartEpoch >= endTs.Height() {
|
||||||
|
return big.Zero(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
startLk := mst.InitialBalance
|
||||||
|
if startTs.Height() > mst.StartEpoch {
|
||||||
|
startLk = mst.AmountLocked(startTs.Height() - mst.StartEpoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
return big.Sub(startLk, mst.AmountLocked(endTs.Height()-mst.StartEpoch)), nil
|
||||||
|
}
|
||||||
|
|
||||||
var initialPledgeNum = types.NewInt(110)
|
var initialPledgeNum = types.NewInt(110)
|
||||||
var initialPledgeDen = types.NewInt(100)
|
var initialPledgeDen = types.NewInt(100)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user