github.com/cerberus-wallet/blockbook@v0.3.2/bchain/coins/bitcore/bitcorerpc.go (about)

     1  package bitcore
     2  
     3  import (
     4  	"blockbook/bchain"
     5  	"blockbook/bchain/coins/btc"
     6  	"encoding/json"
     7  	"github.com/golang/glog"
     8  	"github.com/juju/errors"
     9  )
    10  
    11  // BitcoreRPC is an interface to JSON-RPC bitcoind service.
    12  type BitcoreRPC struct {
    13  	*btc.BitcoinRPC
    14  }
    15  
    16  // NewBitcoreRPC returns new BitcoreRPC instance.
    17  func NewBitcoreRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) {
    18  	b, err := btc.NewBitcoinRPC(config, pushHandler)
    19  	if err != nil {
    20  		return nil, err
    21  	}
    22  
    23  	s := &BitcoreRPC{
    24  		b.(*btc.BitcoinRPC),
    25  	}
    26  	s.RPCMarshaler = btc.JSONMarshalerV2{}
    27  	s.ChainConfig.SupportsEstimateFee = false
    28  
    29  	return s, nil
    30  }
    31  
    32  // Initialize initializes BitcoreRPC instance.
    33  func (b *BitcoreRPC) Initialize() error {
    34  	ci, err := b.GetChainInfo()
    35  	if err != nil {
    36  		return err
    37  	}
    38  	chainName := ci.Chain
    39  	glog.Info("Chain name ", chainName)
    40  	params := GetChainParams(chainName)
    41  
    42  	// always create parser
    43  	b.Parser = NewBitcoreParser(params, b.ChainConfig)
    44  
    45  	// parameters for getInfo request
    46  	if params.Net == MainnetMagic {
    47  		b.Testnet = false
    48  		b.Network = "livenet"
    49  	} else {
    50  		b.Testnet = true
    51  		b.Network = "testnet"
    52  	}
    53  
    54  	glog.Info("rpc: block chain ", params.Name)
    55  
    56  	return nil
    57  }
    58  
    59  // GetBlock returns block with given hash.
    60  
    61  func (f *BitcoreRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
    62  	var err error
    63  	if hash == "" {
    64  		hash, err = f.GetBlockHash(height)
    65  		if err != nil {
    66  			return nil, err
    67  		}
    68  	}
    69  	if !f.ParseBlocks {
    70  		return f.GetBlockFull(hash)
    71  	}
    72  	// optimization
    73  	if height > 0 {
    74  		return f.GetBlockWithoutHeader(hash, height)
    75  	}
    76  	header, err := f.GetBlockHeader(hash)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	data, err := f.GetBlockRaw(hash)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  	block, err := f.Parser.ParseBlock(data)
    85  	if err != nil {
    86  		return nil, errors.Annotatef(err, "hash %v", hash)
    87  	}
    88  	block.BlockHeader = *header
    89  	return block, nil
    90  }
    91  
    92  // GetBlockFull returns block with given hash
    93  func (f *BitcoreRPC) GetBlockFull(hash string) (*bchain.Block, error) {
    94  	glog.V(1).Info("rpc: getblock (verbosity=2) ", hash)
    95  
    96  	res := btc.ResGetBlockFull{}
    97  	req := btc.CmdGetBlock{Method: "getblock"}
    98  	req.Params.BlockHash = hash
    99  	req.Params.Verbosity = 2
   100  	err := f.Call(&req, &res)
   101  
   102  	if err != nil {
   103  		return nil, errors.Annotatef(err, "hash %v", hash)
   104  	}
   105  	if res.Error != nil {
   106  		if btc.IsErrBlockNotFound(res.Error) {
   107  			return nil, bchain.ErrBlockNotFound
   108  		}
   109  		return nil, errors.Annotatef(res.Error, "hash %v", hash)
   110  	}
   111  
   112  	for i := range res.Result.Txs {
   113  		tx := &res.Result.Txs[i]
   114  		for j := range tx.Vout {
   115  			vout := &tx.Vout[j]
   116  			// convert vout.JsonValue to big.Int and clear it, it is only temporary value used for unmarshal
   117  			vout.ValueSat, err = f.Parser.AmountToBigInt(vout.JsonValue)
   118  			if err != nil {
   119  				return nil, err
   120  			}
   121  			vout.JsonValue = ""
   122  		}
   123  	}
   124  
   125  	return &res.Result, nil
   126  }
   127  
   128  // GetTransactionForMempool returns a transaction by the transaction ID.
   129  // It could be optimized for mempool, i.e. without block time and confirmations
   130  func (f *BitcoreRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
   131  	return f.GetTransaction(txid)
   132  }