From 1565e10fff20f25d6dd6177b9dd317664f5195c5 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 24 Apr 2020 17:55:33 -0400 Subject: [PATCH 1/3] Allow users to specify sender when creating multisigs --- cli/multisig.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/cli/multisig.go b/cli/multisig.go index 0913c1ff9..fb0294b51 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -59,6 +59,10 @@ var msigCreateCmd = &cli.Command{ Usage: "initial funds to give to multisig", Value: "0", }, + &cli.StringFlag{ + Name: "sender", + Usage: "account to send the create message from", + }, }, Action: func(cctx *cli.Context) error { api, closer, err := GetFullNodeAPI(cctx) @@ -78,9 +82,21 @@ var msigCreateCmd = &cli.Command{ } // get the address we're going to use to create the multisig (can be one of the above, as long as they have funds) - sendAddr, err := api.WalletDefaultAddress(ctx) - if err != nil { - return err + var sendAddr address.Address + if send := cctx.String("sender"); send == "" { + defaddr, err := api.WalletDefaultAddress(ctx) + if err != nil { + return err + } + + sendAddr = defaddr + } else { + addr, err := address.NewFromString(send) + if err != nil { + return err + } + + sendAddr = addr } val := cctx.String("value") From c3b1cf19a4b6d849b11b597eb89aaf03e9bc3cd0 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 24 Apr 2020 18:00:31 -0400 Subject: [PATCH 2/3] Actually use the multisig source flag --- cli/multisig.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cli/multisig.go b/cli/multisig.go index fb0294b51..36f0bb5c9 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -291,7 +291,12 @@ var msigProposeCmd = &cli.Command{ Name: "propose", Usage: "Propose a multisig transaction", ArgsUsage: "[multisigAddress destinationAddress value (optional)]", - Flags: []cli.Flag{}, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "source", + Usage: "account to send the propose message from", + }, + }, Action: func(cctx *cli.Context) error { api, closer, err := GetFullNodeAPI(cctx) if err != nil { @@ -341,7 +346,7 @@ var msigProposeCmd = &cli.Command{ enc, err := actors.SerializeParams(&samsig.ProposeParams{ To: dest, - Value: abi.TokenAmount(types.BigInt(value)), + Value: types.BigInt(value), Method: abi.MethodNum(method), Params: params, }) From fa1b559b2c171b88a80065bac9e5a21a0fc03898 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Sat, 25 Apr 2020 01:39:25 -0400 Subject: [PATCH 3/3] CLI: multisig approve needs to recreate proposal hash --- cli/multisig.go | 76 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/cli/multisig.go b/cli/multisig.go index 36f0bb5c9..e5b8e9a41 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -6,6 +6,7 @@ import ( "encoding/binary" "encoding/hex" "fmt" + "github.com/minio/blake2b-simd" "os" "sort" "strconv" @@ -290,7 +291,7 @@ func state(tx *samsig.Transaction) string { var msigProposeCmd = &cli.Command{ Name: "propose", Usage: "Propose a multisig transaction", - ArgsUsage: "[multisigAddress destinationAddress value (optional)]", + ArgsUsage: "[multisigAddress destinationAddress value (optional)]", Flags: []cli.Flag{ &cli.StringFlag{ Name: "source", @@ -409,8 +410,13 @@ var msigProposeCmd = &cli.Command{ var msigApproveCmd = &cli.Command{ Name: "approve", Usage: "Approve a multisig message", - ArgsUsage: "[multisigAddress messageId]", - Flags: []cli.Flag{}, + ArgsUsage: "[multisigAddress messageId proposerAddress destination value (optional)]", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "source", + Usage: "account to send the approve message from", + }, + }, Action: func(cctx *cli.Context) error { api, closer, err := GetFullNodeAPI(cctx) if err != nil { @@ -419,8 +425,12 @@ var msigApproveCmd = &cli.Command{ defer closer() ctx := ReqContext(cctx) - if cctx.Args().Len() != 2 { - return fmt.Errorf("must pass multisig address and message ID") + if cctx.Args().Len() < 5 { + return fmt.Errorf("must pass multisig address, message ID, proposer address, destination, and value") + } + + if cctx.Args().Len() > 5 && cctx.Args().Len() != 7 { + return fmt.Errorf("usage: msig approve [ ]") } msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -433,9 +443,63 @@ var msigApproveCmd = &cli.Command{ return err } + proposer, err := address.NewFromString(cctx.Args().Get(2)) + if err != nil { + return err + } + + if proposer.Protocol() != address.ID { + proposer, err = api.StateLookupID(ctx, proposer, types.EmptyTSK) + if err != nil { + return err + } + } + + dest, err := address.NewFromString(cctx.Args().Get(3)) + if err != nil { + return err + } + + value, err := types.ParseFIL(cctx.Args().Get(4)) + if err != nil { + return err + } + + var method uint64 + var params []byte + if cctx.Args().Len() == 7 { + m, err := strconv.ParseUint(cctx.Args().Get(5), 10, 64) + if err != nil { + return err + } + method = m + + p, err := hex.DecodeString(cctx.Args().Get(6)) + if err != nil { + return err + } + params = p + } + + p := samsig.ProposalHashData{ + Requester: proposer, + To: dest, + Value: types.BigInt(value), + Method: abi.MethodNum(method), + Params: params, + } + + pser, err := p.Serialize() + if err != nil { + return err + } + phash := blake2b.Sum256(pser) + enc, err := actors.SerializeParams(&samsig.TxnIDParams{ - ID: samsig.TxnID(txid), + ID: samsig.TxnID(txid), + ProposalHash: phash[:], }) + if err != nil { return err }