4 log "github.com/sirupsen/logrus"
7 "github.com/bytom/blockchain/query"
8 "github.com/bytom/wallet"
9 "github.com/bytom/consensus"
10 "github.com/bytom/consensus/difficulty"
11 chainjson "github.com/bytom/encoding/json"
12 "github.com/bytom/protocol/bc"
13 "github.com/bytom/protocol/bc/types"
16 func (bcr *BlockchainReactor) GetNodeInfo() *api.NetInfo {
18 Listening: bcr.sw.IsListening(),
19 Syncing: bcr.blockKeeper.IsCaughtUp(),
20 Mining: bcr.mining.IsMining(),
21 PeerCount: len(bcr.sw.Peers().List()),
22 CurrentBlock: bcr.blockKeeper.chainHeight,
23 HighestBlock: bcr.blockKeeper.maxPeerHeight,
27 func (bcr *BlockchainReactor) IsMining() bool {
28 return bcr.mining.IsMining()
31 // return network infomation
32 func (a *API) getNetInfo() Response {
33 return NewSuccessResponse(a.bcr.GetNodeInfo())
36 // return best block hash
37 func (a *API) getBestBlockHash() Response {
38 blockHash := map[string]string{"blockHash": a.chain.BestBlockHash().String()}
39 return NewSuccessResponse(blockHash)
42 // return block header by hash
43 func (a *API) 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 := a.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 (a *API) 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 = a.chain.GetBlockByHash(&hash)
102 block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
105 return NewErrorResponse(err)
108 blockHash := block.Hash()
109 txStatus, err := a.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 (a *API) 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 := a.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 (a *API) getBlockTransactionsCountByHeight(height uint64) Response {
175 legacyBlock, err := a.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 current block count
186 func (a *API) getBlockCount() Response {
187 blockHeight := map[string]uint64{"block_count": a.chain.Height()}
188 return NewSuccessResponse(blockHeight)
191 // return is in mining or not
192 func (a *API) isMining() Response {
193 IsMining := map[string]bool{"isMining": a.bcr.IsMining()}
194 return NewSuccessResponse(IsMining)
198 func (a *API) gasRate() Response {
199 gasrate := map[string]int64{"gasRate": consensus.VMGasRate}
200 return NewSuccessResponse(gasrate)