diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index e280dfba..2d9da669 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -34,6 +34,7 @@ import ( "blockbook/bchain/coins/qtum" "blockbook/bchain/coins/ravencoin" "blockbook/bchain/coins/ritocoin" + "blockbook/bchain/coins/snowgem" "blockbook/bchain/coins/unobtanium" "blockbook/bchain/coins/vertcoin" "blockbook/bchain/coins/viacoin" @@ -108,6 +109,7 @@ func init() { BlockChainFactories["CPUchain"] = cpuchain.NewCPUchainRPC BlockChainFactories["Unobtanium"] = unobtanium.NewUnobtaniumRPC BlockChainFactories["DeepOnion"] = deeponion.NewDeepOnionRPC + BlockChainFactories["SnowGem"] = snowgem.NewSnowGemRPC BlockChainFactories["Bitcore"] = bitcore.NewBitcoreRPC BlockChainFactories["Omotenashicoin"] = omotenashicoin.NewOmotenashiCoinRPC BlockChainFactories["Omotenashicoin Testnet"] = omotenashicoin.NewOmotenashiCoinRPC diff --git a/bchain/coins/snowgem/snowgemparser.go b/bchain/coins/snowgem/snowgemparser.go new file mode 100644 index 00000000..e320f5a3 --- /dev/null +++ b/bchain/coins/snowgem/snowgemparser.go @@ -0,0 +1,98 @@ +package snowgem + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + + "github.com/martinboehm/btcd/wire" + "github.com/martinboehm/btcutil/chaincfg" +) + +const ( + // MainnetMagic is mainnet network constant + MainnetMagic wire.BitcoinNet = 0x6427c824 + // TestnetMagic is testnet network constant + TestnetMagic wire.BitcoinNet = 0xbff91afa + // RegtestMagic is regtest network constant + RegtestMagic wire.BitcoinNet = 0x5f3fe8aa +) + +var ( + // MainNetParams are parser parameters for mainnet + MainNetParams chaincfg.Params + // TestNetParams are parser parameters for testnet + TestNetParams chaincfg.Params + // RegtestParams are parser parameters for regtest + RegtestParams chaincfg.Params +) + +func init() { + MainNetParams = chaincfg.MainNetParams + MainNetParams.Net = MainnetMagic + + // Address encoding magics + MainNetParams.AddressMagicLen = 2 + MainNetParams.PubKeyHashAddrID = []byte{0x1C, 0x28} // base58 prefix: s1 + MainNetParams.ScriptHashAddrID = []byte{0x1C, 0x2D} // base58 prefix: s3 + + TestNetParams = chaincfg.TestNet3Params + TestNetParams.Net = TestnetMagic + + // Address encoding magics + TestNetParams.AddressMagicLen = 2 + TestNetParams.PubKeyHashAddrID = []byte{0x1D, 0x25} // base58 prefix: tm + TestNetParams.ScriptHashAddrID = []byte{0x1C, 0xBA} // base58 prefix: t2 + + RegtestParams = chaincfg.RegressionNetParams + RegtestParams.Net = RegtestMagic +} + +// SnowGemParser handle +type SnowGemParser struct { + *btc.BitcoinParser + baseparser *bchain.BaseParser +} + +// NewSnowGemParser returns new SnowGemParser instance +func NewSnowGemParser(params *chaincfg.Params, c *btc.Configuration) *SnowGemParser { + return &SnowGemParser{ + BitcoinParser: btc.NewBitcoinParser(params, c), + baseparser: &bchain.BaseParser{}, + } +} + +// GetChainParams contains network parameters for the main SnowGem network, +// the regression test SnowGem network, the test SnowGem network and +// the simulation test SnowGem network, in this order +func GetChainParams(chain string) *chaincfg.Params { + if !chaincfg.IsRegistered(&MainNetParams) { + err := chaincfg.Register(&MainNetParams) + if err == nil { + err = chaincfg.Register(&TestNetParams) + } + if err == nil { + err = chaincfg.Register(&RegtestParams) + } + if err != nil { + panic(err) + } + } + switch chain { + case "test": + return &TestNetParams + case "regtest": + return &RegtestParams + default: + return &MainNetParams + } +} + +// PackTx packs transaction to byte array using protobuf +func (p *SnowGemParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) { + return p.baseparser.PackTx(tx, height, blockTime) +} + +// UnpackTx unpacks transaction from protobuf byte array +func (p *SnowGemParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) { + return p.baseparser.UnpackTx(buf) +} diff --git a/bchain/coins/snowgem/snowgemparser_test.go b/bchain/coins/snowgem/snowgemparser_test.go new file mode 100644 index 00000000..c7524191 --- /dev/null +++ b/bchain/coins/snowgem/snowgemparser_test.go @@ -0,0 +1,248 @@ +// +build unittest + +package snowgem + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + "bytes" + "encoding/hex" + "math/big" + "os" + "reflect" + "testing" + + "github.com/martinboehm/btcutil/chaincfg" +) + +var ( + testTx1, testTx2 bchain.Tx + + testTxPacked1 = "0a20241803e368d7459f31286a155191ee386896d366d57c19d8e67a8f040d6ff71f12f4010400008085202f890119950c49d69b37d5f4fbb390d852387559e6a6d3fce9f390a409e4acf3f06381020000006a4730440220452aedf599e575598eb36d27ed98a6d388efda6e9be2bab96f16d0644e7df3060220669f4f3a4976ed73fa3ca9ecaad84dcf6ec35099c3bad631499985ea6a378d19012102ed9fb7fb61ec514be890ab45a925d554ff12050f099514251d5ebe904accc93ffeffffff02d3d0a146000000001976a9141a78c04d87f553545ba225b7bc7a271731f659d688ac7c54ae02000000001976a914b86f4b063545ebc2e80522a59d2dd206b707401b88aca68d0e00c58d0e00000000000000000000000018aba4b8ed0520a69b3a28b19b3a3298010a0012208163f0f3ace409a490f3e9fcd3a6e659753852d890b3fbf4d5379bd6490c95191802226a4730440220452aedf599e575598eb36d27ed98a6d388efda6e9be2bab96f16d0644e7df3060220669f4f3a4976ed73fa3ca9ecaad84dcf6ec35099c3bad631499985ea6a378d19012102ed9fb7fb61ec514be890ab45a925d554ff12050f099514251d5ebe904accc93f28feffffff0f3a480a0446a1d0d310001a1976a9141a78c04d87f553545ba225b7bc7a271731f659d688ac2223733150636953644665724a78665673397451353571446f3839695676466f7162436a7a3a480a0402ae547c10011a1976a914b86f4b063545ebc2e80522a59d2dd206b707401b88ac22237331653177736d6f7955625673794b726745374b73714c5164374c69755961685261524000" + testTxPacked2 = "0a2071dd4d998b0a711fe5ed21f8661ed27ca8b99afc488f5bbe149ec3c6492ec50312d2010400008085202f89017308714b21338783a435c5e420542a0f6243da5be6dc8bdf19e2d526a318d6a8000000006a47304402207ce5ebcb2dc5e8027b5d672babd2e6aaa186a917caf2b44eec63f7db16277b8b02207a89214d825fae08ebc86bca1f46579e770e830bd31b8101498207a2d901fd74012103c3fe8969a7b08f1d586a68da70d6aeff61aa3b4cbe7ca2cb5aae11529ca2af12feffffff014dd45023000000001976a914cef34ec02e80351cf4f9d63843fc79a77c9ab71888acaa8d0e00c98d0e00000000000000000000000018f9a6b8ed0520aa9b3a28b59b3a3298010a001220a8d618a326d5e219df8bdce65bda43620f2a5420e4c535a4838733214b7108731800226a47304402207ce5ebcb2dc5e8027b5d672babd2e6aaa186a917caf2b44eec63f7db16277b8b02207a89214d825fae08ebc86bca1f46579e770e830bd31b8101498207a2d901fd74012103c3fe8969a7b08f1d586a68da70d6aeff61aa3b4cbe7ca2cb5aae11529ca2af1228feffffff0f3a480a042350d44d10001a1976a914cef34ec02e80351cf4f9d63843fc79a77c9ab71888ac2223733167347a74585446447751326b506253385431666755334c645075666376354d764d4000" +) + +func init() { + testTx1 = bchain.Tx{ + Hex: "0400008085202f890119950c49d69b37d5f4fbb390d852387559e6a6d3fce9f390a409e4acf3f06381020000006a4730440220452aedf599e575598eb36d27ed98a6d388efda6e9be2bab96f16d0644e7df3060220669f4f3a4976ed73fa3ca9ecaad84dcf6ec35099c3bad631499985ea6a378d19012102ed9fb7fb61ec514be890ab45a925d554ff12050f099514251d5ebe904accc93ffeffffff02d3d0a146000000001976a9141a78c04d87f553545ba225b7bc7a271731f659d688ac7c54ae02000000001976a914b86f4b063545ebc2e80522a59d2dd206b707401b88aca68d0e00c58d0e000000000000000000000000", + Blocktime: 1571689003, + Time: 1571689003, + Txid: "241803e368d7459f31286a155191ee386896d366d57c19d8e67a8f040d6ff71f", + LockTime: 953766, + Vin: []bchain.Vin{ + { + ScriptSig: bchain.ScriptSig{ + Hex: "4730440220452aedf599e575598eb36d27ed98a6d388efda6e9be2bab96f16d0644e7df3060220669f4f3a4976ed73fa3ca9ecaad84dcf6ec35099c3bad631499985ea6a378d19012102ed9fb7fb61ec514be890ab45a925d554ff12050f099514251d5ebe904accc93f", + }, + Txid: "8163f0f3ace409a490f3e9fcd3a6e659753852d890b3fbf4d5379bd6490c9519", + Vout: 2, + Sequence: 4294967294, + }, + }, + Vout: []bchain.Vout{ + { + ValueSat: *big.NewInt(1185009875), + N: 0, + ScriptPubKey: bchain.ScriptPubKey{ + Hex: "76a9141a78c04d87f553545ba225b7bc7a271731f659d688ac", + Addresses: []string{ + "s1PciSdFerJxfVs9tQ55qDo89iVvFoqbCjz", + }, + }, + }, + { + ValueSat: *big.NewInt(44979324), + N: 1, + ScriptPubKey: bchain.ScriptPubKey{ + Hex: "76a914b86f4b063545ebc2e80522a59d2dd206b707401b88ac", + Addresses: []string{ + "s1e1wsmoyUbVsyKrgE7KsqLQd7LiuYahRaR", + }, + }, + }, + }, + } + + testTx2 = bchain.Tx{ + Hex: "0400008085202f89017308714b21338783a435c5e420542a0f6243da5be6dc8bdf19e2d526a318d6a8000000006a47304402207ce5ebcb2dc5e8027b5d672babd2e6aaa186a917caf2b44eec63f7db16277b8b02207a89214d825fae08ebc86bca1f46579e770e830bd31b8101498207a2d901fd74012103c3fe8969a7b08f1d586a68da70d6aeff61aa3b4cbe7ca2cb5aae11529ca2af12feffffff014dd45023000000001976a914cef34ec02e80351cf4f9d63843fc79a77c9ab71888acaa8d0e00c98d0e000000000000000000000000", + Blocktime: 1571689337, + Time: 1571689337, + Txid: "71dd4d998b0a711fe5ed21f8661ed27ca8b99afc488f5bbe149ec3c6492ec503", + LockTime: 953770, + Vin: []bchain.Vin{ + { + ScriptSig: bchain.ScriptSig{ + Hex: "47304402207ce5ebcb2dc5e8027b5d672babd2e6aaa186a917caf2b44eec63f7db16277b8b02207a89214d825fae08ebc86bca1f46579e770e830bd31b8101498207a2d901fd74012103c3fe8969a7b08f1d586a68da70d6aeff61aa3b4cbe7ca2cb5aae11529ca2af12", + }, + Txid: "a8d618a326d5e219df8bdce65bda43620f2a5420e4c535a4838733214b710873", + Vout: 0, + Sequence: 4294967294, + }, + }, + Vout: []bchain.Vout{ + { + ValueSat: *big.NewInt(592499789), + N: 0, + ScriptPubKey: bchain.ScriptPubKey{ + Hex: "76a914cef34ec02e80351cf4f9d63843fc79a77c9ab71888ac", + Addresses: []string{ + "s1g4ztXTFDwQ2kPbS8T1fgU3LdPufcv5MvM", + }, + }, + }, + }, + } +} + +func TestMain(m *testing.M) { + c := m.Run() + chaincfg.ResetParams() + os.Exit(c) +} + +func TestGetAddrDesc(t *testing.T) { + type args struct { + tx bchain.Tx + parser *SnowGemParser + } + tests := []struct { + name string + args args + }{ + { + name: "snowgem-1", + args: args{ + tx: testTx1, + parser: NewSnowGemParser(GetChainParams("main"), &btc.Configuration{}), + }, + }, + { + name: "snowgem-2", + args: args{ + tx: testTx2, + parser: NewSnowGemParser(GetChainParams("main"), &btc.Configuration{}), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for n, vout := range tt.args.tx.Vout { + got1, err := tt.args.parser.GetAddrDescFromVout(&vout) + if err != nil { + t.Errorf("getAddrDescFromVout() error = %v, vout = %d", err, n) + return + } + got2, err := tt.args.parser.GetAddrDescFromAddress(vout.ScriptPubKey.Addresses[0]) + if err != nil { + t.Errorf("getAddrDescFromAddress() error = %v, vout = %d", err, n) + return + } + if !bytes.Equal(got1, got2) { + t.Errorf("Address descriptors mismatch: got1 = %v, got2 = %v", got1, got2) + } + } + }) + } +} + +func TestPackTx(t *testing.T) { + type args struct { + tx bchain.Tx + height uint32 + blockTime int64 + parser *SnowGemParser + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "snowgem-1", + args: args{ + tx: testTx1, + height: 953777, + blockTime: 1571689003, + parser: NewSnowGemParser(GetChainParams("main"), &btc.Configuration{}), + }, + want: testTxPacked1, + wantErr: false, + }, + { + name: "snowgem-2", + args: args{ + tx: testTx2, + height: 953781, + blockTime: 1571689337, + parser: NewSnowGemParser(GetChainParams("main"), &btc.Configuration{}), + }, + want: testTxPacked2, + 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 TestUnpackTx(t *testing.T) { + type args struct { + packedTx string + parser *SnowGemParser + } + tests := []struct { + name string + args args + want *bchain.Tx + want1 uint32 + wantErr bool + }{ + { + name: "snowgem-1", + args: args{ + packedTx: testTxPacked1, + parser: NewSnowGemParser(GetChainParams("main"), &btc.Configuration{}), + }, + want: &testTx1, + want1: 953777, + wantErr: false, + }, + { + name: "snowgem-2", + args: args{ + packedTx: testTxPacked2, + parser: NewSnowGemParser(GetChainParams("main"), &btc.Configuration{}), + }, + want: &testTx2, + want1: 953781, + 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/snowgem/snowgemrpc.go b/bchain/coins/snowgem/snowgemrpc.go new file mode 100644 index 00000000..0a6b11e4 --- /dev/null +++ b/bchain/coins/snowgem/snowgemrpc.go @@ -0,0 +1,115 @@ +package snowgem + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + "encoding/json" + + "github.com/golang/glog" + "github.com/juju/errors" +) + +// SnowGemRPC is an interface to JSON-RPC bitcoind service +type SnowGemRPC struct { + *btc.BitcoinRPC +} + +// NewSnowGemRPC returns new SnowGemRPC instance +func NewSnowGemRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) { + b, err := btc.NewBitcoinRPC(config, pushHandler) + if err != nil { + return nil, err + } + z := &SnowGemRPC{ + BitcoinRPC: b.(*btc.BitcoinRPC), + } + z.RPCMarshaler = btc.JSONMarshalerV1{} + z.ChainConfig.SupportsEstimateSmartFee = false + return z, nil +} + +// Initialize initializes SnowGemRPC instance +func (z *SnowGemRPC) Initialize() error { + ci, err := z.GetChainInfo() + if err != nil { + return err + } + chainName := ci.Chain + + params := GetChainParams(chainName) + + z.Parser = NewSnowGemParser(params, z.ChainConfig) + + // parameters for getInfo request + if params.Net == MainnetMagic { + z.Testnet = false + z.Network = "livenet" + } else { + z.Testnet = true + z.Network = "testnet" + } + + glog.Info("rpc: block chain ", params.Name) + + return nil +} + +// GetBlock returns block with given hash. +func (z *SnowGemRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) { + var err error + if hash == "" && height > 0 { + hash, err = z.GetBlockHash(height) + if err != nil { + return nil, err + } + } + + glog.V(1).Info("rpc: getblock (verbosity=1) ", hash) + + res := btc.ResGetBlockThin{} + req := btc.CmdGetBlock{Method: "getblock"} + req.Params.BlockHash = hash + req.Params.Verbosity = 1 + err = z.Call(&req, &res) + + if err != nil { + return nil, errors.Annotatef(err, "hash %v", hash) + } + if res.Error != nil { + return nil, errors.Annotatef(res.Error, "hash %v", hash) + } + + txs := make([]bchain.Tx, 0, len(res.Result.Txids)) + for _, txid := range res.Result.Txids { + tx, err := z.GetTransaction(txid) + if err != nil { + if err == bchain.ErrTxNotFound { + glog.Errorf("rpc: getblock: skipping transanction in block %s due error: %s", hash, err) + continue + } + return nil, err + } + txs = append(txs, *tx) + } + block := &bchain.Block{ + BlockHeader: res.Result.BlockHeader, + Txs: txs, + } + return block, nil +} + +// GetTransactionForMempool returns a transaction by the transaction ID. +// It could be optimized for mempool, i.e. without block time and confirmations +func (z *SnowGemRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) { + return z.GetTransaction(txid) +} + +// GetMempoolEntry returns mempool data for given transaction +func (z *SnowGemRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error) { + return nil, errors.New("GetMempoolEntry: not implemented") +} + +func isErrBlockNotFound(err *bchain.RPCError) bool { + return err.Message == "Block not found" || + err.Message == "Block height out of range" +} diff --git a/configs/coins/snowgem.json b/configs/coins/snowgem.json new file mode 100644 index 00000000..0550ae34 --- /dev/null +++ b/configs/coins/snowgem.json @@ -0,0 +1,72 @@ +{ + "coin": { + "name": "SnowGem", + "shortcut": "XSG", + "label": "SnowGem", + "alias": "snowgem" + }, + "ports": { + "backend_rpc": 8062, + "backend_message_queue": 38362, + "blockbook_internal": 9062, + "blockbook_public": 9162 + }, + "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-snowgem", + "package_revision": "satoshilabs-1", + "system_user": "snowgem", + "version": "3.0.4-7", + "binary_url": "https://github.com/Snowgem/Snowgem/releases/download/v3000457-20190909/snowgem-debian9.11.0-3000457-20190926.zip", + "verification_type": "sha256", + "verification_source": "c5583bd31c8de86b19c481cf2c6445ebc1129e74fafc05e205064eb776ca96d3", + "extract_command": "unzip -j -d backend", + "exclude_files": [], + "exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/snowgemd -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": "HOME={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend {{.Env.BackendInstallPath}}/{{.Coin.Alias}}/fetch-params.sh", + "service_type": "forking", + "service_additional_params_template": "Environment=\"HOME={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend\"", + "protect_memory": false, + "mainnet": true, + "server_config_file": "bitcoin_like.conf", + "client_config_file": "bitcoin_like_client.conf", + "additional_params": { + "addnode": [ + "seednode1.snowgem.org", + "seednode2.snowgem.org", + "seednode3.snowgem.org", + "explorer.snowgem.org", + "explorer1.snowgem.org", + "explorer2.snowgem.org" + ] + } + }, + "blockbook": { + "package_name": "blockbook-snowgem", + "system_user": "blockbook-snowgem", + "internal_binding_template": ":{{.Ports.BlockbookInternal}}", + "public_binding_template": ":{{.Ports.BlockbookPublic}}", + "explorer_url": "", + "additional_params": "", + "block_chain": { + "parse": true, + "mempool_workers": 4, + "mempool_sub_workers": 8, + "block_addresses_to_keep": 300, + "xpub_magic": 76067358, + "slip44": 410, + "additional_params": {} + } + }, + "meta": { + "package_maintainer": "Amitabha", + "package_maintainer_email": "nedelcu.alexandru@yahoo.com" + } +} diff --git a/docs/ports.md b/docs/ports.md index 9a2450f7..78293ccf 100644 --- a/docs/ports.md +++ b/docs/ports.md @@ -34,6 +34,7 @@ | Ravencoin | 9059 | 9159 | 8059 | 38359 | | Ritocoin | 9060 | 9160 | 8060 | 38360 | | Decred | 9061 | 9161 | 8061 | 38361 | +| SnowGem | 9062 | 9162 | 8062 | 38362 | | Flo | 9066 | 9166 | 8066 | 38366 | | Polis | 9067 | 9167 | 8067 | 38367 | | Qtum | 9088 | 9188 | 8088 | 38388 | diff --git a/docs/testing.md b/docs/testing.md index 3426a9e3..aa6de9ee 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -42,7 +42,7 @@ It perfectly fits with layered test definitions. For example, you can: * run tests for single coin – `make test-integration ARGS="-run=TestIntegration/bitcoin/"` * run single test suite – `make test-integration ARGS="-run=TestIntegration//sync/"` * run single test – `make test-integration ARGS="-run=TestIntegration//sync/HandleFork"` -* run tests for set of coins – `make test-integration ARGS="-run='TestIntegration/(bcash|bgold|bitcoin|dash|dogecoin|litecoin|vertcoin|zcash|zelcash)/'"` +* run tests for set of coins – `make test-integration ARGS="-run='TestIntegration/(bcash|bgold|bitcoin|dash|dogecoin|litecoin|snowgem|vertcoin|zcash|zelcash)/'"` Test fixtures are defined in *testdata* directory in package of particular test suite. They are separate JSON files named by coin. File schemes are very similar with verbose results of CLI tools and are described below. Integration tests diff --git a/tests/rpc/testdata/snowgem.json b/tests/rpc/testdata/snowgem.json new file mode 100644 index 00000000..67e4647e --- /dev/null +++ b/tests/rpc/testdata/snowgem.json @@ -0,0 +1,150 @@ +{ + "blockHeight":917888, + "blockHash":"00000662d02c2fcf3dd53f38a551db8e01e06cd1f6e26567cbaf1100208feba4", + "blockTime":1569520212, + "blockTxs":[ + "fbbd4595cc152ee19d3f160dccfca5af7589dfad8e5867e671b5ae8dfe434533", + "b1ab0b7bc4f30dea352ba6b641777d0ed6157027625aacb36da1c5eedc28e157", + "3d5b131f9e39070d595a89ac09426f62f8ea914e6af3a0ff0c592c9f9a9a68af", + "0fc8c13e18de2c4f95ce5651dd9386b75da679570c27d9b458cbe3e0340a71c3", + "fc192471f04051fcdf2669273c54c3ce75c472e312a2af0f885bd8bd8d718bf8" + ], + "txDetails":{ + "b1ab0b7bc4f30dea352ba6b641777d0ed6157027625aacb36da1c5eedc28e157":{ + "hex":"0400008085202f8901d79a4bae6a56937ddbe26fa44ad8eedc389a415fcbbf75a46ef1500cd0837e5d000000006a47304402207d7268375db5a1544368fa9a3c4e77244bc36c3ecf18b21a409f267f1436aac802202e0d7f4abafab362607d70c88a35cc50bfb4f5643d9f8d5208f5db0862946dd2012103af4c37554efb4420c42edc2f7a84e3e687dc050a832afb6ac5bcc12cfb903fbffeffffff0584f1f81f000000001976a914b38cf949ff45875224793172f8333c43e657e3e888aca61ef369000000001976a914559f99e0b3f83666cb0ef0b55c1c367b68e1d65988ac20d55023000000001976a9147a7b884e38d58bbfffbec0a0f0bee44336ca1e8a88ac205c5071000000001976a9149d0da224652d49091082f0b1c2e2b713cbceb47a88ac20d55023000000001976a91406a5e5f229d7bfd6b979747c92e6e1f6dcc95c3488ac74010e0093010e000000000000000000000000", + "txid":"b1ab0b7bc4f30dea352ba6b641777d0ed6157027625aacb36da1c5eedc28e157", + "blocktime":1569520212, + "time":1569520212, + "locktime":917876, + "version":4, + "vin":[ + { + "txid":"5d7e83d00c50f16ea475bfcb5f419a38dceed84aa46fe2db7d93566aae4b9ad7", + "vout":0, + "sequence":4294967294, + "n":0, + "scriptSig":{ + "hex":"47304402207d7268375db5a1544368fa9a3c4e77244bc36c3ecf18b21a409f267f1436aac802202e0d7f4abafab362607d70c88a35cc50bfb4f5643d9f8d5208f5db0862946dd2012103af4c37554efb4420c42edc2f7a84e3e687dc050a832afb6ac5bcc12cfb903fbf", + "asm":"304402207d7268375db5a1544368fa9a3c4e77244bc36c3ecf18b21a409f267f1436aac802202e0d7f4abafab362607d70c88a35cc50bfb4f5643d9f8d5208f5db0862946dd2[ALL] 03af4c37554efb4420c42edc2f7a84e3e687dc050a832afb6ac5bcc12cfb903fbf" + }, + "addr":"s1YHHWM4vUV6fDHv4CgUG2Uj3b2s9fe5FFw", + "valueZat":5400041445, + "value":54.00041445, + "doubleSpentTxID":null + } + ], + "vout":[ + { + "value":"5.36408452", + "n":0, + "scriptPubKey":{ + "hex":"76a914b38cf949ff45875224793172f8333c43e657e3e888ac", + "asm":"OP_DUP OP_HASH160 b38cf949ff45875224793172f8333c43e657e3e8 OP_EQUALVERIFY OP_CHECKSIG", + "addresses":[ + "s1da844qW7tuQvbtqMERetbCYuqnHwy5k9L" + ], + "type":"pubkeyhash" + } + }, + { + "value":"17.77540774", + "n":1, + "scriptPubKey":{ + "hex":"76a914559f99e0b3f83666cb0ef0b55c1c367b68e1d65988ac", + "asm":"OP_DUP OP_HASH160 559f99e0b3f83666cb0ef0b55c1c367b68e1d659 OP_EQUALVERIFY OP_CHECKSIG", + "addresses":[ + "s1V1UrHL8MFmUB8cEfrfaLhjxo8FA4D9w5W" + ], + "type":"pubkeyhash" + } + }, + { + "value":"5.92500000", + "n":2, + "scriptPubKey":{ + "hex":"76a9147a7b884e38d58bbfffbec0a0f0bee44336ca1e8a88ac", + "asm":"OP_DUP OP_HASH160 7a7b884e38d58bbfffbec0a0f0bee44336ca1e8a OP_EQUALVERIFY OP_CHECKSIG", + "addresses":[ + "s1YNNeHbZZW4biHAKj8G9HyA7QwHDrWPo7C" + ], + "type":"pubkeyhash" + } + }, + { + "value":"19.01091872", + "n":3, + "scriptPubKey":{ + "hex":"76a9149d0da224652d49091082f0b1c2e2b713cbceb47a88ac", + "asm":"OP_DUP OP_HASH160 9d0da224652d49091082f0b1c2e2b713cbceb47a OP_EQUALVERIFY OP_CHECKSIG", + "addresses":[ + "s1bXAe5ZFY69SH4NckixTFfJjYaApyCWzkb" + ], + "type":"pubkeyhash" + } + }, + { + "value":"5.92500000", + "n":4, + "scriptPubKey":{ + "hex":"76a91406a5e5f229d7bfd6b979747c92e6e1f6dcc95c3488ac", + "asm":"OP_DUP OP_HASH160 06a5e5f229d7bfd6b979747c92e6e1f6dcc95c34 OP_EQUALVERIFY OP_CHECKSIG", + "addresses":[ + "s1Mou1fHFBFDaW54DtBJFG6iYNKMe55gi8x" + ], + "type":"pubkeyhash" + } + } + ] + }, + "3d5b131f9e39070d595a89ac09426f62f8ea914e6af3a0ff0c592c9f9a9a68af":{ + "hex":"0400008085202f890156b8879f14dcc4290d211a0ff14b7e91e55c67e7e776bc84cd69d712c025eef9000000006a4730440220144962d60a9aa0ebcf588bd2e6e2318688638ebcd304ab6f8e1d885a8519584102204f7f79bc5a20d19e5cc8cb30d4a540abe6a4c5899687f8165ea4f2aecf37dfae01210249172fff41eb94f01fb91c40aa833a8f448dcb1e04a9ca4eda609448cd62f6a8feffffff02d3952606000000001976a9141b94f6e3fc8601a3d9c059548e880c50738603db88ac691e868c000000001976a914f1af4ea3681f7d71cb7eaf55d899b9b78b1e095f88ac75010e0094010e000000000000000000000000", + "txid":"3d5b131f9e39070d595a89ac09426f62f8ea914e6af3a0ff0c592c9f9a9a68af", + "blocktime":1569520212, + "time":1569520212, + "locktime":917877, + "version":4, + "vin":[ + { + "txid":"f9ee25c012d769cd84bc76e7e7675ce5917e4bf10f1a210d29c4dc149f87b856", + "vout":0, + "sequence":4294967294, + "n":0, + "scriptSig":{ + "hex":"4730440220144962d60a9aa0ebcf588bd2e6e2318688638ebcd304ab6f8e1d885a8519584102204f7f79bc5a20d19e5cc8cb30d4a540abe6a4c5899687f8165ea4f2aecf37dfae01210249172fff41eb94f01fb91c40aa833a8f448dcb1e04a9ca4eda609448cd62f6a8", + "asm":"30440220144962d60a9aa0ebcf588bd2e6e2318688638ebcd304ab6f8e1d885a8519584102204f7f79bc5a20d19e5cc8cb30d4a540abe6a4c5899687f8165ea4f2aecf37dfae[ALL] 0249172fff41eb94f01fb91c40aa833a8f448dcb1e04a9ca4eda609448cd62f6a8" + }, + "addr":"s1ikGwxJc6MTs3nWWc7ZTMMGLJtZwJwZedH", + "valueZat":2460792113, + "value":24.60792113, + "doubleSpentTxID":null + } + ], + "vout":[ + { + "value":"1.03192019", + "n":0, + "scriptPubKey":{ + "hex":"76a9141b94f6e3fc8601a3d9c059548e880c50738603db88ac", + "asm":"OP_DUP OP_HASH160 1b94f6e3fc8601a3d9c059548e880c50738603db OP_EQUALVERIFY OP_CHECKSIG", + "addresses":[ + "s1Piav7BuN4kn2AnTb4SdzkHQsw8UHQiu7n" + ], + "type":"pubkeyhash" + } + }, + { + "value":"23.57599849", + "n":1, + "scriptPubKey":{ + "hex":"76a914f1af4ea3681f7d71cb7eaf55d899b9b78b1e095f88ac", + "asm":"OP_DUP OP_HASH160 f1af4ea3681f7d71cb7eaf55d899b9b78b1e095f OP_EQUALVERIFY OP_CHECKSIG", + "addresses":[ + "s1jEf5VB8hseLWbw5HUUuSZnzYGQQBKi3nb" + ], + "type":"pubkeyhash" + } + } + ] + } + } +} diff --git a/tests/sync/testdata/snowgem.json b/tests/sync/testdata/snowgem.json new file mode 100644 index 00000000..2b24a403 --- /dev/null +++ b/tests/sync/testdata/snowgem.json @@ -0,0 +1,239 @@ +{ + "connectBlocks": { + "syncRanges": [ + { + "lower": 943331, + "upper": 943351 + } + ], + "blocks": { + "943349": { + "height": 943349, + "hash": "000007d5b11959867bf46720791a6799d83d87de9384d2f5f3f892bc52d8c281", + "noTxs": 10, + "txDetails": [ + { + "hex": "0400008085202f89025f30318bdb82c4a6a5ac5b870f171127ecfa508da040ba801bd0cad8be351427000000006b483045022100fc76eac8cf79322a4da3d7d2e097813b2d69546fbe0a1b6ef397b7ec15d0082f0220189f66e38da34ee8cd7d3345e7c04b461a0a51e4a7d24ada54d0f778a0e0623e012103c5431c6d472a228bd3e6e78bc26fa4b18b018a4c8043baa7364135376dfd8508feffffffea9069e91fa1abd7a937a92e1275b1ff0f0926c706ca43abfeaba664743e1af2030000006a473044022079fd5b5df1af2ce9ce9bcd2c135dd170d4efe21af3033955a6a545e61565d66002202199b916f6e114367ae1a315400f48366d5e108b90f442ca5124f0e8afd9804101210399d3bcde8bfae660708bd01fc0721e50ff0a3daa37b2145b2d1218e1bac59a47feffffff045c2c2813000000001976a91480eca29dfabef283f5018ba0897edf004c2b080188ac71b5760a000000001976a914ee71004bfceea3150b26677b6394363f224c7d7688acf39af204000000001976a9147abec94753493aa2605e98e9f793a556f962b26688ac146f4700000000001976a914d37c693d4e726e8856018fae6d5bc1a66a36bed388acea640e0009650e000000000000000000000000", + "txid": "bb3720854b9632491f9eeb47b51267acd42a7deef314fac8a82ab91be369ffcd", + "version": 4, + "vin":[ + { + "txid":"271435bed8cad01b80ba40a08d50faec2711170f875baca5a6c482db8b31305f", + "vout":0, + "sequence":4294967294, + "n":0, + "scriptSig":{ + "hex":"483045022100fc76eac8cf79322a4da3d7d2e097813b2d69546fbe0a1b6ef397b7ec15d0082f0220189f66e38da34ee8cd7d3345e7c04b461a0a51e4a7d24ada54d0f778a0e0623e012103c5431c6d472a228bd3e6e78bc26fa4b18b018a4c8043baa7364135376dfd8508", + "asm":"3045022100fc76eac8cf79322a4da3d7d2e097813b2d69546fbe0a1b6ef397b7ec15d0082f0220189f66e38da34ee8cd7d3345e7c04b461a0a51e4a7d24ada54d0f778a0e0623e[ALL] 03c5431c6d472a228bd3e6e78bc26fa4b18b018a4c8043baa7364135376dfd8508" + }, + "addr":"s1XpTwKfMfbgeDawaB62WCiDtqwcZh3CctP", + "valueZat":579980000, + "value":5.7998, + "doubleSpentTxID":null + }, + { + "txid":"f21a3e7464a6abfeab43ca06c726090fffb175122ea937a9d7aba11fe96990ea", + "vout":3, + "sequence":4294967294, + "n":1, + "scriptSig":{ + "hex":"473044022079fd5b5df1af2ce9ce9bcd2c135dd170d4efe21af3033955a6a545e61565d66002202199b916f6e114367ae1a315400f48366d5e108b90f442ca5124f0e8afd9804101210399d3bcde8bfae660708bd01fc0721e50ff0a3daa37b2145b2d1218e1bac59a47", + "asm":"3044022079fd5b5df1af2ce9ce9bcd2c135dd170d4efe21af3033955a6a545e61565d66002202199b916f6e114367ae1a315400f48366d5e108b90f442ca5124f0e8afd98041[ALL] 0399d3bcde8bfae660708bd01fc0721e50ff0a3daa37b2145b2d1218e1bac59a47" + }, + "addr":"s1NEhKJELW4RWbpGoDVmXQTQqo1ivktbnYU", + "valueZat":4661952, + "value":0.04661952, + "doubleSpentTxID":null + } + ], + "vout":[ +{ +"value":"3.21399900", +"n":0, +"scriptPubKey":{ +"hex":"76a91480eca29dfabef283f5018ba0897edf004c2b080188ac", +"asm":"OP_DUP OP_HASH160 80eca29dfabef283f5018ba0897edf004c2b0801 OP_EQUALVERIFY OP_CHECKSIG", +"addresses":[ +"s1YxSBxT1Wu6vzqgs1N6Hph7VLmRUPJNdZw" +], +"type":"pubkeyhash" +} +}, +{ +"value":"1.75551857", +"n":1, +"scriptPubKey":{ +"hex":"76a914ee71004bfceea3150b26677b6394363f224c7d7688ac", +"asm":"OP_DUP OP_HASH160 ee71004bfceea3150b26677b6394363f224c7d76 OP_EQUALVERIFY OP_CHECKSIG", +"addresses":[ +"s1iwWQp6dVVovMFyHfwJaUmxpZhrveDDzrK" +], +"type":"pubkeyhash" +} +}, +{ +"value":"0.83008243", +"n":2, +"scriptPubKey":{ +"hex":"76a9147abec94753493aa2605e98e9f793a556f962b26688ac", +"asm":"OP_DUP OP_HASH160 7abec94753493aa2605e98e9f793a556f962b266 OP_EQUALVERIFY OP_CHECKSIG", +"addresses":[ +"s1YPmDAQUhykLKjkGSvV7pxn28YL6mbKzce" +], +"type":"pubkeyhash" +} +}, +{ +"value":"0.04681492", +"n":3, +"scriptPubKey":{ +"hex":"76a914d37c693d4e726e8856018fae6d5bc1a66a36bed388ac", +"asm":"OP_DUP OP_HASH160 d37c693d4e726e8856018fae6d5bc1a66a36bed3 OP_EQUALVERIFY OP_CHECKSIG", +"addresses":[ +"s1gUyqQhV5ru7XvErupwxgxHH3Zkvv1c917" +], +"type":"pubkeyhash" +} +} +], + "blockhash": "000007d5b11959867bf46720791a6799d83d87de9384d2f5f3f892bc52d8c281", + "time": 1571060124, + "blocktime": 1571060124 + }, + { + "hex": "0400008085202f8902142080004eebe2717ecbd4c1c76f2be9ffa21852f1d01b119876f45e78d17702000000006a473044022078cee145819259dcd48c39ea775879f97376ac83dccd43169d3bfd0e1b366a46022041de61b262ea8c52c2f690369e01fdc2173d458a7b6301d18de9443a31f4033c0121031d8aa9aac23547fd74cc684b97b44522411c2dd46b2e5a976506e4fd03a6ddc4feffffff7cd5b3f717a0a47c417272fa89713ba2cdb02158ffb5b098086521a40817a852030000006b4830450221009eb6971b2987eb820876d0645c6356889d1c0c9da0cd27f21f10fa1b5012a4b6022008acfec60206c53d0a4cc07264887d995ab48b82f72806d02d415ccfb931bfc3012102325fcd6c5832bd35fd3a21deac58eac116a47e470a64e1c832abb761d2c34960feffffff046faa3b11000000001976a914c4add9b9b3821a8980429b5cca3d7e01b80372b988ac0189cb0c000000001976a914ee71004bfceea3150b26677b6394363f224c7d7688acf7121a00000000001976a914eed272078828027547346245251850b1b6227e0588ac39562305000000001976a9141e62bd8aabfa73997d2cf018255e2e981e50d7ce88acea640e0009650e000000000000000000000000", + "txid": "80a8b77f8dd5ce0d3a4a6d4b54219a6989d266eb4dabb9ee5de1b5252040a841", + "version": 4, + "vin":[ + { + "txid":"0277d1785ef47698111bd0f15218a2ffe92b6fc7c1d4cb7e71e2eb4e00802014", + "vout":0, + "sequence":4294967294, + "n":0, + "scriptSig":{ + "hex":"473044022078cee145819259dcd48c39ea775879f97376ac83dccd43169d3bfd0e1b366a46022041de61b262ea8c52c2f690369e01fdc2173d458a7b6301d18de9443a31f4033c0121031d8aa9aac23547fd74cc684b97b44522411c2dd46b2e5a976506e4fd03a6ddc4", + "asm":"3044022078cee145819259dcd48c39ea775879f97376ac83dccd43169d3bfd0e1b366a46022041de61b262ea8c52c2f690369e01fdc2173d458a7b6301d18de9443a31f4033c[ALL] 031d8aa9aac23547fd74cc684b97b44522411c2dd46b2e5a976506e4fd03a6ddc4" + }, + "addr":"s1dXDK6JqSjPXrtV7WUn4M91wJoYN4DyTzF", + "valueZat":589980000, + "value":5.8998, + "doubleSpentTxID":null + }, + { + "txid":"52a81708a421650898b0b5ff5821b0cda23b7189fa7272417ca4a017f7b3d57c", + "vout":3, + "sequence":4294967294, + "n":1, + "scriptSig":{ + "hex":"4830450221009eb6971b2987eb820876d0645c6356889d1c0c9da0cd27f21f10fa1b5012a4b6022008acfec60206c53d0a4cc07264887d995ab48b82f72806d02d415ccfb931bfc3012102325fcd6c5832bd35fd3a21deac58eac116a47e470a64e1c832abb761d2c34960", + "asm":"30450221009eb6971b2987eb820876d0645c6356889d1c0c9da0cd27f21f10fa1b5012a4b6022008acfec60206c53d0a4cc07264887d995ab48b82f72806d02d415ccfb931bfc3[ALL] 02325fcd6c5832bd35fd3a21deac58eac116a47e470a64e1c832abb761d2c34960" + }, + "addr":"s1YyURMT6a7KpKxmn8K8qqo7dJ1crpzMYSD", + "valueZat":1719564, + "value":0.01719564, + "doubleSpentTxID":null + } + ], + "vout":[ +{ +"value":"2.89122927", +"n":0, +"scriptPubKey":{ +"hex":"76a914c4add9b9b3821a8980429b5cca3d7e01b80372b988ac", +"asm":"OP_DUP OP_HASH160 c4add9b9b3821a8980429b5cca3d7e01b80372b9 OP_EQUALVERIFY OP_CHECKSIG", +"addresses":[ +"s1f8gveARasBFZA7yWLja6neqkysD2591wv" +], +"type":"pubkeyhash" +} +}, +{ +"value":"2.14665473", +"n":1, +"scriptPubKey":{ +"hex":"76a914ee71004bfceea3150b26677b6394363f224c7d7688ac", +"asm":"OP_DUP OP_HASH160 ee71004bfceea3150b26677b6394363f224c7d76 OP_EQUALVERIFY OP_CHECKSIG", +"addresses":[ +"s1iwWQp6dVVovMFyHfwJaUmxpZhrveDDzrK" +], +"type":"pubkeyhash" +} +}, +{ +"value":"0.01708791", +"n":2, +"scriptPubKey":{ +"hex":"76a914eed272078828027547346245251850b1b6227e0588ac", +"asm":"OP_DUP OP_HASH160 eed272078828027547346245251850b1b6227e05 OP_EQUALVERIFY OP_CHECKSIG", +"addresses":[ +"s1iyX9MnpyyZqHgVSC4QLDTfRD9TV5FPYPy" +], +"type":"pubkeyhash" +} +}, +{ +"value":"0.86201913", +"n":3, +"scriptPubKey":{ +"hex":"76a9141e62bd8aabfa73997d2cf018255e2e981e50d7ce88ac", +"asm":"OP_DUP OP_HASH160 1e62bd8aabfa73997d2cf018255e2e981e50d7ce OP_EQUALVERIFY OP_CHECKSIG", +"addresses":[ +"s1PyQn4FuzA7CMfmc1N48dZTT3v12vrmCJy" +], +"type":"pubkeyhash" +} +} +], + "blockhash": "000007d5b11959867bf46720791a6799d83d87de9384d2f5f3f892bc52d8c281", + "time": 1571060124, + "blocktime": 1571060124 + } + ] + } + } + }, + "handleFork": { + "syncRanges": [ + { + "lower": 943331, + "upper": 943351 + } + ], + "fakeBlocks": { + "943348": { + "height": 943348, + "hash": "000006ee20e7b5786deb6d85026c506dd6e8818595ad0294794696216d5f9ebb" + }, + "943349": { + "height": 943349, + "hash": "0000019cb463362807e0039d994be5aa1cd825a750d1247d2bdd2a02d5f928b5" + }, + "943350": { + "height": 943350, + "hash": "0000033273a875149c0f443c9857696a9c76244c60fc952d710b17647c139dfe" + }, + "943351": { + "height": 943351, + "hash": "000007228f8f328fae080b58d9953f8da05c51083dce5ca30d88fa986be43ea3" + } + }, + "realBlocks": { + "943348": { + "height": 943348, + "hash": "0000088a040ab7ce267433641c9c0589db78a0166e61b8fe1d9651944f76516e" + }, + "943349": { + "height": 943349, + "hash": "000007d5b11959867bf46720791a6799d83d87de9384d2f5f3f892bc52d8c281" + }, + "943350": { + "height": 943350, + "hash": "000000fe40bbd6dec887ef4dceea547fd28b8ece496e2c2202bfdff5da9f3462" + }, + "943351": { + "height": 943351, + "hash": "0000039f0e6e3b4be8ccfdbfd9758784a8258e09053a5270c0843fc7fa3788eb" + } + } + } +} \ No newline at end of file diff --git a/tests/tests.json b/tests/tests.json index da443d97..49ae8212 100644 --- a/tests/tests.json +++ b/tests/tests.json @@ -206,6 +206,11 @@ "GetBestBlockHash", "GetBestBlockHeight"], "sync": ["ConnectBlocksParallel", "ConnectBlocks"] }, + "snowgem": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", + "EstimateSmartFee", "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"], + "sync": ["ConnectBlocksParallel", "ConnectBlocks", "HandleFork"] + }, "omotenashicoin": { "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight"],