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