diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index ea995562..12827037 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -6,6 +6,7 @@ import ( "blockbook/bchain/coins/btc" "blockbook/bchain/coins/btg" "blockbook/bchain/coins/dash" + "blockbook/bchain/coins/dogecoin" "blockbook/bchain/coins/eth" "blockbook/bchain/coins/litecoin" "blockbook/bchain/coins/zec" @@ -38,6 +39,7 @@ func init() { blockChainFactories["Dash Testnet"] = dash.NewDashRPC blockChainFactories["Litecoin"] = litecoin.NewLitecoinRPC blockChainFactories["Litecoin Testnet"] = litecoin.NewLitecoinRPC + blockChainFactories["Dogecoin"] = dogecoin.NewDogecoinRPC } // GetCoinNameFromConfig gets coin name from config file diff --git a/bchain/coins/btc/bitcoinrpc.go b/bchain/coins/btc/bitcoinrpc.go index df855f35..ac482b8b 100644 --- a/bchain/coins/btc/bitcoinrpc.go +++ b/bchain/coins/btc/bitcoinrpc.go @@ -458,7 +458,7 @@ func (b *BitcoinRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) } // optimization if height > 0 { - return b.getBlockWithoutHeader(hash, height) + return b.GetBlockWithoutHeader(hash, height) } header, err := b.GetBlockHeader(hash) if err != nil { @@ -478,7 +478,7 @@ func (b *BitcoinRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) // getBlockWithoutHeader is an optimization - it does not call GetBlockHeader to get prev, next hashes // instead it sets to header only block hash and height passed in parameters -func (b *BitcoinRPC) getBlockWithoutHeader(hash string, height uint32) (*bchain.Block, error) { +func (b *BitcoinRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.Block, error) { data, err := b.GetBlockRaw(hash) if err != nil { return nil, err diff --git a/bchain/coins/dogecoin/dogecoinparser.go b/bchain/coins/dogecoin/dogecoinparser.go new file mode 100644 index 00000000..075cdfa9 --- /dev/null +++ b/bchain/coins/dogecoin/dogecoinparser.go @@ -0,0 +1,167 @@ +package dogecoin + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + "bytes" + "fmt" + "io" + + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/wire" +) + +const ( + MainnetMagic wire.BitcoinNet = 0xc0c0c0c0 +) + +var ( + MainNetParams chaincfg.Params +) + +func init() { + MainNetParams = chaincfg.MainNetParams + MainNetParams.Net = MainnetMagic + MainNetParams.PubKeyHashAddrID = 30 + MainNetParams.ScriptHashAddrID = 22 + + err := chaincfg.Register(&MainNetParams) + if err != nil { + panic(err) + } +} + +// DogecoinParser handle +type DogecoinParser struct { + *btc.BitcoinParser +} + +// NewDogecoinParser returns new DogecoinParser instance +func NewDogecoinParser(params *chaincfg.Params, c *btc.Configuration) *DogecoinParser { + return &DogecoinParser{BitcoinParser: btc.NewBitcoinParser(params, c)} +} + +// GetChainParams contains network parameters for the main Dogecoin network, +// and the test Dogecoin network +func GetChainParams(chain string) *chaincfg.Params { + switch chain { + default: + return &MainNetParams + } +} + +// minTxPayload is the minimum payload size for a transaction. Note +// that any realistically usable transaction must have at least one +// input or output, but that is a rule enforced at a higher layer, so +// it is intentionally not included here. +// Version 4 bytes + Varint number of transaction inputs 1 byte + Varint +// number of transaction outputs 1 byte + LockTime 4 bytes + min input +// payload + min output payload. +const minTxPayload = 10 + +// maxTxPerBlock is the maximum number of transactions that could +// possibly fit into a block. +const maxTxPerBlock = (wire.MaxBlockPayload / minTxPayload) + 1 + +const versionAuxpow = (1 << 8) + +// 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 *DogecoinParser) 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 & versionAuxpow) != 0 { + // skip Auxpow part of the block + // https://github.com/dogecoin/dogecoin/blob/master/src/auxpow.h#L130 + // CMerkleTx CTransaction + tx := wire.MsgTx{} + err = tx.BtcDecode(r, 0, wire.WitnessEncoding) + if err != nil { + return nil, err + } + // CMerkleTx uint256 hashBlock + _, err = r.Seek(32, io.SeekCurrent) + if err != nil { + return nil, err + } + // CMerkleTx std::vector vMerkleBranch + size, err := wire.ReadVarInt(r, 0) + if err != nil { + return nil, err + } + _, err = r.Seek(int64(size)*32, io.SeekCurrent) + if err != nil { + return nil, err + } + // CMerkleTx int nIndex + _, err = r.Seek(4, io.SeekCurrent) + if err != nil { + return nil, err + } + // CAuxPow std::vector vChainMerkleBranch; + size, err = wire.ReadVarInt(r, 0) + if err != nil { + return nil, err + } + _, err = r.Seek(int64(size)*32, io.SeekCurrent) + if err != nil { + return nil, err + } + // CAuxPow int nChainIndex; + _, err = r.Seek(4, io.SeekCurrent) + if err != nil { + return nil, err + } + // CAuxPow CPureBlockHeader parentBlock; + ph := wire.BlockHeader{} + err = ph.Deserialize(r) + if err != nil { + return nil, err + } + } + + err = 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{Txs: txs}, nil +} + +func decodeTransactions(r io.Reader, pver uint32, enc wire.MessageEncoding, blk *wire.MsgBlock) error { + txCount, err := wire.ReadVarInt(r, pver) + if err != nil { + return err + } + + // Prevent more transactions than could possibly fit into a block. + // It would be possible to cause memory exhaustion and panics without + // a sane upper bound on this count. + if txCount > maxTxPerBlock { + str := fmt.Sprintf("too many transactions to fit into a block "+ + "[count %d, max %d]", txCount, maxTxPerBlock) + return &wire.MessageError{Func: "btg.decodeTransactions", Description: str} + } + + blk.Transactions = make([]*wire.MsgTx, 0, txCount) + for i := uint64(0); i < txCount; i++ { + tx := wire.MsgTx{} + err := tx.BtcDecode(r, pver, enc) + if err != nil { + return err + } + blk.Transactions = append(blk.Transactions, &tx) + } + + return nil +} diff --git a/bchain/coins/dogecoin/dogecoinparser_test.go b/bchain/coins/dogecoin/dogecoinparser_test.go new file mode 100644 index 00000000..a0b3a36e --- /dev/null +++ b/bchain/coins/dogecoin/dogecoinparser_test.go @@ -0,0 +1,406 @@ +package dogecoin + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + "bytes" + "encoding/hex" + "fmt" + "io/ioutil" + "path/filepath" + "reflect" + "testing" +) + +func TestAddressToOutputScript_Mainnet(t *testing.T) { + type args struct { + address string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "P2PKH1", + args: args{address: "DHZYinsaM9nW5piCMN639ELRKbZomThPnZ"}, + want: "76a9148841590909747c0f97af158f22fadacb1652522088ac", + wantErr: false, + }, + { + name: "P2PKH2", + args: args{address: "DSzaAYEYyy9ngjoJ294r7jzFM3xhD6bKHK"}, + want: "76a914efb6158f75743c611858fdfd0f4aaec6cc6196bc88ac", + wantErr: false, + }, + { + name: "P2SH1", + args: args{address: "9tg1kVUk339Tk58ewu5T8QT82Z6cE4UvSU"}, + want: "a9141889a089400ea25d28694fd98aa7702b21eeeab187", + wantErr: false, + }, + { + name: "P2SH2", + args: args{address: "9sLa1AKzjWuNTe1CkLh5GDYyRP9enb1Spp"}, + want: "a91409e41aff9f97412ab3d4a07cf0667fdba84caf4487", + wantErr: false, + }, + } + parser := NewDogecoinParser(GetChainParams("main"), &btc.Configuration{}) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := parser.AddressToOutputScript(tt.args.address) + if (err != nil) != tt.wantErr { + t.Errorf("AddressToOutputScript() error = %v, wantErr %v", err, tt.wantErr) + return + } + h := hex.EncodeToString(got) + if !reflect.DeepEqual(h, tt.want) { + t.Errorf("AddressToOutputScript() = %v, want %v", h, tt.want) + } + }) + } +} + +var ( + testTx1 bchain.Tx + testTxPacked1 = "00030e6d8ba8d7aa2001000000016b3c0c53267964120acf7f7e72217e3f463e52ce622f89659f6a6bb8e69a4d91000000006c493046022100a96454237e3a020994534583e28c04757881374bceac89f933ea9ff00b4db259022100fbb757ff7ea4f02c4e42556b2834c61eba1f1af605db089d836a0614d90a3b46012103cebdde6d1046e285df4f48497bc50dc20a4a258ca5b7308cb0a929c9fdadcd9dffffffff0217e823ca7f0200001976a914eef21768a546590993e313c7f3dfadf6a6efa1e888acaddf4cba010000001976a914e0fee2ea29dd9c6c759d8341bd0da4c4f738cced88ac00000000" + + testTx2 bchain.Tx + testTxPacked2 = "0001193a8ba8d7835601000000016d0211b5656f1b8c2ac002445638e247082090ffc5d5fa7c38b445b84a2c2054000000006b4830450221008856f2f620df278c0fc6a5d5e2d50451c0a65a75aaf7a4a9cbfcac3918b5536802203dc685a784d49e2a95eb72763ad62f02094af78507c57b0a3c3f1d8a60f74db6012102db814cd43df584804fde1949365a6309714e342aef0794dc58385d7e413444cdffffffff0237daa2ee0a4715001976a9149355c01ed20057eac9fe0bbf8b07d87e62fe712d88ac8008389e7e8d03001976a9145b4f2511c94e4fcaa8f8835b2458f8cb6542ca7688ac00000000" +) + +func init() { + var ( + addr1, addr2, addr3, addr4 bchain.Address + err error + ) + addr1, err = bchain.NewBaseAddress("DSvXNiqvG42wdteLqh3i6inxgDTs8Y9w2i") + if err == nil { + addr2, err = bchain.NewBaseAddress("DRemF3ZcqJ1PFeM7e7sXzzwQJKR8GNUtwK") + } + if err == nil { + addr3, err = bchain.NewBaseAddress("DJa8bWDrZKu4HgsYRYWuJrvxt6iTYuvXJ6") + } + if err == nil { + addr4, err = bchain.NewBaseAddress("DDTtqnuZ5kfRT5qh2c7sNtqrJmV3iXYdGG") + } + if err != nil { + panic(err) + } + + testTx1 = bchain.Tx{ + Hex: "01000000016b3c0c53267964120acf7f7e72217e3f463e52ce622f89659f6a6bb8e69a4d91000000006c493046022100a96454237e3a020994534583e28c04757881374bceac89f933ea9ff00b4db259022100fbb757ff7ea4f02c4e42556b2834c61eba1f1af605db089d836a0614d90a3b46012103cebdde6d1046e285df4f48497bc50dc20a4a258ca5b7308cb0a929c9fdadcd9dffffffff0217e823ca7f0200001976a914eef21768a546590993e313c7f3dfadf6a6efa1e888acaddf4cba010000001976a914e0fee2ea29dd9c6c759d8341bd0da4c4f738cced88ac00000000", + Blocktime: 1519053456, + Txid: "097ea09ba284f3f2a9e880e11f837edf7e5cea81c8da2238f5bc7c2c4c407943", + LockTime: 0, + Vin: []bchain.Vin{ + { + ScriptSig: bchain.ScriptSig{ + Hex: "493046022100a96454237e3a020994534583e28c04757881374bceac89f933ea9ff00b4db259022100fbb757ff7ea4f02c4e42556b2834c61eba1f1af605db089d836a0614d90a3b46012103cebdde6d1046e285df4f48497bc50dc20a4a258ca5b7308cb0a929c9fdadcd9d", + }, + Txid: "914d9ae6b86b6a9f65892f62ce523e463f7e21727e7fcf0a12647926530c3c6b", + Vout: 0, + Sequence: 4294967295, + }, + }, + Vout: []bchain.Vout{ + { + Value: 27478.75452951, + N: 0, + ScriptPubKey: bchain.ScriptPubKey{ + Hex: "76a914eef21768a546590993e313c7f3dfadf6a6efa1e888ac", + Addresses: []string{ + "DSvXNiqvG42wdteLqh3i6inxgDTs8Y9w2i", + }, + }, + Address: addr1, + }, + { + Value: 74.20567469, + N: 1, + ScriptPubKey: bchain.ScriptPubKey{ + Hex: "76a914e0fee2ea29dd9c6c759d8341bd0da4c4f738cced88ac", + Addresses: []string{ + "DRemF3ZcqJ1PFeM7e7sXzzwQJKR8GNUtwK", + }, + }, + Address: addr2, + }, + }, + } + + testTx2 = bchain.Tx{ + Hex: "01000000016d0211b5656f1b8c2ac002445638e247082090ffc5d5fa7c38b445b84a2c2054000000006b4830450221008856f2f620df278c0fc6a5d5e2d50451c0a65a75aaf7a4a9cbfcac3918b5536802203dc685a784d49e2a95eb72763ad62f02094af78507c57b0a3c3f1d8a60f74db6012102db814cd43df584804fde1949365a6309714e342aef0794dc58385d7e413444cdffffffff0237daa2ee0a4715001976a9149355c01ed20057eac9fe0bbf8b07d87e62fe712d88ac8008389e7e8d03001976a9145b4f2511c94e4fcaa8f8835b2458f8cb6542ca7688ac00000000", + Blocktime: 1519050987, + Txid: "b276545af246e3ed5a4e3e5b60d359942a1808579effc53ff4f343e4f6cfc5a0", + LockTime: 0, + Vin: []bchain.Vin{ + { + ScriptSig: bchain.ScriptSig{ + Hex: "4830450221008856f2f620df278c0fc6a5d5e2d50451c0a65a75aaf7a4a9cbfcac3918b5536802203dc685a784d49e2a95eb72763ad62f02094af78507c57b0a3c3f1d8a60f74db6012102db814cd43df584804fde1949365a6309714e342aef0794dc58385d7e413444cd", + }, + Txid: "54202c4ab845b4387cfad5c5ff90200847e238564402c02a8c1b6f65b511026d", + Vout: 0, + Sequence: 4294967295, + }, + }, + Vout: []bchain.Vout{ + { + Value: 59890867.89818935, + N: 0, + ScriptPubKey: bchain.ScriptPubKey{ + Hex: "76a9149355c01ed20057eac9fe0bbf8b07d87e62fe712d88ac", + Addresses: []string{ + "DJa8bWDrZKu4HgsYRYWuJrvxt6iTYuvXJ6", + }, + }, + Address: addr3, + }, + { + Value: 9999998.90000000, + N: 1, + ScriptPubKey: bchain.ScriptPubKey{ + Hex: "76a9145b4f2511c94e4fcaa8f8835b2458f8cb6542ca7688ac", + Addresses: []string{ + "DDTtqnuZ5kfRT5qh2c7sNtqrJmV3iXYdGG", + }, + }, + Address: addr4, + }, + }, + } +} + +func Test_PackTx(t *testing.T) { + type args struct { + tx bchain.Tx + height uint32 + blockTime int64 + parser *DogecoinParser + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "dogecoin-1", + args: args{ + tx: testTx1, + height: 200301, + blockTime: 1519053456, + parser: NewDogecoinParser(GetChainParams("main"), &btc.Configuration{}), + }, + want: testTxPacked1, + wantErr: false, + }, + { + name: "dogecoin-2", + args: args{ + tx: testTx2, + height: 71994, + blockTime: 1519050987, + parser: NewDogecoinParser(GetChainParams("main"), &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 Test_UnpackTx(t *testing.T) { + type args struct { + packedTx string + parser *DogecoinParser + } + tests := []struct { + name string + args args + want *bchain.Tx + want1 uint32 + wantErr bool + }{ + { + name: "dogecoin-1", + args: args{ + packedTx: testTxPacked1, + parser: NewDogecoinParser(GetChainParams("main"), &btc.Configuration{}), + }, + want: &testTx1, + want1: 200301, + wantErr: false, + }, + { + name: "dogecoin-2", + args: args{ + packedTx: testTxPacked2, + parser: NewDogecoinParser(GetChainParams("main"), &btc.Configuration{}), + }, + want: &testTx2, + want1: 71994, + 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) + } + }) + } +} + +var testParseBlockTxs = map[int][]string{ + // block without auxpow + 12345: []string{ + "9d1662dcc1443af9999c4fd1d6921b91027b5e2d0d3ebfaa41d84163cb99cad5", + "8284292cedeb0c9c509f9baa235802d52a546e1e9990040d35d018b97ad11cfa", + "3299d93aae5c3d37c795c07150ceaf008aefa5aad3205ea2519f94a35adbbe10", + "3f03016f32b63db48fdc0b17443c2d917ba5e307dcc2fc803feeb21c7219ee1b", + "a889449e9bc618c131c01f564cd309d2217ba1c5731480314795e44f1e02609b", + "29f79d91c10bc311ff5b69fe7ba57101969f68b6391cf0ca67d5f37ca1f0601b", + "b794ebc7c0176c35b125cd8b84a980257cf3dd9cefe2ed47da4ed1d73ee568f3", + "0ec479ba3c954dd422d75c4c5488a6edc3c588deb10ebdbfa8bd8edb7afcfea0", + "f357b6e667dfa456e7988bfa474377df25d0e0bfe07e5f97fc97ea3a0155f031", + "4ff189766f0455721a93d6be27a91eafa750383c800cb053fad2f86c434122d2", + "446d164e2ec4c9f2ac6c499c110735606d949a3625fb849274ac627c033eddbc", + "c489edebd8a2e17fd08f2801f528b95663aaafe15c897d56686423dd430e2d1f", + "3f42a7f1a356897da324d41eed94169c79438212bb9874eea58e9cbaf07481df", + "62c88fdd0fb111676844fcbaebc9e2211a0c990aa7e7529539cb25947a307a1b", + "522c47e315bc1949826339c535d419eb206aec4a332f91dfbd25c206f3c9527b", + "18ea78346e7e34cbdf2d2b6ba1630f8b15f9ef9a940114a3e6ee92d26f96691e", + "43dc0fbd1b9b87bcfc9a51c89457a7b3274855c01d429193aff1181791225f3c", + "d78cdfaadbe5b6b591529cb5c6869866a4cabe46ef82aa835fd2432056b4a383", + "d181759c7a3900ccaf4958f1f25a44949163ceefc306006502efc7a1de6f579e", + "8610b9230188854c7871258163cd1c2db353443d631c5512bff17224a24e95bf", + "e82f40a6bea32122f1d568d427c92708dcb684bdb3035ff3905617230e5ae5b8", + "c50ae6c127f8c346c60e7438fbd10c44c3629f3fe426646db77a2250fb2939f9", + "585202c03894ecaf25188ba4e5447dadd413f2010c2dc2a65c37598dbc6ad907", + "8bd766fde8c65e2f724dad581944dde4e23e4dbb4f7f7faf55bc348923f4d5ee", + "2d2fa25691088181569e508dd8f683b21f2b80ceefb5ccbd6714ebe2a697139f", + "5954622ffc602bec177d61da6c26a68990c42c1886627b218c3ab0e9e3491f4a", + "01b634bc53334df1cd9f04522729a34d811c418c2535144c3ed156cbc319e43e", + "c429a6c8265482b2d824af03afe1c090b233a856f243791485cb4269f2729649", + "dbe79231b916b6fb47a91ef874f35150270eb571af60c2d640ded92b41749940", + "1c396493a8dfd59557052b6e8643123405894b64f48b2eb6eb7a003159034077", + "2e2816ffb7bf1378f11acf5ba30d498efc8fd219d4b67a725e8254ce61b1b7ee", + }, + // 1st block with auxpow + 371337: []string{ + "4547b14bc16db4184fa9f141d645627430dd3dfa662d0e6f418fba497091da75", + "a965dba2ed06827ed9a24f0568ec05b73c431bc7f0fb6913b144e62db7faa519", + "5e3ab18cb7ba3abc44e62fb3a43d4c8168d00cf0a2e0f8dbeb2636bb9a212d12", + "f022935ac7c4c734bd2c9c6a780f8e7280352de8bd358d760d0645b7fe734a93", + "ec063cc8025f9f30a6ed40fc8b1fe63b0cbd2ea2c62664eb26b365e6243828ca", + "02c16e3389320da3e77686d39773dda65a1ecdf98a2ef9cfb938c9f4b58f7a40", + }, + // block with auxpow + 567890: []string{ + "db20feea53be1f60848a66604d5bca63df62de4f6c66220f9c84436d788625a8", + "cf7e9e27c0f56f0b100eaf5c776ce106025e3412bd5927c6e1ce575500e24eaa", + "af84e010c1cf0bd927740d08e5e8163db45397b70f00df07aea5339c14d5f3aa", + "7362e25e8131255d101e5d874e6b6bb2faa7a821356cb041f1843d0901dffdbd", + "3b875344302e8893f6d5c9e7269d806ed27217ec67944940ae9048fc619bdae9", + "e3b95e269b7c251d87e8e241ea2a08a66ec14d12a1012762be368b3db55471e3", + "6ba3f95a37bcab5d0cb5b8bd2fe48040db0a6ae390f320d6dcc8162cc096ff8f", + "3211ccc66d05b10959fa6e56d1955c12368ea52b40303558b254d7dc22570382", + "54c1b279e78b924dfa15857c80131c3ddf835ab02f513dc03aa514f87b680493", + }, + // recent block + 2264125: []string{ + "76f0126562c99e020b5fba41b68dd8141a4f21eef62012b76a1e0635092045e9", + "7bb6688bec16de94014574e3e1d3f6f5fb956530d6b179b28db367f1fd8ae099", + "d7e2ee30c3d179ac896651fc09c1396333f41d952d008af8d5d6665cbea377bf", + "8e4783878df782003c43d014fcbb9c57d2034dfd1d9fcd7319bb1a9f501dbbb7", + "8d2a4ae226b6f23eea545957be5d71c68cd08674d96a3502d4ca21ffadacb5a9", + "a0da2b49de881133655c54b1b5c23af443a71c2b937e2d9bbdf3f498247e6b7b", + "c780a19b9cf46ed70b53c5d5722e8d33951211a4051cb165b25fb0c22a4ae1ff", + "ce29c2644d642bb4fedd09d0840ed98c9945bf292967fede8fcc6b26054b4058", + "a360b0566f68c329e2757918f67ee6421d3d76f70f1b452cdd32266805986119", + "17e85bd33cc5fb5035e489c5188979f45e75e92d14221eca937e14f5f7d7b074", + "3973eb930fd2d0726abbd81912eae645384268cd3500b9ec84d806fdd65a426a", + "b91cc1c98e5c77e80eec9bf93e86af27f810b00dfbce3ee2646758797a28d5f2", + "1a8c7bd3389dcbbc1133ee600898ed9e082f7a9c75f9eb52f33940ed7c2247ef", + "9b1782449bbd3fc3014c363167777f7bdf41f5ef6db192fbda784b29603911b0", + "afab4bcdc1a32891d638579c3029ae49ee72be3303425c6d62e1f8eaebe0ce18", + "5f839f9cd5293c02ff4f7cf5589c53dec52adb42a077599dc7a2c5842a156ca9", + "756d2dfd1d2872ba2531fae3b8984008506871bec41d19cb299f5e0f216cfb9b", + "6aa82514ab7a9cc624fabf3d06ccbd46ecb4009b3c784768e6243d7840d4bf93", + "d1430b3f7ecf147534796c39ba631ea22ac03530e25b9428367c0dc381b10863", + "2aeb69b1eb9eef8039da6b97d7851e46f57325851e6998ef5a84fc9a826c2c74", + "fc61d13eef806af8da693cfa621fe92110694f1514567b186a35c54e7ef4a188", + "a02dd44e60ba62fa00c83a67116f8079bf71062939b207bee0808cb98b30cf22", + "279f97cfc606fe62777b44614ff28675ce661687904e068e3ec79f619c4fdae7", + "d515d271849717b091a9c46bf11c47efb9d975e72b668c137786a208cf0a9739", + "a800da44e6eed944043561fe22ee0a6e11341e6bc1a8ec2789b83930cc9b170e", + }, +} + +func helperLoadBlock(t *testing.T, height int) []byte { + name := fmt.Sprintf("block_dump.%d", height) + path := filepath.Join("testdata", name) + + d, err := ioutil.ReadFile(path) + if err != nil { + t.Fatal(err) + } + + d = bytes.TrimSpace(d) + + b := make([]byte, hex.DecodedLen(len(d))) + _, err = hex.Decode(b, d) + if err != nil { + t.Fatal(err) + } + + return b +} + +func TestParseBlock(t *testing.T) { + p := NewDogecoinParser(GetChainParams("main"), &btc.Configuration{}) + + for height, txs := range testParseBlockTxs { + b := helperLoadBlock(t, height) + + blk, err := p.ParseBlock(b) + if err != nil { + t.Fatal(err) + } + + if len(blk.Txs) != len(txs) { + t.Errorf("ParseBlock() number of transactions: got %d, want %d", len(blk.Txs), len(txs)) + } + + for ti, tx := range txs { + if blk.Txs[ti].Txid != tx { + t.Errorf("ParseBlock() transaction %d: got %s, want %s", ti, blk.Txs[ti].Txid, tx) + } + } + } +} diff --git a/bchain/coins/dogecoin/dogecoinrpc.go b/bchain/coins/dogecoin/dogecoinrpc.go new file mode 100644 index 00000000..d0ebb31c --- /dev/null +++ b/bchain/coins/dogecoin/dogecoinrpc.go @@ -0,0 +1,76 @@ +package dogecoin + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + "encoding/json" + + "github.com/golang/glog" +) + +// DogecoinRPC is an interface to JSON-RPC dogecoind service. +type DogecoinRPC struct { + *btc.BitcoinRPC +} + +// NewDogecoinRPC returns new DogecoinRPC instance. +func NewDogecoinRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) { + b, err := btc.NewBitcoinRPC(config, pushHandler) + if err != nil { + return nil, err + } + + s := &DogecoinRPC{ + b.(*btc.BitcoinRPC), + } + s.RPCMarshaler = btc.JSONMarshalerV1{} + + return s, nil +} + +// Initialize initializes DogecoinRPC instance. +func (b *DogecoinRPC) 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 = NewDogecoinParser(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 *DogecoinRPC) 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) +} + +// EstimateSmartFee returns fee estimation. +func (b *DogecoinRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) { + return b.EstimateFee(blocks) +} diff --git a/bchain/coins/dogecoin/testdata/block_dump.12345 b/bchain/coins/dogecoin/testdata/block_dump.12345 new file mode 100644 index 00000000..23e9527e --- /dev/null +++ b/bchain/coins/dogecoin/testdata/block_dump.12345 @@ -0,0 +1 @@ +010000009b2cbbcc43d33a4acff9bb64c5672c3aafb89dc9ee2eb67c152cb1536419a04ce5678293430d9b2274e77e8f90dfd61956379b0dccda1be2a7a725a9831998f7df87ad52af10081c00886fa71f01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff26023930062f503253482f04e187ad5208f8000ea2020000000d2f7374726174756d506f6f6c2f0000000001c02e4dc9d60000001976a9148493610d1e80e6a1f446784401ac8e7febe8e8ab88ac00000000010000000269a391603f74e6b0770b369298092bf798021b529760451885ab41be6d0f343d010000006b4830450221008fc72e8e561fe41cd0d60414bfc8701d017b5b75d8714b0949714d2b6bab81370220306f1e0c36717d5742f822256f7fe119e6c6fd7525d7817dc90cd47a7e89a95e0121030d247ee340f4966cd32ce4baedafde6dff08cc42a3c3d93fa20ed447ceb70fc6fffffffff45c2c75f879c21f100617398089e14768fff1bb489d73b4c5e7405adda53884010000006b48304502207a34bbdb880f794c68bc76e787bce0de268a80f8f25b285723a1ef57a6f438ad022100aea59451ce9573da3d202d762a392a3fcf9cf38a97d4b2410e2da318f629c8150121030d247ee340f4966cd32ce4baedafde6dff08cc42a3c3d93fa20ed447ceb70fc6ffffffff0232fb217d790000001976a91484f47009dcaec32b535d304eeaa76ccae99d047c88ac00a0724e180900001976a9145b58fffc04e038f73faf3b3375a01f5a0d1f3e6e88ac000000000100000001372474d5c2ca467fb2a976690cae8a0d321448d54e906f448b3ef20b016889b6000000006b483045022100efbc30dff8c0afe855b59aab88e0ce85ee3bc9d8eb629fa750d62d858e240c3f0220790f4ef233100775b0ae950581fc5a9bec8ef6dd010b7a946276b10416b19bd2012103b3227c9bf66af7025cbfc788cebd3f90e10bb0dc790aacc80ef9759f40b6d680ffffffff024006d53bc60500001976a914396c3ddeb0b9f6c8334a2692ba5798795c161b2888ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac00000000010000000baa8ef1c23898f9b501b5ea24b198e10533a1bbb6fe068eab5f261bd30a0b4685010000006b483045022100affbd657eb02c9c6ab355c9c6c1c2cc9a22a640888b70a5f7d851ea38f9d6a1402200111e9b423f7022ea1a2893bd0241c40be3ae7f1b03d5406b2ebcba4b7f3bad5012103f2b6d0e64e6e1a534268759e9f5f33f980729fc2d773d9f793bb56ed021de17bffffffff8fc1ab553a2c903d5df06f52b1bf472806a678437de830b774aaf51ee109540e010000006b4830450221009d80d9aeecad5c1a323825609c055d51e6388066462d79ec979f275e2c9d557c022068a80db169ecf078ef762d37ea30d6cb58655e51366bfff595e105f59521d050012103f2b6d0e64e6e1a534268759e9f5f33f980729fc2d773d9f793bb56ed021de17bffffffffe148b9c73a95f2b6d829381a0846282541dde3d3d042ad21bcd521c36261027f010000006b483045022029de0208286559e85fadf7b5061d3cefdec7436bc4b9c6b0afdec4c259211710022100f1a30070d5f3d9e5216a5637a144764c41801196e52be78c2ee0e2313d80ccf0012103f2b6d0e64e6e1a534268759e9f5f33f980729fc2d773d9f793bb56ed021de17bffffffff93dfdc68110a3b99ca00d809faf8ce77906ff225c62dd483a0288c92be80a364010000006b483045022100c404bbb03fc9ef2c97fdea578727b0503bd6f4109244a528bf0083403cd21266022075b97cff0bcffca94c71491f4a0a85cd46aefd957be5a2aeceb3e82300422b0c012103f2b6d0e64e6e1a534268759e9f5f33f980729fc2d773d9f793bb56ed021de17bffffffff5658981c5bce7de2d5563459972b2796aad3be3e6d5dd5b42c8be0473c54d8a4010000006b48304502203e0d7d3e6ba6958c9f5baa83b3242121debefb35e6a6e6e6984ab4377af0ceab022100f144d3636e204a154fe4dae0a723db04984c563017a6153444b4c94f67d03e4f012103f2b6d0e64e6e1a534268759e9f5f33f980729fc2d773d9f793bb56ed021de17bffffffff8961ed359ad0a1a22c092baadb3a8ec2b17152d21f569a37396a1a3c555d09f5010000006c493046022100fc28288c62b180c40bcd0269137405f0d6527d98d980a5bffe293df3a3ac7e73022100e05370afcd9238594f1e495ccfc7a0e7f38c9c5884b994b17b60774f07340568012103f2b6d0e64e6e1a534268759e9f5f33f980729fc2d773d9f793bb56ed021de17bffffffff4f9c14778859298f74b260b191b4a7ec3b0d2541c06a4d764b096465c94ecbf1010000006a47304402204fa35d122ddbafb78f65749264522be3d063a0027a28bf69780ecbcdebf33cee022022cc49db2a2c1fbd0f500dcf598a2ccd6c342132522a42ff93f50b88df77ba09012103f2b6d0e64e6e1a534268759e9f5f33f980729fc2d773d9f793bb56ed021de17bffffffff530a58c4ddf7407ac210358a12b50aa865162625ad357b6b69e7bad66940c5fd010000006a473044022012a86373f2a43669d1fcea487ea2812579d26937a21400d565f0c4a4a0e253f102201c6fd0b97cf64cdf679901e1c4435c9f5e99de7e4646f489334e56a14f394ddd012103f2b6d0e64e6e1a534268759e9f5f33f980729fc2d773d9f793bb56ed021de17bffffffff4267b2bb5e8b6862121a2a35ab7765622ef7a75ed417e7de13544473124af6a3010000006c493046022100a13f13d28dcc2f48686e974f5eef04e2f0e257c2cd36aefd58a5e31a290a5cb0022100d97aa6b80187d152e84ad25457e10e8caf33bd2bd2ee47ca08c1319e1faf6191012103f2b6d0e64e6e1a534268759e9f5f33f980729fc2d773d9f793bb56ed021de17bffffffffe2ade51cb3e1015aac944a4ae91fc6f887e8e124fc3a388658f432d096b84d4d010000006c4930460221008dff823bf0cca37e0326a257b9bd682aed1236619023692b605ce3d79b7f81be022100e0287c076158cdffd32092aa980ed813a72a7b6265aa7973e412b8a8bde27e42012103f2b6d0e64e6e1a534268759e9f5f33f980729fc2d773d9f793bb56ed021de17bffffffff965753c7acb83bd9ad03f06859024de951278be1fec6df40609cf47d7a062e99010000006b48304502203d46ccafb9a9701f6d90d74196ce56a46e916d085a7f203e7dbc47453ecfbc36022100f0db7eba8d09f8bd8f2786e369c0953c7d9bfbcc3814a432f5bece38762cad8c012103f2b6d0e64e6e1a534268759e9f5f33f980729fc2d773d9f793bb56ed021de17bffffffff0100ba1dd2050000001976a9142eeab1c7064f91d10f8d560c41934478617fc2e388ac00000000010000000124a4ae22590bde5a952c135e2d4ca4c528b557e962a83103321b439a026307aa000000006a4730440220696853d5d8cf33c84cd01397697d9c84e5cacc8674190511a9c5858d7d8b670f022076ac49ea4a2c9f2b758be016a9d30e427412e506c3a9e3072390c05890a8ba83012103e92d826848aba2937b6e869cdc6baaa6d90fcab3bf917977bf9e637911e137c0ffffffff02803cd9fd0c0000001976a91446ecf92d37e1fe491ef456e5ad6d181ec93db1cc88ac00a3e111000000001976a9149e985098403f93cf04f885138407998f8a9aa3b188ac000000000100000001b5c21f72db3478406c757cd151b4ed3eb24adb8b8e3e79baec092da447adcdc0000000006c493046022100b4146877f982b6f17008efcf85da450c00716ae7d02875a4cd3e717f5f0b238b022100a4f9d8cfe86bc4216fd7e7e30f5695fd6eb2da44e479ef2043d0c10b51118cb401210328e8180749a04861a86621ba6c124e0e782010b09548a20ffc6ffb3a14d22d99ffffffff0260aaa932000000001976a91439f5a188cf5b918641c0b60d875183b0b19820ae88ac807c814a000000001976a9147d0978563830c9d3ff5b933d9483dc3d0e471aea88ac0000000001000000019e38404e10158171a4a07935e43cfc8f766c309147503824563f4a52978bcf2c000000006b4830450220437aa278dcdc81d42ca72410f8b3795befe14feffd3ac082a3b95e0a47b16bf5022100b404cb986d877cd2f01058ae2bb21e1a2900b255fbaf67dbf0a5ba2046fd4964012103c186eb747f3ef500ac583a377cef40c4ed7f11f416ee39217180703b40a9860affffffff02a0c83e71000000001976a91448cfbdda2f557c1bfd2b265972ba719e34f1797688ac0046c323000000001976a914ed77d6f058c2b9dcef7c6e50e407f351660125b888ac000000000100000001042437136e0eeb85a9dee443c38497128f905ca36de2123db72a4fbfdc4107f6000000006c49304602210092970458417035018eba7501e8aae6a47cc8416189bc871fe72e2ca053a3b23c022100b4c01957775f5d31fd7588a8845ab7a06a47043c3ae526df5b176a6c689ebeb201210376db3a154451e8d79f6494a71146671c4d52d922303d8669166c66689e94a7b1ffffffff0260462705000000001976a91464c4f46e24e79499de57ecc7af99deb0fe310cc988ac404b4c00000000001976a914729dd2b76c23965e99aca2d3eeef2a20634d7dad88ac00000000010000000110bedb5aa3949f51a25e20d3aaa5ef8a00afce5071c095c7373d5cae3ad99932000000006c49304602210086cdc899e97791029b354a16d324725d56ca4517cfb24263b523daaa999df93502210093d6cc5ce21d9e5f6703c16afcee6330b650da1583d992c2080e8d8467d53344012102332b64cd16da186de2b29810dcf79a57087f0f23e8342cf5713f4cc8debcc375ffffffff0230153a00c60500001976a9142f0c4c111193d0ea01b030800a9df86e3ebaa5e088ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac00000000010000000131f055013aea97fc975f7ee0bfe0d025df774347fa8b98e756a4df67e6b657f3000000006c49304602210092970b73993b30ea48e70d1fff9e064a1e479448986c06cf5e0b9c87a0a25bc3022100a65788a7ebdc514c0c3718a58728653d17695b538f8d8b1d6b69fbf1aba57f88012102a0d1eb79b096679fef7a8940116be82e7a6122bcebd5d03b8fcbb328f55fd5bfffffffff0220249fc4c50500001976a914ecbdcd308f96b19558f7f9233c34a14cf302cab888ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac000000000100000001d22241436cf8d2fa53b00c803c3850a7af1ea927bed6931a7255046f7689f14f000000006b48304502200693cdfd89da04c581c79e344c63083c5feb99b5f4b5f9f642b400082d4c08b6022100c4d4f5dab1557ae6e4c8fc6caed981c791672c135a66fe58e05b439e15c1c93901210379d16e96a028dcc87ca7aa40a82f0db51ad42aa9a98af838c7eb1f70365ed0f0ffffffff0210330489c50500001976a9148541bca7ef2a2bd91b9238ff6c5db4f148c93da188ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac000000000100000001bcdd3e037c62ac749284fb25369a946d603507119c496cacf2c9c42e4e166d44000000006b483045022100dc9f459eac83368b89e1b84aa27bf58df0f389c110871c762173b4e554ede44e022010cfb1ae8672068cc6692dc311342b9bcdcb2e602f5d23eeb45f286a755759af012102ed7ff5eb06ffb514c433174e923478c686f291613b770fb210a2b5688e8c6d58ffffffff020042694dc50500001976a9146e91a2d66c9102f56a50943b8cb66cb26d882b8a88ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac0000000001000000011f2d0e43dd236468567d895ce1afaa6356b928f501288fd07fe1a2d8ebed89c4000000006a473044022075a8ed829cbb52e551c07b780caf02eb3e1fb0cf44798fcac04e22fc06a065f1022072e2f2197b6bd2eb9e7d1c052c676415cef097f095f4414f1b2aed00c95b72de01210205eb52ad77b19e822843da1b38d4c547820df2b810475f32377de895c934fe71ffffffff02f050ce11c50500001976a914e7b718bc145518ddaba2e73b88f180482652eecc88ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac000000000100000001df8174f0ba9c8ea5ee7498bb128243799c1694ed1ed424a37d8956a3f1a7423f000000006a47304402201822fec3f73ec1c7f06514ca6fb03a92c7e278af1f1651bcf28acd100d4c9be1022013030058a09501f5aec10c7df1570941aa86de6eb218604369d0c67b31ebd508012102b668225f5c8bcb8eb5e1432a8ce45f34a35d5fc1f1a0b3d437913ac67b6dac79ffffffff02e05f33d6c40500001976a914a1bf785c66cec98a6689e48abc4fe258e9c1ec4988ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac0000000001000000011b7a307a9425cb399552e7a70a990c1a21e2c9ebbafc44686711b10fdd8fc862000000006b48304502207d548f050e74bcfce86fa98dde1f4ecf74656f8d4ef210b15cfdd5ae4b5915fd022100cf4bd0cdbdf464af75d89570d6b531f5be56c35440099c24a1934724a4a5d264012103b64b8467494aa9213ecd935e38f87292a4cb0f6afc60734c7a1ff53f4c3ab064ffffffff02d06e989ac40500001976a9142b3664d465f2d4ad3d0210cb6c6ea117f926a2f588ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac0000000001000000017b52c9f306c225bddf912f334aec6a20eb19d435c53963824919bc15e3472c52000000006b483045022010399589953d4bb678deb693944ee94865b4b607543677c13621d72471d5d230022100972dba47f9249644c431eb3c1b6ba17d95e4539ce57b9df77d300d4c12b7e1d5012103f847c95ffa4032b0bab3f0ae7efbbdd5bd4012c7a17e1ac56f264820e59b677effffffff02c07dfd5ec40500001976a914f65b071ecea3c83add2b3037c865c70e38a7912888ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac0000000001000000011e69966fd292eee6a31401949aeff9158b0f63a16b2b2ddfcb347e6e3478ea18000000006c493046022100f09116760aa200f3af950dba88deff541cdf51627395efab5a08cb11b7e85ec7022100d24eb7f57aad4ecfecf1ce7de10eed45ede526db56c936ed8fcfb333ec239a5001210340cb97986837902f57e1d17c294ed479b13e4f9acab43a7e99c766aec0a78785ffffffff02b08c6223c40500001976a91441fbacea308be181e959b17900466e94326dba1e88ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac0000000001000000013c5f22911718f1af9391421dc0554827b3a75794c8519afcbc879b1bbd0fdc43000000006c493046022100c3367087539c68203572c0e78bf2caa2b9118ca2cbb964be09e00de227472ef8022100bd88800c3dc18147be6ccbb3ab6f61b1eb3d8a75a6a96e979cdc31a30e0577a20121021a8bccf4a5a09f090b2ebec19da3a3775f676a00146058d1db35f8514360c3f2ffffffff02a09bc7e7c30500001976a91480fa3a5f601d4c220ea8440b4100d313aae8089988ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac00000000010000000183a3b4562043d25f83aa82ef46becaa4669886c6b59c5291b5b6e5dbaadf8cd7000000006c4930460221009a92d2ce672a5a6d0f111ed44c7164d9e99847774a7bb15c815a71c54d7dd03d022100e41a327ffac7ea6eb1560757c6d3d231fe4ae1f8fe1de212ead914dbeefdba60012102116911dcbe5edae3096c2fce4cf6b8d09b4ec101d0d1cb78a2b13e3c062805a6ffffffff0290aa2cacc30500001976a9143316e2771081711515aeadf9a913b8d447332f7d88ac00ca9a3b000000001976a9149b733b138e7490b12e49a5ad0366017b2eb9a13a88ac0000000001000000019e576fdea1c7ef02650006c3efce639194445af2f15849afcc00397a9c7581d1000000006c493046022100fd1ca6d88bfab4db13da2a43a43cc443427ff4fb402acd3d7fb870a200e1353c022100973c790aa1278f762e8353154463fbff6772d158f9d3dda3bf25132193288436012102b1b1220e03a72f0661793ffbfb7248c384f1537d4f7773e4434df0ef6845c766ffffffff0280b99170c30500001976a91465e20319638b6434f54a4884cda229a1c5b4190888ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac000000000100000001bf954ea22472f1bf12551c633d4453b32d1ccd63812571784c85880123b91086000000006b48304502205bc5f0d974b840394a4a4a435e31ed2f1c28f79ccb457997547dc6ea7219213a0221009bfce30788989c414e5a5435eac8d15e8c8ee23b4aab56ffac8071e0a53e6712012102727b42851e28511be1a4d437f54ebbb7a39015a3b8a149a0abb79a87ddef8d51ffffffff0270c8f634c30500001976a9146ec7fb901f3760f940ccd9c84d1c8687fc6e697888ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac000000000100000001b8e55a0e23175690f35f03b3bd84b6dc0827c927d468d5f12221a3bea6402fe8000000006b483045022100d647a8d254c9fc22b0d67abe4730d1352d419d389c04b47ed54c93380a68c0c002205de4b2042694cbf05378df8904ea167254b5abc277c28182ffcb6b1646efdcc7012102f9b514f02f101204e15d6fa2fab5c639fe5b15acf5bfd952e27556d9a450114effffffff0260d75bf9c20500001976a91407dcaac3c755dce057ddcb220ada5c4ece109ea888ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac000000000100000001f93929fb50227ab76d6426e43f9f62c3440cd1fb38740ec646c3f827c1e60ac5000000006c493046022100ff86f3daebd61d36f4f39af4d992b5b8ca8f742844b6e3f191fc7c356c8556de0221009c52617c93c89e8671fcffa0e65691fda5692cb4c767b985a741650512a4d5820121030556e8276a7a9727e97a7e1dfde0c14ccdf9a2fdf7a93894e1a613f0808b095bffffffff0250e6c0bdc20500001976a914ad0f2b2029b217a0a51ec590246247c977036de988ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac00000000010000000107d96abc8d59375ca6c22d0c01f213d4ad7d44e5a48b1825afec9438c0025258000000006a473044022078e20eaaf174d7298e7bd616cb0ef53c303d13f4422f08deab303bfbb2d3fa15022041b5f1f2ea87b4420e18c7d039d3b4bf0ebd6a7d702d619ff297ae9eb7b28ab60121024d661e7890741f1f58916c2edccff019ff2a9c0a16ecacf9f30c74367a418122ffffffff0240f52582c20500001976a914d82203c94aec145188eb07019be70eae2aea82e988ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac000000000100000001eed5f4238934bc55af7f7f4fbb4d3ee2e4dd441958ad4d722f5ec6e8fd66d78b000000006b483045022072c5bb83aa8244da25617bdc2144a8477409ac4988baa6656ccde8547672701a022100ef98d40df8a13f02ed4489beb992e5d9caa2c410bbb30bc88dba400f6c336cb8012103eb7690e9fa970dfb49212f9a2ca18637d094127f1adf98121b307313bb9eba75ffffffff0230048b46c20500001976a91493d0e03ead630d21e5cbd7184976b23c37344ab588ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac0000000001000000019f1397a6e2eb1467bdccb5efce802b1fb283f6d88d509e568181089156a22f2d000000006c49304602210083afa9c8d81c6e8c4a022099cd0a10661afebbcd5110ca5c5556f34abc4d8ec0022100b7f0ba84e500be4c5176509cd8b6b28dc74af5556131fb281dae6367bbb44b1f01210288551b59ecdf56b7f796337dfd30fc3c297ad7cb4aa88cb57fe3c0d50e57ecd5ffffffff022013f00ac20500001976a9145bc269f07596ad04d819df92bf6d63cd37eaf52a88ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac0000000001000000014a1f49e3e9b03a8c217b6286182cc49089a6266cda617d17ec2b60fc2f625459000000006a4730440220401bef29c92effbd0abdf5322ef2bee0fc5a5a57fbc6d9ef9c6fe4f9f8d7ba1e0220175af27f7cecdcea9227371cc909ccbf9d8b7854f1af274bcf873368c91846160121031c4d9c1e0c1ef1d42f52b43dd3ef2ba05b32cb101e8fe49a4c4fdc16cf499775ffffffff02102255cfc10500001976a914596b261f24d0da450d09e8cfa52f6241b124774a88ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac0000000001000000013ee419c3cb56d13e4c1435258c411c814da3292752049fcdf14d3353bc34b601000000006b483045022100e38add24d4665b2c653c986d9c9983f53fdb619ca3b49fe589fb5f5faaeed9dd022025aec0c5d9bfb91bdff10cafc6023424a66fb228b596e682848cc7414dcaa638012102e1a7d968217bb3bff60bd83744d81d0bd8fafeb5affbb053eaa5282e51db00fbffffffff020031ba93c10500001976a914cb61fc6fd6f13b08daccccf104b6a9af8fc17abc88ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac000000000100000001499672f26942cb85147943f256a833b290c0e1af03af24d8b2825426c8a629c4000000006a4730440220754a90a56d9b6620e4dffad03da32eb080ddc2df96fb12aa1158bfc47daadffe02207d03268e21cee0aac3305253adfc9125aeead55ff78480c7b4f82d10581bda8d01210232e5eed4176b55d12d948fd2c219f173d39d60eb21dc0529053f326d06eb71a7ffffffff02f03f1f58c10500001976a91448ff58908d94d7e251cebe597dcaeca71b95fcb888ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac000000000100000001409974412bd9de40d6c260af71b50e275051f374f81ea947fbb616b93192e7db000000006b48304502202d36320b6dfb5ffd40e684fbfbd1f08122b545714ae2cf4e84ad3fc6f1c289e0022100a0c6eab031a476acd2a135796855c31bc78be6c424ed397e002c2dcb616a695b012103b7ffadd57293efee2737ea486ccc37256cfa411904f522691e64907bf9004faeffffffff02e04e841cc10500001976a914c5c0b9a41acefb029df536c563a43c3a1732424f88ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac0000000001000000017740035931007aebb62e8bf4644b8905341243866e2b055795d5dfa89364391c000000006a473044022062a9948655914b7bdd1aa9138e5748568671d0a05bd4c756fbb5c839bbaaf5d202202c4538af7daaee3b04c674a2d8002fcdcc9e303341d2f8cbecaf7b5863c4407a012103395a37aef3b029bda5db189a5b1339df355eaf77017b9d41d851c8a2c3613dbeffffffff02d05de9e0c00500001976a9146fd088a995c8f1acb1991a059bbad1ec86583b6888ac00ca9a3b000000001976a9141e0f7f778726d1ea820e4127f5cb949ea330680088ac00000000 \ No newline at end of file diff --git a/bchain/coins/dogecoin/testdata/block_dump.2264125 b/bchain/coins/dogecoin/testdata/block_dump.2264125 new file mode 100644 index 00000000..ccd33f8a --- /dev/null +++ b/bchain/coins/dogecoin/testdata/block_dump.2264125 @@ -0,0 +1 @@ +030162008d1154d17d87ae969b9a6ad754a29df3f3354386e2ab187f67184f5bd712ae5363b4886e7f9ce876853f353f7ff3d027341a76de4154d3ee076f829a73b1154ec036245b243b041a0000000001000000010000000000000000000000000000000000000000000000000000000000000000ffffffff640360f9152cfabe6d6d1c6847a6cbe53dca3a65cd1f21bf8221b92198c3838db88ff8df3c762c8d50c108000000f09f9886154d696e6564206279206131353838383233343232300000000000000000000000000000000000000000000000000000000000650000000200342a95000000001976a914aa3750aa18b8a0f3f0590731e1fab934856680cf88ac00000000000000002f6a24aa21a9ede149980ba0b45da674bd2f51e9d507257bdbf505f8b7ce463ff94f3715bd460b08000000000000000061e7303e7b7ff6e14d9fa683c833f1cbc51b64b9544210fc5324b03b100000000000000006d67a6526913f11d6e6b3a5fe83759f450d5a16f8725be11e380181d26a962a90dcbe3e3b682e4a4a94651b839fb7a3260e3e65fe7a3b1c93817cc057babc373c430a5aa57dfc45d7c6ac0a8ecb8facb031deb5eeb1ca8821508c32595900bc9d16f7f8cebacd3caf7edacafe8872ba3967af232dc17eb4538dee12192f1e3c0238b9a03dce250bbcde9998cdcbd5a6969f97b82d9fa6b8f92cd0dabb89cf2a0fe8ef0ca4de645f903d629413b38fb2b3ca3aac2e7a482bfbacb1e326928d864f000000000301000000000000000000000000000000000000000000000000000000000000004bd17ef3ab1e19336a217f754ef38b3e96b9da39c79bfce6b51e9d42ce34bbd1e140f5cb3bd15598686e7bc18efdd6c9920fb63bb6796a7e7882b220a6766dc100000000000000203abcc448d6e94732635a5ace72c17b627fc829974067434b89ba1d1ec8b1a93b26ba2bcc6e0987b857d299615ed5f0ddb0a03d07f42af30c4a6d667688f0ffe1f736245b4e86011aa0c533921901000000010000000000000000000000000000000000000000000000000000000000000000ffffffff35033d8c220fe4b883e5bda9e7a59ee4bb99e9b1bc205b323031382d30362d31355432313a35393a32392e3230303331393535325a5dffffffff013e68f952e900000023210214a5f15a73686b64cf27405e018e2f06e0501b52f4ff98282badd9d6948fb57dac000000000100000003fa2eb9a646593374ca5b855b008b6bd95ae090ccaf20307695aee1961020ec750f0000006b483045022100f6dec2f5294b88a6a53940a9828765c111c91335679e9d61521518a78b9a02c502205383e4399c68c04a04f05a68ee0a8464cc8db72f72ad3fb14835b61ec48455c50121036e292c23237d103a4be3fc54df14a905fe1b77044ed5baa13a46a4ab9e418e2dfefffffff8e59be52783681c7893d0aff108f6408ab90de5df0d1ff37574406ad7260372000000006a473044022043b5c0b33bd06fa0df2f62d58948d245095baa52b4eea0b5668951af796dac6602203ce034905382621021dd790e110f91515d374015910b1cc84f4f77500640ec4c012103b9d8c5415aa21ff07e6a50eca171c37c40f972626378daa473f7edc7347eccd0feffffff9c73136dda7533655024b68bfad836f3146a393c7a599f94abe1b95ab60a8d0a5b0100006a473044022002d72753134781be5798628e2467edca5b723c826d165ba90526e3f295b5824702203cbb74f8fc2b12b9a4a41063758609e923cf30d3c573cc9ca2278f9c582d83b001210333982edad03ce0d636578aeb8d86d8c270df288b62b5f55d7ba5c3590c70c6edfeffffff0600ac23fc060000001976a9143335bbafce0ce576f710fecb1e9e0d7cbb6f897388ac24540f00000000001976a914dcb90715965bbb59c1b1387f219f7cef2f2d375188ac00e3826d090000001976a914422bef9f6000976bf68836fe3d9afa63b338fc6e88ac6091d4deec0400001976a914a320fff6223f1bfc80b766f65ebe17f0953aa50988ac3b22bf1d0200000017a91471b409015d4bd38b6063f62ba31ca7beb7e4ea5f87efa9f64f0200000017a914f6d20e30a2e2dd7ad6614e8e89bca3ddd7cb915b872e8c22000100000006391a2cb1d22b46f73a0f2a304378fba0aa5112ca9a02a9a22b3a051b5f61c300000000006a47304402204d944268f4ea8be4d99dba1887f8dd331fbee3fc2e8d3856b9af94124513ce7602204cf22c3fba072253b44f441a4ec0577169be9ce934909f9f7bb9cd53897fe19f012102d9c31a7b69eea72df29e8d30d8503a661fd8d83609688f2bb48f5b967c5d9c5bffffffff6e198ad9ceb90a5dfe3393f13dd854e484f752e1ca4bbc0c02416e1303c9e736010000006b483045022100d8535a54e87c7b6f8730f9bd8aff10f31e0135f8c12141adace312389cb44ae8022075e25c1c48b3d512879179c7354456327fcbd4f338b6dea69f9642f32b8bbbb2012102f8f75877cb0dbb5d9b47610b24665e27a57a90de3b88412b696ffeca8c4535c3ffffffff7a1b604f0b96fcc60e33a52a3dbf1016c6e99e481aa5ae19d9f339cd9d497281010000006b483045022100f92811ab19890b1ac01fcb0f84a4b77808af1542ae3e36b3de3e5bdc9e2b39b702200989fc7516f4535a7ee102eac256d544b8a03f8c06ed738ea9788d95f9e167870121035729c859d42354513906acb0ab6468489ed5fa98129c02b4f554124fc313717affffffffaa4a53fc5327d788c1d604b3be43af9cd8ee580872d4e672a8bf942fb48fb87a020000006b483045022100e6298687eb6aa4f6886a0673cf027d131ee0f979e13df40a99a2a361b5786de80220719f9e2bb2af0ede78f8b4b5e17efeefa89a8f2bf62133561760a806591075fb0121037fdfcaaec2a380afbaeb92af646e77edcd2b5a396d370662c08a8aa0e149b3aeffffffffd40e6e4b60b4140b750bfcd71a7edc8668564d6d9e4b2b0b5a7ae534bec9c6a5000000006b4830450221008c42a2f241d29b29a54a97ee2c797e0407dc78957692683cb12ff1fa5e94cbc7022059c8eb69b6391eebbce736bddd6a84c004678aa7d3b3e330acebd9d8b9fadd5601210291218829f37d610b40690ef5d8b527cc80180066fbfc5bb43edbc85035ee611effffffffdbcf92ece4f31f7e516098800c4ee91991fd64d7c06c1e270ce2ae80a001c3c0010000006a473044022033a21a54cbd8061bd32eebea27155914c50c3a0c1143b84c732fb8306e249a5902202c393ed4a1aaeba796ddbac720e31074131da7f2cf63fff37acc8292edef4b14012102cb0b8853a41bfee68e371e32d7f0ce4fd05df44b45a87724aa62ce337459668cffffffff0253546c2bf90400001976a914b59dcb46eaf092babb20731cd4a9eb474c7ca92888ac58ea6208780900001976a91427fd67d6ea90864ff10f6ed784f06a6739f8fdde88ac0000000001000000018d758b15458c9e5b3a7af3728f09f47cdbfa04b24fcd5d68c663e23017bd7f2201000000d90047304402200d9cec85cc49a2196ccb7365da85c3bd58e9c89f894f3e92cf4ae84051e3a4970220792acccdbba9fb7d50832e8adf7da203548ee07eb39588fe1805c955d5e60e4301473044022075768ae16f497d5a1f19709ab6acec8257940e060c11e37183f5b8a1f87da66002202205f810fc04175d5b855e42e807f88bff1e4c77075d7acbb5761cc5da7459a80147522102554394dd0d90cb527a85e588f5d1a4e3aafae6abffcb499e7826a3e96e356caa210265d9c11a740848060f0e6c97c1a13904dd49341d707e77e39635f6c49317ad5852aeffffffff020010a5d4e80000001976a914deaa08833580a0c6e7da35dd3400fa379e90af6a88ac404f24b33306000017a91434ab9241b4dc3088635eb75ee1d719c606f7575887000000000100000001264edeeeb2b28b587597f892200c272672219dcc18176de0b50f3afc6d560885000000006b483045022100f6249d470d63b43a7c1bee56b2a1dfbaa1cd19e43261f65f97acfb0170f00dd20220593dc3a42866358a5fb3deed96a416047e5aa4a1274e9b810affff08de1488820121023679d737f5cd83782872ddcecee41510517fcffaa6c4390132a67c7276cdb428feffffff02b0f46cba010000001976a9144825f122855b70a11632723a4e48f13a49d17afd88ac00c03e1b465900001976a914678d55b9d7b2d70c37d54741958c0ae1bc6c242188ac318c22000100000001a8527ffb83883440b66b0d2d1d1bc404f6d25c5b137426dcdd4a4a0d4a4527ab000000006b483045022100da2868bbe43c081c6ccd4a9a3cc847618cac2a724b319dfd5beb5216ecfc5186022077ef0c6946970d258836781a19a360c369491fb9268d4abfc27978da0dcfa429012103b00a51fb65488ce2e982b0413172453a66edc4ae7d3b9ad78e660ccfb5c47434feffffff0240029f7aeb5800001976a9145820f370991bb629c872196841c1679a8e5a88bd88ac30fea91c010000001976a914c17a426d939c3b2f18c4fe23b430cf5efcfaa43388ac318c22000100000001d99f30e0b003a71238b67f07fb585046ad7fd2ec69727850a11184a2eab82c80000000006a47304402207f505d1c2ecfdbf555cbc3629c3308cca5b94ff3f92a62484be776fb2b1a19db022007c6894fee87d7abab290a5c40cf78cf3ae74ff76e872c2588363ba88d7e5462012102c505658bc1f19bb64a98848ed6a0c8fd54c6f2c42f333a78c1ec3b8a4442dacefeffffff02d060b71b010000001976a9146dc939409253dc64c5d157b936992799525c136b88acd070132ede5800001976a914366553b08f5f679648c379a4fa03947649fa148788ac318c22000100000002c7fa34c33ab10d9e0fd586e1e2dc78b434b4e09af0206dc708cd497a1d9ff4edf20000008b483045022100d640b156974cea1e165fa3fe3d00b155186d6397ca8d7ea91f5f700d3dc48b4a02207f2061b5383e59a673fae833177cb2290615ed7f6f6b2e65202780121a954fed014104176cca38637730cf73475803193d68f47b2857ec752fce0977cedfd77045494b5865d8b346aea50baf61b9e728c9ea06ea4af90382ef5938d666a13348defb4effffffff85da9b795f0957f805b6d68f4e859f21306d433731b5c4866f846b2b7bd81037010000008b483045022100aacec083994cfcd3b88d1603c3c874a37c48e51927211c2cf15fdb5d0d53c7750220238748f00ff8987fa6e443a0aae48d1b5ad410e86699d8efda78bd7c348abcdb014104176cca38637730cf73475803193d68f47b2857ec752fce0977cedfd77045494b5865d8b346aea50baf61b9e728c9ea06ea4af90382ef5938d666a13348defb4effffffff0200f8d4a7170000001976a9143f70a10786cfa2e4c53d0cd990b31ec4ca29049d88ac401b14818c0000001976a914bfd37f1f06ad1728b8ab28a0e680cab4f365809188ac000000000100000004c2b9f3e4bca3ece767d976e546a9a20c7665b9db7060d0579b3e657242a74fc7880000008b483045022100e1ec13518e42ccdc1b940b21e1aab3eed93079823b6756e910cf68b1d9ed3e16022009e613b9309b22deadbcf5493b9e64b083f02e9b737714fa4f6e2b84abaca6a00141040c0bffb8a6e7c9310198cd392c8290219f25dba82c25dc43cd05debee055dbaccd5ac6ef7639debf8042b4908ee9762393800120cdd16ce20d330220890264deffffffff6aa2222e7520e49fc2c618cfc351680eb41282e229dc039851d1c97721f9fb092f0000008b483045022100e5f3ee1d4b0f6cab214497c2f5119435b613194eb9570bab36356b554ad89361022068d6675868537cde27a915ef87de6eda383a640b6d12ed66b98182f02209a89c0141040c0bffb8a6e7c9310198cd392c8290219f25dba82c25dc43cd05debee055dbaccd5ac6ef7639debf8042b4908ee9762393800120cdd16ce20d330220890264deffffffff5b4c4bfeb1fac6a183306ddae890bbfdaf12e138203bd9da262274d5d00953b58d0000008b483045022100cf34676c863587cfb277b6294d8cc938716eb2b7549bee250790cb202acb899802200716fc221aa02c3d00a66de8070eda08e0f9c91a4e61ce668c6a814144edb1260141040c0bffb8a6e7c9310198cd392c8290219f25dba82c25dc43cd05debee055dbaccd5ac6ef7639debf8042b4908ee9762393800120cdd16ce20d330220890264deffffffff312fed12cb7006fc907c701b359dc222750930824b07135266268b354e21eec6000000008b4830450221008f7188feda3f1f29aba5184714e46f58912076dcef75994d134c781401a188a80220618b6fa55e28a33bd44598433e692591d2d73cead0c71bb2105fcd6121bcb0e20141040c0bffb8a6e7c9310198cd392c8290219f25dba82c25dc43cd05debee055dbaccd5ac6ef7639debf8042b4908ee9762393800120cdd16ce20d330220890264deffffffff02009057bbf70000001976a914a076ec90b493e8667e4876f58cecf1d9ae89d73088ac8022160b000000001976a9140a845a4457df512d84e60a6ce683e5950516553c88ac0000000001000000012ad1a5de60a2ff2c81c17744126d2edacd6345917fe382b17416d2c1799cc6f5010000006b483045022100b0955a6a974e2b1062ee6088bb59cec6e54ac0a90e42f348e7807cf29ec7ef400220016ccddac0e078c6abf6ccd2d7560ae502ac4589a6dde4a284b7b5d26daf2d7e0121032507f1a4ab74f49c1e2289b1d546b5f171ae5f74bcd715a12a188e8afd7aa466feffffff02c0a3b6f5490000001976a91482856114932910f0037fd6b61744e88116c8cac888ac308813c24e5500001976a914cbbf91a80280b6485364b52d3f7b9f60cb441bc888ac318c22000100000001437a898ce9725b491264370ff81e8ecf59a31af11f476313f818e5ba624cb9c8010000006b483045022100cdc90398ba39717e7a6a8ebb6ebeff2e3e551e61a29f06b83e5da6b845f6f8fc02200a58095c9e83a444ebbc489f3feb21f550c22f170a8b457a517042c1b789d114012102f5af0161883e2a90ef313f74c41854489de8c5f64a3a2cfa473dad3db68f1d70feffffff02a0eebc24080000001976a9144825f122855b70a11632723a4e48f13a49d17afd88ac60c818aad85400001976a9143deb6001f0c38f62ba336d2edff1bd4dfef9bffd88ac318c22000100000001a6cd21e17c3cdd79e4707a002e44936d132015c1bd9f9baaf7dab11bf9d38e97000000006b483045022100a85ef591b82b457481dfd337d11cd91f9b89a0fed3a5c08b382cd6622080c34502201dc27e5044d45c485a07bc04eab96c8a02e340e35db5f9c2a13f10be52dcf0ca0121032a6e690705ce6ad06a57325f4ddbf8a72824e4057fd1203587eaa778475f4dccfeffffff02e0fc056aae5400001976a9141f6e0668f4b82c19ee16373db07c7f36ba34173f88ac00943577000000001976a91482856114932910f0037fd6b61744e88116c8cac888ac318c2200010000000160eb8bd8fe754fc82910fc021be7ccbab9e717377d14ceb54f15ecd277defbbe000000006b483045022100e1152a424b24dface4685644f6f23c59f47ca038145ee48aecf19a88cbd71b8b022034fbdaf80780ed06c669f5d8784368b78aca886e57793bb58a89b954c0db5eb60121022d675bd3dd03030e969a05e2a9fd13fa3d3316d530aa434dae9dffc0bb340678feffffff0200fab459010000001976a914b748e0b3fa96b7eeeb30c1ee4cbd10fb94af7fcf88acc0d59228ec4e00001976a914eed57e0179a1154811a959c1a7c39f6f2d0ba8b888ac318c22000100000001c7fa34c33ab10d9e0fd586e1e2dc78b434b4e09af0206dc708cd497a1d9ff4edef0000006a4730440220632df279a1f2ff32924c57b5acf54a4c7cbe2b21139d1ccd14d0b3da37f2b57302205933cba0e1e252a12920e8a89594f8e860ac539fcfe3e78e7e44e13cd35e0e1f012103f258dba590dd8bb380cf3f9275a1407a8603d74560fcff1868d8f21a3c24ffbaffffffff0200c96c4e170000001976a91494dab48a15b230dbf99fe801680e2386ed436bf588ac20e70f9e090000001976a914d1cc665d203e7f1c9d83c88d68dae179966c299088ac000000000100000001567dc7787d2819cfc065481205e3af3143a20ea63a7640f5afbc2eac6020d020000000006b483045022100e847278dfba091c1f73f1faf049740bad05a63cc61f25ba367ec95ce24c5a15f022022b53b26ca427b10805b20dcbc36dcd3d8c8c2ff7833aaa27dcf89b51e8157d3012103a713845161c6ec474a23d836a3c6234be6d09a01ce0509918c96c3ceffc45ee5feffffff02a0414fafa45700001976a9148dd2e0f062c4b0ff49009b6728be161e70b7a22a88ac40806736010000001976a914715505e74bdf3b299adf9f06298ee7cfbaa422ae88ac328c2200010000000184c592ead40c2cb94ede620704843b059e9c0f7dcbfada8c51bc7175bba68a6a000000006a47304402207dff76498f3d970f980e8e7d619d5964d7e3eee7ef6ed16fe75601682176a97b02205ba61caa448573721ef7566ad1907b8aaac51a89d0050dab838483121f55bbbb0121031a43e9b25b5a3ba593300bc3fef6708695b64bd024fe15a09c0444c9272bc7feffffffff0200d0ed902e0000001976a914c7453a2658922be99e6849a418bfee94a3c4a58288ac0095450cb40000001976a914b3f5b3aa6c742ae3203e4c51dc8a58c31c3577df88ac000000000100000001cc6d486a691bb4e6f8fbee3e72e4f2922ccdd2712d9952ebe706d4cc57ecacd6010000006a473044022007d362e5b2484f6cf70312887a5ec0989e78fd3b3da2655ea50d0d3a4570951302200be16c53db2c00676b66a0ce1a2578f3061ccff91d13def8fda9783a7eb0712a012103137a1a05dbe2ff735e1d9ae3dd1d6ff800ec47fc63a85bd5c49e2187d4b7612ffeffffff02c04cbc06990000001976a9146ee6a63258e38ce9e4f22c837bbbeb6cf6073a8088acc0034687281400001976a914e54b61c84d12c88b9c8a145720103994469f411588ac328c22000100000001fbe9833af7adcc9e201e9458012b688eea372de341bb9f5ff89412b6b821d63a220000008a47304402200bf5e07f0575bc46e4b8751f2f31bda54cfea49959c9599ce0563dd73eafbebc022049e5a7bfa49031308998cee30971af8291e6b9ed6affff4ae4e3fc5a31f01b6c014104549a38e44b756a013f458d588dcab03a25f7e2b0ae6d1d2a90129bb9db100b57b8485620db08eb4cff7aca816a690bc8c6b992ca6864f41d658fbbf81188c4bfffffffff0100b26ea2050000001976a9147eef222258fb82905ae3ea84f6f3c6b49bbdc24088ac000000000100000001e481a8e6ec7bdf0a2fa8e8fef7bb577b7497edfe65f2ed64c108fa780a5453c0000000006b48304502210083b555af67efa40d2714ceecc4b4486d5e88f963069081bd9864cb6b70854f7d02205566b50ca9d9cd47f927719177fd13842331774c789893b78a2adf86f9527b5c0121030de813528c078ac755ac322ed76e9329a413a0a74b77f7dcdfdb5fecbc2f20a1ffffffff02004eb816240000001976a91494b38be4d05c5b463fd13a11561edd1da1fff10688ac00854bc80c0000001976a9144fef9f0daf21451fcb6db6c53e1a676642cff67a88ac000000000100000001395c571d03bc7587bb064eda25c86c54f290f89a0a981900ac16ef56ef54e1c7000000006b4830450221008169ff15855315a3395c128a2a13ee79553c904c2364efe1de9025865b9fc3e002201cccd8dc66ce34661b020d0fef7e67202eb7c95b3f1547bc80c4ba046242290b01210372929150997d67e659babba075c213dae289df7b1235165d98ded7772dfcadeefeffffff025583a033010000001976a914ef993e165aad9058a1156af72fc1f8c90b8c130988ac5db659332f0000001976a91486af0fa466f296d61f4c891dfc70b30f4b59edea88ac328c22000100000001213377f68c0ddc65b81fd31e8bf632be5225dc9ef3101cc7cfee06e43ac1bbf7010000008b483045022100a6dcd91c2bfab5c80100a42b84093b6eee460fddc43f1a0ca894ab29a609bba80220711398a7cdf2a2a82647fd0f5076a577e8da92533a357d8b4a09ff53c6c3af4b014104090c239e12cbf624b0bccff77c054723083fb79defe95316fe8bba8bb361c6575a09c9b80348a1d28d71ce1443d9b5344e41068506cf214debb8942d1314e23fffffffff0200e87648170000001976a914d23bbfda4b37ef61df19dfe2b1fb3d1bad4db45a88ac000c5838090000001976a91468043fcf9402d5f85d64410ba7640720a40c72cb88ac000000000100000002a3d08715bc8691c675ba26b3b98c2ccaad95c792223e4a754ab5e721db5e8762000000006b48304502210099367b0324d0c5802a40014f914942bb8f2065092051d92b3f0de3ad1c24bcfa02204465bc66b508799ab0fb8a70b66ab2416424d1b2f02af41495867f16eefa86d8012102da0482762dba356b9644c6b239024e2fb0b39362fd74f140832b3a2f7c68a776feffffff57722e75ba9003455b2597408fe883d819e2466a509462b64b3ee97320dcb55d010000006a47304402205fee6082c71fb43921ca316b5c2fa19d27708b8345de4760fd041d3413a1eeff022033b7f6569509b932ccfd56996676a9aa82f5a7c78d439bd168d9a9fb4fe0c784012102fa73eb45220142caffab2040b2c1294e3a80ba98df4dbe9ae6ad458ab359ecfbfeffffff02bce9c310010000001976a914c17a426d939c3b2f18c4fe23b430cf5efcfaa43388ac23a39b00000000001976a914f2f24e4ae8a2dae44925996c089dd2d6127f20b488ac318c22000100000001a11a414a106c15e45b6a43b7bc4258f241fa736c6ecd3c16a799a02f51eb2d71000000006a473044022019597cc8d095f022ba88c9167fd9ecab64520529bbae57d6162944e198c1c63c02200c7babb16578333a0d9d415a290448edee9b38e996e2421f273cf5b2dfa963a50121026b30a121378e5900943a7dca5e907872ab660b1e666905c83b4af2b258c06d2dfeffffff02c63f966c010000001976a91462acfcbdb4577f0bab408253aeb800293a60c5d988ac0471d69b000000001976a9144825f122855b70a11632723a4e48f13a49d17afd88ac328c220001000000014e15d364cd601ed0ee24b37e2b19391ff68ec33ccf07d814945e3af022fb387a010000006b483045022100944f8595c2a414c425056e199db9b852be0678c9b3233ab28d3eb37cabb9b99b02206d10ef82d3ba5198ff9d4c6934fc553df6c0132438c4b7d69927c00490eeb5b1012103eb0726deeae483846e0eff4a48d5156b4a1cfe92cbcf750b706079bfa6066653feffffff02c0acf419020000001976a91411a9c729187f0e2a3a77e6e4484fbcb2126251c588ac00e1f505000000001976a9146e911aa97af692e8ce30c5ea2df9a78e1ceff0ee88ac328c220001000000013e7220903708bfb0b89c5835e7ed76162d88adbc182ac1c62ffc6374ad2c3dda010000006b483045022100cb956904545ba7bc221e4424e52760b67c74de05d9b4529c862a3a96b2e34b9502204ebb37bb35cc5ef67ff639b05d770a4f5255daa370b3e099251160566c7d80a8012103f9216f9cdea2a27fa8c6868849f4b88ae5859224caf8b19d50a9bb05d37325b8feffffff02804cb942000000001976a91491455265dd37089d871cac20b9b02fe226bd2f1088ac00c2e421000000001976a9147f3a0ea2bdb3640e678df02a4d034ccd6bc2d49c88ac318c2200 \ No newline at end of file diff --git a/bchain/coins/dogecoin/testdata/block_dump.371337 b/bchain/coins/dogecoin/testdata/block_dump.371337 new file mode 100644 index 00000000..b3023bf7 --- /dev/null +++ b/bchain/coins/dogecoin/testdata/block_dump.371337 @@ -0,0 +1 @@ +020162000d6f03470d329026cd1fc720c0609cd378ca8691a117bd1aa46f01fb09b1a8468a15bf6f0b0e83f2e5036684169eafb9406468d4f075c999fb5b2a78fbb827ee41fb11548441361b0000000001000000010000000000000000000000000000000000000000000000000000000000000000ffffffff380345bf09fabe6d6d980ba42120410de0554d42a5b5ee58167bcd86bf7591f429005f24da45fb51cf0800000000000000cdb1f1ff0e000000ffffffff01800c0c2a010000001976a914aa3750aa18b8a0f3f0590731e1fab934856680cf88ac00000000b3e64e02fff596209c498f1b18f798d62f216f11c8462bf3922319000000000003a979a636db2450363972d211aee67b71387a3daaa3051be0fd260c5acd4739cd52a418d29d8a0e56c8714c95a0dc24e1c9624480ec497fe2441941f3fee8f9481a3370c334178415c83d1d0c2deeec727c2330617a47691fc5e79203669312d100000000036fa40307b3a439538195245b0de56a2c1db6ba3a64f8bdd2071d00bc48c841b5e77b98e5c7d6f06f92dec5cf6d61277ecb9a0342406f49f34c51ee8ce4abd678038129485de14238bd1ca12cd2de12ff0e383aee542d90437cd664ce139446a00000000002000000d2ec7dfeb7e8f43fe77aba3368df95ac2088034420402730ee0492a2084217083411b3fc91033bfdeea339bc11b9efc986e161c703e07a9045338c165673f09940fb11548b54021b58cc9ae50601000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0d0389aa050101062f503253482fffffffff010066f33caf050000232102b73438165461b826b30a46078f211aa005d1e7e430b1e0ed461678a5fe516c73ac000000000100000001ef2e86aa5f027e13d7fc1f0bd4a1fc677d698e42850680634ccd1834668ff320010000006b483045022100fcf5dc43afa85978a71e76a9f4c11cd6bf2a7d5677212f9001ad085d420a5d3a022068982e1e53e94fc6007cf8b60ff3919bcaf7f0b70fefb79112cb840777d8c7cf0121022b050b740dd02c1b4e1e7cdbffe6d836d987c9db4c4db734b58526f08942193bffffffff02004e7253000000001976a91435cb1f77e88e96fb3094d84e8d3b7789a092636d88ac00d4b7e8b00700001976a9146ca1f634daa4efc7871abab945c7cefd282b481f88ac0000000001000000010a6c24bbc92fd0ec32bb5b0a051c44eba0c1325f0b24d9523c109f8bb1281f49000000006a4730440220608577619fb3a0b826f09df5663ffbf121c8e0164f43b73d9affe2f9e4576bd0022040782c9a7df0a20afe1a7e3578bf27e1331c862253af21ced4fde5ef1b44b787012103e4f91ad831a87cc532249944bc7138a355f7d0aac25dc4737a8701181ce680a5ffffffff010019813f0d0000001976a91481db1aa49ebc6a71cad96949eb28e22af85eb0bd88ac0000000001000000017b82db0f644ecff378217d9b8dc0de8817eaf85ceefacab23bf344e2e495dca5010000006b483045022100f07ced6bfdbd6cdeb8b2c8fc92b9803f5798754b5b6c454c8f084198bea303f402205616f84d7ec882af9c34a3fd2457ca3fb81ec5a463a963a6e684edee427d4525012102c056b10494520dbd7b37e2e6bb8f72f98d73a609a926901221bfb114fa1d5a80ffffffff02f0501a22000000001976a914ca63ded8b23d0252158a3bdc816747ef89fb438988ac80b65ea1350700001976a914fb26a7c16ace531a8e7bbd925e46c67c3150c1c888ac000000000100000001c9bdba900e1579ebf4e44415fe8b9abec57a763f8c70a30604bea7fbe7c55d42000000006a47304402204ccbeeace0630e72102fdaf0836e41f8f6dcdde6a178f0fbc2d96a4d17a1df8f02207e4a91203a2abd87fdddee96510482ef96535741b6c17a1acae93c977ad248e5012103e0747583a342b76a5de9c21db138b9640d49b4f3b67a306d3b3f217416d49b55ffffffff020058850c020000001976a9144417c63a91208a02a5f46a0f7a2b806adc7d19a788ac0042dc06030000001976a9147b61c5adef0d559e5acf2901c2989294624b651988ac0000000001000000017c1423b198dfc3da37ae9a5fc11a3720e4343b3049d3b289b8285eb04595c04b000000006b483045022100b0c1cb9608bf644d7a8916bf61f36ced95bd045e97612804ca774f60e05e7bde022017c12255eecc474c8d8b05d0910013b2df8703af68212cf0962b6b8ee0e101ee01210341e154088c23b8ea943bca94c1d4f65361668a242b168522f00199365414b46affffffff01019891ad000000001976a91481db1aa49ebc6a71cad96949eb28e22af85eb0bd88ac00000000 \ No newline at end of file diff --git a/bchain/coins/dogecoin/testdata/block_dump.567890 b/bchain/coins/dogecoin/testdata/block_dump.567890 new file mode 100644 index 00000000..81b4589f --- /dev/null +++ b/bchain/coins/dogecoin/testdata/block_dump.567890 @@ -0,0 +1 @@ +020162003a68158d4e0815de2572f716c1e9a3044756dbda8d68e3316d78862044e328f7f80627da6800e5a5cc6cb7b2d1af9a28ce3a212b9674b90ff0fa01478617db57130dcf542f18041b0000000001000000010000000000000000000000000000000000000000000000000000000000000000ffffffff5303e3040b062f503253482f04160dcf5408fabe6d6d333d89ade33bc29cf231d533a98a0dd9e9afe1c66db38cae3f5dfde43aff1c4f01000000000000001fffff6a090000000d2f6e6f64655374726174756d2f000000000170b7662a010000001976a914629e344f6575b9cb4491934a192455880c6788a788ac00000000d14203af39cb3a8c991008d2436ea2182fb83e2e3fb1fbee19b100000000000006de364688e6eba0bee24dc25f079fd251e016b11dedbd9a3dc37ae5e4b16cda15f3ca23366044338e79cf18ad197c2ecdcdde07683fc0b9f603aadb4f461c73ba15e6d7ccdc1d27e7c42ab46aecff71965a230c64b42a4cec231f467bbbdb67ecb705c8b9deaa6c8fd2b13c4c1cf027360c6e3f071f6f56fd37b7b502317f8afeab8bbb9e1faf13d35ecce88ed7f4d6d392b92bf97b6fb0d3587fe5f42e7afbbf540fcf0e55d38314ad5c5ae5bfb145d073483894c698e26d53b2ab30057cc12500000000000000000002000000897cd6afecaaa9e6b2967553bb2e21121e150f116a1aaec38dbb9ba5ec4f5ba3f671bc7939e72dce4e547640acf6d165e37901789ecad131eef457d92da61b13160dcf542786011baf45595f0901000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0d0352aa080101062f503253482fffffffff0100f1f0fb6b0100002321022986270cf40678ec266121f464c05ca1b38614dd7c9acefd271f5c2fb1b801b6ac00000000010000000468160c6ab0ad9704144a823bbfe62fd0c5476b9fe38bfdb9f12df41110c62915000000006a473044022008b2496d52740747718786ba4fb3ee3e540279ffdfa87016393dd95c039d94bf02201fc69d9866e86821c54ff487f85d463c2826b88be64792655c455126a65e1012012103f65fdd467a3b618c2754470ef1cb492e9c507895e8c971aff20af337dec92175ffffffff9f485841f44108c2ed4b963ed3055fd23970cb26b6b8acde67c2d1f5810e5c03000000006b48304502210085df61e32b2c7cae9b9075e2cbdd976884bae065d0b6e95a09286ed2419a38a20220186fc632799d2784851fe141fe515b3d201cb660af578b8bd49566ec3e99f93f0121029c2d6649bd974d945a334812415e9e5bf5d1bf880b87459df8a41b11c8b03e19ffffffff88ec0f68a1cf46b59087dc71d260ff7296490245d50433b06cef865eb9bf077f000000006a4730440220645df71efb21b85a2864d14f63a41a4dc316dc45d35fde78d6571856238a5758022071d68546a0f26ea622bf8f2f6090840eae8cc15c3927cdd4332fb47981ea6c980121029c2d6649bd974d945a334812415e9e5bf5d1bf880b87459df8a41b11c8b03e19ffffffff65a26116e69494e945dfd9ad9bf07e860bb0c9ea02631acfdb36cfae19a9d87e000000006a473044022070b0fd43169fa3fb292238b32ef660a46cb259c31931296c82dc4b733a177094022016abd1b84dbbf806d627b16a05a98c2655d4ce63b5f7a5af5f73d3d636289e03012102285b2657ef2b64a8efb5d901d2f242b03ac1bdfd3e83e44156c1c35c5d302fc2ffffffff020010a5d4e80000001976a9144aed7bbb32e9046bd592c954cef90f8c7809b97888ac8dca8444600000001976a914e7d82bb03cf66e15ba6d46828959ee6936a1a8b288ac000000000100000002138401ada35843f4052af5cd749bbd4f2d18cafc3efdc6c7a2494405cba5c7ea000000006b483045022100b13866821d0e241827c2e7df2fe2ec8a9447e9704125f82918e3c58759c28f3102202ecfadad01a0717c91d02b6989a09e624e06f984e4dccdafbeeaaad12a4c9e22012102172ee1ef0561178f654b1256acdf4bad4c1176e2d011c7555b69561e5694709dfffffffff4527c876ca88e45f7959570c09fd46f22168ffbf358ecb0e8e366b5e626be5a000000006a47304402201ea98e61350132beac86ca0897806e038c8362702044f984559cae617aae9b3802201451ebda8e8cf9a5d6c82738518d24ab368036bdef36dafd28676ee06bd3e550012102172ee1ef0561178f654b1256acdf4bad4c1176e2d011c7555b69561e5694709dffffffff0200ce624e030000001976a914deb74bf67ccd2334b8b98eb84b7d9eb4749e791988ac00cb2df6060000001976a914c7bf99152193d1d7a522e3dbd90a51ee231d21b388ac0000000001000000015454c150af72f3b5ce2cb3ccfcf4f851f160459b80d4986f963a12acd082d445000000006a473044022054067b9eae5c96c8e39aac2b59d0f6954a8763d7560d1b69d4338e061d8a5e3d02203e370c619d09851f3992d2895caf63116a5a4995cffe733b8cccaa12cadc6537012103f8d134a9e3ae9d685136a256041953f2248f69c913115a891f11db81320be034ffffffff02007ddaac000000001976a9147f56cc5b7ccf2b57879163ba4f86ffbaaa50eedc88ac00cb2df6060000001976a914c7bf99152193d1d7a522e3dbd90a51ee231d21b388ac000000000100000003737922e8b40d2bdebc994991a821f91bccb7ddfe4de99faa1120939259274712000000006b4830450221009346f3e39d110fdb61187abded0b841c6c5ea41dff4fc929a2ebb2723c021f9102206dde9caf81db155e94695a016e4f5693a275f23581fcfe412151926000c4a43b012102172ee1ef0561178f654b1256acdf4bad4c1176e2d011c7555b69561e5694709dffffffff636b3b1286012ce52615317da7b443b1bd5ba88f3fc73a93b8ffc3e4d197f216010000006b48304502210093cfe53ad7bd9727d74eb74f29dfc65a588e1948ac34d87d31f7badeec51321902204c38815975f5b53c5fec21ee41559c8ba662986a4a632d71b88c2e93f5074a54012102f5f3b29d309d941392c5332850a39772fb6f05c89dbc444a7bbe26238bb24b3affffffffeabfcdf2b6fe2e4d638a8c12de9306a4e11300ab2148c3fb12cc5e3eb340f4ed000000006b48304502210081cb5c299b9780572f3d839180a25737071a0e6e202840e58edf679952f80b69022025fefdcea390c8e76576a2bc3219ad7048d0f28c9551545da7e7590dacdbdd15012102eeacf7737afa3477037127e0774cfe7fa4c02502f421269c164bc43f4a3aa544ffffffff0200cb2df6060000001976a914c7bf99152193d1d7a522e3dbd90a51ee231d21b388ac002f6859000000001976a9149a513e51ee03350760c7c7108baef270106555e788ac0000000001000000021bfaadf88ca670f3d0d84dc6e96f4fdefa1e46f57602d3ab273169a9e046a803000000008a47304402204812d62b2c553f452db30481ad71795cbfe20adb32c4fa0fab2bbd14b7c5d46802200a8aed5089250b629799fe258e5d531e2953ccab10d1b891d0d0cf944e9df79c014104f4da83f7c607ac00bb41d098c55032a96f73451501493aa86ba0db49cf315bcbeecc5b674cb0d7a2c605dd5b6cc8466df20004d0ad799aaebdf2624413ed2c42ffffffffb877ab812a14e7fa4cfdc82aa2ff35109b67238f67bf358da8ad8a0d85e3536a000000008b483045022100980f593017ab3288c8fc32e4e00f270f926f4d47c44c871699904d0ff69cf7fa02202a4f7a17db99b58ef49f486e6587ca6f12407db59cbebe99a7ded3125e7a1b24014104f4da83f7c607ac00bb41d098c55032a96f73451501493aa86ba0db49cf315bcbeecc5b674cb0d7a2c605dd5b6cc8466df20004d0ad799aaebdf2624413ed2c42ffffffff0137750080b80100001976a9142c6e7be07833d7a12ae69fc14cca4f915f053c1988ac000000000100000001e3c977c0738add4784e65350ec78694ce39fad9e5866dd3033aacb9f819ba734000000006b483045022100f627ecaa03549baa72cc1f0a9c78a41b4aba7a126403f0d52c35d08a92a2344f02206f395453634fa5f41dd47d938e3e72a75f504626a81dcbb95e713495edd6b3a7012102212e1ea8c7e6aa57e60a4164431960a152e6f290e77105f66f9eb26930f1ec91ffffffff029e7680ac170000001976a91483b1fef25745d401b24af353c2e023b32785748688acc053455b010000001976a914685743b8f055b44ab98d18e20185a28a4d5db39b88ac0000000001000000025e1b66f77753f21337dc60a95003e9f8f889df03e2677709590c4b1146f7d0e6000000006a47304402205154e97875246499672fbc359c26f0e70fb79937c4600ee5f22d621179a2935e022055f036eb7dbf9bbbe81fbab365ee60eb0871fb0c68dae5dcbb97876c1567c55c0121027e4d08211f2980401f5295d54383fcdd39f9e19fd638dc4444b07ac3e31c185affffffff3b7b31dd6d520892d5b6469201e4393136c57ec8909c1ad2272036d4eba09bc8010000006a473044022012cdad86c02f29cbcd30e430fc478d62c596c1c9dad2e97fa59f9ce9c480cac0022035553616708979da1711ae1f7adc1e9763d13f97e118600c4bed79bc4472cec3012103bddd8caf1e62d8ecaa961f8ad302cad5469f14ae014c3890b309474bf7c14060ffffffff0200209db4060000001976a9142bebfeb92b59296c6f83f978814a60b486e5abcb88ac340cc414000000001976a9148075d71e9729c7571ef1ba70b9e728ae8a7e365c88ac0000000001000000024b5ead834ef9ffec4a65a63710efc9ee2ae5832792151cb162191b555d505b25000000006b483045022100e05b17eafec10d2b4fd7ea53fbe10e532f24018da6225061bf0e97717e745e660220654e0121ab12092f8f36c88a5ec18130ea4bfaf1a25714bc927083cc55ea2e780121034a0fa6ae90089789dc96025d2f2f42ce84c330763f3970df3cabd18f7b7149a7ffffffff70ce83e011fe09971516fe8cfad11d6897ec66a6f656613029340b75a3a0a9ae010000006b4830450221009aeb3a3f1da4a02fd6676c5547a75ff95178e167faa7a0daa634e44ae0a71a890220620961f5af2d2be33bcaff9a899697abed344b896d8bfe8d75327802dc9161f10121034a0fa6ae90089789dc96025d2f2f42ce84c330763f3970df3cabd18f7b7149a7ffffffff023a038759000000001976a91499a909ac4bc4058b6afd81fcd6189efe991d748988acc86fc335000000001976a91433954f88bae252585ab8ab53fcaf884dc65ebb4388ac00000000 \ No newline at end of file diff --git a/blockbook.go b/blockbook.go index e28f3f52..41fbfb34 100644 --- a/blockbook.go +++ b/blockbook.go @@ -26,15 +26,9 @@ import ( _ "net/http/pprof" ) -// resync index at least each resyncIndexPeriodMs (could be more often if invoked by message from ZeroMQ) -const resyncIndexPeriodMs = 935093 - // debounce too close requests for resync const debounceResyncIndexMs = 1009 -// resync mempool at least each resyncMempoolPeriodMs (could be more often if invoked by message from ZeroMQ) -const resyncMempoolPeriodMs = 60017 - // debounce too close requests for resync mempool (ZeroMQ sends message for each tx, when new block there are many transactions) const debounceResyncMempoolMs = 1009 @@ -71,6 +65,12 @@ var ( noTxCache = flag.Bool("notxcache", false, "disable tx cache") computeColumnStats = flag.Bool("computedbstats", false, "compute column stats and exit") + + // resync index at least each resyncIndexPeriodMs (could be more often if invoked by message from ZeroMQ) + resyncIndexPeriodMs = flag.Int("resyncindexperiod", 935093, "resync index period in milliseconds") + + // resync mempool at least each resyncMempoolPeriodMs (could be more often if invoked by message from ZeroMQ) + resyncMempoolPeriodMs = flag.Int("resyncmempoolperiod", 60017, "resync mempool period in milliseconds") ) var ( @@ -384,7 +384,7 @@ func syncIndexLoop() { defer close(chanSyncIndexDone) glog.Info("syncIndexLoop starting") // resync index about every 15 minutes if there are no chanSyncIndex requests, with debounce 1 second - tickAndDebounce(resyncIndexPeriodMs*time.Millisecond, debounceResyncIndexMs*time.Millisecond, chanSyncIndex, func() { + tickAndDebounce(time.Duration(*resyncIndexPeriodMs)*time.Millisecond, debounceResyncIndexMs*time.Millisecond, chanSyncIndex, func() { if err := syncWorker.ResyncIndex(onNewBlockHash); err != nil { glog.Error("syncIndexLoop ", errors.ErrorStack(err)) } @@ -402,7 +402,7 @@ func syncMempoolLoop() { defer close(chanSyncMempoolDone) glog.Info("syncMempoolLoop starting") // resync mempool about every minute if there are no chanSyncMempool requests, with debounce 1 second - tickAndDebounce(resyncMempoolPeriodMs*time.Millisecond, debounceResyncMempoolMs*time.Millisecond, chanSyncMempool, func() { + tickAndDebounce(time.Duration(*resyncMempoolPeriodMs)*time.Millisecond, debounceResyncMempoolMs*time.Millisecond, chanSyncMempool, func() { internalState.StartedMempoolSync() if count, err := chain.ResyncMempool(onNewTxAddr); err != nil { glog.Error("syncMempoolLoop ", errors.ErrorStack(err)) diff --git a/build/deb/debian/blockbook-dogecoin.conffiles b/build/deb/debian/blockbook-dogecoin.conffiles new file mode 100644 index 00000000..b2cd43e9 --- /dev/null +++ b/build/deb/debian/blockbook-dogecoin.conffiles @@ -0,0 +1 @@ +/opt/coins/blockbook/dogecoin/config/blockchaincfg.json diff --git a/build/deb/debian/blockbook-dogecoin.cron.daily b/build/deb/debian/blockbook-dogecoin.cron.daily new file mode 100644 index 00000000..2e3cd8f4 --- /dev/null +++ b/build/deb/debian/blockbook-dogecoin.cron.daily @@ -0,0 +1,2 @@ +#!/bin/sh +/opt/coins/blockbook/dogecoin/bin/logrotate.sh diff --git a/build/deb/debian/blockbook-dogecoin.dirs b/build/deb/debian/blockbook-dogecoin.dirs new file mode 100644 index 00000000..734baa69 --- /dev/null +++ b/build/deb/debian/blockbook-dogecoin.dirs @@ -0,0 +1,2 @@ +/opt/coins/data/dogecoin/blockbook +/opt/coins/blockbook/dogecoin/logs diff --git a/build/deb/debian/blockbook-dogecoin.install b/build/deb/debian/blockbook-dogecoin.install new file mode 100755 index 00000000..ee846bf9 --- /dev/null +++ b/build/deb/debian/blockbook-dogecoin.install @@ -0,0 +1,6 @@ +#!/usr/bin/dh-exec +blockbook /opt/coins/blockbook/dogecoin/bin +cert /opt/coins/blockbook/dogecoin +static /opt/coins/blockbook/dogecoin +configs/dogecoin.json => /opt/coins/blockbook/dogecoin/config/blockchaincfg.json +logrotate.sh /opt/coins/blockbook/dogecoin/bin diff --git a/build/deb/debian/blockbook-dogecoin.links b/build/deb/debian/blockbook-dogecoin.links new file mode 100644 index 00000000..b8c6ebe5 --- /dev/null +++ b/build/deb/debian/blockbook-dogecoin.links @@ -0,0 +1,2 @@ +/opt/coins/blockbook/dogecoin/cert/testcert.crt /opt/coins/blockbook/dogecoin/cert/blockbook.crt +/opt/coins/blockbook/dogecoin/cert/testcert.key /opt/coins/blockbook/dogecoin/cert/blockbook.key diff --git a/build/deb/debian/blockbook-dogecoin.postinst b/build/deb/debian/blockbook-dogecoin.postinst new file mode 100644 index 00000000..383110d5 --- /dev/null +++ b/build/deb/debian/blockbook-dogecoin.postinst @@ -0,0 +1,23 @@ +#!/bin/bash +set -e + +case "$1" in + + configure) + if ! id -u blockbook-dogecoin &> /dev/null + then + useradd --system -M -U blockbook-dogecoin -s /bin/false + fi + + for dir in /opt/coins/data/dogecoin/blockbook /opt/coins/blockbook/dogecoin/logs + do + if [ "$(stat -c '%U' $dir)" != "blockbook-dogecoin" ] + then + chown -R blockbook-dogecoin:blockbook-dogecoin $dir + fi + done + ;; + +esac + +#DEBHELPER# diff --git a/build/deb/debian/blockbook-dogecoin.service b/build/deb/debian/blockbook-dogecoin.service new file mode 100644 index 00000000..00d2dd19 --- /dev/null +++ b/build/deb/debian/blockbook-dogecoin.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-dogecoin.service +# See "man systemd.service" for details. + +[Unit] +Description=Blockbook daemon (Dogecoin mainnet) +After=network.target +Wants=backend-dogecoin.service + +[Service] +ExecStart=/opt/coins/blockbook/dogecoin/bin/blockbook -blockchaincfg=/opt/coins/blockbook/dogecoin/config/blockchaincfg.json -datadir=/opt/coins/data/dogecoin/blockbook/db -sync -httpserver=:9038 -socketio=:9138 -certfile=/opt/coins/blockbook/dogecoin/cert/blockbook -explorer=https://dogechain.info/ -resyncindexperiod=30011 -resyncmempoolperiod=2011 -log_dir=/opt/coins/blockbook/dogecoin/logs +User=blockbook-dogecoin +Type=simple +Restart=on-failure +WorkingDirectory=/opt/coins/blockbook/dogecoin + +# 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 7f22f9f9..1557d713 100644 --- a/build/deb/debian/control +++ b/build/deb/debian/control @@ -74,3 +74,8 @@ Package: blockbook-ethereum-testnet-ropsten Architecture: amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, coreutils, passwd, findutils, psmisc, backend-ethereum-testnet-ropsten Description: Satoshilabs blockbook server (Ethereum testnet ropsten) + +Package: blockbook-dogecoin +Architecture: amd64 +Depends: ${shlibs:Depends}, ${misc:Depends}, coreutils, passwd, findutils, psmisc, backend-dogecoin +Description: Satoshilabs blockbook server (Dogecoin mainnet) diff --git a/configs/dogecoin.json b/configs/dogecoin.json new file mode 100644 index 00000000..c16fdc3a --- /dev/null +++ b/configs/dogecoin.json @@ -0,0 +1,12 @@ +{ + "coin_name": "Dogecoin", + "rpcURL": "http://127.0.0.1:8038", + "rpcUser": "rpc", + "rpcPass": "rpcp", + "rpcTimeout": 25, + "parse": true, + "zeroMQBinding": "tcp://127.0.0.1:38338", + "mempoolWorkers": 8, + "mempoolSubWorkers": 2, + "blockAddressesToKeep": 300 +} diff --git a/contrib/backends/Makefile b/contrib/backends/Makefile index 9e5ede01..2862f19e 100644 --- a/contrib/backends/Makefile +++ b/contrib/backends/Makefile @@ -1,4 +1,4 @@ -TARGETS = bitcoin zcash bcash ethereum bgold dash litecoin +TARGETS = bitcoin zcash bcash ethereum bgold dash litecoin dogecoin IMAGE = blockbook-backend-build-deb NO_CACHE = false diff --git a/contrib/backends/dogecoin/Makefile b/contrib/backends/dogecoin/Makefile new file mode 100644 index 00000000..65f4bb29 --- /dev/null +++ b/contrib/backends/dogecoin/Makefile @@ -0,0 +1,13 @@ +DOGECOIN_VERSION := 1.10.0 + +all: + wget https://github.com/dogecoin/dogecoin/releases/download/v${DOGECOIN_VERSION}/dogecoin-${DOGECOIN_VERSION}-linux64.tar.gz + tar -xf dogecoin-${DOGECOIN_VERSION}-linux64.tar.gz + mv dogecoin-${DOGECOIN_VERSION} dogecoin + rm dogecoin/bin/dogecoin-qt + rm dogecoin/bin/test_dogecoin* + + +clean: + rm -rf dogecoin + rm -f dogecoin-${DOGECOIN_VERSION}-linux64.tar.gz diff --git a/contrib/backends/dogecoin/debian/backend-dogecoin.conffiles b/contrib/backends/dogecoin/debian/backend-dogecoin.conffiles new file mode 100644 index 00000000..1e030a36 --- /dev/null +++ b/contrib/backends/dogecoin/debian/backend-dogecoin.conffiles @@ -0,0 +1 @@ +/opt/coins/nodes/dogecoin/dogecoin.conf diff --git a/contrib/backends/dogecoin/debian/backend-dogecoin.dirs b/contrib/backends/dogecoin/debian/backend-dogecoin.dirs new file mode 100644 index 00000000..8e1d86a8 --- /dev/null +++ b/contrib/backends/dogecoin/debian/backend-dogecoin.dirs @@ -0,0 +1 @@ +/opt/coins/data/dogecoin/backend diff --git a/contrib/backends/dogecoin/debian/backend-dogecoin.install b/contrib/backends/dogecoin/debian/backend-dogecoin.install new file mode 100644 index 00000000..324c8702 --- /dev/null +++ b/contrib/backends/dogecoin/debian/backend-dogecoin.install @@ -0,0 +1,2 @@ +dogecoin/* /opt/coins/nodes/dogecoin +dogecoin.conf /opt/coins/nodes/dogecoin diff --git a/contrib/backends/dogecoin/debian/backend-dogecoin.logrotate b/contrib/backends/dogecoin/debian/backend-dogecoin.logrotate new file mode 100644 index 00000000..3233690b --- /dev/null +++ b/contrib/backends/dogecoin/debian/backend-dogecoin.logrotate @@ -0,0 +1,10 @@ +/opt/coins/data/dogecoin/backend/debug.log +/opt/coins/data/dogecoin/backend/db.log +{ + rotate 7 + daily + compress + missingok + notifempty + copytruncate +} diff --git a/contrib/backends/dogecoin/debian/backend-dogecoin.postinst b/contrib/backends/dogecoin/debian/backend-dogecoin.postinst new file mode 100644 index 00000000..bab28e43 --- /dev/null +++ b/contrib/backends/dogecoin/debian/backend-dogecoin.postinst @@ -0,0 +1,20 @@ +#!/bin/bash +set -e + +case "$1" in + + configure) + if ! id -u dogecoin &> /dev/null + then + useradd --system -M -U dogecoin -s /bin/false + fi + + if [ "$(stat -c '%U' /opt/coins/data/dogecoin/backend)" != "dogecoin" ] + then + chown -R dogecoin:dogecoin /opt/coins/data/dogecoin/backend + fi + ;; + +esac + +#DEBHELPER# diff --git a/contrib/backends/dogecoin/debian/backend-dogecoin.service b/contrib/backends/dogecoin/debian/backend-dogecoin.service new file mode 100644 index 00000000..9d3c4107 --- /dev/null +++ b/contrib/backends/dogecoin/debian/backend-dogecoin.service @@ -0,0 +1,47 @@ +# 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 dogecoin.service +# See "man systemd.service" for details. + +# Note that almost all daemon options could be specified in +# /opt/coins/nodes/dogecoin/dogecoin.conf + +[Unit] +Description=Dogecoin daemon (mainnet) +After=network.target + +[Service] +ExecStart=/opt/coins/nodes/dogecoin/bin/dogecoind -datadir=/opt/coins/data/dogecoin/backend -conf=/opt/coins/nodes/dogecoin/dogecoin.conf -pid=/run/dogecoind/dogecoin.pid +# Creates /run/dogecoind owned by dogecoin +RuntimeDirectory=dogecoind +User=dogecoin +Type=forking +PIDFile=/run/dogecoind/dogecoin.pid +Restart=on-failure + +# 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/contrib/backends/dogecoin/debian/changelog b/contrib/backends/dogecoin/debian/changelog new file mode 100644 index 00000000..3e9adc1d --- /dev/null +++ b/contrib/backends/dogecoin/debian/changelog @@ -0,0 +1,5 @@ +dogecoin (1.10.0-satoshilabs1) unstable; urgency=medium + + * Initial build + + -- Martin Bohm Thu, 14 Jun 2018 11:12:13 +0200 diff --git a/contrib/backends/dogecoin/debian/compat b/contrib/backends/dogecoin/debian/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/contrib/backends/dogecoin/debian/compat @@ -0,0 +1 @@ +9 diff --git a/contrib/backends/dogecoin/debian/control b/contrib/backends/dogecoin/debian/control new file mode 100644 index 00000000..a5ded050 --- /dev/null +++ b/contrib/backends/dogecoin/debian/control @@ -0,0 +1,11 @@ +Source: dogecoin +Section: satoshilabs +Priority: optional +Maintainer: martin.bohm@satoshilabs.com +Build-Depends: debhelper, wget, tar, gzip, make, dh-systemd, dh-exec +Standards-Version: 3.9.5 + +Package: backend-dogecoin +Architecture: amd64 +Depends: ${shlibs:Depends}, ${misc:Depends}, logrotate +Description: Satoshilabs packaged dogecoin server diff --git a/contrib/backends/dogecoin/debian/rules b/contrib/backends/dogecoin/debian/rules new file mode 100755 index 00000000..f69489df --- /dev/null +++ b/contrib/backends/dogecoin/debian/rules @@ -0,0 +1,11 @@ +#!/usr/bin/make -f + +DH_VERBOSE = 1 + +%: + dh $@ --with=systemd + +override_dh_systemd_start: + dh_systemd_start --no-start + +override_dh_installinit: diff --git a/contrib/backends/dogecoin/dogecoin.conf b/contrib/backends/dogecoin/dogecoin.conf new file mode 100644 index 00000000..efa9fa21 --- /dev/null +++ b/contrib/backends/dogecoin/dogecoin.conf @@ -0,0 +1,21 @@ +daemon=1 +server=1 +nolisten=1 +rpcuser=rpc +rpcpassword=rpcp +rpcport=8038 +txindex=1 +whitelist=127.0.0.1 +upnp=0 +discover=0 + +zmqpubhashtx=tcp://127.0.0.1:38338 +zmqpubhashblock=tcp://127.0.0.1:38338 + +rpcthreads=32 + +rpcworkqueue=1100 +maxmempool=2000 +dbcache=1000 + +