diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index df1514bd..0ce5e626 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -9,6 +9,7 @@ import ( "blockbook/bchain/coins/cpuchain" "blockbook/bchain/coins/dash" "blockbook/bchain/coins/dcr" + "blockbook/bchain/coins/deeponion" "blockbook/bchain/coins/digibyte" "blockbook/bchain/coins/divi" "blockbook/bchain/coins/dogecoin" @@ -103,6 +104,7 @@ func init() { BlockChainFactories["Divi"] = divi.NewDiviRPC BlockChainFactories["CPUchain"] = cpuchain.NewCPUchainRPC BlockChainFactories["Unobtanium"] = unobtanium.NewUnobtaniumRPC + BlockChainFactories["DeepOnion"] = deeponion.NewDeepOnionRPC } // GetCoinNameFromConfig gets coin name and coin shortcut from config file diff --git a/bchain/coins/deeponion/deeponionparser.go b/bchain/coins/deeponion/deeponionparser.go new file mode 100644 index 00000000..7e63afe3 --- /dev/null +++ b/bchain/coins/deeponion/deeponionparser.go @@ -0,0 +1,68 @@ +package deeponion + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + + "github.com/martinboehm/btcd/wire" + "github.com/martinboehm/btcutil/chaincfg" +) + +// magic numbers +const ( + MainnetMagic wire.BitcoinNet = 0xf2dbf1d1 +) + +// chain parameters +var ( + MainNetParams chaincfg.Params +) + +func init() { + MainNetParams = chaincfg.MainNetParams + MainNetParams.Net = MainnetMagic + MainNetParams.PubKeyHashAddrID = []byte{31} + MainNetParams.ScriptHashAddrID = []byte{78} + MainNetParams.Bech32HRPSegwit = "dpn" +} + +// DeepOnionParser handle +type DeepOnionParser struct { + *btc.BitcoinParser + baseparser *bchain.BaseParser +} + +// NewDeepOnionParser returns new DeepOnionParser instance +func NewDeepOnionParser(params *chaincfg.Params, c *btc.Configuration) *DeepOnionParser { + return &DeepOnionParser{ + BitcoinParser: btc.NewBitcoinParser(params, c), + baseparser: &bchain.BaseParser{}, + } +} + +// GetChainParams contains network parameters for the main DeepOnion network, +func GetChainParams(chain string) *chaincfg.Params { + // register bitcoin parameters in addition to deeponion parameters + // deeponion has dual standard of addresses and we want to be able to + // parse both standards + if !chaincfg.IsRegistered(&chaincfg.MainNetParams) { + chaincfg.RegisterBitcoinParams() + } + if !chaincfg.IsRegistered(&MainNetParams) { + err := chaincfg.Register(&MainNetParams) + if err != nil { + panic(err) + } + } + return &MainNetParams +} + +// PackTx packs transaction to byte array using protobuf +func (p *DeepOnionParser) 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 *DeepOnionParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) { + return p.baseparser.UnpackTx(buf) +} diff --git a/bchain/coins/deeponion/deeponionparser_test.go b/bchain/coins/deeponion/deeponionparser_test.go new file mode 100644 index 00000000..a19fb097 --- /dev/null +++ b/bchain/coins/deeponion/deeponionparser_test.go @@ -0,0 +1,201 @@ +// +build unittest + +package deeponion + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + "encoding/hex" + "math/big" + "os" + "reflect" + "testing" + + "github.com/martinboehm/btcutil/chaincfg" +) + +func TestMain(m *testing.M) { + c := m.Run() + chaincfg.ResetParams() + os.Exit(c) +} + + +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: "DYPyxvq57iSRA5xUXzSVfsTENPz4DKFr5S"}, + want: "76a9142afc25b8b5d4ed490026d38b3b464c140a32dc7588ac", + wantErr: false, + }, + { + name: "P2PKH2", + args: args{address: "DshhBSub7vexDFNm45UtG2wBJFt8cm5Uwr"}, + want: "76a914fec0038b0db67c1b304f6c25b3e860277a96226188ac", + wantErr: false, + }, + { + name: "P2SH1", + args: args{address: "YYDTMNJmKqajnWjFPjenzs2awwE4cwYHtC"}, + want: "a91461190c0272b059b2c09b352da81b1712dd83305e87", + wantErr: false, + }, + { + name: "P2SH2", + args: args{address: "Yh1qpMEA4EFMTB4BmhkeyivJ92WiGr3ETX"}, + want: "a914c19ff0bfc8f4387bee48e2cd3628bf72f7053cd787", + wantErr: false, + }, + } + parser := NewDeepOnionParser(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 = "0a206ba18524d81af732d0226ffdb63d2bcdc0d58a35ac97b5ad731057932d324e1412b401010000001134415d0114caae2bf9a7808aee0798e6245a347405d46c8131dbf55cbbbc689bbee367e902000000484730440220280f3fa80b4e93834fe0a8d9884105310eaa8d36d77b9aff113b6c498138e5bb02204578409f0a14fa1950ea4951314fd495fd503b42a6325efb5c139a6c8253912401ffffffff0200000000000000000005f22f5904000000232102bdb95d89f07e3a29305f3c8de86ec211ed77b7e15cf314c85c532a6b71c2ce07ac000000001891e884ea05200028b88a5432760a001220e967e3be9b68bcbb5cf5db31816cd40574345a24e69807ee8a80a7f92baeca14180222484730440220280f3fa80b4e93834fe0a8d9884105310eaa8d36d77b9aff113b6c498138e5bb02204578409f0a14fa1950ea4951314fd495fd503b42a6325efb5c139a6c825391240128ffffffff0f3a0210003a520a0504583af7fb10011a232102bdb95d89f07e3a29305f3c8de86ec211ed77b7e15cf314c85c532a6b71c2ce07ac2222446d343835624e4a6169474a6d4556746832426e5a345931796763756644736934454001" +) + +func init() { + testTx1 = bchain.Tx{ + Hex: "010000001134415d0114caae2bf9a7808aee0798e6245a347405d46c8131dbf55cbbbc689bbee367e902000000484730440220280f3fa80b4e93834fe0a8d9884105310eaa8d36d77b9aff113b6c498138e5bb02204578409f0a14fa1950ea4951314fd495fd503b42a6325efb5c139a6c8253912401ffffffff0200000000000000000005f22f5904000000232102bdb95d89f07e3a29305f3c8de86ec211ed77b7e15cf314c85c532a6b71c2ce07ac00000000", + Blocktime: 1564554257, + Txid: "6ba18524d81af732d0226ffdb63d2bcdc0d58a35ac97b5ad731057932d324e14", + LockTime: 0, + Time: 1564554257, + Version: 1, + Vin: []bchain.Vin{ + { + ScriptSig: bchain.ScriptSig{ + Hex: "4730440220280f3fa80b4e93834fe0a8d9884105310eaa8d36d77b9aff113b6c498138e5bb02204578409f0a14fa1950ea4951314fd495fd503b42a6325efb5c139a6c8253912401", + }, + Txid: "e967e3be9b68bcbb5cf5db31816cd40574345a24e69807ee8a80a7f92baeca14", + Vout: 2, + Sequence: 4294967295, + }, + }, + Vout: []bchain.Vout{ + { + ValueSat: *big.NewInt(0), + N: 0, + ScriptPubKey: bchain.ScriptPubKey{ + Hex: "", + }, + }, + { + ValueSat: *big.NewInt(18660128763), + N: 1, + ScriptPubKey: bchain.ScriptPubKey{ + Hex: "2102bdb95d89f07e3a29305f3c8de86ec211ed77b7e15cf314c85c532a6b71c2ce07ac", + Addresses: []string{ + "Dm485bNJaiGJmEVth2BnZ4Y1ygcufDsi4E", + }, + }, + }, + }, + } +} + +func Test_PackTx(t *testing.T) { + type args struct { + tx bchain.Tx + height uint32 + blockTime int64 + parser *DeepOnionParser + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "deeponion-1", + args: args{ + tx: testTx1, + height: 1377592, + blockTime: 1564554257, + parser: NewDeepOnionParser(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 *DeepOnionParser + } + tests := []struct { + name string + args args + want *bchain.Tx + want1 uint32 + wantErr bool + }{ + { + name: "deeponion-1", + args: args{ + packedTx: testTxPacked1, + parser: NewDeepOnionParser(GetChainParams("main"), &btc.Configuration{}), + }, + want: &testTx1, + want1: 1377592, + 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(1) error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("unpackTx(2) got = %v, want %v", got, tt.want) + } + if got1 != tt.want1 { + t.Errorf("unpackTx(3) got1 = %v, want %v", got1, tt.want1) + } + }) + } +} diff --git a/bchain/coins/deeponion/deeponionrpc.go b/bchain/coins/deeponion/deeponionrpc.go new file mode 100644 index 00000000..6fab0c49 --- /dev/null +++ b/bchain/coins/deeponion/deeponionrpc.go @@ -0,0 +1,109 @@ +package deeponion + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + "encoding/json" + + "github.com/golang/glog" + "github.com/juju/errors" +) + +// DeepOnionRPC is an interface to JSON-RPC bitcoind service. +type DeepOnionRPC struct { + *btc.BitcoinRPC +} + +// NewDeepOnionRPC returns new DeepOnionRPC instance. +func NewDeepOnionRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) { + b, err := btc.NewBitcoinRPC(config, pushHandler) + if err != nil { + return nil, err + } + + s := &DeepOnionRPC{ + b.(*btc.BitcoinRPC), + } + s.RPCMarshaler = btc.JSONMarshalerV2{} + s.ChainConfig.SupportsEstimateFee = false + + return s, nil +} + +// Initialize initializes DeepOnionRPC instance. +func (b *DeepOnionRPC) Initialize() error { + ci, err := b.GetChainInfo() + if err != nil { + return err + } + chainName := ci.Chain + + glog.Info("Chain name ", chainName) + params := GetChainParams(chainName) + + // always create parser + b.Parser = NewDeepOnionParser(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 +} + +// GetBlock returns block with given hash. +func (s *DeepOnionRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) { + var err error + if hash == "" && height > 0 { + hash, err = s.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 = s.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 := s.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 (s *DeepOnionRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) { + return s.GetTransaction(txid) +} diff --git a/build/templates/backend/config/deeponion.conf b/build/templates/backend/config/deeponion.conf new file mode 100644 index 00000000..ca92d14f --- /dev/null +++ b/build/templates/backend/config/deeponion.conf @@ -0,0 +1,29 @@ +{{define "main" -}} +daemon=1 +server=1 +{{if .Backend.Mainnet}}mainnet=1{{else}}testnet=1{{end}} +rpcuser={{.IPC.RPCUser}} +rpcpassword={{.IPC.RPCPass}} +rpcport={{.Ports.BackendRPC}} +txindex=1 + +zmqpubhashtx={{template "IPC.MessageQueueBindingTemplate" .}} +zmqpubhashblock={{template "IPC.MessageQueueBindingTemplate" .}} + +rpcworkqueue=1100 +maxmempool=2000 +dbcache=1000 + +{{- if .Backend.AdditionalParams}} +# generated from additional_params +{{- range $name, $value := .Backend.AdditionalParams}} +{{- if eq $name "addnode"}} +{{- range $index, $node := $value}} +addnode={{$node}} +{{- end}} +{{- else}} +{{$name}}={{$value}} +{{- end}} +{{- end}} +{{- end}} +{{end}} diff --git a/configs/coins/deeponion.json b/configs/coins/deeponion.json new file mode 100644 index 00000000..d5c42fd2 --- /dev/null +++ b/configs/coins/deeponion.json @@ -0,0 +1,67 @@ +{ + "coin": { + "name": "DeepOnion", + "shortcut": "ONION", + "label": "DeepOnion", + "alias": "deeponion" + }, + "ports": { + "backend_rpc": 8091, + "backend_message_queue": 38391, + "blockbook_internal": 9091, + "blockbook_public": 9191 + }, + "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-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", + "extract_command": "tar -C backend --strip 1 -xpf", + "exclude_files": [ + ], + "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", + "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": "deeponion.conf", + "client_config_file": "bitcoin_like_client.conf", + "additional_params": { + "whitelist": "127.0.0.1" + } + }, + "blockbook": { + "package_name": "blockbook-deeponion", + "system_user": "blockbook-deeponion", + "internal_binding_template": ":{{.Ports.BlockbookInternal}}", + "public_binding_template": ":{{.Ports.BlockbookPublic}}", + "explorer_url": "", + "additional_params": "", + "block_chain": { + "parse": true, + "subversion": "/DeepOnionCore:2.0.5/", + "mempool_workers": 8, + "mempool_sub_workers": 2, + "block_addresses_to_keep": 300, + "xpub_magic": 27108450, + "xpub_magic_segwit_p2sh": 28471030, + "xpub_magic_segwit_native": 78792518, + "slip44": 305, + "additional_params": {} + } + }, + "meta": { + "package_maintainer": "DeepOnion", + "package_maintainer_email": "info@deeponion.org" + } +} diff --git a/docs/ports.md b/docs/ports.md index 835d5e07..0c63c18b 100644 --- a/docs/ports.md +++ b/docs/ports.md @@ -8,7 +8,7 @@ | Dash | 9033 | 9133 | 8033 | 38333 | | Litecoin | 9034 | 9134 | 8034 | 38334 | | Bitcoin Gold | 9035 | 9135 | 8035 | 38335 | -| Ethereum | 9036 | 9136 | 8036 | 8136 http, 38336 p2p | +| Ethereum | 9036 | 9136 | 8036 | 38336 p2p, 8136 http | | Ethereum Classic | 9037 | 9137 | 8037 | | | Dogecoin | 9038 | 9138 | 8038 | 38338 | | Namecoin | 9039 | 9139 | 8039 | 38339 | @@ -38,6 +38,7 @@ | Qtum | 9088 | 9188 | 8088 | 38388 | | Divi Project | 9089 | 9189 | 8089 | 38389 | | CPUchain | 9090 | 9190 | 8090 | 38390 | +| DeepOnion | 9091 | 9191 | 8091 | 38391 | | Unobtanium | 9092 | 9192 | 65535 | 38392 | | Bitcoin Testnet | 19030 | 19130 | 18030 | 48330 | | Bitcoin Cash Testnet | 19031 | 19131 | 18031 | 48331 | diff --git a/tests/rpc/testdata/deeponion.json b/tests/rpc/testdata/deeponion.json new file mode 100644 index 00000000..4fe9943d --- /dev/null +++ b/tests/rpc/testdata/deeponion.json @@ -0,0 +1,52 @@ +{ + "blockHeight": 1377592, + "blockHash": "9993684c15a793130f43120839e5c2c711907631ef4ad7b43ba535322e4c6649", + "blockTime": 1564554257, + "blockTxs": [ + "200b681e57d19131a87c3aa4172b9e2e128cc48ecdf54cc91dcbc44e96e8f7cf", + "6ba18524d81af732d0226ffdb63d2bcdc0d58a35ac97b5ad731057932d324e14" + ], + "txDetails": { + "e967e3be9b68bcbb5cf5db31816cd40574345a24e69807ee8a80a7f92baeca14": { + "hex": "0100000015cc175d016012730925e8e7eaff1a7cbd18e255f749e936730c001ca4b900a9a93230abbd0100000048473044022066a828d9d7d3e03dba2ad028bfdcad4e989ab76f11a7a033702759c37525bd8502206480c14e3c39a1d244e00c4113557bd9651d8b2b944426d88f8d7f95f8957c5601ffffffff03000000000000000000c0be295804000000232102bdb95d89f07e3a29305f3c8de86ec211ed77b7e15cf314c85c532a6b71c2ce07acfbf73a5804000000232102bdb95d89f07e3a29305f3c8de86ec211ed77b7e15cf314c85c532a6b71c2ce07ac00000000", + "txid": "e967e3be9b68bcbb5cf5db31816cd40574345a24e69807ee8a80a7f92baeca14", + "blocktime": 1561840661, + "time": 1561840661, + "locktime": 0, + "version": 1, + "vin": [ + { + "txid": "bdab3032a9a900b9a41c000c7336e949f755e218bd7c1affeae7e82509731260", + "vout": 1, + "scriptSig": { + "hex": "473044022066a828d9d7d3e03dba2ad028bfdcad4e989ab76f11a7a033702759c37525bd8502206480c14e3c39a1d244e00c4113557bd9651d8b2b944426d88f8d7f95f8957c5601" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00000000, + "n": 0, + "scriptPubKey": { + "hex": "" + } + }, + { + "value": 186.59, + "n": 1, + "scriptPubKey": { + "hex": "2102bdb95d89f07e3a29305f3c8de86ec211ed77b7e15cf314c85c532a6b71c2ce07ac" + } + }, + { + "value": 186.60128763, + "n": 2, + "scriptPubKey": { + "hex": "2102bdb95d89f07e3a29305f3c8de86ec211ed77b7e15cf314c85c532a6b71c2ce07ac" + } + } + ] + } + } +} diff --git a/tests/sync/testdata/deeponion.json b/tests/sync/testdata/deeponion.json new file mode 100644 index 00000000..b307dca7 --- /dev/null +++ b/tests/sync/testdata/deeponion.json @@ -0,0 +1,96 @@ +{ + "connectBlocks": { + "syncRanges": [ + {"lower": 1003776, "upper": 1003796} + ], + "blocks": { + "1003776": { + "height": 1003776, + "hash": "b9775282a6def6a186d29584af8907c991e27e91603ce461bf5c79890f020a45", + "noTxs": 2, + "txDetails": [ + { + "txid": "9f3400d241a594a5d7b039cad7c535226d481e486c8e54cf0e88d47149a53a79", + "version": 1, + "vin": [ + { + "txid": "c2b57977801b69472ac635e2d53cb53e652ff432caa91c47ae9c70bc8d4b27a6", + "vout": 0, + "scriptSig": { + "hex": "47304402203e68a85b0ae7fd4f6b4ab6abe44e091d08aba37dd787fc271467ffaee8c9733402205264badf478dbc18051331b2f53a43447f53f950ea98db5fdcca28ef179c122201" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00000000, + "n": 0, + "scriptPubKey": { + "hex": "" + } + }, + { + "value": 118.27, + "n": 1, + "scriptPubKey": { + "hex": "2103fb4259bbe5c1e956a6b804ab19812f0cd0938cf6151be81aa14e3ffa955dfcd6ac" + } + }, + { + "value": 118.28219178, + "n": 2, + "scriptPubKey": { + "hex": "2103fb4259bbe5c1e956a6b804ab19812f0cd0938cf6151be81aa14e3ffa955dfcd6ac" + } + } + ], + "hex": "010000006eed435c01a6274b8dbc709cae471ca9ca32f42f653eb53cd5e235c62a47691b807779b5c2010000004847304402203e68a85b0ae7fd4f6b4ab6abe44e091d08aba37dd787fc271467ffaee8c9733402205264badf478dbc18051331b2f53a43447f53f950ea98db5fdcca28ef179c122201ffffffff03000000000000000000c0b2f1c002000000232103fb4259bbe5c1e956a6b804ab19812f0cd0938cf6151be81aa14e3ffa955dfcd6ac2a4d04c102000000232103fb4259bbe5c1e956a6b804ab19812f0cd0938cf6151be81aa14e3ffa955dfcd6ac00000000", + "time": 1547955566, + "blocktime": 1547955566 + } + ] + }, + "1003796": { + "height": 1003796, + "hash": "8ec7b5006dd4b6683c6b58185064e94ab0b87f083ed4e58706f6f928cb4f9d58", + "noTxs": 2, + "txDetails": [ + { + "txid": "1d8a926a59f64b0b5a5efcb3872801f74dfe30d0ed68330bd98295f05f6c0580", + "version": 1, + "vin": [ + { + "txid": "7807e471847d0f66616653601d02b2ea482e97385d2c03daec77e000b62c10a1", + "vout": 1, + "scriptSig": { + "hex": "473044022033a999110dcadb95223db2028f5fcbf3a5b37ec48498ec4678eaff0f6c8787b002207100681343a265c9995681702f3694cbbffaadaf1bc42a3b6fd69e3a79896f1701" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00000000, + "n": 0, + "scriptPubKey": { + "hex": "" + } + }, + { + "value": 459.47739724, + "n": 1, + "scriptPubKey": { + "hex": "21025f48dc22185bc3f9428068600d779b9bbbe208a49ffbbe6af551000e70979cb7ac" + } + } + ], + "hex": "010000006eed435c01a6274b8dbc709cae471ca9ca32f42f653eb53cd5e235c62a47691b807779b5c2010000004847304402203e68a85b0ae7fd4f6b4ab6abe44e091d08aba37dd787fc271467ffaee8c9733402205264badf478dbc18051331b2f53a43447f53f950ea98db5fdcca28ef179c122201ffffffff03000000000000000000c0b2f1c002000000232103fb4259bbe5c1e956a6b804ab19812f0cd0938cf6151be81aa14e3ffa955dfcd6ac2a4d04c102000000232103fb4259bbe5c1e956a6b804ab19812f0cd0938cf6151be81aa14e3ffa955dfcd6ac00000000", + "time": 1547956478, + "blocktime": 1547956478 + } + ] + } + } + } +} diff --git a/tests/tests.json b/tests/tests.json index d555f383..7f935426 100644 --- a/tests/tests.json +++ b/tests/tests.json @@ -52,6 +52,11 @@ "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"], "sync": ["ConnectBlocksParallel", "ConnectBlocks"] }, + "deeponion": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", + "EstimateSmartFee", "EstimateFee"], + "sync": ["ConnectBlocksParallel", "ConnectBlocks"] + }, "digibyte": { "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"]