Detect type of the block chain and use correct chain params
This commit is contained in:
parent
cac412527d
commit
0783cac294
@ -11,6 +11,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/juju/errors"
|
"github.com/juju/errors"
|
||||||
)
|
)
|
||||||
@ -60,6 +62,22 @@ type resGetBlockCount struct {
|
|||||||
Result uint32 `json:"result"`
|
Result uint32 `json:"result"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getblockchaininfo
|
||||||
|
|
||||||
|
type cmdGetBlockChainInfo struct {
|
||||||
|
Method string `json:"method"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type resGetBlockChainInfo struct {
|
||||||
|
Error *RPCError `json:"error"`
|
||||||
|
Result struct {
|
||||||
|
Chain string `json:"chain"`
|
||||||
|
Blocks int `json:"blocks"`
|
||||||
|
Headers int `json:"headers"`
|
||||||
|
Bestblockhash string `json:"bestblockhash"`
|
||||||
|
} `json:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
// getrawmempool
|
// getrawmempool
|
||||||
|
|
||||||
type cmdGetMempool struct {
|
type cmdGetMempool struct {
|
||||||
@ -166,32 +184,50 @@ type resSendRawTransaction struct {
|
|||||||
Result string `json:"result"`
|
Result string `json:"result"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlockParser interface {
|
|
||||||
ParseBlock(b []byte) (*Block, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BitcoinRPC is an interface to JSON-RPC bitcoind service.
|
// BitcoinRPC is an interface to JSON-RPC bitcoind service.
|
||||||
type BitcoinRPC struct {
|
type BitcoinRPC struct {
|
||||||
client http.Client
|
client http.Client
|
||||||
URL string
|
URL string
|
||||||
User string
|
User string
|
||||||
Password string
|
Password string
|
||||||
Parser BlockParser
|
Parser *BitcoinBlockParser
|
||||||
|
Testnet bool
|
||||||
|
Network string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBitcoinRPC returns new BitcoinRPC instance.
|
// NewBitcoinRPC returns new BitcoinRPC instance.
|
||||||
func NewBitcoinRPC(url string, user string, password string, timeout time.Duration) *BitcoinRPC {
|
func NewBitcoinRPC(url string, user string, password string, timeout time.Duration, parse bool) (*BitcoinRPC, error) {
|
||||||
transport := &http.Transport{
|
transport := &http.Transport{
|
||||||
Dial: (&net.Dialer{KeepAlive: 600 * time.Second}).Dial,
|
Dial: (&net.Dialer{KeepAlive: 600 * time.Second}).Dial,
|
||||||
MaxIdleConns: 100,
|
MaxIdleConns: 100,
|
||||||
MaxIdleConnsPerHost: 100, // necessary to not to deplete ports
|
MaxIdleConnsPerHost: 100, // necessary to not to deplete ports
|
||||||
}
|
}
|
||||||
return &BitcoinRPC{
|
s := &BitcoinRPC{
|
||||||
client: http.Client{Timeout: timeout, Transport: transport},
|
client: http.Client{Timeout: timeout, Transport: transport},
|
||||||
URL: url,
|
URL: url,
|
||||||
User: user,
|
User: user,
|
||||||
Password: password,
|
Password: password,
|
||||||
}
|
}
|
||||||
|
chain, err := s.GetBlockChainInfo()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// always create parser
|
||||||
|
s.Parser = &BitcoinBlockParser{
|
||||||
|
Params: GetChainParams(chain),
|
||||||
|
}
|
||||||
|
|
||||||
|
// parameters for getInfo request
|
||||||
|
if s.Parser.Params.Net == wire.MainNet {
|
||||||
|
s.Testnet = false
|
||||||
|
s.Network = "livenet"
|
||||||
|
} else {
|
||||||
|
s.Testnet = true
|
||||||
|
s.Network = "testnet"
|
||||||
|
}
|
||||||
|
glog.Info("rpc: block chain ", s.Parser.Params.Name)
|
||||||
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBestBlockHash returns hash of the tip of the best-block-chain.
|
// GetBestBlockHash returns hash of the tip of the best-block-chain.
|
||||||
@ -229,6 +265,23 @@ func (b *BitcoinRPC) GetBestBlockHeight() (uint32, error) {
|
|||||||
return res.Result, nil
|
return res.Result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBlockChainInfo returns the name of the block chain: main/test/regtest.
|
||||||
|
func (b *BitcoinRPC) GetBlockChainInfo() (string, error) {
|
||||||
|
glog.V(1).Info("rpc: getblockchaininfo")
|
||||||
|
|
||||||
|
res := resGetBlockChainInfo{}
|
||||||
|
req := cmdGetBlockChainInfo{Method: "getblockchaininfo"}
|
||||||
|
err := b.call(&req, &res)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if res.Error != nil {
|
||||||
|
return "", res.Error
|
||||||
|
}
|
||||||
|
return res.Result.Chain, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetBlockHash returns hash of block in best-block-chain at given height.
|
// GetBlockHash returns hash of block in best-block-chain at given height.
|
||||||
func (b *BitcoinRPC) GetBlockHash(height uint32) (string, error) {
|
func (b *BitcoinRPC) GetBlockHash(height uint32) (string, error) {
|
||||||
glog.V(1).Info("rpc: getblockhash ", height)
|
glog.V(1).Info("rpc: getblockhash ", height)
|
||||||
|
|||||||
@ -15,13 +15,14 @@ import (
|
|||||||
// GetChainParams contains network parameters for the main Bitcoin network,
|
// GetChainParams contains network parameters for the main Bitcoin network,
|
||||||
// the regression test Bitcoin network, the test Bitcoin network and
|
// the regression test Bitcoin network, the test Bitcoin network and
|
||||||
// the simulation test Bitcoin network, in this order
|
// the simulation test Bitcoin network, in this order
|
||||||
func GetChainParams() []*chaincfg.Params {
|
func GetChainParams(chain string) *chaincfg.Params {
|
||||||
return []*chaincfg.Params{
|
switch chain {
|
||||||
&chaincfg.MainNetParams,
|
case "test":
|
||||||
&chaincfg.RegressionNetParams,
|
return &chaincfg.TestNet3Params
|
||||||
&chaincfg.TestNet3Params,
|
case "regtest":
|
||||||
&chaincfg.SimNetParams,
|
return &chaincfg.RegressionNetParams
|
||||||
}
|
}
|
||||||
|
return &chaincfg.MainNetParams
|
||||||
}
|
}
|
||||||
|
|
||||||
type BitcoinBlockParser struct {
|
type BitcoinBlockParser struct {
|
||||||
@ -29,8 +30,8 @@ type BitcoinBlockParser struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddressToOutputScript converts bitcoin address to ScriptPubKey
|
// AddressToOutputScript converts bitcoin address to ScriptPubKey
|
||||||
func AddressToOutputScript(address string) ([]byte, error) {
|
func (p *BitcoinBlockParser) AddressToOutputScript(address string) ([]byte, error) {
|
||||||
da, err := btcutil.DecodeAddress(address, GetChainParams()[0])
|
da, err := btcutil.DecodeAddress(address, p.Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -42,8 +43,8 @@ func AddressToOutputScript(address string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OutputScriptToAddresses converts ScriptPubKey to bitcoin addresses
|
// OutputScriptToAddresses converts ScriptPubKey to bitcoin addresses
|
||||||
func OutputScriptToAddresses(script []byte) ([]string, error) {
|
func (p *BitcoinBlockParser) OutputScriptToAddresses(script []byte) ([]string, error) {
|
||||||
_, addresses, _, err := txscript.ExtractPkScriptAddrs(script, GetChainParams()[0])
|
_, addresses, _, err := txscript.ExtractPkScriptAddrs(script, p.Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -55,18 +56,18 @@ func OutputScriptToAddresses(script []byte) ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParseTx parses byte array containing transaction and returns Tx struct
|
// ParseTx parses byte array containing transaction and returns Tx struct
|
||||||
func ParseTx(b []byte) (*Tx, error) {
|
func (p *BitcoinBlockParser) ParseTx(b []byte) (*Tx, error) {
|
||||||
t := wire.MsgTx{}
|
t := wire.MsgTx{}
|
||||||
r := bytes.NewReader(b)
|
r := bytes.NewReader(b)
|
||||||
if err := t.Deserialize(r); err != nil {
|
if err := t.Deserialize(r); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tx := txFromMsgTx(&t, true)
|
tx := p.txFromMsgTx(&t, true)
|
||||||
tx.Hex = hex.EncodeToString(b)
|
tx.Hex = hex.EncodeToString(b)
|
||||||
return &tx, nil
|
return &tx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func txFromMsgTx(t *wire.MsgTx, parseAddresses bool) Tx {
|
func (p *BitcoinBlockParser) txFromMsgTx(t *wire.MsgTx, parseAddresses bool) Tx {
|
||||||
vin := make([]Vin, len(t.TxIn))
|
vin := make([]Vin, len(t.TxIn))
|
||||||
for i, in := range t.TxIn {
|
for i, in := range t.TxIn {
|
||||||
if blockchain.IsCoinBaseTx(t) {
|
if blockchain.IsCoinBaseTx(t) {
|
||||||
@ -91,7 +92,7 @@ func txFromMsgTx(t *wire.MsgTx, parseAddresses bool) Tx {
|
|||||||
for i, out := range t.TxOut {
|
for i, out := range t.TxOut {
|
||||||
addrs := []string{}
|
addrs := []string{}
|
||||||
if parseAddresses {
|
if parseAddresses {
|
||||||
addrs, _ = OutputScriptToAddresses(out.PkScript)
|
addrs, _ = p.OutputScriptToAddresses(out.PkScript)
|
||||||
}
|
}
|
||||||
s := ScriptPubKey{
|
s := ScriptPubKey{
|
||||||
Hex: hex.EncodeToString(out.PkScript),
|
Hex: hex.EncodeToString(out.PkScript),
|
||||||
@ -130,7 +131,7 @@ func (p *BitcoinBlockParser) ParseBlock(b []byte) (*Block, error) {
|
|||||||
|
|
||||||
txs := make([]Tx, len(w.Transactions))
|
txs := make([]Tx, len(w.Transactions))
|
||||||
for ti, t := range w.Transactions {
|
for ti, t := range w.Transactions {
|
||||||
txs[ti] = txFromMsgTx(t, false)
|
txs[ti] = p.txFromMsgTx(t, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Block{Txs: txs}, nil
|
return &Block{Txs: txs}, nil
|
||||||
|
|||||||
@ -41,9 +41,11 @@ func TestAddressToOutputScript(t *testing.T) {
|
|||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
parser := &BitcoinBlockParser{Params: GetChainParams("main")}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
got, err := AddressToOutputScript(tt.args.address)
|
got, err := parser.AddressToOutputScript(tt.args.address)
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Errorf("AddressToOutputScript() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("AddressToOutputScript() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
return
|
return
|
||||||
@ -91,10 +93,11 @@ func TestOutputScriptToAddresses(t *testing.T) {
|
|||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
parser := &BitcoinBlockParser{Params: GetChainParams("main")}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
b, _ := hex.DecodeString(tt.args.script)
|
b, _ := hex.DecodeString(tt.args.script)
|
||||||
got, err := OutputScriptToAddresses(b)
|
got, err := parser.OutputScriptToAddresses(b)
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Errorf("OutputScriptToAddresses() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("OutputScriptToAddresses() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
return
|
return
|
||||||
|
|||||||
20
blockbook.go
20
blockbook.go
@ -102,22 +102,14 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
chain = bchain.NewBitcoinRPC(
|
var err error
|
||||||
*rpcURL,
|
if chain, err = bchain.NewBitcoinRPC(*rpcURL, *rpcUser, *rpcPass, time.Duration(*rpcTimeout)*time.Second, *parse); err != nil {
|
||||||
*rpcUser,
|
glog.Fatal("NewBitcoinRPC ", err)
|
||||||
*rpcPass,
|
|
||||||
time.Duration(*rpcTimeout)*time.Second)
|
|
||||||
|
|
||||||
if *parse {
|
|
||||||
chain.Parser = &bchain.BitcoinBlockParser{
|
|
||||||
Params: bchain.GetChainParams()[0],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mempool = bchain.NewMempool(chain)
|
mempool = bchain.NewMempool(chain)
|
||||||
|
|
||||||
var err error
|
index, err = db.NewRocksDB(*dbPath, chain.Parser)
|
||||||
index, err = db.NewRocksDB(*dbPath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("NewRocksDB %v", err)
|
glog.Fatalf("NewRocksDB %v", err)
|
||||||
}
|
}
|
||||||
@ -164,7 +156,7 @@ func main() {
|
|||||||
|
|
||||||
var httpServer *server.HTTPServer
|
var httpServer *server.HTTPServer
|
||||||
if *httpServerBinding != "" {
|
if *httpServerBinding != "" {
|
||||||
httpServer, err = server.NewHTTPServer(*httpServerBinding, *certFiles, index, mempool)
|
httpServer, err = server.NewHTTPServer(*httpServerBinding, *certFiles, index, mempool, chain, txCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error("https: ", err)
|
glog.Error("https: ", err)
|
||||||
return
|
return
|
||||||
@ -232,7 +224,7 @@ func main() {
|
|||||||
address := *queryAddress
|
address := *queryAddress
|
||||||
|
|
||||||
if address != "" {
|
if address != "" {
|
||||||
script, err := bchain.AddressToOutputScript(address)
|
script, err := chain.Parser.AddressToOutputScript(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error("GetTransactions ", err)
|
glog.Error("GetTransactions ", err)
|
||||||
return
|
return
|
||||||
|
|||||||
@ -29,11 +29,12 @@ func RepairRocksDB(name string) error {
|
|||||||
|
|
||||||
// RocksDB handle
|
// RocksDB handle
|
||||||
type RocksDB struct {
|
type RocksDB struct {
|
||||||
path string
|
path string
|
||||||
db *gorocksdb.DB
|
db *gorocksdb.DB
|
||||||
wo *gorocksdb.WriteOptions
|
wo *gorocksdb.WriteOptions
|
||||||
ro *gorocksdb.ReadOptions
|
ro *gorocksdb.ReadOptions
|
||||||
cfh []*gorocksdb.ColumnFamilyHandle
|
cfh []*gorocksdb.ColumnFamilyHandle
|
||||||
|
chainParser *bchain.BitcoinBlockParser
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -93,13 +94,13 @@ func openDB(path string) (*gorocksdb.DB, []*gorocksdb.ColumnFamilyHandle, error)
|
|||||||
|
|
||||||
// NewRocksDB opens an internal handle to RocksDB environment. Close
|
// NewRocksDB opens an internal handle to RocksDB environment. Close
|
||||||
// needs to be called to release it.
|
// needs to be called to release it.
|
||||||
func NewRocksDB(path string) (d *RocksDB, err error) {
|
func NewRocksDB(path string, parser *bchain.BitcoinBlockParser) (d *RocksDB, err error) {
|
||||||
glog.Infof("rocksdb: open %s", path)
|
glog.Infof("rocksdb: open %s", path)
|
||||||
db, cfh, err := openDB(path)
|
db, cfh, err := openDB(path)
|
||||||
wo := gorocksdb.NewDefaultWriteOptions()
|
wo := gorocksdb.NewDefaultWriteOptions()
|
||||||
ro := gorocksdb.NewDefaultReadOptions()
|
ro := gorocksdb.NewDefaultReadOptions()
|
||||||
ro.SetFillCache(false)
|
ro.SetFillCache(false)
|
||||||
return &RocksDB{path, db, wo, ro, cfh}, nil
|
return &RocksDB{path, db, wo, ro, cfh, parser}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *RocksDB) closeDB() error {
|
func (d *RocksDB) closeDB() error {
|
||||||
@ -541,7 +542,7 @@ func (d *RocksDB) GetTx(txid string) (*bchain.Tx, uint32, error) {
|
|||||||
defer val.Free()
|
defer val.Free()
|
||||||
data := val.Data()
|
data := val.Data()
|
||||||
if len(data) > 4 {
|
if len(data) > 4 {
|
||||||
return unpackTx(data)
|
return unpackTx(data, d.chainParser)
|
||||||
}
|
}
|
||||||
return nil, 0, nil
|
return nil, 0, nil
|
||||||
}
|
}
|
||||||
@ -649,10 +650,10 @@ func packTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) {
|
|||||||
return buf, err
|
return buf, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
func unpackTx(buf []byte, parser *bchain.BitcoinBlockParser) (*bchain.Tx, uint32, error) {
|
||||||
height := unpackUint(buf)
|
height := unpackUint(buf)
|
||||||
bt, l := unpackVarint64(buf[4:])
|
bt, l := unpackVarint64(buf[4:])
|
||||||
tx, err := bchain.ParseTx(buf[4+l:])
|
tx, err := parser.ParseTx(buf[4+l:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -120,6 +120,7 @@ func Test_packTx(t *testing.T) {
|
|||||||
func Test_unpackTx(t *testing.T) {
|
func Test_unpackTx(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
packedTx string
|
packedTx string
|
||||||
|
parser *bchain.BitcoinBlockParser
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@ -129,16 +130,21 @@ func Test_unpackTx(t *testing.T) {
|
|||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "btc-1",
|
name: "btc-1",
|
||||||
args: args{packedTx: testTxPacked1},
|
args: args{
|
||||||
|
packedTx: testTxPacked1,
|
||||||
|
parser: &bchain.BitcoinBlockParser{Params: bchain.GetChainParams("main")},
|
||||||
|
},
|
||||||
want: &testTx1,
|
want: &testTx1,
|
||||||
want1: 123456,
|
want1: 123456,
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
// this test fails now, needs testnet chaincfg.TestNet3Params
|
|
||||||
{
|
{
|
||||||
name: "testnet-1",
|
name: "testnet-1",
|
||||||
args: args{packedTx: testTxPacked2},
|
args: args{
|
||||||
|
packedTx: testTxPacked2,
|
||||||
|
parser: &bchain.BitcoinBlockParser{Params: bchain.GetChainParams("test")},
|
||||||
|
},
|
||||||
want: &testTx2,
|
want: &testTx2,
|
||||||
want1: 510234,
|
want1: 510234,
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
@ -147,7 +153,7 @@ func Test_unpackTx(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
b, _ := hex.DecodeString(tt.args.packedTx)
|
b, _ := hex.DecodeString(tt.args.packedTx)
|
||||||
got, got1, err := unpackTx(b)
|
got, got1, err := unpackTx(b, tt.args.parser)
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Errorf("unpackTx() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("unpackTx() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
return
|
return
|
||||||
|
|||||||
@ -21,11 +21,13 @@ type HTTPServer struct {
|
|||||||
https *http.Server
|
https *http.Server
|
||||||
certFiles string
|
certFiles string
|
||||||
db *db.RocksDB
|
db *db.RocksDB
|
||||||
|
txCache *db.TxCache
|
||||||
mempool *bchain.Mempool
|
mempool *bchain.Mempool
|
||||||
|
chain *bchain.BitcoinRPC
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHTTPServer creates new REST interface to blockbook and returns its handle
|
// NewHTTPServer creates new REST interface to blockbook and returns its handle
|
||||||
func NewHTTPServer(httpServerBinding string, certFiles string, db *db.RocksDB, mempool *bchain.Mempool) (*HTTPServer, error) {
|
func NewHTTPServer(httpServerBinding string, certFiles string, db *db.RocksDB, mempool *bchain.Mempool, chain *bchain.BitcoinRPC, txCache *db.TxCache) (*HTTPServer, error) {
|
||||||
https := &http.Server{
|
https := &http.Server{
|
||||||
Addr: httpServerBinding,
|
Addr: httpServerBinding,
|
||||||
}
|
}
|
||||||
@ -33,7 +35,9 @@ func NewHTTPServer(httpServerBinding string, certFiles string, db *db.RocksDB, m
|
|||||||
https: https,
|
https: https,
|
||||||
certFiles: certFiles,
|
certFiles: certFiles,
|
||||||
db: db,
|
db: db,
|
||||||
|
txCache: txCache,
|
||||||
mempool: mempool,
|
mempool: mempool,
|
||||||
|
chain: chain,
|
||||||
}
|
}
|
||||||
|
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
@ -129,14 +133,14 @@ func (s *HTTPServer) blockHash(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAddress(r *http.Request) (address string, script []byte, err error) {
|
func (s *HTTPServer) getAddress(r *http.Request) (address string, script []byte, err error) {
|
||||||
address = mux.Vars(r)["address"]
|
address = mux.Vars(r)["address"]
|
||||||
script, err = bchain.AddressToOutputScript(address)
|
script, err = s.chain.Parser.AddressToOutputScript(address)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAddressAndHeightRange(r *http.Request) (address string, script []byte, lower, higher uint32, err error) {
|
func (s *HTTPServer) getAddressAndHeightRange(r *http.Request) (address string, script []byte, lower, higher uint32, err error) {
|
||||||
address, script, err = getAddress(r)
|
address, script, err = s.getAddress(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -156,7 +160,7 @@ type transactionList struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *HTTPServer) unconfirmedTransactions(w http.ResponseWriter, r *http.Request) {
|
func (s *HTTPServer) unconfirmedTransactions(w http.ResponseWriter, r *http.Request) {
|
||||||
address, script, err := getAddress(r)
|
address, script, err := s.getAddress(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
respondError(w, err, fmt.Sprint("unconfirmedTransactions for address", address))
|
respondError(w, err, fmt.Sprint("unconfirmedTransactions for address", address))
|
||||||
}
|
}
|
||||||
@ -169,7 +173,7 @@ func (s *HTTPServer) unconfirmedTransactions(w http.ResponseWriter, r *http.Requ
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *HTTPServer) confirmedTransactions(w http.ResponseWriter, r *http.Request) {
|
func (s *HTTPServer) confirmedTransactions(w http.ResponseWriter, r *http.Request) {
|
||||||
address, script, lower, higher, err := getAddressAndHeightRange(r)
|
address, script, lower, higher, err := s.getAddressAndHeightRange(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
respondError(w, err, fmt.Sprint("confirmedTransactions for address", address))
|
respondError(w, err, fmt.Sprint("confirmedTransactions for address", address))
|
||||||
}
|
}
|
||||||
@ -185,7 +189,7 @@ func (s *HTTPServer) confirmedTransactions(w http.ResponseWriter, r *http.Reques
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *HTTPServer) transactions(w http.ResponseWriter, r *http.Request) {
|
func (s *HTTPServer) transactions(w http.ResponseWriter, r *http.Request) {
|
||||||
address, script, lower, higher, err := getAddressAndHeightRange(r)
|
address, script, lower, higher, err := s.getAddressAndHeightRange(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
respondError(w, err, fmt.Sprint("transactions for address", address))
|
respondError(w, err, fmt.Sprint("transactions for address", address))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -241,7 +241,7 @@ func (s *SocketIoServer) getAddressTxids(addr []string, rr *reqRange) (res resul
|
|||||||
txids := make([]string, 0)
|
txids := make([]string, 0)
|
||||||
lower, higher := uint32(rr.To), uint32(rr.Start)
|
lower, higher := uint32(rr.To), uint32(rr.Start)
|
||||||
for _, address := range addr {
|
for _, address := range addr {
|
||||||
script, err := bchain.AddressToOutputScript(address)
|
script, err := s.chain.Parser.AddressToOutputScript(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
@ -558,19 +558,19 @@ func (s *SocketIoServer) estimateSmartFee(blocks int, conservative bool) (res re
|
|||||||
|
|
||||||
type resultGetInfo struct {
|
type resultGetInfo struct {
|
||||||
Result struct {
|
Result struct {
|
||||||
Version int `json:"version"`
|
Version int `json:"version,omitempty"`
|
||||||
ProtocolVersion int `json:"protocolVersion"`
|
ProtocolVersion int `json:"protocolVersion,omitempty"`
|
||||||
Blocks int `json:"blocks"`
|
Blocks int `json:"blocks"`
|
||||||
TimeOffset int `json:"timeOffset"`
|
TimeOffset int `json:"timeOffset,omitempty"`
|
||||||
Connections int `json:"connections"`
|
Connections int `json:"connections,omitempty"`
|
||||||
Proxy string `json:"proxy"`
|
Proxy string `json:"proxy,omitempty"`
|
||||||
Difficulty float64 `json:"difficulty"`
|
Difficulty float64 `json:"difficulty,omitempty"`
|
||||||
Testnet bool `json:"testnet"`
|
Testnet bool `json:"testnet"`
|
||||||
RelayFee float64 `json:"relayFee"`
|
RelayFee float64 `json:"relayFee,omitempty"`
|
||||||
Errors string `json:"errors"`
|
Errors string `json:"errors,omitempty"`
|
||||||
Network string `json:"network"`
|
Network string `json:"network,omitempty"`
|
||||||
Subversion string `json:"subversion"`
|
Subversion string `json:"subversion,omitempty"`
|
||||||
LocalServices string `json:"localServices"`
|
LocalServices string `json:"localServices,omitempty"`
|
||||||
} `json:"result"`
|
} `json:"result"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user