shed: Commad to decode messages
This commit is contained in:
parent
c81db5a21c
commit
067de4508b
@ -1291,7 +1291,7 @@ var chainDecodeParamsCmd = &cli.Command{
|
|||||||
return xerrors.Errorf("getting actor: %w", err)
|
return xerrors.Errorf("getting actor: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pstr, err := jsonParams(act.Code, abi.MethodNum(method), params)
|
pstr, err := JsonParams(act.Code, abi.MethodNum(method), params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1211,7 +1211,7 @@ func ComputeStateHTMLTempl(w io.Writer, ts *types.TipSet, o *api.ComputeStateOut
|
|||||||
"GetCode": getCode,
|
"GetCode": getCode,
|
||||||
"GetMethod": getMethod,
|
"GetMethod": getMethod,
|
||||||
"ToFil": toFil,
|
"ToFil": toFil,
|
||||||
"JsonParams": jsonParams,
|
"JsonParams": JsonParams,
|
||||||
"JsonReturn": jsonReturn,
|
"JsonReturn": jsonReturn,
|
||||||
"IsSlow": isSlow,
|
"IsSlow": isSlow,
|
||||||
"IsVerySlow": isVerySlow,
|
"IsVerySlow": isVerySlow,
|
||||||
@ -1298,7 +1298,7 @@ func sumGas(changes []*types.GasTrace) types.GasTrace {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonParams(code cid.Cid, method abi.MethodNum, params []byte) (string, error) {
|
func JsonParams(code cid.Cid, method abi.MethodNum, params []byte) (string, error) {
|
||||||
methodMeta, found := stmgr.MethodsMap[code][method]
|
methodMeta, found := stmgr.MethodsMap[code][method]
|
||||||
if !found {
|
if !found {
|
||||||
return "", fmt.Errorf("method %d not found on actor %s", method, code)
|
return "", fmt.Errorf("method %d not found on actor %s", method, code)
|
||||||
|
@ -45,6 +45,7 @@ func main() {
|
|||||||
datastoreCmd,
|
datastoreCmd,
|
||||||
ledgerCmd,
|
ledgerCmd,
|
||||||
sectorsCmd,
|
sectorsCmd,
|
||||||
|
msgCmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
app := &cli.App{
|
app := &cli.App{
|
||||||
|
280
cmd/lotus-shed/msg.go
Normal file
280
cmd/lotus-shed/msg.go
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
|
"github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
||||||
|
)
|
||||||
|
|
||||||
|
var msgCmd = &cli.Command{
|
||||||
|
Name: "msg",
|
||||||
|
Usage: "Translate message between various formats",
|
||||||
|
ArgsUsage: "Message in any form",
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() != 1 {
|
||||||
|
return xerrors.Errorf("expected 1 argument")
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := messageFromString(cctx, cctx.Args().First())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case *types.SignedMessage:
|
||||||
|
return printSignedMessage(cctx, msg)
|
||||||
|
case *types.Message:
|
||||||
|
return printMessage(cctx, msg)
|
||||||
|
default:
|
||||||
|
return xerrors.Errorf("this error message can't be printed")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func printSignedMessage(cctx *cli.Context, smsg *types.SignedMessage) error {
|
||||||
|
color.Green("Signed:")
|
||||||
|
color.Blue("CID: %s\n", smsg.Cid())
|
||||||
|
|
||||||
|
b, err := smsg.Serialize()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
color.Magenta("HEX: %x\n", b)
|
||||||
|
color.Blue("B64: %s\n", base64.StdEncoding.EncodeToString(b))
|
||||||
|
jm, err := json.MarshalIndent(smsg, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("marshaling as json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
color.Magenta("JSON: %s\n", string(jm))
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("---")
|
||||||
|
color.Green("Signed Message Details:")
|
||||||
|
fmt.Printf("Signature(hex): %x\n", smsg.Signature.Data)
|
||||||
|
fmt.Printf("Signature(b64): %s\n", base64.StdEncoding.EncodeToString(smsg.Signature.Data))
|
||||||
|
|
||||||
|
sigtype, err := smsg.Signature.Type.Name()
|
||||||
|
if err != nil {
|
||||||
|
sigtype = err.Error()
|
||||||
|
}
|
||||||
|
fmt.Printf("Signature type: %d (%s)\n", smsg.Signature.Type, sigtype)
|
||||||
|
|
||||||
|
fmt.Println("-------")
|
||||||
|
return printMessage(cctx, &smsg.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
func printMessage(cctx *cli.Context, msg *types.Message) error {
|
||||||
|
if msg.Version != 0x6d736967 {
|
||||||
|
color.Green("Unsigned:")
|
||||||
|
color.Yellow("CID: %s\n", msg.Cid())
|
||||||
|
|
||||||
|
b, err := msg.Serialize()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
color.Cyan("HEX: %x\n", b)
|
||||||
|
color.Yellow("B64: %s\n", base64.StdEncoding.EncodeToString(b))
|
||||||
|
|
||||||
|
jm, err := json.MarshalIndent(msg, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("marshaling as json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
color.Cyan("JSON: %s\n", string(jm))
|
||||||
|
fmt.Println()
|
||||||
|
} else {
|
||||||
|
color.Green("Msig Propose:")
|
||||||
|
pp := &multisig.ProposeParams{
|
||||||
|
To: msg.To,
|
||||||
|
Value: msg.Value,
|
||||||
|
Method: msg.Method,
|
||||||
|
Params: msg.Params,
|
||||||
|
}
|
||||||
|
var b bytes.Buffer
|
||||||
|
if err := pp.MarshalCBOR(&b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
color.Cyan("HEX: %x\n", b.Bytes())
|
||||||
|
color.Yellow("B64: %s\n", base64.StdEncoding.EncodeToString(b.Bytes()))
|
||||||
|
jm, err := json.MarshalIndent(pp, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("marshaling as json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
color.Cyan("JSON: %s\n", string(jm))
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("---")
|
||||||
|
color.Green("Message Details:")
|
||||||
|
fmt.Println("Value:", types.FIL(msg.Value))
|
||||||
|
fmt.Println("Max Fees:", types.FIL(msg.RequiredFunds()))
|
||||||
|
fmt.Println("Max Total Cost:", types.FIL(big.Add(msg.RequiredFunds(), msg.Value)))
|
||||||
|
|
||||||
|
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer closer()
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
|
toact, err := api.StateGetActor(ctx, msg.To, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Method:", stmgr.MethodsMap[toact.Code][msg.Method].Name)
|
||||||
|
p, err := lcli.JsonParams(toact.Code, msg.Method, msg.Params)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Params:", p)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func messageFromString(cctx *cli.Context, smsg string) (types.ChainMsg, error) {
|
||||||
|
// a CID is least likely to just decode
|
||||||
|
if c, err := cid.Parse(smsg); err == nil {
|
||||||
|
return messageFromCID(cctx, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// try baseX serializations next
|
||||||
|
{
|
||||||
|
// hex first, some hay strings may be decodable as b64
|
||||||
|
if b, err := hex.DecodeString(smsg); err == nil {
|
||||||
|
return messageFromBytes(cctx, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// b64 next
|
||||||
|
if b, err := base64.StdEncoding.DecodeString(smsg); err == nil {
|
||||||
|
return messageFromBytes(cctx, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// b64u??
|
||||||
|
if b, err := base64.URLEncoding.DecodeString(smsg); err == nil {
|
||||||
|
return messageFromBytes(cctx, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// maybe it's json?
|
||||||
|
if _, err := messageFromJson(cctx, []byte(smsg)); err == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// declare defeat
|
||||||
|
return nil, xerrors.Errorf("couldn't decode the message")
|
||||||
|
}
|
||||||
|
|
||||||
|
func messageFromJson(cctx *cli.Context, msgb []byte) (types.ChainMsg, error) {
|
||||||
|
// Unsigned
|
||||||
|
{
|
||||||
|
var msg types.Message
|
||||||
|
if err := json.Unmarshal(msgb, &msg); err == nil {
|
||||||
|
if msg.To != address.Undef {
|
||||||
|
return &msg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signed
|
||||||
|
{
|
||||||
|
var msg types.SignedMessage
|
||||||
|
if err := json.Unmarshal(msgb, &msg); err == nil {
|
||||||
|
if msg.Message.To != address.Undef {
|
||||||
|
return &msg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, xerrors.New("probably not a json-serialized message")
|
||||||
|
}
|
||||||
|
|
||||||
|
func messageFromBytes(cctx *cli.Context, msgb []byte) (types.ChainMsg, error) {
|
||||||
|
// Signed
|
||||||
|
{
|
||||||
|
var msg types.SignedMessage
|
||||||
|
if err := msg.UnmarshalCBOR(bytes.NewReader(msgb)); err == nil {
|
||||||
|
return &msg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unsigned
|
||||||
|
{
|
||||||
|
var msg types.Message
|
||||||
|
if err := msg.UnmarshalCBOR(bytes.NewReader(msgb)); err == nil {
|
||||||
|
return &msg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multisig propose?
|
||||||
|
{
|
||||||
|
var pp multisig.ProposeParams
|
||||||
|
if err := pp.UnmarshalCBOR(bytes.NewReader(msgb)); err == nil {
|
||||||
|
i, err := address.NewIDAddress(0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
// Hack(-ish)
|
||||||
|
Version: 0x6d736967,
|
||||||
|
From: i,
|
||||||
|
|
||||||
|
To: pp.To,
|
||||||
|
Value: pp.Value,
|
||||||
|
|
||||||
|
Method: pp.Method,
|
||||||
|
Params: pp.Params,
|
||||||
|
|
||||||
|
GasFeeCap: big.Zero(),
|
||||||
|
GasPremium: big.Zero(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encoded json???
|
||||||
|
{
|
||||||
|
if msg, err := messageFromJson(cctx, msgb); err == nil {
|
||||||
|
return msg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, xerrors.New("probably not a cbor-serialized message")
|
||||||
|
}
|
||||||
|
|
||||||
|
func messageFromCID(cctx *cli.Context, c cid.Cid) (types.ChainMsg, error) {
|
||||||
|
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer closer()
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
|
msgb, err := api.ChainReadObj(ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return messageFromBytes(cctx, msgb)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user