From 5fb59c06bdf4fdb14fe4662bcd5f249446a3f0d7 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Mon, 22 Jul 2019 17:54:27 -0700 Subject: [PATCH] add a getblock command --- api/api.go | 2 ++ api/struct.go | 18 ++++++++--- chain/address/address.go | 11 ++++--- cli/chain.go | 69 ++++++++++++++++++++++++++++++++++++++++ go.mod | 1 + node/api.go | 13 ++++++++ 6 files changed, 106 insertions(+), 8 deletions(-) diff --git a/api/api.go b/api/api.go index d2c2ad424..7c676c066 100644 --- a/api/api.go +++ b/api/api.go @@ -39,6 +39,8 @@ type API interface { ChainSubmitBlock(ctx context.Context, blk *chain.BlockMsg) error // TODO: check serialization ChainGetRandomness(context.Context, *chain.TipSet) ([]byte, error) ChainWaitMsg(context.Context, cid.Cid) (*MsgWait, error) + ChainGetBlock(context.Context, cid.Cid) (*chain.BlockHeader, error) + ChainGetBlockMessages(context.Context, cid.Cid) ([]*chain.SignedMessage, error) // messages diff --git a/api/struct.go b/api/struct.go index 7783bcabc..6a47be1f0 100644 --- a/api/struct.go +++ b/api/struct.go @@ -17,10 +17,12 @@ type Struct struct { ID func(context.Context) (peer.ID, error) Version func(context.Context) (Version, error) - ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error - ChainHead func(context.Context) (*chain.TipSet, error) - ChainGetRandomness func(context.Context, *chain.TipSet) ([]byte, error) - ChainWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) + ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error + ChainHead func(context.Context) (*chain.TipSet, error) + ChainGetRandomness func(context.Context, *chain.TipSet) ([]byte, error) + ChainWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) + ChainGetBlock func(context.Context, cid.Cid) (*chain.BlockHeader, error) + ChainGetBlockMessages func(context.Context, cid.Cid) ([]*chain.SignedMessage, error) MpoolPending func(context.Context, *chain.TipSet) ([]*chain.SignedMessage, error) MpoolPush func(context.Context, *chain.SignedMessage) error @@ -130,4 +132,12 @@ func (c *Struct) MpoolGetNonce(ctx context.Context, addr address.Address) (uint6 return c.Internal.MpoolGetNonce(ctx, addr) } +func (c *Struct) ChainGetBlock(ctx context.Context, b cid.Cid) (*chain.BlockHeader, error) { + return c.Internal.ChainGetBlock(ctx, b) +} + +func (c *Struct) ChainGetBlockMessages(ctx context.Context, b cid.Cid) ([]*chain.SignedMessage, error) { + return c.Internal.ChainGetBlockMessages(ctx, b) +} + var _ API = &Struct{} diff --git a/chain/address/address.go b/chain/address/address.go index 677abcc6a..362477148 100644 --- a/chain/address/address.go +++ b/chain/address/address.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "strconv" - "strings" "github.com/filecoin-project/go-bls-sigs" "github.com/filecoin-project/go-leb128" @@ -106,8 +105,12 @@ func (a Address) Marshal() ([]byte, error) { // UnmarshalJSON implements the json unmarshal interface. func (a *Address) UnmarshalJSON(b []byte) error { - in := strings.TrimSuffix(strings.TrimPrefix(string(b), `"`), `"`) - addr, err := decode(in) + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + + addr, err := decode(s) if err != nil { return err } @@ -117,7 +120,7 @@ func (a *Address) UnmarshalJSON(b []byte) error { // MarshalJSON implements the json marshal interface. func (a Address) MarshalJSON() ([]byte, error) { - return json.Marshal(a.String()) + return []byte(`"` + a.String() + `"`), nil } // Format implements the Formatter interface. diff --git a/cli/chain.go b/cli/chain.go index ce1fed1a6..c310cdd4f 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -1,9 +1,13 @@ package cli import ( + "encoding/json" "fmt" "gopkg.in/urfave/cli.v2" + + "github.com/filecoin-project/go-lotus/chain" + cid "github.com/ipfs/go-cid" ) var chainCmd = &cli.Command{ @@ -11,6 +15,7 @@ var chainCmd = &cli.Command{ Usage: "Interact with filecoin blockchain", Subcommands: []*cli.Command{ chainHeadCmd, + chainGetBlock, }, } @@ -35,3 +40,67 @@ var chainHeadCmd = &cli.Command{ return nil }, } + +var chainGetBlock = &cli.Command{ + Name: "getblock", + Usage: "Get a block and print its details", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "raw", + Usage: "print just the raw block header", + }, + }, + Action: func(cctx *cli.Context) error { + api, err := getAPI(cctx) + if err != nil { + return err + } + ctx := reqContext(cctx) + + if !cctx.Args().Present() { + return fmt.Errorf("must pass cid of block to print") + } + + bcid, err := cid.Decode(cctx.Args().First()) + if err != nil { + return err + } + + blk, err := api.ChainGetBlock(ctx, bcid) + if err != nil { + return err + } + + if cctx.Bool("raw") { + out, err := json.MarshalIndent(blk, "", " ") + if err != nil { + return err + } + + fmt.Println(string(out)) + return nil + } + + msgs, err := api.ChainGetBlockMessages(ctx, bcid) + if err != nil { + return err + } + + cblock := struct { + chain.BlockHeader + Messages []*chain.SignedMessage + }{} + + cblock.BlockHeader = *blk + cblock.Messages = msgs + + out, err := json.MarshalIndent(cblock, "", " ") + if err != nil { + return err + } + + fmt.Println(string(out)) + return nil + + }, +} diff --git a/go.mod b/go.mod index 052eacd27..bbdb89d66 100644 --- a/go.mod +++ b/go.mod @@ -67,6 +67,7 @@ require ( go4.org v0.0.0-20190313082347-94abd6928b1d // indirect golang.org/x/sync v0.0.0-20190423024810-112230192c58 // indirect golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 + google.golang.org/appengine v1.4.0 // indirect gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect ) diff --git a/node/api.go b/node/api.go index ee0954ee6..810bb9924 100644 --- a/node/api.go +++ b/node/api.go @@ -55,6 +55,19 @@ func (a *API) ChainWaitMsg(ctx context.Context, msg cid.Cid) (*api.MsgWait, erro panic("TODO") } +func (a *API) ChainGetBlock(ctx context.Context, msg cid.Cid) (*chain.BlockHeader, error) { + return a.Chain.GetBlock(msg) +} + +func (a *API) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) ([]*chain.SignedMessage, error) { + b, err := a.Chain.GetBlock(msg) + if err != nil { + return nil, err + } + + return a.Chain.MessagesForBlock(b) +} + func (a *API) ID(context.Context) (peer.ID, error) { return a.Host.ID(), nil }