4 log "github.com/sirupsen/logrus"
6 "github.com/bytom/blockchain/query"
7 "github.com/bytom/blockchain/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 (bcr *BlockchainReactor) getNetInfo() Response {
18 Listening bool `json:"listening"`
19 Syncing bool `json:"syncing"`
20 Mining bool `json:"mining"`
21 PeerCount int `json:"peer_count"`
22 CurrentBlock uint64 `json:"current_block"`
23 HighestBlock uint64 `json:"highest_block"`
26 net.Listening = bcr.sw.IsListening()
27 net.Syncing = bcr.blockKeeper.IsCaughtUp()
28 net.Mining = bcr.mining.IsMining()
29 net.PeerCount = len(bcr.sw.Peers().List())
30 net.CurrentBlock = bcr.blockKeeper.chainHeight
31 net.HighestBlock = bcr.blockKeeper.maxPeerHeight
33 return NewSuccessResponse(net)
36 // return best block hash
37 func (bcr *BlockchainReactor) getBestBlockHash() Response {
38 blockHash := map[string]string{"blockHash": bcr.chain.BestBlockHash().String()}
39 return NewSuccessResponse(blockHash)
42 // return block header by hash
43 func (bcr *BlockchainReactor) getBlockHeaderByHash(strHash string) Response {
45 if err := hash.UnmarshalText([]byte(strHash)); err != nil {
46 log.WithField("error", err).Error("Error occurs when transforming string hash to hash struct")
47 return NewErrorResponse(err)
49 block, err := bcr.chain.GetBlockByHash(&hash)
51 log.WithField("error", err).Error("Fail to get block by hash")
52 return NewErrorResponse(err)
55 bcBlock := types.MapBlock(block)
56 return NewSuccessResponse(bcBlock.BlockHeader)
59 // BlockTx is the tx struct for getBlock func
61 ID bc.Hash `json:"id"`
62 Version uint64 `json:"version"`
63 Size uint64 `json:"size"`
64 TimeRange uint64 `json:"time_range"`
65 Inputs []*query.AnnotatedInput `json:"inputs"`
66 Outputs []*query.AnnotatedOutput `json:"outputs"`
67 StatusFail bool `json:"status_fail"`
70 // GetBlockReq is used to handle getBlock req
71 type GetBlockReq struct {
72 BlockHeight uint64 `json:"block_height"`
73 BlockHash chainjson.HexBytes `json:"block_hash"`
76 // GetBlockResp is the resp for getBlock api
77 type GetBlockResp struct {
78 Hash *bc.Hash `json:"hash"`
79 Size uint64 `json:"size"`
80 Version uint64 `json:"version"`
81 Height uint64 `json:"height"`
82 PreviousBlockHash *bc.Hash `json:"previous_block_hash"`
83 Timestamp uint64 `json:"timestamp"`
84 Nonce uint64 `json:"nonce"`
85 Bits uint64 `json:"bits"`
86 Difficulty string `json:"difficulty"`
87 TransactionsMerkleRoot *bc.Hash `json:"transaction_merkle_root"`
88 TransactionStatusHash *bc.Hash `json:"transaction_status_hash"`
89 Transactions []*BlockTx `json:"transactions"`
92 // return block by hash
93 func (bcr *BlockchainReactor) getBlock(ins GetBlockReq) Response {
95 block := &types.Block{}
96 if len(ins.BlockHash) == 32 {
98 copy(b32[:], ins.BlockHash)
99 hash := bc.NewHash(b32)
100 block, err = bcr.chain.GetBlockByHash(&hash)
102 block, err = bcr.chain.GetBlockByHeight(ins.BlockHeight)
105 return NewErrorResponse(err)
108 blockHash := block.Hash()
109 txStatus, err := bcr.chain.GetTransactionStatus(&blockHash)
110 rawBlock, err := block.MarshalText()
112 return NewErrorResponse(err)
115 resp := &GetBlockResp{
117 Size: uint64(len(rawBlock)),
118 Version: block.Version,
119 Height: block.Height,
120 PreviousBlockHash: &block.PreviousBlockHash,
121 Timestamp: block.Timestamp,
124 Difficulty: difficulty.CompactToBig(block.Bits).String(),
125 TransactionsMerkleRoot: &block.TransactionsMerkleRoot,
126 TransactionStatusHash: &block.TransactionStatusHash,
127 Transactions: []*BlockTx{},
130 for i, orig := range block.Transactions {
133 Version: orig.Version,
134 Size: orig.SerializedSize,
135 TimeRange: orig.TimeRange,
136 Inputs: []*query.AnnotatedInput{},
137 Outputs: []*query.AnnotatedOutput{},
139 tx.StatusFail, err = txStatus.GetStatus(i)
141 NewSuccessResponse(resp)
144 for i := range orig.Inputs {
145 tx.Inputs = append(tx.Inputs, wallet.BuildAnnotatedInput(orig, uint32(i)))
147 for i := range orig.Outputs {
148 tx.Outputs = append(tx.Outputs, wallet.BuildAnnotatedOutput(orig, i))
150 resp.Transactions = append(resp.Transactions, tx)
152 return NewSuccessResponse(resp)
155 // return block transactions count by hash
156 func (bcr *BlockchainReactor) getBlockTransactionsCountByHash(strHash string) Response {
158 if err := hash.UnmarshalText([]byte(strHash)); err != nil {
159 log.WithField("error", err).Error("Error occurs when transforming string hash to hash struct")
160 return NewErrorResponse(err)
163 legacyBlock, err := bcr.chain.GetBlockByHash(&hash)
165 log.WithField("error", err).Error("Fail to get block by hash")
166 return NewErrorResponse(err)
169 count := map[string]int{"count": len(legacyBlock.Transactions)}
170 return NewSuccessResponse(count)
173 // return block transactions count by height
174 func (bcr *BlockchainReactor) getBlockTransactionsCountByHeight(height uint64) Response {
175 legacyBlock, err := bcr.chain.GetBlockByHeight(height)
177 log.WithField("error", err).Error("Fail to get block by hash")
178 return NewErrorResponse(err)
181 count := map[string]int{"count": len(legacyBlock.Transactions)}
182 return NewSuccessResponse(count)
185 // return block height
186 func (bcr *BlockchainReactor) blockHeight() Response {
187 blockHeight := map[string]uint64{"blockHeight": bcr.chain.Height()}
188 return NewSuccessResponse(blockHeight)
191 // return is in mining or not
192 func (bcr *BlockchainReactor) isMining() Response {
193 IsMining := map[string]bool{"isMining": bcr.mining.IsMining()}
194 return NewSuccessResponse(IsMining)
198 func (bcr *BlockchainReactor) gasRate() Response {
199 gasrate := map[string]int64{"gasRate": consensus.VMGasRate}
200 return NewSuccessResponse(gasrate)