add GameCredits (GAME) to Blockbook (#79)

* add GameCredits (GAME) to Blockbook

* add GameCredits (GAME) integration tests
pull/85/head
Samad Sajanlal 2018-10-24 04:33:26 -05:00 committed by Martin
parent 4422661918
commit 4cd6b3b49c
8 changed files with 614 additions and 0 deletions

View File

@ -8,6 +8,7 @@ import (
"blockbook/bchain/coins/dash"
"blockbook/bchain/coins/dogecoin"
"blockbook/bchain/coins/eth"
"blockbook/bchain/coins/gamecredits"
"blockbook/bchain/coins/grs"
"blockbook/bchain/coins/litecoin"
"blockbook/bchain/coins/monacoin"
@ -44,6 +45,7 @@ func init() {
BlockChainFactories["Bgold"] = btg.NewBGoldRPC
BlockChainFactories["Dash"] = dash.NewDashRPC
BlockChainFactories["Dash Testnet"] = dash.NewDashRPC
BlockChainFactories["GameCredits"] = gamecredits.NewGameCreditsRPC
BlockChainFactories["Litecoin"] = litecoin.NewLitecoinRPC
BlockChainFactories["Litecoin Testnet"] = litecoin.NewLitecoinRPC
BlockChainFactories["Dogecoin"] = dogecoin.NewDogecoinRPC

View File

@ -0,0 +1,63 @@
package gamecredits
import (
"blockbook/bchain/coins/btc"
"github.com/btcsuite/btcd/wire"
"github.com/jakm/btcutil/chaincfg"
)
const (
MainnetMagic wire.BitcoinNet = 0xdbb6c0fb
TestnetMagic wire.BitcoinNet = 0x0709110b
RegtestMagic wire.BitcoinNet = 0xdab5bffa
)
var (
MainNetParams chaincfg.Params
TestNetParams chaincfg.Params
)
func init() {
MainNetParams = chaincfg.MainNetParams
MainNetParams.Net = MainnetMagic
MainNetParams.PubKeyHashAddrID = []byte{38}
MainNetParams.ScriptHashAddrID = []byte{62}
MainNetParams.Bech32HRPSegwit = "game"
TestNetParams = chaincfg.TestNet3Params
TestNetParams.Net = TestnetMagic
TestNetParams.PubKeyHashAddrID = []byte{111}
TestNetParams.ScriptHashAddrID = []byte{58}
TestNetParams.Bech32HRPSegwit = "tgame"
}
// GameCreditsParser handle
type GameCreditsParser struct {
*btc.BitcoinParser
}
// NewGameCreditsParser returns new GameCreditsParser instance
func NewGameCreditsParser(params *chaincfg.Params, c *btc.Configuration) *GameCreditsParser {
return &GameCreditsParser{BitcoinParser: btc.NewBitcoinParser(params, c)}
}
// GetChainParams contains network parameters for the main GameCredits network,
// and the test GameCredits network
func GetChainParams(chain string) *chaincfg.Params {
if !chaincfg.IsRegistered(&MainNetParams) {
err := chaincfg.Register(&MainNetParams)
if err == nil {
err = chaincfg.Register(&TestNetParams)
}
if err != nil {
panic(err)
}
}
switch chain {
case "test":
return &TestNetParams
default:
return &MainNetParams
}
}

View File

@ -0,0 +1,220 @@
// +build unittest
package gamecredits
import (
"blockbook/bchain"
"blockbook/bchain/coins/btc"
"encoding/hex"
"math/big"
"os"
"reflect"
"testing"
"github.com/jakm/btcutil/chaincfg"
)
func TestMain(m *testing.M) {
c := m.Run()
chaincfg.ResetParams()
os.Exit(c)
}
func Test_GetAddrDescFromAddress_Testnet(t *testing.T) {
type args struct {
address string
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "P2PKH1",
args: args{address: "GcGBy77CCfZJJhGLALohdahf9eAc7jo7Yk"},
want: "76a914ca093a938a0e19e86b36859d9423a475d45eb3a288ac",
wantErr: false,
},
{
name: "P2SH1",
args: args{address: "S84eckDshWupTwErdLKkyDauNwtWfa9rPL"},
want: "a9146edfea548a7d6c25aa28e37bf2ea382891882fa687",
wantErr: false,
},
}
parser := NewGameCreditsParser(GetChainParams("test"), &btc.Configuration{})
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parser.GetAddrDescFromAddress(tt.args.address)
if (err != nil) != tt.wantErr {
t.Errorf("GetAddrDescFromAddress() error = %v, wantErr %v", err, tt.wantErr)
return
}
h := hex.EncodeToString(got)
if !reflect.DeepEqual(h, tt.want) {
t.Errorf("GetAddrDescFromAddress() = %v, want %v", h, tt.want)
}
})
}
}
func Test_GetAddrDescFromAddress_Mainnet(t *testing.T) {
type args struct {
address string
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "P2PKH1",
args: args{address: "GcGBy77CCfZJJhGLALohdahf9eAc7jo7Yk"},
want: "76a914ca093a938a0e19e86b36859d9423a475d45eb3a288ac",
wantErr: false,
},
{
name: "P2SH1",
args: args{address: "S84eckDshWupTwErdLKkyDauNwtWfa9rPL"},
want: "a9146edfea548a7d6c25aa28e37bf2ea382891882fa687",
wantErr: false,
},
}
parser := NewGameCreditsParser(GetChainParams("main"), &btc.Configuration{})
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parser.GetAddrDescFromAddress(tt.args.address)
if (err != nil) != tt.wantErr {
t.Errorf("GetAddrDescFromAddress() error = %v, wantErr %v", err, tt.wantErr)
return
}
h := hex.EncodeToString(got)
if !reflect.DeepEqual(h, tt.want) {
t.Errorf("GetAddrDescFromAddress() = %v, want %v", h, tt.want)
}
})
}
}
var (
testTx1 bchain.Tx
testTxPacked1 = "002151148bbcaa8406010000000123c41ad26dd5782635638effbc9e31c9b4a3b757591a52c83d2770ad82b33e93000000006b483045022100a20302bde6d2fb194bb9c0a8d7beb52ed0b5b72b912da75364efe169d5b74c67022065632d4032673a6093f513b93e380323487ad2708003e161a12e7b7362bf9f4a01210325c1b08d90a016cb73f4e8d37614cac7da00cb78121f21b7b6e0a7d4a03fbae4fdffffff0100f4aa01000000001976a914ca093a938a0e19e86b36859d9423a475d45eb3a288acc54f2100"
)
func init() {
testTx1 = bchain.Tx{
Hex: "010000000123c41ad26dd5782635638effbc9e31c9b4a3b757591a52c83d2770ad82b33e93000000006b483045022100a20302bde6d2fb194bb9c0a8d7beb52ed0b5b72b912da75364efe169d5b74c67022065632d4032673a6093f513b93e380323487ad2708003e161a12e7b7362bf9f4a01210325c1b08d90a016cb73f4e8d37614cac7da00cb78121f21b7b6e0a7d4a03fbae4fdffffff0100f4aa01000000001976a914ca093a938a0e19e86b36859d9423a475d45eb3a288acc54f2100",
Blocktime: 1539653891,
Txid: "983da8317fff45afb17290d4dd8da6ec1cd8ffbbfa98e53a0754e9b60f8cc0f9",
LockTime: 2183109,
Version: 1,
Vin: []bchain.Vin{
{
ScriptSig: bchain.ScriptSig{
Hex: "483045022100a20302bde6d2fb194bb9c0a8d7beb52ed0b5b72b912da75364efe169d5b74c67022065632d4032673a6093f513b93e380323487ad2708003e161a12e7b7362bf9f4a01210325c1b08d90a016cb73f4e8d37614cac7da00cb78121f21b7b6e0a7d4a03fbae4",
},
Txid: "933eb382ad70273dc8521a5957b7a3b4c9319ebcff8e63352678d56dd21ac423",
Vout: 0,
Sequence: 4294967293,
},
},
Vout: []bchain.Vout{
{
ValueSat: *big.NewInt(27980800),
N: 0,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a914ca093a938a0e19e86b36859d9423a475d45eb3a288ac",
Addresses: []string{
"GcGBy77CCfZJJhGLALohdahf9eAc7jo7Yk",
},
},
},
},
}
}
func Test_PackTx(t *testing.T) {
type args struct {
tx bchain.Tx
height uint32
blockTime int64
parser *GameCreditsParser
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "gamecredits-1",
args: args{
tx: testTx1,
height: 2183444,
blockTime: 1539653891,
parser: NewGameCreditsParser(GetChainParams("main"), &btc.Configuration{}),
},
want: testTxPacked1,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := tt.args.parser.PackTx(&tt.args.tx, tt.args.height, tt.args.blockTime)
if (err != nil) != tt.wantErr {
t.Errorf("packTx() error = %v, wantErr %v", err, tt.wantErr)
return
}
h := hex.EncodeToString(got)
if !reflect.DeepEqual(h, tt.want) {
t.Errorf("packTx() = %v, want %v", h, tt.want)
}
})
}
}
func Test_UnpackTx(t *testing.T) {
type args struct {
packedTx string
parser *GameCreditsParser
}
tests := []struct {
name string
args args
want *bchain.Tx
want1 uint32
wantErr bool
}{
{
name: "gamecredits-1",
args: args{
packedTx: testTxPacked1,
parser: NewGameCreditsParser(GetChainParams("main"), &btc.Configuration{}),
},
want: &testTx1,
want1: 2183444,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b, _ := hex.DecodeString(tt.args.packedTx)
got, got1, err := tt.args.parser.UnpackTx(b)
if (err != nil) != tt.wantErr {
t.Errorf("unpackTx() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("unpackTx() got = %v, want %v", got, tt.want)
}
if got1 != tt.want1 {
t.Errorf("unpackTx() got1 = %v, want %v", got1, tt.want1)
}
})
}
}

View File

@ -0,0 +1,57 @@
package gamecredits
import (
"blockbook/bchain"
"blockbook/bchain/coins/btc"
"encoding/json"
"github.com/golang/glog"
)
// GameCreditsRPC is an interface to JSON-RPC bitcoind service.
type GameCreditsRPC struct {
*btc.BitcoinRPC
}
// NewGameCreditsRPC returns new GameCreditsRPC instance.
func NewGameCreditsRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) {
b, err := btc.NewBitcoinRPC(config, pushHandler)
if err != nil {
return nil, err
}
s := &GameCreditsRPC{
b.(*btc.BitcoinRPC),
}
s.RPCMarshaler = btc.JSONMarshalerV2{}
s.ChainConfig.SupportsEstimateFee = false
return s, nil
}
// Initialize initializes GameCreditsRPC instance.
func (b *GameCreditsRPC) Initialize() error {
chainName, err := b.GetChainInfoAndInitializeMempool(b)
if err != nil {
return err
}
glog.Info("Chain name ", chainName)
params := GetChainParams(chainName)
// always create parser
b.Parser = NewGameCreditsParser(params, b.ChainConfig)
// parameters for getInfo request
if params.Net == MainnetMagic {
b.Testnet = false
b.Network = "livenet"
} else {
b.Testnet = true
b.Network = "testnet"
}
glog.Info("rpc: block chain ", params.Name)
return nil
}

View File

@ -0,0 +1,65 @@
{
"coin": {
"name": "GameCredits",
"shortcut": "GAME",
"label": "GameCredits",
"alias": "gamecredits"
},
"ports": {
"backend_rpc": 8044,
"backend_message_queue": 38344,
"blockbook_internal": 9044,
"blockbook_public": 9144
},
"ipc": {
"rpc_url_template": "http://127.0.0.1:{{.Ports.BackendRPC}}",
"rpc_user": "rpc",
"rpc_pass": "rpc",
"rpc_timeout": 25,
"message_queue_binding_template": "tcp://127.0.0.1:{{.Ports.BackendMessageQueue}}"
},
"backend": {
"package_name": "backend-gamecredits",
"package_revision": "satoshilabs-1",
"system_user": "gamecredits",
"version": "0.15.3",
"binary_url": "https://github.com/gamecredits-project/GameCredits/releases/download/0.15.3/gamecredits-0.15.3-x86_64-linux-gnu.tar.gz",
"verification_type": "sha256",
"verification_source": "38531ea877dfc1cedd3125bb79216a587f0974f20bee6243efcde61d05e07e5c",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [
"bin/gamecredits-qt"
],
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/gamecreditsd -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",
"service_additional_params_template": "",
"protect_memory": true,
"mainnet": true,
"server_config_file": "bitcoin_like.conf",
"client_config_file": "bitcoin_like_client.conf",
"additional_params": {
"whitelist": "127.0.0.1"
}
},
"blockbook": {
"package_name": "blockbook-gamecredits",
"system_user": "blockbook-gamecredits",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "https://gamecredits.network",
"additional_params": "",
"block_chain": {
"parse": true,
"mempool_workers": 8,
"mempool_sub_workers": 2,
"block_addresses_to_keep": 300,
"additional_params": {}
}
},
"meta": {
"package_maintainer": "Samad Sajanlal",
"package_maintainer_email": "samad@gamecredits.org"
}
}

View File

@ -0,0 +1,47 @@
{
"blockHeight": 20000,
"blockHash": "181a7c4b110ca609df9c7dcc76c5304a02c73fecb768ed659e8025f1f5fb3fb7",
"blockTime": 1395288011,
"blockTxs": [
"2996d6e15d962839e2608315a0cfc9459f4969a0312fea483c1f0529248765ea",
"ba9fdfdb2373d88d20d9ddaa2c9e25820f8e18d852ed5d4062d8e46b7ea1c95e",
"eaea085406cbbee0f46002db388e35c38d526d7b82616c41523a6187c35e549f",
"e647a5cd2e01e7d0ad52869d6b33a9be163fcbe7c3080aca2cfa3e366a71f6de"
],
"txDetails": {
"eaea085406cbbee0f46002db388e35c38d526d7b82616c41523a6187c35e549f": {
"hex": "01000000019e41d32f54bf72489df2846bc58196e29d648cb96bfc0ad89eb2847b1efa0c04000000006c493046022100d87440b92f29e0e79159e5ccc7b76efec31209b88ea1bbdfdf0ff463f250eb1f022100908e71f4f19204d4cfaa0abd6b4753a6b3870052a4721a73cd2bad85f916a9fa012103319f1de23237d05be3dbadd03ab952bbc6641f86c77d0189e5592a4298f39ab9ffffffff0275d0b65f000000001976a91428cd329a2572f3cb19204b02251cbcf485a446f788ace8174606000000001976a914b0ff75d5586d99de1b0a6783c8568ac67f80e3a788ac00000000",
"txid": "eaea085406cbbee0f46002db388e35c38d526d7b82616c41523a6187c35e549f",
"blocktime": 1395288011,
"time": 1395288011,
"locktime": 0,
"version": 1,
"vin": [
{
"txid": "040cfa1e7b84b29ed80afc6bb98c649de29681c56b84f29d4872bf542fd3419e",
"vout": 0,
"scriptSig": {
"hex": "493046022100d87440b92f29e0e79159e5ccc7b76efec31209b88ea1bbdfdf0ff463f250eb1f022100908e71f4f19204d4cfaa0abd6b4753a6b3870052a4721a73cd2bad85f916a9fa012103319f1de23237d05be3dbadd03ab952bbc6641f86c77d0189e5592a4298f39ab9"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 16.05816437,
"n": 0,
"scriptPubKey": {
"hex": "76a91428cd329a2572f3cb19204b02251cbcf485a446f788ac"
}
},
{
"value": 1.05256936,
"n": 1,
"scriptPubKey": {
"hex": "76a914b0ff75d5586d99de1b0a6783c8568ac67f80e3a788ac"
}
}
]
}
}
}

View File

@ -0,0 +1,155 @@
{
"connectBlocks": {
"syncRanges": [
{"lower": 19996, "upper": 20000}
],
"blocks": {
"20000": {
"height": 20000,
"hash": "181a7c4b110ca609df9c7dcc76c5304a02c73fecb768ed659e8025f1f5fb3fb7",
"noTxs": 4,
"txDetails": [
{
"txid": "eaea085406cbbee0f46002db388e35c38d526d7b82616c41523a6187c35e549f",
"version": 1,
"vin": [
{
"txid": "040cfa1e7b84b29ed80afc6bb98c649de29681c56b84f29d4872bf542fd3419e",
"vout": 0,
"scriptSig": {
"hex": "493046022100d87440b92f29e0e79159e5ccc7b76efec31209b88ea1bbdfdf0ff463f250eb1f022100908e71f4f19204d4cfaa0abd6b4753a6b3870052a4721a73cd2bad85f916a9fa012103319f1de23237d05be3dbadd03ab952bbc6641f86c77d0189e5592a4298f39ab9"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 16.05816437,
"n": 0,
"scriptPubKey": {
"hex": "76a91428cd329a2572f3cb19204b02251cbcf485a446f788ac"
}
},
{
"value": 1.05256936,
"n": 1,
"scriptPubKey": {
"hex": "76a914b0ff75d5586d99de1b0a6783c8568ac67f80e3a788ac"
}
}
],
"hex": "01000000019e41d32f54bf72489df2846bc58196e29d648cb96bfc0ad89eb2847b1efa0c04000000006c493046022100d87440b92f29e0e79159e5ccc7b76efec31209b88ea1bbdfdf0ff463f250eb1f022100908e71f4f19204d4cfaa0abd6b4753a6b3870052a4721a73cd2bad85f916a9fa012103319f1de23237d05be3dbadd03ab952bbc6641f86c77d0189e5592a4298f39ab9ffffffff0275d0b65f000000001976a91428cd329a2572f3cb19204b02251cbcf485a446f788ace8174606000000001976a914b0ff75d5586d99de1b0a6783c8568ac67f80e3a788ac00000000",
"time": 1395288011,
"blocktime": 1395288011
},
{
"txid": "e647a5cd2e01e7d0ad52869d6b33a9be163fcbe7c3080aca2cfa3e366a71f6de",
"version": 1,
"vin": [
{
"txid": "4395b4c27cf240d02fa7092f1e7210bf29ce65d08f9b4a4f05a83aa7690cd4f7",
"vout": 0,
"scriptSig": {
"hex": "4830450220465aa4cc8b4d6b3d858cbd9af018468e3c0854c7e6e26fef26bf74c30378b4c2022100a512deb0ef2b82a2862c2c3750400a0760cb249d80b4410860f606f12c19e9da012103c1dbd2cd54ac068dba0a70fe2cfc5faa0390b92c9526d15283d0ed8cc1e1e636"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 7.27384700,
"n": 0,
"scriptPubKey": {
"hex": "76a914c92c955e515850c58ad8e0fa26ebb22b0747fe6d88ac"
}
},
{
"value": 3.93954109,
"n": 1,
"scriptPubKey": {
"hex": "76a914d601816f4e8998e5d1492775f5bd088a5583c65888ac"
}
}
],
"hex": "0100000001f7d40c69a73aa8054f4a9b8fd065ce29bf10721e2f09a72fd040f27cc2b49543000000006b4830450220465aa4cc8b4d6b3d858cbd9af018468e3c0854c7e6e26fef26bf74c30378b4c2022100a512deb0ef2b82a2862c2c3750400a0760cb249d80b4410860f606f12c19e9da012103c1dbd2cd54ac068dba0a70fe2cfc5faa0390b92c9526d15283d0ed8cc1e1e636ffffffff027c025b2b000000001976a914c92c955e515850c58ad8e0fa26ebb22b0747fe6d88ac3d437b17000000001976a914d601816f4e8998e5d1492775f5bd088a5583c65888ac00000000",
"time": 1395288011,
"blocktime": 1395288011
}
]
},
"19996": {
"height": 19996,
"hash": "b637594b407313d29f8c8d2a32c38bb850549e5d430cfc31456c77385e9559b9",
"noTxs": 4,
"txDetails": [
{
"txid": "583985bdb1f41cd828d349a73f683e7b9921464ccf1fee6184af738fc02a4b25",
"version": 1,
"vin": [
{
"txid": "5a301225da616a5bb6041e61ad66b17676e1d93cede5745902cd892674b71e20",
"vout": 0,
"scriptSig": {
"hex": "483045022071fbf14909514638fe2b8827f9b4997516dbebf4642c83f39f905b9571b1ee0d022100f84296fd0e3deea165ef016d6773ddb488105cc53e8c83a37fe1903fce8d6f33012102c945500b3466398c723010b8fd3c74173391724c88515e3fed7989eba7a1b096"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 27.24067865,
"n": 0,
"scriptPubKey": {
"hex": "76a91493ad6d2ce1381cd1902f429f159f588011d1fe7888ac"
}
},
{
"value": 6.58598171,
"n": 1,
"scriptPubKey": {
"hex": "76a91475b80ba9929c5c51dd31fe2ccc4c15e1e18bdb6488ac"
}
}
],
"hex": "0100000001201eb7742689cd025974e5ed3cd9e17676b166ad611e04b65b6a61da2512305a000000006b483045022071fbf14909514638fe2b8827f9b4997516dbebf4642c83f39f905b9571b1ee0d022100f84296fd0e3deea165ef016d6773ddb488105cc53e8c83a37fe1903fce8d6f33012102c945500b3466398c723010b8fd3c74173391724c88515e3fed7989eba7a1b096ffffffff0219fa5da2000000001976a91493ad6d2ce1381cd1902f429f159f588011d1fe7888ac1b694127000000001976a91475b80ba9929c5c51dd31fe2ccc4c15e1e18bdb6488ac00000000",
"time": 1395287965,
"blocktime": 1395287965
}
]
}
}
},
"handleFork": {
"syncRanges": [
{"lower": 19998, "upper": 20000}
],
"fakeBlocks": {
"19998": {
"height": 19998,
"hash": "74316a1bab32d550a572901fd94fb4e27014e0e673ee1d0254fe80af74873fc2"
},
"19999": {
"height": 19999,
"hash": "72a3b6ad6b22bfd3479fd1f7392201a227b449d2fe43af7ce7ecb0f2863052e9"
},
"20000": {
"height": 20000,
"hash": "04373b83f4e6cc80c09fb72af523944903cc7566a1d75308f0e8bf3d41ba8da4"
}
},
"realBlocks": {
"19998": {
"height": 19998,
"hash": "6fe35692d79e74079dbc3f96b1ae7ce06530f69c8eedcec8c543dbcdba0968f0"
},
"19999": {
"height": 19999,
"hash": "f20c6bec1cd52493d8d51b55cde07df3f0742083bfaf22184393f55412edbad3"
},
"20000": {
"height": 20000,
"hash": "181a7c4b110ca609df9c7dcc76c5304a02c73fecb768ed659e8025f1f5fb3fb7"
}
}
}
}

View File

@ -40,6 +40,11 @@
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight",
"GetBlockHeader"]
},
"gamecredits": {
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync",
"EstimateSmartFee", "EstimateFee"],
"sync": ["ConnectBlocksParallel", "ConnectBlocks", "HandleFork"]
},
"groestlcoin": {
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync",
"EstimateSmartFee", "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"],