diff --git a/api/api.go b/api/api.go index 083c47b54..1dff49e13 100644 --- a/api/api.go +++ b/api/api.go @@ -54,6 +54,7 @@ type FullNode interface { ChainSubmitBlock(ctx context.Context, blk *types.BlockMsg) error // TODO: check serialization ChainGetRandomness(context.Context, *types.TipSet, []*types.Ticket, int) ([]byte, error) ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error) + ChainGetTipSet(context.Context, []cid.Cid) (*types.TipSet, error) ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error) ChainGetParentReceipts(context.Context, cid.Cid) ([]*types.MessageReceipt, error) ChainGetParentMessages(context.Context, cid.Cid) ([]Message, error) diff --git a/api/struct.go b/api/struct.go index bc83eea54..1a6068dc4 100644 --- a/api/struct.go +++ b/api/struct.go @@ -42,6 +42,7 @@ type FullNodeStruct struct { ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"` ChainGetRandomness func(context.Context, *types.TipSet, []*types.Ticket, int) ([]byte, error) `perm:"read"` ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"` + ChainGetTipSet func(context.Context, []cid.Cid) (*types.TipSet, error) `perm:"read"` ChainGetBlockMessages func(context.Context, cid.Cid) (*BlockMessages, error) `perm:"read"` ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` ChainGetParentMessages func(context.Context, cid.Cid) ([]Message, error) `perm:"read"` @@ -285,6 +286,10 @@ func (c *FullNodeStruct) ChainGetBlock(ctx context.Context, b cid.Cid) (*types.B return c.Internal.ChainGetBlock(ctx, b) } +func (c *FullNodeStruct) ChainGetTipSet(ctx context.Context, cids []cid.Cid) (*types.TipSet, error) { + return c.Internal.ChainGetTipSet(ctx, cids) +} + func (c *FullNodeStruct) ChainGetBlockMessages(ctx context.Context, b cid.Cid) (*BlockMessages, error) { return c.Internal.ChainGetBlockMessages(ctx, b) } diff --git a/cli/chain.go b/cli/chain.go index 521350000..e16fadef7 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -22,6 +22,7 @@ var chainCmd = &cli.Command{ chainReadObjCmd, chainGetMsgCmd, chainSetHeadCmd, + chainListCmd, }, } @@ -271,3 +272,46 @@ func parseTipSet(api api.FullNode, ctx context.Context, vals []string) (*types.T return types.NewTipSet(headers) } + +var chainListCmd = &cli.Command{ + Name: "list", + Usage: "View a segment of the chain", + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + head, err := api.ChainHead(ctx) + if err != nil { + return err + } + + tss := []*types.TipSet{head} + cur := head + for i := 1; i < 30; i++ { + if cur.Height() == 0 { + break + } + + next, err := api.ChainGetTipSet(ctx, cur.Parents()) + if err != nil { + return err + } + + tss = append(tss, next) + cur = next + } + + for i := len(tss) - 1; i >= 0; i-- { + fmt.Printf("%d [ ", tss[i].Height()) + for _, b := range tss[i].Blocks() { + fmt.Printf("%s: %s,", b.Cid(), b.Miner) + } + fmt.Println("]") + } + return nil + }, +} diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index 91780af6a..748cb3ad6 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -50,6 +50,10 @@ func (a *ChainAPI) ChainGetBlock(ctx context.Context, msg cid.Cid) (*types.Block return a.Chain.GetBlock(msg) } +func (a *ChainAPI) ChainGetTipSet(ctx context.Context, cids []cid.Cid) (*types.TipSet, error) { + return a.Chain.LoadTipSet(cids) +} + func (a *ChainAPI) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) (*api.BlockMessages, error) { b, err := a.Chain.GetBlock(msg) if err != nil {