github.com/cryptohub-digital/blockbook@v0.3.5-0.20240403155730-99ab40b9104c/bchain/coins/blockchain.go (about) 1 package coins 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "math/big" 9 "reflect" 10 "time" 11 12 "github.com/cryptohub-digital/blockbook/bchain" 13 "github.com/cryptohub-digital/blockbook/bchain/coins/avalanche" 14 "github.com/cryptohub-digital/blockbook/bchain/coins/bch" 15 "github.com/cryptohub-digital/blockbook/bchain/coins/bellcoin" 16 "github.com/cryptohub-digital/blockbook/bchain/coins/bitcore" 17 "github.com/cryptohub-digital/blockbook/bchain/coins/bitzeny" 18 "github.com/cryptohub-digital/blockbook/bchain/coins/bsc" 19 "github.com/cryptohub-digital/blockbook/bchain/coins/btc" 20 "github.com/cryptohub-digital/blockbook/bchain/coins/btg" 21 "github.com/cryptohub-digital/blockbook/bchain/coins/cpuchain" 22 "github.com/cryptohub-digital/blockbook/bchain/coins/dash" 23 "github.com/cryptohub-digital/blockbook/bchain/coins/dcr" 24 "github.com/cryptohub-digital/blockbook/bchain/coins/deeponion" 25 "github.com/cryptohub-digital/blockbook/bchain/coins/digibyte" 26 "github.com/cryptohub-digital/blockbook/bchain/coins/divi" 27 "github.com/cryptohub-digital/blockbook/bchain/coins/dogecoin" 28 "github.com/cryptohub-digital/blockbook/bchain/coins/ecash" 29 "github.com/cryptohub-digital/blockbook/bchain/coins/eth" 30 "github.com/cryptohub-digital/blockbook/bchain/coins/firo" 31 "github.com/cryptohub-digital/blockbook/bchain/coins/flo" 32 "github.com/cryptohub-digital/blockbook/bchain/coins/fujicoin" 33 "github.com/cryptohub-digital/blockbook/bchain/coins/gamecredits" 34 "github.com/cryptohub-digital/blockbook/bchain/coins/grs" 35 "github.com/cryptohub-digital/blockbook/bchain/coins/koto" 36 "github.com/cryptohub-digital/blockbook/bchain/coins/liquid" 37 "github.com/cryptohub-digital/blockbook/bchain/coins/litecoin" 38 "github.com/cryptohub-digital/blockbook/bchain/coins/monacoin" 39 "github.com/cryptohub-digital/blockbook/bchain/coins/monetaryunit" 40 "github.com/cryptohub-digital/blockbook/bchain/coins/myriad" 41 "github.com/cryptohub-digital/blockbook/bchain/coins/namecoin" 42 "github.com/cryptohub-digital/blockbook/bchain/coins/nuls" 43 "github.com/cryptohub-digital/blockbook/bchain/coins/omotenashicoin" 44 "github.com/cryptohub-digital/blockbook/bchain/coins/pivx" 45 "github.com/cryptohub-digital/blockbook/bchain/coins/polis" 46 "github.com/cryptohub-digital/blockbook/bchain/coins/qtum" 47 "github.com/cryptohub-digital/blockbook/bchain/coins/ravencoin" 48 "github.com/cryptohub-digital/blockbook/bchain/coins/ritocoin" 49 "github.com/cryptohub-digital/blockbook/bchain/coins/snowgem" 50 "github.com/cryptohub-digital/blockbook/bchain/coins/trezarcoin" 51 "github.com/cryptohub-digital/blockbook/bchain/coins/unobtanium" 52 "github.com/cryptohub-digital/blockbook/bchain/coins/vertcoin" 53 "github.com/cryptohub-digital/blockbook/bchain/coins/viacoin" 54 "github.com/cryptohub-digital/blockbook/bchain/coins/vipstarcoin" 55 "github.com/cryptohub-digital/blockbook/bchain/coins/xcb" 56 "github.com/cryptohub-digital/blockbook/bchain/coins/zec" 57 58 "github.com/cryptohub-digital/blockbook/common" 59 "github.com/juju/errors" 60 ) 61 62 type blockChainFactory func(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) 63 64 // BlockChainFactories is a map of constructors of coin RPC interfaces 65 var BlockChainFactories = make(map[string]blockChainFactory) 66 67 func init() { 68 BlockChainFactories["Bitcoin"] = btc.NewBitcoinRPC 69 BlockChainFactories["Testnet"] = btc.NewBitcoinRPC 70 BlockChainFactories["Signet"] = btc.NewBitcoinRPC 71 BlockChainFactories["Regtest"] = btc.NewBitcoinRPC 72 BlockChainFactories["Zcash"] = zec.NewZCashRPC 73 BlockChainFactories["Zcash Testnet"] = zec.NewZCashRPC 74 BlockChainFactories["Ethereum"] = eth.NewEthereumRPC 75 BlockChainFactories["Ethereum Archive"] = eth.NewEthereumRPC 76 BlockChainFactories["Ethereum Classic"] = eth.NewEthereumRPC 77 BlockChainFactories["Ethereum Testnet Ropsten"] = eth.NewEthereumRPC 78 BlockChainFactories["Ethereum Testnet Ropsten Archive"] = eth.NewEthereumRPC 79 BlockChainFactories["Ethereum Testnet Goerli"] = eth.NewEthereumRPC 80 BlockChainFactories["Ethereum Testnet Goerli Archive"] = eth.NewEthereumRPC 81 BlockChainFactories["Ethereum Testnet Sepolia"] = eth.NewEthereumRPC 82 BlockChainFactories["Ethereum Testnet Sepolia Archive"] = eth.NewEthereumRPC 83 BlockChainFactories["Bcash"] = bch.NewBCashRPC 84 BlockChainFactories["Bcash Testnet"] = bch.NewBCashRPC 85 BlockChainFactories["Bgold"] = btg.NewBGoldRPC 86 BlockChainFactories["Bgold Testnet"] = btg.NewBGoldRPC 87 BlockChainFactories["Dash"] = dash.NewDashRPC 88 BlockChainFactories["Dash Testnet"] = dash.NewDashRPC 89 BlockChainFactories["Decred"] = dcr.NewDecredRPC 90 BlockChainFactories["Decred Testnet"] = dcr.NewDecredRPC 91 BlockChainFactories["GameCredits"] = gamecredits.NewGameCreditsRPC 92 BlockChainFactories["Koto"] = koto.NewKotoRPC 93 BlockChainFactories["Koto Testnet"] = koto.NewKotoRPC 94 BlockChainFactories["Litecoin"] = litecoin.NewLitecoinRPC 95 BlockChainFactories["Litecoin Testnet"] = litecoin.NewLitecoinRPC 96 BlockChainFactories["Dogecoin"] = dogecoin.NewDogecoinRPC 97 BlockChainFactories["Dogecoin Testnet"] = dogecoin.NewDogecoinRPC 98 BlockChainFactories["Vertcoin"] = vertcoin.NewVertcoinRPC 99 BlockChainFactories["Vertcoin Testnet"] = vertcoin.NewVertcoinRPC 100 BlockChainFactories["Namecoin"] = namecoin.NewNamecoinRPC 101 BlockChainFactories["Monacoin"] = monacoin.NewMonacoinRPC 102 BlockChainFactories["Monacoin Testnet"] = monacoin.NewMonacoinRPC 103 BlockChainFactories["MonetaryUnit"] = monetaryunit.NewMonetaryUnitRPC 104 BlockChainFactories["DigiByte"] = digibyte.NewDigiByteRPC 105 BlockChainFactories["DigiByte Testnet"] = digibyte.NewDigiByteRPC 106 BlockChainFactories["Myriad"] = myriad.NewMyriadRPC 107 BlockChainFactories["Liquid"] = liquid.NewLiquidRPC 108 BlockChainFactories["Groestlcoin"] = grs.NewGroestlcoinRPC 109 BlockChainFactories["Groestlcoin Testnet"] = grs.NewGroestlcoinRPC 110 BlockChainFactories["Groestlcoin Signet"] = grs.NewGroestlcoinRPC 111 BlockChainFactories["Groestlcoin Regtest"] = grs.NewGroestlcoinRPC 112 BlockChainFactories["PIVX"] = pivx.NewPivXRPC 113 BlockChainFactories["PIVX Testnet"] = pivx.NewPivXRPC 114 BlockChainFactories["Polis"] = polis.NewPolisRPC 115 BlockChainFactories["Firo"] = firo.NewFiroRPC 116 BlockChainFactories["Fujicoin"] = fujicoin.NewFujicoinRPC 117 BlockChainFactories["Flo"] = flo.NewFloRPC 118 BlockChainFactories["Bellcoin"] = bellcoin.NewBellcoinRPC 119 BlockChainFactories["Qtum"] = qtum.NewQtumRPC 120 BlockChainFactories["Viacoin"] = viacoin.NewViacoinRPC 121 BlockChainFactories["Qtum Testnet"] = qtum.NewQtumRPC 122 BlockChainFactories["NULS"] = nuls.NewNulsRPC 123 BlockChainFactories["VIPSTARCOIN"] = vipstarcoin.NewVIPSTARCOINRPC 124 BlockChainFactories["Flux"] = zec.NewZCashRPC 125 BlockChainFactories["Ravencoin"] = ravencoin.NewRavencoinRPC 126 BlockChainFactories["Ritocoin"] = ritocoin.NewRitocoinRPC 127 BlockChainFactories["Divi"] = divi.NewDiviRPC 128 BlockChainFactories["CPUchain"] = cpuchain.NewCPUchainRPC 129 BlockChainFactories["Unobtanium"] = unobtanium.NewUnobtaniumRPC 130 BlockChainFactories["DeepOnion"] = deeponion.NewDeepOnionRPC 131 BlockChainFactories["SnowGem"] = snowgem.NewSnowGemRPC 132 BlockChainFactories["Bitcore"] = bitcore.NewBitcoreRPC 133 BlockChainFactories["Omotenashicoin"] = omotenashicoin.NewOmotenashiCoinRPC 134 BlockChainFactories["Omotenashicoin Testnet"] = omotenashicoin.NewOmotenashiCoinRPC 135 BlockChainFactories["BitZeny"] = bitzeny.NewBitZenyRPC 136 BlockChainFactories["Trezarcoin"] = trezarcoin.NewTrezarcoinRPC 137 BlockChainFactories["ECash"] = ecash.NewECashRPC 138 BlockChainFactories["Avalanche"] = avalanche.NewAvalancheRPC 139 BlockChainFactories["Avalanche Archive"] = avalanche.NewAvalancheRPC 140 BlockChainFactories["BNB Smart Chain"] = bsc.NewBNBSmartChainRPC 141 BlockChainFactories["BNB Smart Chain Archive"] = bsc.NewBNBSmartChainRPC 142 BlockChainFactories["Core Coin"] = xcb.NewCoreblockchainRPC 143 BlockChainFactories["Core Coin Testnet"] = xcb.NewCoreblockchainRPC 144 145 } 146 147 // GetCoinNameFromConfig gets coin name and coin shortcut from config file 148 func GetCoinNameFromConfig(configFileContent []byte) (string, string, string, error) { 149 var cn struct { 150 CoinName string `json:"coin_name"` 151 CoinShortcut string `json:"coin_shortcut"` 152 CoinLabel string `json:"coin_label"` 153 } 154 err := json.Unmarshal(configFileContent, &cn) 155 if err != nil { 156 return "", "", "", errors.Annotatef(err, "Error parsing config file ") 157 } 158 return cn.CoinName, cn.CoinShortcut, cn.CoinLabel, nil 159 } 160 161 // NewBlockChain creates bchain.BlockChain and bchain.Mempool for the coin passed by the parameter coin 162 func NewBlockChain(coin string, configfile string, pushHandler func(bchain.NotificationType), metrics *common.Metrics) (bchain.BlockChain, bchain.Mempool, error) { 163 data, err := ioutil.ReadFile(configfile) 164 if err != nil { 165 return nil, nil, errors.Annotatef(err, "Error reading file %v", configfile) 166 } 167 var config json.RawMessage 168 err = json.Unmarshal(data, &config) 169 if err != nil { 170 return nil, nil, errors.Annotatef(err, "Error parsing file %v", configfile) 171 } 172 bcf, ok := BlockChainFactories[coin] 173 if !ok { 174 return nil, nil, errors.New(fmt.Sprint("Unsupported coin '", coin, "'. Must be one of ", reflect.ValueOf(BlockChainFactories).MapKeys())) 175 } 176 bc, err := bcf(config, pushHandler) 177 if err != nil { 178 return nil, nil, err 179 } 180 err = bc.Initialize() 181 if err != nil { 182 return nil, nil, err 183 } 184 mempool, err := bc.CreateMempool(bc) 185 if err != nil { 186 return nil, nil, err 187 } 188 return &blockChainWithMetrics{b: bc, m: metrics}, &mempoolWithMetrics{mempool: mempool, m: metrics}, nil 189 } 190 191 type blockChainWithMetrics struct { 192 b bchain.BlockChain 193 m *common.Metrics 194 } 195 196 func (c *blockChainWithMetrics) observeRPCLatency(method string, start time.Time, err error) { 197 var e string 198 if err != nil { 199 e = "failure" 200 } 201 c.m.RPCLatency.With(common.Labels{"method": method, "error": e}).Observe(float64(time.Since(start)) / 1e6) // in milliseconds 202 } 203 204 func (c *blockChainWithMetrics) AddVerifiedSCData(contract *bchain.ContractInfo) *bchain.ContractInfo { 205 return c.b.AddVerifiedSCData(contract) 206 } 207 208 func (c *blockChainWithMetrics) FindVerifiedByName(query string) *bchain.AddressDescriptor { 209 return c.b.FindVerifiedByName(query) 210 } 211 212 func (c *blockChainWithMetrics) AddVerifiedAddressData(address bchain.AddressDescriptor) *bchain.VerifiedAddress { 213 return c.b.AddVerifiedAddressData(address) 214 } 215 216 func (c *blockChainWithMetrics) Initialize() error { 217 return c.b.Initialize() 218 } 219 220 func (c *blockChainWithMetrics) CreateMempool(chain bchain.BlockChain) (bchain.Mempool, error) { 221 return c.b.CreateMempool(chain) 222 } 223 224 func (c *blockChainWithMetrics) InitializeMempool(addrDescForOutpoint bchain.AddrDescForOutpointFunc, onNewTxAddr bchain.OnNewTxAddrFunc, onNewTx bchain.OnNewTxFunc) error { 225 return c.b.InitializeMempool(addrDescForOutpoint, onNewTxAddr, onNewTx) 226 } 227 228 func (c *blockChainWithMetrics) Shutdown(ctx context.Context) error { 229 return c.b.Shutdown(ctx) 230 } 231 232 func (c *blockChainWithMetrics) IsTestnet() bool { 233 return c.b.IsTestnet() 234 } 235 236 func (c *blockChainWithMetrics) GetNetworkName() string { 237 return c.b.GetNetworkName() 238 } 239 240 func (c *blockChainWithMetrics) GetCoinName() string { 241 return c.b.GetCoinName() 242 } 243 244 func (c *blockChainWithMetrics) GetSubversion() string { 245 return c.b.GetSubversion() 246 } 247 248 func (c *blockChainWithMetrics) GetChainInfo() (v *bchain.ChainInfo, err error) { 249 defer func(s time.Time) { c.observeRPCLatency("GetChainInfo", s, err) }(time.Now()) 250 return c.b.GetChainInfo() 251 } 252 253 func (c *blockChainWithMetrics) GetBestBlockHash() (v string, err error) { 254 defer func(s time.Time) { c.observeRPCLatency("GetBestBlockHash", s, err) }(time.Now()) 255 return c.b.GetBestBlockHash() 256 } 257 258 func (c *blockChainWithMetrics) GetBestBlockHeight() (v uint32, err error) { 259 defer func(s time.Time) { c.observeRPCLatency("GetBestBlockHeight", s, err) }(time.Now()) 260 return c.b.GetBestBlockHeight() 261 } 262 263 func (c *blockChainWithMetrics) GetBlockHash(height uint32) (v string, err error) { 264 defer func(s time.Time) { c.observeRPCLatency("GetBlockHash", s, err) }(time.Now()) 265 return c.b.GetBlockHash(height) 266 } 267 268 func (c *blockChainWithMetrics) GetBlockHeader(hash string) (v *bchain.BlockHeader, err error) { 269 defer func(s time.Time) { c.observeRPCLatency("GetBlockHeader", s, err) }(time.Now()) 270 return c.b.GetBlockHeader(hash) 271 } 272 273 func (c *blockChainWithMetrics) GetBlock(hash string, height uint32) (v *bchain.Block, err error) { 274 defer func(s time.Time) { c.observeRPCLatency("GetBlock", s, err) }(time.Now()) 275 return c.b.GetBlock(hash, height) 276 } 277 278 func (c *blockChainWithMetrics) GetBlockInfo(hash string) (v *bchain.BlockInfo, err error) { 279 defer func(s time.Time) { c.observeRPCLatency("GetBlockInfo", s, err) }(time.Now()) 280 return c.b.GetBlockInfo(hash) 281 } 282 283 func (c *blockChainWithMetrics) GetBlockRaw(hash string) (v string, err error) { 284 defer func(s time.Time) { c.observeRPCLatency("GetBlockRaw", s, err) }(time.Now()) 285 return c.b.GetBlockRaw(hash) 286 } 287 288 func (c *blockChainWithMetrics) GetMempoolTransactions() (v []string, err error) { 289 defer func(s time.Time) { c.observeRPCLatency("GetMempoolTransactions", s, err) }(time.Now()) 290 return c.b.GetMempoolTransactions() 291 } 292 293 func (c *blockChainWithMetrics) GetTransaction(txid string) (v *bchain.Tx, err error) { 294 defer func(s time.Time) { c.observeRPCLatency("GetTransaction", s, err) }(time.Now()) 295 return c.b.GetTransaction(txid) 296 } 297 298 func (c *blockChainWithMetrics) GetTransactionSpecific(tx *bchain.Tx) (v json.RawMessage, err error) { 299 defer func(s time.Time) { c.observeRPCLatency("GetTransactionSpecific", s, err) }(time.Now()) 300 return c.b.GetTransactionSpecific(tx) 301 } 302 303 func (c *blockChainWithMetrics) GetTransactionForMempool(txid string) (v *bchain.Tx, err error) { 304 defer func(s time.Time) { c.observeRPCLatency("GetTransactionForMempool", s, err) }(time.Now()) 305 return c.b.GetTransactionForMempool(txid) 306 } 307 308 func (c *blockChainWithMetrics) EstimateSmartFee(blocks int, conservative bool) (v big.Int, err error) { 309 defer func(s time.Time) { c.observeRPCLatency("EstimateSmartFee", s, err) }(time.Now()) 310 return c.b.EstimateSmartFee(blocks, conservative) 311 } 312 313 func (c *blockChainWithMetrics) EstimateFee(blocks int) (v big.Int, err error) { 314 defer func(s time.Time) { c.observeRPCLatency("EstimateFee", s, err) }(time.Now()) 315 return c.b.EstimateFee(blocks) 316 } 317 318 func (c *blockChainWithMetrics) SendRawTransaction(tx string) (v string, err error) { 319 defer func(s time.Time) { c.observeRPCLatency("SendRawTransaction", s, err) }(time.Now()) 320 return c.b.SendRawTransaction(tx) 321 } 322 323 func (c *blockChainWithMetrics) GetMempoolEntry(txid string) (v *bchain.MempoolEntry, err error) { 324 defer func(s time.Time) { c.observeRPCLatency("GetMempoolEntry", s, err) }(time.Now()) 325 return c.b.GetMempoolEntry(txid) 326 } 327 328 func (c *blockChainWithMetrics) GetChainParser() bchain.BlockChainParser { 329 return c.b.GetChainParser() 330 } 331 332 func (c *blockChainWithMetrics) EthereumTypeGetBalance(addrDesc bchain.AddressDescriptor) (v *big.Int, err error) { 333 defer func(s time.Time) { c.observeRPCLatency("EthereumTypeGetBalance", s, err) }(time.Now()) 334 return c.b.EthereumTypeGetBalance(addrDesc) 335 } 336 337 func (c *blockChainWithMetrics) EthereumTypeGetNonce(addrDesc bchain.AddressDescriptor) (v uint64, err error) { 338 defer func(s time.Time) { c.observeRPCLatency("EthereumTypeGetNonce", s, err) }(time.Now()) 339 return c.b.EthereumTypeGetNonce(addrDesc) 340 } 341 342 func (c *blockChainWithMetrics) EthereumTypeEstimateGas(params map[string]interface{}) (v uint64, err error) { 343 defer func(s time.Time) { c.observeRPCLatency("EthereumTypeEstimateGas", s, err) }(time.Now()) 344 return c.b.EthereumTypeEstimateGas(params) 345 } 346 347 func (c *blockChainWithMetrics) GetContractInfo(contractDesc bchain.AddressDescriptor) (v *bchain.ContractInfo, err error) { 348 defer func(s time.Time) { c.observeRPCLatency("GetContractInfo", s, err) }(time.Now()) 349 return c.b.GetContractInfo(contractDesc) 350 } 351 352 func (c *blockChainWithMetrics) EthereumTypeGetErc20ContractBalance(addrDesc, contractDesc bchain.AddressDescriptor) (v *big.Int, err error) { 353 defer func(s time.Time) { c.observeRPCLatency("EthereumTypeGetErc20ContractBalance", s, err) }(time.Now()) 354 return c.b.EthereumTypeGetErc20ContractBalance(addrDesc, contractDesc) 355 } 356 357 // GetTokenURI returns URI of non fungible or multi token defined by token id 358 func (c *blockChainWithMetrics) GetTokenURI(contractDesc bchain.AddressDescriptor, tokenID *big.Int) (v string, err error) { 359 defer func(s time.Time) { c.observeRPCLatency("GetTokenURI", s, err) }(time.Now()) 360 return c.b.GetTokenURI(contractDesc, tokenID) 361 } 362 363 func (c *blockChainWithMetrics) CoreCoinTypeGetBalance(addrDesc bchain.AddressDescriptor) (v *big.Int, err error) { 364 defer func(s time.Time) { c.observeRPCLatency("CoreCoinTypeGetBalance", s, err) }(time.Now()) 365 return c.b.CoreCoinTypeGetBalance(addrDesc) 366 } 367 368 func (c *blockChainWithMetrics) CoreCoinTypeGetNonce(addrDesc bchain.AddressDescriptor) (v uint64, err error) { 369 defer func(s time.Time) { c.observeRPCLatency("CoreCoinTypeGetNonce", s, err) }(time.Now()) 370 return c.b.CoreCoinTypeGetNonce(addrDesc) 371 } 372 373 func (c *blockChainWithMetrics) CoreCoinTypeEstimateEnergy(params map[string]interface{}) (v uint64, err error) { 374 defer func(s time.Time) { c.observeRPCLatency("CoreCoinTypeEstimateEnergy", s, err) }(time.Now()) 375 return c.b.CoreCoinTypeEstimateEnergy(params) 376 } 377 378 func (c *blockChainWithMetrics) CoreCoinTypeGetCbc20ContractBalance(addrDesc, contractDesc bchain.AddressDescriptor) (v *big.Int, err error) { 379 defer func(s time.Time) { c.observeRPCLatency("CoreCoinTypeGetCbc20ContractBalance", s, err) }(time.Now()) 380 return c.b.CoreCoinTypeGetCbc20ContractBalance(addrDesc, contractDesc) 381 } 382 383 type mempoolWithMetrics struct { 384 mempool bchain.Mempool 385 m *common.Metrics 386 } 387 388 func (c *mempoolWithMetrics) observeRPCLatency(method string, start time.Time, err error) { 389 var e string 390 if err != nil { 391 e = "failure" 392 } 393 c.m.RPCLatency.With(common.Labels{"method": method, "error": e}).Observe(float64(time.Since(start)) / 1e6) // in milliseconds 394 } 395 396 func (c *mempoolWithMetrics) Resync() (count int, err error) { 397 defer func(s time.Time) { c.observeRPCLatency("ResyncMempool", s, err) }(time.Now()) 398 count, err = c.mempool.Resync() 399 if err == nil { 400 c.m.MempoolSize.Set(float64(count)) 401 } 402 return count, err 403 } 404 405 func (c *mempoolWithMetrics) GetTransactions(address string) (v []bchain.Outpoint, err error) { 406 defer func(s time.Time) { c.observeRPCLatency("GetMempoolTransactions", s, err) }(time.Now()) 407 return c.mempool.GetTransactions(address) 408 } 409 410 func (c *mempoolWithMetrics) GetAddrDescTransactions(addrDesc bchain.AddressDescriptor) (v []bchain.Outpoint, err error) { 411 defer func(s time.Time) { c.observeRPCLatency("GetMempoolTransactionsForAddrDesc", s, err) }(time.Now()) 412 return c.mempool.GetAddrDescTransactions(addrDesc) 413 } 414 415 func (c *mempoolWithMetrics) GetAllEntries() (v bchain.MempoolTxidEntries) { 416 defer func(s time.Time) { c.observeRPCLatency("GetAllEntries", s, nil) }(time.Now()) 417 return c.mempool.GetAllEntries() 418 } 419 420 func (c *mempoolWithMetrics) GetTransactionTime(txid string) uint32 { 421 return c.mempool.GetTransactionTime(txid) 422 } 423 424 func (c *mempoolWithMetrics) GetTxidFilterEntries(filterScripts string, fromTimestamp uint32) (bchain.MempoolTxidFilterEntries, error) { 425 return c.mempool.GetTxidFilterEntries(filterScripts, fromTimestamp) 426 }