Add get raw block API request #736
This commit is contained in:
parent
ad18eda804
commit
93ea126123
@ -399,6 +399,11 @@ type Block struct {
|
|||||||
Transactions []*Tx `json:"txs,omitempty"`
|
Transactions []*Tx `json:"txs,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BlockRaw contains raw block in hex
|
||||||
|
type BlockRaw struct {
|
||||||
|
Hex string `json:"hex"`
|
||||||
|
}
|
||||||
|
|
||||||
// BlockbookInfo contains information about the running blockbook instance
|
// BlockbookInfo contains information about the running blockbook instance
|
||||||
type BlockbookInfo struct {
|
type BlockbookInfo struct {
|
||||||
Coin string `json:"coin"`
|
Coin string `json:"coin"`
|
||||||
|
|||||||
@ -1486,8 +1486,8 @@ func (w *Worker) GetFiatRatesTickersList(timestamp int64) (*db.ResultTickerListA
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getBlockInfoFromBlockID returns block info from block height or block hash
|
// getBlockHashBlockID returns block hash from block height or block hash
|
||||||
func (w *Worker) getBlockInfoFromBlockID(bid string) (*bchain.BlockInfo, error) {
|
func (w *Worker) getBlockHashBlockID(bid string) string {
|
||||||
// try to decide if passed string (bid) is block height or block hash
|
// try to decide if passed string (bid) is block height or block hash
|
||||||
// if it's a number, must be less than int32
|
// if it's a number, must be less than int32
|
||||||
var hash string
|
var hash string
|
||||||
@ -1500,6 +1500,12 @@ func (w *Worker) getBlockInfoFromBlockID(bid string) (*bchain.BlockInfo, error)
|
|||||||
} else {
|
} else {
|
||||||
hash = bid
|
hash = bid
|
||||||
}
|
}
|
||||||
|
return hash
|
||||||
|
}
|
||||||
|
|
||||||
|
// getBlockInfoFromBlockID returns block info from block height or block hash
|
||||||
|
func (w *Worker) getBlockInfoFromBlockID(bid string) (*bchain.BlockInfo, error) {
|
||||||
|
hash:=w.getBlockHashBlockID(bid)
|
||||||
if hash == "" {
|
if hash == "" {
|
||||||
return nil, NewAPIError("Block not found", true)
|
return nil, NewAPIError("Block not found", true)
|
||||||
}
|
}
|
||||||
@ -1678,6 +1684,16 @@ func (w *Worker) GetBlock(bid string, page int, txsOnPage int) (*Block, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBlock returns paged data about block
|
||||||
|
func (w *Worker) GetBlockRaw(bid string) (*BlockRaw, error) {
|
||||||
|
hash:=w.getBlockHashBlockID(bid)
|
||||||
|
if hash == "" {
|
||||||
|
return nil, NewAPIError("Block not found", true)
|
||||||
|
}
|
||||||
|
hex, err := w.chain.GetBlockRaw(hash)
|
||||||
|
return &BlockRaw{Hex: hex}, err
|
||||||
|
}
|
||||||
|
|
||||||
// ComputeFeeStats computes fee distribution in defined blocks and logs them to log
|
// ComputeFeeStats computes fee distribution in defined blocks and logs them to log
|
||||||
func (w *Worker) ComputeFeeStats(blockFrom, blockTo int, stopCompute chan os.Signal) error {
|
func (w *Worker) ComputeFeeStats(blockFrom, blockTo int, stopCompute chan os.Signal) error {
|
||||||
bestheight, _, err := w.db.GetBestBlock()
|
bestheight, _, err := w.db.GetBestBlock()
|
||||||
|
|||||||
@ -29,6 +29,11 @@ func (b *BaseChain) GetNetworkName() string {
|
|||||||
return b.Network
|
return b.Network
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBlockRaw is not supported by default
|
||||||
|
func (b *BaseChain) GetBlockRaw(hash string) (string, error) {
|
||||||
|
return "", errors.New("GetBlockRaw: not supported")
|
||||||
|
}
|
||||||
|
|
||||||
// GetMempoolEntry is not supported by default
|
// GetMempoolEntry is not supported by default
|
||||||
func (b *BaseChain) GetMempoolEntry(txid string) (*MempoolEntry, error) {
|
func (b *BaseChain) GetMempoolEntry(txid string) (*MempoolEntry, error) {
|
||||||
return nil, errors.New("GetMempoolEntry: not supported")
|
return nil, errors.New("GetMempoolEntry: not supported")
|
||||||
|
|||||||
@ -95,7 +95,7 @@ func (b *BCashRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
data, err := b.GetBlockRaw(hash)
|
data, err := b.GetBlockBytes(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ func (b *BCashRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockRaw returns block with given hash as bytes.
|
// GetBlockRaw returns block with given hash as bytes.
|
||||||
func (b *BCashRPC) GetBlockRaw(hash string) ([]byte, error) {
|
func (b *BCashRPC) GetBlockRaw(hash string) (string, error) {
|
||||||
glog.V(1).Info("rpc: getblock (verbose=0) ", hash)
|
glog.V(1).Info("rpc: getblock (verbose=0) ", hash)
|
||||||
|
|
||||||
res := btc.ResGetBlockRaw{}
|
res := btc.ResGetBlockRaw{}
|
||||||
@ -121,15 +121,24 @@ func (b *BCashRPC) GetBlockRaw(hash string) ([]byte, error) {
|
|||||||
err := b.Call(&req, &res)
|
err := b.Call(&req, &res)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Annotatef(err, "hash %v", hash)
|
return "", errors.Annotatef(err, "hash %v", hash)
|
||||||
}
|
}
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
if isErrBlockNotFound(res.Error) {
|
if isErrBlockNotFound(res.Error) {
|
||||||
return nil, bchain.ErrBlockNotFound
|
return "", bchain.ErrBlockNotFound
|
||||||
}
|
}
|
||||||
return nil, errors.Annotatef(res.Error, "hash %v", hash)
|
return "", errors.Annotatef(res.Error, "hash %v", hash)
|
||||||
}
|
}
|
||||||
return hex.DecodeString(res.Result)
|
return res.Result,nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlockBytes returns block with given hash as bytes
|
||||||
|
func (b *BCashRPC) GetBlockBytes(hash string) ([]byte, error) {
|
||||||
|
block,err:=b.GetBlockRaw(hash)
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
return hex.DecodeString(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockInfo returns extended header (more info than in bchain.BlockHeader) with a list of txids
|
// GetBlockInfo returns extended header (more info than in bchain.BlockHeader) with a list of txids
|
||||||
|
|||||||
@ -78,7 +78,7 @@ func (f *BitcoreRPC) GetBlock(hash string, height uint32) (*bchain.Block, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
data, err := f.GetBlockRaw(hash)
|
data, err := f.GetBlockBytes(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -254,6 +254,11 @@ func (c *blockChainWithMetrics) GetBlockInfo(hash string) (v *bchain.BlockInfo,
|
|||||||
return c.b.GetBlockInfo(hash)
|
return c.b.GetBlockInfo(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *blockChainWithMetrics) GetBlockRaw(hash string) (v string, err error) {
|
||||||
|
defer func(s time.Time) { c.observeRPCLatency("GetBlockRaw", s, err) }(time.Now())
|
||||||
|
return c.b.GetBlockRaw(hash)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *blockChainWithMetrics) GetMempoolTransactions() (v []string, err error) {
|
func (c *blockChainWithMetrics) GetMempoolTransactions() (v []string, err error) {
|
||||||
defer func(s time.Time) { c.observeRPCLatency("GetMempoolTransactions", s, err) }(time.Now())
|
defer func(s time.Time) { c.observeRPCLatency("GetMempoolTransactions", s, err) }(time.Now())
|
||||||
return c.b.GetMempoolTransactions()
|
return c.b.GetMempoolTransactions()
|
||||||
|
|||||||
@ -551,7 +551,7 @@ func (b *BitcoinRPC) GetBlock(hash string, height uint32) (*bchain.Block, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
data, err := b.GetBlockRaw(hash)
|
data, err := b.GetBlockBytes(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -588,7 +588,7 @@ func (b *BitcoinRPC) GetBlockInfo(hash string) (*bchain.BlockInfo, error) {
|
|||||||
// GetBlockWithoutHeader is an optimization - it does not call GetBlockHeader to get prev, next hashes
|
// GetBlockWithoutHeader is an optimization - it does not call GetBlockHeader to get prev, next hashes
|
||||||
// instead it sets to header only block hash and height passed in parameters
|
// instead it sets to header only block hash and height passed in parameters
|
||||||
func (b *BitcoinRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.Block, error) {
|
func (b *BitcoinRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.Block, error) {
|
||||||
data, err := b.GetBlockRaw(hash)
|
data, err := b.GetBlockBytes(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -601,8 +601,8 @@ func (b *BitcoinRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.
|
|||||||
return block, nil
|
return block, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockRaw returns block with given hash as bytes
|
// GetBlockRaw returns block with given hash as hex string
|
||||||
func (b *BitcoinRPC) GetBlockRaw(hash string) ([]byte, error) {
|
func (b *BitcoinRPC) GetBlockRaw(hash string) (string, error) {
|
||||||
glog.V(1).Info("rpc: getblock (verbosity=0) ", hash)
|
glog.V(1).Info("rpc: getblock (verbosity=0) ", hash)
|
||||||
|
|
||||||
res := ResGetBlockRaw{}
|
res := ResGetBlockRaw{}
|
||||||
@ -612,15 +612,24 @@ func (b *BitcoinRPC) GetBlockRaw(hash string) ([]byte, error) {
|
|||||||
err := b.Call(&req, &res)
|
err := b.Call(&req, &res)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Annotatef(err, "hash %v", hash)
|
return "", errors.Annotatef(err, "hash %v", hash)
|
||||||
}
|
}
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
if IsErrBlockNotFound(res.Error) {
|
if IsErrBlockNotFound(res.Error) {
|
||||||
return nil, bchain.ErrBlockNotFound
|
return "", bchain.ErrBlockNotFound
|
||||||
}
|
}
|
||||||
return nil, errors.Annotatef(res.Error, "hash %v", hash)
|
return "", errors.Annotatef(res.Error, "hash %v", hash)
|
||||||
}
|
}
|
||||||
return hex.DecodeString(res.Result)
|
return res.Result,nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlockBytes returns block with given hash as bytes
|
||||||
|
func (b *BitcoinRPC) GetBlockBytes(hash string) ([]byte, error) {
|
||||||
|
block,err:=b.GetBlockRaw(hash)
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
return hex.DecodeString(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockFull returns block with given hash
|
// GetBlockFull returns block with given hash
|
||||||
|
|||||||
@ -81,7 +81,7 @@ func (zc *FiroRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := zc.GetBlockRaw(hash)
|
data, err := zc.GetBlockBytes(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ func (zc *FiroRPC) GetBlockInfo(hash string) (*bchain.BlockInfo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (zc *FiroRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.Block, error) {
|
func (zc *FiroRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.Block, error) {
|
||||||
data, err := zc.GetBlockRaw(hash)
|
data, err := zc.GetBlockBytes(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -134,7 +134,8 @@ func (zc *FiroRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.Bl
|
|||||||
return block, nil
|
return block, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (zc *FiroRPC) GetBlockRaw(hash string) ([]byte, error) {
|
// GetBlockRaw returns block with given hash as hex string
|
||||||
|
func (zc *FiroRPC) GetBlockRaw(hash string) (string, error) {
|
||||||
glog.V(1).Info("rpc: getblock (verbosity=false) ", hash)
|
glog.V(1).Info("rpc: getblock (verbosity=false) ", hash)
|
||||||
|
|
||||||
res := btc.ResGetBlockRaw{}
|
res := btc.ResGetBlockRaw{}
|
||||||
@ -144,15 +145,24 @@ func (zc *FiroRPC) GetBlockRaw(hash string) ([]byte, error) {
|
|||||||
err := zc.Call(&req, &res)
|
err := zc.Call(&req, &res)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Annotatef(err, "hash %v", hash)
|
return "", errors.Annotatef(err, "hash %v", hash)
|
||||||
}
|
}
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
if btc.IsErrBlockNotFound(res.Error) {
|
if btc.IsErrBlockNotFound(res.Error) {
|
||||||
return nil, bchain.ErrBlockNotFound
|
return "", bchain.ErrBlockNotFound
|
||||||
}
|
}
|
||||||
return nil, errors.Annotatef(res.Error, "hash %v", hash)
|
return "", errors.Annotatef(res.Error, "hash %v", hash)
|
||||||
}
|
}
|
||||||
return hex.DecodeString(res.Result)
|
return res.Result,nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlockBytes returns block with given hash as bytes
|
||||||
|
func (zc *FiroRPC) GetBlockBytes(hash string) ([]byte, error) {
|
||||||
|
block,err:=zc.GetBlockRaw(hash)
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
return hex.DecodeString(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (zc *FiroRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
|
func (zc *FiroRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
|
||||||
|
|||||||
@ -78,7 +78,7 @@ func (f *FloRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
data, err := f.GetBlockRaw(hash)
|
data, err := f.GetBlockBytes(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -164,7 +164,8 @@ func (z *ZCashRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error) {
|
|||||||
return nil, errors.New("GetMempoolEntry: not implemented")
|
return nil, errors.New("GetMempoolEntry: not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func isErrBlockNotFound(err *bchain.RPCError) bool {
|
// GetBlockRaw is not supported
|
||||||
return err.Message == "Block not found" ||
|
func (z *ZCashRPC) GetBlockRaw(hash string) (string, error) {
|
||||||
err.Message == "Block height out of range"
|
return "", errors.New("GetBlockRaw: not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -285,6 +285,7 @@ type BlockChain interface {
|
|||||||
GetBlockHeader(hash string) (*BlockHeader, error)
|
GetBlockHeader(hash string) (*BlockHeader, error)
|
||||||
GetBlock(hash string, height uint32) (*Block, error)
|
GetBlock(hash string, height uint32) (*Block, error)
|
||||||
GetBlockInfo(hash string) (*BlockInfo, error)
|
GetBlockInfo(hash string) (*BlockInfo, error)
|
||||||
|
GetBlockRaw(hash string) (string, error)
|
||||||
GetMempoolTransactions() ([]string, error)
|
GetMempoolTransactions() ([]string, error)
|
||||||
GetTransaction(txid string) (*Tx, error)
|
GetTransaction(txid string) (*Tx, error)
|
||||||
GetTransactionForMempool(txid string) (*Tx, error)
|
GetTransactionForMempool(txid string) (*Tx, error)
|
||||||
|
|||||||
@ -174,6 +174,7 @@ func (s *PublicServer) ConnectFullPublicInterface() {
|
|||||||
serveMux.HandleFunc(path+"api/xpub/", s.jsonHandler(s.apiXpub, apiDefault))
|
serveMux.HandleFunc(path+"api/xpub/", s.jsonHandler(s.apiXpub, apiDefault))
|
||||||
serveMux.HandleFunc(path+"api/utxo/", s.jsonHandler(s.apiUtxo, apiDefault))
|
serveMux.HandleFunc(path+"api/utxo/", s.jsonHandler(s.apiUtxo, apiDefault))
|
||||||
serveMux.HandleFunc(path+"api/block/", s.jsonHandler(s.apiBlock, apiDefault))
|
serveMux.HandleFunc(path+"api/block/", s.jsonHandler(s.apiBlock, apiDefault))
|
||||||
|
serveMux.HandleFunc(path+"api/rawblock/", s.jsonHandler(s.apiBlockRaw, apiDefault))
|
||||||
serveMux.HandleFunc(path+"api/sendtx/", s.jsonHandler(s.apiSendTx, apiDefault))
|
serveMux.HandleFunc(path+"api/sendtx/", s.jsonHandler(s.apiSendTx, apiDefault))
|
||||||
serveMux.HandleFunc(path+"api/estimatefee/", s.jsonHandler(s.apiEstimateFee, apiDefault))
|
serveMux.HandleFunc(path+"api/estimatefee/", s.jsonHandler(s.apiEstimateFee, apiDefault))
|
||||||
serveMux.HandleFunc(path+"api/balancehistory/", s.jsonHandler(s.apiBalanceHistory, apiDefault))
|
serveMux.HandleFunc(path+"api/balancehistory/", s.jsonHandler(s.apiBalanceHistory, apiDefault))
|
||||||
@ -185,6 +186,7 @@ func (s *PublicServer) ConnectFullPublicInterface() {
|
|||||||
serveMux.HandleFunc(path+"api/v2/xpub/", s.jsonHandler(s.apiXpub, apiV2))
|
serveMux.HandleFunc(path+"api/v2/xpub/", s.jsonHandler(s.apiXpub, apiV2))
|
||||||
serveMux.HandleFunc(path+"api/v2/utxo/", s.jsonHandler(s.apiUtxo, apiV2))
|
serveMux.HandleFunc(path+"api/v2/utxo/", s.jsonHandler(s.apiUtxo, apiV2))
|
||||||
serveMux.HandleFunc(path+"api/v2/block/", s.jsonHandler(s.apiBlock, apiV2))
|
serveMux.HandleFunc(path+"api/v2/block/", s.jsonHandler(s.apiBlock, apiV2))
|
||||||
|
serveMux.HandleFunc(path+"api/v2/rawblock/", s.jsonHandler(s.apiBlockRaw, apiDefault))
|
||||||
serveMux.HandleFunc(path+"api/v2/sendtx/", s.jsonHandler(s.apiSendTx, apiV2))
|
serveMux.HandleFunc(path+"api/v2/sendtx/", s.jsonHandler(s.apiSendTx, apiV2))
|
||||||
serveMux.HandleFunc(path+"api/v2/estimatefee/", s.jsonHandler(s.apiEstimateFee, apiV2))
|
serveMux.HandleFunc(path+"api/v2/estimatefee/", s.jsonHandler(s.apiEstimateFee, apiV2))
|
||||||
serveMux.HandleFunc(path+"api/v2/feestats/", s.jsonHandler(s.apiFeeStats, apiV2))
|
serveMux.HandleFunc(path+"api/v2/feestats/", s.jsonHandler(s.apiFeeStats, apiV2))
|
||||||
@ -1139,6 +1141,16 @@ func (s *PublicServer) apiBlock(r *http.Request, apiVersion int) (interface{}, e
|
|||||||
return block, err
|
return block, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PublicServer) apiBlockRaw(r *http.Request, apiVersion int) (interface{}, error) {
|
||||||
|
var block *api.BlockRaw
|
||||||
|
var err error
|
||||||
|
s.metrics.ExplorerViews.With(common.Labels{"action": "api-block-raw"}).Inc()
|
||||||
|
if i := strings.LastIndexByte(r.URL.Path, '/'); i > 0 {
|
||||||
|
block, err = s.api.GetBlockRaw(r.URL.Path[i+1:])
|
||||||
|
}
|
||||||
|
return block, err
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PublicServer) apiFeeStats(r *http.Request, apiVersion int) (interface{}, error) {
|
func (s *PublicServer) apiFeeStats(r *http.Request, apiVersion int) (interface{}, error) {
|
||||||
var feeStats *api.FeeStats
|
var feeStats *api.FeeStats
|
||||||
var err error
|
var err error
|
||||||
|
|||||||
@ -937,6 +937,15 @@ func httpTestsBitcoinType(t *testing.T, ts *httptest.Server) {
|
|||||||
`{"page":1,"totalPages":1,"itemsOnPage":1000,"hash":"0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997","nextBlockHash":"00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6","height":225493,"confirmations":2,"size":1234567,"time":1521515026,"version":0,"merkleRoot":"","nonce":"","bits":"","difficulty":"","txCount":2,"txs":[{"txid":"00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840","vin":[],"vout":[{"value":"100000000","n":0,"addresses":["mfcWp7DB6NuaZsExybTTXpVgWz559Np4Ti"],"isAddress":true},{"value":"12345","n":1,"spent":true,"addresses":["mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz"],"isAddress":true},{"value":"12345","n":2,"addresses":["mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz"],"isAddress":true}],"blockHash":"0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997","blockHeight":225493,"confirmations":2,"blockTime":1521515026,"value":"100024690","valueIn":"0","fees":"0"},{"txid":"effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75","vin":[],"vout":[{"value":"1234567890123","n":0,"spent":true,"addresses":["mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw"],"isAddress":true},{"value":"1","n":1,"spent":true,"addresses":["2MzmAKayJmja784jyHvRUW1bXPget1csRRG"],"isAddress":true},{"value":"9876","n":2,"spent":true,"addresses":["2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1"],"isAddress":true}],"blockHash":"0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997","blockHeight":225493,"confirmations":2,"blockTime":1521515026,"value":"1234567900000","valueIn":"0","fees":"0"}]}`,
|
`{"page":1,"totalPages":1,"itemsOnPage":1000,"hash":"0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997","nextBlockHash":"00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6","height":225493,"confirmations":2,"size":1234567,"time":1521515026,"version":0,"merkleRoot":"","nonce":"","bits":"","difficulty":"","txCount":2,"txs":[{"txid":"00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840","vin":[],"vout":[{"value":"100000000","n":0,"addresses":["mfcWp7DB6NuaZsExybTTXpVgWz559Np4Ti"],"isAddress":true},{"value":"12345","n":1,"spent":true,"addresses":["mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz"],"isAddress":true},{"value":"12345","n":2,"addresses":["mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz"],"isAddress":true}],"blockHash":"0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997","blockHeight":225493,"confirmations":2,"blockTime":1521515026,"value":"100024690","valueIn":"0","fees":"0"},{"txid":"effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75","vin":[],"vout":[{"value":"1234567890123","n":0,"spent":true,"addresses":["mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw"],"isAddress":true},{"value":"1","n":1,"spent":true,"addresses":["2MzmAKayJmja784jyHvRUW1bXPget1csRRG"],"isAddress":true},{"value":"9876","n":2,"spent":true,"addresses":["2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1"],"isAddress":true}],"blockHash":"0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997","blockHeight":225493,"confirmations":2,"blockTime":1521515026,"value":"1234567900000","valueIn":"0","fees":"0"}]}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "apiGetRawBlock",
|
||||||
|
r: newGetRequest(ts.URL + "/api/v2/rawblock/225493"),
|
||||||
|
status: http.StatusOK,
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
body: []string{
|
||||||
|
`{"hex":"00e0ff3fd42677a86f1515bafcf9802c1765e02226655a9b97fd44132602000000000000"}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|||||||
@ -136,6 +136,11 @@ func getTxInBlock(b *bchain.Block, txid string) *bchain.Tx {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *fakeBlockChain) GetBlockRaw(hash string) (string, error) {
|
||||||
|
return "00e0ff3fd42677a86f1515bafcf9802c1765e02226655a9b97fd44132602000000000000", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func (c *fakeBlockChain) GetTransaction(txid string) (v *bchain.Tx, err error) {
|
func (c *fakeBlockChain) GetTransaction(txid string) (v *bchain.Tx, err error) {
|
||||||
v = getTxInBlock(GetTestBitcoinTypeBlock1(c.Parser), txid)
|
v = getTxInBlock(GetTestBitcoinTypeBlock1(c.Parser), txid)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user