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