github.com/turingchain2020/turingchain@v1.1.21/system/dapp/commands/block.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package commands
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"strconv"
    11  	"strings"
    12  
    13  	"github.com/turingchain2020/turingchain/blockchain"
    14  	"github.com/turingchain2020/turingchain/rpc/jsonclient"
    15  	rpctypes "github.com/turingchain2020/turingchain/rpc/types"
    16  	commandtypes "github.com/turingchain2020/turingchain/system/dapp/commands/types"
    17  	"github.com/turingchain2020/turingchain/types"
    18  	"github.com/spf13/cobra"
    19  )
    20  
    21  // BlockCmd block command
    22  func BlockCmd() *cobra.Command {
    23  	cmd := &cobra.Command{
    24  		Use:   "block",
    25  		Short: "Get block header or body info",
    26  		Args:  cobra.MinimumNArgs(1),
    27  	}
    28  
    29  	cmd.AddCommand(
    30  		GetBlocksCmd(),
    31  		GetBlockHashCmd(),
    32  		GetBlockOverviewCmd(),
    33  		GetHeadersCmd(),
    34  		GetLastHeaderCmd(),
    35  
    36  		GetBlockByHashsCmd(),
    37  		GetBlockSequencesCmd(),
    38  		GetLastBlockSequenceCmd(),
    39  		AddPushSubscribeCmd(),
    40  		ListPushesCmd(),
    41  		GetPushSeqLastNumCmd(),
    42  	)
    43  
    44  	return cmd
    45  }
    46  
    47  // GetBlocksCmd get blocks between start and end
    48  func GetBlocksCmd() *cobra.Command {
    49  	cmd := &cobra.Command{
    50  		Use:   "get",
    51  		Short: "Get blocks between [start, end]",
    52  		Run:   blockBodyCmd,
    53  	}
    54  	addBlockBodyCmdFlags(cmd)
    55  	return cmd
    56  }
    57  
    58  func addBlockBodyCmdFlags(cmd *cobra.Command) {
    59  	cmd.Flags().Int64P("start", "s", 0, "block start height")
    60  	cmd.MarkFlagRequired("start")
    61  
    62  	cmd.Flags().Int64P("end", "e", 0, "block end height")
    63  	cmd.MarkFlagRequired("end")
    64  
    65  	cmd.Flags().StringP("detail", "d", "f", "whether print block detail info (0/f/false for No; 1/t/true for Yes)")
    66  }
    67  
    68  func blockBodyCmd(cmd *cobra.Command, args []string) {
    69  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
    70  	startH, _ := cmd.Flags().GetInt64("start")
    71  	endH, _ := cmd.Flags().GetInt64("end")
    72  	isDetail, _ := cmd.Flags().GetString("detail")
    73  	detailBool, err := strconv.ParseBool(isDetail)
    74  	if err != nil {
    75  		fmt.Fprintln(os.Stderr, err)
    76  		return
    77  	}
    78  	params := rpctypes.BlockParam{
    79  		Start:    startH,
    80  		End:      endH,
    81  		Isdetail: detailBool,
    82  	}
    83  	var res rpctypes.BlockDetails
    84  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetBlocks", params, &res)
    85  	ctx.SetResultCb(parseBlockDetail)
    86  	ctx.Run()
    87  }
    88  
    89  func parseBlockDetail(res interface{}) (interface{}, error) {
    90  	var result commandtypes.BlockDetailsResult
    91  	for _, vItem := range res.(*rpctypes.BlockDetails).Items {
    92  		b := &commandtypes.BlockResult{
    93  			Version:    vItem.Block.Version,
    94  			ParentHash: vItem.Block.ParentHash,
    95  			TxHash:     vItem.Block.TxHash,
    96  			StateHash:  vItem.Block.StateHash,
    97  			Height:     vItem.Block.Height,
    98  			BlockTime:  vItem.Block.BlockTime,
    99  		}
   100  		for _, vTx := range vItem.Block.Txs {
   101  			b.Txs = append(b.Txs, commandtypes.DecodeTransaction(vTx))
   102  		}
   103  		bd := &commandtypes.BlockDetailResult{Block: b, Receipts: vItem.Receipts}
   104  		result.Items = append(result.Items, bd)
   105  	}
   106  	return result, nil
   107  }
   108  
   109  // GetBlockHashCmd get hash of a block
   110  func GetBlockHashCmd() *cobra.Command {
   111  	cmd := &cobra.Command{
   112  		Use:   "hash",
   113  		Short: "Get hash of block at height",
   114  		Run:   blockHeightHash,
   115  	}
   116  	addBlockHashFlags(cmd)
   117  	return cmd
   118  }
   119  
   120  func addBlockHashFlags(cmd *cobra.Command) {
   121  	cmd.Flags().Int64P("height", "t", 0, "block height")
   122  	cmd.MarkFlagRequired("height")
   123  }
   124  
   125  func blockHeightHash(cmd *cobra.Command, args []string) {
   126  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   127  	height, _ := cmd.Flags().GetInt64("height")
   128  	params := types.ReqInt{
   129  		Height: height,
   130  	}
   131  	var res rpctypes.ReplyHash
   132  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetBlockHash", params, &res)
   133  	ctx.Run()
   134  }
   135  
   136  // GetBlockOverviewCmd get overview of a block
   137  func GetBlockOverviewCmd() *cobra.Command {
   138  	cmd := &cobra.Command{
   139  		Use:   "view",
   140  		Short: "View block info by block hash",
   141  		Run:   blockViewByHash,
   142  	}
   143  	addBlockViewFlags(cmd)
   144  	return cmd
   145  }
   146  
   147  func addBlockViewFlags(cmd *cobra.Command) {
   148  	cmd.Flags().StringP("hash", "s", "", "block hash at height")
   149  	cmd.MarkFlagRequired("hash")
   150  }
   151  
   152  func blockViewByHash(cmd *cobra.Command, args []string) {
   153  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   154  	blockHash, _ := cmd.Flags().GetString("hash")
   155  	params := rpctypes.QueryParm{
   156  		Hash: blockHash,
   157  	}
   158  	var res rpctypes.BlockOverview
   159  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetBlockOverview", params, &res)
   160  	ctx.Run()
   161  }
   162  
   163  // GetHeadersCmd get block headers between start and end
   164  func GetHeadersCmd() *cobra.Command {
   165  	cmd := &cobra.Command{
   166  		Use:   "headers",
   167  		Short: "Get block headers between [start, end]",
   168  		Run:   blockHeader,
   169  	}
   170  	addBlockHeaderFlags(cmd)
   171  	return cmd
   172  }
   173  
   174  func addBlockHeaderFlags(cmd *cobra.Command) {
   175  	cmd.Flags().Int64P("start", "s", 0, "block start height")
   176  	cmd.MarkFlagRequired("start")
   177  
   178  	cmd.Flags().Int64P("end", "e", 0, "block end height")
   179  	cmd.MarkFlagRequired("end")
   180  
   181  	cmd.Flags().StringP("detail", "d", "f", "whether print header detail info (0/f/false for No; 1/t/true for Yes)")
   182  }
   183  
   184  func blockHeader(cmd *cobra.Command, args []string) {
   185  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   186  	startH, _ := cmd.Flags().GetInt64("start")
   187  	endH, _ := cmd.Flags().GetInt64("end")
   188  	isDetail, _ := cmd.Flags().GetString("detail")
   189  	detailBool, err := strconv.ParseBool(isDetail)
   190  	if err != nil {
   191  		fmt.Fprintln(os.Stderr, err)
   192  		return
   193  	}
   194  	params := types.ReqBlocks{
   195  		Start:    startH,
   196  		End:      endH,
   197  		IsDetail: detailBool,
   198  	}
   199  	var res rpctypes.Headers
   200  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetHeaders", params, &res)
   201  	ctx.Run()
   202  }
   203  
   204  // GetLastHeaderCmd get information of latest header
   205  func GetLastHeaderCmd() *cobra.Command {
   206  	cmd := &cobra.Command{
   207  		Use:   "last_header",
   208  		Short: "View last block header",
   209  		Run:   lastHeader,
   210  	}
   211  	return cmd
   212  }
   213  
   214  func lastHeader(cmd *cobra.Command, args []string) {
   215  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   216  	var res rpctypes.Header
   217  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetLastHeader", nil, &res)
   218  	ctx.Run()
   219  }
   220  
   221  // GetLastBlockSequenceCmd get latest Sequence
   222  func GetLastBlockSequenceCmd() *cobra.Command {
   223  	cmd := &cobra.Command{
   224  		Use:   "last_sequence",
   225  		Short: "View last block sequence",
   226  		Run:   lastSequence,
   227  	}
   228  	return cmd
   229  }
   230  
   231  func lastSequence(cmd *cobra.Command, args []string) {
   232  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   233  	var res int64
   234  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetLastBlockSequence", nil, &res)
   235  	ctx.Run()
   236  }
   237  
   238  // GetBlockSequencesCmd  get block Sequences
   239  func GetBlockSequencesCmd() *cobra.Command {
   240  	cmd := &cobra.Command{
   241  		Use:   "sequences",
   242  		Short: "Get block sequences between [start, end]",
   243  		Run:   getsequences,
   244  	}
   245  	blockSequencesCmdFlags(cmd)
   246  	return cmd
   247  }
   248  
   249  func getsequences(cmd *cobra.Command, args []string) {
   250  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   251  	startH, _ := cmd.Flags().GetInt64("start")
   252  	endH, _ := cmd.Flags().GetInt64("end")
   253  
   254  	params := rpctypes.BlockParam{
   255  		Start:    startH,
   256  		End:      endH,
   257  		Isdetail: false,
   258  	}
   259  	var res rpctypes.ReplyBlkSeqs
   260  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetBlockSequences", params, &res)
   261  	//ctx.SetResultCb(parseBlockDetail)
   262  	ctx.Run()
   263  }
   264  
   265  func blockSequencesCmdFlags(cmd *cobra.Command) {
   266  	cmd.Flags().Int64P("start", "s", 0, "block start sequence")
   267  	cmd.MarkFlagRequired("start")
   268  
   269  	cmd.Flags().Int64P("end", "e", 0, "block end sequence")
   270  	cmd.MarkFlagRequired("end")
   271  }
   272  
   273  // GetBlockByHashsCmd get Block Details By block Hashs
   274  func GetBlockByHashsCmd() *cobra.Command {
   275  	cmd := &cobra.Command{
   276  		Use:   "query_hashs",
   277  		Short: "Query block by hashs",
   278  		Run:   getblockbyhashs,
   279  	}
   280  	addBlockByHashsFlags(cmd)
   281  	return cmd
   282  }
   283  
   284  func addBlockByHashsFlags(cmd *cobra.Command) {
   285  	cmd.Flags().StringP("hashes", "s", "", "block hash(es), separated by space")
   286  	cmd.MarkFlagRequired("hashes")
   287  }
   288  
   289  func getblockbyhashs(cmd *cobra.Command, args []string) {
   290  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   291  	hashes, _ := cmd.Flags().GetString("hashes")
   292  	hashesArr := strings.Fields(hashes)
   293  
   294  	params := rpctypes.ReqHashes{
   295  		Hashes: hashesArr,
   296  	}
   297  
   298  	var res rpctypes.BlockDetails
   299  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetBlockByHashes", params, &res)
   300  	//ctx.SetResultCb(parseQueryTxsByHashesRes)
   301  	ctx.Run()
   302  }
   303  
   304  // AddPushSubscribeCmd add block sequence call back
   305  func AddPushSubscribeCmd() *cobra.Command {
   306  	cmd := &cobra.Command{
   307  		Use:   "add_push",
   308  		Short: "add push for block or tx receipt",
   309  		Run:   addPushSubscribe,
   310  	}
   311  	addPushSubscribeFlags(cmd)
   312  	return cmd
   313  }
   314  
   315  func addPushSubscribeFlags(cmd *cobra.Command) {
   316  	cmd.Flags().StringP("name", "n", "", "call back name")
   317  	cmd.MarkFlagRequired("name")
   318  
   319  	cmd.Flags().StringP("url", "u", "", "call back URL")
   320  	cmd.MarkFlagRequired("url")
   321  
   322  	cmd.Flags().StringP("encode", "e", "", "data encode type,json or proto buff")
   323  	cmd.MarkFlagRequired("encode")
   324  
   325  	cmd.Flags().StringP("isheader", "i", "f", "push header or block (0/f/false for block; 1/t/true for header)")
   326  
   327  	cmd.Flags().Int64P("lastSequence", "", 0, "lastSequence")
   328  	cmd.Flags().Int64P("lastHeight", "", 0, "lastHeight")
   329  	cmd.Flags().StringP("lastBlockHash", "", "", "lastBlockHash")
   330  }
   331  
   332  func addPushSubscribe(cmd *cobra.Command, args []string) {
   333  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   334  	name, _ := cmd.Flags().GetString("name")
   335  	url, _ := cmd.Flags().GetString("url")
   336  	encode, _ := cmd.Flags().GetString("encode")
   337  
   338  	isHeaderStr, _ := cmd.Flags().GetString("isheader")
   339  	isHeader, err := strconv.ParseBool(isHeaderStr)
   340  	if err != nil {
   341  		fmt.Fprintln(os.Stderr, err)
   342  		return
   343  	}
   344  
   345  	lastSeq, _ := cmd.Flags().GetInt64("lastSequence")
   346  	lastHeight, _ := cmd.Flags().GetInt64("lastHeight")
   347  	lastBlockHash, _ := cmd.Flags().GetString("lastBlockHash")
   348  	if lastSeq != 0 || lastHeight != 0 || lastBlockHash != "" {
   349  		if lastSeq == 0 || lastHeight == 0 || lastBlockHash == "" {
   350  			fmt.Println("lastSequence, lastHeight, lastBlockHash need at the same time")
   351  			return
   352  		}
   353  	}
   354  	pushType := blockchain.PushBlock
   355  	if isHeader {
   356  		pushType = blockchain.PushBlockHeader
   357  	}
   358  
   359  	params := types.PushSubscribeReq{
   360  		Name:          name,
   361  		URL:           url,
   362  		Encode:        encode,
   363  		LastSequence:  lastSeq,
   364  		LastHeight:    lastHeight,
   365  		LastBlockHash: lastBlockHash,
   366  		Type:          pushType,
   367  	}
   368  
   369  	var res types.ReplySubscribePush
   370  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.AddPushSubscribe", params, &res)
   371  	ctx.Run()
   372  }
   373  
   374  // ListPushesCmd list block sequence call back
   375  func ListPushesCmd() *cobra.Command {
   376  	cmd := &cobra.Command{
   377  		Use:   "list_pushes",
   378  		Short: "list pushes",
   379  		Run:   listPushes,
   380  	}
   381  	return cmd
   382  }
   383  
   384  func listPushes(cmd *cobra.Command, args []string) {
   385  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   386  
   387  	var res types.PushSubscribes
   388  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.ListPushes", nil, &res)
   389  	ctx.Run()
   390  }
   391  
   392  // GetPushSeqLastNumCmd Get Seq Call Back Last Num
   393  func GetPushSeqLastNumCmd() *cobra.Command {
   394  	cmd := &cobra.Command{
   395  		Use:   "last_push",
   396  		Short: "show the sequence number of last push",
   397  		Run:   getPushSeqLastNumCmd,
   398  	}
   399  	getPushSeqLastNumFlags(cmd)
   400  	return cmd
   401  }
   402  
   403  func getPushSeqLastNumFlags(cmd *cobra.Command) {
   404  	cmd.Flags().StringP("name", "n", "", "call back name")
   405  	cmd.MarkFlagRequired("name")
   406  }
   407  
   408  func getPushSeqLastNumCmd(cmd *cobra.Command, args []string) {
   409  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   410  	name, _ := cmd.Flags().GetString("name")
   411  
   412  	params := types.ReqString{
   413  		Data: name,
   414  	}
   415  
   416  	var res types.Int64
   417  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetPushSeqLastNum", params, &res)
   418  	ctx.Run()
   419  }