diff --git a/README.md b/README.md index e4b4e040..424d52ad 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Developer build guide is [here](/docs/build.md). Contribution guide is [here](CONTRIBUTING.md). -# Implemented coins +## Implemented coins Blockbook currently supports over 20 coins, among them: - Bitcoin, Litecoin, Bitcoin Cash, Bgold, ZCash, Dash, Ethereum, Ethereum Classic @@ -37,10 +37,10 @@ Testnets for some coins are also supported, for example: List of all implemented coins is in [the registry of ports](/docs/ports.md). -# Data storage in RocksDB +## Data storage in RocksDB Blockbook stores data the key-value store RocksDB. Database format is described [here](/docs/rocksdb.md). -# API +## API Blockbook API is described [here](/docs/api.md). diff --git a/api/types.go b/api/types.go index 8e539992..a2ddde4a 100644 --- a/api/types.go +++ b/api/types.go @@ -291,10 +291,21 @@ type Blocks struct { Blocks []db.BlockInfo `json:"blocks"` } +// BlockInfo contains extended block header data and a list of block txids +type BlockInfo struct { + bchain.BlockHeader + Version json.Number `json:"version"` + MerkleRoot string `json:"merkleroot"` + Nonce string `json:"nonce"` + Bits string `json:"bits"` + Difficulty string `json:"difficulty"` + Txids []string `json:"tx,omitempty"` +} + // Block contains information about block type Block struct { Paging - bchain.BlockInfo + BlockInfo TxCount int `json:"txCount"` Transactions []*Tx `json:"txs,omitempty"` } diff --git a/api/typesv1.go b/api/typesv1.go index bcdad73f..1e64b598 100644 --- a/api/typesv1.go +++ b/api/typesv1.go @@ -96,8 +96,8 @@ type AddressUtxoV1 struct { // BlockV1 contains information about block type BlockV1 struct { Paging - bchain.BlockInfo - TxCount int `json:"TxCount"` + BlockInfo + TxCount int `json:"txCount"` Transactions []*TxV1 `json:"txs,omitempty"` } diff --git a/api/worker.go b/api/worker.go index b1c30cc3..c8632758 100644 --- a/api/worker.go +++ b/api/worker.go @@ -1014,8 +1014,16 @@ func (w *Worker) GetBlock(bid string, page int, txsOnPage int) (*Block, error) { bi.Txids = nil glog.Info("GetBlock ", bid, ", page ", page, " finished in ", time.Since(start)) return &Block{ - Paging: pg, - BlockInfo: *bi, + Paging: pg, + BlockInfo: BlockInfo{ + BlockHeader: bi.BlockHeader, + Bits: bi.Bits, + Difficulty: string(bi.Difficulty), + MerkleRoot: bi.MerkleRoot, + Nonce: string(bi.Nonce), + Txids: bi.Txids, + Version: bi.Version, + }, TxCount: txCount, Transactions: txs, }, nil diff --git a/docs/api.md b/docs/api.md index c1d59314..26a7bfc2 100644 --- a/docs/api.md +++ b/docs/api.md @@ -399,9 +399,9 @@ Response: "time": 1553096617, "version": 6422787, "merkleroot": "6783f6083788c4f69b8af23bd2e4a194cf36ac34d590dfd97e510fe7aebc72c8", - "nonce": 0, + "nonce": "0", "bits": "1a063f3b", - "difficulty": 2685605.260733312, + "difficulty": "2685605.260733312", "txCount": 2, "txs": [ { diff --git a/server/public_test.go b/server/public_test.go index 7e112421..e203d947 100644 --- a/server/public_test.go +++ b/server/public_test.go @@ -588,7 +588,7 @@ func httpTests_BitcoinType(t *testing.T, ts *httptest.Server) { }, { name: "apiSendTx", - r: newGetRequest(ts.URL + "/api/sendtx/1234567890"), + r: newGetRequest(ts.URL + "/api/v2/sendtx/1234567890"), status: http.StatusBadRequest, contentType: "application/json; charset=utf-8", body: []string{ @@ -597,7 +597,7 @@ func httpTests_BitcoinType(t *testing.T, ts *httptest.Server) { }, { name: "apiSendTx POST", - r: newPostRequest(ts.URL+"/api/sendtx/", "123456"), + r: newPostRequest(ts.URL+"/api/v2/sendtx/", "123456"), status: http.StatusOK, contentType: "application/json; charset=utf-8", body: []string{ @@ -606,7 +606,7 @@ func httpTests_BitcoinType(t *testing.T, ts *httptest.Server) { }, { name: "apiSendTx POST empty", - r: newPostRequest(ts.URL+"/api/sendtx", ""), + r: newPostRequest(ts.URL+"/api/v2/sendtx", ""), status: http.StatusBadRequest, contentType: "application/json; charset=utf-8", body: []string{ @@ -622,6 +622,15 @@ func httpTests_BitcoinType(t *testing.T, ts *httptest.Server) { `{"result":"0.00012299"}`, }, }, + { + name: "apiGetBlock", + r: newGetRequest(ts.URL + "/api/v2/block/225493"), + status: http.StatusOK, + contentType: "application/json; charset=utf-8", + body: []string{ + `{"page":1,"totalPages":1,"itemsOnPage":1000,"hash":"0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997","previousblockhash":"","nextblockhash":"00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6","height":225493,"confirmations":2,"size":1234567,"time":1534858021,"version":0,"merkleroot":"","nonce":"","bits":"","difficulty":"","txCount":2,"txs":[{"txid":"00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840","vin":[],"vout":[{"value":"100000000","n":0,"addresses":["mfcWp7DB6NuaZsExybTTXpVgWz559Np4Ti"]},{"value":"12345","n":1,"spent":true,"addresses":["mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz"]}],"blockhash":"0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997","blockheight":225493,"confirmations":2,"blocktime":1534858021,"value":"100012345","valueIn":"0","fees":"0"},{"txid":"effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75","vin":[],"vout":[{"value":"1234567890123","n":0,"spent":true,"addresses":["mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw"]},{"value":"1","n":1,"spent":true,"addresses":["2MzmAKayJmja784jyHvRUW1bXPget1csRRG"]},{"value":"9876","n":2,"spent":true,"addresses":["2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1"]}],"blockhash":"0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997","blockheight":225493,"confirmations":2,"blocktime":1534858021,"value":"1234567900000","valueIn":"0","fees":"0"}]}`, + }, + }, } for _, tt := range tests {