diff --git a/Makefile b/Makefile index e7ec249a..0698ed8f 100644 --- a/Makefile +++ b/Makefile @@ -3,26 +3,27 @@ DEB_IMAGE = blockbook-build-deb PACKAGER = $(shell id -u):$(shell id -g) NO_CACHE = false UPDATE_VENDOR = 1 +ARGS ?= .PHONY: build build-debug test deb build: .bin-image - docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v $(CURDIR):/src -v $(CURDIR)/build:/out $(BIN_IMAGE) make build + docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v $(CURDIR):/src -v $(CURDIR)/build:/out $(BIN_IMAGE) make build ARGS="$(ARGS)" build-debug: .bin-image - docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v $(CURDIR):/src -v $(CURDIR)/build:/out $(BIN_IMAGE) make build-debug + docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v $(CURDIR):/src -v $(CURDIR)/build:/out $(BIN_IMAGE) make build-debug ARGS="$(ARGS)" test: .bin-image - docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v $(CURDIR):/src $(BIN_IMAGE) make test + docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v $(CURDIR):/src --network="host" $(BIN_IMAGE) make test ARGS="$(ARGS)" test-all: .bin-image - docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v $(CURDIR):/src $(BIN_IMAGE) make test-all + docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v $(CURDIR):/src --network="host" $(BIN_IMAGE) make test-all ARGS="$(ARGS)" deb: .deb-image clean-deb - docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v $(CURDIR):/src -v $(CURDIR)/build:/out $(DEB_IMAGE) + docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v $(CURDIR):/src -v $(CURDIR)/build:/out $(DEB_IMAGE) /build/build-deb.sh $(ARGS) tools: - docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v $(CURDIR):/src -v $(CURDIR)/build:/out $(BIN_IMAGE) make tools + docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v $(CURDIR):/src -v $(CURDIR)/build:/out $(BIN_IMAGE) make tools ARGS="$(ARGS)" all: build-images deb diff --git a/bchain/baseparser.go b/bchain/baseparser.go index dfba4ea9..8f7bc08a 100644 --- a/bchain/baseparser.go +++ b/bchain/baseparser.go @@ -8,9 +8,11 @@ import ( "github.com/juju/errors" ) +type AddressFactoryFunc func(string) (Address, error) + // BaseParser implements data parsing/handling functionality base for all other parsers type BaseParser struct { - AddressFactory func(string) (Address, error) + AddressFactory AddressFactoryFunc BlockAddressesToKeep int } @@ -19,6 +21,11 @@ func (p *BaseParser) AddressToOutputScript(address string) ([]byte, error) { return nil, errors.New("AddressToOutputScript: not implemented") } +// OutputScriptToAddresses converts ScriptPubKey to addresses - currently not implemented +func (p *BaseParser) OutputScriptToAddresses(script []byte) ([]string, error) { + return nil, errors.New("OutputScriptToAddresses: not implemented") +} + // ParseBlock parses raw block to our Block struct - currently not implemented func (p *BaseParser) ParseBlock(b []byte) (*Block, error) { return nil, errors.New("ParseBlock: not implemented") diff --git a/bchain/coins/bch/bcashparser.go b/bchain/coins/bch/bcashparser.go index 2be69fa4..95284d84 100644 --- a/bchain/coins/bch/bcashparser.go +++ b/bchain/coins/bch/bcashparser.go @@ -50,8 +50,8 @@ func NewBCashParser(params *chaincfg.Params, c *btc.Configuration) (*BCashParser AddressFactory: func(addr string) (bchain.Address, error) { return newBCashAddress(addr, format) }, BlockAddressesToKeep: c.BlockAddressesToKeep, }, - Params: params, - OutputScriptToAddresses: outputScriptToAddresses, + Params: params, + OutputScriptToAddressesFunc: outputScriptToAddresses, }, AddressFormat: format, } diff --git a/bchain/coins/bch/bcashparser_test.go b/bchain/coins/bch/bcashparser_test.go index 5ef506f7..1d042b9f 100644 --- a/bchain/coins/bch/bcashparser_test.go +++ b/bchain/coins/bch/bcashparser_test.go @@ -1,3 +1,5 @@ +// +build unittest + package bch import ( diff --git a/bchain/coins/bch/bcashrpc_test.go b/bchain/coins/bch/bcashrpc_test.go new file mode 100644 index 00000000..8185fd05 --- /dev/null +++ b/bchain/coins/bch/bcashrpc_test.go @@ -0,0 +1,45 @@ +// +build integration + +package bch + +import ( + "blockbook/bchain" + "blockbook/bchain/tests/rpc" + "encoding/json" + "testing" +) + +func getRPCClient(cfg json.RawMessage) (bchain.BlockChain, error) { + c, err := NewBCashRPC(cfg, nil) + if err != nil { + return nil, err + } + cli := c.(*BCashRPC) + cli.Parser, err = NewBCashParser(GetChainParams("test"), cli.ChainConfig) + if err != nil { + return nil, err + } + return cli, nil +} + +var rpcTest *rpc.Test + +func init() { + t, err := rpc.NewTest("Bcash Testnet", getRPCClient) + if err != nil { + panic(err) + } + rpcTest = t +} + +func TestBCashRPC_GetBlockHash(t *testing.T) { + rpcTest.TestGetBlockHash(t) +} + +func TestBCashRPC_GetBlock(t *testing.T) { + rpcTest.TestGetBlock(t) +} + +func TestBCashRPC_GetTransaction(t *testing.T) { + rpcTest.TestGetTransaction(t) +} diff --git a/bchain/coins/btc/bitcoinparser.go b/bchain/coins/btc/bitcoinparser.go index eab5891d..41c52759 100644 --- a/bchain/coins/btc/bitcoinparser.go +++ b/bchain/coins/btc/bitcoinparser.go @@ -20,8 +20,8 @@ type OutputScriptToAddressesFunc func(script []byte, params *chaincfg.Params) ([ // BitcoinParser handle type BitcoinParser struct { *bchain.BaseParser - Params *chaincfg.Params - OutputScriptToAddresses OutputScriptToAddressesFunc + Params *chaincfg.Params + OutputScriptToAddressesFunc OutputScriptToAddressesFunc } // NewBitcoinParser returns new BitcoinParser instance @@ -72,6 +72,11 @@ func (p *BitcoinParser) AddressToOutputScript(address string) ([]byte, error) { return script, nil } +// OutputScriptToAddresses converts ScriptPubKey to bitcoin addresses +func (p *BitcoinParser) OutputScriptToAddresses(script []byte) ([]string, error) { + return p.OutputScriptToAddressesFunc(script, p.Params) +} + // outputScriptToAddresses converts ScriptPubKey to bitcoin addresses func outputScriptToAddresses(script []byte, params *chaincfg.Params) ([]string, error) { _, addresses, _, err := txscript.ExtractPkScriptAddrs(script, params) @@ -110,7 +115,7 @@ func (p *BitcoinParser) TxFromMsgTx(t *wire.MsgTx, parseAddresses bool) bchain.T for i, out := range t.TxOut { addrs := []string{} if parseAddresses { - addrs, _ = p.OutputScriptToAddresses(out.PkScript, p.Params) + addrs, _ = p.OutputScriptToAddresses(out.PkScript) } s := bchain.ScriptPubKey{ Hex: hex.EncodeToString(out.PkScript), diff --git a/bchain/coins/btc/bitcoinparser_test.go b/bchain/coins/btc/bitcoinparser_test.go index 669a4927..46490f6c 100644 --- a/bchain/coins/btc/bitcoinparser_test.go +++ b/bchain/coins/btc/bitcoinparser_test.go @@ -1,3 +1,5 @@ +// +build unittest + package btc import ( diff --git a/bchain/coins/btc/bitcoinrpc_test.go b/bchain/coins/btc/bitcoinrpc_test.go new file mode 100644 index 00000000..52b09898 --- /dev/null +++ b/bchain/coins/btc/bitcoinrpc_test.go @@ -0,0 +1,45 @@ +// +build integration + +package btc + +import ( + "blockbook/bchain" + "blockbook/bchain/tests/rpc" + "encoding/json" + "testing" +) + +func getRPCClient(cfg json.RawMessage) (bchain.BlockChain, error) { + c, err := NewBitcoinRPC(cfg, nil) + if err != nil { + return nil, err + } + cli := c.(*BitcoinRPC) + cli.Parser = NewBitcoinParser(GetChainParams("test"), cli.ChainConfig) + if err != nil { + return nil, err + } + return cli, nil +} + +var rpcTest *rpc.Test + +func init() { + t, err := rpc.NewTest("Bitcoin Testnet", getRPCClient) + if err != nil { + panic(err) + } + rpcTest = t +} + +func TestBitcoinRPC_GetBlockHash(t *testing.T) { + rpcTest.TestGetBlockHash(t) +} + +func TestBitcoinRPC_GetBlock(t *testing.T) { + rpcTest.TestGetBlock(t) +} + +func TestBitcoinRPC_GetTransaction(t *testing.T) { + rpcTest.TestGetTransaction(t) +} diff --git a/bchain/coins/btg/bgoldparser_test.go b/bchain/coins/btg/bgoldparser_test.go index f308aced..8834cfc0 100644 --- a/bchain/coins/btg/bgoldparser_test.go +++ b/bchain/coins/btg/bgoldparser_test.go @@ -1,3 +1,5 @@ +// +build unittest + package btg import ( diff --git a/bchain/coins/dash/dashrpc_test.go b/bchain/coins/dash/dashrpc_test.go new file mode 100644 index 00000000..90c09bb4 --- /dev/null +++ b/bchain/coins/dash/dashrpc_test.go @@ -0,0 +1,42 @@ +// +build integration + +package dash + +import ( + "blockbook/bchain" + "blockbook/bchain/tests/rpc" + "encoding/json" + "testing" +) + +func getRPCClient(cfg json.RawMessage) (bchain.BlockChain, error) { + c, err := NewDashRPC(cfg, nil) + if err != nil { + return nil, err + } + cli := c.(*DashRPC) + cli.Parser = NewDashParser(GetChainParams("test"), cli.ChainConfig) + return cli, nil +} + +var rpcTest *rpc.Test + +func init() { + t, err := rpc.NewTest("Dash Testnet", getRPCClient) + if err != nil { + panic(err) + } + rpcTest = t +} + +func TestDashRPC_GetBlockHash(t *testing.T) { + rpcTest.TestGetBlockHash(t) +} + +func TestDashRPC_GetBlock(t *testing.T) { + rpcTest.TestGetBlock(t) +} + +func TestDashRPC_GetTransaction(t *testing.T) { + rpcTest.TestGetTransaction(t) +} diff --git a/bchain/coins/eth/ethparser_test.go b/bchain/coins/eth/ethparser_test.go index 08958b7f..c1f4620f 100644 --- a/bchain/coins/eth/ethparser_test.go +++ b/bchain/coins/eth/ethparser_test.go @@ -1,3 +1,5 @@ +// +build unittest + package eth import ( diff --git a/bchain/coins/eth/ethrpc_test.go b/bchain/coins/eth/ethrpc_test.go index 41f75338..f4794edc 100644 --- a/bchain/coins/eth/ethrpc_test.go +++ b/bchain/coins/eth/ethrpc_test.go @@ -1,44 +1,48 @@ +// +build integration + package eth import ( "blockbook/bchain" - "flag" + "blockbook/bchain/tests/rpc" + "encoding/json" "reflect" "testing" - "time" ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/rpc" ) -var rpcURL = flag.String("rpc", "ws://localhost:18036", "URL of geth server") -var ethClient *ethclient.Client -var ethRPCClient *rpc.Client +func getRPCClient(cfg json.RawMessage) (bchain.BlockChain, error) { + c, err := NewEthereumRPC(cfg, nil) + if err != nil { + return nil, err + } + return c, nil +} -func setupEthRPC() *EthereumRPC { - if ethClient == nil { - rc, err := rpc.Dial(*rpcURL) - if err != nil { - panic(err) - } - ec := ethclient.NewClient(rc) - ethRPCClient = rc - ethClient = ec - } - return &EthereumRPC{ - client: ethClient, - rpc: ethRPCClient, - timeout: time.Duration(25) * time.Second, - rpcURL: *rpcURL, - Parser: NewEthereumParser(), +var rpcTest *rpc.Test + +func init() { + t, err := rpc.NewTest("Ethereum Testnet", getRPCClient) + if err != nil { + panic(err) } + rpcTest = t +} + +func TestEthRPC_GetBlockHash(t *testing.T) { + rpcTest.TestGetBlockHash(t) +} + +func TestEthRPC_GetBlock(t *testing.T) { + rpcTest.TestGetBlock(t) +} + +func TestEthRPC_GetTransaction(t *testing.T) { + rpcTest.TestGetTransaction(t) } func TestEthRPC_getBestHeader(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } type fields struct { b *EthereumRPC } @@ -51,7 +55,7 @@ func TestEthRPC_getBestHeader(t *testing.T) { { name: "1", fields: fields{ - b: setupEthRPC(), + b: rpcTest.Client.(*EthereumRPC), }, }, } @@ -68,9 +72,6 @@ func TestEthRPC_getBestHeader(t *testing.T) { } func TestEthRPC_GetBestBlockHash(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } type fields struct { b *EthereumRPC } @@ -83,7 +84,7 @@ func TestEthRPC_GetBestBlockHash(t *testing.T) { { name: "1", fields: fields{ - b: setupEthRPC(), + b: rpcTest.Client.(*EthereumRPC), }, want: 66, }, @@ -104,9 +105,6 @@ func TestEthRPC_GetBestBlockHash(t *testing.T) { } func TestEthRPC_GetBestBlockHeight(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } type fields struct { b *EthereumRPC } @@ -119,7 +117,7 @@ func TestEthRPC_GetBestBlockHeight(t *testing.T) { { name: "1", fields: fields{ - b: setupEthRPC(), + b: rpcTest.Client.(*EthereumRPC), }, want: 1000000, }, @@ -138,74 +136,8 @@ func TestEthRPC_GetBestBlockHeight(t *testing.T) { } } -func TestEthRPC_GetBlockHash(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - type fields struct { - b *EthereumRPC - } - type args struct { - height uint32 - } - tests := []struct { - name string - fields fields - args args - want string - wantErr error - }{ - { - name: "1000000", - fields: fields{ - b: setupEthRPC(), - }, - args: args{ - height: 1000000, - }, - want: "0x6e6b2e771a3026a1981227ab4a4c8d018edb568494f17df46bcddfa427df686e", - }, - { - name: "2870000", - fields: fields{ - b: setupEthRPC(), - }, - args: args{ - height: 2870000, - }, - want: "0xeccd6b0031015a19cb7d4e10f28590ba65a6a54ad1baa322b50fe5ad16903895", - }, - { - name: "ErrBlockNotFound", - fields: fields{ - b: setupEthRPC(), - }, - args: args{ - height: 1 << 31, - }, - want: "", - wantErr: bchain.ErrBlockNotFound, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := tt.fields.b.GetBlockHash(tt.args.height) - if err != tt.wantErr { - t.Errorf("EthRPC.GetBlockHash() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("EthRPC.GetBlockHash() = %v, want %v", got, tt.want) - } - }) - } -} - func TestEthRPC_GetBlockHeader(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - bh, err := setupEthRPC().getBestHeader() + bh, err := rpcTest.Client.(*EthereumRPC).getBestHeader() if err != nil { panic(err) } @@ -225,7 +157,7 @@ func TestEthRPC_GetBlockHeader(t *testing.T) { { name: "2870000", fields: fields{ - b: setupEthRPC(), + b: rpcTest.Client.(*EthereumRPC), }, args: args{ hash: "eccd6b0031015a19cb7d4e10f28590ba65a6a54ad1baa322b50fe5ad16903895", @@ -239,7 +171,7 @@ func TestEthRPC_GetBlockHeader(t *testing.T) { { name: "ErrBlockNotFound", fields: fields{ - b: setupEthRPC(), + b: rpcTest.Client.(*EthereumRPC), }, args: args{ hash: "0xeccd6b0031015a19cb7d4e10f28590ba65a6a54ad1baa322b50fe5ad16903896", @@ -261,214 +193,7 @@ func TestEthRPC_GetBlockHeader(t *testing.T) { } } -func TestEthRPC_GetBlock(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - bh, err := setupEthRPC().getBestHeader() - if err != nil { - panic(err) - } - type fields struct { - b *EthereumRPC - } - type args struct { - hash string - height uint32 - } - tests := []struct { - name string - fields fields - args args - want *bchain.Block - wantTxCount int - wantErr error - }{ - { - name: "2870000 by hash", - fields: fields{ - b: setupEthRPC(), - }, - args: args{ - hash: "eccd6b0031015a19cb7d4e10f28590ba65a6a54ad1baa322b50fe5ad16903895", - }, - want: &bchain.Block{ - BlockHeader: bchain.BlockHeader{ - Hash: "0xeccd6b0031015a19cb7d4e10f28590ba65a6a54ad1baa322b50fe5ad16903895", - Height: 2870000, - Confirmations: int(uint32(bh.Number.Uint64()) - 2870000 + 1), - }, - }, - wantTxCount: 12, - }, - { - name: "2870000 by height", - fields: fields{ - b: setupEthRPC(), - }, - args: args{ - height: 2870000, - }, - want: &bchain.Block{ - BlockHeader: bchain.BlockHeader{ - Hash: "0xeccd6b0031015a19cb7d4e10f28590ba65a6a54ad1baa322b50fe5ad16903895", - Height: 2870000, - Confirmations: int(uint32(bh.Number.Uint64()) - 2870000 + 1), - }, - }, - wantTxCount: 12, - }, - { - name: "ErrBlockNotFound", - fields: fields{ - b: setupEthRPC(), - }, - args: args{ - hash: "0xeccd6b0031015a19cb7d4e10f28590ba65a6a54ad1baa322b50fe5ad16903896", - }, - wantErr: bchain.ErrBlockNotFound, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := tt.fields.b.GetBlock(tt.args.hash, tt.args.height) - if err != tt.wantErr { - t.Errorf("EthRPC.GetBlock() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got == nil && tt.want == nil { - return - } - if got.Hash != tt.want.Hash { - t.Errorf("EthRPC.GetBlock().Hash = %v, want %v", got.Hash, tt.want.Hash) - return - } - if got.Height != tt.want.Height { - t.Errorf("EthRPC.GetBlock().Height = %v, want %v", got.Height, tt.want.Height) - return - } - if got.Confirmations != tt.want.Confirmations { - t.Errorf("EthRPC.GetBlock().Confirmations = %v, want %v", got.Confirmations, tt.want.Confirmations) - return - } - if len(got.Txs) != tt.wantTxCount { - t.Errorf("EthRPC.GetBlock().Txs = %v, want %v", len(got.Txs), tt.wantTxCount) - return - } - }) - } -} - -func TestEthRPC_GetTransaction(t *testing.T) { - var ( - addr1, addr2 bchain.Address - err error - ) - addr1, err = bchain.NewBaseAddress("0x682b7903a11098cf770c7aef4aa02a85b3f3601a") - if err == nil { - addr2, err = bchain.NewBaseAddress("0x555ee11fbddc0e49a9bab358a8941ad95ffdb48f") - } - if err != nil { - panic(err) - } - - if testing.Short() { - t.Skip("skipping test in short mode.") - } - bh, err := setupEthRPC().getBestHeader() - if err != nil { - panic(err) - } - type fields struct { - b *EthereumRPC - } - type args struct { - txid string - } - tests := []struct { - name string - fields fields - args args - want *bchain.Tx - wantErr bool - }{ - { - name: "1", - fields: fields{ - b: setupEthRPC(), - }, - args: args{ - txid: "0xe6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d", - }, - want: &bchain.Tx{ - Blocktime: 1521515026, - Confirmations: uint32(bh.Number.Uint64()) - 2870000 + 1, - Hex: "7b226e6f6e6365223a2230783239666165222c226761735072696365223a223078313261303566323030222c22676173223a2230786462626130222c22746f223a22307836383262373930336131313039386366373730633761656634616130326138356233663336303161222c2276616c7565223a22307830222c22696e707574223a223078663032356361616630303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030323235222c2268617368223a22307865366231363864366262336438656437386530336462663832386236626664316662363133663665313239636261363234393634393834353533373234633564222c22626c6f636b4e756d626572223a223078326263616630222c2266726f6d223a22307864616363396336313735346130633436313666633533323364633934366538396562323732333032222c227472616e73616374696f6e496e646578223a22307831222c2276223a2230783162222c2272223a22307831626434306133313132326330333931386466366431363664373430613661336132326630386132353933346365623136383863363239373736363163383063222c2273223a22307836303766626331356331663739393561343235386635613962636363363362303430333632643139393164356566653133363163353632323265346361383966227d", - Time: 1521515026, - Txid: "0xe6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d", - Vin: []bchain.Vin{ - { - Addresses: []string{"0xdacc9c61754a0c4616fc5323dc946e89eb272302"}, - }, - }, - Vout: []bchain.Vout{ - { - ScriptPubKey: bchain.ScriptPubKey{ - Addresses: []string{"0x682b7903a11098cf770c7aef4aa02a85b3f3601a"}, - }, - Address: addr1, - }, - }, - }, - }, - { - name: "2", - fields: fields{ - b: setupEthRPC(), - }, - args: args{ - txid: "cd647151552b5132b2aef7c9be00dc6f73afc5901dde157aab131335baaa853b", - }, - want: &bchain.Tx{ - Blocktime: 1521533434, - Confirmations: uint32(bh.Number.Uint64()) - 2871048 + 1, - Hex: "7b226e6f6e6365223a22307862323663222c226761735072696365223a223078343330653233343030222c22676173223a22307835323038222c22746f223a22307835353565653131666264646330653439613962616233353861383934316164393566666462343866222c2276616c7565223a22307831626330313539643533306536303030222c22696e707574223a223078222c2268617368223a22307863643634373135313535326235313332623261656637633962653030646336663733616663353930316464653135376161623133313333356261616138353362222c22626c6f636b4e756d626572223a223078326263663038222c2266726f6d223a22307833653361336436396463363662613130373337663533316564303838393534613965633839643937222c227472616e73616374696f6e496e646578223a22307861222c2276223a2230783239222c2272223a22307866373136316331373064343335373361643963386437303163646166373134666632613534386135363262306463363339323330643137383839666364343035222c2273223a22307833633439373766633930333835613237656661303033326531376234396664353735623238323663623536653364316563663231353234663261393466393135227d", - Time: 1521533434, - Txid: "0xcd647151552b5132b2aef7c9be00dc6f73afc5901dde157aab131335baaa853b", - Vin: []bchain.Vin{ - { - Addresses: []string{"0x3e3a3d69dc66ba10737f531ed088954a9ec89d97"}, - }, - }, - Vout: []bchain.Vout{ - { - ScriptPubKey: bchain.ScriptPubKey{ - Addresses: []string{"0x555ee11fbddc0e49a9bab358a8941ad95ffdb48f"}, - }, - Address: addr2, - }, - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := tt.fields.b.GetTransaction(tt.args.txid) - if (err != nil) != tt.wantErr { - t.Errorf("EthRPC.GetTransaction() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("EthRPC.GetTransaction() = %v, want %v", got, tt.want) - } - }) - } -} - func TestEthRPC_EstimateFee(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } type fields struct { b *EthereumRPC } @@ -485,7 +210,7 @@ func TestEthRPC_EstimateFee(t *testing.T) { { name: "1", fields: fields{ - b: setupEthRPC(), + b: rpcTest.Client.(*EthereumRPC), }, args: args{ blocks: 10, @@ -508,9 +233,6 @@ func TestEthRPC_EstimateFee(t *testing.T) { } func TestEthRPC_GetMempool(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } type fields struct { b *EthereumRPC } @@ -523,7 +245,7 @@ func TestEthRPC_GetMempool(t *testing.T) { { name: "1", fields: fields{ - b: setupEthRPC(), + b: rpcTest.Client.(*EthereumRPC), }, }, } diff --git a/bchain/coins/litecoin/litecoinparser_test.go b/bchain/coins/litecoin/litecoinparser_test.go index 2d8cd90e..a28a4a35 100644 --- a/bchain/coins/litecoin/litecoinparser_test.go +++ b/bchain/coins/litecoin/litecoinparser_test.go @@ -1,3 +1,5 @@ +// +build unittest + package litecoin import ( diff --git a/bchain/coins/zec/zcashparser_test.go b/bchain/coins/zec/zcashparser_test.go index 7b8db889..0bb61fe1 100644 --- a/bchain/coins/zec/zcashparser_test.go +++ b/bchain/coins/zec/zcashparser_test.go @@ -1,3 +1,5 @@ +// +build unittest + package zec import ( diff --git a/bchain/coins/zec/zcashrpc_test.go b/bchain/coins/zec/zcashrpc_test.go new file mode 100644 index 00000000..a69ffa77 --- /dev/null +++ b/bchain/coins/zec/zcashrpc_test.go @@ -0,0 +1,42 @@ +// +build integration + +package zec + +import ( + "blockbook/bchain" + "blockbook/bchain/tests/rpc" + "encoding/json" + "testing" +) + +func getRPCClient(cfg json.RawMessage) (bchain.BlockChain, error) { + c, err := NewZCashRPC(cfg, nil) + if err != nil { + return nil, err + } + cli := c.(*ZCashRPC) + cli.Parser = NewZCashParser(cli.ChainConfig) + return cli, nil +} + +var rpcTest *rpc.Test + +func init() { + t, err := rpc.NewTest("Zcash Testnet", getRPCClient) + if err != nil { + panic(err) + } + rpcTest = t +} + +func TestZCashRPC_GetBlockHash(t *testing.T) { + rpcTest.TestGetBlockHash(t) +} + +func TestZCashRPC_GetBlock(t *testing.T) { + rpcTest.TestGetBlock(t) +} + +func TestZCashRPC_GetTransaction(t *testing.T) { + rpcTest.TestGetTransaction(t) +} diff --git a/bchain/tests/rpc/config.json b/bchain/tests/rpc/config.json new file mode 100644 index 00000000..086a0105 --- /dev/null +++ b/bchain/tests/rpc/config.json @@ -0,0 +1,27 @@ +{ + "Bcash Testnet": { + "url": "http://localhost:18031", + "user": "rpc", + "pass": "rpc" + }, + "Bitcoin Testnet": { + "url": "http://localhost:18030", + "user": "rpc", + "pass": "rpc" + }, + "Dash Testnet": { + "url": "http://localhost:18033", + "user": "rpc", + "pass": "rpc" + }, + "Ethereum Testnet": { + "url": "ws://localhost:18036", + "user": null, + "pass": null + }, + "Zcash Testnet": { + "url": "http://localhost:18032", + "user": "rpc", + "pass": "rpc" + } +} diff --git a/bchain/tests/rpc/data.go b/bchain/tests/rpc/data.go new file mode 100644 index 00000000..7d50460a --- /dev/null +++ b/bchain/tests/rpc/data.go @@ -0,0 +1,97 @@ +// +build integration + +package rpc + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "path/filepath" + "strings" +) + +func joinPathsWithCommonElement(p1, p2 string) (string, bool) { + idx := strings.IndexRune(p2, filepath.Separator) + if idx <= 0 { + return "", false + } + p2root := p2[:idx] + idx = strings.LastIndex(p1, p2root) + if idx < 0 { + return "", false + } + prefix := p1[:idx] + return filepath.Join(prefix, p2), true +} + +func readDataFile(dir, relDir, filename string) ([]byte, error) { + var err error + dir, err = filepath.Abs(dir) + if err == nil { + dir, err = filepath.EvalSymlinks(dir) + } + if err != nil { + return nil, err + } + path, ok := joinPathsWithCommonElement(dir, relDir) + if !ok { + return nil, errors.New("Path not found") + } + filename = strings.Replace(filename, " ", "_", -1) + path = filepath.Join(path, filename) + return ioutil.ReadFile(path) +} + +var testConfigRegistry map[string]*TestConfig + +func LoadTestConfig(coin string) (*TestConfig, error) { + if testConfigRegistry == nil { + b, err := readDataFile(".", "bchain/tests/rpc", "config.json") + if err != nil { + return nil, err + } + var v map[string]*TestConfig + err = json.Unmarshal(b, &v) + if err != nil { + return nil, err + } + testConfigRegistry = v + } + c, found := testConfigRegistry[coin] + if !found { + return nil, errors.New("Test config not found") + } + return c, nil +} + +func LoadRPCConfig(coin string) (json.RawMessage, error) { + t := `{ + "coin_name": "%s", + "rpcURL": "%s", + "rpcUser": "%s", + "rpcPass": "%s", + "rpcTimeout": 25, + "parse": true + }` + + c, err := LoadTestConfig(coin) + if err != nil { + return json.RawMessage{}, err + } + + return json.RawMessage(fmt.Sprintf(t, coin, c.URL, c.User, c.Pass)), nil +} + +func LoadTestData(coin string) (*TestData, error) { + b, err := readDataFile(".", "bchain/tests/rpc/testdata", coin+".json") + if err != nil { + return nil, err + } + var v TestData + err = json.Unmarshal(b, &v) + if err != nil { + return nil, err + } + return &v, nil +} diff --git a/bchain/tests/rpc/rpc.go b/bchain/tests/rpc/rpc.go new file mode 100644 index 00000000..0a486963 --- /dev/null +++ b/bchain/tests/rpc/rpc.go @@ -0,0 +1,126 @@ +// +build integration + +package rpc + +import ( + "blockbook/bchain" + "encoding/json" + "reflect" + "testing" +) + +type TestConfig struct { + URL string `json:"url"` + User string `json:"user"` + Pass string `json:"pass"` +} + +type TestData struct { + BlockHeight uint32 `json:"blockHeight"` + BlockHash string `json:"blockHash"` + BlockHex string `json:"blockHex"` + BlockTxs []string `json:"blockTxs"` + TxDetails map[string]*bchain.Tx `json:"txDetails"` +} + +type Test struct { + Client bchain.BlockChain + TestData *TestData +} + +type TestChainFactoryFunc func(json.RawMessage) (bchain.BlockChain, error) + +func NewTest(coin string, factory TestChainFactoryFunc) (*Test, error) { + cfg, err := LoadRPCConfig(coin) + if err != nil { + return nil, err + } + cli, err := factory(cfg) + if err != nil { + return nil, err + } + td, err := LoadTestData(coin) + if err != nil { + return nil, err + } + + if td.TxDetails != nil { + parser := cli.GetChainParser() + + for _, tx := range td.TxDetails { + err := setTxAddresses(parser, tx) + if err != nil { + return nil, err + } + } + } + + return &Test{Client: cli, TestData: td}, nil +} + +func setTxAddresses(parser bchain.BlockChainParser, tx *bchain.Tx) error { + // pack and unpack transaction in order to get addresses decoded - ugly but works + var tmp *bchain.Tx + b, err := parser.PackTx(tx, 0, 0) + if err == nil { + tmp, _, err = parser.UnpackTx(b) + if err == nil { + for i := 0; i < len(tx.Vout); i++ { + tx.Vout[i].ScriptPubKey.Addresses = tmp.Vout[i].ScriptPubKey.Addresses + tx.Vout[i].Address = tmp.Vout[i].Address + } + } + } + return err +} +func (rt *Test) TestGetBlockHash(t *testing.T) { + hash, err := rt.Client.GetBlockHash(rt.TestData.BlockHeight) + if err != nil { + t.Error(err) + return + } + + if hash != rt.TestData.BlockHash { + t.Errorf("GetBlockHash() got %q, want %q", hash, rt.TestData.BlockHash) + } +} + +func (rt *Test) TestGetBlock(t *testing.T) { + blk, err := rt.Client.GetBlock(rt.TestData.BlockHash, 0) + if err != nil { + t.Error(err) + return + } + + if len(blk.Txs) != len(rt.TestData.BlockTxs) { + t.Errorf("GetBlock() number of transactions: got %d, want %d", len(blk.Txs), len(rt.TestData.BlockTxs)) + } + + for ti, tx := range blk.Txs { + if tx.Txid != rt.TestData.BlockTxs[ti] { + t.Errorf("GetBlock() transaction %d: got %s, want %s", ti, tx.Txid, rt.TestData.BlockTxs[ti]) + } + } + +} +func (rt *Test) TestGetTransaction(t *testing.T) { + for txid, want := range rt.TestData.TxDetails { + got, err := rt.Client.GetTransaction(txid) + if err != nil { + t.Error(err) + return + } + + // Confirmations is variable field, we just check if is set and reset it + if got.Confirmations > 0 { + got.Confirmations = 0 + } else { + t.Errorf("GetTransaction() has empty Confirmations field") + continue + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("GetTransaction() got %v, want %v", got, want) + } + } +} diff --git a/bchain/tests/rpc/testdata/Bcash_Testnet.json b/bchain/tests/rpc/testdata/Bcash_Testnet.json new file mode 100644 index 00000000..99d94025 --- /dev/null +++ b/bchain/tests/rpc/testdata/Bcash_Testnet.json @@ -0,0 +1,145 @@ +{ + "blockHeight": 1239639, + "blockHash": "0000000075dd9708c23f5830de27c5d644983bb877c575c52926f19be7d80fe2", + "blockTxs": [ + "f12d490ad439ff37c91e9ec5ecd5440c2d4a96653f2668402c5ebacc6d07dcf8", + "0e78e3276bd59dd403306334ab05b2d58167b4cf04dbb94ae76dc189db5bf3df", + "9eeba85181725993afc6a89e2e98c07e12bbd9c732b851af448eb6055d8d8ba7", + "045f898538c5b9a99a4bf21c8e06aa7279caacdf7616994b7d4f0ed39637dff7", + "8614ae1addce0983f8b1bb2e6139fca4e7aa2d4f57f28ce1145bd1103c75a307", + "1d10b63e6d336b19ce7f7a867639b52b42be7e63ea53a86e5c7b101eb8f5bf59", + "1cbb193374d455ad09f1ae4486418dbbd65435ac14b1b8733897976bd776478b", + "722d99abace73265477b42849c86f9a8460a07aef7497187db24cffb4b27c856", + "a856b35655852ec5d698561633f997b945ee03d57a7b60e3c86eaabdd3a90054", + "e82cdbb67f6c23c72d0273bdd976697d5bfc4b2373e637f4eeb5211134b84bd6", + "efd3295c37cd3988f16efc09d083dbbc27f5c0074b9ea0dffd4f8540b36dd02c", + "b955bc3e800aa6d72c1a9eb9ce4a513f409ec923c31e30075f58336c830040a8", + "9730ec3e10e5a3bf358e533a497e75f44aceaf28da8248534326e5d7dac0d048", + "a90df75c045e638a0c00902d35c9c72592d0e76ac0fa34fba6aad749c5aded21", + "0e21dd654596cac9f579e21a549a533d1be7319470fcf8f920a35d64cf020d1f" + ], + "txDetails": { + "9eeba85181725993afc6a89e2e98c07e12bbd9c732b851af448eb6055d8d8ba7": { + "hex": "0200000001b2c673aede02a4054a8c23e456e581d684f47dadb54083317d6152949d55d94e010000006b483045022100f31a23984a44f485a570a102899e3a25cdf6d1234259e602dbe61f2c3e77e490022069a6a7b013452bd66ed3c11aba22a64559134cd1af3d283730a9b7fb33631cca412103cb05918b81d36c387c791d2accfaefead287a4a30427387fb1095fc0c363ef8efeffffff0200c2eb0b0000000017a914ac90ed8510c9a7445b104fd1602341dc2f890d15878906e1e1160000001976a9147f7ed17e71afc40beac9b8d0b0fb53731161339c88ac56ea1200", + "txid": "9eeba85181725993afc6a89e2e98c07e12bbd9c732b851af448eb6055d8d8ba7", + "blocktime":1528796166, + "time":1528796166, + "locktime": 1239638, + "vin": [ + { + "txid": "4ed9559d9452617d318340b5ad7df484d681e556e4238c4a05a402deae73c6b2", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "483045022100f31a23984a44f485a570a102899e3a25cdf6d1234259e602dbe61f2c3e77e490022069a6a7b013452bd66ed3c11aba22a64559134cd1af3d283730a9b7fb33631cca412103cb05918b81d36c387c791d2accfaefead287a4a30427387fb1095fc0c363ef8e" + } + } + ], + "vout": [ + { + "value": 2.0, + "n": 0, + "scriptPubKey": { + "hex": "a914ac90ed8510c9a7445b104fd1602341dc2f890d1587" + } + }, + { + "value": 982.78901385, + "n": 1, + "scriptPubKey": { + "hex": "76a9147f7ed17e71afc40beac9b8d0b0fb53731161339c88ac" + } + } + ] + }, + "0e21dd654596cac9f579e21a549a533d1be7319470fcf8f920a35d64cf020d1f": { + "hex": "0200000008349c1ef994e931d4da1f545d2e578f898ddf457392c5485dc75378de8f36bef4010000006a4730440220351f1566e3ef02e900942103c60cba5a768cd710d3d1afbc75406099ad2d9e4702206e0f639a9991c7afb2136fb2e437629103ad0989898d1c90078ded5f08f5cb3341210303ae341929bdb242226a9a8c15cdbed5b89fa286842714d8be7e3f16c63abe11feffffff4ae685c8efc7f090e75b80f1b705d7bf5fa6dbbcf88c5f5cf2dc0678a9646fb4000000006b483045022100b8dae1825b0d0ccbe212e8da6767ea049bad9acfc737e5c5ef3dc5eeef6d313c02207e4c669956f871a4a5f71903bf38a8c587b81940943682364b11fb1cd9c078d7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2feffffff1ac21ded05387165cb7d0d95e2036a82f79a314575f065407e0c32a6b24b2f1d010000006b483045022100ef4a9469a5b3dbc0f03e8d8c5f254ad86f2c1e92e75a5ee737c3b3186b5edd95022076abcdfa976c3c78d2b196fb79699057248fad6d3d5e782524b85d84704394cc412103882df93f092501520bb36206703dadb65b25a3fbd0323c690dc8e72f5ee4a770feffffffea6905abb313a2aa3f6c8a056294abe06774dbf75688b03b96b8a2132aaf0cbf010000006b483045022100e4ab9dd0a75bc76c6c2cf549fb37c5577bad7f58953a7103abe4a77a95b873c10220545aa0c2b2869d444fb99d237549d6ac270c711d60788a6463ef4fee63ebd8fc4121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9efeffffff8c9a7a668dad3766f953d9779861f9c007b0a06f6ea2afbf8ab30137f34300fa000000006a47304402207253f724d891f5e1e66ec0c8084ade910a52257a1257933c23bd1b4da862e33a0220363df96e31dffa0a599b56c5049519a4d8ed34e96dc1fefecfd2bc31fc6d79d9412103186a4fc8445b3b437587c71f00fc9da7a267c0a38915fcf567528e310a73c0bdfeffffff82445d5b10b84b5256ef028615465e2d139c45584884c06e68bc38930d826e72010000006a47304402204846adc41599336307a087d4fa779a059ffe12c69456c82fa4b03942c901284002203e5f0c5e72b9ded7f48b4d22cbdb39390bea33003d46d8b4652c8ede1f13b3e54121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9efeffffffb8816c2c3b95aa8126f6d2d04798632b3167e6e2144d5f4e84cfb29e9d6f442d010000006a473044022078b1aff9a4ed3452f782db38341d846edd295f9a907c7373519408fb33eeb3240220578da5e91ec0c82604982b09cbd1f44e28260fcd640bcc55f086ce296ef32ef7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2feffffff70628ac9b2814f99fe4cd5f67a76047af533774ae90331fa8cb68e4dcbff1cb0010000006b483045022100cd88592589ab3bbd6e23920770a067a37ffbff3a31238167731377f11903676202202cb1c019365870dad3113abb3b0bc68ab9e65d9d60592f3315ffa444dfd88be741210393bd44ad6ed9295bf408e01bcdbdf6e4e8fd4a573ad20f37e54ff6e9b1596028feffffff027f766c02000000001976a9149f96c6e6c3aabf438eef5c589c47fa4b4f96592a88ac1c3d0f00000000001976a914e2ffd7cf2fe9468512878196d1b48fee9e9d003288ac56ea1200", + "txid": "0e21dd654596cac9f579e21a549a533d1be7319470fcf8f920a35d64cf020d1f", + "blocktime":1528796166, + "time":1528796166, + "locktime": 1239638, + "vin": [ + { + "txid": "f4be368fde7853c75d48c5927345df8d898f572e5d541fdad431e994f91e9c34", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "4730440220351f1566e3ef02e900942103c60cba5a768cd710d3d1afbc75406099ad2d9e4702206e0f639a9991c7afb2136fb2e437629103ad0989898d1c90078ded5f08f5cb3341210303ae341929bdb242226a9a8c15cdbed5b89fa286842714d8be7e3f16c63abe11" + } + }, + { + "txid": "b46f64a97806dcf25c5f8cf8bcdba65fbfd705b7f1805be790f0c7efc885e64a", + "vout": 0, + "sequence": 4294967294, + "scriptSig": { + "hex": "483045022100b8dae1825b0d0ccbe212e8da6767ea049bad9acfc737e5c5ef3dc5eeef6d313c02207e4c669956f871a4a5f71903bf38a8c587b81940943682364b11fb1cd9c078d7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2" + } + }, + { + "txid": "1d2f4bb2a6320c7e4065f07545319af7826a03e2950d7dcb65713805ed1dc21a", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "483045022100ef4a9469a5b3dbc0f03e8d8c5f254ad86f2c1e92e75a5ee737c3b3186b5edd95022076abcdfa976c3c78d2b196fb79699057248fad6d3d5e782524b85d84704394cc412103882df93f092501520bb36206703dadb65b25a3fbd0323c690dc8e72f5ee4a770" + } + }, + { + "txid": "bf0caf2a13a2b8963bb08856f7db7467e0ab9462058a6c3faaa213b3ab0569ea", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "483045022100e4ab9dd0a75bc76c6c2cf549fb37c5577bad7f58953a7103abe4a77a95b873c10220545aa0c2b2869d444fb99d237549d6ac270c711d60788a6463ef4fee63ebd8fc4121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9e" + } + }, + { + "txid": "fa0043f33701b38abfafa26e6fa0b007c0f9619877d953f96637ad8d667a9a8c", + "vout": 0, + "sequence": 4294967294, + "scriptSig": { + "hex": "47304402207253f724d891f5e1e66ec0c8084ade910a52257a1257933c23bd1b4da862e33a0220363df96e31dffa0a599b56c5049519a4d8ed34e96dc1fefecfd2bc31fc6d79d9412103186a4fc8445b3b437587c71f00fc9da7a267c0a38915fcf567528e310a73c0bd" + } + }, + { + "txid": "726e820d9338bc686ec0844858459c132d5e46158602ef56524bb8105b5d4482", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "47304402204846adc41599336307a087d4fa779a059ffe12c69456c82fa4b03942c901284002203e5f0c5e72b9ded7f48b4d22cbdb39390bea33003d46d8b4652c8ede1f13b3e54121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9e" + } + }, + { + "txid": "2d446f9d9eb2cf844e5f4d14e2e667312b639847d0d2f62681aa953b2c6c81b8", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "473044022078b1aff9a4ed3452f782db38341d846edd295f9a907c7373519408fb33eeb3240220578da5e91ec0c82604982b09cbd1f44e28260fcd640bcc55f086ce296ef32ef7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2" + } + }, + { + "txid": "b01cffcb4d8eb68cfa3103e94a7733f57a04767af6d54cfe994f81b2c98a6270", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "483045022100cd88592589ab3bbd6e23920770a067a37ffbff3a31238167731377f11903676202202cb1c019365870dad3113abb3b0bc68ab9e65d9d60592f3315ffa444dfd88be741210393bd44ad6ed9295bf408e01bcdbdf6e4e8fd4a573ad20f37e54ff6e9b1596028" + } + } + ], + "vout": [ + { + "value": 0.40662655, + "n": 0, + "scriptPubKey": { + "hex": "76a9149f96c6e6c3aabf438eef5c589c47fa4b4f96592a88ac" + } + }, + { + "value": 0.00998684, + "n": 1, + "scriptPubKey": { + "hex": "76a914e2ffd7cf2fe9468512878196d1b48fee9e9d003288ac" + } + } + ] + } + } +} diff --git a/bchain/tests/rpc/testdata/Bitcoin_Testnet.json b/bchain/tests/rpc/testdata/Bitcoin_Testnet.json new file mode 100644 index 00000000..0eb09a8a --- /dev/null +++ b/bchain/tests/rpc/testdata/Bitcoin_Testnet.json @@ -0,0 +1,123 @@ +{ + "blockHeight": 1325168, + "blockHash": "000000000000004ed0834f3de922e66d024ec4da9fcc2da17be61369cb6dc041", + "blockTxs": [ + "e1179f205aabbf48dc2ce4ebd9ed255571b0578e4de551f6574a50cb81120007", + "00a5aa2891d41af9eb1dc30c940f142a609ecab8f370eb0874ba7d32252d1b1b", + "1c519d80804dd17258cfc801bf2c875607956fc9f065a664f43e88d53f80af6f", + "b10c1e2f7c8a6b10fddf94260aff0f8a5f56e33c8d0de48c49a72eb8418c3f6e", + "ba85ca543b290deb84cde9c4ca53614dbe557a3dede5d0adb141f803f8e82f34", + "60dfc2c9cc184ae68ca9e540ab4393d9d2179d060e2ac290f29560c6a1360f51", + "3a40bca678653ae8f7f6d2771b571d5ace1a258056b99e3fd361a10f1016bc53", + "4d4e495f3329801d92c7e3dc9874a372576bf3548decf884ede388143980ecab", + "74ba4bee8d559e4d8b4859c086b0ea5f2c36bcabc95d8578e775f065f70943b8", + "32bcc281f081e172dcb40ad137564724bd9486095813b78990d1d986173ac3c6", + "b6e77c59f4a988731d9b8520e0f4971223e622946eb12e28cc2bab72f1e9c2f8", + "0bc8f39da5d5300a2728b45edb18c8219e94a8b27a2e8074f6c5c10a00d99788", + "8329b31d2a490d57980afcf5c7df4574ce57f952aef6f5aecb3b7786f5c9f255", + "e559c2fd0f4e8aebe28fcb6dbb099fc6ee92d726d74fda28522f52bc1490a470", + "3005378ee85fc905a1812bdfae4b2e0e9bb09f5867a53fd73237bb319a1774aa", + "ebea245b9e4d96fab65c938547a9b3ffd03659b92b8ae4fcdfe4ac9bc325c0a2", + "a2d5fe23b50253dda9941dd6c97c04853d58f048acf347acf9ccf549ee215b51", + "017c2ccec866850521db877c1c7f6d095b7df668f891cfaf70a5e14ce39d010c", + "d101d3467a831cc4dfc87bdd19d0ff5d01b8c872e47b2096eeeac3b44c2a258a", + "3884180bab62d0f0498a8ad012b0005aceec778a18a617e5392d99cee5f21869", + "a00200e57bed4fbd193c4cad49549d311282fee9a82956083353a2874f9bfd9f", + "d32ce7a9413111fb2e3578472d520eb1437db701f20256e3afd37b7c0a6d67e6", + "fed1df6d23a40e1a1f26820bbe35febb668aa2240902f1fd17b31a84dde6eb39", + "5bef621ad6d0970939ae36270a3228d3c315f8008fb04eebffab5f7a3589d114", + "411e7f3f4cae4125c8933403809771ebfcaa088f6ef773e5a412ead8639fb515", + "d53858bbbbde4518ea92abda93ac5d01e5122d420a468e6d076244edd99bcea1", + "b5fc4d963805b439d11f06b5d5d89ce3aac225e7145d1673d20d3d37a12c61dd", + "c8d7332377d4bf43c232bc7afc3d7e3aacf13523d1c8488f68f530e58e6cfd88", + "3c21a6b7e3810ca10efac45446cd2b7ef0c9848ac589be7375b61ea5aabbbea4", + "5a25c2b70e2194e05a6208c99343ebe0fad970dd19f3f9cca88aaf77ab9e4658", + "031e3c08ebdcafccf6dc5d7ff1161cd5314424d0a943d2c22a5a2109286e332d", + "4992d16008aa3050b3e2e4aab67e488eb338850ff1c348367ae3d089d8d67a52", + "beb3e71b8da7da7917228f5ce8a88afdc45836c421b053dde24d367865326bd7" + ], + "txDetails": { + "e559c2fd0f4e8aebe28fcb6dbb099fc6ee92d726d74fda28522f52bc1490a470": { + "hex": "01000000000102a4b8c14f271cfa77d5ecaed9c3026472a55ea6bca119e2ff7b04975326f5974001000000171600147edbcdda98080eeb6e8a63c63da135498295c3cdffffffffabcdf96b8ba187c24d70f98a2edfbf100821506212637f28b30a08efa970a4eb0100000017160014df7d60680e984aae4052e24bce8f17e4bfdcc532ffffffff0292fe1e00000000001976a914abba3808b854c70b63ff038fcddfbafcb707713988ac13e796110100000017a914c9e67d2b78a38857c786ea9a2fc3e64cb6e775648702483045022100a6910d3a3b64545a44e097a3739b1206095602fa796afc51f81b249d1293ad0a02206cdae51853b59ca52003f4e54ea8ae418b6b4d036cbe1fdd78677efe8eddb318012102b45e239d96f8504ae45a32af7c80f6164f7b9658166e318521ee822192fee3ef0247304402202684a6f59ee255f3f5e9a9209a735bf2aaa818d47add7c3f7a5590623bd2211c0220452bf2fb8d0dc0380862988f0f098c21e861004e02da7bd1fc6bea4e7f33d2dc012103f308867fda821467f77d372791644225174ae16daba86e55754c150a8d5aa40d00000000", + "txid": "e559c2fd0f4e8aebe28fcb6dbb099fc6ee92d726d74fda28522f52bc1490a470", + "blocktime": 1528788394, + "time": 1528788394, + "locktime": 0, + "vin": [ + { + "txid": "4097f5265397047bffe219a1bca65ea5726402c3d9aeecd577fa1c274fc1b8a4", + "vout": 1, + "sequence": 4294967295, + "scriptSig": { + "hex": "1600147edbcdda98080eeb6e8a63c63da135498295c3cd" + } + }, + { + "txid": "eba470a9ef080ab3287f63126250210810bfdf2e8af9704dc287a18b6bf9cdab", + "vout": 1, + "sequence": 4294967295, + "scriptSig": { + "hex": "160014df7d60680e984aae4052e24bce8f17e4bfdcc532" + } + } + ], + "vout": [ + { + "value": 0.02031250, + "n": 0, + "scriptPubKey": { + "hex": "76a914abba3808b854c70b63ff038fcddfbafcb707713988ac" + } + }, + { + "value": 45.90069523, + "n": 1, + "scriptPubKey": { + "hex": "a914c9e67d2b78a38857c786ea9a2fc3e64cb6e7756487" + } + } + ] + }, + "5bef621ad6d0970939ae36270a3228d3c315f8008fb04eebffab5f7a3589d114": { + "hex": "01000000025b0551bd0fffcf55881e285e15b364ab9a831d2494d2eb7a163a4bbd6f551151000000006b483045022100dff500e8c060a9c8810483d4ada8f91c0b844e92778cc762300040870109c0be02207029fa781ec37ddeb0ffbfa7160e625afdd126f30ec11fb9bc25f4d2164933bb0121023c6017ab9f471a69157180c5e30b9aef2ff73ea2a1a774c53a975e2557536314ffffffffd49a58913818610b0aa065d4f32995863d216c44040a49d454f6b7eeb65c9adc010000006b483045022100dce24b819b70f920d0bb60fa1241fa14f2500412a60aceeaae2610e1593b5e3c022041fdc5a02dc26af043bea27713f1245340b98bd47aa283e23b96ecc4aae157a4012102d18a88bcf5f65d937de7d9bc24d2f492a55216087262bf4683d0055dd0521a56feffffff02da869800000000001976a914b4f1349ec3e7c751c6720e2c0783e3449e21e36888ac80fe210a000000001976a914b4f1349ec3e7c751c6720e2c0783e3449e21e36888ac00000000", + "txid": "5bef621ad6d0970939ae36270a3228d3c315f8008fb04eebffab5f7a3589d114", + "blocktime": 1528788394, + "time": 1528788394, + "locktime": 0, + "vin": [ + { + "txid": "5111556fbd4b3a167aebd294241d839aab64b3155e281e8855cfff0fbd51055b", + "vout": 0, + "sequence": 4294967295, + "scriptSig": { + "hex": "483045022100dff500e8c060a9c8810483d4ada8f91c0b844e92778cc762300040870109c0be02207029fa781ec37ddeb0ffbfa7160e625afdd126f30ec11fb9bc25f4d2164933bb0121023c6017ab9f471a69157180c5e30b9aef2ff73ea2a1a774c53a975e2557536314" + } + }, + { + "txid": "dc9a5cb6eeb7f654d4490a04446c213d869529f3d465a00a0b61183891589ad4", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "483045022100dce24b819b70f920d0bb60fa1241fa14f2500412a60aceeaae2610e1593b5e3c022041fdc5a02dc26af043bea27713f1245340b98bd47aa283e23b96ecc4aae157a4012102d18a88bcf5f65d937de7d9bc24d2f492a55216087262bf4683d0055dd0521a56" + } + } + ], + "vout": [ + { + "value": 0.09995994, + "n": 0, + "scriptPubKey": { + "hex": "76a914b4f1349ec3e7c751c6720e2c0783e3449e21e36888ac" + } + }, + { + "value": 1.7, + "n": 1, + "scriptPubKey": { + "hex": "76a914b4f1349ec3e7c751c6720e2c0783e3449e21e36888ac" + } + } + ] + } + } +} diff --git a/bchain/tests/rpc/testdata/Dash_Testnet.json b/bchain/tests/rpc/testdata/Dash_Testnet.json new file mode 100644 index 00000000..d86f0bee --- /dev/null +++ b/bchain/tests/rpc/testdata/Dash_Testnet.json @@ -0,0 +1,111 @@ +{ + "blockHeight": 139521, + "blockHash": "000000000296ea05e13b5479f6c041de575eec90759f58f57d311a8918b0af17", + "blockTxs": [ + "cfe2d2c5bd9929349a9d8f3d8f2423f4f0c9b408ed41b3002be5e7437a20aa7d", + "3f7ac6c55c0b383feb17715aef3cebf29182039fc42577d7c517b2fc04096942", + "3f296b929f6ee4f0ad3d6fce35873d6aeacbdf06aaf2abe384beb6e3f2a4dd03", + "5ef4f9b7e4c0240687c3a6e6a073e0fbc753645d231ca35435b95325778b7186", + "805b5ba055227b0f7dbbdef8e603632c4d25b93f0e87c59fc74cbe8ad8dbe806", + "392785b88f03c82492172827f30cbed4761de3098a0faaa740999b412ff15e46", + "13fafd7c8afc6fd2c860d342eaf0cfe0edd2b994bb836898c02830b2f688155e", + "26bc95fcc71380f0d66e437314c72999c0848cab81fe1f91c9c95bf15b74855c", + "7873d8d774f2aae72100620a21b38ea681b488b328802b6ec3271b1d727c6b73", + "23147585fd4ed3970118027ce9b2e190e264f26fbf5d8c9708a483cee6cada43", + "e079894b2545eca7184a2f0eaccf4b069242f18fa0721aedc8f66b73112a1e8f", + "b36284854fa1947844ecc5d62768be3e14cc44c430db87b1b90184364b30dbf4", + "1fd3ad5d0392cedf318600908270986c801cac161ef06f660591634cc2a29652", + "7a5b8944589b0cfba9c408b24b095648b0040a37fd769a9785982603bb7ca1f7", + "7da1811ec3f2c6381d89e59f40957d36c898ba1bb70b976e0b5490d3b9fa8952", + "dbcfa65bdfe758353305eaff11b300463018efb7fa8f17c6c6a98bb8dba6bcc9", + "c046821e5503770304359792c20c1ed3e71509a19a867acf1dae113bf52d2a6f", + "d3cea11e1a4937323cc94172f93a2e0edc0981a706f2d2c3315ace94b01b375a", + "6ef2a57e38dd891690c8f230b65f26247799b2421860e6cf8a1c7c8cfdedd96e", + "53834414d8a88afe4268b85f959e526a0c677ac6b7dedba9a796d1549852fd41", + "b761ebaccfb6d0eeaa5350ccafdf6a7633e59d6baadc932c6d78491cb08052a6" + ], + "txDetails": { + "3f7ac6c55c0b383feb17715aef3cebf29182039fc42577d7c517b2fc04096942": { + "hex": "020000000109d37a59b7da8902b8822547c927e35554b16667ffd698daae985c58c71616a4010000006b483045022100f3ef92ae1c8442eff171bd2dbc69373db384c86617032917b3bb2c5cd892bb2702207485cf5f8e6aa9fe245f5708a5c6ec37580c1c35e54429c6b43b322678f54cad012102ba7dbd059cc4f03e9fa4b6007b407279a154a8fc2103241511df155a52b7ea58feffffff02a055e18e170000001976a914e2114cb0a8b5d6f1c3c720f314cbf79e14bb9cdd88ac8cb65df0440000001976a9141ed486862342afd134f96a6cee5ca105801375df88ac00210200", + "txid": "3f7ac6c55c0b383feb17715aef3cebf29182039fc42577d7c517b2fc04096942", + "blocktime": 1528713762, + "time": 1528713762, + "locktime": 139520, + "vin": [ + { + "txid": "a41616c7585c98aeda98d6ff6766b15455e327c9472582b80289dab7597ad309", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "483045022100f3ef92ae1c8442eff171bd2dbc69373db384c86617032917b3bb2c5cd892bb2702207485cf5f8e6aa9fe245f5708a5c6ec37580c1c35e54429c6b43b322678f54cad012102ba7dbd059cc4f03e9fa4b6007b407279a154a8fc2103241511df155a52b7ea58" + } + } + ], + "vout": [ + { + "value": 1011.81380000, + "n": 0, + "scriptPubKey": { + "hex": "76a914e2114cb0a8b5d6f1c3c720f314cbf79e14bb9cdd88ac" + } + }, + { + "value": 2960.90449548, + "n": 1, + "scriptPubKey": { + "hex": "76a9141ed486862342afd134f96a6cee5ca105801375df88ac" + } + } + ] + }, + "6ef2a57e38dd891690c8f230b65f26247799b2421860e6cf8a1c7c8cfdedd96e": { + "hex": "020000000327ee9a2a360c6304fda56fa029670a95db595f70ae185a6f76ff1de415e07a18000000006a473044022011e7aed7a1cf187a9b6ca294bb76e3576cadebce48b5b944ad8393a60e8aa485022000818546dc7ba47c625258223dcefd6e84dc3faa8d54c646bfc0f55c4506c8f00121023fe7680caadc7bf3f796936de04d77e1007dea53880621c01d7b34720345d4ecfeffffff1ae8beeed571f491410ed327a6821b683d8ae571aea56057634da7aa8ce1041f000000006b4830450221009277cfac065a076814e18613d89c7d85a6461cf5283f2a9cee7254ec83fce637022023cf7186be7714921fe24719450e65a204d803738a1cb9fe35f30753f0696b8b012102aff34da05a74891899aace72f2e650ec1c039bfc519c192e6c231a2b7fa05749feffffff6388454ad1e5718af92def6fe307e64e97c43324d30c322b31edf85088020dc9000000006a47304402204435602e00d22417ff489302758a246df5fbc05e9bc4d0025464556ae7f77e70022036e30d2d46937ee0fc0cdf9a63e7baf8351bd16454ec02311cac52655ac4c32801210395fbe30126fc97a2c8b1e29bc27028a5a6885e4a4116d13e2cbe32c9d71e7f03feffffff02ce177e09000000001976a91437617547a3e0ba0adeead7c8c33c03970341404088acd0f7aad1010000001976a914f0b3dff509993e0b7035ce997b52763ce501d67888ac00210200", + "txid": "6ef2a57e38dd891690c8f230b65f26247799b2421860e6cf8a1c7c8cfdedd96e", + "blocktime": 1528713762, + "time": 1528713762, + "locktime": 139520, + "vin": [ + { + "txid": "187ae015e41dff766f5a18ae705f59db950a6729a06fa5fd04630c362a9aee27", + "vout": 0, + "sequence": 4294967294, + "scriptSig": { + "hex": "473044022011e7aed7a1cf187a9b6ca294bb76e3576cadebce48b5b944ad8393a60e8aa485022000818546dc7ba47c625258223dcefd6e84dc3faa8d54c646bfc0f55c4506c8f00121023fe7680caadc7bf3f796936de04d77e1007dea53880621c01d7b34720345d4ec" + } + }, + { + "txid": "1f04e18caaa74d635760a5ae71e58a3d681b82a627d30e4191f471d5eebee81a", + "vout": 0, + "sequence": 4294967294, + "scriptSig": { + "hex": "4830450221009277cfac065a076814e18613d89c7d85a6461cf5283f2a9cee7254ec83fce637022023cf7186be7714921fe24719450e65a204d803738a1cb9fe35f30753f0696b8b012102aff34da05a74891899aace72f2e650ec1c039bfc519c192e6c231a2b7fa05749" + } + }, + { + "txid": "c90d028850f8ed312b320cd32433c4974ee607e36fef2df98a71e5d14a458863", + "vout": 0, + "sequence": 4294967294, + "scriptSig": { + "hex": "47304402204435602e00d22417ff489302758a246df5fbc05e9bc4d0025464556ae7f77e70022036e30d2d46937ee0fc0cdf9a63e7baf8351bd16454ec02311cac52655ac4c32801210395fbe30126fc97a2c8b1e29bc27028a5a6885e4a4116d13e2cbe32c9d71e7f03" + } + } + ], + "vout": [ + { + "value": 1.59258574, + "n": 0, + "scriptPubKey": { + "hex": "76a91437617547a3e0ba0adeead7c8c33c03970341404088ac" + } + }, + { + "value": 78.12610000, + "n": 1, + "scriptPubKey": { + "hex": "76a914f0b3dff509993e0b7035ce997b52763ce501d67888ac" + } + } + ] + } + } +} diff --git a/bchain/tests/rpc/testdata/Ethereum_Testnet.json b/bchain/tests/rpc/testdata/Ethereum_Testnet.json new file mode 100644 index 00000000..cef9511f --- /dev/null +++ b/bchain/tests/rpc/testdata/Ethereum_Testnet.json @@ -0,0 +1,38 @@ +{ + "blockHeight": 2870000, + "blockHash": "0xeccd6b0031015a19cb7d4e10f28590ba65a6a54ad1baa322b50fe5ad16903895", + "blockTxs": [ + "0x17ee235fc0359155b25419e0e4c65d9c500df6e71e8288d6ef020d04cc2f2cb3", + "0xe6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d", + "0xe14e6628e866555091fda44f934dfc6bfbbcd8a81e1281bb682eaf293d248be8", + "0xcffe6d5f4022822ba5f1e64f5b413c7f91c3a48c3739429d72065ec1a8b82e91", + "0x1d261bf23077b7e68ad9300ce9d88e7f4f95075fe98ea76b70534acaf5cf891b", + "0x92f73c26c99ea3b15535829cf686541a1318623baf8c49fe2bf0168bf3c3e272", + "0x392394bb4e4463c9ed59182797b5dbf23aa41c6f6edd7f4b5025d82acf43c357", + "0x3dd838b8d5d9b7155c960f8a138a9c499b87d84b7c9d9a513d8022b1991f959c", + "0x4889b4d1ad3652f6c410a6b6c05a459b86e68363d795f38ec13d5dc6d595d977", + "0xd1e1ff22a80135d904d119252c5d56a8c5b07af9d26de79fd3dda8aeffccf9ae", + "0xd1c3b7835c6032eb9eb07fdce90944f26d470b1c027adf2951b329a783e8e628", + "0x7f0d140329941f120b5b3fc751e30adeb87b2aebbfce5adcd0216604a34b6cc0" + ], + "txDetails": { + "0xe6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d": { + "hex": "7b226e6f6e6365223a2230783239666165222c226761735072696365223a223078313261303566323030222c22676173223a2230786462626130222c22746f223a22307836383262373930336131313039386366373730633761656634616130326138356233663336303161222c2276616c7565223a22307830222c22696e707574223a223078663032356361616630303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030323235222c2268617368223a22307865366231363864366262336438656437386530336462663832386236626664316662363133663665313239636261363234393634393834353533373234633564222c22626c6f636b4e756d626572223a223078326263616630222c2266726f6d223a22307864616363396336313735346130633436313666633533323364633934366538396562323732333032222c227472616e73616374696f6e496e646578223a22307831222c2276223a2230783162222c2272223a22307831626434306133313132326330333931386466366431363664373430613661336132326630386132353933346365623136383863363239373736363163383063222c2273223a22307836303766626331356331663739393561343235386635613962636363363362303430333632643139393164356566653133363163353632323265346361383966227d", + "txid": "0xe6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d", + "blocktime": 1521515026, + "time": 1521515026, + "vin": [ + { + "addresses": ["0xdacc9c61754a0c4616fc5323dc946e89eb272302"] + } + ], + "vout": [ + { + "scriptPubKey": { + "addresses": ["0x682b7903a11098cf770c7aef4aa02a85b3f3601a"] + } + } + ] + } + } +} diff --git a/bchain/tests/rpc/testdata/Zcash_Testnet.json b/bchain/tests/rpc/testdata/Zcash_Testnet.json new file mode 100644 index 00000000..aca84131 --- /dev/null +++ b/bchain/tests/rpc/testdata/Zcash_Testnet.json @@ -0,0 +1,89 @@ +{ + "blockHeight": 251102, + "blockHash": "001335906f981bbf0633e124e2fa8afef3d882e34a0306a4e0c55162e57e673d", + "blockTxs": [ + "f02aa1c4c86e1d0cef6ccbbc48b2b7b38355bc3612d8f77dd58d04be1ec6ba19", + "a9f7cc34d7e272d2d9fb68cfa1c1941e338f377e6e426ae2fea1c12616d89c63", + "83f3db1d129a77bee9c6cf32cbc12d959cd0af8c8d734c2611db4bfddfe99202" + ], + "txDetails": { + "a9f7cc34d7e272d2d9fb68cfa1c1941e338f377e6e426ae2fea1c12616d89c63": { + "hex": "030000807082c40301601ade5f535f62f3da01e0c88b16beb916877fa0fa43299a9e2398b813d0a119020000006a4730440220770472192407cfc5c01e331442ac579a68e445a7ccb0fe8a481161519555794a02207b00b4c01af416a4972c2fd2fba8d58a6467da545400469ab57e9207a0ee3ca201210201d494a45f36f545443bafd1a9050b02f448dd236bb4ce2602f83978980b98f2feffffff02ea5e2c1c000000001976a9144ef2de10b304381a9404ccbe12f83395e7860bbd88ac00a3e1110000000017a9146a8eecfe3a7949a4a8c68754accaea75ab32cd9e8794d40300f1d4030000", + "txid": "a9f7cc34d7e272d2d9fb68cfa1c1941e338f377e6e426ae2fea1c12616d89c63", + "blocktime": 1528781777, + "time": 1528781777, + "locktime": 251028, + "vin": [ + { + "txid": "19a1d013b898239e9a2943faa07f8716b9be168bc8e001daf3625f535fde1a60", + "vout": 2, + "sequence": 4294967294, + "scriptSig": { + "hex": "4730440220770472192407cfc5c01e331442ac579a68e445a7ccb0fe8a481161519555794a02207b00b4c01af416a4972c2fd2fba8d58a6467da545400469ab57e9207a0ee3ca201210201d494a45f36f545443bafd1a9050b02f448dd236bb4ce2602f83978980b98f2" + } + } + ], + "vout": [ + { + "value": 4.72669930, + "n": 0, + "scriptPubKey": { + "hex": "76a9144ef2de10b304381a9404ccbe12f83395e7860bbd88ac", + "addresses": ["tmGunyrqeeHBKX3Jm23zKLokRogrS51Qzqh"] + } + }, + { + "value": 3.0, + "n": 1, + "scriptPubKey": { + "hex": "a9146a8eecfe3a7949a4a8c68754accaea75ab32cd9e87", + "addresses": ["t2GGEpYQUKiTsb9WYKD9AKNEriao84tVsr5"] + } + } + ] + }, + "83f3db1d129a77bee9c6cf32cbc12d959cd0af8c8d734c2611db4bfddfe99202": { + "hex": "030000807082c40302eac0139a677c07b6fcdddd205f4bf538d9cc9fb586565fe77440f93cf1b5ca9a010000006b4830450221009ad50b4f0da90a1876af6b43c029e55f1c8b8c44e94161a7f14c812adcebeaa902204b9df40096337eb43120408d4743693b17ea27fc0f660948a0a761264e67a6b00121036ec451bd1d3d39bb8d2d0264dd5a0ff817ae306ec7ce0c7c9b86be3f3dde8727feffffff6a1ed49e62634ab5a60b23ec73f9014ad1c9d3bd3bf023333c8eb311c802f298000000006b4830450221009008a10ebebf45f1a9aeb01a5b49a5de820a1a396ca1b900ea0420a1c2c49ea7022053fad044ff42792dcad16d084d67d7c4cc565458f78a14292fe5ef5e9f7a20bb012103448301b9253e6822ae05af64c61517fe8cf8b22590cc7d0b308b7f5cbce26db1feffffff0200a3e111000000001976a9149bc587e2cdd13b78e26f601f084ea0597b357f4d88ac3176a002000000001976a91414a88f1032c8ef1c6bd9177f62cdb260b5087b5488acd2d40300f1d4030000", + "txid": "83f3db1d129a77bee9c6cf32cbc12d959cd0af8c8d734c2611db4bfddfe99202", + "blocktime": 1528781777, + "time": 1528781777, + "locktime": 251090, + "vin": [ + { + "txid": "9acab5f13cf94074e75f5686b59fccd938f54b5f20ddddfcb6077c679a13c0ea", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "4830450221009ad50b4f0da90a1876af6b43c029e55f1c8b8c44e94161a7f14c812adcebeaa902204b9df40096337eb43120408d4743693b17ea27fc0f660948a0a761264e67a6b00121036ec451bd1d3d39bb8d2d0264dd5a0ff817ae306ec7ce0c7c9b86be3f3dde8727" + } + }, + { + "txid": "98f202c811b38e3c3323f03bbdd3c9d14a01f973ec230ba6b54a63629ed41e6a", + "vout": 0, + "sequence": 4294967294, + "scriptSig": { + "hex": "4830450221009008a10ebebf45f1a9aeb01a5b49a5de820a1a396ca1b900ea0420a1c2c49ea7022053fad044ff42792dcad16d084d67d7c4cc565458f78a14292fe5ef5e9f7a20bb012103448301b9253e6822ae05af64c61517fe8cf8b22590cc7d0b308b7f5cbce26db1" + } + } + ], + "vout": [ + { + "value": 3.0, + "n": 0, + "scriptPubKey": { + "hex": "76a9149bc587e2cdd13b78e26f601f084ea0597b357f4d88ac", + "addresses": ["tmPuzhaxL3vzTqkyJ6wn48Q4ZfAo6PBvHKC"] + } + }, + { + "value": 0.44070449, + "n": 1, + "scriptPubKey": { + "hex": "76a91414a88f1032c8ef1c6bd9177f62cdb260b5087b5488ac", + "addresses": ["tmBbamgVqVBTAsEzPmEymbczdoaQvE5qwaR"] + } + } + ] + } + } +} diff --git a/bchain/types.go b/bchain/types.go index 538b9645..582e50b3 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -158,6 +158,7 @@ type BlockChainParser interface { GetAddrIDFromAddress(address string) ([]byte, error) // address to output script conversions AddressToOutputScript(address string) ([]byte, error) + OutputScriptToAddresses(script []byte) ([]string, error) // transactions PackedTxidLen() int PackTxid(txid string) ([]byte, error) diff --git a/build/bin/Makefile b/build/bin/Makefile index 0c2e5ec0..5a55cd7e 100644 --- a/build/bin/Makefile +++ b/build/bin/Makefile @@ -4,16 +4,17 @@ VERSION ?= devel GITCOMMIT = $(shell cd /src && git describe --tags --always --dirty) BUILDTIME = $(shell date --iso-8601=seconds) LDFLAGS := -X blockbook/common.version=$(VERSION) -X blockbook/common.gitcommit=$(GITCOMMIT) -X blockbook/common.buildtime=$(BUILDTIME) +ARGS ?= all: build tools build: prepare-sources - cd $(GOPATH)/src/blockbook && go build -o $(CURDIR)/blockbook -ldflags="-s -w $(LDFLAGS)" + cd $(GOPATH)/src/blockbook && go build -o $(CURDIR)/blockbook -ldflags="-s -w $(LDFLAGS)" $(ARGS) cp $(CURDIR)/blockbook /out/blockbook chown $(PACKAGER) /out/blockbook build-debug: prepare-sources - cd $(GOPATH)/src/blockbook && go build -o $(CURDIR)/blockbook -ldflags="$(LDFLAGS)" + cd $(GOPATH)/src/blockbook && go build -o $(CURDIR)/blockbook -ldflags="$(LDFLAGS)" $(ARGS) cp $(CURDIR)/blockbook /out/blockbook chown $(PACKAGER) /out/blockbook @@ -22,10 +23,10 @@ tools: chown $(PACKAGER) /out/{ldb,sst_dump} test: prepare-sources - cd $(GOPATH)/src/blockbook && go test -short ./... + cd $(GOPATH)/src/blockbook && go test -tags unittest ./... $(ARGS) test-all: prepare-sources - cd $(GOPATH)/src/blockbook && go test ./... + cd $(GOPATH)/src/blockbook && go test -tags 'unittest integration' ./... $(ARGS) prepare-sources: @ [ -n "`ls /src 2> /dev/null`" ] || (echo "/src doesn't exist or is empty" 1>&2 && exit 1) diff --git a/build/deb/Dockerfile b/build/deb/Dockerfile index df454131..c924f02f 100644 --- a/build/deb/Dockerfile +++ b/build/deb/Dockerfile @@ -11,5 +11,3 @@ ADD build-deb.sh /build/build-deb.sh ADD logrotate.sh /build/logrotate.sh WORKDIR /build - -CMD /build/build-deb.sh diff --git a/build/deb/build-deb.sh b/build/deb/build-deb.sh index 368060b6..f39e48d1 100755 --- a/build/deb/build-deb.sh +++ b/build/deb/build-deb.sh @@ -8,6 +8,6 @@ mkdir cert && cp /src/server/testcert.* cert export VERSION=$(dpkg-parsechangelog | sed -rne 's/^Version: ([0-9.]+)([-+~].+)?$/\1/p') -dpkg-buildpackage -us -uc +dpkg-buildpackage -us -uc $@ mv ../*.deb /out chown $PACKAGER /out/*.deb diff --git a/contrib/scripts/start-backend-tunnels.sh b/contrib/scripts/start-backend-tunnels.sh new file mode 100755 index 00000000..913a8e81 --- /dev/null +++ b/contrib/scripts/start-backend-tunnels.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +if [ $# -ne 1 ]; then + echo "Usage: $(basename $0) host" 1>&2 + exit 1 +fi + +host=$1 + +# change dir to root of git repository +cd $(cd $(dirname $(readlink -f $0)) && git rev-parse --show-toplevel) + +# get all testnet ports from configs/ +testnet_ports=$(gawk 'match($0, /"rpcURL":\s+"(http|ws):\/\/[^:]+:([0-9]+)"/, a) {print a[2]}' configs/*_testnet*.json) + +for port in $testnet_ports +do + ssh -nNT -L $port:localhost:$port blockbook-dev.corp & + pid=$! + echo "Started tunnel to ${host}:${port} (pid: ${pid})" +done + +at_exit() { + pkill -P $$ +} + +trap at_exit EXIT +sleep inf diff --git a/db/rocksdb_test.go b/db/rocksdb_test.go index 100a7b08..52be1c5d 100644 --- a/db/rocksdb_test.go +++ b/db/rocksdb_test.go @@ -1,3 +1,5 @@ +// +build unittest + package db import ( diff --git a/server/socketio_test.go b/server/socketio_test.go index c7a6ce53..108815cd 100644 --- a/server/socketio_test.go +++ b/server/socketio_test.go @@ -1,3 +1,5 @@ +// +build unittest + package server import (