From 2d0c56c442f38a159090ed115858e74090624107 Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Thu, 31 May 2018 14:17:34 +0200 Subject: [PATCH] Added Bitcoin Gold support --- bchain/coins/blockchain.go | 2 + bchain/coins/btg/bgoldparser.go | 49 ++++ bchain/coins/btg/bgoldparser_test.go | 274 ++++++++++++++++++++++ bchain/coins/btg/bgoldrpc.go | 175 ++++++++++++++ build/deb/debian/blockbook-btg.conffiles | 1 + build/deb/debian/blockbook-btg.cron.daily | 2 + build/deb/debian/blockbook-btg.dirs | 2 + build/deb/debian/blockbook-btg.install | 6 + build/deb/debian/blockbook-btg.links | 2 + build/deb/debian/blockbook-btg.postinst | 23 ++ build/deb/debian/blockbook-btg.service | 43 ++++ build/deb/debian/control | 5 + configs/btg.json | 13 + 13 files changed, 597 insertions(+) create mode 100644 bchain/coins/btg/bgoldparser.go create mode 100644 bchain/coins/btg/bgoldparser_test.go create mode 100644 bchain/coins/btg/bgoldrpc.go create mode 100644 build/deb/debian/blockbook-btg.conffiles create mode 100644 build/deb/debian/blockbook-btg.cron.daily create mode 100644 build/deb/debian/blockbook-btg.dirs create mode 100755 build/deb/debian/blockbook-btg.install create mode 100644 build/deb/debian/blockbook-btg.links create mode 100644 build/deb/debian/blockbook-btg.postinst create mode 100644 build/deb/debian/blockbook-btg.service create mode 100644 configs/btg.json diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index 4be02c9c..bcb3c3d0 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -4,6 +4,7 @@ import ( "blockbook/bchain" "blockbook/bchain/coins/bch" "blockbook/bchain/coins/btc" + "blockbook/bchain/coins/btg" "blockbook/bchain/coins/eth" "blockbook/bchain/coins/zec" "blockbook/common" @@ -30,6 +31,7 @@ func init() { blockChainFactories["Ethereum Testnet Ropsten"] = eth.NewEthereumRPC blockChainFactories["bch"] = bch.NewBCashRPC blockChainFactories["bch-testnet"] = bch.NewBCashRPC + blockChainFactories["btg"] = btg.NewBGoldRPC } // GetCoinNameFromConfig gets coin name from config file diff --git a/bchain/coins/btg/bgoldparser.go b/bchain/coins/btg/bgoldparser.go new file mode 100644 index 00000000..af6a5c16 --- /dev/null +++ b/bchain/coins/btg/bgoldparser.go @@ -0,0 +1,49 @@ +package bch + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + "fmt" + + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcutil" + "github.com/cpacia/bchutil" + "github.com/schancel/cashaddr-converter/address" +) + +const ( + MainnetMagic wire.BitcoinNet = 0x446d47e1 + TestnetMagic wire.BitcoinNet = 0x456e48e2 + RegtestMagic wire.BitcoinNet = 0xdab5bffa +) + +// BGoldParser handle +type BGoldParser struct { + *btc.BitcoinParser +} + +// NewBCashParser returns new BGoldParser instance +func NewBGoldParser(params *chaincfg.Params, c *btc.Configuration) *BGoldParser { + return BGoldParser{BitcoinParser: btc.NewBitcoinParser(params, c)} +} + +// GetChainParams contains network parameters for the main Bitcoin Cash network, +// the regression test Bitcoin Cash network, the test Bitcoin Cash network and +// the simulation test Bitcoin Cash network, in this order +func GetChainParams(chain string) *chaincfg.Params { + var params *chaincfg.Params + switch chain { + case "test": + params = &chaincfg.TestNet3Params + params.Net = TestnetMagic + case "regtest": + params = &chaincfg.RegressionNetParams + params.Net = Regtestmagic + default: + params = &chaincfg.MainNetParams + params.Net = MainnetMagic + } + + return params +} diff --git a/bchain/coins/btg/bgoldparser_test.go b/bchain/coins/btg/bgoldparser_test.go new file mode 100644 index 00000000..9402a0dc --- /dev/null +++ b/bchain/coins/btg/bgoldparser_test.go @@ -0,0 +1,274 @@ +package bch + +// import ( +// "blockbook/bchain" +// "blockbook/bchain/coins/btc" +// "bytes" +// "encoding/hex" +// "reflect" +// "testing" +// ) +// +// func TestBcashAddressEncodeAddress(t *testing.T) { +// addr1, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", Legacy) +// if err != nil { +// t.Errorf("newBCashAddress() error = %v", err) +// return +// } +// got1 := addr1.String() +// if got1 != "13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji" { +// t.Errorf("String() got1 = %v, want %v", got1, "13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji") +// } +// addr2, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", CashAddr) +// if err != nil { +// t.Errorf("newBCashAddress() error = %v", err) +// return +// } +// got2 := addr2.String() +// if got2 != "bitcoincash:qqsvjuqqwgyzvz7zz9xcvxent0ul2xjs6y4d9qvsrf" { +// t.Errorf("String() got2 = %v, want %v", got2, "bitcoincash:qqsvjuqqwgyzvz7zz9xcvxent0ul2xjs6y4d9qvsrf") +// } +// } +// +// func TestBcashAddressAreEqual(t *testing.T) { +// addr1, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", Legacy) +// if err != nil { +// t.Errorf("newBCashAddress() error = %v", err) +// return +// } +// addr2, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", CashAddr) +// if err != nil { +// t.Errorf("newBCashAddress() error = %v", err) +// return +// } +// got1 := addr1.AreEqual("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji") +// if got1 != true { +// t.Errorf("AreEqual() got1 = %v, want %v", got1, true) +// } +// got2 := addr2.AreEqual("bitcoincash:qqsvjuqqwgyzvz7zz9xcvxent0ul2xjs6y4d9qvsrf") +// if got2 != true { +// t.Errorf("AreEqual() got2 = %v, want %v", got2, true) +// } +// got3 := addr1.AreEqual("1HoKgKQh7ZNomWURmS9Tk3z8JM2MWm7S1w") +// if got3 != false { +// t.Errorf("AreEqual() got3 = %v, want %v", got3, false) +// } +// got4 := addr2.AreEqual("bitcoincash:qzuyf0gpqj7q5wfck3nyghhklju7r0k3ksmq6d0vch") +// if got4 != false { +// t.Errorf("AreEqual() got4 = %v, want %v", got4, false) +// } +// } +// +// func TestBcashAddressInSlice(t *testing.T) { +// addr1, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", Legacy) +// if err != nil { +// t.Errorf("newBCashAddress() error = %v", err) +// return +// } +// addr2, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", CashAddr) +// if err != nil { +// t.Errorf("newBCashAddress() error = %v", err) +// return +// } +// got1 := addr1.InSlice([]string{"13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", "1HoKgKQh7ZNomWURmS9Tk3z8JM2MWm7S1w"}) +// if got1 != true { +// t.Errorf("InSlice() got1 = %v, want %v", got1, true) +// } +// got2 := addr2.InSlice([]string{"bitcoincash:qzuyf0gpqj7q5wfck3nyghhklju7r0k3ksmq6d0vch", "bitcoincash:qqsvjuqqwgyzvz7zz9xcvxent0ul2xjs6y4d9qvsrf"}) +// if got2 != true { +// t.Errorf("InSlice() got2 = %v, want %v", got2, true) +// } +// got3 := addr1.InSlice([]string{"1HoKgKQh7ZNomWURmS9Tk3z8JM2MWm7S1w", "1E6Np6dUPYpBSdLMLuwBF8sRQ3cngdaRRY"}) +// if got3 != false { +// t.Errorf("InSlice() got3 = %v, want %v", got3, false) +// } +// got4 := addr2.InSlice([]string{"bitcoincash:qzuyf0gpqj7q5wfck3nyghhklju7r0k3ksmq6d0vch", "bitcoincash:qz8emmpenqgeg7et8xsz8prvhy6cqcalyyjcamt7e9"}) +// if got4 != false { +// t.Errorf("InSlice() got4 = %v, want %v", got4, false) +// } +// } +// +// func TestAddressToOutputScript(t *testing.T) { +// parser, err := NewBCashParser(GetChainParams("test"), &btc.Configuration{AddressFormat: "legacy"}) +// if err != nil { +// t.Errorf("NewBCashParser() error = %v", err) +// return +// } +// want, err := hex.DecodeString("76a9144fa927fd3bcf57d4e3c582c3d2eb2bd3df8df47c88ac") +// if err != nil { +// panic(err) +// } +// got1, err := parser.AddressToOutputScript("mnnAKPTSrWjgoi3uEYaQkHA1QEC5btFeBr") +// if err != nil { +// t.Errorf("AddressToOutputScript() error = %v", err) +// return +// } +// if !bytes.Equal(got1, want) { +// t.Errorf("AddressToOutputScript() got1 = %v, want %v", got1, want) +// } +// got2, err := parser.AddressToOutputScript("bchtest:qp86jfla8084048rckpv85ht90falr050s03ejaesm") +// if err != nil { +// t.Errorf("AddressToOutputScript() error = %v", err) +// return +// } +// if !bytes.Equal(got2, want) { +// t.Errorf("AddressToOutputScript() got2 = %v, want %v", got2, want) +// } +// } +// +// var ( +// testTx1, testTx2 bchain.Tx +// +// testTxPacked1 = "0001e2408ba8d7af5401000000017f9a22c9cbf54bd902400df746f138f37bcf5b4d93eb755820e974ba43ed5f42040000006a4730440220037f4ed5427cde81d55b9b6a2fd08c8a25090c2c2fff3a75c1a57625ca8a7118022076c702fe55969fa08137f71afd4851c48e31082dd3c40c919c92cdbc826758d30121029f6da5623c9f9b68a9baf9c1bc7511df88fa34c6c2f71f7c62f2f03ff48dca80feffffff019c9700000000000017a9146144d57c8aff48492c9dfb914e120b20bad72d6f8773d00700" +// testTxPacked2 = "0007c91a899ab7da6a010000000001019d64f0c72a0d206001decbffaa722eb1044534c74eee7a5df8318e42a4323ec10000000017160014550da1f5d25a9dae2eafd6902b4194c4c6500af6ffffffff02809698000000000017a914cd668d781ece600efa4b2404dc91fd26b8b8aed8870553d7360000000017a914246655bdbd54c7e477d0ea2375e86e0db2b8f80a8702473044022076aba4ad559616905fa51d4ddd357fc1fdb428d40cb388e042cdd1da4a1b7357022011916f90c712ead9a66d5f058252efd280439ad8956a967e95d437d246710bc9012102a80a5964c5612bb769ef73147b2cf3c149bc0fd4ecb02f8097629c94ab013ffd00000000" +// ) +// +// func init() { +// var ( +// addr1, addr2, addr3 bchain.Address +// err error +// ) +// addr1, err = newBCashAddress("3AZKvpKhSh1o8t1QrX3UeXG9d2BhCRnbcK", Legacy) +// if err == nil { +// addr2, err = newBCashAddress("2NByHN6A8QYkBATzxf4pRGbCSHD5CEN2TRu", Legacy) +// } +// if err == nil { +// addr3, err = newBCashAddress("2MvZguYaGjM7JihBgNqgLF2Ca2Enb76Hj9D", Legacy) +// } +// if err != nil { +// panic(err) +// } +// +// testTx1 = bchain.Tx{ +// Hex: "01000000017f9a22c9cbf54bd902400df746f138f37bcf5b4d93eb755820e974ba43ed5f42040000006a4730440220037f4ed5427cde81d55b9b6a2fd08c8a25090c2c2fff3a75c1a57625ca8a7118022076c702fe55969fa08137f71afd4851c48e31082dd3c40c919c92cdbc826758d30121029f6da5623c9f9b68a9baf9c1bc7511df88fa34c6c2f71f7c62f2f03ff48dca80feffffff019c9700000000000017a9146144d57c8aff48492c9dfb914e120b20bad72d6f8773d00700", +// Blocktime: 1519053802, +// Txid: "056e3d82e5ffd0e915fb9b62797d76263508c34fe3e5dbed30dd3e943930f204", +// LockTime: 512115, +// Vin: []bchain.Vin{ +// { +// ScriptSig: bchain.ScriptSig{ +// Hex: "4730440220037f4ed5427cde81d55b9b6a2fd08c8a25090c2c2fff3a75c1a57625ca8a7118022076c702fe55969fa08137f71afd4851c48e31082dd3c40c919c92cdbc826758d30121029f6da5623c9f9b68a9baf9c1bc7511df88fa34c6c2f71f7c62f2f03ff48dca80", +// }, +// Txid: "425fed43ba74e9205875eb934d5bcf7bf338f146f70d4002d94bf5cbc9229a7f", +// Vout: 4, +// Sequence: 4294967294, +// }, +// }, +// Vout: []bchain.Vout{ +// { +// Value: 0.00038812, +// N: 0, +// ScriptPubKey: bchain.ScriptPubKey{ +// Hex: "a9146144d57c8aff48492c9dfb914e120b20bad72d6f87", +// Addresses: []string{ +// "bitcoincash:pps5f4tu3tl5sjfvnhaeznsjpvst44eddugfcnqpy9", +// }, +// }, +// Address: addr1, +// }, +// }, +// } +// +// testTx2 = bchain.Tx{ +// Hex: "010000000001019d64f0c72a0d206001decbffaa722eb1044534c74eee7a5df8318e42a4323ec10000000017160014550da1f5d25a9dae2eafd6902b4194c4c6500af6ffffffff02809698000000000017a914cd668d781ece600efa4b2404dc91fd26b8b8aed8870553d7360000000017a914246655bdbd54c7e477d0ea2375e86e0db2b8f80a8702473044022076aba4ad559616905fa51d4ddd357fc1fdb428d40cb388e042cdd1da4a1b7357022011916f90c712ead9a66d5f058252efd280439ad8956a967e95d437d246710bc9012102a80a5964c5612bb769ef73147b2cf3c149bc0fd4ecb02f8097629c94ab013ffd00000000", +// Blocktime: 1235678901, +// Txid: "474e6795760ebe81cb4023dc227e5a0efe340e1771c89a0035276361ed733de7", +// LockTime: 0, +// Vin: []bchain.Vin{ +// { +// ScriptSig: bchain.ScriptSig{ +// Hex: "160014550da1f5d25a9dae2eafd6902b4194c4c6500af6", +// }, +// Txid: "c13e32a4428e31f85d7aee4ec7344504b12e72aaffcbde0160200d2ac7f0649d", +// Vout: 0, +// Sequence: 4294967295, +// }, +// }, +// Vout: []bchain.Vout{ +// { +// Value: .1, +// N: 0, +// ScriptPubKey: bchain.ScriptPubKey{ +// Hex: "a914cd668d781ece600efa4b2404dc91fd26b8b8aed887", +// Addresses: []string{ +// "bchtest:prxkdrtcrm8xqrh6fvjqfhy3l5nt3w9wmq9fmsvkmz", +// }, +// }, +// Address: addr2, +// }, +// { +// Value: 9.20081157, +// N: 1, +// ScriptPubKey: bchain.ScriptPubKey{ +// Hex: "a914246655bdbd54c7e477d0ea2375e86e0db2b8f80a87", +// Addresses: []string{ +// "bchtest:pqjxv4dah42v0erh6r4zxa0gdcxm9w8cpg0qw8tqf6", +// }, +// }, +// Address: addr3, +// }, +// }, +// } +// } +// +// func Test_UnpackTx(t *testing.T) { +// parser1, err := NewBCashParser(GetChainParams("main"), &btc.Configuration{AddressFormat: "legacy"}) +// if err != nil { +// t.Errorf("NewBCashParser() error = %v", err) +// return +// } +// parser2, err := NewBCashParser(GetChainParams("test"), &btc.Configuration{AddressFormat: "legacy"}) +// if err != nil { +// t.Errorf("NewBCashParser() error = %v", err) +// return +// } +// +// type args struct { +// packedTx string +// parser *BCashParser +// } +// tests := []struct { +// name string +// args args +// want *bchain.Tx +// want1 uint32 +// wantErr bool +// }{ +// { +// name: "btc-1", +// args: args{ +// packedTx: testTxPacked1, +// parser: parser1, +// }, +// want: &testTx1, +// want1: 123456, +// wantErr: false, +// }, +// { +// name: "testnet-1", +// args: args{ +// packedTx: testTxPacked2, +// parser: parser2, +// }, +// want: &testTx2, +// want1: 510234, +// wantErr: false, +// }, +// } +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// b, _ := hex.DecodeString(tt.args.packedTx) +// got, got1, err := tt.args.parser.UnpackTx(b) +// if (err != nil) != tt.wantErr { +// t.Errorf("unpackTx() error = %v, wantErr %v", err, tt.wantErr) +// return +// } +// if !reflect.DeepEqual(got, tt.want) { +// t.Errorf("unpackTx() got = %v, want %v", got, tt.want) +// } +// if got1 != tt.want1 { +// t.Errorf("unpackTx() got1 = %v, want %v", got1, tt.want1) +// } +// }) +// } +// } diff --git a/bchain/coins/btg/bgoldrpc.go b/bchain/coins/btg/bgoldrpc.go new file mode 100644 index 00000000..c3a88bdb --- /dev/null +++ b/bchain/coins/btg/bgoldrpc.go @@ -0,0 +1,175 @@ +package bch + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + "encoding/hex" + "encoding/json" + + "github.com/cpacia/bchutil" + "github.com/golang/glog" + "github.com/juju/errors" +) + +// BGoldRPC is an interface to JSON-RPC bitcoind service. +type BGoldRPC struct { + *btc.BitcoinRPC +} + +// NewBCashRPC returns new BGoldRPC instance. +func NewBGoldRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) { + b, err := btc.NewBitcoinRPC(config, pushHandler) + if err != nil { + return nil, err + } + + s := &BGoldRPC{ + b.(*btc.BitcoinRPC), + } + + return s, nil +} + +// Initialize initializes BGoldRPC instance. +func (b *BGoldRPC) Initialize() error { + chainName, err := b.GetChainInfoAndInitializeMempool(b) + if err != nil { + return err + } + + params := GetChainParams(chainName) + + // always create parser + b.Parser, err = NewBGoldParser(params, b.ChainConfig) + + if err != nil { + return err + } + + // 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 +// +// type cmdGetBlock struct { +// Method string `json:"method"` +// Params struct { +// BlockHash string `json:"blockhash"` +// Verbose bool `json:"verbose"` +// } `json:"params"` +// } +// +// type resGetBlockRaw struct { +// Error *bchain.RPCError `json:"error"` +// Result string `json:"result"` +// } +// +// type resGetBlockThin struct { +// Error *bchain.RPCError `json:"error"` +// Result bchain.ThinBlock `json:"result"` +// } +// +// // estimatesmartfee +// +// type cmdEstimateSmartFee struct { +// Method string `json:"method"` +// Params struct { +// Blocks int `json:"nblocks"` +// } `json:"params"` +// } +// +// type resEstimateSmartFee struct { +// Error *bchain.RPCError `json:"error"` +// Result struct { +// Feerate float64 `json:"feerate"` +// Blocks int `json:"blocks"` +// } `json:"result"` +// } +// +// // GetBlock returns block with given hash. +// func (b *BGoldRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) { +// var err error +// if hash == "" && height > 0 { +// hash, err = b.GetBlockHash(height) +// if err != nil { +// return nil, err +// } +// } +// header, err := b.GetBlockHeader(hash) +// if err != nil { +// return nil, err +// } +// data, err := b.GetBlockRaw(hash) +// if err != nil { +// return nil, err +// } +// block, err := b.Parser.ParseBlock(data) +// if err != nil { +// return nil, errors.Annotatef(err, "hash %v", hash) +// } +// block.BlockHeader = *header +// return block, nil +// } +// +// // GetBlockRaw returns block with given hash as bytes. +// func (b *BGoldRPC) GetBlockRaw(hash string) ([]byte, error) { +// glog.V(1).Info("rpc: getblock (verbose=0) ", hash) +// +// res := resGetBlockRaw{} +// req := cmdGetBlock{Method: "getblock"} +// req.Params.BlockHash = hash +// req.Params.Verbose = false +// err := b.Call(&req, &res) +// +// if err != nil { +// return nil, errors.Annotatef(err, "hash %v", hash) +// } +// if res.Error != nil { +// if isErrBlockNotFound(res.Error) { +// return nil, bchain.ErrBlockNotFound +// } +// return nil, errors.Annotatef(res.Error, "hash %v", hash) +// } +// return hex.DecodeString(res.Result) +// } +// +// // GetBlockFull returns block with given hash. +// func (b *BGoldRPC) GetBlockFull(hash string) (*bchain.Block, error) { +// return nil, errors.New("Not implemented") +// } +// +// // EstimateSmartFee returns fee estimation. +// func (b *BGoldRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) { +// glog.V(1).Info("rpc: estimatesmartfee ", blocks) +// +// res := resEstimateSmartFee{} +// req := cmdEstimateSmartFee{Method: "estimatesmartfee"} +// req.Params.Blocks = blocks +// // conservative param is omitted +// err := b.Call(&req, &res) +// +// if err != nil { +// return 0, err +// } +// if res.Error != nil { +// return 0, res.Error +// } +// return res.Result.Feerate, nil +// } +// +// func isErrBlockNotFound(err *bchain.RPCError) bool { +// return err.Message == "Block not found" || +// err.Message == "Block height out of range" +// } diff --git a/build/deb/debian/blockbook-btg.conffiles b/build/deb/debian/blockbook-btg.conffiles new file mode 100644 index 00000000..db6e2662 --- /dev/null +++ b/build/deb/debian/blockbook-btg.conffiles @@ -0,0 +1 @@ +/opt/coins/blockbook/btg/config/blockchaincfg.json diff --git a/build/deb/debian/blockbook-btg.cron.daily b/build/deb/debian/blockbook-btg.cron.daily new file mode 100644 index 00000000..23bb381f --- /dev/null +++ b/build/deb/debian/blockbook-btg.cron.daily @@ -0,0 +1,2 @@ +#!/bin/sh +/opt/coins/blockbook/btg/bin/logrotate.sh diff --git a/build/deb/debian/blockbook-btg.dirs b/build/deb/debian/blockbook-btg.dirs new file mode 100644 index 00000000..1f63c9d2 --- /dev/null +++ b/build/deb/debian/blockbook-btg.dirs @@ -0,0 +1,2 @@ +/opt/coins/data/btg/blockbook +/opt/coins/blockbook/btg/logs diff --git a/build/deb/debian/blockbook-btg.install b/build/deb/debian/blockbook-btg.install new file mode 100755 index 00000000..4287cdad --- /dev/null +++ b/build/deb/debian/blockbook-btg.install @@ -0,0 +1,6 @@ +#!/usr/bin/dh-exec +blockbook /opt/coins/blockbook/btg/bin +cert /opt/coins/blockbook/btg +static /opt/coins/blockbook/btg +configs/btg.json => /opt/coins/blockbook/btg/config/blockchaincfg.json +logrotate.sh /opt/coins/blockbook/btg/bin diff --git a/build/deb/debian/blockbook-btg.links b/build/deb/debian/blockbook-btg.links new file mode 100644 index 00000000..214928f1 --- /dev/null +++ b/build/deb/debian/blockbook-btg.links @@ -0,0 +1,2 @@ +/opt/coins/blockbook/btg/cert/testcert.crt /opt/coins/blockbook/btg/cert/blockbook.crt +/opt/coins/blockbook/btg/cert/testcert.key /opt/coins/blockbook/btg/cert/blockbook.key diff --git a/build/deb/debian/blockbook-btg.postinst b/build/deb/debian/blockbook-btg.postinst new file mode 100644 index 00000000..1173d21c --- /dev/null +++ b/build/deb/debian/blockbook-btg.postinst @@ -0,0 +1,23 @@ +#!/bin/bash +set -e + +case "$1" in + + configure) + if ! id -u blockbook-btg &> /dev/null + then + useradd --system -M -U blockbook-btg -s /bin/false + fi + + for dir in /opt/coins/data/btg/blockbook /opt/coins/blockbook/btg/logs + do + if [ "$(stat -c '%U' $dir)" != "blockbook-btg" ] + then + chown -R blockbook-btg:blockbook-btg $dir + fi + done + ;; + +esac + +#DEBHELPER# diff --git a/build/deb/debian/blockbook-btg.service b/build/deb/debian/blockbook-btg.service new file mode 100644 index 00000000..83c61b97 --- /dev/null +++ b/build/deb/debian/blockbook-btg.service @@ -0,0 +1,43 @@ +# It is not recommended to modify this file in-place, because it will +# be overwritten during package upgrades. If you want to add further +# options or overwrite existing ones then use +# $ systemctl edit blockbook-btg.service +# See "man systemd.service" for details. + +[Unit] +Description=Blockbook daemon (BTG mainnet) +After=network.target +Wants=bgold-btg.service + +[Service] +ExecStart=/opt/coins/blockbook/btg/bin/blockbook -coin=btg -blockchaincfg=/opt/coins/blockbook/btg/config/blockchaincfg.json -datadir=/opt/coins/data/btg/blockbook/db -sync -httpserver=:9035 -socketio=:9135 -certfile=/opt/coins/blockbook/btg/cert/blockbook -explorer=https://btg-bitcore1.trezor.io/ -log_dir=/opt/coins/blockbook/btg/logs +User=blockbook-btg +Type=simple +Restart=on-failure +WorkingDirectory=/opt/coins/blockbook/btg + +# Resource limits +LimitNOFILE=500000 + +# Hardening measures +#################### + +# Provide a private /tmp and /var/tmp. +PrivateTmp=true + +# Mount /usr, /boot/ and /etc read-only for the process. +ProtectSystem=full + +# Disallow the process and all of its children to gain +# new privileges through execve(). +NoNewPrivileges=true + +# Use a new /dev namespace only populated with API pseudo devices +# such as /dev/null, /dev/zero and /dev/random. +PrivateDevices=true + +# Deny the creation of writable and executable memory mappings. +MemoryDenyWriteExecute=true + +[Install] +WantedBy=multi-user.target diff --git a/build/deb/debian/control b/build/deb/debian/control index 93c828bf..31105e72 100644 --- a/build/deb/debian/control +++ b/build/deb/debian/control @@ -39,3 +39,8 @@ Package: blockbook-bch-testnet Architecture: amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, coreutils, passwd, findutils, psmisc, bcash-testnet Description: Satoshilabs blockbook server (Bitcoin Cash testnet) + +Package: blockbook-btg +Architecture: amd64 +Depends: ${shlibs:Depends}, ${misc:Depends}, coreutils, passwd, findutils, psmisc, bgold-btg +Description: Satoshilabs blockbook server (Bitcoin Gold mainnet) diff --git a/configs/btg.json b/configs/btg.json new file mode 100644 index 00000000..f13c32a9 --- /dev/null +++ b/configs/btg.json @@ -0,0 +1,13 @@ +{ + "rpcURL": "http://127.0.0.1:8035", + "rpcUser": "rpc", + "rpcPass": "rpc", + "rpcTimeout": 25, + "parse": true, + "zeroMQBinding": "tcp://127.0.0.1:38335", + "subversion": "/Bitcoin Gold:0.15.0.2/", + "mempoolWorkers": 8, + "mempoolSubWorkers": 2, + "blockAddressesToKeep": 300, + "addressFormat": "legacy" +}