From 4cd6b3b49c8547761f74931ee42d07f3e81ca7a8 Mon Sep 17 00:00:00 2001 From: Samad Sajanlal Date: Wed, 24 Oct 2018 04:33:26 -0500 Subject: [PATCH] add GameCredits (GAME) to Blockbook (#79) * add GameCredits (GAME) to Blockbook * add GameCredits (GAME) integration tests --- bchain/coins/blockchain.go | 2 + bchain/coins/gamecredits/gamecreditsparser.go | 63 +++++ .../gamecredits/gamecreditsparser_test.go | 220 ++++++++++++++++++ bchain/coins/gamecredits/gamecreditsrpc.go | 57 +++++ configs/coins/gamecredits.json | 65 ++++++ tests/rpc/testdata/gamecredits.json | 47 ++++ tests/sync/testdata/gamecredits.json | 155 ++++++++++++ tests/tests.json | 5 + 8 files changed, 614 insertions(+) create mode 100644 bchain/coins/gamecredits/gamecreditsparser.go create mode 100644 bchain/coins/gamecredits/gamecreditsparser_test.go create mode 100644 bchain/coins/gamecredits/gamecreditsrpc.go create mode 100644 configs/coins/gamecredits.json create mode 100644 tests/rpc/testdata/gamecredits.json create mode 100644 tests/sync/testdata/gamecredits.json diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index da2df8b8..1deb839f 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -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 diff --git a/bchain/coins/gamecredits/gamecreditsparser.go b/bchain/coins/gamecredits/gamecreditsparser.go new file mode 100644 index 00000000..39c2808c --- /dev/null +++ b/bchain/coins/gamecredits/gamecreditsparser.go @@ -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 + } +} diff --git a/bchain/coins/gamecredits/gamecreditsparser_test.go b/bchain/coins/gamecredits/gamecreditsparser_test.go new file mode 100644 index 00000000..17074f6b --- /dev/null +++ b/bchain/coins/gamecredits/gamecreditsparser_test.go @@ -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) + } + }) + } +} diff --git a/bchain/coins/gamecredits/gamecreditsrpc.go b/bchain/coins/gamecredits/gamecreditsrpc.go new file mode 100644 index 00000000..bb3cecb0 --- /dev/null +++ b/bchain/coins/gamecredits/gamecreditsrpc.go @@ -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 +} diff --git a/configs/coins/gamecredits.json b/configs/coins/gamecredits.json new file mode 100644 index 00000000..bfdb5744 --- /dev/null +++ b/configs/coins/gamecredits.json @@ -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" + } +} diff --git a/tests/rpc/testdata/gamecredits.json b/tests/rpc/testdata/gamecredits.json new file mode 100644 index 00000000..c2557e91 --- /dev/null +++ b/tests/rpc/testdata/gamecredits.json @@ -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" + } + } + ] + } + } +} \ No newline at end of file diff --git a/tests/sync/testdata/gamecredits.json b/tests/sync/testdata/gamecredits.json new file mode 100644 index 00000000..71ffd3c8 --- /dev/null +++ b/tests/sync/testdata/gamecredits.json @@ -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" + } + } + } +} diff --git a/tests/tests.json b/tests/tests.json index f567aba7..d0b749e8 100644 --- a/tests/tests.json +++ b/tests/tests.json @@ -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"],