github.com/aychain/blockbook@v0.1.1-0.20181121092459-6d1fc7e07c5b/bchain/coins/grs/grsrpc.go (about) 1 package grs 2 3 import ( 4 "blockbook/bchain" 5 "blockbook/bchain/coins/btc" 6 "encoding/json" 7 8 "github.com/golang/glog" 9 "github.com/juju/errors" 10 ) 11 12 type GroestlcoinRPC struct { 13 *btc.BitcoinRPC 14 } 15 16 func NewGroestlcoinRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) { 17 b, err := btc.NewBitcoinRPC(config, pushHandler) 18 if err != nil { 19 return nil, err 20 } 21 g := &GroestlcoinRPC{ 22 BitcoinRPC: b.(*btc.BitcoinRPC), 23 } 24 g.RPCMarshaler = btc.JSONMarshalerV1{} 25 return g, nil 26 } 27 28 // Initialize initializes GroestlcoinRPC instance. 29 func (g *GroestlcoinRPC) Initialize() error { 30 chainName, err := g.GetChainInfoAndInitializeMempool(g) 31 if err != nil { 32 return err 33 } 34 35 params := GetChainParams(chainName) 36 37 g.Parser = NewGroestlcoinParser(params, g.ChainConfig) 38 39 // parameters for getInfo request 40 if params.Net == MainnetMagic { 41 g.Testnet = false 42 g.Network = "livenet" 43 } else { 44 g.Testnet = true 45 g.Network = "testnet" 46 } 47 48 glog.Info("rpc: block chain ", params.Name) 49 50 return nil 51 } 52 53 // GetBlock returns block with given hash. 54 func (g *GroestlcoinRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) { 55 var err error 56 if hash == "" && height > 0 { 57 hash, err = g.GetBlockHash(height) 58 if err != nil { 59 return nil, err 60 } 61 } 62 63 glog.V(1).Info("rpc: getblock (verbosity=1) ", hash) 64 65 res := btc.ResGetBlockThin{} 66 req := btc.CmdGetBlock{Method: "getblock"} 67 req.Params.BlockHash = hash 68 req.Params.Verbosity = 1 69 err = g.Call(&req, &res) 70 71 if err != nil { 72 return nil, errors.Annotatef(err, "hash %v", hash) 73 } 74 if res.Error != nil { 75 return nil, errors.Annotatef(res.Error, "hash %v", hash) 76 } 77 78 txs := make([]bchain.Tx, 0, len(res.Result.Txids)) 79 for _, txid := range res.Result.Txids { 80 tx, err := g.GetTransaction(txid) 81 if err != nil { 82 if isInvalidTx(err) { 83 glog.Errorf("rpc: getblock: skipping transanction in block %s due error: %s", hash, err) 84 continue 85 } 86 return nil, err 87 } 88 txs = append(txs, *tx) 89 } 90 block := &bchain.Block{ 91 BlockHeader: res.Result.BlockHeader, 92 Txs: txs, 93 } 94 return block, nil 95 } 96 97 func isInvalidTx(err error) bool { 98 switch e1 := err.(type) { 99 case *errors.Err: 100 switch e2 := e1.Cause().(type) { 101 case *bchain.RPCError: 102 if e2.Code == -5 { // "No information available about transaction" 103 return true 104 } 105 } 106 } 107 108 return false 109 } 110 111 // GetTransactionForMempool returns a transaction by the transaction ID. 112 // It could be optimized for mempool, i.e. without block time and confirmations 113 func (g *GroestlcoinRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) { 114 return g.GetTransaction(txid) 115 }