Groestlcoin (GRS) support (#33)
This commit is contained in:
parent
ee3d145ca5
commit
11520bd18f
10
Gopkg.lock
generated
10
Gopkg.lock
generated
@ -1,6 +1,12 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/Groestlcoin/go-groestl-hash"
|
||||
packages = ["groestl","hash"]
|
||||
revision = "790653ac190c4029ee200e82a8f21b5d1afaf7d6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/beorn7/perks"
|
||||
@ -89,13 +95,13 @@
|
||||
branch = "master"
|
||||
name = "github.com/jakm/bchutil"
|
||||
packages = ["."]
|
||||
revision = "9e4fc13b082c87967b0befbcbad6fe5a5aa5ac1a"
|
||||
revision = "5a273ca8a96628732c07ff5cfb9f3e7d965241e8"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/jakm/btcutil"
|
||||
packages = [".","base58","bech32","chaincfg","txscript"]
|
||||
revision = "83dfbb3d0b20916f89b36b95c6ca580e3a785856"
|
||||
revision = "224b76333062172edefdeb502123fdda12205f76"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"blockbook/bchain/coins/dash"
|
||||
"blockbook/bchain/coins/dogecoin"
|
||||
"blockbook/bchain/coins/eth"
|
||||
"blockbook/bchain/coins/grs"
|
||||
"blockbook/bchain/coins/litecoin"
|
||||
"blockbook/bchain/coins/monacoin"
|
||||
"blockbook/bchain/coins/myriad"
|
||||
@ -52,6 +53,8 @@ func init() {
|
||||
BlockChainFactories["Monacoin"] = monacoin.NewMonacoinRPC
|
||||
BlockChainFactories["Monacoin Testnet"] = monacoin.NewMonacoinRPC
|
||||
BlockChainFactories["Myriad"] = myriad.NewMyriadRPC
|
||||
BlockChainFactories["Groestlcoin"] = grs.NewGroestlcoinRPC
|
||||
BlockChainFactories["Groestlcoin Testnet"] = grs.NewGroestlcoinRPC
|
||||
}
|
||||
|
||||
// GetCoinNameFromConfig gets coin name and coin shortcut from config file
|
||||
|
||||
88
bchain/coins/grs/grsparser.go
Normal file
88
bchain/coins/grs/grsparser.go
Normal file
@ -0,0 +1,88 @@
|
||||
package grs
|
||||
|
||||
import (
|
||||
"blockbook/bchain"
|
||||
"blockbook/bchain/coins/btc"
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/jakm/btcutil/base58"
|
||||
"github.com/jakm/btcutil/chaincfg"
|
||||
)
|
||||
|
||||
const (
|
||||
MainnetMagic wire.BitcoinNet = 0xd4b4bef9
|
||||
TestnetMagic wire.BitcoinNet = 0x0709110b
|
||||
)
|
||||
|
||||
var (
|
||||
MainNetParams chaincfg.Params
|
||||
TestNetParams chaincfg.Params
|
||||
)
|
||||
|
||||
func init() {
|
||||
MainNetParams = chaincfg.MainNetParams
|
||||
MainNetParams.Net = MainnetMagic
|
||||
|
||||
// Address encoding magics
|
||||
MainNetParams.PubKeyHashAddrID = []byte{36}
|
||||
MainNetParams.ScriptHashAddrID = []byte{5}
|
||||
MainNetParams.Bech32HRPSegwit = "grs"
|
||||
MainNetParams.Base58CksumHasher = base58.Groestl512D
|
||||
|
||||
TestNetParams = chaincfg.TestNet3Params
|
||||
TestNetParams.Net = TestnetMagic
|
||||
|
||||
// Address encoding magics
|
||||
TestNetParams.PubKeyHashAddrID = []byte{111}
|
||||
TestNetParams.ScriptHashAddrID = []byte{196}
|
||||
TestNetParams.Bech32HRPSegwit = "tgrs"
|
||||
TestNetParams.Base58CksumHasher = base58.Groestl512D
|
||||
}
|
||||
|
||||
// GroestlcoinParser handle
|
||||
type GroestlcoinParser struct {
|
||||
*btc.BitcoinParser
|
||||
baseparser *bchain.BaseParser
|
||||
}
|
||||
|
||||
// NewGroestlcoinParser returns new GroestlcoinParser instance
|
||||
func NewGroestlcoinParser(params *chaincfg.Params, c *btc.Configuration) *GroestlcoinParser {
|
||||
return &GroestlcoinParser{
|
||||
BitcoinParser: btc.NewBitcoinParser(params, c),
|
||||
baseparser: &bchain.BaseParser{},
|
||||
}
|
||||
}
|
||||
|
||||
// GetChainParams contains network parameters for the main Groestlcoin network,
|
||||
// the regression test Groestlcoin network, the test Groestlcoin network and
|
||||
// the simulation test Groestlcoin network, in this order
|
||||
func GetChainParams(chain string) *chaincfg.Params {
|
||||
if !chaincfg.IsRegistered(&MainNetParams) {
|
||||
err := chaincfg.Register(&MainNetParams)
|
||||
if err == nil {
|
||||
err = chaincfg.Register(&TestNetParams)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
var params *chaincfg.Params
|
||||
switch chain {
|
||||
case "test":
|
||||
return &TestNetParams
|
||||
default:
|
||||
return &MainNetParams
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
// PackTx packs transaction to byte array using protobuf
|
||||
func (p *GroestlcoinParser) 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 *GroestlcoinParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
||||
return p.baseparser.UnpackTx(buf)
|
||||
}
|
||||
248
bchain/coins/grs/grsparser_test.go
Normal file
248
bchain/coins/grs/grsparser_test.go
Normal file
@ -0,0 +1,248 @@
|
||||
// +build unittest
|
||||
|
||||
package grs
|
||||
|
||||
import (
|
||||
"blockbook/bchain"
|
||||
"blockbook/bchain/coins/btc"
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/jakm/btcutil/chaincfg"
|
||||
)
|
||||
|
||||
var (
|
||||
testTx1, testTx2 bchain.Tx
|
||||
|
||||
testTxPacked1 = "0a20f56521b17b828897f72b30dd21b0192fd942342e89acbb06abf1d446282c30f512bf0101000000014a9d1fdba915e0907ab02f04f88898863112a2b4fdcf872c7414588c47c874cb000000006a47304402201fb96d20d0778f54520ab59afe70d5fb20e500ecc9f02281cf57934e8029e8e10220383d5a3e80f2e1eb92765b6da0f23d454aecbd8236f083d483e9a7430236876101210331693756f749180aeed0a65a0fab0625a2250bd9abca502282a4cf0723152e67ffffffff01a0330300000000001976a914fe40329c95c5598ac60752a5310b320cb52d18e688ac0000000018ffff87da05200028a6f383013298010a001220cb74c8478c5814742c87cffdb4a21231869888f8042fb07a90e015a9db1f9d4a1800226a47304402201fb96d20d0778f54520ab59afe70d5fb20e500ecc9f02281cf57934e8029e8e10220383d5a3e80f2e1eb92765b6da0f23d454aecbd8236f083d483e9a7430236876101210331693756f749180aeed0a65a0fab0625a2250bd9abca502282a4cf0723152e6728ffffffff0f3a460a030333a010001a1976a914fe40329c95c5598ac60752a5310b320cb52d18e688ac222246744d347a416e39615659674867786d616d5742675750795a7362365268766b4139"
|
||||
testTxPacked2 = "0a209b5c4859a8a31e69788cb4402812bb28f14ad71cbd8c60b09903478bc56f79a312e00101000000000101d1613f483f2086d076c82fe34674385a86beb08f052d5405fe1aed397f852f4f0000000000feffffff02404b4c000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c987a8386f0000000000160014cc8067093f6f843d6d3e22004a4290cd0c0f336b02483045022100ea8780bc1e60e14e945a80654a41748bbf1aa7d6f2e40a88d91dfc2de1f34bd10220181a474a3420444bd188501d8d270736e1e9fe379da9970de992ff445b0972e3012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f862d9ed090018caa384da0520d9db2728dadb27322c0a0012204f2f857f39ed1afe05542d058fb0be865a387446e32fc876d086203f483f61d1180028feffffff0f3a450a034c4b4010001a17a9147a55d61848e77ca266e79a39bfc85c580a6426c9872223324e345135466855323439374272794666556762716b414a453837614b4476335633653a4d0a036f38a810011a160014cc8067093f6f843d6d3e22004a4290cd0c0f336b222c746772733171656a7178777a666c64377a72366d663779677179357335736535787137766d74396c6b643537"
|
||||
)
|
||||
|
||||
func init() {
|
||||
testTx1 = bchain.Tx{
|
||||
Hex: "01000000014a9d1fdba915e0907ab02f04f88898863112a2b4fdcf872c7414588c47c874cb000000006a47304402201fb96d20d0778f54520ab59afe70d5fb20e500ecc9f02281cf57934e8029e8e10220383d5a3e80f2e1eb92765b6da0f23d454aecbd8236f083d483e9a7430236876101210331693756f749180aeed0a65a0fab0625a2250bd9abca502282a4cf0723152e67ffffffff01a0330300000000001976a914fe40329c95c5598ac60752a5310b320cb52d18e688ac00000000",
|
||||
Blocktime: 1531052031,
|
||||
Time: 1531052031,
|
||||
Txid: "f56521b17b828897f72b30dd21b0192fd942342e89acbb06abf1d446282c30f5",
|
||||
LockTime: 0,
|
||||
Vin: []bchain.Vin{
|
||||
{
|
||||
ScriptSig: bchain.ScriptSig{
|
||||
Hex: "47304402201fb96d20d0778f54520ab59afe70d5fb20e500ecc9f02281cf57934e8029e8e10220383d5a3e80f2e1eb92765b6da0f23d454aecbd8236f083d483e9a7430236876101210331693756f749180aeed0a65a0fab0625a2250bd9abca502282a4cf0723152e67",
|
||||
},
|
||||
Txid: "cb74c8478c5814742c87cffdb4a21231869888f8042fb07a90e015a9db1f9d4a",
|
||||
Vout: 0,
|
||||
Sequence: 4294967295,
|
||||
},
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
ValueSat: *big.NewInt(209824),
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "76a914fe40329c95c5598ac60752a5310b320cb52d18e688ac",
|
||||
Addresses: []string{
|
||||
"FtM4zAn9aVYgHgxmamWBgWPyZsb6RhvkA9",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
testTx2 = bchain.Tx{
|
||||
Hex: "01000000000101d1613f483f2086d076c82fe34674385a86beb08f052d5405fe1aed397f852f4f0000000000feffffff02404b4c000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c987a8386f0000000000160014cc8067093f6f843d6d3e22004a4290cd0c0f336b02483045022100ea8780bc1e60e14e945a80654a41748bbf1aa7d6f2e40a88d91dfc2de1f34bd10220181a474a3420444bd188501d8d270736e1e9fe379da9970de992ff445b0972e3012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f862d9ed0900",
|
||||
Blocktime: 1530991050,
|
||||
Time: 1530991050,
|
||||
Txid: "9b5c4859a8a31e69788cb4402812bb28f14ad71cbd8c60b09903478bc56f79a3",
|
||||
LockTime: 650713,
|
||||
Vin: []bchain.Vin{
|
||||
{
|
||||
ScriptSig: bchain.ScriptSig{
|
||||
Hex: "",
|
||||
},
|
||||
Txid: "4f2f857f39ed1afe05542d058fb0be865a387446e32fc876d086203f483f61d1",
|
||||
Vout: 0,
|
||||
Sequence: 4294967294,
|
||||
},
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
ValueSat: *big.NewInt(5000000),
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "a9147a55d61848e77ca266e79a39bfc85c580a6426c987",
|
||||
Addresses: []string{
|
||||
"2N4Q5FhU2497BryFfUgbqkAJE87aKDv3V3e",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ValueSat: *big.NewInt(7289000),
|
||||
N: 1,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "0014cc8067093f6f843d6d3e22004a4290cd0c0f336b",
|
||||
Addresses: []string{
|
||||
"tgrs1qejqxwzfld7zr6mf7ygqy5s5se5xq7vmt9lkd57",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
c := m.Run()
|
||||
chaincfg.ResetParams()
|
||||
os.Exit(c)
|
||||
}
|
||||
|
||||
func TestGetAddrDesc(t *testing.T) {
|
||||
type args struct {
|
||||
tx bchain.Tx
|
||||
parser *GroestlcoinParser
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
{
|
||||
name: "grs-1",
|
||||
args: args{
|
||||
tx: testTx1,
|
||||
parser: NewGroestlcoinParser(GetChainParams("main"), &btc.Configuration{}),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "grs-2",
|
||||
args: args{
|
||||
tx: testTx2,
|
||||
parser: NewGroestlcoinParser(GetChainParams("test"), &btc.Configuration{}),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
for n, vout := range tt.args.tx.Vout {
|
||||
got1, err := tt.args.parser.GetAddrDescFromVout(&vout)
|
||||
if err != nil {
|
||||
t.Errorf("getAddrDescFromVout() error = %v, vout = %d", err, n)
|
||||
return
|
||||
}
|
||||
got2, err := tt.args.parser.GetAddrDescFromAddress(vout.ScriptPubKey.Addresses[0])
|
||||
if err != nil {
|
||||
t.Errorf("getAddrDescFromAddress() error = %v, vout = %d", err, n)
|
||||
return
|
||||
}
|
||||
if !bytes.Equal(got1, got2) {
|
||||
t.Errorf("Address descriptors mismatch: got1 = %v, got2 = %v", got1, got2)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPackTx(t *testing.T) {
|
||||
type args struct {
|
||||
tx bchain.Tx
|
||||
height uint32
|
||||
blockTime int64
|
||||
parser *GroestlcoinParser
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "grs-1",
|
||||
args: args{
|
||||
tx: testTx1,
|
||||
height: 2161062,
|
||||
blockTime: 1531052031,
|
||||
parser: NewGroestlcoinParser(GetChainParams("main"), &btc.Configuration{}),
|
||||
},
|
||||
want: testTxPacked1,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "grs-2",
|
||||
args: args{
|
||||
tx: testTx2,
|
||||
height: 650714,
|
||||
blockTime: 1530991050,
|
||||
parser: NewGroestlcoinParser(GetChainParams("test"), &btc.Configuration{}),
|
||||
},
|
||||
want: testTxPacked2,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := tt.args.parser.PackTx(&tt.args.tx, tt.args.height, tt.args.blockTime)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("packTx() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
h := hex.EncodeToString(got)
|
||||
if !reflect.DeepEqual(h, tt.want) {
|
||||
t.Errorf("packTx() = %v, want %v", h, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnpackTx(t *testing.T) {
|
||||
type args struct {
|
||||
packedTx string
|
||||
parser *GroestlcoinParser
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *bchain.Tx
|
||||
want1 uint32
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "grs-1",
|
||||
args: args{
|
||||
packedTx: testTxPacked1,
|
||||
parser: NewGroestlcoinParser(GetChainParams("main"), &btc.Configuration{}),
|
||||
},
|
||||
want: &testTx1,
|
||||
want1: 2161062,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "grs-2",
|
||||
args: args{
|
||||
packedTx: testTxPacked2,
|
||||
parser: NewGroestlcoinParser(GetChainParams("test"), &btc.Configuration{}),
|
||||
},
|
||||
want: &testTx2,
|
||||
want1: 650714,
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
115
bchain/coins/grs/grsrpc.go
Normal file
115
bchain/coins/grs/grsrpc.go
Normal file
@ -0,0 +1,115 @@
|
||||
package grs
|
||||
|
||||
import (
|
||||
"blockbook/bchain"
|
||||
"blockbook/bchain/coins/btc"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
type GroestlcoinRPC struct {
|
||||
*btc.BitcoinRPC
|
||||
}
|
||||
|
||||
func NewGroestlcoinRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) {
|
||||
b, err := btc.NewBitcoinRPC(config, pushHandler)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
g := &GroestlcoinRPC{
|
||||
BitcoinRPC: b.(*btc.BitcoinRPC),
|
||||
}
|
||||
g.RPCMarshaler = btc.JSONMarshalerV1{}
|
||||
return g, nil
|
||||
}
|
||||
|
||||
// Initialize initializes GroestlcoinRPC instance.
|
||||
func (g *GroestlcoinRPC) Initialize() error {
|
||||
chainName, err := g.GetChainInfoAndInitializeMempool(g)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
params := GetChainParams(chainName)
|
||||
|
||||
g.Parser = NewGroestlcoinParser(params, g.ChainConfig)
|
||||
|
||||
// parameters for getInfo request
|
||||
if params.Net == MainnetMagic {
|
||||
g.Testnet = false
|
||||
g.Network = "livenet"
|
||||
} else {
|
||||
g.Testnet = true
|
||||
g.Network = "testnet"
|
||||
}
|
||||
|
||||
glog.Info("rpc: block chain ", params.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetBlock returns block with given hash.
|
||||
func (g *GroestlcoinRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
|
||||
var err error
|
||||
if hash == "" && height > 0 {
|
||||
hash, err = g.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 = g.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 := g.GetTransaction(txid)
|
||||
if err != nil {
|
||||
if isInvalidTx(err) {
|
||||
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
|
||||
}
|
||||
|
||||
func isInvalidTx(err error) bool {
|
||||
switch e1 := err.(type) {
|
||||
case *errors.Err:
|
||||
switch e2 := e1.Cause().(type) {
|
||||
case *bchain.RPCError:
|
||||
if e2.Code == -5 { // "No information available about transaction"
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// GetTransactionForMempool returns a transaction by the transaction ID.
|
||||
// It could be optimized for mempool, i.e. without block time and confirmations
|
||||
func (g *GroestlcoinRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
|
||||
return g.GetTransaction(txid)
|
||||
}
|
||||
66
configs/coins/groestlcoin.json
Normal file
66
configs/coins/groestlcoin.json
Normal file
@ -0,0 +1,66 @@
|
||||
{
|
||||
"coin": {
|
||||
"name": "Groestlcoin",
|
||||
"shortcut": "GRS",
|
||||
"label": "Groestlcoin",
|
||||
"alias": "groestlcoin"
|
||||
},
|
||||
"ports": {
|
||||
"backend_rpc": 8045,
|
||||
"backend_message_queue": 38345,
|
||||
"blockbook_internal": 9045,
|
||||
"blockbook_public": 9145
|
||||
},
|
||||
"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-groestlcoin",
|
||||
"package_revision": "satoshilabs-1",
|
||||
"system_user": "groestlcoin",
|
||||
"version": "2.16.3",
|
||||
"binary_url": "https://github.com/Groestlcoin/groestlcoin/releases/download/v2.16.3/groestlcoin-2.16.3-x86_64-linux-gnu.tar.gz",
|
||||
"verification_type": "sha256",
|
||||
"verification_source": "f15bd5e38b25a103821f1563cd0e1b2cf7146ec9f9835493a30bd57313d3b86f",
|
||||
"extract_command": "mkdir -p backend/bin; tar -C backend/bin -xf",
|
||||
"exclude_files": [
|
||||
"bin/groestlcoin-qt"
|
||||
],
|
||||
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/groestlcoind -datadir={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend -conf={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/{{.Coin.Alias}}.conf -pid=/run/{{.Coin.Alias}}/{{.Coin.Alias}}.pid",
|
||||
"logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/*.log",
|
||||
"postinst_script_template": "",
|
||||
"service_type": "forking",
|
||||
"service_additional_params_template": "",
|
||||
"protect_memory": true,
|
||||
"mainnet": true,
|
||||
"server_config_file": "bitcoin_like.conf",
|
||||
"client_config_file": "bitcoin_like_client.conf",
|
||||
"additional_params": {
|
||||
"deprecatedrpc": "estimatefee",
|
||||
"whitelist": "127.0.0.1"
|
||||
}
|
||||
},
|
||||
"blockbook": {
|
||||
"package_name": "blockbook-groestlcoin",
|
||||
"system_user": "blockbook-groestlcoin",
|
||||
"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": "Groestlcoin team",
|
||||
"package_maintainer_email": "support@groestlcoin.org"
|
||||
}
|
||||
}
|
||||
66
configs/coins/groestlcoin_testnet.json
Normal file
66
configs/coins/groestlcoin_testnet.json
Normal file
@ -0,0 +1,66 @@
|
||||
{
|
||||
"coin": {
|
||||
"name": "Groestlcoin Testnet",
|
||||
"shortcut": "tGRS",
|
||||
"label": "Groestlcoin Testnet",
|
||||
"alias": "groestlcoin_testnet"
|
||||
},
|
||||
"ports": {
|
||||
"backend_rpc": 18045,
|
||||
"backend_message_queue": 48345,
|
||||
"blockbook_internal": 19045,
|
||||
"blockbook_public": 19145
|
||||
},
|
||||
"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-groestlcoin-testnet",
|
||||
"package_revision": "satoshilabs-1",
|
||||
"system_user": "groestlcoin",
|
||||
"version": "2.16.3",
|
||||
"binary_url": "https://github.com/Groestlcoin/groestlcoin/releases/download/v2.16.3/groestlcoin-2.16.3-x86_64-linux-gnu.tar.gz",
|
||||
"verification_type": "sha256",
|
||||
"verification_source": "f15bd5e38b25a103821f1563cd0e1b2cf7146ec9f9835493a30bd57313d3b86f",
|
||||
"extract_command": "mkdir -p backend/bin; tar -C backend/bin -xf",
|
||||
"exclude_files": [
|
||||
"bin/groestlcoin-qt"
|
||||
],
|
||||
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/groestlcoind -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/testnet3/*.log",
|
||||
"postinst_script_template": "",
|
||||
"service_type": "forking",
|
||||
"service_additional_params_template": "",
|
||||
"protect_memory": true,
|
||||
"mainnet": false,
|
||||
"server_config_file": "bitcoin_like.conf",
|
||||
"client_config_file": "bitcoin_like_client.conf",
|
||||
"additional_params": {
|
||||
"deprecatedrpc": "estimatefee",
|
||||
"whitelist": "127.0.0.1"
|
||||
}
|
||||
},
|
||||
"blockbook": {
|
||||
"package_name": "blockbook-groestlcoin-testnet",
|
||||
"system_user": "blockbook-groestlcoin",
|
||||
"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": "Groestlcoin team",
|
||||
"package_maintainer_email": "support@groestlcoin.org"
|
||||
}
|
||||
}
|
||||
57
tests/rpc/testdata/groestlcoin.json
vendored
Normal file
57
tests/rpc/testdata/groestlcoin.json
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"blockHeight": 2294439,
|
||||
"blockHash": "0000000000003e6b31abe139b028a97f4fe4dea10fd52a04c404cc85b4d7f773",
|
||||
"blockTime": 1539462668,
|
||||
"blockTxs": [
|
||||
"986e0848c7e0b438ad3816875ed6dc867393897a0e893e6006efefec0197f90d",
|
||||
"dce355dd367e757ead8bbf4480d96885108d9f248d1e74e493ff4693f97cc11c",
|
||||
"4b5f5892a385f75bcd8c5584cea2765f25976b38c450e98bc6d22e342f805ae1",
|
||||
"dfa2ae8837705ee9c5b05ffc652d54dc1b5d38dd836d8b30c5b16c655db8a75b",
|
||||
"0b41b9325d3366a3bba0bf2cf76218ea23ec74aca19c0ce37dc55b5cbcaa8b84",
|
||||
"91a2a72dacf0774c7d4f37e0c9b011a3f747518c20ea6f44ee47d8d35aed4f1a",
|
||||
"f13366400b6ee643f48aa40592382dbf3085c3e31f42e0283b0efd970533c55d",
|
||||
"062f4f5eab8ef188922c197b8becf94ab292f6f1efff57173617b27380a55616"
|
||||
],
|
||||
"txDetails": {
|
||||
"4b5f5892a385f75bcd8c5584cea2765f25976b38c450e98bc6d22e342f805ae1": {
|
||||
"hex": "020000000001011cc17cf99346ff93e4741e8d249f8d108568d98044bf8bad7e757e36dd55e3dc01000000171600142e9f7a9a16b2fcb817752f1f44c7518c83886cdefeffffff02fa76e3e50200000017a914b996e79692d2212707e59235f0a00f2f951c1ba487004d4466170000001976a914fcad3abf614562d224c6cc8b0e00d2fa9016404388ac0247304402206794af78bbfc6f39fa86788bdaff9959af9b519af133e696e2b1226a3df2c0830220254855ae4270af92a6add130efe41222cf150033f5a55225308cd0a39b7b73ee01210352b1a67fef7a34042ff4ed75cd375f22d2f5ea24353d3e6be363f967d9deb612a6022300",
|
||||
"txid": "4b5f5892a385f75bcd8c5584cea2765f25976b38c450e98bc6d22e342f805ae1",
|
||||
"blocktime": 1539462668,
|
||||
"time": 1539462668,
|
||||
"locktime": 2294438,
|
||||
"version": 2,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "dce355dd367e757ead8bbf4480d96885108d9f248d1e74e493ff4693f97cc11c",
|
||||
"vout": 1,
|
||||
"scriptSig": {
|
||||
"hex": "1600142e9f7a9a16b2fcb817752f1f44c7518c83886cde"
|
||||
},
|
||||
"sequence": 4294967294
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 124.46824186,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"hex": "a914b996e79692d2212707e59235f0a00f2f951c1ba487",
|
||||
"addresses": [
|
||||
"3JcKi541GubsiCdpdZqvsSy3rfA6R11tg7"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"value": 1005.00000000,
|
||||
"n": 1,
|
||||
"scriptPubKey": {
|
||||
"hex": "76a914fcad3abf614562d224c6cc8b0e00d2fa9016404388ac",
|
||||
"addresses": [
|
||||
"FtCkFSrwrgiJzjQzGRZvjHzrmHp4HJeGYm"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
68
tests/sync/testdata/groestlcoin.json
vendored
Normal file
68
tests/sync/testdata/groestlcoin.json
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"connectBlocks": {
|
||||
"syncRanges": [
|
||||
{"lower": 2200724, "upper": 2200744}
|
||||
],
|
||||
"blocks": {
|
||||
"2200744": {
|
||||
"height": 2200744,
|
||||
"hash": "000000000000239eef9c547395bdedb12c05377479a00a6e85cc2eac2ba33e18",
|
||||
"noTxs": 1,
|
||||
"txDetails": [
|
||||
{
|
||||
"hex": "010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff2003a8942104fb2e685b0837ff5e928d0000000d2f6e6f64655374726174756d2f00000000020000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90065cd1d000000001976a9147a2dd8d03f7ae3c1acc88d51213aaf7de20e62d088ac0120000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"txid": "d12a3d710831f88c02caaf66a6662b211ec05adfa94392ddc2c57edbb006b299",
|
||||
"version": 1,
|
||||
"vin": [
|
||||
{
|
||||
"coinbase": "03a8942104fb2e685b0837ff5e928d0000000d2f6e6f64655374726174756d2f",
|
||||
"sequence": 0
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"hex": "6a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"value": 5.00000000,
|
||||
"n": 1,
|
||||
"scriptPubKey": {
|
||||
"hex": "76a9147a2dd8d03f7ae3c1acc88d51213aaf7de20e62d088ac"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"handleFork": {
|
||||
"syncRanges": [
|
||||
{"lower": 2200724, "upper": 2200744}
|
||||
],
|
||||
"fakeBlocks": {
|
||||
"2200744": {
|
||||
"height": 2200744,
|
||||
"hash": "00000000000091c2f138f8e97dfda7256f8aee2d4ee4ad52cefbad837ca50a99"
|
||||
},
|
||||
"2200743": {
|
||||
"height": 2200743,
|
||||
"hash": "000000000001596f4fd5ba68aa7a7e09d1a28096ea520940080fb1c128ca13a4"
|
||||
}
|
||||
},
|
||||
"realBlocks": {
|
||||
"2200744": {
|
||||
"height": 2200744,
|
||||
"hash": "000000000000239eef9c547395bdedb12c05377479a00a6e85cc2eac2ba33e18"
|
||||
},
|
||||
"2200743": {
|
||||
"height": 2200743,
|
||||
"hash": "000000000000b75b5efad34254aef25060f695a532589f993cf07f77986629df"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -40,6 +40,11 @@
|
||||
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight",
|
||||
"GetBlockHeader"]
|
||||
},
|
||||
"groestlcoin": {
|
||||
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync",
|
||||
"EstimateSmartFee", "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"],
|
||||
"sync": ["ConnectBlocksParallel", "ConnectBlocks", "HandleFork"]
|
||||
},
|
||||
"litecoin": {
|
||||
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync",
|
||||
"EstimateSmartFee", "EstimateFee"],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user