github.com/bchainhub/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 }