4 log "github.com/sirupsen/logrus"
6 "github.com/bytom/blockchain/query"
7 "github.com/bytom/wallet"
8 "github.com/bytom/consensus"
9 "github.com/bytom/consensus/difficulty"
10 chainjson "github.com/bytom/encoding/json"
11 "github.com/bytom/protocol/bc"
12 "github.com/bytom/protocol/bc/types"
15 // return network infomation
16 func (a *API) getNetInfo() Response {
17 return NewSuccessResponse(a.bcr.GetNodeInfo())
20 // return best block hash
21 func (a *API) getBestBlockHash() Response {
22 blockHash := map[string]string{"blockHash": a.chain.BestBlockHash().String()}
23 return NewSuccessResponse(blockHash)
26 // return block header by hash
27 func (a *API) getBlockHeaderByHash(strHash string) Response {
29 if err := hash.UnmarshalText([]byte(strHash)); err != nil {
30 log.WithField("error", err).Error("Error occurs when transforming string hash to hash struct")
31 return NewErrorResponse(err)
33 block, err := a.chain.GetBlockByHash(&hash)
35 log.WithField("error", err).Error("Fail to get block by hash")
36 return NewErrorResponse(err)
39 bcBlock := types.MapBlock(block)
40 return NewSuccessResponse(bcBlock.BlockHeader)
43 // BlockTx is the tx struct for getBlock func
45 ID bc.Hash `json:"id"`
46 Version uint64 `json:"version"`
47 Size uint64 `json:"size"`
48 TimeRange uint64 `json:"time_range"`
49 Inputs []*query.AnnotatedInput `json:"inputs"`
50 Outputs []*query.AnnotatedOutput `json:"outputs"`
51 StatusFail bool `json:"status_fail"`
54 // GetBlockReq is used to handle getBlock req
55 type GetBlockReq struct {
56 BlockHeight uint64 `json:"block_height"`
57 BlockHash chainjson.HexBytes `json:"block_hash"`
60 // GetBlockResp is the resp for getBlock api
61 type GetBlockResp struct {
62 Hash *bc.Hash `json:"hash"`
63 Size uint64 `json:"size"`
64 Version uint64 `json:"version"`
65 Height uint64 `json:"height"`
66 PreviousBlockHash *bc.Hash `json:"previous_block_hash"`
67 Timestamp uint64 `json:"timestamp"`
68 Nonce uint64 `json:"nonce"`
69 Bits uint64 `json:"bits"`
70 Difficulty string `json:"difficulty"`
71 TransactionsMerkleRoot *bc.Hash `json:"transaction_merkle_root"`
72 TransactionStatusHash *bc.Hash `json:"transaction_status_hash"`
73 Transactions []*BlockTx `json:"transactions"`
76 // return block by hash
77 func (a *API) getBlock(ins GetBlockReq) Response {
79 block := &types.Block{}
80 if len(ins.BlockHash) == 32 {
82 copy(b32[:], ins.BlockHash)
83 hash := bc.NewHash(b32)
84 block, err = a.chain.GetBlockByHash(&hash)
86 block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
89 return NewErrorResponse(err)
92 blockHash := block.Hash()
93 txStatus, err := a.chain.GetTransactionStatus(&blockHash)
94 rawBlock, err := block.MarshalText()
96 return NewErrorResponse(err)
99 resp := &GetBlockResp{
101 Size: uint64(len(rawBlock)),
102 Version: block.Version,
103 Height: block.Height,
104 PreviousBlockHash: &block.PreviousBlockHash,
105 Timestamp: block.Timestamp,
108 Difficulty: difficulty.CompactToBig(block.Bits).String(),
109 TransactionsMerkleRoot: &block.TransactionsMerkleRoot,
110 TransactionStatusHash: &block.TransactionStatusHash,
111 Transactions: []*BlockTx{},
114 for i, orig := range block.Transactions {
117 Version: orig.Version,
118 Size: orig.SerializedSize,
119 TimeRange: orig.TimeRange,
120 Inputs: []*query.AnnotatedInput{},
121 Outputs: []*query.AnnotatedOutput{},
123 tx.StatusFail, err = txStatus.GetStatus(i)
125 NewSuccessResponse(resp)
128 for i := range orig.Inputs {
129 tx.Inputs = append(tx.Inputs, wallet.BuildAnnotatedInput(orig, uint32(i)))
131 for i := range orig.Outputs {
132 tx.Outputs = append(tx.Outputs, wallet.BuildAnnotatedOutput(orig, i))
134 resp.Transactions = append(resp.Transactions, tx)
136 return NewSuccessResponse(resp)
139 // return block transactions count by hash
140 func (a *API) getBlockTransactionsCountByHash(strHash string) Response {
142 if err := hash.UnmarshalText([]byte(strHash)); err != nil {
143 log.WithField("error", err).Error("Error occurs when transforming string hash to hash struct")
144 return NewErrorResponse(err)
147 legacyBlock, err := a.chain.GetBlockByHash(&hash)
149 log.WithField("error", err).Error("Fail to get block by hash")
150 return NewErrorResponse(err)
153 count := map[string]int{"count": len(legacyBlock.Transactions)}
154 return NewSuccessResponse(count)
157 // return block transactions count by height
158 func (a *API) getBlockTransactionsCountByHeight(height uint64) Response {
159 legacyBlock, err := a.chain.GetBlockByHeight(height)
161 log.WithField("error", err).Error("Fail to get block by hash")
162 return NewErrorResponse(err)
165 count := map[string]int{"count": len(legacyBlock.Transactions)}
166 return NewSuccessResponse(count)
169 // return current block count
170 func (a *API) getBlockCount() Response {
171 blockHeight := map[string]uint64{"block_count": a.chain.Height()}
172 return NewSuccessResponse(blockHeight)
175 // return is in mining or not
176 func (a *API) isMining() Response {
177 IsMining := map[string]bool{"isMining": a.bcr.IsMining()}
178 return NewSuccessResponse(IsMining)
182 func (a *API) gasRate() Response {
183 gasrate := map[string]int64{"gasRate": consensus.VMGasRate}
184 return NewSuccessResponse(gasrate)