Merge pull request #2541 from filecoin-project/feat/better-send

implement method and parameter specification for send
This commit is contained in:
Łukasz Magiera 2020-07-23 10:14:19 +02:00 committed by GitHub
commit c2b7e983bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,11 +1,20 @@
package cli
import (
"bytes"
"context"
"encoding/hex"
"encoding/json"
"fmt"
"reflect"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/urfave/cli/v2"
cbg "github.com/whyrusleeping/cbor-gen"
)
var sendCmd = &cli.Command{
@ -27,6 +36,19 @@ var sendCmd = &cli.Command{
Usage: "specify the nonce to use",
Value: -1,
},
&cli.Uint64Flag{
Name: "method",
Usage: "specify method to invoke",
Value: 0,
},
&cli.StringFlag{
Name: "params-json",
Usage: "specify invocation parameters in json",
},
&cli.StringFlag{
Name: "params-hex",
Usage: "specify invocation parameters in hex",
},
},
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
@ -73,11 +95,34 @@ var sendCmd = &cli.Command{
return err
}
method := abi.MethodNum(cctx.Uint64("method"))
var params []byte
if cctx.IsSet("params-json") {
decparams, err := decodeTypedParams(ctx, api, toAddr, method, cctx.String("params-json"))
if err != nil {
return fmt.Errorf("failed to decode json params: %w", err)
}
params = decparams
}
if cctx.IsSet("params-hex") {
if params != nil {
return fmt.Errorf("can only specify one of 'params-json' and 'params-hex'")
}
decparams, err := hex.DecodeString(cctx.String("params-hex"))
if err != nil {
return fmt.Errorf("failed to decode hex params: %w", err)
}
params = decparams
}
msg := &types.Message{
From: fromAddr,
To: toAddr,
Value: types.BigInt(val),
GasPrice: gp,
Method: method,
Params: params,
}
if cctx.Int64("nonce") > 0 {
@ -103,3 +148,22 @@ var sendCmd = &cli.Command{
return nil
},
}
func decodeTypedParams(ctx context.Context, fapi api.FullNode, to address.Address, method abi.MethodNum, paramstr string) ([]byte, error) {
act, err := fapi.StateGetActor(ctx, to, types.EmptyTSK)
if err != nil {
return nil, err
}
p := reflect.New(stmgr.MethodsMap[act.Code][method].Params.Elem()).Interface().(cbg.CBORMarshaler)
if err := json.Unmarshal([]byte(paramstr), p); err != nil {
return nil, fmt.Errorf("unmarshaling input into params type: %w", err)
}
buf := new(bytes.Buffer)
if err := p.MarshalCBOR(buf); err != nil {
return nil, err
}
return buf.Bytes(), nil
}