diff --git a/chain/types/mock/chain.go b/chain/types/mock/chain.go index e4bb2fcee..c69f7f56f 100644 --- a/chain/types/mock/chain.go +++ b/chain/types/mock/chain.go @@ -2,6 +2,7 @@ package mock import ( "context" + "crypto/rand" "fmt" "github.com/filecoin-project/go-address" @@ -24,15 +25,7 @@ func Address(i uint64) address.Address { } func MkMessage(from, to address.Address, nonce uint64, w *wallet.LocalWallet) *types.SignedMessage { - msg := &types.Message{ - To: to, - From: from, - Value: types.NewInt(1), - Nonce: nonce, - GasLimit: 1000000, - GasFeeCap: types.NewInt(100), - GasPremium: types.NewInt(1), - } + msg := UnsignedMessage(from, to, nonce) sig, err := w.WalletSign(context.TODO(), from, msg.Cid().Bytes(), api.MsgMeta{}) if err != nil { @@ -96,3 +89,30 @@ func TipSet(blks ...*types.BlockHeader) *types.TipSet { } return ts } + +func RandomActorAddress() (*address.Address, error) { + bytes := make([]byte, 32) + _, err := rand.Read(bytes) + if err != nil { + return nil, err + } + + addr, err := address.NewActorAddress(bytes) + if err != nil { + return nil, err + } + + return &addr, nil +} + +func UnsignedMessage(from, to address.Address, nonce uint64) *types.Message { + return &types.Message{ + To: to, + From: from, + Value: types.NewInt(1), + Nonce: nonce, + GasLimit: 1000000, + GasFeeCap: types.NewInt(100), + GasPremium: types.NewInt(1), + } +} diff --git a/cli/chain.go b/cli/chain.go index 10fa9900f..d3259c6c8 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -301,6 +301,8 @@ var ChainGetMsgCmd = &cli.Command{ Usage: "Get and print a message by its cid", ArgsUsage: "[messageCid]", Action: func(cctx *cli.Context) error { + afmt := NewAppFmt(cctx.App) + if !cctx.Args().Present() { return fmt.Errorf("must pass a cid of a message to get") } @@ -339,7 +341,7 @@ var ChainGetMsgCmd = &cli.Command{ return err } - fmt.Println(string(enc)) + afmt.Println(string(enc)) return nil }, } diff --git a/cli/chain_test.go b/cli/chain_test.go index fd43644d1..064393f3a 100644 --- a/cli/chain_test.go +++ b/cli/chain_test.go @@ -150,6 +150,7 @@ func TestChainDeleteObj(t *testing.T) { }) } +// TestChainStatObj checks if "chain delete-obj" prints size and IPLD link counts for object, respecting the --base flag func TestChainStatObj(t *testing.T) { cmd := WithCategory("chain", ChainStatObjCmd) block := mock.MkBlock(nil, 0, 0) @@ -199,3 +200,37 @@ func TestChainStatObj(t *testing.T) { checkOutput(buf) }) } + +// TestChainGetMsg checks if "chain getmessage" properly decodes and serializes as JSON a Message fetched from the IPLD store +func TestChainGetMsg(t *testing.T) { + app, mockApi, buf, done := newMockAppWithFullAPI(t, WithCategory("chain", ChainGetMsgCmd)) + defer done() + + from, err := mock.RandomActorAddress() + assert.NoError(t, err) + + to, err := mock.RandomActorAddress() + assert.NoError(t, err) + + msg := mock.UnsignedMessage(*from, *to, 0) + + obj := new(bytes.Buffer) + err = msg.MarshalCBOR(obj) + assert.NoError(t, err) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + gomock.InOrder( + mockApi.EXPECT().ChainReadObj(ctx, msg.Cid()).Return(obj.Bytes(), nil), + ) + + err = app.Run([]string{"chain", "getmessage", msg.Cid().String()}) + assert.NoError(t, err) + + var out types.Message + err = json.Unmarshal(buf.Bytes(), &out) + assert.NoError(t, err) + + assert.Equal(t, *msg, out) +}