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 }