Merge branch 'master' into tests

pull/78/head
Jakub Matys 2018-10-03 13:18:50 +02:00
commit cb06687ccf
17 changed files with 488 additions and 6 deletions

2
Gopkg.lock generated
View File

@ -113,7 +113,7 @@
branch = "master"
name = "github.com/jakm/btcutil"
packages = [".","base58","bech32","chaincfg","txscript"]
revision = "c50a69d8979c23daad1728b3574c6f20691174f7"
revision = "4656891ba33d07bb3c37ed1eb5120774c42a6bf6"
[[projects]]
branch = "master"

View File

@ -30,6 +30,8 @@ deb-blockbook-%: .deb-image
deb-%: .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 all $* $(ARGS)
deb-blockbook-all: clean-deb $(addprefix deb-blockbook-, $(TARGETS))
$(addprefix all-, $(TARGETS)): all-%: clean-deb build-images deb-%
all: clean-deb build-images $(addprefix deb-, $(TARGETS))

View File

@ -10,6 +10,7 @@ import (
"blockbook/bchain/coins/eth"
"blockbook/bchain/coins/litecoin"
"blockbook/bchain/coins/monacoin"
"blockbook/bchain/coins/myriad"
"blockbook/bchain/coins/namecoin"
"blockbook/bchain/coins/vertcoin"
"blockbook/bchain/coins/zec"
@ -50,6 +51,7 @@ func init() {
BlockChainFactories["Namecoin"] = namecoin.NewNamecoinRPC
BlockChainFactories["Monacoin"] = monacoin.NewMonacoinRPC
BlockChainFactories["Monacoin Testnet"] = monacoin.NewMonacoinRPC
BlockChainFactories["Myriad"] = myriad.NewMyriadRPC
}
// GetCoinNameFromConfig gets coin name and coin shortcut from config file

View File

@ -137,7 +137,7 @@ func (p *BitcoinParser) outputScriptToAddresses(script []byte) ([]string, bool,
rv[i] = a.EncodeAddress()
}
var s bool
if sc != txscript.NonStandardTy && sc != txscript.NullDataTy {
if sc == txscript.PubKeyHashTy || sc == txscript.WitnessV0PubKeyHashTy || sc == txscript.ScriptHashTy || sc == txscript.WitnessV0ScriptHashTy {
s = true
} else if len(rv) == 0 {
or := TryParseOPReturn(script)

View File

@ -122,6 +122,7 @@ func (b *BitcoinRPC) GetChainInfoAndInitializeMempool(bc bchain.BlockChain) (str
// Initialize initializes BitcoinRPC instance.
func (b *BitcoinRPC) Initialize() error {
b.ChainConfig.SupportsEstimateFee = false
chainName, err := b.GetChainInfoAndInitializeMempool(b)
if err != nil {

View File

@ -131,7 +131,7 @@ func (p *MonacoinParser) outputScriptToAddresses(script []byte) ([]string, bool,
rv[i] = a.EncodeAddress()
}
var s bool
if sc != txscript.NonStandardTy && sc != txscript.NullDataTy {
if sc == txscript.PubKeyHashTy || sc == txscript.WitnessV0PubKeyHashTy || sc == txscript.ScriptHashTy || sc == txscript.WitnessV0ScriptHashTy {
s = true
} else if len(rv) == 0 {
or := btc.TryParseOPReturn(script)
@ -150,7 +150,7 @@ func (p *MonacoinParser) outputScriptToAddresses(script []byte) ([]string, bool,
rv[i] = a.EncodeAddress()
}
var s bool
if sc != txscript.NonStandardTy && sc != txscript.NullDataTy {
if sc == txscript.PubKeyHashTy || sc == txscript.WitnessV0PubKeyHashTy || sc == txscript.ScriptHashTy || sc == txscript.WitnessV0ScriptHashTy {
s = true
} else if len(rv) == 0 {
or := btc.TryParseOPReturn(script)

View File

@ -0,0 +1,91 @@
package myriad
import (
"blockbook/bchain"
"blockbook/bchain/coins/btc"
"blockbook/bchain/coins/utils"
"bytes"
"github.com/btcsuite/btcd/wire"
"github.com/jakm/btcutil/chaincfg"
)
const (
MainnetMagic wire.BitcoinNet = 0xee7645af
)
var (
MainNetParams chaincfg.Params
)
func init() {
MainNetParams = chaincfg.MainNetParams
MainNetParams.Net = MainnetMagic
MainNetParams.Bech32HRPSegwit = "my"
MainNetParams.PubKeyHashAddrID = []byte{50} // 0x32 - starts with M
MainNetParams.ScriptHashAddrID = []byte{9} // 0x09 - starts with 4
MainNetParams.PrivateKeyID = []byte{178} // 0xB2
MainNetParams.HDCoinType = 90
}
// MyriadParser handle
type MyriadParser struct {
*btc.BitcoinParser
}
// NewMyriadParser returns new MyriadParser instance
func NewMyriadParser(params *chaincfg.Params, c *btc.Configuration) *MyriadParser {
return &MyriadParser{BitcoinParser: btc.NewBitcoinParser(params, c)}
}
// GetChainParams contains network parameters for the main Myriad network
func GetChainParams(chain string) *chaincfg.Params {
if !chaincfg.IsRegistered(&MainNetParams) {
err := chaincfg.Register(&MainNetParams)
if err != nil {
panic(err)
}
}
switch chain {
default:
return &MainNetParams
}
}
// ParseBlock parses raw block to our Block struct
// it has special handling for Auxpow blocks that cannot be parsed by standard btc wire parser
func (p *MyriadParser) ParseBlock(b []byte) (*bchain.Block, error) {
r := bytes.NewReader(b)
w := wire.MsgBlock{}
h := wire.BlockHeader{}
err := h.Deserialize(r)
if err != nil {
return nil, err
}
if (h.Version & utils.VersionAuxpow) != 0 {
if err = utils.SkipAuxpow(r); err != nil {
return nil, err
}
}
err = utils.DecodeTransactions(r, 0, wire.WitnessEncoding, &w)
if err != nil {
return nil, err
}
txs := make([]bchain.Tx, len(w.Transactions))
for ti, t := range w.Transactions {
txs[ti] = p.TxFromMsgTx(t, false)
}
return &bchain.Block{
BlockHeader: bchain.BlockHeader{
Size: len(b),
Time: h.Timestamp.Unix(),
},
Txs: txs,
}, nil
}

View File

@ -0,0 +1,195 @@
// +build unittest
package myriad
import (
"blockbook/bchain"
"blockbook/bchain/coins/btc"
"encoding/hex"
"math/big"
"os"
"reflect"
"testing"
"github.com/jakm/btcutil/chaincfg"
)
func TestMain(m *testing.M) {
c := m.Run()
chaincfg.ResetParams()
os.Exit(c)
}
func Test_GetAddrDescFromAddress_Mainnet(t *testing.T) {
type args struct {
address string
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "P2PKH1",
args: args{address: "MUs3PnZLdBQyct2emEc7QJvVnjeQj52kug"},
want: "76a914e5f419d3b464c67152fb9d3ecc36932d5280673f88ac",
wantErr: false,
},
{
name: "P2SH1",
args: args{address: "4ijSZESajWvhhJAz1APdzGivwc31WCjxHD"},
want: "a9143e69d8c4772eb34d77c96aae58c041e887b404f387",
wantErr: false,
},
{
name: "witness_v0_keyhash",
args: args{address: "my1qr9y3pd7wy7jjpqf87qsmp08ecppc0p2jxhfcfc"},
want: "0014194910b7ce27a5208127f021b0bcf9c043878552",
wantErr: false,
},
}
parser := NewMyriadParser(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 = "00004e208ab194a1180100000001163465df9bb21d89e90056f11887a398d5a313aef71e3974306459661a91588c000000006b4830450220129c9e9a27406796f3f7d7edcc446037b38ddb3ef94745cec8e7cde618a811140221008eb3b893cdd3725e99b74c020867821e1f74199065260586f5ef3c22b133dd2a012103e2e23d38dc8fa493cde4077f650ab9f22eacafd14a10b123994f38c9f35dfee9ffffffff025e90ec28050000001976a9141cba92fe1510b8c73550fd4d3e0b44acdffcd12d88ac79c268ba0a0000001976a9142f86cdfa98cac89143cf9e3d309cc072caccdf6f88ac00000000"
)
func init() {
testTx1 = bchain.Tx{
Hex: "0100000001163465df9bb21d89e90056f11887a398d5a313aef71e3974306459661a91588c000000006b4830450220129c9e9a27406796f3f7d7edcc446037b38ddb3ef94745cec8e7cde618a811140221008eb3b893cdd3725e99b74c020867821e1f74199065260586f5ef3c22b133dd2a012103e2e23d38dc8fa493cde4077f650ab9f22eacafd14a10b123994f38c9f35dfee9ffffffff025e90ec28050000001976a9141cba92fe1510b8c73550fd4d3e0b44acdffcd12d88ac79c268ba0a0000001976a9142f86cdfa98cac89143cf9e3d309cc072caccdf6f88ac00000000",
Blocktime: 1393723468,
Txid: "b01e2eb866ed101ed117b4ad18b753929e85c42e3d8add76bdd16e5c00519dcc",
LockTime: 0,
Version: 1,
Vin: []bchain.Vin{
{
ScriptSig: bchain.ScriptSig{
Hex: "4830450220129c9e9a27406796f3f7d7edcc446037b38ddb3ef94745cec8e7cde618a811140221008eb3b893cdd3725e99b74c020867821e1f74199065260586f5ef3c22b133dd2a012103e2e23d38dc8fa493cde4077f650ab9f22eacafd14a10b123994f38c9f35dfee9",
},
Txid: "8c58911a6659643074391ef7ae13a3d598a38718f15600e9891db29bdf653416",
Vout: 0,
Sequence: 4294967295,
},
},
Vout: []bchain.Vout{
{
ValueSat: *big.NewInt(22161428574),
N: 0,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a9141cba92fe1510b8c73550fd4d3e0b44acdffcd12d88ac",
Addresses: []string{
"MAX4fCkTJwaRzbA3xzJp9DjrMwnnK32T6Z",
},
},
},
{
ValueSat: *big.NewInt(46077100665),
N: 1,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a9142f86cdfa98cac89143cf9e3d309cc072caccdf6f88ac",
Addresses: []string{
"MCETUqM7MH6NietcsPY3w2sVUKz255m1yY",
},
},
},
},
}
}
func Test_PackTx(t *testing.T) {
type args struct {
tx bchain.Tx
height uint32
blockTime int64
parser *MyriadParser
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "myriad-1",
args: args{
tx: testTx1,
height: 20000,
blockTime: 1393723468,
parser: NewMyriadParser(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 *MyriadParser
}
tests := []struct {
name string
args args
want *bchain.Tx
want1 uint32
wantErr bool
}{
{
name: "myriad-1",
args: args{
packedTx: testTxPacked1,
parser: NewMyriadParser(GetChainParams("main"), &btc.Configuration{}),
},
want: &testTx1,
want1: 20000,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b, _ := hex.DecodeString(tt.args.packedTx)
got, got1, err := tt.args.parser.UnpackTx(b)
if (err != nil) != tt.wantErr {
t.Errorf("unpackTx() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("unpackTx() got = %v, want %v", got, tt.want)
}
if got1 != tt.want1 {
t.Errorf("unpackTx() got1 = %v, want %v", got1, tt.want1)
}
})
}
}

View File

@ -0,0 +1,72 @@
package myriad
import (
"blockbook/bchain"
"blockbook/bchain/coins/btc"
"encoding/json"
"github.com/golang/glog"
)
// MyriadRPC is an interface to JSON-RPC bitcoind service.
type MyriadRPC struct {
*btc.BitcoinRPC
}
// NewMyriadRPC returns new MyriadRPC instance.
func NewMyriadRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) {
b, err := btc.NewBitcoinRPC(config, pushHandler)
if err != nil {
return nil, err
}
s := &MyriadRPC{
b.(*btc.BitcoinRPC),
}
s.RPCMarshaler = btc.JSONMarshalerV2{}
s.ChainConfig.SupportsEstimateFee = false
return s, nil
}
// Initialize initializes MyriadRPC instance.
func (b *MyriadRPC) Initialize() error {
chainName, err := b.GetChainInfoAndInitializeMempool(b)
if err != nil {
return err
}
glog.Info("Chain name ", chainName)
params := GetChainParams(chainName)
// always create parser
b.Parser = NewMyriadParser(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 (b *MyriadRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
var err error
if hash == "" {
hash, err = b.GetBlockHash(height)
if err != nil {
return nil, err
}
}
if !b.ParseBlocks {
return b.GetBlockFull(hash)
}
return b.GetBlockWithoutHeader(hash, height)
}

View File

@ -24,7 +24,7 @@ func NewNamecoinRPC(config json.RawMessage, pushHandler func(bchain.Notification
b.(*btc.BitcoinRPC),
}
s.RPCMarshaler = btc.JSONMarshalerV1{}
s.ChainConfig.SupportsEstimateSmartFee = false
s.ChainConfig.SupportsEstimateFee = false
return s, nil
}

View File

@ -362,6 +362,7 @@ func blockbookAppInfoMetric(db *db.RocksDB, chain bchain.BlockChain, txCache *db
metrics.BlockbookAppInfo.With(common.Labels{
"blockbook_version": si.Blockbook.Version,
"blockbook_commit": si.Blockbook.GitCommit,
"blockbook_buildtime": si.Blockbook.BuildTime,
"backend_version": si.Backend.Version,
"backend_subversion": si.Backend.Subversion,
"backend_protocol_version": si.Backend.ProtocolVersion}).Set(float64(0))

View File

@ -146,7 +146,7 @@ func GetMetrics(coin string) (*Metrics, error) {
Help: "Information about blockbook and backend application versions",
ConstLabels: Labels{"coin": coin},
},
[]string{"blockbook_version", "blockbook_commit", "backend_version", "backend_subversion", "backend_protocol_version"},
[]string{"blockbook_version", "blockbook_commit", "blockbook_buildtime", "backend_version", "backend_subversion", "backend_protocol_version"},
)
v := reflect.ValueOf(metrics)

View File

@ -0,0 +1,64 @@
{
"coin": {
"name": "Myriad",
"shortcut": "XMY",
"label": "Myriad",
"alias": "myriad"
},
"ports": {
"backend_rpc": 8043,
"backend_message_queue": 38343,
"blockbook_internal": 9043,
"blockbook_public": 9143
},
"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-myriad",
"package_revision": "satoshilabs-1",
"system_user": "myriad",
"version": "0.16.3.0",
"binary_url": "https://github.com/myriadteam/myriadcoin/releases/download/v0.16.3.0-beta0/myriadcoin-0.16.3.0-beta0-x86_64-linux-gnu.tar.gz",
"verification_type": "sha256",
"verification_source": "36b076eebb5951d7b2bc3c2d4654c76024fbabb3ea5a82c987d05c462a09324c",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [
"bin/myriadcoin-qt"
],
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/myriadcoind -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,
"config_file": "bitcoin.conf",
"additional_params": {
"whitelist": "127.0.0.1"
}
},
"blockbook": {
"package_name": "blockbook-myriad",
"system_user": "blockbook-myriad",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "",
"additional_params": "",
"block_chain": {
"parse": true,
"mempool_workers": 8,
"mempool_sub_workers": 2,
"block_addresses_to_keep": 300,
"additional_params": {}
}
},
"meta": {
"package_maintainer": "wlc-",
"package_maintainer_email": "wwwwllllcccc@gmail.com"
}
}

View File

@ -14,6 +14,7 @@
| Namecoin | 9039 | 9139 | 8039 | 38339 |
| Vertcoin | 9040 | 9140 | 8040 | 38340 |
| Monacoin | 9041 | 9141 | 8041 | 38341 |
| Myriad | 9043 | 9143 | 8043 | 38343 |
| Testnet | 19030 | 19130 | 18030 | 48330 |
| Bcash Testnet | 19031 | 19131 | 18031 | 48331 |
| Zcash Testnet | 19032 | 19132 | 18032 | 48332 |

View File

@ -15,6 +15,8 @@ import (
"path/filepath"
"reflect"
"testing"
"github.com/jakm/btcutil/chaincfg"
)
type TestFunc func(t *testing.T, coin string, chain bchain.BlockChain, testConfig json.RawMessage)
@ -52,6 +54,7 @@ func runTests(t *testing.T, coin string, cfg map[string]json.RawMessage) {
if cfg == nil || len(cfg) == 0 {
t.Skip("No tests to run")
}
defer chaincfg.ResetParams()
bc, err := makeBlockChain(coin)
if err != nil {

46
tests/rpc/testdata/myriad.json vendored 100644
View File

@ -0,0 +1,46 @@
{
"blockHeight": 20000,
"blockHash": "a5eac2e226d40d758059c3b5041372c82f49e5df72047424187be72bab410885",
"blockTime": 1393723468,
"blockTxs": [
"b5860208ff392f5c750fd4e0d5c8d647f9fc9e1d30a1b5401d3717a9fc604c16",
"b01e2eb866ed101ed117b4ad18b753929e85c42e3d8add76bdd16e5c00519dcc",
"834e1498be0c5b00dfa5db855f18c69aff19ff9f823b05922077c0875057bce0"
],
"txDetails": {
"b01e2eb866ed101ed117b4ad18b753929e85c42e3d8add76bdd16e5c00519dcc": {
"hex": "0100000001163465df9bb21d89e90056f11887a398d5a313aef71e3974306459661a91588c000000006b4830450220129c9e9a27406796f3f7d7edcc446037b38ddb3ef94745cec8e7cde618a811140221008eb3b893cdd3725e99b74c020867821e1f74199065260586f5ef3c22b133dd2a012103e2e23d38dc8fa493cde4077f650ab9f22eacafd14a10b123994f38c9f35dfee9ffffffff025e90ec28050000001976a9141cba92fe1510b8c73550fd4d3e0b44acdffcd12d88ac79c268ba0a0000001976a9142f86cdfa98cac89143cf9e3d309cc072caccdf6f88ac00000000",
"txid": "b01e2eb866ed101ed117b4ad18b753929e85c42e3d8add76bdd16e5c00519dcc",
"blocktime": 1393723468,
"time": 1393723468,
"locktime": 0,
"version": 1,
"vin": [
{
"txid": "8c58911a6659643074391ef7ae13a3d598a38718f15600e9891db29bdf653416",
"vout": 0,
"sequence": 4294967295,
"scriptSig": {
"hex": "4830450220129c9e9a27406796f3f7d7edcc446037b38ddb3ef94745cec8e7cde618a811140221008eb3b893cdd3725e99b74c020867821e1f74199065260586f5ef3c22b133dd2a012103e2e23d38dc8fa493cde4077f650ab9f22eacafd14a10b123994f38c9f35dfee9"
}
}
],
"vout": [
{
"value": 221.61428574,
"n": 0,
"scriptPubKey": {
"hex": "76a9141cba92fe1510b8c73550fd4d3e0b44acdffcd12d88ac"
}
},
{
"value": 460.77100665,
"n": 1,
"scriptPubKey": {
"hex": "76a9142f86cdfa98cac89143cf9e3d309cc072caccdf6f88ac"
}
}
]
}
}
}

View File

@ -40,6 +40,10 @@
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync",
"EstimateSmartFee", "EstimateFee"]
},
"myriad": {
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync",
"EstimateSmartFee", "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"]
},
"namecoin": {
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "MempoolSync", "EstimateSmartFee",
"EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"]