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 }