Merge pull request #6 from RiddleAndCode/bcash-build

Syncing with trezor/blockbook
pull/581/head
Jürgen Eckel 2021-03-16 08:50:04 +01:00 committed by GitHub
commit 9b41d64f33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 293 additions and 225 deletions

View File

@ -424,18 +424,19 @@ type BlockbookInfo struct {
// BackendInfo is used to get information about blockchain
type BackendInfo struct {
BackendError string `json:"error,omitempty"`
Chain string `json:"chain,omitempty"`
Blocks int `json:"blocks,omitempty"`
Headers int `json:"headers,omitempty"`
BestBlockHash string `json:"bestBlockHash,omitempty"`
Difficulty string `json:"difficulty,omitempty"`
SizeOnDisk int64 `json:"sizeOnDisk,omitempty"`
Version string `json:"version,omitempty"`
Subversion string `json:"subversion,omitempty"`
ProtocolVersion string `json:"protocolVersion,omitempty"`
Timeoffset float64 `json:"timeOffset,omitempty"`
Warnings string `json:"warnings,omitempty"`
BackendError string `json:"error,omitempty"`
Chain string `json:"chain,omitempty"`
Blocks int `json:"blocks,omitempty"`
Headers int `json:"headers,omitempty"`
BestBlockHash string `json:"bestBlockHash,omitempty"`
Difficulty string `json:"difficulty,omitempty"`
SizeOnDisk int64 `json:"sizeOnDisk,omitempty"`
Version string `json:"version,omitempty"`
Subversion string `json:"subversion,omitempty"`
ProtocolVersion string `json:"protocolVersion,omitempty"`
Timeoffset float64 `json:"timeOffset,omitempty"`
Warnings string `json:"warnings,omitempty"`
Consensus interface{} `json:"consensus,omitempty"`
}
// SystemInfo contains information about the running blockbook and backend instance

View File

@ -335,7 +335,7 @@ func (w *Worker) GetTransactionFromMempoolTx(mempoolTx *bchain.MempoolTx) (*Tx,
if bchainVin.Txid != "" {
vin.ValueSat = (*Amount)(&bchainVin.ValueSat)
vin.AddrDesc = bchainVin.AddrDesc
vin.Addresses, vin.IsAddress, err = w.chainParser.GetAddressesFromAddrDesc(vin.AddrDesc)
vin.Addresses, vin.IsAddress, _ = w.chainParser.GetAddressesFromAddrDesc(vin.AddrDesc)
if vin.ValueSat != nil {
valInSat.Add(&valInSat, (*big.Int)(vin.ValueSat))
}
@ -1777,6 +1777,7 @@ func (w *Worker) GetSystemInfo(internal bool) (*SystemInfo, error) {
Timeoffset: ci.Timeoffset,
Version: ci.Version,
Warnings: ci.Warnings,
Consensus: ci.Consensus,
}
glog.Info("GetSystemInfo finished in ", time.Since(start))
return &SystemInfo{blockbookInfo, backendInfo}, nil

View File

@ -7,6 +7,7 @@ import (
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"github.com/trezor/blockbook/common"
)
// ZCashRPC is an interface to JSON-RPC bitcoind service
@ -14,6 +15,23 @@ type ZCashRPC struct {
*btc.BitcoinRPC
}
type ResGetBlockChainInfo struct {
Error *bchain.RPCError `json:"error"`
Result struct {
Chain string `json:"chain"`
Blocks int `json:"blocks"`
Headers int `json:"headers"`
Bestblockhash string `json:"bestblockhash"`
Difficulty common.JSONNumber `json:"difficulty"`
Pruned bool `json:"pruned"`
SizeOnDisk int64 `json:"size_on_disk"`
Consensus struct {
Chaintip string `json:"chaintip"`
Nextblock string `json:"nextblock"`
} `json:"consensus"`
} `json:"result"`
}
// NewZCashRPC returns new ZCashRPC instance
func NewZCashRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) {
b, err := btc.NewBitcoinRPC(config, pushHandler)
@ -54,6 +72,41 @@ func (z *ZCashRPC) Initialize() error {
return nil
}
func (z *ZCashRPC) GetChainInfo() (*bchain.ChainInfo, error) {
chainInfo := ResGetBlockChainInfo{}
err := z.Call(&btc.CmdGetBlockChainInfo{Method: "getblockchaininfo"}, &chainInfo)
if err != nil {
return nil, err
}
if chainInfo.Error != nil {
return nil, chainInfo.Error
}
networkInfo := btc.ResGetNetworkInfo{}
err = z.Call(&btc.CmdGetNetworkInfo{Method: "getnetworkinfo"}, &networkInfo)
if err != nil {
return nil, err
}
if networkInfo.Error != nil {
return nil, networkInfo.Error
}
return &bchain.ChainInfo{
Bestblockhash: chainInfo.Result.Bestblockhash,
Blocks: chainInfo.Result.Blocks,
Chain: chainInfo.Result.Chain,
Difficulty: string(chainInfo.Result.Difficulty),
Headers: chainInfo.Result.Headers,
SizeOnDisk: chainInfo.Result.SizeOnDisk,
Version: string(networkInfo.Result.Version),
Subversion: string(networkInfo.Result.Subversion),
ProtocolVersion: string(networkInfo.Result.ProtocolVersion),
Timeoffset: networkInfo.Result.Timeoffset,
Consensus: chainInfo.Result.Consensus,
Warnings: networkInfo.Result.Warnings,
}, nil
}
// GetBlock returns block with given hash.
func (z *ZCashRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
var err error

View File

@ -89,8 +89,9 @@ func (mq *MQ) run(callback func(NotificationType)) {
}
repeatedError = true
time.Sleep(100 * time.Millisecond)
} else {
repeatedError = false
}
repeatedError = false
if msg != nil && len(msg) >= 3 {
var nt NotificationType
switch string(msg[0]) {

View File

@ -161,17 +161,18 @@ type MempoolEntry struct {
// ChainInfo is used to get information about blockchain
type ChainInfo struct {
Chain string `json:"chain"`
Blocks int `json:"blocks"`
Headers int `json:"headers"`
Bestblockhash string `json:"bestblockhash"`
Difficulty string `json:"difficulty"`
SizeOnDisk int64 `json:"size_on_disk"`
Version string `json:"version"`
Subversion string `json:"subversion"`
ProtocolVersion string `json:"protocolversion"`
Timeoffset float64 `json:"timeoffset"`
Warnings string `json:"warnings"`
Chain string `json:"chain"`
Blocks int `json:"blocks"`
Headers int `json:"headers"`
Bestblockhash string `json:"bestblockhash"`
Difficulty string `json:"difficulty"`
SizeOnDisk int64 `json:"size_on_disk"`
Version string `json:"version"`
Subversion string `json:"subversion"`
ProtocolVersion string `json:"protocolversion"`
Timeoffset float64 `json:"timeoffset"`
Warnings string `json:"warnings"`
Consensus interface{} `json:"consensus,omitempty"`
}
// RPCError defines rpc error returned by backend

View File

@ -545,12 +545,22 @@ func syncIndexLoop() {
}
func onNewBlockHash(hash string, height uint32) {
defer func() {
if r := recover(); r != nil {
glog.Error("onNewBlockHash recovered from panic: ", r)
}
}()
for _, c := range callbacksOnNewBlock {
c(hash, height)
}
}
func onNewFiatRatesTicker(ticker *db.CurrencyRatesTicker) {
defer func() {
if r := recover(); r != nil {
glog.Error("onNewFiatRatesTicker recovered from panic: ", r)
}
}()
for _, c := range callbacksOnNewFiatRatesTicker {
c(ticker)
}
@ -617,12 +627,22 @@ func storeInternalStateLoop() {
}
func onNewTxAddr(tx *bchain.Tx, desc bchain.AddressDescriptor) {
defer func() {
if r := recover(); r != nil {
glog.Error("onNewTxAddr recovered from panic: ", r)
}
}()
for _, c := range callbacksOnNewTxAddr {
c(tx, desc)
}
}
func onNewTx(tx *bchain.MempoolTx) {
defer func() {
if r := recover(); r != nil {
glog.Error("onNewTx recovered from panic: ", r)
}
}()
for _, c := range callbacksOnNewTx {
c(tx)
}

View File

@ -1,91 +1,65 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: User-ID: Alexander Block (codablock) <ablock84@gmail.com>
Comment: Created: 5/29/18 3:12 PM
Comment: Type: 4096-bit RSA
Comment: Usage: Signing, Encryption, Certifying User-IDs
Comment: Fingerprint: 99DF0DABDEE182FA53A33AE763A96B406102E091
mQINBFsNUbwBEADAJC8Bm81jFH5CcIDz0hzmWB957Yt3MBoF5EMrE8xW7GZtNoTJ
5kLPOd4lEEfpK7KWUcwqh12LeWzL0IpVxBwJTx3r/A/PPAJpRtr2g1JlYa26kyBz
QurPxxoCUUhMP+k8XvaDMdnTzxar+Y7C3KUQ/t8ikb7rZgsS3Xzt6KxYAWXGkqhl
kPGq40FfSGUFqlZ+/GnXURFvAcVHKvzOhUjt5Yp2K/vaoaSOwWpPG4DfNm3ulNTo
yKFypBk2Pv+kXovTZDy9VNrDQ9uJqR0s0jhcmnEzQQEbhQYQgZl7s/mchYBmgflb
5WvENzhTW7DTtbWmZyCUGkhe9+d7OA+I3w6vGNf4ekt6G7D1WrXL1LCIfRHNnreG
cYjkvOOPhP4Rb8LKH7Bpa4QdTzofKMiUfvDWkSSENsbU7oq4YfqzhjJFoiwnkw+y
78Ts6AAchby2LUHfN6qJN3yI1KybwMT29+FjoJEo5xWv8sYI3iW2ZLIuBAMZZi9b
LFLKEE0tP4PmFDm1y+mVL6QEiT4Zo5+Qiipo7z8E7/PHUEEVOw/eX2BUIEan9NwY
jWf1h+ewSjizuS+U2Q8VZYfplvGw4c76nGP7ik2W3rX+A5szOyQnrHy05hJ4ax1L
K99DQRTiq+3ztjQ+unozb2hhh1AOxfHTJZ6PEfoZ4VN26etkFigkXQl9oQARAQAB
tDBBbGV4YW5kZXIgQmxvY2sgKGNvZGFibG9jaykgPGFibG9jazg0QGdtYWlsLmNv
bT6JAk4EEwEIADgCGwMCHgECF4AWIQSZ3w2r3uGC+lOjOudjqWtAYQLgkQUCWw1T
bAULCQgHAwUVCgkICwUWAgMBAAAKCRBjqWtAYQLgkZznD/9RLUgiFaiCFDypsvUL
72/6VMXHEMLq1wIxDWcnls/6hG+zS9IfuCxS5KrZnwBDuXkRARv//gXb0TVymun0
+B/WLzj9rIp+kA8M/iQ8Bhy3LmJiX78p62gZvruO7Qirks5a4rwVNrngYDMrwvIp
B3JWVnO8YU7TlIDIa7jujERj5+xRWp2i9ZRu/9ioC+COyIWxUcPMuzWCh98HjZIf
uZf88SfIUP0Z86P7C5SP3QqZt7bkmT1XqD87k7f1N/JLIDFCQ2a4YKrgIQwkRa+t
hydKDl9Ofv25hc5/6yy06bdMlAf0fpeX7sxYB6JZXzbCDe/UmSx+Ycqe64hr0BN0
Ww5koG1WjpFWH3/NJ1CxzgfaVWfX1EWJXHIkmSEQKFQKBH7t3v2G6zb4Uzp8t5xk
c5QLR9wv48U1ryRJ9a+WJzGfkRJKmfw458BveaNVVKJX0q3yEG+JMmbOsPxiD5lJ
HzW6CyqkuiBzxixTRGeZlGZtAJmJElklBNbUnqEEdeWr2tHHNkGc8D7VEovquyxh
rwKOS2tGFYZhZApcfYCPYbFlCdfQ32WmQXz7T/JbhuqqyTpNhlCG4Uz6as6OXhdB
91Fdu5mJR+l7aWo5hnnm4W3KKvuthNIqaJ5yqUTKTaNPIbMIJ2NiihFZsuDzEuRn
BkXPS33mMc7p6dXU/VsadrC/dbkCDQRbDVG8ARAAwXnPOlLjYlplum7rkyvNWwEG
bqI01FFnOXF9vR/N5WtceAd4HOmM+ayRN3g6EtgL84/Hjc0sIKS6bNHvpJMVM+4h
Yl0V9kdHx2UHqb9WR9GhsEfbU0SP6Np8LqVJIpTu9iMdSxHYDyUTV5/8k3TW/Bzo
UbvBpyl4xDQXBB94qcDiLPKhkCRbaC7tzfycvTzu+uLX6Fz49ud55HRRT8Y0haMY
hj93vqH1Npz5gkwMqn3alejmt4APuwKzqnz9FU3AN3oBxQLcDrLmOE5R9CDV0NJP
jprloYlRGbrbZKjvpK7WkPQnmmCsOchcRfJNpRJVnyHOdvTyCLf5mC/jATUMlrf9
dKL0eqDjTu2cKjJHiWJ3mrzCq8ud31lHW8FazzbOi/vU40NkRkOcUrQaaLayruVn
VK0qy7M9E9o121Z3UOeGoJQeRDi6XpjuNjZS/34rGNjuX5/d0bQ1ORSIrPJBz8Pe
9l3zmqKt9Uj/816QqxXSEN2/ZfIpiAEMrL+QDADwW48QqkzZGjpFyFOvUgJtAkPc
2QOvSkpb+qalz7XWLtUoRTA4AFIZXzzwdoQIWlkSNBsVKJQFKlhVyDpn/p8wDVCo
EucQm/B0iD4u3gGaguVyvNktCB7HH1vvTQAXLRb0S3GkL4kyEvLuK/f+HO5fIOwx
0QVovso80gnwa0CeifUAEQEAAYkCNgQYAQgAIBYhBJnfDave4YL6U6M652Opa0Bh
AuCRBQJbDVG8AhsMAAoJEGOpa0BhAuCRmQMP/i3cQONkKZo/V/IM3olWJvi0oSbO
1ylsWHoyqM5Dk7ZiKSSIMBpMj1vhjKRiAp0Uwq64epSSPcYq9/NSE5d1zi8LlOZ3
3yt+zu+rqoK51O6i41NERYlU1Pw6pyFfbrJVdjYKA0KO/ag3S6EF9dUsFZ+lbZxe
34KYirDTYy2C7EixkKQwLmML2Q4qkNpq1JNnv3KtjYLDC8jNuizQiTEgq9DCT3JZ
p/ykppP+z4AhwDZuOeQ232XrLzRPFzU5H/sEpYI0vGahnCwooyo84jzQOu3aAUjR
wuWADp6HDmzgMaOFQffxShQ0bdRiRv9JPu50TxwmuAca6T8x83i5AJosOkb7Ci8N
bl6i/qtv922MT8u326RVCUHlQxVUAdvMcuE0QSwmRP2CB82AqGCU29TNo/KPq44b
Rs2oBG4VhKnCu2xvNwsX5Lt8vxyFTr5++LpfDDUlG26N5HFG0YCr0yqdunPGQEvN
NeJ4HScrlNYABIAS/Cy30EAYes0qPLlr7e07XDdteSFCwzmsvM0kyjv2lTbtB81p
t7Dh+BhcB+7I2IzEzaeeQBC6tSeE9LzqAHdCyrh5jOHT+p+3YIsgg1dF88gZsc6i
uOJiBjxjxLh4RxJmHaj0E4Sk4rqf8AS4sN5P0tyykhYh6tvEJSPwLRrh0Qldu4Yq
Gn6Os2zcQi6bXdWSuQINBFsNU50BEADOf4QB2IhrZrX0vtdz1mkwMIZYrZrPYQO1
M+odvQPXzpTh2gkAPz0IcbEGTvcQb6ikv+ovsrXsY797mmVIIG7TtqW25xRuPXD/
t881fpVF/LnsoULg3rHrkHCXvG5QU0wtAVsooiquCC7u0EEBT1wHhn68qOxWspuK
vYwNB/7bH5qQm1/k5ygLKfFX4dNh6+zmSG6HKckplaCaSPnETYsyD9k7GITs4Zrx
0rL5pj5grGcefr7QOOsmd1K/2cwvlpe3ll+f3agIQKKSN/rZYK81U/U91+6ZBTe5
QQW1U6nE6ceS3oY4LVJYU8DUncsiFfrrfzdqIqYIKmpuKXEQFi2lejDfMoWZSKTM
zVX6OWgnhqLGTGuPsyEIu2AkFM5f+aDSnYxhdurGZqtnC+67d5Y1igwVCcUsPOsZ
7VzOPUXH71/PzT+OCXHpKuEIeiGz5BOuB7Wf4mPPSRFs9VTYaSHyPpfqQWNUxf+W
qORwEFObIH1SdTEM+2QcEyr/omcC/FejrXx0i/knAuwNs3Lo2HnY4DIEA16mEQW4
ftfhu2OaDxcUG7x/MW0bMEr1hIHD9XuQA/vXRAK0uc7dM84W5tLoECRh+kSGQwmP
JnAG/GqsepkXYLbYxysAorucoIKUKzfJi+imHXqhdYlYEUQ1y2SQMPQoy9NIeTxv
yViXeLQ4PQARAQABiQRsBBgBCAAgFiEEmd8Nq97hgvpTozrnY6lrQGEC4JEFAlsN
U50CGwICQAkQY6lrQGEC4JHBdCAEGQEIAB0WIQSBczIrb6WLLEr1M4wWbCr47BBd
BAUCWw1TnQAKCRAWbCr47BBdBOXeEACkxc0Y+ZyS0P92j135sTInLtJMwPG0sjWQ
JGYFUswyVEcZ9fEmCCH7jheeBHROxojSLksYREH/LbKLhiqLqfZDzMdlwDzSYAmr
k7rEkFGStsXwCi4nYIBJfOk0HIvxMOOj8q+AkXVVMBSeMY9pB8XDsk5Wn4nuU22A
dCx22zRiOXYXeqK8B3fnVrDEBKI5pJcXA22+2jASZBC2V6GqnLV4aBl5UNzdlvfi
ADf8UuNj0Qt9usXTIvlZEn+DFFlmE9ftOdsaTGUEqiiN8y87TGs48Ep3ze1ltzt1
B7zytlTJ1Y23o0oQUbYvSm8NiIk0oJXpfbiKdd6TP7/5mXAvxazH37MJIhY8Ifb/
2NsS85SsvCc6w6cyKEihiH4/4aeRyUU5D7SFh5lDmKm7uCRS8riqY6twFvpjvaR0
/fcfje4WglRZND4Lbh4hHYDCviThdXyHQM/5q0+wR18qOE7o4a/7bt3vQvbuGK62
dAYLKNoO7c/2ZvugdVE0W8+w3PeLxKp5VFj/t7P69ElWkHpkmbR8x4F17qKENxN7
BUyujWNT6II4PnXC+6nx/quvsogNe95IK/NRDUFAOT1xJYTAKC6146ogAMHVMWDG
t+V9ZcdgpuBkwRBwhgn8yswKRjfAn9dooYTnIz6ZCZnSH+xJ8qkkm3o7PXs1lcYm
iJ2ADZo+6RSWD/9GbSU1WWOHoqBN7DXNA9lvUhNjh3hakXVi0GTSQbRrGr6FkxBS
NL0bu/x5yLsKhqQlxC4TL7IPR+9kJ3IQXh1pZjzsVrtIdyr5wApiQyotM9hwhEE8
Fbkzens163l7sSFNCNs9JZHUwnXkt6Rpz+NLoDgroS7fSA8+3nyoNekajkW0Tnu8
MJigln7pqUwjJbacz4K8gyhXX/xEIhlXrIarmwN6XfLNYhwytQD4eRkM0bgeYp/8
cmNsGG1+5JbX0XK2aq+ClQdPyMluo/YA+TyHmqHb1D3ncyIc9d9nYLyuo5OK701t
xI9U0HzpL1CwkqE0BENVFBf91mL1Nht6qa4vL8eTTKIsh+I1s1xIf77N1SHGx+eD
4pu6TUy/C3VwibGgngy86bEa8VVs2SDNCEpfzYNGpN81f9TpIe5KVCIzMVvCk9+5
k7YjAuyzPQ3EVzHueON/jXmTR20EbB0YwiO7H5AD3Md5G6SZo71CN7O6SyePY1HY
HKNAd5FrVGJ8fadcVL0LaBcRX3J+VxGJlhEc+MzcIgVr6z3bWgngkY/QFafvf4Ar
c/mOJlsgqUTg+JG/iN4EO0s6IRLks1Oj/pq0bVz0Ri4Mdyo1Cu85ScTh64sww7OV
E5z8OE4LeQfRmqXG1zpLARBsr09iTxZG8X3vDHJCdCRlwebpQ2DSrwoSuA==
=nX/z
-----END PGP PUBLIC KEY BLOCK-----
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
96I=
=85Kq
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -22,10 +22,10 @@
"package_name": "backend-bcash",
"package_revision": "satoshilabs-1",
"system_user": "bcash",
"version": "0.22.0",
"binary_url": "https://download.bitcoinabc.org/0.22.0/linux/bitcoin-abc-0.22.0-x86_64-linux-gnu.tar.gz",
"version": "22.1.0",
"binary_url": "https://github.com/bitcoin-cash-node/bitcoin-cash-node/releases/download/v22.1.0/bitcoin-cash-node-22.1.0-x86_64-linux-gnu.tar.gz",
"verification_type": "sha256",
"verification_source": "9d3718cbaf0516cc1e2bff40bd9ff708e61b6ed2469afb18e87e9fc1de3c4d5c",
"verification_source": "aa1002d51833b0de44084bde09951223be4f9c455427aef277f91dacd2f0f657",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [
"bin/bitcoin-qt"
@ -49,7 +49,7 @@
"additional_params": "",
"block_chain": {
"parse": true,
"subversion": "/Bitcoin ABC:0.22.0/",
"subversion": "/Bitcoin ABC Cash Node:22.1.0/",
"address_format": "cashaddr",
"mempool_workers": 8,
"mempool_sub_workers": 2,

View File

@ -22,10 +22,10 @@
"package_name": "backend-bcash-testnet",
"package_revision": "satoshilabs-1",
"system_user": "bcash",
"version": "0.22.0",
"binary_url": "https://download.bitcoinabc.org/0.22.0/linux/bitcoin-abc-0.22.0-x86_64-linux-gnu.tar.gz",
"version": "22.1.0",
"binary_url": "https://github.com/bitcoin-cash-node/bitcoin-cash-node/releases/download/v22.1.0/bitcoin-cash-node-22.1.0-x86_64-linux-gnu.tar.gz",
"verification_type": "sha256",
"verification_source": "9d3718cbaf0516cc1e2bff40bd9ff708e61b6ed2469afb18e87e9fc1de3c4d5c",
"verification_source": "aa1002d51833b0de44084bde09951223be4f9c455427aef277f91dacd2f0f657",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [
"bin/bitcoin-qt"
@ -49,7 +49,7 @@
"additional_params": "",
"block_chain": {
"parse": true,
"subversion": "/Bitcoin ABC:0.22.0/",
"subversion": "/Bitcoin ABC Cash Node:22.1.0/",
"address_format": "cashaddr",
"mempool_workers": 8,
"mempool_sub_workers": 2,

View File

@ -22,15 +22,15 @@
"package_name": "backend-dash",
"package_revision": "satoshilabs-1",
"system_user": "dash",
"version": "0.15.0.0",
"binary_url": "https://github.com/dashpay/dash/releases/download/v0.15.0.0/dashcore-0.15.0.0-x86_64-linux-gnu.tar.gz",
"version": "0.16.0.1",
"binary_url": "https://github.com/dashpay/dash/releases/download/v0.16.0.1/dashcore-0.16.0.1-x86_64-linux-gnu.tar.gz",
"verification_type": "gpg-sha256",
"verification_source": "https://github.com/dashpay/dash/releases/download/v0.15.0.0/SHA256SUMS.asc",
"verification_source": "https://github.com/dashpay/dash/releases/download/v0.16.0.1/SHA256SUMS.asc",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [
"bin/dash-qt"
],
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/dashd -datadir={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend -conf={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/{{.Coin.Alias}}.conf -pid=/run/{{.Coin.Alias}}/{{.Coin.Alias}}.pid",
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/dashd -deprecatedrpc=estimatefee -datadir={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend -conf={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/{{.Coin.Alias}}.conf -pid=/run/{{.Coin.Alias}}/{{.Coin.Alias}}.pid",
"logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/*.log",
"postinst_script_template": "",
"service_type": "forking",

View File

@ -22,15 +22,15 @@
"package_name": "backend-dash-testnet",
"package_revision": "satoshilabs-1",
"system_user": "dash",
"version": "0.15.0.0",
"binary_url": "https://github.com/dashpay/dash/releases/download/v0.15.0.0/dashcore-0.15.0.0-x86_64-linux-gnu.tar.gz",
"version": "0.16.0.1",
"binary_url": "https://github.com/dashpay/dash/releases/download/v0.16.0.1/dashcore-0.16.0.1-x86_64-linux-gnu.tar.gz",
"verification_type": "gpg-sha256",
"verification_source": "https://github.com/dashpay/dash/releases/download/v0.15.0.0/SHA256SUMS.asc",
"verification_source": "https://github.com/dashpay/dash/releases/download/v0.16.0.1/SHA256SUMS.asc",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [
"bin/dash-qt"
],
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/dashd -datadir={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend -conf={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/{{.Coin.Alias}}.conf -pid=/run/{{.Coin.Alias}}/{{.Coin.Alias}}.pid",
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/dashd -deprecatedrpc=estimatefee -datadir={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend -conf={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/{{.Coin.Alias}}.conf -pid=/run/{{.Coin.Alias}}/{{.Coin.Alias}}.pid",
"logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/testnet3/*.log",
"postinst_script_template": "",
"service_type": "forking",

View File

@ -22,12 +22,13 @@
"package_name": "backend-deeponion",
"package_revision": "satoshilabs-1",
"system_user": "deeponion",
"version": "2.0.5",
"binary_url": "https://github.com/deeponion/deeponion/releases/download/v2.0.5/deeponion-2.0.5-x86_64-linux-gnu.tar.gz",
"version": "2.2.0",
"binary_url": "https://github.com/deeponion/deeponion/releases/download/v2.2.0/DeepOnion-2.2.0-x86_64-linux-gnu.tar.gz",
"extract_command": "tar -C backend --strip 1 -xpf",
"exclude_files": [
"bin/DeepOnion-qt"
],
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/DeepOniond -datadir={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend -conf={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/{{.Coin.Alias}}.conf -pid=/run/{{.Coin.Alias}}/{{.Coin.Alias}}.pid",
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/DeepOniond -datadir={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend -conf={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/{{.Coin.Alias}}.conf -pid=/run/{{.Coin.Alias}}/{{.Coin.Alias}}.pid",
"logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/*.log",
"postinst_script_template": "",
"service_type": "forking",
@ -49,7 +50,7 @@
"additional_params": "",
"block_chain": {
"parse": true,
"subversion": "/DeepOnionCore:2.0.5/",
"subversion": "/DeepOnionCore:2.2.0/",
"mempool_workers": 8,
"mempool_sub_workers": 2,
"block_addresses_to_keep": 300,

View File

@ -19,10 +19,10 @@
"package_name": "backend-ethereum-classic",
"package_revision": "satoshilabs-1",
"system_user": "ethereum-classic",
"version": "1.11.12",
"binary_url": "https://github.com/etclabscore/core-geth/releases/download/v1.11.12/core-geth-linux-v1.11.12.zip",
"version": "1.11.18",
"binary_url": "https://github.com/etclabscore/core-geth/releases/download/v1.11.18/core-geth-linux-v1.11.18.zip",
"verification_type": "sha256",
"verification_source": "6d1f5499e84cf7849c5eb4a6870cc72a33891662274241b00d6cd2e315c4fac4",
"verification_source": "ee1533e546e9520eeb327be30978b55449cce09341c3d242f4104ae41b2c9c2c",
"extract_command": "unzip -d backend",
"exclude_files": [],
"exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/geth --classic --ipcdisable --cache 1024 --nat none --datadir {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend --port 38337 --ws --wsaddr 127.0.0.1 --wsport {{.Ports.BackendRPC}} --wsorigins \"*\" --rpc --rpcport 8137 -rpcaddr 127.0.0.1 --rpccorsdomain \"*\" 2>>{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'",

View File

@ -21,10 +21,10 @@
"package_name": "backend-ethereum",
"package_revision": "satoshilabs-1",
"system_user": "ethereum",
"version": "1.9.20-979fc968",
"binary_url": "https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.20-979fc968.tar.gz",
"version": "1.9.24-cc05b050",
"binary_url": "https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.24-cc05b050.tar.gz",
"verification_type": "gpg",
"verification_source": "https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.20-979fc968.tar.gz.asc",
"verification_source": "https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.24-cc05b050.tar.gz.asc",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [],
"exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/geth --ipcdisable --syncmode full --cache 1024 --nat none --datadir {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend --port 38336 --ws --wsaddr 127.0.0.1 --wsport {{.Ports.BackendRPC}} --wsorigins \"*\" --rpc --rpcport 8136 -rpcaddr 127.0.0.1 --rpccorsdomain \"*\" --rpcvhosts \"*\" 2>>{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'",

View File

@ -20,10 +20,10 @@
"package_name": "backend-ethereum-testnet-ropsten",
"package_revision": "satoshilabs-1",
"system_user": "ethereum",
"version": "1.9.20-979fc968",
"binary_url": "https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.20-979fc968.tar.gz",
"version": "1.9.24-cc05b050",
"binary_url": "https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.24-cc05b050.tar.gz",
"verification_type": "gpg",
"verification_source": "https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.20-979fc968.tar.gz.asc",
"verification_source": "https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.24-cc05b050.tar.gz.asc",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [],
"exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/geth --testnet --syncmode full --ipcdisable --cache 1024 --nat none --datadir {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend --port 48336 --ws --wsaddr 127.0.0.1 --wsport {{.Ports.BackendRPC}} --wsorigins \"*\" 2>>{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'",

View File

@ -22,10 +22,10 @@
"package_name": "backend-koto",
"package_revision": "satoshilabs-1",
"system_user": "koto",
"version": "2.1.2",
"binary_url": "https://github.com/KotoDevelopers/koto/releases/download/v2.1.2/koto-2.1.2-linux64.tar.gz",
"version": "4.0.0",
"binary_url": "https://github.com/KotoDevelopers/koto/releases/download/v4.0.0/koto-4.0.0-linux64.tar.gz",
"verification_type": "gpg",
"verification_source": "https://github.com/KotoDevelopers/koto/releases/download/v2.1.2/koto-2.1.2-linux64.tar.gz.asc",
"verification_source": "https://github.com/KotoDevelopers/koto/releases/download/v4.0.0/koto-4.0.0-linux64.tar.gz.asc",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [
"bin/koto-qt"

View File

@ -22,10 +22,10 @@
"package_name": "backend-koto-testnet",
"package_revision": "satoshilabs-1",
"system_user": "koto",
"version": "2.1.2",
"binary_url": "https://github.com/KotoDevelopers/koto/releases/download/v2.1.2/koto-2.1.2-linux64.tar.gz",
"version": "4.0.0",
"binary_url": "https://github.com/KotoDevelopers/koto/releases/download/v4.0.0/koto-4.0.0-linux64.tar.gz",
"verification_type": "gpg",
"verification_source": "https://github.com/KotoDevelopers/koto/releases/download/v2.1.2/koto-2.1.2-linux64.tar.gz.asc",
"verification_source": "https://github.com/KotoDevelopers/koto/releases/download/v4.0.0/koto-4.0.0-linux64.tar.gz.asc",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [
"bin/koto-qt"

View File

@ -22,10 +22,10 @@
"package_name": "backend-ritocoin",
"package_revision": "satoshilabs-1",
"system_user": "ritocoin",
"version": "2.4.0.0",
"binary_url": "https://github.com/RitoProject/Ritocoin/releases/download/2.4.1.0/rito-2.4.1.0-x86_64-linux-gnu.tar.gz",
"version": "2.4.2.0",
"binary_url": "https://github.com/RitoProject/Ritocoin/releases/download/2.4.2.0/rito-2.4.2.0-x86_64-linux-gnu.tar.gz",
"verification_type": "sha256",
"verification_source": "753f8a536080af1f2348e255a1cf7115039b22f6753d278931ddd5473906bc39",
"verification_source": "69301b7bfa74765d5b535b2c2b93bcbd4d5c2870625004593b4c5c769e098f67",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [
"bin/rito-qt"

View File

@ -22,10 +22,10 @@
"package_name": "backend-zcash",
"package_revision": "satoshilabs-1",
"system_user": "zcash",
"version": "4.0.0",
"binary_url": "https://z.cash/downloads/zcash-4.0.0-linux64-debian-stretch.tar.gz",
"version": "4.1.1",
"binary_url": "https://z.cash/downloads/zcash-4.1.1-linux64-debian-stretch.tar.gz",
"verification_type": "sha256",
"verification_source": "a0daf673d45e92fe97f2dd43bbaf6d6653940643aff62915f46df89af4d8c8b5",
"verification_source": "50b639f0d1c7177809535bad7631490297aa7873d867425096eb8c7a04b2b132",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [],
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/zcashd -datadir={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend -conf={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/{{.Coin.Alias}}.conf -pid=/run/{{.Coin.Alias}}/{{.Coin.Alias}}.pid",

View File

@ -22,10 +22,10 @@
"package_name": "backend-zcash-testnet",
"package_revision": "satoshilabs-1",
"system_user": "zcash",
"version": "4.0.0",
"binary_url": "https://z.cash/downloads/zcash-4.0.0-linux64-debian-stretch.tar.gz",
"version": "4.1.1",
"binary_url": "https://z.cash/downloads/zcash-4.1.1-linux64-debian-stretch.tar.gz",
"verification_type": "sha256",
"verification_source": "a0daf673d45e92fe97f2dd43bbaf6d6653940643aff62915f46df89af4d8c8b5",
"verification_source": "50b639f0d1c7177809535bad7631490297aa7873d867425096eb8c7a04b2b132",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [],
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/zcashd -datadir={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend -conf={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/{{.Coin.Alias}}.conf -pid=/run/{{.Coin.Alias}}/{{.Coin.Alias}}.pid",

View File

@ -143,6 +143,12 @@ func (s *WebsocketServer) GetHandler() http.Handler {
}
func (s *WebsocketServer) closeChannel(c *websocketChannel) {
if c.CloseOut() {
s.onDisconnect(c)
}
}
func (c *websocketChannel) CloseOut() bool {
c.aliveLock.Lock()
defer c.aliveLock.Unlock()
if c.alive {
@ -153,14 +159,24 @@ func (s *WebsocketServer) closeChannel(c *websocketChannel) {
for len(c.out) > 0 {
<-c.out
}
s.onDisconnect(c)
return true
}
return false
}
func (c *websocketChannel) IsAlive() bool {
func (c *websocketChannel) DataOut(data *websocketRes) {
c.aliveLock.Lock()
defer c.aliveLock.Unlock()
return c.alive
if c.alive {
if len(c.out) < outChannelSize-1 {
c.out <- data
} else {
glog.Warning("Channel ", c.id, " overflow, closing")
// close the connection but do not call CloseOut - would call duplicate c.aliveLock.Lock
// CloseOut will be called because the closed connection will cause break in the inputLoop
c.conn.Close()
}
}
}
func (s *WebsocketServer) inputLoop(c *websocketChannel) {
@ -204,11 +220,18 @@ func (s *WebsocketServer) inputLoop(c *websocketChannel) {
}
func (s *WebsocketServer) outputLoop(c *websocketChannel) {
defer func() {
if r := recover(); r != nil {
glog.Error("recovered from panic: ", r, ", ", c.id)
s.closeChannel(c)
}
}()
for m := range c.out {
err := c.conn.WriteJSON(m)
if err != nil {
glog.Error("Error sending message to ", c.id, ", ", err)
s.closeChannel(c)
return
}
}
}
@ -383,18 +406,6 @@ var requestHandlers = map[string]func(*WebsocketServer, *websocketChannel, *webs
},
}
func sendResponse(c *websocketChannel, req *websocketReq, data interface{}) {
defer func() {
if r := recover(); r != nil {
glog.Error("Client ", c.id, ", onRequest ", req.Method, " recovered from panic: ", r)
}
}()
c.out <- &websocketRes{
ID: req.ID,
Data: data,
}
}
func (s *WebsocketServer) onRequest(c *websocketChannel, req *websocketReq) {
var err error
var data interface{}
@ -408,7 +419,10 @@ func (s *WebsocketServer) onRequest(c *websocketChannel, req *websocketReq) {
}
// nil data means no response
if data != nil {
sendResponse(c, req, data)
c.DataOut(&websocketRes{
ID: req.ID,
Data: data,
})
}
}()
t := time.Now()
@ -429,7 +443,7 @@ func (s *WebsocketServer) onRequest(c *websocketChannel, req *websocketReq) {
data = e
}
} else {
glog.Warning("Client ", c.id, " onMessage ", req.Method, ": unknown method, data ", string(req.Params))
glog.V(1).Info("Client ", c.id, " onMessage ", req.Method, ": unknown method, data ", string(req.Params))
}
}
@ -665,11 +679,25 @@ func (s *WebsocketServer) unmarshalAddresses(params []byte) ([]bchain.AddressDes
return rv, nil
}
// unsubscribe addresses without addressSubscriptionsLock - can be called only from subscribeAddresses and unsubscribeAddresses
func (s *WebsocketServer) doUnsubscribeAddresses(c *websocketChannel) {
for ads, sa := range s.addressSubscriptions {
for sc := range sa {
if sc == c {
delete(sa, c)
}
}
if len(sa) == 0 {
delete(s.addressSubscriptions, ads)
}
}
}
func (s *WebsocketServer) subscribeAddresses(c *websocketChannel, addrDesc []bchain.AddressDescriptor, req *websocketReq) (res interface{}, err error) {
// unsubscribe all previous subscriptions
s.unsubscribeAddresses(c)
s.addressSubscriptionsLock.Lock()
defer s.addressSubscriptionsLock.Unlock()
// unsubscribe all previous subscriptions
s.doUnsubscribeAddresses(c)
for i := range addrDesc {
ads := string(addrDesc[i])
as, ok := s.addressSubscriptions[ads]
@ -686,26 +714,30 @@ func (s *WebsocketServer) subscribeAddresses(c *websocketChannel, addrDesc []bch
func (s *WebsocketServer) unsubscribeAddresses(c *websocketChannel) (res interface{}, err error) {
s.addressSubscriptionsLock.Lock()
defer s.addressSubscriptionsLock.Unlock()
for ads, sa := range s.addressSubscriptions {
s.doUnsubscribeAddresses(c)
return &subscriptionResponse{false}, nil
}
// unsubscribe fiat rates without fiatRatesSubscriptionsLock - can be called only from subscribeFiatRates and unsubscribeFiatRates
func (s *WebsocketServer) doUnsubscribeFiatRates(c *websocketChannel) {
for fr, sa := range s.fiatRatesSubscriptions {
for sc := range sa {
if sc == c {
delete(sa, c)
}
}
if len(sa) == 0 {
delete(s.addressSubscriptions, ads)
delete(s.fiatRatesSubscriptions, fr)
}
}
return &subscriptionResponse{false}, nil
}
// subscribeFiatRates subscribes all FiatRates subscriptions by this channel
func (s *WebsocketServer) subscribeFiatRates(c *websocketChannel, currency string, req *websocketReq) (res interface{}, err error) {
// unsubscribe all previous subscriptions
s.unsubscribeFiatRates(c)
s.fiatRatesSubscriptionsLock.Lock()
defer s.fiatRatesSubscriptionsLock.Unlock()
// unsubscribe all previous subscriptions
s.doUnsubscribeFiatRates(c)
if currency == "" {
currency = allFiatRates
}
@ -722,16 +754,7 @@ func (s *WebsocketServer) subscribeFiatRates(c *websocketChannel, currency strin
func (s *WebsocketServer) unsubscribeFiatRates(c *websocketChannel) (res interface{}, err error) {
s.fiatRatesSubscriptionsLock.Lock()
defer s.fiatRatesSubscriptionsLock.Unlock()
for fr, sa := range s.fiatRatesSubscriptions {
for sc := range sa {
if sc == c {
delete(sa, c)
}
}
if len(sa) == 0 {
delete(s.fiatRatesSubscriptions, fr)
}
}
s.doUnsubscribeFiatRates(c)
return &subscriptionResponse{false}, nil
}
@ -747,12 +770,10 @@ func (s *WebsocketServer) OnNewBlock(hash string, height uint32) {
Hash: hash,
}
for c, id := range s.newBlockSubscriptions {
if c.IsAlive() {
c.out <- &websocketRes{
ID: id,
Data: &data,
}
}
c.DataOut(&websocketRes{
ID: id,
Data: &data,
})
}
glog.Info("broadcasting new block ", height, " ", hash, " to ", len(s.newBlockSubscriptions), " channels")
}
@ -772,30 +793,26 @@ func (s *WebsocketServer) sendOnNewTxAddr(stringAddressDescriptor string, tx *ap
Address: addr[0],
Tx: tx,
}
// get the list of subscriptions again, this time keep the lock
s.addressSubscriptionsLock.Lock()
defer s.addressSubscriptionsLock.Unlock()
as, ok := s.addressSubscriptions[stringAddressDescriptor]
if ok {
for c, id := range as {
if c.IsAlive() {
c.out <- &websocketRes{
ID: id,
Data: &data,
}
}
c.DataOut(&websocketRes{
ID: id,
Data: &data,
})
}
glog.Info("broadcasting new tx ", tx.Txid, ", addr ", addr[0], " to ", len(as), " channels")
}
}
}
// OnNewTx is a callback that broadcasts info about a tx affecting subscribed address
func (s *WebsocketServer) OnNewTx(tx *bchain.MempoolTx) {
func (s *WebsocketServer) getNewTxSubscriptions(tx *bchain.MempoolTx) map[string]struct{} {
// check if there is any subscription in inputs, outputs and erc20
// release the lock immediately, GetTransactionFromMempoolTx is potentially slow
subscribed := make(map[string]struct{})
s.addressSubscriptionsLock.Lock()
defer s.addressSubscriptionsLock.Unlock()
subscribed := make(map[string]struct{})
for i := range tx.Vin {
sad := string(tx.Vin[i].AddrDesc)
if len(sad) > 0 {
@ -833,7 +850,12 @@ func (s *WebsocketServer) OnNewTx(tx *bchain.MempoolTx) {
}
}
}
s.addressSubscriptionsLock.Unlock()
return subscribed
}
// OnNewTx is a callback that broadcasts info about a tx affecting subscribed address
func (s *WebsocketServer) OnNewTx(tx *bchain.MempoolTx) {
subscribed := s.getNewTxSubscriptions(tx)
if len(subscribed) > 0 {
atx, err := s.api.GetTransactionFromMempoolTx(tx)
if err != nil {
@ -847,8 +869,6 @@ func (s *WebsocketServer) OnNewTx(tx *bchain.MempoolTx) {
}
func (s *WebsocketServer) broadcastTicker(currency string, rates map[string]float64) {
s.fiatRatesSubscriptionsLock.Lock()
defer s.fiatRatesSubscriptionsLock.Unlock()
as, ok := s.fiatRatesSubscriptions[currency]
if ok && len(as) > 0 {
data := struct {
@ -856,24 +876,20 @@ func (s *WebsocketServer) broadcastTicker(currency string, rates map[string]floa
}{
Rates: rates,
}
// get the list of subscriptions again, this time keep the lock
as, ok = s.fiatRatesSubscriptions[currency]
if ok {
for c, id := range as {
if c.IsAlive() {
c.out <- &websocketRes{
ID: id,
Data: &data,
}
}
}
glog.Info("broadcasting new rates for currency ", currency, " to ", len(as), " channels")
for c, id := range as {
c.DataOut(&websocketRes{
ID: id,
Data: &data,
})
}
glog.Info("broadcasting new rates for currency ", currency, " to ", len(as), " channels")
}
}
// OnNewFiatRatesTicker is a callback that broadcasts info about fiat rates affecting subscribed currency
func (s *WebsocketServer) OnNewFiatRatesTicker(ticker *db.CurrencyRatesTicker) {
s.fiatRatesSubscriptionsLock.Lock()
defer s.fiatRatesSubscriptionsLock.Unlock()
for currency, rate := range ticker.Rates {
s.broadcastTicker(currency, map[string]float64{currency: rate})
}