├── .gitignore ├── .travis.yml ├── CHANGES ├── LICENSE ├── README.md ├── addrmgr ├── addrmanager.go ├── addrmanager_test.go ├── cov_report.sh ├── doc.go ├── internal_test.go ├── knownaddress.go ├── knownaddress_test.go ├── log.go ├── network.go ├── network_test.go └── test_coverage.txt ├── blockchain ├── README.md ├── accept.go ├── bench_test.go ├── blockindex.go ├── chain.go ├── chain_test.go ├── chainio.go ├── chainio_test.go ├── chainview.go ├── chainview_test.go ├── checkpoints.go ├── common_test.go ├── compress.go ├── compress_test.go ├── difficulty.go ├── difficulty_test.go ├── doc.go ├── error.go ├── error_test.go ├── example_test.go ├── fullblocks_test.go ├── fullblocktests │ ├── README.md │ ├── doc.go │ ├── generate.go │ └── params.go ├── indexers │ ├── README.md │ ├── addrindex.go │ ├── addrindex_test.go │ ├── blocklogger.go │ ├── cfindex.go │ ├── common.go │ ├── log.go │ ├── manager.go │ └── txindex.go ├── log.go ├── mediantime.go ├── mediantime_test.go ├── merkle.go ├── merkle_test.go ├── notifications.go ├── notifications_test.go ├── process.go ├── scriptval.go ├── scriptval_test.go ├── testdata │ ├── 277647.dat.bz2 │ ├── 277647.utxostore.bz2 │ ├── blk_0_to_4.dat.bz2 │ ├── blk_3A.dat.bz2 │ ├── blk_4A.dat.bz2 │ ├── blk_5A.dat.bz2 │ └── reorgtest.hex ├── thresholdstate.go ├── thresholdstate_test.go ├── timesorter.go ├── timesorter_test.go ├── utxoviewpoint.go ├── validate.go ├── validate_test.go ├── versionbits.go └── weight.go ├── blocklogger.go ├── blockmanager.go ├── btcd.go ├── btcec ├── README.md ├── bench_test.go ├── btcec.go ├── btcec_test.go ├── ciphering.go ├── ciphering_test.go ├── doc.go ├── example_test.go ├── field.go ├── field_test.go ├── genprecomps.go ├── gensecp256k1.go ├── precompute.go ├── privkey.go ├── privkey_test.go ├── pubkey.go ├── pubkey_test.go ├── secp256k1.go ├── signature.go └── signature_test.go ├── btcjson ├── CONTRIBUTORS ├── README.md ├── btcdextcmds.go ├── btcdextcmds_test.go ├── btcdextresults.go ├── btcdextresults_test.go ├── btcwalletextcmds.go ├── btcwalletextcmds_test.go ├── chainsvrcmds.go ├── chainsvrcmds_test.go ├── chainsvrresults.go ├── chainsvrresults_test.go ├── chainsvrwscmds.go ├── chainsvrwscmds_test.go ├── chainsvrwsntfns.go ├── chainsvrwsntfns_test.go ├── chainsvrwsresults.go ├── chainsvrwsresults_test.go ├── cmdinfo.go ├── cmdinfo_test.go ├── cmdparse.go ├── cmdparse_test.go ├── doc.go ├── error.go ├── error_test.go ├── example_test.go ├── export_test.go ├── help.go ├── help_test.go ├── helpers.go ├── helpers_test.go ├── jsonrpc.go ├── jsonrpc_test.go ├── jsonrpcerr.go ├── register.go ├── register_test.go ├── walletsvrcmds.go ├── walletsvrcmds_test.go ├── walletsvrresults.go ├── walletsvrwscmds.go ├── walletsvrwscmds_test.go ├── walletsvrwsntfns.go └── walletsvrwsntfns_test.go ├── chaincfg ├── README.md ├── chainhash │ ├── README.md │ ├── doc.go │ ├── hash.go │ ├── hash_test.go │ ├── hashfuncs.go │ └── hashfuncs_test.go ├── doc.go ├── genesis.go ├── genesis_test.go ├── params.go ├── params_test.go └── register_test.go ├── cmd ├── addblock │ ├── addblock.go │ ├── config.go │ └── import.go ├── findcheckpoint │ ├── config.go │ └── findcheckpoint.go ├── gencerts │ └── gencerts.go └── ltcctl │ ├── config.go │ ├── httpclient.go │ ├── ltcctl.go │ └── version.go ├── config.go ├── config_test.go ├── connmgr ├── README.md ├── connmanager.go ├── connmanager_test.go ├── doc.go ├── dynamicbanscore.go ├── dynamicbanscore_test.go ├── log.go ├── seed.go └── tor.go ├── database ├── README.md ├── cmd │ └── dbtool │ │ ├── fetchblock.go │ │ ├── fetchblockregion.go │ │ ├── globalconfig.go │ │ ├── insecureimport.go │ │ ├── loadheaders.go │ │ ├── main.go │ │ └── signal.go ├── doc.go ├── driver.go ├── driver_test.go ├── error.go ├── error_test.go ├── example_test.go ├── export_test.go ├── ffldb │ ├── README.md │ ├── bench_test.go │ ├── blockio.go │ ├── db.go │ ├── dbcache.go │ ├── doc.go │ ├── driver.go │ ├── driver_test.go │ ├── export_test.go │ ├── interface_test.go │ ├── ldbtreapiter.go │ ├── mockfile_test.go │ ├── reconcile.go │ └── whitebox_test.go ├── interface.go ├── internal │ └── treap │ │ ├── README.md │ │ ├── common.go │ │ ├── common_test.go │ │ ├── doc.go │ │ ├── immutable.go │ │ ├── immutable_test.go │ │ ├── mutable.go │ │ ├── mutable_test.go │ │ ├── treapiter.go │ │ └── treapiter_test.go ├── log.go └── testdata │ └── blocks1-256.bz2 ├── doc.go ├── docs ├── README.md ├── code_contribution_guidelines.md ├── configure_peer_server_listen_interfaces.md ├── configure_rpc_server_listen_interfaces.md ├── configuring_tor.md ├── default_ports.md ├── json_rpc_api.md └── using_bootstrap_dat.md ├── glide.lock ├── glide.yaml ├── goclean.sh ├── integration ├── README.md ├── bip0009_test.go ├── csv_fork_test.go ├── main.go ├── rpcserver_test.go └── rpctest │ ├── README.md │ ├── blockgen.go │ ├── doc.go │ ├── memwallet.go │ ├── node.go │ ├── rpc_harness.go │ ├── rpc_harness_test.go │ └── utils.go ├── limits ├── limits_plan9.go ├── limits_unix.go └── limits_windows.go ├── log.go ├── mempool ├── README.md ├── doc.go ├── error.go ├── log.go ├── mempool.go ├── mempool_test.go ├── policy.go └── policy_test.go ├── mining ├── README.md ├── cpuminer │ ├── README.md │ ├── cpuminer.go │ └── log.go ├── log.go ├── mining.go ├── mining_test.go ├── policy.go └── policy_test.go ├── params.go ├── peer ├── README.md ├── doc.go ├── example_test.go ├── export_test.go ├── log.go ├── mruinvmap.go ├── mruinvmap_test.go ├── mrunoncemap.go ├── mrunoncemap_test.go ├── peer.go └── peer_test.go ├── release ├── notes.sample └── prep_release.sh ├── rpcadapters.go ├── rpcclient ├── CONTRIBUTORS ├── README.md ├── chain.go ├── doc.go ├── examples │ ├── bitcoincorehttp │ │ ├── README.md │ │ └── main.go │ ├── btcdwebsockets │ │ ├── README.md │ │ └── main.go │ └── btcwalletwebsockets │ │ ├── README.md │ │ └── main.go ├── extensions.go ├── infrastructure.go ├── log.go ├── mining.go ├── net.go ├── notify.go ├── rawrequest.go ├── rawtransactions.go └── wallet.go ├── rpcserver.go ├── rpcserverhelp.go ├── rpcserverhelp_test.go ├── rpcwebsocket.go ├── sample-ltcd.conf ├── server.go ├── service_windows.go ├── signal.go ├── signalsigterm.go ├── txscript ├── README.md ├── consensus.go ├── data │ ├── LICENSE │ ├── script_tests.json │ ├── sighash.json │ ├── tx_invalid.json │ └── tx_valid.json ├── doc.go ├── engine.go ├── engine_test.go ├── error.go ├── error_test.go ├── example_test.go ├── hashcache.go ├── hashcache_test.go ├── log.go ├── opcode.go ├── opcode_test.go ├── reference_test.go ├── script.go ├── script_test.go ├── scriptbuilder.go ├── scriptbuilder_test.go ├── scriptnum.go ├── scriptnum_test.go ├── sigcache.go ├── sigcache_test.go ├── sign.go ├── sign_test.go ├── stack.go ├── stack_test.go ├── standard.go └── standard_test.go ├── upgrade.go ├── upnp.go ├── version.go └── wire ├── README.md ├── bench_test.go ├── blockheader.go ├── blockheader_test.go ├── common.go ├── common_test.go ├── doc.go ├── error.go ├── fakemessage_test.go ├── fixedIO_test.go ├── invvect.go ├── invvect_test.go ├── message.go ├── message_test.go ├── msgaddr.go ├── msgaddr_test.go ├── msgalert.go ├── msgalert_test.go ├── msgblock.go ├── msgblock_test.go ├── msgcfheaders.go ├── msgcfilter.go ├── msgfeefilter.go ├── msgfeefilter_test.go ├── msgfilteradd.go ├── msgfilteradd_test.go ├── msgfilterclear.go ├── msgfilterclear_test.go ├── msgfilterload.go ├── msgfilterload_test.go ├── msggetaddr.go ├── msggetaddr_test.go ├── msggetblocks.go ├── msggetblocks_test.go ├── msggetcfheaders.go ├── msggetcfilter.go ├── msggetdata.go ├── msggetdata_test.go ├── msggetheaders.go ├── msggetheaders_test.go ├── msgheaders.go ├── msgheaders_test.go ├── msginv.go ├── msginv_test.go ├── msgmempool.go ├── msgmempool_test.go ├── msgmerkleblock.go ├── msgmerkleblock_test.go ├── msgnotfound.go ├── msgnotfound_test.go ├── msgping.go ├── msgping_test.go ├── msgpong.go ├── msgpong_test.go ├── msgreject.go ├── msgreject_test.go ├── msgsendheaders.go ├── msgsendheaders_test.go ├── msgtx.go ├── msgtx_test.go ├── msgverack.go ├── msgverack_test.go ├── msgversion.go ├── msgversion_test.go ├── netaddress.go ├── netaddress_test.go ├── protocol.go ├── protocol_test.go └── testdata └── megatx.bin.bz2 /.gitignore: -------------------------------------------------------------------------------- 1 | # Temp files 2 | *~ 3 | 4 | # Databases 5 | btcd.db 6 | *-shm 7 | *-wal 8 | 9 | # Log files 10 | *.log 11 | 12 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 13 | *.o 14 | *.a 15 | *.so 16 | 17 | # Folders 18 | _obj 19 | _test 20 | vendor 21 | 22 | # Architecture specific extensions/prefixes 23 | *.[568vq] 24 | [568vq].out 25 | 26 | *.cgo1.go 27 | *.cgo2.c 28 | _cgo_defun.c 29 | _cgo_gotypes.go 30 | _cgo_export.* 31 | 32 | _testmain.go 33 | 34 | *.exe 35 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.6.x 4 | - 1.7.x 5 | sudo: false 6 | install: 7 | - GLIDE_TAG=v0.12.3 8 | - GLIDE_DOWNLOAD="https://github.com/Masterminds/glide/releases/download/$GLIDE_TAG/glide-$GLIDE_TAG-linux-amd64.tar.gz" 9 | - curl -L $GLIDE_DOWNLOAD | tar -xvz 10 | - export PATH=$PATH:$PWD/linux-amd64/ 11 | - glide install 12 | - go install . ./cmd/... 13 | - go get -v github.com/alecthomas/gometalinter 14 | - gometalinter --install 15 | script: 16 | - export PATH=$PATH:$HOME/gopath/bin 17 | - ./goclean.sh 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2013-2017 The btcsuite developers 4 | Copyright (c) 2015-2016 The Decred developers 5 | 6 | Permission to use, copy, modify, and distribute this software for any 7 | purpose with or without fee is hereby granted, provided that the above 8 | copyright notice and this permission notice appear in all copies. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | -------------------------------------------------------------------------------- /addrmgr/cov_report.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This script uses gocov to generate a test coverage report. 4 | # The gocov tool my be obtained with the following command: 5 | # go get github.com/axw/gocov/gocov 6 | # 7 | # It will be installed to $GOPATH/bin, so ensure that location is in your $PATH. 8 | 9 | # Check for gocov. 10 | type gocov >/dev/null 2>&1 11 | if [ $? -ne 0 ]; then 12 | echo >&2 "This script requires the gocov tool." 13 | echo >&2 "You may obtain it with the following command:" 14 | echo >&2 "go get github.com/axw/gocov/gocov" 15 | exit 1 16 | fi 17 | gocov test | gocov report 18 | -------------------------------------------------------------------------------- /addrmgr/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package addrmgr implements concurrency safe Bitcoin address manager. 7 | 8 | Address Manager Overview 9 | 10 | In order maintain the peer-to-peer Bitcoin network, there needs to be a source 11 | of addresses to connect to as nodes come and go. The Bitcoin protocol provides 12 | the getaddr and addr messages to allow peers to communicate known addresses with 13 | each other. However, there needs to a mechanism to store those results and 14 | select peers from them. It is also important to note that remote peers can't 15 | be trusted to send valid peers nor attempt to provide you with only peers they 16 | control with malicious intent. 17 | 18 | With that in mind, this package provides a concurrency safe address manager for 19 | caching and selecting peers in a non-deterministic manner. The general idea is 20 | the caller adds addresses to the address manager and notifies it when addresses 21 | are connected, known good, and attempted. The caller also requests addresses as 22 | it needs them. 23 | 24 | The address manager internally segregates the addresses into groups and 25 | non-deterministically selects groups in a cryptographically random manner. This 26 | reduce the chances multiple addresses from the same nets are selected which 27 | generally helps provide greater peer diversity, and perhaps more importantly, 28 | drastically reduces the chances an attacker is able to coerce your peer into 29 | only connecting to nodes they control. 30 | 31 | The address manager also understands routability and Tor addresses and tries 32 | hard to only return routable addresses. In addition, it uses the information 33 | provided by the caller about connected, known good, and attempted addresses to 34 | periodically purge peers which no longer appear to be good peers as well as 35 | bias the selection toward known good peers. The general idea is to make a best 36 | effort at only providing usable addresses. 37 | */ 38 | package addrmgr 39 | -------------------------------------------------------------------------------- /addrmgr/internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package addrmgr 6 | 7 | import ( 8 | "time" 9 | 10 | "github.com/ltcsuite/ltcd/wire" 11 | ) 12 | 13 | func TstKnownAddressIsBad(ka *KnownAddress) bool { 14 | return ka.isBad() 15 | } 16 | 17 | func TstKnownAddressChance(ka *KnownAddress) float64 { 18 | return ka.chance() 19 | } 20 | 21 | func TstNewKnownAddress(na *wire.NetAddress, attempts int, 22 | lastattempt, lastsuccess time.Time, tried bool, refs int) *KnownAddress { 23 | return &KnownAddress{na: na, attempts: attempts, lastattempt: lastattempt, 24 | lastsuccess: lastsuccess, tried: tried, refs: refs} 25 | } 26 | -------------------------------------------------------------------------------- /addrmgr/knownaddress.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package addrmgr 6 | 7 | import ( 8 | "time" 9 | 10 | "github.com/ltcsuite/ltcd/wire" 11 | ) 12 | 13 | // KnownAddress tracks information about a known network address that is used 14 | // to determine how viable an address is. 15 | type KnownAddress struct { 16 | na *wire.NetAddress 17 | srcAddr *wire.NetAddress 18 | attempts int 19 | lastattempt time.Time 20 | lastsuccess time.Time 21 | tried bool 22 | refs int // reference count of new buckets 23 | } 24 | 25 | // NetAddress returns the underlying wire.NetAddress associated with the 26 | // known address. 27 | func (ka *KnownAddress) NetAddress() *wire.NetAddress { 28 | return ka.na 29 | } 30 | 31 | // LastAttempt returns the last time the known address was attempted. 32 | func (ka *KnownAddress) LastAttempt() time.Time { 33 | return ka.lastattempt 34 | } 35 | 36 | // chance returns the selection probability for a known address. The priority 37 | // depends upon how recently the address has been seen, how recently it was last 38 | // attempted and how often attempts to connect to it have failed. 39 | func (ka *KnownAddress) chance() float64 { 40 | now := time.Now() 41 | lastAttempt := now.Sub(ka.lastattempt) 42 | 43 | if lastAttempt < 0 { 44 | lastAttempt = 0 45 | } 46 | 47 | c := 1.0 48 | 49 | // Very recent attempts are less likely to be retried. 50 | if lastAttempt < 10*time.Minute { 51 | c *= 0.01 52 | } 53 | 54 | // Failed attempts deprioritise. 55 | for i := ka.attempts; i > 0; i-- { 56 | c /= 1.5 57 | } 58 | 59 | return c 60 | } 61 | 62 | // isBad returns true if the address in question has not been tried in the last 63 | // minute and meets one of the following criteria: 64 | // 1) It claims to be from the future 65 | // 2) It hasn't been seen in over a month 66 | // 3) It has failed at least three times and never succeeded 67 | // 4) It has failed ten times in the last week 68 | // All addresses that meet these criteria are assumed to be worthless and not 69 | // worth keeping hold of. 70 | func (ka *KnownAddress) isBad() bool { 71 | if ka.lastattempt.After(time.Now().Add(-1 * time.Minute)) { 72 | return false 73 | } 74 | 75 | // From the future? 76 | if ka.na.Timestamp.After(time.Now().Add(10 * time.Minute)) { 77 | return true 78 | } 79 | 80 | // Over a month old? 81 | if ka.na.Timestamp.Before(time.Now().Add(-1 * numMissingDays * time.Hour * 24)) { 82 | return true 83 | } 84 | 85 | // Never succeeded? 86 | if ka.lastsuccess.IsZero() && ka.attempts >= numRetries { 87 | return true 88 | } 89 | 90 | // Hasn't succeeded in too long? 91 | if !ka.lastsuccess.After(time.Now().Add(-1*minBadDays*time.Hour*24)) && 92 | ka.attempts >= maxFailures { 93 | return true 94 | } 95 | 96 | return false 97 | } 98 | -------------------------------------------------------------------------------- /addrmgr/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package addrmgr 6 | 7 | import ( 8 | "github.com/btcsuite/btclog" 9 | ) 10 | 11 | // log is a logger that is initialized with no output filters. This 12 | // means the package will not perform any logging by default until the caller 13 | // requests it. 14 | var log btclog.Logger 15 | 16 | // The default amount of logging is none. 17 | func init() { 18 | DisableLog() 19 | } 20 | 21 | // DisableLog disables all library log output. Logging output is disabled 22 | // by default until either UseLogger or SetLogWriter are called. 23 | func DisableLog() { 24 | log = btclog.Disabled 25 | } 26 | 27 | // UseLogger uses a specified Logger to output package logging info. 28 | // This should be used in preference to SetLogWriter if the caller is also 29 | // using btclog. 30 | func UseLogger(logger btclog.Logger) { 31 | log = logger 32 | } 33 | -------------------------------------------------------------------------------- /blockchain/bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package blockchain 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/ltcsuite/ltcutil" 11 | ) 12 | 13 | // BenchmarkIsCoinBase performs a simple benchmark against the IsCoinBase 14 | // function. 15 | func BenchmarkIsCoinBase(b *testing.B) { 16 | tx, _ := ltcutil.NewBlock(&Block100000).Tx(1) 17 | b.ResetTimer() 18 | for i := 0; i < b.N; i++ { 19 | IsCoinBase(tx) 20 | } 21 | } 22 | 23 | // BenchmarkIsCoinBaseTx performs a simple benchmark against the IsCoinBaseTx 24 | // function. 25 | func BenchmarkIsCoinBaseTx(b *testing.B) { 26 | tx := Block100000.Transactions[1] 27 | b.ResetTimer() 28 | for i := 0; i < b.N; i++ { 29 | IsCoinBaseTx(tx) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /blockchain/difficulty_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2017 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package blockchain 6 | 7 | import ( 8 | "math/big" 9 | "testing" 10 | ) 11 | 12 | // TestBigToCompact ensures BigToCompact converts big integers to the expected 13 | // compact representation. 14 | func TestBigToCompact(t *testing.T) { 15 | tests := []struct { 16 | in int64 17 | out uint32 18 | }{ 19 | {0, 0}, 20 | {-1, 25231360}, 21 | } 22 | 23 | for x, test := range tests { 24 | n := big.NewInt(test.in) 25 | r := BigToCompact(n) 26 | if r != test.out { 27 | t.Errorf("TestBigToCompact test #%d failed: got %d want %d\n", 28 | x, r, test.out) 29 | return 30 | } 31 | } 32 | } 33 | 34 | // TestCompactToBig ensures CompactToBig converts numbers using the compact 35 | // representation to the expected big intergers. 36 | func TestCompactToBig(t *testing.T) { 37 | tests := []struct { 38 | in uint32 39 | out int64 40 | }{ 41 | {10000000, 0}, 42 | } 43 | 44 | for x, test := range tests { 45 | n := CompactToBig(test.in) 46 | want := big.NewInt(test.out) 47 | if n.Cmp(want) != 0 { 48 | t.Errorf("TestCompactToBig test #%d failed: got %d want %d\n", 49 | x, n.Int64(), want.Int64()) 50 | return 51 | } 52 | } 53 | } 54 | 55 | // TestCalcWork ensures CalcWork calculates the expected work value from values 56 | // in compact representation. 57 | func TestCalcWork(t *testing.T) { 58 | tests := []struct { 59 | in uint32 60 | out int64 61 | }{ 62 | {10000000, 0}, 63 | } 64 | 65 | for x, test := range tests { 66 | bits := uint32(test.in) 67 | 68 | r := CalcWork(bits) 69 | if r.Int64() != test.out { 70 | t.Errorf("TestCalcWork test #%d failed: got %v want %d\n", 71 | x, r.Int64(), test.out) 72 | return 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /blockchain/fullblocktests/README.md: -------------------------------------------------------------------------------- 1 | fullblocktests 2 | ============== 3 | 4 | [![Build Status](http://img.shields.io/travis/ltcsuite/ltcd.svg)](https://travis-ci.org/ltcsuite/ltcd) 5 | [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 6 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)] 7 | 8 | Package fullblocktests provides a set of full block tests to be used for testing 9 | the consensus validation rules. The tests are intended to be flexible enough to 10 | allow both unit-style tests directly against the blockchain code as well as 11 | integration style tests over the peer-to-peer network. To achieve that goal, 12 | each test contains additional information about the expected result, however 13 | that information can be ignored when doing comparison tests between two 14 | independent versions over the peer-to-peer network. 15 | 16 | This package has intentionally been designed so it can be used as a standalone 17 | package for any projects needing to test their implementation against a full set 18 | of blocks that excerise the consensus validation rules. 19 | 20 | ## Installation and Updating 21 | 22 | ```bash 23 | $ go get -u github.com/ltcsuite/ltcd/blockchain/fullblocktests 24 | ``` 25 | 26 | ## License 27 | 28 | Package fullblocktests is licensed under the [copyfree](http://copyfree.org) ISC 29 | License. 30 | -------------------------------------------------------------------------------- /blockchain/fullblocktests/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package fullblocktests provides a set of block consensus validation tests. 7 | 8 | All of the generated test instances involve full blocks that are to be used for 9 | testing the consensus validation rules. The tests are intended to be flexible 10 | enough to allow both unit-style tests directly against the blockchain code as 11 | well as integration style tests over the peer-to-peer network. To achieve that 12 | goal, each test contains additional information about the expected result, 13 | however that information can be ignored when doing comparison tests between two 14 | independent versions over the peer-to-peer network. 15 | 16 | This package has intentionally been designed so it can be used as a standalone 17 | package for any projects needing to test their implementation against a full set 18 | of blocks that excerise the consensus validation rules. 19 | */ 20 | package fullblocktests 21 | -------------------------------------------------------------------------------- /blockchain/indexers/README.md: -------------------------------------------------------------------------------- 1 | indexers 2 | ======== 3 | 4 | [![Build Status](https://travis-ci.org/ltcsuite/ltcd.png?branch=master)](https://travis-ci.org/ltcsuite/ltcd) 5 | 6 | Package indexers implements optional block chain indexes. 7 | 8 | These indexes are typically used to enhance the amount of information available 9 | via an RPC interface. 10 | 11 | ## Supported Indexers 12 | 13 | - Transaction-by-hash (txbyhashidx) Index 14 | - Creates a mapping from the hash of each transaction to the block that 15 | contains it along with its offset and length within the serialized block 16 | - Transaction-by-address (txbyaddridx) Index 17 | - Creates a mapping from every address to all transactions which either credit 18 | or debit the address 19 | - Requires the transaction-by-hash index 20 | 21 | ## Installation 22 | 23 | ```bash 24 | $ go get -u github.com/ltcsuite/ltcd/blockchain/indexers 25 | ``` 26 | 27 | ## License 28 | 29 | Package indexers is licensed under the [copyfree](http://copyfree.org) ISC 30 | License. 31 | -------------------------------------------------------------------------------- /blockchain/indexers/blocklogger.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package indexers 6 | 7 | import ( 8 | "sync" 9 | "time" 10 | 11 | "github.com/btcsuite/btclog" 12 | "github.com/ltcsuite/ltcutil" 13 | ) 14 | 15 | // blockProgressLogger provides periodic logging for other services in order 16 | // to show users progress of certain "actions" involving some or all current 17 | // blocks. Ex: syncing to best chain, indexing all blocks, etc. 18 | type blockProgressLogger struct { 19 | receivedLogBlocks int64 20 | receivedLogTx int64 21 | lastBlockLogTime time.Time 22 | 23 | subsystemLogger btclog.Logger 24 | progressAction string 25 | sync.Mutex 26 | } 27 | 28 | // newBlockProgressLogger returns a new block progress logger. 29 | // The progress message is templated as follows: 30 | // {progressAction} {numProcessed} {blocks|block} in the last {timePeriod} 31 | // ({numTxs}, height {lastBlockHeight}, {lastBlockTimeStamp}) 32 | func newBlockProgressLogger(progressMessage string, logger btclog.Logger) *blockProgressLogger { 33 | return &blockProgressLogger{ 34 | lastBlockLogTime: time.Now(), 35 | progressAction: progressMessage, 36 | subsystemLogger: logger, 37 | } 38 | } 39 | 40 | // LogBlockHeight logs a new block height as an information message to show 41 | // progress to the user. In order to prevent spam, it limits logging to one 42 | // message every 10 seconds with duration and totals included. 43 | func (b *blockProgressLogger) LogBlockHeight(block *ltcutil.Block) { 44 | b.Lock() 45 | defer b.Unlock() 46 | 47 | b.receivedLogBlocks++ 48 | b.receivedLogTx += int64(len(block.MsgBlock().Transactions)) 49 | 50 | now := time.Now() 51 | duration := now.Sub(b.lastBlockLogTime) 52 | if duration < time.Second*10 { 53 | return 54 | } 55 | 56 | // Truncate the duration to 10s of milliseconds. 57 | durationMillis := int64(duration / time.Millisecond) 58 | tDuration := 10 * time.Millisecond * time.Duration(durationMillis/10) 59 | 60 | // Log information about new block height. 61 | blockStr := "blocks" 62 | if b.receivedLogBlocks == 1 { 63 | blockStr = "block" 64 | } 65 | txStr := "transactions" 66 | if b.receivedLogTx == 1 { 67 | txStr = "transaction" 68 | } 69 | b.subsystemLogger.Infof("%s %d %s in the last %s (%d %s, height %d, %s)", 70 | b.progressAction, b.receivedLogBlocks, blockStr, tDuration, b.receivedLogTx, 71 | txStr, block.Height(), block.MsgBlock().Header.Timestamp) 72 | 73 | b.receivedLogBlocks = 0 74 | b.receivedLogTx = 0 75 | b.lastBlockLogTime = now 76 | } 77 | -------------------------------------------------------------------------------- /blockchain/indexers/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package indexers 6 | 7 | import "github.com/btcsuite/btclog" 8 | 9 | // log is a logger that is initialized with no output filters. This 10 | // means the package will not perform any logging by default until the caller 11 | // requests it. 12 | var log btclog.Logger 13 | 14 | // The default amount of logging is none. 15 | func init() { 16 | DisableLog() 17 | } 18 | 19 | // DisableLog disables all library log output. Logging output is disabled 20 | // by default until either UseLogger or SetLogWriter are called. 21 | func DisableLog() { 22 | log = btclog.Disabled 23 | } 24 | 25 | // UseLogger uses a specified Logger to output package logging info. 26 | // This should be used in preference to SetLogWriter if the caller is also 27 | // using btclog. 28 | func UseLogger(logger btclog.Logger) { 29 | log = logger 30 | } 31 | -------------------------------------------------------------------------------- /blockchain/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package blockchain 6 | 7 | import ( 8 | "github.com/btcsuite/btclog" 9 | ) 10 | 11 | // log is a logger that is initialized with no output filters. This 12 | // means the package will not perform any logging by default until the caller 13 | // requests it. 14 | var log btclog.Logger 15 | 16 | // The default amount of logging is none. 17 | func init() { 18 | DisableLog() 19 | } 20 | 21 | // DisableLog disables all library log output. Logging output is disabled 22 | // by default until UseLogger is called. 23 | func DisableLog() { 24 | log = btclog.Disabled 25 | } 26 | 27 | // UseLogger uses a specified Logger to output package logging info. 28 | func UseLogger(logger btclog.Logger) { 29 | log = logger 30 | } 31 | -------------------------------------------------------------------------------- /blockchain/merkle_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2017 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package blockchain 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/ltcsuite/ltcutil" 11 | ) 12 | 13 | // TestMerkle tests the BuildMerkleTreeStore API. 14 | func TestMerkle(t *testing.T) { 15 | block := ltcutil.NewBlock(&Block100000) 16 | merkles := BuildMerkleTreeStore(block.Transactions(), false) 17 | calculatedMerkleRoot := merkles[len(merkles)-1] 18 | wantMerkle := &Block100000.Header.MerkleRoot 19 | if !wantMerkle.IsEqual(calculatedMerkleRoot) { 20 | t.Errorf("BuildMerkleTreeStore: merkle root mismatch - "+ 21 | "got %v, want %v", calculatedMerkleRoot, wantMerkle) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /blockchain/notifications.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package blockchain 6 | 7 | import ( 8 | "fmt" 9 | ) 10 | 11 | // NotificationType represents the type of a notification message. 12 | type NotificationType int 13 | 14 | // NotificationCallback is used for a caller to provide a callback for 15 | // notifications about various chain events. 16 | type NotificationCallback func(*Notification) 17 | 18 | // Constants for the type of a notification message. 19 | const ( 20 | // NTBlockAccepted indicates the associated block was accepted into 21 | // the block chain. Note that this does not necessarily mean it was 22 | // added to the main chain. For that, use NTBlockConnected. 23 | NTBlockAccepted NotificationType = iota 24 | 25 | // NTBlockConnected indicates the associated block was connected to the 26 | // main chain. 27 | NTBlockConnected 28 | 29 | // NTBlockDisconnected indicates the associated block was disconnected 30 | // from the main chain. 31 | NTBlockDisconnected 32 | ) 33 | 34 | // notificationTypeStrings is a map of notification types back to their constant 35 | // names for pretty printing. 36 | var notificationTypeStrings = map[NotificationType]string{ 37 | NTBlockAccepted: "NTBlockAccepted", 38 | NTBlockConnected: "NTBlockConnected", 39 | NTBlockDisconnected: "NTBlockDisconnected", 40 | } 41 | 42 | // String returns the NotificationType in human-readable form. 43 | func (n NotificationType) String() string { 44 | if s, ok := notificationTypeStrings[n]; ok { 45 | return s 46 | } 47 | return fmt.Sprintf("Unknown Notification Type (%d)", int(n)) 48 | } 49 | 50 | // Notification defines notification that is sent to the caller via the callback 51 | // function provided during the call to New and consists of a notification type 52 | // as well as associated data that depends on the type as follows: 53 | // - NTBlockAccepted: *ltcutil.Block 54 | // - NTBlockConnected: *ltcutil.Block 55 | // - NTBlockDisconnected: *ltcutil.Block 56 | type Notification struct { 57 | Type NotificationType 58 | Data interface{} 59 | } 60 | 61 | // Subscribe to block chain notifications. Registers a callback to be executed 62 | // when various events take place. See the documentation on Notification and 63 | // NotificationType for details on the types and contents of notifications. 64 | func (b *BlockChain) Subscribe(callback NotificationCallback) { 65 | b.notificationsLock.Lock() 66 | b.notifications = append(b.notifications, callback) 67 | b.notificationsLock.Unlock() 68 | } 69 | 70 | // sendNotification sends a notification with the passed type and data if the 71 | // caller requested notifications by providing a callback function in the call 72 | // to New. 73 | func (b *BlockChain) sendNotification(typ NotificationType, data interface{}) { 74 | // Generate and send the notification. 75 | n := Notification{Type: typ, Data: data} 76 | b.notificationsLock.RLock() 77 | for _, callback := range b.notifications { 78 | callback(&n) 79 | } 80 | b.notificationsLock.RUnlock() 81 | } 82 | -------------------------------------------------------------------------------- /blockchain/notifications_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package blockchain 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/ltcsuite/ltcd/chaincfg" 11 | ) 12 | 13 | // TestNotifications ensures that notification callbacks are fired on events. 14 | func TestNotifications(t *testing.T) { 15 | blocks, err := loadBlocks("blk_0_to_4.dat.bz2") 16 | if err != nil { 17 | t.Fatalf("Error loading file: %v\n", err) 18 | } 19 | 20 | // Create a new database and chain instance to run tests against. 21 | chain, teardownFunc, err := chainSetup("notifications", 22 | &chaincfg.MainNetParams) 23 | if err != nil { 24 | t.Fatalf("Failed to setup chain instance: %v", err) 25 | } 26 | defer teardownFunc() 27 | 28 | notificationCount := 0 29 | callback := func(notification *Notification) { 30 | if notification.Type == NTBlockAccepted { 31 | notificationCount++ 32 | } 33 | } 34 | 35 | // Register callback multiple times then assert it is called that many 36 | // times. 37 | const numSubscribers = 3 38 | for i := 0; i < numSubscribers; i++ { 39 | chain.Subscribe(callback) 40 | } 41 | 42 | _, _, err = chain.ProcessBlock(blocks[1], BFNone) 43 | if err != nil { 44 | t.Fatalf("ProcessBlock fail on block 1: %v\n", err) 45 | } 46 | 47 | if notificationCount != numSubscribers { 48 | t.Fatalf("Expected notification callback to be executed %d "+ 49 | "times, found %d", numSubscribers, notificationCount) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /blockchain/scriptval_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2017 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package blockchain 6 | 7 | import ( 8 | "fmt" 9 | "runtime" 10 | "testing" 11 | 12 | "github.com/ltcsuite/ltcd/txscript" 13 | ) 14 | 15 | // TestCheckBlockScripts ensures that validating the all of the scripts in a 16 | // known-good block doesn't return an error. 17 | func TestCheckBlockScripts(t *testing.T) { 18 | runtime.GOMAXPROCS(runtime.NumCPU()) 19 | 20 | testBlockNum := 277647 21 | blockDataFile := fmt.Sprintf("%d.dat.bz2", testBlockNum) 22 | blocks, err := loadBlocks(blockDataFile) 23 | if err != nil { 24 | t.Errorf("Error loading file: %v\n", err) 25 | return 26 | } 27 | if len(blocks) > 1 { 28 | t.Errorf("The test block file must only have one block in it") 29 | return 30 | } 31 | if len(blocks) == 0 { 32 | t.Errorf("The test block file may not be empty") 33 | return 34 | } 35 | 36 | storeDataFile := fmt.Sprintf("%d.utxostore.bz2", testBlockNum) 37 | view, err := loadUtxoView(storeDataFile) 38 | if err != nil { 39 | t.Errorf("Error loading txstore: %v\n", err) 40 | return 41 | } 42 | 43 | scriptFlags := txscript.ScriptBip16 44 | err = checkBlockScripts(blocks[0], view, scriptFlags, nil, nil) 45 | if err != nil { 46 | t.Errorf("Transaction script validation failed: %v\n", err) 47 | return 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /blockchain/testdata/277647.dat.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ltcsuite-archive/ltcd/01737289d815e0e32c91e55593ba2fbd8d090b2c/blockchain/testdata/277647.dat.bz2 -------------------------------------------------------------------------------- /blockchain/testdata/277647.utxostore.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ltcsuite-archive/ltcd/01737289d815e0e32c91e55593ba2fbd8d090b2c/blockchain/testdata/277647.utxostore.bz2 -------------------------------------------------------------------------------- /blockchain/testdata/blk_0_to_4.dat.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ltcsuite-archive/ltcd/01737289d815e0e32c91e55593ba2fbd8d090b2c/blockchain/testdata/blk_0_to_4.dat.bz2 -------------------------------------------------------------------------------- /blockchain/testdata/blk_3A.dat.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ltcsuite-archive/ltcd/01737289d815e0e32c91e55593ba2fbd8d090b2c/blockchain/testdata/blk_3A.dat.bz2 -------------------------------------------------------------------------------- /blockchain/testdata/blk_4A.dat.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ltcsuite-archive/ltcd/01737289d815e0e32c91e55593ba2fbd8d090b2c/blockchain/testdata/blk_4A.dat.bz2 -------------------------------------------------------------------------------- /blockchain/testdata/blk_5A.dat.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ltcsuite-archive/ltcd/01737289d815e0e32c91e55593ba2fbd8d090b2c/blockchain/testdata/blk_5A.dat.bz2 -------------------------------------------------------------------------------- /blockchain/timesorter.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2017 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package blockchain 6 | 7 | // timeSorter implements sort.Interface to allow a slice of timestamps to 8 | // be sorted. 9 | type timeSorter []int64 10 | 11 | // Len returns the number of timestamps in the slice. It is part of the 12 | // sort.Interface implementation. 13 | func (s timeSorter) Len() int { 14 | return len(s) 15 | } 16 | 17 | // Swap swaps the timestamps at the passed indices. It is part of the 18 | // sort.Interface implementation. 19 | func (s timeSorter) Swap(i, j int) { 20 | s[i], s[j] = s[j], s[i] 21 | } 22 | 23 | // Less returns whether the timstamp with index i should sort before the 24 | // timestamp with index j. It is part of the sort.Interface implementation. 25 | func (s timeSorter) Less(i, j int) bool { 26 | return s[i] < s[j] 27 | } 28 | -------------------------------------------------------------------------------- /blockchain/timesorter_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2017 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package blockchain 6 | 7 | import ( 8 | "reflect" 9 | "sort" 10 | "testing" 11 | ) 12 | 13 | // TestTimeSorter tests the timeSorter implementation. 14 | func TestTimeSorter(t *testing.T) { 15 | tests := []struct { 16 | in []int64 17 | want []int64 18 | }{ 19 | { 20 | in: []int64{ 21 | 1351228575, // Fri Oct 26 05:16:15 UTC 2012 (Block #205000) 22 | 1348310759, // Sat Sep 22 10:45:59 UTC 2012 (Block #200000) 23 | 1305758502, // Wed May 18 22:41:42 UTC 2011 (Block #125000) 24 | 1347777156, // Sun Sep 16 06:32:36 UTC 2012 (Block #199000) 25 | 1349492104, // Sat Oct 6 02:55:04 UTC 2012 (Block #202000) 26 | }, 27 | want: []int64{ 28 | 1305758502, // Wed May 18 22:41:42 UTC 2011 (Block #125000) 29 | 1347777156, // Sun Sep 16 06:32:36 UTC 2012 (Block #199000) 30 | 1348310759, // Sat Sep 22 10:45:59 UTC 2012 (Block #200000) 31 | 1349492104, // Sat Oct 6 02:55:04 UTC 2012 (Block #202000) 32 | 1351228575, // Fri Oct 26 05:16:15 UTC 2012 (Block #205000) 33 | }, 34 | }, 35 | } 36 | 37 | for i, test := range tests { 38 | result := make([]int64, len(test.in)) 39 | copy(result, test.in) 40 | sort.Sort(timeSorter(result)) 41 | if !reflect.DeepEqual(result, test.want) { 42 | t.Errorf("timeSorter #%d got %v want %v", i, result, 43 | test.want) 44 | continue 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /blocklogger.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "sync" 5 | "time" 6 | 7 | "github.com/btcsuite/btclog" 8 | "github.com/ltcsuite/ltcutil" 9 | ) 10 | 11 | // blockProgressLogger provides periodic logging for other services in order 12 | // to show users progress of certain "actions" involving some or all current 13 | // blocks. Ex: syncing to best chain, indexing all blocks, etc. 14 | type blockProgressLogger struct { 15 | receivedLogBlocks int64 16 | receivedLogTx int64 17 | lastBlockLogTime time.Time 18 | 19 | subsystemLogger btclog.Logger 20 | progressAction string 21 | sync.Mutex 22 | } 23 | 24 | // newBlockProgressLogger returns a new block progress logger. 25 | // The progress message is templated as follows: 26 | // {progressAction} {numProcessed} {blocks|block} in the last {timePeriod} 27 | // ({numTxs}, height {lastBlockHeight}, {lastBlockTimeStamp}) 28 | func newBlockProgressLogger(progressMessage string, logger btclog.Logger) *blockProgressLogger { 29 | return &blockProgressLogger{ 30 | lastBlockLogTime: time.Now(), 31 | progressAction: progressMessage, 32 | subsystemLogger: logger, 33 | } 34 | } 35 | 36 | // LogBlockHeight logs a new block height as an information message to show 37 | // progress to the user. In order to prevent spam, it limits logging to one 38 | // message every 10 seconds with duration and totals included. 39 | func (b *blockProgressLogger) LogBlockHeight(block *ltcutil.Block) { 40 | b.Lock() 41 | defer b.Unlock() 42 | 43 | b.receivedLogBlocks++ 44 | b.receivedLogTx += int64(len(block.MsgBlock().Transactions)) 45 | 46 | now := time.Now() 47 | duration := now.Sub(b.lastBlockLogTime) 48 | if duration < time.Second*10 { 49 | return 50 | } 51 | 52 | // Truncate the duration to 10s of milliseconds. 53 | durationMillis := int64(duration / time.Millisecond) 54 | tDuration := 10 * time.Millisecond * time.Duration(durationMillis/10) 55 | 56 | // Log information about new block height. 57 | blockStr := "blocks" 58 | if b.receivedLogBlocks == 1 { 59 | blockStr = "block" 60 | } 61 | txStr := "transactions" 62 | if b.receivedLogTx == 1 { 63 | txStr = "transaction" 64 | } 65 | b.subsystemLogger.Infof("%s %d %s in the last %s (%d %s, height %d, %s)", 66 | b.progressAction, b.receivedLogBlocks, blockStr, tDuration, b.receivedLogTx, 67 | txStr, block.Height(), block.MsgBlock().Header.Timestamp) 68 | 69 | b.receivedLogBlocks = 0 70 | b.receivedLogTx = 0 71 | b.lastBlockLogTime = now 72 | } 73 | 74 | func (b *blockProgressLogger) SetLastLogTime(time time.Time) { 75 | b.lastBlockLogTime = time 76 | } 77 | -------------------------------------------------------------------------------- /btcec/README.md: -------------------------------------------------------------------------------- 1 | btcec 2 | ===== 3 | 4 | [![Build Status](https://travis-ci.org/ltcsuite/ltcd.png?branch=master)] 5 | (https://travis-ci.org/btcsuite/btcec) [![ISC License] 6 | (http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 7 | [![GoDoc](https://godoc.org/github.com/ltcsuite/ltcd/btcec?status.png)] 8 | (http://godoc.org/github.com/ltcsuite/ltcd/btcec) 9 | 10 | Package btcec implements elliptic curve cryptography needed for working with 11 | Bitcoin (secp256k1 only for now). It is designed so that it may be used with the 12 | standard crypto/ecdsa packages provided with go. A comprehensive suite of test 13 | is provided to ensure proper functionality. Package btcec was originally based 14 | on work from ThePiachu which is licensed under the same terms as Go, but it has 15 | signficantly diverged since then. The btcsuite developers original is licensed 16 | under the liberal ISC license. 17 | 18 | Although this package was primarily written for ltcd, it has intentionally been 19 | designed so it can be used as a standalone package for any projects needing to 20 | use secp256k1 elliptic curve cryptography. 21 | 22 | ## Installation and Updating 23 | 24 | ```bash 25 | $ go get -u github.com/ltcsuite/ltcd/btcec 26 | ``` 27 | 28 | ## Examples 29 | 30 | * [Sign Message] 31 | (http://godoc.org/github.com/ltcsuite/ltcd/btcec#example-package--SignMessage) 32 | Demonstrates signing a message with a secp256k1 private key that is first 33 | parsed form raw bytes and serializing the generated signature. 34 | 35 | * [Verify Signature] 36 | (http://godoc.org/github.com/ltcsuite/ltcd/btcec#example-package--VerifySignature) 37 | Demonstrates verifying a secp256k1 signature against a public key that is 38 | first parsed from raw bytes. The signature is also parsed from raw bytes. 39 | 40 | * [Encryption] 41 | (http://godoc.org/github.com/ltcsuite/ltcd/btcec#example-package--EncryptMessage) 42 | Demonstrates encrypting a message for a public key that is first parsed from 43 | raw bytes, then decrypting it using the corresponding private key. 44 | 45 | * [Decryption] 46 | (http://godoc.org/github.com/ltcsuite/ltcd/btcec#example-package--DecryptMessage) 47 | Demonstrates decrypting a message using a private key that is first parsed 48 | from raw bytes. 49 | 50 | ## GPG Verification Key 51 | 52 | All official release tags are signed by Conformal so users can ensure the code 53 | has not been tampered with and is coming from the btcsuite developers. To 54 | verify the signature perform the following: 55 | 56 | - Download the public key from the Conformal website at 57 | https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt 58 | 59 | - Import the public key into your GPG keyring: 60 | ```bash 61 | gpg --import GIT-GPG-KEY-conformal.txt 62 | ``` 63 | 64 | - Verify the release tag with the following command where `TAG_NAME` is a 65 | placeholder for the specific tag: 66 | ```bash 67 | git tag -v TAG_NAME 68 | ``` 69 | 70 | ## License 71 | 72 | Package btcec is licensed under the [copyfree](http://copyfree.org) ISC License 73 | except for btcec.go and btcec_test.go which is under the same license as Go. 74 | 75 | -------------------------------------------------------------------------------- /btcec/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package btcec implements support for the elliptic curves needed for bitcoin. 7 | 8 | Bitcoin uses elliptic curve cryptography using koblitz curves 9 | (specifically secp256k1) for cryptographic functions. See 10 | http://www.secg.org/collateral/sec2_final.pdf for details on the 11 | standard. 12 | 13 | This package provides the data structures and functions implementing the 14 | crypto/elliptic Curve interface in order to permit using these curves 15 | with the standard crypto/ecdsa package provided with go. Helper 16 | functionality is provided to parse signatures and public keys from 17 | standard formats. It was designed for use with ltcd, but should be 18 | general enough for other uses of elliptic curve crypto. It was originally based 19 | on some initial work by ThePiachu, but has significantly diverged since then. 20 | */ 21 | package btcec 22 | -------------------------------------------------------------------------------- /btcec/genprecomps.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | // This file is ignored during the regular build due to the following build tag. 6 | // It is called by go generate and used to automatically generate pre-computed 7 | // tables used to accelerate operations. 8 | // +build ignore 9 | 10 | package main 11 | 12 | import ( 13 | "bytes" 14 | "compress/zlib" 15 | "encoding/base64" 16 | "fmt" 17 | "log" 18 | "os" 19 | 20 | "github.com/ltcsuite/ltcd/btcec" 21 | ) 22 | 23 | func main() { 24 | fi, err := os.Create("secp256k1.go") 25 | if err != nil { 26 | log.Fatal(err) 27 | } 28 | defer fi.Close() 29 | 30 | // Compress the serialized byte points. 31 | serialized := btcec.S256().SerializedBytePoints() 32 | var compressed bytes.Buffer 33 | w := zlib.NewWriter(&compressed) 34 | if _, err := w.Write(serialized); err != nil { 35 | fmt.Println(err) 36 | os.Exit(1) 37 | } 38 | w.Close() 39 | 40 | // Encode the compressed byte points with base64. 41 | encoded := make([]byte, base64.StdEncoding.EncodedLen(compressed.Len())) 42 | base64.StdEncoding.Encode(encoded, compressed.Bytes()) 43 | 44 | fmt.Fprintln(fi, "// Copyright (c) 2015 The btcsuite developers") 45 | fmt.Fprintln(fi, "// Use of this source code is governed by an ISC") 46 | fmt.Fprintln(fi, "// license that can be found in the LICENSE file.") 47 | fmt.Fprintln(fi) 48 | fmt.Fprintln(fi, "package btcec") 49 | fmt.Fprintln(fi) 50 | fmt.Fprintln(fi, "// Auto-generated file (see genprecomps.go)") 51 | fmt.Fprintln(fi, "// DO NOT EDIT") 52 | fmt.Fprintln(fi) 53 | fmt.Fprintf(fi, "var secp256k1BytePoints = %q\n", string(encoded)) 54 | 55 | a1, b1, a2, b2 := btcec.S256().EndomorphismVectors() 56 | fmt.Println("The following values are the computed linearly " + 57 | "independent vectors needed to make use of the secp256k1 " + 58 | "endomorphism:") 59 | fmt.Printf("a1: %x\n", a1) 60 | fmt.Printf("b1: %x\n", b1) 61 | fmt.Printf("a2: %x\n", a2) 62 | fmt.Printf("b2: %x\n", b2) 63 | } 64 | -------------------------------------------------------------------------------- /btcec/precompute.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package btcec 6 | 7 | import ( 8 | "compress/zlib" 9 | "encoding/base64" 10 | "encoding/binary" 11 | "io/ioutil" 12 | "strings" 13 | ) 14 | 15 | //go:generate go run -tags gensecp256k1 genprecomps.go 16 | 17 | // loadS256BytePoints decompresses and deserializes the pre-computed byte points 18 | // used to accelerate scalar base multiplication for the secp256k1 curve. This 19 | // approach is used since it allows the compile to use significantly less ram 20 | // and be performed much faster than it is with hard-coding the final in-memory 21 | // data structure. At the same time, it is quite fast to generate the in-memory 22 | // data structure at init time with this approach versus computing the table. 23 | func loadS256BytePoints() error { 24 | // There will be no byte points to load when generating them. 25 | bp := secp256k1BytePoints 26 | if len(bp) == 0 { 27 | return nil 28 | } 29 | 30 | // Decompress the pre-computed table used to accelerate scalar base 31 | // multiplication. 32 | decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(bp)) 33 | r, err := zlib.NewReader(decoder) 34 | if err != nil { 35 | return err 36 | } 37 | serialized, err := ioutil.ReadAll(r) 38 | if err != nil { 39 | return err 40 | } 41 | 42 | // Deserialize the precomputed byte points and set the curve to them. 43 | offset := 0 44 | var bytePoints [32][256][3]fieldVal 45 | for byteNum := 0; byteNum < 32; byteNum++ { 46 | // All points in this window. 47 | for i := 0; i < 256; i++ { 48 | px := &bytePoints[byteNum][i][0] 49 | py := &bytePoints[byteNum][i][1] 50 | pz := &bytePoints[byteNum][i][2] 51 | for i := 0; i < 10; i++ { 52 | px.n[i] = binary.LittleEndian.Uint32(serialized[offset:]) 53 | offset += 4 54 | } 55 | for i := 0; i < 10; i++ { 56 | py.n[i] = binary.LittleEndian.Uint32(serialized[offset:]) 57 | offset += 4 58 | } 59 | for i := 0; i < 10; i++ { 60 | pz.n[i] = binary.LittleEndian.Uint32(serialized[offset:]) 61 | offset += 4 62 | } 63 | } 64 | } 65 | secp256k1.bytePoints = &bytePoints 66 | return nil 67 | } 68 | -------------------------------------------------------------------------------- /btcec/privkey.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package btcec 6 | 7 | import ( 8 | "crypto/ecdsa" 9 | "crypto/elliptic" 10 | "crypto/rand" 11 | "math/big" 12 | ) 13 | 14 | // PrivateKey wraps an ecdsa.PrivateKey as a convenience mainly for signing 15 | // things with the the private key without having to directly import the ecdsa 16 | // package. 17 | type PrivateKey ecdsa.PrivateKey 18 | 19 | // PrivKeyFromBytes returns a private and public key for `curve' based on the 20 | // private key passed as an argument as a byte slice. 21 | func PrivKeyFromBytes(curve elliptic.Curve, pk []byte) (*PrivateKey, 22 | *PublicKey) { 23 | x, y := curve.ScalarBaseMult(pk) 24 | 25 | priv := &ecdsa.PrivateKey{ 26 | PublicKey: ecdsa.PublicKey{ 27 | Curve: curve, 28 | X: x, 29 | Y: y, 30 | }, 31 | D: new(big.Int).SetBytes(pk), 32 | } 33 | 34 | return (*PrivateKey)(priv), (*PublicKey)(&priv.PublicKey) 35 | } 36 | 37 | // NewPrivateKey is a wrapper for ecdsa.GenerateKey that returns a PrivateKey 38 | // instead of the normal ecdsa.PrivateKey. 39 | func NewPrivateKey(curve elliptic.Curve) (*PrivateKey, error) { 40 | key, err := ecdsa.GenerateKey(curve, rand.Reader) 41 | if err != nil { 42 | return nil, err 43 | } 44 | return (*PrivateKey)(key), nil 45 | } 46 | 47 | // PubKey returns the PublicKey corresponding to this private key. 48 | func (p *PrivateKey) PubKey() *PublicKey { 49 | return (*PublicKey)(&p.PublicKey) 50 | } 51 | 52 | // ToECDSA returns the private key as a *ecdsa.PrivateKey. 53 | func (p *PrivateKey) ToECDSA() *ecdsa.PrivateKey { 54 | return (*ecdsa.PrivateKey)(p) 55 | } 56 | 57 | // Sign generates an ECDSA signature for the provided hash (which should be the result 58 | // of hashing a larger message) using the private key. Produced signature 59 | // is deterministic (same message and same key yield the same signature) and canonical 60 | // in accordance with RFC6979 and BIP0062. 61 | func (p *PrivateKey) Sign(hash []byte) (*Signature, error) { 62 | return signRFC6979(p, hash) 63 | } 64 | 65 | // PrivKeyBytesLen defines the length in bytes of a serialized private key. 66 | const PrivKeyBytesLen = 32 67 | 68 | // Serialize returns the private key number d as a big-endian binary-encoded 69 | // number, padded to a length of 32 bytes. 70 | func (p *PrivateKey) Serialize() []byte { 71 | b := make([]byte, 0, PrivKeyBytesLen) 72 | return paddedAppend(PrivKeyBytesLen, b, p.ToECDSA().D.Bytes()) 73 | } 74 | -------------------------------------------------------------------------------- /btcec/privkey_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package btcec 6 | 7 | import ( 8 | "bytes" 9 | "testing" 10 | ) 11 | 12 | func TestPrivKeys(t *testing.T) { 13 | tests := []struct { 14 | name string 15 | key []byte 16 | }{ 17 | { 18 | name: "check curve", 19 | key: []byte{ 20 | 0xea, 0xf0, 0x2c, 0xa3, 0x48, 0xc5, 0x24, 0xe6, 21 | 0x39, 0x26, 0x55, 0xba, 0x4d, 0x29, 0x60, 0x3c, 22 | 0xd1, 0xa7, 0x34, 0x7d, 0x9d, 0x65, 0xcf, 0xe9, 23 | 0x3c, 0xe1, 0xeb, 0xff, 0xdc, 0xa2, 0x26, 0x94, 24 | }, 25 | }, 26 | } 27 | 28 | for _, test := range tests { 29 | priv, pub := PrivKeyFromBytes(S256(), test.key) 30 | 31 | _, err := ParsePubKey(pub.SerializeUncompressed(), S256()) 32 | if err != nil { 33 | t.Errorf("%s privkey: %v", test.name, err) 34 | continue 35 | } 36 | 37 | hash := []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9} 38 | sig, err := priv.Sign(hash) 39 | if err != nil { 40 | t.Errorf("%s could not sign: %v", test.name, err) 41 | continue 42 | } 43 | 44 | if !sig.Verify(hash, pub) { 45 | t.Errorf("%s could not verify: %v", test.name, err) 46 | continue 47 | } 48 | 49 | serializedKey := priv.Serialize() 50 | if !bytes.Equal(serializedKey, test.key) { 51 | t.Errorf("%s unexpected serialized bytes - got: %x, "+ 52 | "want: %x", test.name, serializedKey, test.key) 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /btcjson/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This is the list of people who have contributed code to the repository. 2 | # 3 | # Names should be added to this file only after verifying that the individual 4 | # or the individual's organization has agreed to the LICENSE. 5 | # 6 | # Names should be added to this file like so: 7 | # Name 8 | 9 | John C. Vernaleo 10 | Dave Collins 11 | Owain G. Ainsworth 12 | David Hill 13 | Josh Rickmar 14 | Andreas Metsälä 15 | Francis Lam 16 | Geert-Johan Riemer 17 | -------------------------------------------------------------------------------- /btcjson/README.md: -------------------------------------------------------------------------------- 1 | btcjson 2 | ======= 3 | 4 | [![Build Status](https://travis-ci.org/ltcsuite/ltcd.png?branch=master)] 5 | (https://travis-ci.org/ltcsuite/ltcd) [![ISC License] 6 | (http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 7 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)] 8 | (http://godoc.org/github.com/ltcsuite/ltcd/btcjson) 9 | 10 | Package btcjson implements concrete types for marshalling to and from the 11 | bitcoin JSON-RPC API. A comprehensive suite of tests is provided to ensure 12 | proper functionality. 13 | 14 | Although this package was primarily written for the btcsuite, it has 15 | intentionally been designed so it can be used as a standalone package for any 16 | projects needing to marshal to and from bitcoin JSON-RPC requests and responses. 17 | 18 | Note that although it's possible to use this package directly to implement an 19 | RPC client, it is not recommended since it is only intended as an infrastructure 20 | package. Instead, RPC clients should use the 21 | [btcrpcclient](https://github.com/roasbeef/btcrpcclient) package which provides 22 | a full blown RPC client with many features such as automatic connection 23 | management, websocket support, automatic notification re-registration on 24 | reconnect, and conversion from the raw underlying RPC types (strings, floats, 25 | ints, etc) to higher-level types with many nice and useful properties. 26 | 27 | ## Installation and Updating 28 | 29 | ```bash 30 | $ go get -u github.com/ltcsuite/ltcd/btcjson 31 | ``` 32 | 33 | ## Examples 34 | 35 | * [Marshal Command] 36 | (http://godoc.org/github.com/ltcsuite/ltcd/btcjson#example-MarshalCmd) 37 | Demonstrates how to create and marshal a command into a JSON-RPC request. 38 | 39 | * [Unmarshal Command] 40 | (http://godoc.org/github.com/ltcsuite/ltcd/btcjson#example-UnmarshalCmd) 41 | Demonstrates how to unmarshal a JSON-RPC request and then unmarshal the 42 | concrete request into a concrete command. 43 | 44 | * [Marshal Response] 45 | (http://godoc.org/github.com/ltcsuite/ltcd/btcjson#example-MarshalResponse) 46 | Demonstrates how to marshal a JSON-RPC response. 47 | 48 | * [Unmarshal Response] 49 | (http://godoc.org/github.com/ltcsuite/ltcd/btcjson#example-package--UnmarshalResponse) 50 | Demonstrates how to unmarshal a JSON-RPC response and then unmarshal the 51 | result field in the response to a concrete type. 52 | 53 | ## GPG Verification Key 54 | 55 | All official release tags are signed by Conformal so users can ensure the code 56 | has not been tampered with and is coming from the btcsuite developers. To 57 | verify the signature perform the following: 58 | 59 | - Download the public key from the Conformal website at 60 | https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt 61 | 62 | - Import the public key into your GPG keyring: 63 | ```bash 64 | gpg --import GIT-GPG-KEY-conformal.txt 65 | ``` 66 | 67 | - Verify the release tag with the following command where `TAG_NAME` is a 68 | placeholder for the specific tag: 69 | ```bash 70 | git tag -v TAG_NAME 71 | ``` 72 | 73 | ## License 74 | 75 | Package btcjson is licensed under the [copyfree](http://copyfree.org) ISC 76 | License. 77 | -------------------------------------------------------------------------------- /btcjson/btcdextresults.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 The btcsuite developers 2 | // Copyright (c) 2015-2017 The Decred developers 3 | // Use of this source code is governed by an ISC 4 | // license that can be found in the LICENSE file. 5 | 6 | package btcjson 7 | 8 | // VersionResult models objects included in the version response. In the actual 9 | // result, these objects are keyed by the program or API name. 10 | // 11 | // NOTE: This is a btcsuite extension ported from 12 | // github.com/decred/dcrd/dcrjson. 13 | type VersionResult struct { 14 | VersionString string `json:"versionstring"` 15 | Major uint32 `json:"major"` 16 | Minor uint32 `json:"minor"` 17 | Patch uint32 `json:"patch"` 18 | Prerelease string `json:"prerelease"` 19 | BuildMetadata string `json:"buildmetadata"` 20 | } 21 | -------------------------------------------------------------------------------- /btcjson/btcdextresults_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 The btcsuite developers 2 | // Copyright (c) 2015-2016 The Decred developers 3 | // Use of this source code is governed by an ISC 4 | // license that can be found in the LICENSE file. 5 | 6 | package btcjson_test 7 | 8 | import ( 9 | "encoding/json" 10 | "testing" 11 | 12 | "github.com/ltcsuite/ltcd/btcjson" 13 | ) 14 | 15 | // TestBtcdExtCustomResults ensures any results that have custom marshalling 16 | // work as inteded. 17 | // and unmarshal code of results are as expected. 18 | func TestBtcdExtCustomResults(t *testing.T) { 19 | t.Parallel() 20 | 21 | tests := []struct { 22 | name string 23 | result interface{} 24 | expected string 25 | }{ 26 | { 27 | name: "versionresult", 28 | result: &btcjson.VersionResult{ 29 | VersionString: "1.0.0", 30 | Major: 1, 31 | Minor: 0, 32 | Patch: 0, 33 | Prerelease: "pr", 34 | BuildMetadata: "bm", 35 | }, 36 | expected: `{"versionstring":"1.0.0","major":1,"minor":0,"patch":0,"prerelease":"pr","buildmetadata":"bm"}`, 37 | }, 38 | } 39 | 40 | t.Logf("Running %d tests", len(tests)) 41 | for i, test := range tests { 42 | marshalled, err := json.Marshal(test.result) 43 | if err != nil { 44 | t.Errorf("Test #%d (%s) unexpected error: %v", i, 45 | test.name, err) 46 | continue 47 | } 48 | if string(marshalled) != test.expected { 49 | t.Errorf("Test #%d (%s) unexpected marhsalled data - "+ 50 | "got %s, want %s", i, test.name, marshalled, 51 | test.expected) 52 | continue 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /btcjson/chainsvrresults_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package btcjson_test 6 | 7 | import ( 8 | "encoding/json" 9 | "testing" 10 | 11 | "github.com/ltcsuite/ltcd/btcjson" 12 | ) 13 | 14 | // TestChainSvrCustomResults ensures any results that have custom marshalling 15 | // work as inteded. 16 | // and unmarshal code of results are as expected. 17 | func TestChainSvrCustomResults(t *testing.T) { 18 | t.Parallel() 19 | 20 | tests := []struct { 21 | name string 22 | result interface{} 23 | expected string 24 | }{ 25 | { 26 | name: "custom vin marshal with coinbase", 27 | result: &btcjson.Vin{ 28 | Coinbase: "021234", 29 | Sequence: 4294967295, 30 | }, 31 | expected: `{"coinbase":"021234","sequence":4294967295}`, 32 | }, 33 | { 34 | name: "custom vin marshal without coinbase", 35 | result: &btcjson.Vin{ 36 | Txid: "123", 37 | Vout: 1, 38 | ScriptSig: &btcjson.ScriptSig{ 39 | Asm: "0", 40 | Hex: "00", 41 | }, 42 | Sequence: 4294967295, 43 | }, 44 | expected: `{"txid":"123","vout":1,"scriptSig":{"asm":"0","hex":"00"},"sequence":4294967295}`, 45 | }, 46 | { 47 | name: "custom vinprevout marshal with coinbase", 48 | result: &btcjson.VinPrevOut{ 49 | Coinbase: "021234", 50 | Sequence: 4294967295, 51 | }, 52 | expected: `{"coinbase":"021234","sequence":4294967295}`, 53 | }, 54 | { 55 | name: "custom vinprevout marshal without coinbase", 56 | result: &btcjson.VinPrevOut{ 57 | Txid: "123", 58 | Vout: 1, 59 | ScriptSig: &btcjson.ScriptSig{ 60 | Asm: "0", 61 | Hex: "00", 62 | }, 63 | PrevOut: &btcjson.PrevOut{ 64 | Addresses: []string{"addr1"}, 65 | Value: 0, 66 | }, 67 | Sequence: 4294967295, 68 | }, 69 | expected: `{"txid":"123","vout":1,"scriptSig":{"asm":"0","hex":"00"},"prevOut":{"addresses":["addr1"],"value":0},"sequence":4294967295}`, 70 | }, 71 | } 72 | 73 | t.Logf("Running %d tests", len(tests)) 74 | for i, test := range tests { 75 | marshalled, err := json.Marshal(test.result) 76 | if err != nil { 77 | t.Errorf("Test #%d (%s) unexpected error: %v", i, 78 | test.name, err) 79 | continue 80 | } 81 | if string(marshalled) != test.expected { 82 | t.Errorf("Test #%d (%s) unexpected marhsalled data - "+ 83 | "got %s, want %s", i, test.name, marshalled, 84 | test.expected) 85 | continue 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /btcjson/chainsvrwsresults.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 The btcsuite developers 2 | // Copyright (c) 2015-2017 The Decred developers 3 | // Use of this source code is governed by an ISC 4 | // license that can be found in the LICENSE file. 5 | 6 | package btcjson 7 | 8 | // SessionResult models the data from the session command. 9 | type SessionResult struct { 10 | SessionID uint64 `json:"sessionid"` 11 | } 12 | 13 | // RescannedBlock contains the hash and all discovered transactions of a single 14 | // rescanned block. 15 | // 16 | // NOTE: This is a btcsuite extension ported from 17 | // github.com/decred/dcrd/dcrjson. 18 | type RescannedBlock struct { 19 | Hash string `json:"hash"` 20 | Transactions []string `json:"transactions"` 21 | } 22 | -------------------------------------------------------------------------------- /btcjson/chainsvrwsresults_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 The btcsuite developers 2 | // Copyright (c) 2017 The Decred developers 3 | // Use of this source code is governed by an ISC 4 | // license that can be found in the LICENSE file. 5 | 6 | package btcjson_test 7 | 8 | import ( 9 | "encoding/json" 10 | "testing" 11 | 12 | "github.com/ltcsuite/ltcd/btcjson" 13 | ) 14 | 15 | // TestChainSvrWsResults ensures any results that have custom marshalling 16 | // work as inteded. 17 | func TestChainSvrWsResults(t *testing.T) { 18 | t.Parallel() 19 | 20 | tests := []struct { 21 | name string 22 | result interface{} 23 | expected string 24 | }{ 25 | { 26 | name: "RescannedBlock", 27 | result: &btcjson.RescannedBlock{ 28 | Hash: "blockhash", 29 | Transactions: []string{"serializedtx"}, 30 | }, 31 | expected: `{"hash":"blockhash","transactions":["serializedtx"]}`, 32 | }, 33 | } 34 | 35 | t.Logf("Running %d tests", len(tests)) 36 | for i, test := range tests { 37 | marshalled, err := json.Marshal(test.result) 38 | if err != nil { 39 | t.Errorf("Test #%d (%s) unexpected error: %v", i, 40 | test.name, err) 41 | continue 42 | } 43 | if string(marshalled) != test.expected { 44 | t.Errorf("Test #%d (%s) unexpected marhsalled data - "+ 45 | "got %s, want %s", i, test.name, marshalled, 46 | test.expected) 47 | continue 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /btcjson/error_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package btcjson_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/ltcsuite/ltcd/btcjson" 11 | ) 12 | 13 | // TestErrorCodeStringer tests the stringized output for the ErrorCode type. 14 | func TestErrorCodeStringer(t *testing.T) { 15 | t.Parallel() 16 | 17 | tests := []struct { 18 | in btcjson.ErrorCode 19 | want string 20 | }{ 21 | {btcjson.ErrDuplicateMethod, "ErrDuplicateMethod"}, 22 | {btcjson.ErrInvalidUsageFlags, "ErrInvalidUsageFlags"}, 23 | {btcjson.ErrInvalidType, "ErrInvalidType"}, 24 | {btcjson.ErrEmbeddedType, "ErrEmbeddedType"}, 25 | {btcjson.ErrUnexportedField, "ErrUnexportedField"}, 26 | {btcjson.ErrUnsupportedFieldType, "ErrUnsupportedFieldType"}, 27 | {btcjson.ErrNonOptionalField, "ErrNonOptionalField"}, 28 | {btcjson.ErrNonOptionalDefault, "ErrNonOptionalDefault"}, 29 | {btcjson.ErrMismatchedDefault, "ErrMismatchedDefault"}, 30 | {btcjson.ErrUnregisteredMethod, "ErrUnregisteredMethod"}, 31 | {btcjson.ErrNumParams, "ErrNumParams"}, 32 | {btcjson.ErrMissingDescription, "ErrMissingDescription"}, 33 | {0xffff, "Unknown ErrorCode (65535)"}, 34 | } 35 | 36 | // Detect additional error codes that don't have the stringer added. 37 | if len(tests)-1 != int(btcjson.TstNumErrorCodes) { 38 | t.Errorf("It appears an error code was added without adding an " + 39 | "associated stringer test") 40 | } 41 | 42 | t.Logf("Running %d tests", len(tests)) 43 | for i, test := range tests { 44 | result := test.in.String() 45 | if result != test.want { 46 | t.Errorf("String #%d\n got: %s want: %s", i, result, 47 | test.want) 48 | continue 49 | } 50 | } 51 | } 52 | 53 | // TestError tests the error output for the Error type. 54 | func TestError(t *testing.T) { 55 | t.Parallel() 56 | 57 | tests := []struct { 58 | in btcjson.Error 59 | want string 60 | }{ 61 | { 62 | btcjson.Error{Description: "some error"}, 63 | "some error", 64 | }, 65 | { 66 | btcjson.Error{Description: "human-readable error"}, 67 | "human-readable error", 68 | }, 69 | } 70 | 71 | t.Logf("Running %d tests", len(tests)) 72 | for i, test := range tests { 73 | result := test.in.Error() 74 | if result != test.want { 75 | t.Errorf("Error #%d\n got: %s want: %s", i, result, 76 | test.want) 77 | continue 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /btcjson/export_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package btcjson 6 | 7 | // TstHighestUsageFlagBit makes the internal highestUsageFlagBit parameter 8 | // available to the test package. 9 | var TstHighestUsageFlagBit = highestUsageFlagBit 10 | 11 | // TstNumErrorCodes makes the internal numErrorCodes parameter available to the 12 | // test package. 13 | var TstNumErrorCodes = numErrorCodes 14 | 15 | // TstAssignField makes the internal assignField function available to the test 16 | // package. 17 | var TstAssignField = assignField 18 | 19 | // TstFieldUsage makes the internal fieldUsage function available to the test 20 | // package. 21 | var TstFieldUsage = fieldUsage 22 | 23 | // TstReflectTypeToJSONType makes the internal reflectTypeToJSONType function 24 | // available to the test package. 25 | var TstReflectTypeToJSONType = reflectTypeToJSONType 26 | 27 | // TstResultStructHelp makes the internal resultStructHelp function available to 28 | // the test package. 29 | var TstResultStructHelp = resultStructHelp 30 | 31 | // TstReflectTypeToJSONExample makes the internal reflectTypeToJSONExample 32 | // function available to the test package. 33 | var TstReflectTypeToJSONExample = reflectTypeToJSONExample 34 | 35 | // TstResultTypeHelp makes the internal resultTypeHelp function available to the 36 | // test package. 37 | var TstResultTypeHelp = resultTypeHelp 38 | 39 | // TstArgHelp makes the internal argHelp function available to the test package. 40 | var TstArgHelp = argHelp 41 | 42 | // TestMethodHelp makes the internal methodHelp function available to the test 43 | // package. 44 | var TestMethodHelp = methodHelp 45 | 46 | // TstIsValidResultType makes the internal isValidResultType function available 47 | // to the test package. 48 | var TstIsValidResultType = isValidResultType 49 | -------------------------------------------------------------------------------- /btcjson/helpers.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package btcjson 6 | 7 | // Bool is a helper routine that allocates a new bool value to store v and 8 | // returns a pointer to it. This is useful when assigning optional parameters. 9 | func Bool(v bool) *bool { 10 | p := new(bool) 11 | *p = v 12 | return p 13 | } 14 | 15 | // Int is a helper routine that allocates a new int value to store v and 16 | // returns a pointer to it. This is useful when assigning optional parameters. 17 | func Int(v int) *int { 18 | p := new(int) 19 | *p = v 20 | return p 21 | } 22 | 23 | // Uint is a helper routine that allocates a new uint value to store v and 24 | // returns a pointer to it. This is useful when assigning optional parameters. 25 | func Uint(v uint) *uint { 26 | p := new(uint) 27 | *p = v 28 | return p 29 | } 30 | 31 | // Int32 is a helper routine that allocates a new int32 value to store v and 32 | // returns a pointer to it. This is useful when assigning optional parameters. 33 | func Int32(v int32) *int32 { 34 | p := new(int32) 35 | *p = v 36 | return p 37 | } 38 | 39 | // Uint32 is a helper routine that allocates a new uint32 value to store v and 40 | // returns a pointer to it. This is useful when assigning optional parameters. 41 | func Uint32(v uint32) *uint32 { 42 | p := new(uint32) 43 | *p = v 44 | return p 45 | } 46 | 47 | // Int64 is a helper routine that allocates a new int64 value to store v and 48 | // returns a pointer to it. This is useful when assigning optional parameters. 49 | func Int64(v int64) *int64 { 50 | p := new(int64) 51 | *p = v 52 | return p 53 | } 54 | 55 | // Uint64 is a helper routine that allocates a new uint64 value to store v and 56 | // returns a pointer to it. This is useful when assigning optional parameters. 57 | func Uint64(v uint64) *uint64 { 58 | p := new(uint64) 59 | *p = v 60 | return p 61 | } 62 | 63 | // Float64 is a helper routine that allocates a new float64 value to store v and 64 | // returns a pointer to it. This is useful when assigning optional parameters. 65 | func Float64(v float64) *float64 { 66 | p := new(float64) 67 | *p = v 68 | return p 69 | } 70 | 71 | // String is a helper routine that allocates a new string value to store v and 72 | // returns a pointer to it. This is useful when assigning optional parameters. 73 | func String(v string) *string { 74 | p := new(string) 75 | *p = v 76 | return p 77 | } 78 | -------------------------------------------------------------------------------- /btcjson/helpers_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package btcjson_test 6 | 7 | import ( 8 | "reflect" 9 | "testing" 10 | 11 | "github.com/ltcsuite/ltcd/btcjson" 12 | ) 13 | 14 | // TestHelpers tests the various helper functions which create pointers to 15 | // primitive types. 16 | func TestHelpers(t *testing.T) { 17 | t.Parallel() 18 | 19 | tests := []struct { 20 | name string 21 | f func() interface{} 22 | expected interface{} 23 | }{ 24 | { 25 | name: "bool", 26 | f: func() interface{} { 27 | return btcjson.Bool(true) 28 | }, 29 | expected: func() interface{} { 30 | val := true 31 | return &val 32 | }(), 33 | }, 34 | { 35 | name: "int", 36 | f: func() interface{} { 37 | return btcjson.Int(5) 38 | }, 39 | expected: func() interface{} { 40 | val := int(5) 41 | return &val 42 | }(), 43 | }, 44 | { 45 | name: "uint", 46 | f: func() interface{} { 47 | return btcjson.Uint(5) 48 | }, 49 | expected: func() interface{} { 50 | val := uint(5) 51 | return &val 52 | }(), 53 | }, 54 | { 55 | name: "int32", 56 | f: func() interface{} { 57 | return btcjson.Int32(5) 58 | }, 59 | expected: func() interface{} { 60 | val := int32(5) 61 | return &val 62 | }(), 63 | }, 64 | { 65 | name: "uint32", 66 | f: func() interface{} { 67 | return btcjson.Uint32(5) 68 | }, 69 | expected: func() interface{} { 70 | val := uint32(5) 71 | return &val 72 | }(), 73 | }, 74 | { 75 | name: "int64", 76 | f: func() interface{} { 77 | return btcjson.Int64(5) 78 | }, 79 | expected: func() interface{} { 80 | val := int64(5) 81 | return &val 82 | }(), 83 | }, 84 | { 85 | name: "uint64", 86 | f: func() interface{} { 87 | return btcjson.Uint64(5) 88 | }, 89 | expected: func() interface{} { 90 | val := uint64(5) 91 | return &val 92 | }(), 93 | }, 94 | { 95 | name: "string", 96 | f: func() interface{} { 97 | return btcjson.String("abc") 98 | }, 99 | expected: func() interface{} { 100 | val := "abc" 101 | return &val 102 | }(), 103 | }, 104 | } 105 | 106 | t.Logf("Running %d tests", len(tests)) 107 | for i, test := range tests { 108 | result := test.f() 109 | if !reflect.DeepEqual(result, test.expected) { 110 | t.Errorf("Test #%d (%s) unexpected value - got %v, "+ 111 | "want %v", i, test.name, result, test.expected) 112 | continue 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /btcjson/jsonrpcerr.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package btcjson 6 | 7 | // Standard JSON-RPC 2.0 errors. 8 | var ( 9 | ErrRPCInvalidRequest = &RPCError{ 10 | Code: -32600, 11 | Message: "Invalid request", 12 | } 13 | ErrRPCMethodNotFound = &RPCError{ 14 | Code: -32601, 15 | Message: "Method not found", 16 | } 17 | ErrRPCInvalidParams = &RPCError{ 18 | Code: -32602, 19 | Message: "Invalid parameters", 20 | } 21 | ErrRPCInternal = &RPCError{ 22 | Code: -32603, 23 | Message: "Internal error", 24 | } 25 | ErrRPCParse = &RPCError{ 26 | Code: -32700, 27 | Message: "Parse error", 28 | } 29 | ) 30 | 31 | // General application defined JSON errors. 32 | const ( 33 | ErrRPCMisc RPCErrorCode = -1 34 | ErrRPCForbiddenBySafeMode RPCErrorCode = -2 35 | ErrRPCType RPCErrorCode = -3 36 | ErrRPCInvalidAddressOrKey RPCErrorCode = -5 37 | ErrRPCOutOfMemory RPCErrorCode = -7 38 | ErrRPCInvalidParameter RPCErrorCode = -8 39 | ErrRPCDatabase RPCErrorCode = -20 40 | ErrRPCDeserialization RPCErrorCode = -22 41 | ErrRPCVerify RPCErrorCode = -25 42 | ) 43 | 44 | // Peer-to-peer client errors. 45 | const ( 46 | ErrRPCClientNotConnected RPCErrorCode = -9 47 | ErrRPCClientInInitialDownload RPCErrorCode = -10 48 | ErrRPCClientNodeNotAdded RPCErrorCode = -24 49 | ) 50 | 51 | // Wallet JSON errors 52 | const ( 53 | ErrRPCWallet RPCErrorCode = -4 54 | ErrRPCWalletInsufficientFunds RPCErrorCode = -6 55 | ErrRPCWalletInvalidAccountName RPCErrorCode = -11 56 | ErrRPCWalletKeypoolRanOut RPCErrorCode = -12 57 | ErrRPCWalletUnlockNeeded RPCErrorCode = -13 58 | ErrRPCWalletPassphraseIncorrect RPCErrorCode = -14 59 | ErrRPCWalletWrongEncState RPCErrorCode = -15 60 | ErrRPCWalletEncryptionFailed RPCErrorCode = -16 61 | ErrRPCWalletAlreadyUnlocked RPCErrorCode = -17 62 | ) 63 | 64 | // Specific Errors related to commands. These are the ones a user of the RPC 65 | // server are most likely to see. Generally, the codes should match one of the 66 | // more general errors above. 67 | const ( 68 | ErrRPCBlockNotFound RPCErrorCode = -5 69 | ErrRPCBlockCount RPCErrorCode = -5 70 | ErrRPCBestBlockHash RPCErrorCode = -5 71 | ErrRPCDifficulty RPCErrorCode = -5 72 | ErrRPCOutOfRange RPCErrorCode = -1 73 | ErrRPCNoTxInfo RPCErrorCode = -5 74 | ErrRPCNoNewestBlockInfo RPCErrorCode = -5 75 | ErrRPCInvalidTxVout RPCErrorCode = -5 76 | ErrRPCRawTxString RPCErrorCode = -32602 77 | ErrRPCDecodeHexString RPCErrorCode = -22 78 | ) 79 | 80 | // Errors that are specific to ltcd. 81 | const ( 82 | ErrRPCNoWallet RPCErrorCode = -1 83 | ErrRPCUnimplemented RPCErrorCode = -1 84 | ) 85 | -------------------------------------------------------------------------------- /chaincfg/README.md: -------------------------------------------------------------------------------- 1 | chaincfg 2 | ======== 3 | 4 | [![Build Status](http://img.shields.io/travis/ltcsuite/ltcd.svg)] 5 | (https://travis-ci.org/ltcsuite/ltcd) [![ISC License] 6 | (http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 7 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)] 8 | (http://godoc.org/github.com/ltcsuite/ltcd/chaincfg) 9 | 10 | Package chaincfg defines chain configuration parameters for the three standard 11 | Bitcoin networks and provides the ability for callers to define their own custom 12 | Bitcoin networks. 13 | 14 | Although this package was primarily written for ltcd, it has intentionally been 15 | designed so it can be used as a standalone package for any projects needing to 16 | use parameters for the standard Bitcoin networks or for projects needing to 17 | define their own network. 18 | 19 | ## Sample Use 20 | 21 | ```Go 22 | package main 23 | 24 | import ( 25 | "flag" 26 | "fmt" 27 | "log" 28 | 29 | "github.com/ltcsuite/ltcutil" 30 | "github.com/ltcsuite/ltcd/chaincfg" 31 | ) 32 | 33 | var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network") 34 | 35 | // By default (without -testnet), use mainnet. 36 | var chainParams = &chaincfg.MainNetParams 37 | 38 | func main() { 39 | flag.Parse() 40 | 41 | // Modify active network parameters if operating on testnet. 42 | if *testnet { 43 | chainParams = &chaincfg.TestNet4Params 44 | } 45 | 46 | // later... 47 | 48 | // Create and print new payment address, specific to the active network. 49 | pubKeyHash := make([]byte, 20) 50 | addr, err := ltcutil.NewAddressPubKeyHash(pubKeyHash, chainParams) 51 | if err != nil { 52 | log.Fatal(err) 53 | } 54 | fmt.Println(addr) 55 | } 56 | ``` 57 | 58 | ## Installation and Updating 59 | 60 | ```bash 61 | $ go get -u github.com/ltcsuite/ltcd/chaincfg 62 | ``` 63 | 64 | ## GPG Verification Key 65 | 66 | All official release tags are signed by Conformal so users can ensure the code 67 | has not been tampered with and is coming from the btcsuite developers. To 68 | verify the signature perform the following: 69 | 70 | - Download the public key from the Conformal website at 71 | https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt 72 | 73 | - Import the public key into your GPG keyring: 74 | ```bash 75 | gpg --import GIT-GPG-KEY-conformal.txt 76 | ``` 77 | 78 | - Verify the release tag with the following command where `TAG_NAME` is a 79 | placeholder for the specific tag: 80 | ```bash 81 | git tag -v TAG_NAME 82 | ``` 83 | 84 | ## License 85 | 86 | Package chaincfg is licensed under the [copyfree](http://copyfree.org) ISC 87 | License. 88 | -------------------------------------------------------------------------------- /chaincfg/chainhash/README.md: -------------------------------------------------------------------------------- 1 | chainhash 2 | ========= 3 | 4 | [![Build Status](http://img.shields.io/travis/ltcsuite/ltcd.svg)](https://travis-ci.org/ltcsuite/ltcd) 5 | [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 6 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/ltcsuite/ltcd/chaincfg/chainhash) 7 | 8 | chainhash provides a generic hash type and associated functions that allows the 9 | specific hash algorithm to be abstracted. 10 | 11 | ## Installation and Updating 12 | 13 | ```bash 14 | $ go get -u github.com/ltcsuite/ltcd/chaincfg/chainhash 15 | ``` 16 | 17 | ## GPG Verification Key 18 | 19 | All official release tags are signed by Conformal so users can ensure the code 20 | has not been tampered with and is coming from the btcsuite developers. To 21 | verify the signature perform the following: 22 | 23 | - Download the public key from the Conformal website at 24 | https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt 25 | 26 | - Import the public key into your GPG keyring: 27 | ```bash 28 | gpg --import GIT-GPG-KEY-conformal.txt 29 | ``` 30 | 31 | - Verify the release tag with the following command where `TAG_NAME` is a 32 | placeholder for the specific tag: 33 | ```bash 34 | git tag -v TAG_NAME 35 | ``` 36 | 37 | ## License 38 | 39 | Package chainhash is licensed under the [copyfree](http://copyfree.org) ISC 40 | License. 41 | -------------------------------------------------------------------------------- /chaincfg/chainhash/doc.go: -------------------------------------------------------------------------------- 1 | // Package chainhash provides abstracted hash functionality. 2 | // 3 | // This package provides a generic hash type and associated functions that 4 | // allows the specific hash algorithm to be abstracted. 5 | package chainhash 6 | -------------------------------------------------------------------------------- /chaincfg/chainhash/hashfuncs.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The Decred developers 2 | // Copyright (c) 2016-2017 The btcsuite developers 3 | // Use of this source code is governed by an ISC 4 | // license that can be found in the LICENSE file. 5 | 6 | package chainhash 7 | 8 | import "crypto/sha256" 9 | 10 | // HashB calculates hash(b) and returns the resulting bytes. 11 | func HashB(b []byte) []byte { 12 | hash := sha256.Sum256(b) 13 | return hash[:] 14 | } 15 | 16 | // HashH calculates hash(b) and returns the resulting bytes as a Hash. 17 | func HashH(b []byte) Hash { 18 | return Hash(sha256.Sum256(b)) 19 | } 20 | 21 | // DoubleHashB calculates hash(hash(b)) and returns the resulting bytes. 22 | func DoubleHashB(b []byte) []byte { 23 | first := sha256.Sum256(b) 24 | second := sha256.Sum256(first[:]) 25 | return second[:] 26 | } 27 | 28 | // DoubleHashH calculates hash(hash(b)) and returns the resulting bytes as a 29 | // Hash. 30 | func DoubleHashH(b []byte) Hash { 31 | first := sha256.Sum256(b) 32 | return Hash(sha256.Sum256(first[:])) 33 | } 34 | -------------------------------------------------------------------------------- /chaincfg/doc.go: -------------------------------------------------------------------------------- 1 | // Package chaincfg defines chain configuration parameters. 2 | // 3 | // In addition to the main Bitcoin network, which is intended for the transfer 4 | // of monetary value, there also exists two currently active standard networks: 5 | // regression test and testnet (version 3). These networks are incompatible 6 | // with each other (each sharing a different genesis block) and software should 7 | // handle errors where input intended for one network is used on an application 8 | // instance running on a different network. 9 | // 10 | // For library packages, chaincfg provides the ability to lookup chain 11 | // parameters and encoding magics when passed a *Params. Older APIs not updated 12 | // to the new convention of passing a *Params may lookup the parameters for a 13 | // wire.BitcoinNet using ParamsForNet, but be aware that this usage is 14 | // deprecated and will be removed from chaincfg in the future. 15 | // 16 | // For main packages, a (typically global) var may be assigned the address of 17 | // one of the standard Param vars for use as the application's "active" network. 18 | // When a network parameter is needed, it may then be looked up through this 19 | // variable (either directly, or hidden in a library call). 20 | // 21 | // package main 22 | // 23 | // import ( 24 | // "flag" 25 | // "fmt" 26 | // "log" 27 | // 28 | // "github.com/ltcsuite/ltcutil" 29 | // "github.com/ltcsuite/ltcd/chaincfg" 30 | // ) 31 | // 32 | // var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network") 33 | // 34 | // // By default (without -testnet), use mainnet. 35 | // var chainParams = &chaincfg.MainNetParams 36 | // 37 | // func main() { 38 | // flag.Parse() 39 | // 40 | // // Modify active network parameters if operating on testnet. 41 | // if *testnet { 42 | // chainParams = &chaincfg.TestNet4Params 43 | // } 44 | // 45 | // // later... 46 | // 47 | // // Create and print new payment address, specific to the active network. 48 | // pubKeyHash := make([]byte, 20) 49 | // addr, err := ltcutil.NewAddressPubKeyHash(pubKeyHash, chainParams) 50 | // if err != nil { 51 | // log.Fatal(err) 52 | // } 53 | // fmt.Println(addr) 54 | // } 55 | // 56 | // If an application does not use one of the three standard Bitcoin networks, 57 | // a new Params struct may be created which defines the parameters for the 58 | // non-standard network. As a general rule of thumb, all network parameters 59 | // should be unique to the network, but parameter collisions can still occur 60 | // (unfortunately, this is the case with regtest and testnet sharing magics). 61 | package chaincfg 62 | -------------------------------------------------------------------------------- /chaincfg/params_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package chaincfg 6 | 7 | import "testing" 8 | 9 | // TestInvalidHashStr ensures the newShaHashFromStr function panics when used to 10 | // with an invalid hash string. 11 | func TestInvalidHashStr(t *testing.T) { 12 | defer func() { 13 | if r := recover(); r == nil { 14 | t.Errorf("Expected panic for invalid hash, got nil") 15 | } 16 | }() 17 | newHashFromStr("banana") 18 | } 19 | 20 | // TestMustRegisterPanic ensures the mustRegister function panics when used to 21 | // register an invalid network. 22 | func TestMustRegisterPanic(t *testing.T) { 23 | t.Parallel() 24 | 25 | // Setup a defer to catch the expected panic to ensure it actually 26 | // paniced. 27 | defer func() { 28 | if err := recover(); err == nil { 29 | t.Error("mustRegister did not panic as expected") 30 | } 31 | }() 32 | 33 | // Intentionally try to register duplicate params to force a panic. 34 | mustRegister(&MainNetParams) 35 | } 36 | -------------------------------------------------------------------------------- /cmd/ltcctl/version.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "bytes" 9 | "fmt" 10 | "strings" 11 | ) 12 | 13 | // semanticAlphabet 14 | const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" 15 | 16 | // These constants define the application version and follow the semantic 17 | // versioning 2.0.0 spec (http://semver.org/). 18 | const ( 19 | appMajor uint = 0 20 | appMinor uint = 12 21 | appPatch uint = 0 22 | 23 | // appPreRelease MUST only contain characters from semanticAlphabet 24 | // per the semantic versioning spec. 25 | appPreRelease = "beta" 26 | ) 27 | 28 | // appBuild is defined as a variable so it can be overridden during the build 29 | // process with '-ldflags "-X main.appBuild foo' if needed. It MUST only 30 | // contain characters from semanticAlphabet per the semantic versioning spec. 31 | var appBuild string 32 | 33 | // version returns the application version as a properly formed string per the 34 | // semantic versioning 2.0.0 spec (http://semver.org/). 35 | func version() string { 36 | // Start with the major, minor, and patch versions. 37 | version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch) 38 | 39 | // Append pre-release version if there is one. The hyphen called for 40 | // by the semantic versioning spec is automatically appended and should 41 | // not be contained in the pre-release string. The pre-release version 42 | // is not appended if it contains invalid characters. 43 | preRelease := normalizeVerString(appPreRelease) 44 | if preRelease != "" { 45 | version = fmt.Sprintf("%s-%s", version, preRelease) 46 | } 47 | 48 | // Append build metadata if there is any. The plus called for 49 | // by the semantic versioning spec is automatically appended and should 50 | // not be contained in the build metadata string. The build metadata 51 | // string is not appended if it contains invalid characters. 52 | build := normalizeVerString(appBuild) 53 | if build != "" { 54 | version = fmt.Sprintf("%s+%s", version, build) 55 | } 56 | 57 | return version 58 | } 59 | 60 | // normalizeVerString returns the passed string stripped of all characters which 61 | // are not valid according to the semantic versioning guidelines for pre-release 62 | // version and build metadata strings. In particular they MUST only contain 63 | // characters in semanticAlphabet. 64 | func normalizeVerString(str string) string { 65 | var result bytes.Buffer 66 | for _, r := range str { 67 | if strings.ContainsRune(semanticAlphabet, r) { 68 | // Ignoring the error here since it can only fail if 69 | // the the system is out of memory and there are much 70 | // bigger issues at that point. 71 | _, _ = result.WriteRune(r) 72 | } 73 | } 74 | return result.String() 75 | } 76 | -------------------------------------------------------------------------------- /config_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "path/filepath" 7 | "regexp" 8 | "runtime" 9 | "testing" 10 | ) 11 | 12 | var ( 13 | rpcuserRegexp = regexp.MustCompile("(?m)^rpcuser=.+$") 14 | rpcpassRegexp = regexp.MustCompile("(?m)^rpcpass=.+$") 15 | ) 16 | 17 | func TestCreateDefaultConfigFile(t *testing.T) { 18 | // find out where the sample config lives 19 | _, path, _, ok := runtime.Caller(0) 20 | if !ok { 21 | t.Fatalf("Failed finding config file path") 22 | } 23 | sampleConfigFile := filepath.Join(filepath.Dir(path), "sample-ltcd.conf") 24 | 25 | // Setup a temporary directory 26 | tmpDir, err := ioutil.TempDir("", "ltcd") 27 | if err != nil { 28 | t.Fatalf("Failed creating a temporary directory: %v", err) 29 | } 30 | testpath := filepath.Join(tmpDir, "test.conf") 31 | 32 | // copy config file to location of ltcd binary 33 | data, err := ioutil.ReadFile(sampleConfigFile) 34 | if err != nil { 35 | t.Fatalf("Failed reading sample config file: %v", err) 36 | } 37 | appPath, err := filepath.Abs(filepath.Dir(os.Args[0])) 38 | if err != nil { 39 | t.Fatalf("Failed obtaining app path: %v", err) 40 | } 41 | tmpConfigFile := filepath.Join(appPath, "sample-ltcd.conf") 42 | err = ioutil.WriteFile(tmpConfigFile, data, 0644) 43 | if err != nil { 44 | t.Fatalf("Failed copying sample config file: %v", err) 45 | } 46 | 47 | // Clean-up 48 | defer func() { 49 | os.Remove(testpath) 50 | os.Remove(tmpConfigFile) 51 | os.Remove(tmpDir) 52 | }() 53 | 54 | err = createDefaultConfigFile(testpath) 55 | 56 | if err != nil { 57 | t.Fatalf("Failed to create a default config file: %v", err) 58 | } 59 | 60 | content, err := ioutil.ReadFile(testpath) 61 | if err != nil { 62 | t.Fatalf("Failed to read generated default config file: %v", err) 63 | } 64 | 65 | if !rpcuserRegexp.Match(content) { 66 | t.Error("Could not find rpcuser in generated default config file.") 67 | } 68 | 69 | if !rpcpassRegexp.Match(content) { 70 | t.Error("Could not find rpcpass in generated default config file.") 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /connmgr/README.md: -------------------------------------------------------------------------------- 1 | connmgr 2 | ======= 3 | 4 | [![Build Status](http://img.shields.io/travis/ltcsuite/ltcd.svg)] 5 | (https://travis-ci.org/ltcsuite/ltcd) [![ISC License] 6 | (http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 7 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)] 8 | (http://godoc.org/github.com/ltcsuite/ltcd/connmgr) 9 | 10 | Package connmgr implements a generic Bitcoin network connection manager. 11 | 12 | ## Overview 13 | 14 | Connection Manager handles all the general connection concerns such as 15 | maintaining a set number of outbound connections, sourcing peers, banning, 16 | limiting max connections, tor lookup, etc. 17 | 18 | The package provides a generic connection manager which is able to accept 19 | connection requests from a source or a set of given addresses, dial them and 20 | notify the caller on connections. The main intended use is to initialize a pool 21 | of active connections and maintain them to remain connected to the P2P network. 22 | 23 | In addition the connection manager provides the following utilities: 24 | 25 | - Notifications on connections or disconnections 26 | - Handle failures and retry new addresses from the source 27 | - Connect only to specified addresses 28 | - Permanent connections with increasing backoff retry timers 29 | - Disconnect or Remove an established connection 30 | 31 | ## Installation and Updating 32 | 33 | ```bash 34 | $ go get -u github.com/ltcsuite/ltcd/connmgr 35 | ``` 36 | 37 | ## License 38 | 39 | Package connmgr is licensed under the [copyfree](http://copyfree.org) ISC License. 40 | -------------------------------------------------------------------------------- /connmgr/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package connmgr implements a generic Bitcoin network connection manager. 7 | 8 | Connection Manager Overview 9 | 10 | Connection Manager handles all the general connection concerns such as 11 | maintaining a set number of outbound connections, sourcing peers, banning, 12 | limiting max connections, tor lookup, etc. 13 | */ 14 | package connmgr 15 | -------------------------------------------------------------------------------- /connmgr/dynamicbanscore_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package connmgr 6 | 7 | import ( 8 | "math" 9 | "testing" 10 | "time" 11 | ) 12 | 13 | // TestDynamicBanScoreDecay tests the exponential decay implemented in 14 | // DynamicBanScore. 15 | func TestDynamicBanScoreDecay(t *testing.T) { 16 | var bs DynamicBanScore 17 | base := time.Now() 18 | 19 | r := bs.increase(100, 50, base) 20 | if r != 150 { 21 | t.Errorf("Unexpected result %d after ban score increase.", r) 22 | } 23 | 24 | r = bs.int(base.Add(time.Minute)) 25 | if r != 125 { 26 | t.Errorf("Halflife check failed - %d instead of 125", r) 27 | } 28 | 29 | r = bs.int(base.Add(7 * time.Minute)) 30 | if r != 100 { 31 | t.Errorf("Decay after 7m - %d instead of 100", r) 32 | } 33 | } 34 | 35 | // TestDynamicBanScoreLifetime tests that DynamicBanScore properly yields zero 36 | // once the maximum age is reached. 37 | func TestDynamicBanScoreLifetime(t *testing.T) { 38 | var bs DynamicBanScore 39 | base := time.Now() 40 | 41 | r := bs.increase(0, math.MaxUint32, base) 42 | r = bs.int(base.Add(Lifetime * time.Second)) 43 | if r != 3 { // 3, not 4 due to precision loss and truncating 3.999... 44 | t.Errorf("Pre max age check with MaxUint32 failed - %d", r) 45 | } 46 | r = bs.int(base.Add((Lifetime + 1) * time.Second)) 47 | if r != 0 { 48 | t.Errorf("Zero after max age check failed - %d instead of 0", r) 49 | } 50 | } 51 | 52 | // TestDynamicBanScore tests exported functions of DynamicBanScore. Exponential 53 | // decay or other time based behavior is tested by other functions. 54 | func TestDynamicBanScoreReset(t *testing.T) { 55 | var bs DynamicBanScore 56 | if bs.Int() != 0 { 57 | t.Errorf("Initial state is not zero.") 58 | } 59 | bs.Increase(100, 0) 60 | r := bs.Int() 61 | if r != 100 { 62 | t.Errorf("Unexpected result %d after ban score increase.", r) 63 | } 64 | bs.Reset() 65 | if bs.Int() != 0 { 66 | t.Errorf("Failed to reset ban score.") 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /connmgr/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package connmgr 6 | 7 | import "github.com/btcsuite/btclog" 8 | 9 | // log is a logger that is initialized with no output filters. This 10 | // means the package will not perform any logging by default until the caller 11 | // requests it. 12 | var log btclog.Logger 13 | 14 | // The default amount of logging is none. 15 | func init() { 16 | DisableLog() 17 | } 18 | 19 | // DisableLog disables all library log output. Logging output is disabled 20 | // by default until either UseLogger or SetLogWriter are called. 21 | func DisableLog() { 22 | log = btclog.Disabled 23 | } 24 | 25 | // UseLogger uses a specified Logger to output package logging info. 26 | // This should be used in preference to SetLogWriter if the caller is also 27 | // using btclog. 28 | func UseLogger(logger btclog.Logger) { 29 | log = logger 30 | } 31 | -------------------------------------------------------------------------------- /connmgr/seed.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package connmgr 6 | 7 | import ( 8 | "fmt" 9 | mrand "math/rand" 10 | "net" 11 | "strconv" 12 | "time" 13 | 14 | "github.com/ltcsuite/ltcd/chaincfg" 15 | "github.com/ltcsuite/ltcd/wire" 16 | ) 17 | 18 | const ( 19 | // These constants are used by the DNS seed code to pick a random last 20 | // seen time. 21 | secondsIn3Days int32 = 24 * 60 * 60 * 3 22 | secondsIn4Days int32 = 24 * 60 * 60 * 4 23 | ) 24 | 25 | // OnSeed is the signature of the callback function which is invoked when DNS 26 | // seeding is succesfull. 27 | type OnSeed func(addrs []*wire.NetAddress) 28 | 29 | // LookupFunc is the signature of the DNS lookup function. 30 | type LookupFunc func(string) ([]net.IP, error) 31 | 32 | // SeedFromDNS uses DNS seeding to populate the address manager with peers. 33 | func SeedFromDNS(chainParams *chaincfg.Params, reqServices wire.ServiceFlag, 34 | lookupFn LookupFunc, seedFn OnSeed) { 35 | 36 | for _, dnsseed := range chainParams.DNSSeeds { 37 | var host string 38 | if !dnsseed.HasFiltering || reqServices == wire.SFNodeNetwork { 39 | host = dnsseed.Host 40 | } else { 41 | host = fmt.Sprintf("x%x.%s", uint64(reqServices), dnsseed.Host) 42 | } 43 | 44 | go func(host string) { 45 | randSource := mrand.New(mrand.NewSource(time.Now().UnixNano())) 46 | 47 | seedpeers, err := lookupFn(host) 48 | if err != nil { 49 | log.Infof("DNS discovery failed on seed %s: %v", host, err) 50 | return 51 | } 52 | numPeers := len(seedpeers) 53 | 54 | log.Infof("%d addresses found from DNS seed %s", numPeers, host) 55 | 56 | if numPeers == 0 { 57 | return 58 | } 59 | addresses := make([]*wire.NetAddress, len(seedpeers)) 60 | // if this errors then we have *real* problems 61 | intPort, _ := strconv.Atoi(chainParams.DefaultPort) 62 | for i, peer := range seedpeers { 63 | addresses[i] = wire.NewNetAddressTimestamp( 64 | // bitcoind seeds with addresses from 65 | // a time randomly selected between 3 66 | // and 7 days ago. 67 | time.Now().Add(-1*time.Second*time.Duration(secondsIn3Days+ 68 | randSource.Int31n(secondsIn4Days))), 69 | 0, peer, uint16(intPort)) 70 | } 71 | 72 | seedFn(addresses) 73 | }(host) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /database/README.md: -------------------------------------------------------------------------------- 1 | database 2 | ======== 3 | 4 | [![Build Status](http://img.shields.io/travis/ltcsuite/ltcd.svg)] 5 | (https://travis-ci.org/ltcsuite/ltcd) [![ISC License] 6 | (http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 7 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)] 8 | (http://godoc.org/github.com/ltcsuite/ltcd/database) 9 | 10 | Package database provides a block and metadata storage database. 11 | 12 | Please note that this package is intended to enable ltcd to support different 13 | database backends and is not something that a client can directly access as only 14 | one entity can have the database open at a time (for most database backends), 15 | and that entity will be ltcd. 16 | 17 | When a client wants programmatic access to the data provided by ltcd, they'll 18 | likely want to use the [btcrpcclient](https://github.com/roasbeef/btcrpcclient) 19 | package which makes use of the [JSON-RPC API] 20 | (https://github.com/ltcsuite/ltcd/tree/master/docs/json_rpc_api.md). 21 | 22 | However, this package could be extremely useful for any applications requiring 23 | Bitcoin block storage capabilities. 24 | 25 | The default backend, ffldb, has a strong focus on speed, efficiency, and 26 | robustness. It makes use of leveldb for the metadata, flat files for block 27 | storage, and strict checksums in key areas to ensure data integrity. 28 | 29 | ## Feature Overview 30 | 31 | - Key/value metadata store 32 | - Bitcoin block storage 33 | - Efficient retrieval of block headers and regions (transactions, scripts, etc) 34 | - Read-only and read-write transactions with both manual and managed modes 35 | - Nested buckets 36 | - Iteration support including cursors with seek capability 37 | - Supports registration of backend databases 38 | - Comprehensive test coverage 39 | 40 | ## Installation and Updating 41 | 42 | ```bash 43 | $ go get -u github.com/ltcsuite/ltcd/database 44 | ``` 45 | 46 | ## Examples 47 | 48 | * [Basic Usage Example] 49 | (http://godoc.org/github.com/ltcsuite/ltcd/database#example-package--BasicUsage) 50 | Demonstrates creating a new database and using a managed read-write 51 | transaction to store and retrieve metadata. 52 | 53 | * [Block Storage and Retrieval Example] 54 | (http://godoc.org/github.com/ltcsuite/ltcd/database#example-package--BlockStorageAndRetrieval) 55 | Demonstrates creating a new database, using a managed read-write transaction 56 | to store a block, and then using a managed read-only transaction to fetch the 57 | block. 58 | 59 | ## License 60 | 61 | Package database is licensed under the [copyfree](http://copyfree.org) ISC 62 | License. 63 | -------------------------------------------------------------------------------- /database/cmd/dbtool/fetchblock.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "encoding/hex" 9 | "errors" 10 | "time" 11 | 12 | "github.com/ltcsuite/ltcd/chaincfg/chainhash" 13 | "github.com/ltcsuite/ltcd/database" 14 | ) 15 | 16 | // fetchBlockCmd defines the configuration options for the fetchblock command. 17 | type fetchBlockCmd struct{} 18 | 19 | var ( 20 | // fetchBlockCfg defines the configuration options for the command. 21 | fetchBlockCfg = fetchBlockCmd{} 22 | ) 23 | 24 | // Execute is the main entry point for the command. It's invoked by the parser. 25 | func (cmd *fetchBlockCmd) Execute(args []string) error { 26 | // Setup the global config options and ensure they are valid. 27 | if err := setupGlobalConfig(); err != nil { 28 | return err 29 | } 30 | 31 | if len(args) < 1 { 32 | return errors.New("required block hash parameter not specified") 33 | } 34 | blockHash, err := chainhash.NewHashFromStr(args[0]) 35 | if err != nil { 36 | return err 37 | } 38 | 39 | // Load the block database. 40 | db, err := loadBlockDB() 41 | if err != nil { 42 | return err 43 | } 44 | defer db.Close() 45 | 46 | return db.View(func(tx database.Tx) error { 47 | log.Infof("Fetching block %s", blockHash) 48 | startTime := time.Now() 49 | blockBytes, err := tx.FetchBlock(blockHash) 50 | if err != nil { 51 | return err 52 | } 53 | log.Infof("Loaded block in %v", time.Since(startTime)) 54 | log.Infof("Block Hex: %s", hex.EncodeToString(blockBytes)) 55 | return nil 56 | }) 57 | } 58 | 59 | // Usage overrides the usage display for the command. 60 | func (cmd *fetchBlockCmd) Usage() string { 61 | return "" 62 | } 63 | -------------------------------------------------------------------------------- /database/cmd/dbtool/fetchblockregion.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "encoding/hex" 9 | "errors" 10 | "strconv" 11 | "time" 12 | 13 | "github.com/ltcsuite/ltcd/chaincfg/chainhash" 14 | "github.com/ltcsuite/ltcd/database" 15 | ) 16 | 17 | // blockRegionCmd defines the configuration options for the fetchblockregion 18 | // command. 19 | type blockRegionCmd struct{} 20 | 21 | var ( 22 | // blockRegionCfg defines the configuration options for the command. 23 | blockRegionCfg = blockRegionCmd{} 24 | ) 25 | 26 | // Execute is the main entry point for the command. It's invoked by the parser. 27 | func (cmd *blockRegionCmd) Execute(args []string) error { 28 | // Setup the global config options and ensure they are valid. 29 | if err := setupGlobalConfig(); err != nil { 30 | return err 31 | } 32 | 33 | // Ensure expected arguments. 34 | if len(args) < 1 { 35 | return errors.New("required block hash parameter not specified") 36 | } 37 | if len(args) < 2 { 38 | return errors.New("required start offset parameter not " + 39 | "specified") 40 | } 41 | if len(args) < 3 { 42 | return errors.New("required region length parameter not " + 43 | "specified") 44 | } 45 | 46 | // Parse arguments. 47 | blockHash, err := chainhash.NewHashFromStr(args[0]) 48 | if err != nil { 49 | return err 50 | } 51 | startOffset, err := strconv.ParseUint(args[1], 10, 32) 52 | if err != nil { 53 | return err 54 | } 55 | regionLen, err := strconv.ParseUint(args[2], 10, 32) 56 | if err != nil { 57 | return err 58 | } 59 | 60 | // Load the block database. 61 | db, err := loadBlockDB() 62 | if err != nil { 63 | return err 64 | } 65 | defer db.Close() 66 | 67 | return db.View(func(tx database.Tx) error { 68 | log.Infof("Fetching block region %s<%d:%d>", blockHash, 69 | startOffset, startOffset+regionLen-1) 70 | region := database.BlockRegion{ 71 | Hash: blockHash, 72 | Offset: uint32(startOffset), 73 | Len: uint32(regionLen), 74 | } 75 | startTime := time.Now() 76 | regionBytes, err := tx.FetchBlockRegion(®ion) 77 | if err != nil { 78 | return err 79 | } 80 | log.Infof("Loaded block region in %v", time.Since(startTime)) 81 | log.Infof("Double Hash: %s", chainhash.DoubleHashH(regionBytes)) 82 | log.Infof("Region Hex: %s", hex.EncodeToString(regionBytes)) 83 | return nil 84 | }) 85 | } 86 | 87 | // Usage overrides the usage display for the command. 88 | func (cmd *blockRegionCmd) Usage() string { 89 | return " " 90 | } 91 | -------------------------------------------------------------------------------- /database/cmd/dbtool/loadheaders.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "time" 9 | 10 | "github.com/ltcsuite/ltcd/chaincfg/chainhash" 11 | "github.com/ltcsuite/ltcd/database" 12 | ) 13 | 14 | // headersCmd defines the configuration options for the loadheaders command. 15 | type headersCmd struct { 16 | Bulk bool `long:"bulk" description:"Use bulk loading of headers instead of one at a time"` 17 | } 18 | 19 | var ( 20 | // headersCfg defines the configuration options for the command. 21 | headersCfg = headersCmd{ 22 | Bulk: false, 23 | } 24 | ) 25 | 26 | // Execute is the main entry point for the command. It's invoked by the parser. 27 | func (cmd *headersCmd) Execute(args []string) error { 28 | // Setup the global config options and ensure they are valid. 29 | if err := setupGlobalConfig(); err != nil { 30 | return err 31 | } 32 | 33 | // Load the block database. 34 | db, err := loadBlockDB() 35 | if err != nil { 36 | return err 37 | } 38 | defer db.Close() 39 | 40 | // NOTE: This code will only work for ffldb. Ideally the package using 41 | // the database would keep a metadata index of its own. 42 | blockIdxName := []byte("ffldb-blockidx") 43 | if !headersCfg.Bulk { 44 | err = db.View(func(tx database.Tx) error { 45 | totalHdrs := 0 46 | blockIdxBucket := tx.Metadata().Bucket(blockIdxName) 47 | blockIdxBucket.ForEach(func(k, v []byte) error { 48 | totalHdrs++ 49 | return nil 50 | }) 51 | log.Infof("Loading headers for %d blocks...", totalHdrs) 52 | numLoaded := 0 53 | startTime := time.Now() 54 | blockIdxBucket.ForEach(func(k, v []byte) error { 55 | var hash chainhash.Hash 56 | copy(hash[:], k) 57 | _, err := tx.FetchBlockHeader(&hash) 58 | if err != nil { 59 | return err 60 | } 61 | numLoaded++ 62 | return nil 63 | }) 64 | log.Infof("Loaded %d headers in %v", numLoaded, 65 | time.Since(startTime)) 66 | return nil 67 | }) 68 | return err 69 | } 70 | 71 | // Bulk load headers. 72 | err = db.View(func(tx database.Tx) error { 73 | blockIdxBucket := tx.Metadata().Bucket(blockIdxName) 74 | hashes := make([]chainhash.Hash, 0, 500000) 75 | blockIdxBucket.ForEach(func(k, v []byte) error { 76 | var hash chainhash.Hash 77 | copy(hash[:], k) 78 | hashes = append(hashes, hash) 79 | return nil 80 | }) 81 | 82 | log.Infof("Loading headers for %d blocks...", len(hashes)) 83 | startTime := time.Now() 84 | hdrs, err := tx.FetchBlockHeaders(hashes) 85 | if err != nil { 86 | return err 87 | } 88 | log.Infof("Loaded %d headers in %v", len(hdrs), 89 | time.Since(startTime)) 90 | return nil 91 | }) 92 | return err 93 | } 94 | -------------------------------------------------------------------------------- /database/cmd/dbtool/signal.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "os" 9 | "os/signal" 10 | ) 11 | 12 | // interruptChannel is used to receive SIGINT (Ctrl+C) signals. 13 | var interruptChannel chan os.Signal 14 | 15 | // addHandlerChannel is used to add an interrupt handler to the list of handlers 16 | // to be invoked on SIGINT (Ctrl+C) signals. 17 | var addHandlerChannel = make(chan func()) 18 | 19 | // mainInterruptHandler listens for SIGINT (Ctrl+C) signals on the 20 | // interruptChannel and invokes the registered interruptCallbacks accordingly. 21 | // It also listens for callback registration. It must be run as a goroutine. 22 | func mainInterruptHandler() { 23 | // interruptCallbacks is a list of callbacks to invoke when a 24 | // SIGINT (Ctrl+C) is received. 25 | var interruptCallbacks []func() 26 | 27 | // isShutdown is a flag which is used to indicate whether or not 28 | // the shutdown signal has already been received and hence any future 29 | // attempts to add a new interrupt handler should invoke them 30 | // immediately. 31 | var isShutdown bool 32 | 33 | for { 34 | select { 35 | case <-interruptChannel: 36 | // Ignore more than one shutdown signal. 37 | if isShutdown { 38 | log.Infof("Received SIGINT (Ctrl+C). " + 39 | "Already shutting down...") 40 | continue 41 | } 42 | 43 | isShutdown = true 44 | log.Infof("Received SIGINT (Ctrl+C). Shutting down...") 45 | 46 | // Run handlers in LIFO order. 47 | for i := range interruptCallbacks { 48 | idx := len(interruptCallbacks) - 1 - i 49 | callback := interruptCallbacks[idx] 50 | callback() 51 | } 52 | 53 | // Signal the main goroutine to shutdown. 54 | go func() { 55 | shutdownChannel <- nil 56 | }() 57 | 58 | case handler := <-addHandlerChannel: 59 | // The shutdown signal has already been received, so 60 | // just invoke and new handlers immediately. 61 | if isShutdown { 62 | handler() 63 | } 64 | 65 | interruptCallbacks = append(interruptCallbacks, handler) 66 | } 67 | } 68 | } 69 | 70 | // addInterruptHandler adds a handler to call when a SIGINT (Ctrl+C) is 71 | // received. 72 | func addInterruptHandler(handler func()) { 73 | // Create the channel and start the main interrupt handler which invokes 74 | // all other callbacks and exits if not already done. 75 | if interruptChannel == nil { 76 | interruptChannel = make(chan os.Signal, 1) 77 | signal.Notify(interruptChannel, os.Interrupt) 78 | go mainInterruptHandler() 79 | } 80 | 81 | addHandlerChannel <- handler 82 | } 83 | -------------------------------------------------------------------------------- /database/error_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package database_test 6 | 7 | import ( 8 | "errors" 9 | "testing" 10 | 11 | "github.com/ltcsuite/ltcd/database" 12 | ) 13 | 14 | // TestErrorCodeStringer tests the stringized output for the ErrorCode type. 15 | func TestErrorCodeStringer(t *testing.T) { 16 | tests := []struct { 17 | in database.ErrorCode 18 | want string 19 | }{ 20 | {database.ErrDbTypeRegistered, "ErrDbTypeRegistered"}, 21 | {database.ErrDbUnknownType, "ErrDbUnknownType"}, 22 | {database.ErrDbDoesNotExist, "ErrDbDoesNotExist"}, 23 | {database.ErrDbExists, "ErrDbExists"}, 24 | {database.ErrDbNotOpen, "ErrDbNotOpen"}, 25 | {database.ErrDbAlreadyOpen, "ErrDbAlreadyOpen"}, 26 | {database.ErrInvalid, "ErrInvalid"}, 27 | {database.ErrCorruption, "ErrCorruption"}, 28 | {database.ErrTxClosed, "ErrTxClosed"}, 29 | {database.ErrTxNotWritable, "ErrTxNotWritable"}, 30 | {database.ErrBucketNotFound, "ErrBucketNotFound"}, 31 | {database.ErrBucketExists, "ErrBucketExists"}, 32 | {database.ErrBucketNameRequired, "ErrBucketNameRequired"}, 33 | {database.ErrKeyRequired, "ErrKeyRequired"}, 34 | {database.ErrKeyTooLarge, "ErrKeyTooLarge"}, 35 | {database.ErrValueTooLarge, "ErrValueTooLarge"}, 36 | {database.ErrIncompatibleValue, "ErrIncompatibleValue"}, 37 | {database.ErrBlockNotFound, "ErrBlockNotFound"}, 38 | {database.ErrBlockExists, "ErrBlockExists"}, 39 | {database.ErrBlockRegionInvalid, "ErrBlockRegionInvalid"}, 40 | {database.ErrDriverSpecific, "ErrDriverSpecific"}, 41 | 42 | {0xffff, "Unknown ErrorCode (65535)"}, 43 | } 44 | 45 | // Detect additional error codes that don't have the stringer added. 46 | if len(tests)-1 != int(database.TstNumErrorCodes) { 47 | t.Errorf("It appears an error code was added without adding " + 48 | "an associated stringer test") 49 | } 50 | 51 | t.Logf("Running %d tests", len(tests)) 52 | for i, test := range tests { 53 | result := test.in.String() 54 | if result != test.want { 55 | t.Errorf("String #%d\ngot: %s\nwant: %s", i, result, 56 | test.want) 57 | continue 58 | } 59 | } 60 | } 61 | 62 | // TestError tests the error output for the Error type. 63 | func TestError(t *testing.T) { 64 | t.Parallel() 65 | 66 | tests := []struct { 67 | in database.Error 68 | want string 69 | }{ 70 | { 71 | database.Error{Description: "some error"}, 72 | "some error", 73 | }, 74 | { 75 | database.Error{Description: "human-readable error"}, 76 | "human-readable error", 77 | }, 78 | { 79 | database.Error{ 80 | ErrorCode: database.ErrDriverSpecific, 81 | Description: "some error", 82 | Err: errors.New("driver-specific error"), 83 | }, 84 | "some error: driver-specific error", 85 | }, 86 | } 87 | 88 | t.Logf("Running %d tests", len(tests)) 89 | for i, test := range tests { 90 | result := test.in.Error() 91 | if result != test.want { 92 | t.Errorf("Error #%d\n got: %s want: %s", i, result, 93 | test.want) 94 | continue 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /database/export_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | This test file is part of the database package rather than than the 7 | database_test package so it can bridge access to the internals to properly test 8 | cases which are either not possible or can't reliably be tested via the public 9 | interface. The functions, constants, and variables are only exported while the 10 | tests are being run. 11 | */ 12 | 13 | package database 14 | 15 | // TstNumErrorCodes makes the internal numErrorCodes parameter available to the 16 | // test package. 17 | const TstNumErrorCodes = numErrorCodes 18 | -------------------------------------------------------------------------------- /database/ffldb/README.md: -------------------------------------------------------------------------------- 1 | ffldb 2 | ===== 3 | 4 | [![Build Status](https://travis-ci.org/ltcsuite/ltcd.png?branch=master)](https://travis-ci.org/ltcsuite/ltcd) 5 | [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 6 | [![GoDoc](https://godoc.org/github.com/ltcsuite/ltcd/database/ffldb?status.png)](http://godoc.org/github.com/ltcsuite/ltcd/database/ffldb) 7 | 8 | Package ffldb implements a driver for the database package that uses leveldb for 9 | the backing metadata and flat files for block storage. 10 | 11 | This driver is the recommended driver for use with ltcd. It makes use leveldb 12 | for the metadata, flat files for block storage, and checksums in key areas to 13 | ensure data integrity. 14 | 15 | Package ffldb is licensed under the copyfree ISC license. 16 | 17 | ## Usage 18 | 19 | This package is a driver to the database package and provides the database type 20 | of "ffldb". The parameters the Open and Create functions take are the 21 | database path as a string and the block network. 22 | 23 | ```Go 24 | db, err := database.Open("ffldb", "path/to/database", wire.MainNet) 25 | if err != nil { 26 | // Handle error 27 | } 28 | ``` 29 | 30 | ```Go 31 | db, err := database.Create("ffldb", "path/to/database", wire.MainNet) 32 | if err != nil { 33 | // Handle error 34 | } 35 | ``` 36 | 37 | ======= 38 | ## Documentation 39 | 40 | [![GoDoc](https://godoc.org/github.com/ltcsuite/ltcd/database/ffldb?status.png)] 41 | (http://godoc.org/github.com/ltcsuite/ltcd/database/ffldb) 42 | 43 | Full `go doc` style documentation for the project can be viewed online without 44 | installing this package by using the GoDoc site here: 45 | http://godoc.org/github.com/ltcsuite/ltcd/database/ffldb 46 | 47 | You can also view the documentation locally once the package is installed with 48 | the `godoc` tool by running `godoc -http=":6060"` and pointing your browser to 49 | http://localhost:6060/pkg/github.com/ltcsuite/ltcd/database/ffldb 50 | 51 | ## License 52 | 53 | Package ffldb is licensed under the [copyfree](http://copyfree.org) ISC 54 | License. 55 | -------------------------------------------------------------------------------- /database/ffldb/bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package ffldb 6 | 7 | import ( 8 | "os" 9 | "path/filepath" 10 | "testing" 11 | 12 | "github.com/ltcsuite/ltcd/chaincfg" 13 | "github.com/ltcsuite/ltcd/database" 14 | "github.com/ltcsuite/ltcutil" 15 | ) 16 | 17 | // BenchmarkBlockHeader benchmarks how long it takes to load the mainnet genesis 18 | // block header. 19 | func BenchmarkBlockHeader(b *testing.B) { 20 | // Start by creating a new database and populating it with the mainnet 21 | // genesis block. 22 | dbPath := filepath.Join(os.TempDir(), "ffldb-benchblkhdr") 23 | _ = os.RemoveAll(dbPath) 24 | db, err := database.Create("ffldb", dbPath, blockDataNet) 25 | if err != nil { 26 | b.Fatal(err) 27 | } 28 | defer os.RemoveAll(dbPath) 29 | defer db.Close() 30 | err = db.Update(func(tx database.Tx) error { 31 | block := ltcutil.NewBlock(chaincfg.MainNetParams.GenesisBlock) 32 | return tx.StoreBlock(block) 33 | }) 34 | if err != nil { 35 | b.Fatal(err) 36 | } 37 | 38 | b.ReportAllocs() 39 | b.ResetTimer() 40 | err = db.View(func(tx database.Tx) error { 41 | blockHash := chaincfg.MainNetParams.GenesisHash 42 | for i := 0; i < b.N; i++ { 43 | _, err := tx.FetchBlockHeader(blockHash) 44 | if err != nil { 45 | return err 46 | } 47 | } 48 | return nil 49 | }) 50 | if err != nil { 51 | b.Fatal(err) 52 | } 53 | 54 | // Don't benchmark teardown. 55 | b.StopTimer() 56 | } 57 | 58 | // BenchmarkBlockHeader benchmarks how long it takes to load the mainnet genesis 59 | // block. 60 | func BenchmarkBlock(b *testing.B) { 61 | // Start by creating a new database and populating it with the mainnet 62 | // genesis block. 63 | dbPath := filepath.Join(os.TempDir(), "ffldb-benchblk") 64 | _ = os.RemoveAll(dbPath) 65 | db, err := database.Create("ffldb", dbPath, blockDataNet) 66 | if err != nil { 67 | b.Fatal(err) 68 | } 69 | defer os.RemoveAll(dbPath) 70 | defer db.Close() 71 | err = db.Update(func(tx database.Tx) error { 72 | block := ltcutil.NewBlock(chaincfg.MainNetParams.GenesisBlock) 73 | return tx.StoreBlock(block) 74 | }) 75 | if err != nil { 76 | b.Fatal(err) 77 | } 78 | 79 | b.ReportAllocs() 80 | b.ResetTimer() 81 | err = db.View(func(tx database.Tx) error { 82 | blockHash := chaincfg.MainNetParams.GenesisHash 83 | for i := 0; i < b.N; i++ { 84 | _, err := tx.FetchBlock(blockHash) 85 | if err != nil { 86 | return err 87 | } 88 | } 89 | return nil 90 | }) 91 | if err != nil { 92 | b.Fatal(err) 93 | } 94 | 95 | // Don't benchmark teardown. 96 | b.StopTimer() 97 | } 98 | -------------------------------------------------------------------------------- /database/ffldb/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package ffldb implements a driver for the database package that uses leveldb 7 | for the backing metadata and flat files for block storage. 8 | 9 | This driver is the recommended driver for use with ltcd. It makes use leveldb 10 | for the metadata, flat files for block storage, and checksums in key areas to 11 | ensure data integrity. 12 | 13 | Usage 14 | 15 | This package is a driver to the database package and provides the database type 16 | of "ffldb". The parameters the Open and Create functions take are the 17 | database path as a string and the block network: 18 | 19 | db, err := database.Open("ffldb", "path/to/database", wire.MainNet) 20 | if err != nil { 21 | // Handle error 22 | } 23 | 24 | db, err := database.Create("ffldb", "path/to/database", wire.MainNet) 25 | if err != nil { 26 | // Handle error 27 | } 28 | */ 29 | package ffldb 30 | -------------------------------------------------------------------------------- /database/ffldb/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package ffldb 6 | 7 | import ( 8 | "fmt" 9 | 10 | "github.com/ltcsuite/ltcd/database" 11 | "github.com/ltcsuite/ltcd/wire" 12 | "github.com/btcsuite/btclog" 13 | ) 14 | 15 | var log = btclog.Disabled 16 | 17 | const ( 18 | dbType = "ffldb" 19 | ) 20 | 21 | // parseArgs parses the arguments from the database Open/Create methods. 22 | func parseArgs(funcName string, args ...interface{}) (string, wire.BitcoinNet, error) { 23 | if len(args) != 2 { 24 | return "", 0, fmt.Errorf("invalid arguments to %s.%s -- "+ 25 | "expected database path and block network", dbType, 26 | funcName) 27 | } 28 | 29 | dbPath, ok := args[0].(string) 30 | if !ok { 31 | return "", 0, fmt.Errorf("first argument to %s.%s is invalid -- "+ 32 | "expected database path string", dbType, funcName) 33 | } 34 | 35 | network, ok := args[1].(wire.BitcoinNet) 36 | if !ok { 37 | return "", 0, fmt.Errorf("second argument to %s.%s is invalid -- "+ 38 | "expected block network", dbType, funcName) 39 | } 40 | 41 | return dbPath, network, nil 42 | } 43 | 44 | // openDBDriver is the callback provided during driver registration that opens 45 | // an existing database for use. 46 | func openDBDriver(args ...interface{}) (database.DB, error) { 47 | dbPath, network, err := parseArgs("Open", args...) 48 | if err != nil { 49 | return nil, err 50 | } 51 | 52 | return openDB(dbPath, network, false) 53 | } 54 | 55 | // createDBDriver is the callback provided during driver registration that 56 | // creates, initializes, and opens a database for use. 57 | func createDBDriver(args ...interface{}) (database.DB, error) { 58 | dbPath, network, err := parseArgs("Create", args...) 59 | if err != nil { 60 | return nil, err 61 | } 62 | 63 | return openDB(dbPath, network, true) 64 | } 65 | 66 | // useLogger is the callback provided during driver registration that sets the 67 | // current logger to the provided one. 68 | func useLogger(logger btclog.Logger) { 69 | log = logger 70 | } 71 | 72 | func init() { 73 | // Register the driver. 74 | driver := database.Driver{ 75 | DbType: dbType, 76 | Create: createDBDriver, 77 | Open: openDBDriver, 78 | UseLogger: useLogger, 79 | } 80 | if err := database.RegisterDriver(driver); err != nil { 81 | panic(fmt.Sprintf("Failed to regiser database driver '%s': %v", 82 | dbType, err)) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /database/ffldb/export_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | This test file is part of the ffldb package rather than than the ffldb_test 7 | package so it can bridge access to the internals to properly test cases which 8 | are either not possible or can't reliably be tested via the public interface. 9 | The functions are only exported while the tests are being run. 10 | */ 11 | 12 | package ffldb 13 | 14 | import "github.com/ltcsuite/ltcd/database" 15 | 16 | // TstRunWithMaxBlockFileSize runs the passed function with the maximum allowed 17 | // file size for the database set to the provided value. The value will be set 18 | // back to the original value upon completion. 19 | func TstRunWithMaxBlockFileSize(idb database.DB, size uint32, fn func()) { 20 | ffldb := idb.(*db) 21 | origSize := ffldb.store.maxBlockFileSize 22 | 23 | ffldb.store.maxBlockFileSize = size 24 | fn() 25 | ffldb.store.maxBlockFileSize = origSize 26 | } 27 | -------------------------------------------------------------------------------- /database/ffldb/ldbtreapiter.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package ffldb 6 | 7 | import ( 8 | "github.com/ltcsuite/ltcd/database/internal/treap" 9 | "github.com/btcsuite/goleveldb/leveldb/iterator" 10 | "github.com/btcsuite/goleveldb/leveldb/util" 11 | ) 12 | 13 | // ldbTreapIter wraps a treap iterator to provide the additional functionality 14 | // needed to satisfy the leveldb iterator.Iterator interface. 15 | type ldbTreapIter struct { 16 | *treap.Iterator 17 | tx *transaction 18 | released bool 19 | } 20 | 21 | // Enforce ldbTreapIter implements the leveldb iterator.Iterator interface. 22 | var _ iterator.Iterator = (*ldbTreapIter)(nil) 23 | 24 | // Error is only provided to satisfy the iterator interface as there are no 25 | // errors for this memory-only structure. 26 | // 27 | // This is part of the leveldb iterator.Iterator interface implementation. 28 | func (iter *ldbTreapIter) Error() error { 29 | return nil 30 | } 31 | 32 | // SetReleaser is only provided to satisfy the iterator interface as there is no 33 | // need to override it. 34 | // 35 | // This is part of the leveldb iterator.Iterator interface implementation. 36 | func (iter *ldbTreapIter) SetReleaser(releaser util.Releaser) { 37 | } 38 | 39 | // Release releases the iterator by removing the underlying treap iterator from 40 | // the list of active iterators against the pending keys treap. 41 | // 42 | // This is part of the leveldb iterator.Iterator interface implementation. 43 | func (iter *ldbTreapIter) Release() { 44 | if !iter.released { 45 | iter.tx.removeActiveIter(iter.Iterator) 46 | iter.released = true 47 | } 48 | } 49 | 50 | // newLdbTreapIter creates a new treap iterator for the given slice against the 51 | // pending keys for the passed transaction and returns it wrapped in an 52 | // ldbTreapIter so it can be used as a leveldb iterator. It also adds the new 53 | // iterator to the list of active iterators for the transaction. 54 | func newLdbTreapIter(tx *transaction, slice *util.Range) *ldbTreapIter { 55 | iter := tx.pendingKeys.Iterator(slice.Start, slice.Limit) 56 | tx.addActiveIter(iter) 57 | return &ldbTreapIter{Iterator: iter, tx: tx} 58 | } 59 | -------------------------------------------------------------------------------- /database/internal/treap/README.md: -------------------------------------------------------------------------------- 1 | treap 2 | ===== 3 | 4 | [![Build Status](https://travis-ci.org/ltcsuite/ltcd.png?branch=master)] 5 | (https://travis-ci.org/ltcsuite/ltcd) 6 | 7 | Package treap implements a treap data structure that is used to hold ordered 8 | key/value pairs using a combination of binary search tree and heap semantics. 9 | It is a self-organizing and randomized data structure that doesn't require 10 | complex operations to to maintain balance. Search, insert, and delete 11 | operations are all O(log n). Both mutable and immutable variants are provided. 12 | 13 | The mutable variant is typically faster since it is able to simply update the 14 | treap when modifications are made. However, a mutable treap is not safe for 15 | concurrent access without careful use of locking by the caller and care must be 16 | taken when iterating since it can change out from under the iterator. 17 | 18 | The immutable variant works by creating a new version of the treap for all 19 | mutations by replacing modified nodes with new nodes that have updated values 20 | while sharing all unmodified nodes with the previous version. This is extremely 21 | useful in concurrent applications since the caller only has to atomically 22 | replace the treap pointer with the newly returned version after performing any 23 | mutations. All readers can simply use their existing pointer as a snapshot 24 | since the treap it points to is immutable. This effectively provides O(1) 25 | snapshot capability with efficient memory usage characteristics since the old 26 | nodes only remain allocated until there are no longer any references to them. 27 | 28 | Package treap is licensed under the copyfree ISC license. 29 | 30 | ## Usage 31 | 32 | This package is only used internally in the database code and as such is not 33 | available for use outside of it. 34 | 35 | ## License 36 | 37 | Package treap is licensed under the [copyfree](http://copyfree.org) ISC 38 | License. 39 | -------------------------------------------------------------------------------- /database/internal/treap/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package treap implements a treap data structure that is used to hold ordered 7 | key/value pairs using a combination of binary search tree and heap semantics. 8 | It is a self-organizing and randomized data structure that doesn't require 9 | complex operations to to maintain balance. Search, insert, and delete 10 | operations are all O(log n). Both mutable and immutable variants are provided. 11 | 12 | The mutable variant is typically faster since it is able to simply update the 13 | treap when modifications are made. However, a mutable treap is not safe for 14 | concurrent access without careful use of locking by the caller and care must be 15 | taken when iterating since it can change out from under the iterator. 16 | 17 | The immutable variant works by creating a new version of the treap for all 18 | mutations by replacing modified nodes with new nodes that have updated values 19 | while sharing all unmodified nodes with the previous version. This is extremely 20 | useful in concurrent applications since the caller only has to atomically 21 | replace the treap pointer with the newly returned version after performing any 22 | mutations. All readers can simply use their existing pointer as a snapshot 23 | since the treap it points to is immutable. This effectively provides O(1) 24 | snapshot capability with efficient memory usage characteristics since the old 25 | nodes only remain allocated until there are no longer any references to them. 26 | */ 27 | package treap 28 | -------------------------------------------------------------------------------- /database/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package database 6 | 7 | import ( 8 | "github.com/btcsuite/btclog" 9 | ) 10 | 11 | // log is a logger that is initialized with no output filters. This 12 | // means the package will not perform any logging by default until the caller 13 | // requests it. 14 | var log btclog.Logger 15 | 16 | // The default amount of logging is none. 17 | func init() { 18 | DisableLog() 19 | } 20 | 21 | // DisableLog disables all library log output. Logging output is disabled 22 | // by default until UseLogger is called. 23 | func DisableLog() { 24 | log = btclog.Disabled 25 | } 26 | 27 | // UseLogger uses a specified Logger to output package logging info. 28 | func UseLogger(logger btclog.Logger) { 29 | log = logger 30 | 31 | // Update the logger for the registered drivers. 32 | for _, drv := range drivers { 33 | if drv.UseLogger != nil { 34 | drv.UseLogger(logger) 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/testdata/blocks1-256.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ltcsuite-archive/ltcd/01737289d815e0e32c91e55593ba2fbd8d090b2c/database/testdata/blocks1-256.bz2 -------------------------------------------------------------------------------- /docs/configure_peer_server_listen_interfaces.md: -------------------------------------------------------------------------------- 1 | ltcd allows you to bind to specific interfaces which enables you to setup 2 | configurations with varying levels of complexity. The listen parameter can be 3 | specified on the command line as shown below with the -- prefix or in the 4 | configuration file without the -- prefix (as can all long command line options). 5 | The configuration file takes one entry per line. 6 | 7 | **NOTE:** The listen flag can be specified multiple times to listen on multiple 8 | interfaces as a couple of the examples below illustrate. 9 | 10 | Command Line Examples: 11 | 12 | |Flags|Comment| 13 | |----------|------------| 14 | |--listen=|all interfaces on default port which is changed by `--testnet` and `--regtest` (**default**)| 15 | |--listen=0.0.0.0|all IPv4 interfaces on default port which is changed by `--testnet` and `--regtest`| 16 | |--listen=::|all IPv6 interfaces on default port which is changed by `--testnet` and `--regtest`| 17 | |--listen=:9333|all interfaces on port 9333| 18 | |--listen=0.0.0.0:9333|all IPv4 interfaces on port 9333| 19 | |--listen=[::]:9333|all IPv6 interfaces on port 9333| 20 | |--listen=127.0.0.1:9333|only IPv4 localhost on port 9333| 21 | |--listen=[::1]:9333|only IPv6 localhost on port 9333| 22 | |--listen=:9336|all interfaces on non-standard port 9336| 23 | |--listen=0.0.0.0:9336|all IPv4 interfaces on non-standard port 9336| 24 | |--listen=[::]:9336|all IPv6 interfaces on non-standard port 9336| 25 | |--listen=127.0.0.1:9337 --listen=[::1]:9333|IPv4 localhost on port 9337 and IPv6 localhost on port 9333| 26 | |--listen=:9333 --listen=:9337|all interfaces on ports 9333 and 9337| 27 | 28 | The following config file would configure ltcd to only listen on localhost for both IPv4 and IPv6: 29 | 30 | ```text 31 | [Application Options] 32 | 33 | listen=127.0.0.1:9333 34 | listen=[::1]:9333 35 | ``` 36 | -------------------------------------------------------------------------------- /docs/configure_rpc_server_listen_interfaces.md: -------------------------------------------------------------------------------- 1 | ltcd allows you to bind the RPC server to specific interfaces which enables you 2 | to setup configurations with varying levels of complexity. The `rpclisten` 3 | parameter can be specified on the command line as shown below with the -- prefix 4 | or in the configuration file without the -- prefix (as can all long command line 5 | options). The configuration file takes one entry per line. 6 | 7 | A few things to note regarding the RPC server: 8 | * The RPC server will **not** be enabled unless the `rpcuser` and `rpcpass` 9 | options are specified. 10 | * When the `rpcuser` and `rpcpass` and/or `rpclimituser` and `rpclimitpass` 11 | options are specified, the RPC server will only listen on localhost IPv4 and 12 | IPv6 interfaces by default. You will need to override the RPC listen 13 | interfaces to include external interfaces if you want to connect from a remote 14 | machine. 15 | * The RPC server has TLS enabled by default, even for localhost. You may use 16 | the `--notls` option to disable it, but only when all listeners are on 17 | localhost interfaces. 18 | * The `--rpclisten` flag can be specified multiple times to listen on multiple 19 | interfaces as a couple of the examples below illustrate. 20 | * The RPC server is disabled by default when using the `--regtest` and 21 | `--simnet` networks. You can override this by specifying listen interfaces. 22 | 23 | Command Line Examples: 24 | 25 | |Flags|Comment| 26 | |----------|------------| 27 | |--rpclisten=|all interfaces on default port which is changed by `--testnet`| 28 | |--rpclisten=0.0.0.0|all IPv4 interfaces on default port which is changed by `--testnet`| 29 | |--rpclisten=::|all IPv6 interfaces on default port which is changed by `--testnet`| 30 | |--rpclisten=:9334|all interfaces on port 9334| 31 | |--rpclisten=0.0.0.0:9334|all IPv4 interfaces on port 9334| 32 | |--rpclisten=[::]:9334|all IPv6 interfaces on port 9334| 33 | |--rpclisten=127.0.0.1:9334|only IPv4 localhost on port 9334| 34 | |--rpclisten=[::1]:9334|only IPv6 localhost on port 9334| 35 | |--rpclisten=:9336|all interfaces on non-standard port 9336| 36 | |--rpclisten=0.0.0.0:9336|all IPv4 interfaces on non-standard port 9336| 37 | |--rpclisten=[::]:9336|all IPv6 interfaces on non-standard port 9336| 38 | |--rpclisten=127.0.0.1:9337 --listen=[::1]:9334|IPv4 localhost on port 9337 and IPv6 localhost on port 9334| 39 | |--rpclisten=:9334 --listen=:9337|all interfaces on ports 9334 and 9337| 40 | 41 | The following config file would configure the ltcd RPC server to listen to all interfaces on the default port, including external interfaces, for both IPv4 and IPv6: 42 | 43 | ```text 44 | [Application Options] 45 | 46 | rpclisten= 47 | ``` 48 | -------------------------------------------------------------------------------- /docs/default_ports.md: -------------------------------------------------------------------------------- 1 | While ltcd is highly configurable when it comes to the network configuration, 2 | the following is intended to be a quick reference for the default ports used so 3 | port forwarding can be configured as required. 4 | 5 | ltcd provides a `--upnp` flag which can be used to automatically map the bitcoin 6 | peer-to-peer listening port if your router supports UPnP. If your router does 7 | not support UPnP, or you don't wish to use it, please note that only the bitcoin 8 | peer-to-peer port should be forwarded unless you specifically want to allow RPC 9 | access to your ltcd from external sources such as in more advanced network 10 | configurations. 11 | 12 | |Name|Port| 13 | |----|----| 14 | |Default Bitcoin peer-to-peer port|TCP 9333| 15 | |Default RPC port|TCP 9334| 16 | -------------------------------------------------------------------------------- /glide.lock: -------------------------------------------------------------------------------- 1 | hash: ff8c04ac22d1d37cc7a7aae05381f16c8f06956c59d0f3aa6acc15353234ec21 2 | updated: 2017-08-25T16:48:07.912091207-07:00 3 | imports: 4 | - name: github.com/aead/siphash 5 | version: e404fcfc888570cadd1610538e2dbc89f66af814 6 | - name: github.com/btcsuite/btclog 7 | version: 84c8d2346e9fc8c7b947e243b9c24e6df9fd206a 8 | - name: github.com/btcsuite/fastsha256 9 | version: 637e656429416087660c84436a2a035d69d54e2e 10 | - name: github.com/btcsuite/go-flags 11 | version: 6c288d648c1cc1befcb90cb5511dcacf64ae8e61 12 | - name: github.com/btcsuite/go-socks 13 | version: 4720035b7bfd2a9bb130b1c184f8bbe41b6f0d0f 14 | subpackages: 15 | - socks 16 | - name: github.com/btcsuite/golangcrypto 17 | version: 53f62d9b43e87a6c56975cf862af7edf33a8d0df 18 | subpackages: 19 | - ripemd160 20 | - name: github.com/btcsuite/goleveldb 21 | version: 7834afc9e8cd15233b6c3d97e12674a31ca24602 22 | subpackages: 23 | - leveldb 24 | - leveldb/cache 25 | - leveldb/comparer 26 | - leveldb/errors 27 | - leveldb/filter 28 | - leveldb/iterator 29 | - leveldb/journal 30 | - leveldb/memdb 31 | - leveldb/opt 32 | - leveldb/storage 33 | - leveldb/table 34 | - leveldb/util 35 | - name: github.com/btcsuite/snappy-go 36 | version: 0bdef8d067237991ddaa1bb6072a740bc40601ba 37 | - name: github.com/btcsuite/websocket 38 | version: 31079b6807923eb23992c421b114992b95131b55 39 | - name: github.com/btcsuite/winsvc 40 | version: f8fb11f83f7e860e3769a08e6811d1b399a43722 41 | subpackages: 42 | - eventlog 43 | - mgr 44 | - registry 45 | - svc 46 | - winapi 47 | - name: github.com/davecgh/go-spew 48 | version: adab96458c51a58dc1783b3335dcce5461522e75 49 | subpackages: 50 | - spew 51 | - name: github.com/jessevdk/go-flags 52 | version: 1679536dcc895411a9f5848d9a0250be7856448c 53 | - name: github.com/jrick/logrotate 54 | version: a93b200c26cbae3bb09dd0dc2c7c7fe1468a034a 55 | subpackages: 56 | - rotator 57 | - name: github.com/kkdai/bstream 58 | version: f391b8402d23024e7c0f624b31267a89998fca95 59 | - name: github.com/ltcsuite/ltcutil 60 | version: a88d7dfb1c02af5dffe005ad21f40c42d9fd5ad0 61 | subpackages: 62 | - base58 63 | - bech32 64 | - bloom 65 | - gcs 66 | - gcs/builder 67 | - hdkeychain 68 | - name: golang.org/x/crypto 69 | version: 81e90905daefcd6fd217b62423c0908922eadb30 70 | subpackages: 71 | - pbkdf2 72 | - ripemd160 73 | - scrypt 74 | testImports: [] 75 | -------------------------------------------------------------------------------- /glide.yaml: -------------------------------------------------------------------------------- 1 | package: github.com/ltcsuite/ltcd 2 | import: 3 | - package: github.com/btcsuite/btclog 4 | - package: github.com/ltcsuite/ltcutil 5 | version: a88d7dfb1c02af5dffe005ad21f40c42d9fd5ad0 6 | subpackages: 7 | - bloom 8 | - hdkeychain 9 | - package: github.com/btcsuite/go-flags 10 | - package: github.com/btcsuite/go-socks 11 | subpackages: 12 | - socks 13 | - package: golang.org/x/crypto 14 | subpackages: 15 | - ripemd160 16 | - package: github.com/btcsuite/goleveldb 17 | subpackages: 18 | - leveldb 19 | - leveldb/comparer 20 | - leveldb/errors 21 | - leveldb/filter 22 | - leveldb/iterator 23 | - leveldb/opt 24 | - leveldb/util 25 | - package: github.com/btcsuite/websocket 26 | - package: github.com/btcsuite/winsvc 27 | subpackages: 28 | - eventlog 29 | - mgr 30 | - svc 31 | - package: github.com/davecgh/go-spew 32 | subpackages: 33 | - spew 34 | - package: github.com/jessevdk/go-flags 35 | version: 1679536dcc895411a9f5848d9a0250be7856448c 36 | - package: github.com/jrick/logrotate 37 | -------------------------------------------------------------------------------- /goclean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # The script does automatic checking on a Go package and its sub-packages, including: 3 | # 1. gofmt (http://golang.org/cmd/gofmt/) 4 | # 2. golint (https://github.com/golang/lint) 5 | # 3. go vet (http://golang.org/cmd/vet) 6 | # 4. gosimple (https://github.com/dominikh/go-simple) 7 | # 5. unconvert (https://github.com/mdempsky/unconvert) 8 | # 9 | # gometalinter (github.com/alecthomas/gometalinter) is used to run each static 10 | # checker. 11 | 12 | set -ex 13 | 14 | # Make sure glide is installed and $GOPATH/bin is in your path. 15 | # $ go get -u github.com/Masterminds/glide 16 | # $ glide install 17 | if [ ! -x "$(type -p glide)" ]; then 18 | exit 1 19 | fi 20 | 21 | # Make sure gometalinter is installed and $GOPATH/bin is in your path. 22 | # $ go get -v github.com/alecthomas/gometalinter" 23 | # $ gometalinter --install" 24 | if [ ! -x "$(type -p gometalinter)" ]; then 25 | exit 1 26 | fi 27 | 28 | linter_targets=$(glide novendor) 29 | 30 | # Automatic checks 31 | test -z "$(gometalinter -j 4 --disable-all \ 32 | --enable=gofmt \ 33 | --enable=golint \ 34 | --enable=vet \ 35 | --enable=gosimple \ 36 | --enable=unconvert \ 37 | --deadline=10m $linter_targets 2>&1 | grep -v 'ALL_CAPS\|OP_' 2>&1 | tee /dev/stderr)" 38 | go test -tags rpctest $linter_targets 39 | -------------------------------------------------------------------------------- /integration/README.md: -------------------------------------------------------------------------------- 1 | integration 2 | =========== 3 | 4 | [![Build Status](http://img.shields.io/travis/ltcsuite/ltcd.svg)] 5 | (https://travis-ci.org/ltcsuite/ltcd) [![ISC License] 6 | (http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 7 | 8 | This contains integration tests which make use of the 9 | [rpctest](https://github.com/ltcsuite/ltcd/tree/master/rpctest) package to 10 | programmatically drive nodes via RPC. 11 | 12 | ## License 13 | 14 | This code is licensed under the [copyfree](http://copyfree.org) ISC License. 15 | -------------------------------------------------------------------------------- /integration/main.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package integration 6 | 7 | // This file only exists to prevent warnings due to no buildable source files 8 | // when the build tag for enabling the tests is not specified. 9 | -------------------------------------------------------------------------------- /integration/rpctest/README.md: -------------------------------------------------------------------------------- 1 | rpctest 2 | ======= 3 | 4 | [![Build Status](http://img.shields.io/travis/ltcsuite/ltcd.svg)](https://travis-ci.org/ltcsuite/ltcd) 5 | [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 6 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/ltcsuite/ltcd/integration/rpctest) 7 | 8 | Package rpctest provides a ltcd-specific RPC testing harness crafting and 9 | executing integration tests by driving a `ltcd` instance via the `RPC` 10 | interface. Each instance of an active harness comes equipped with a simple 11 | in-memory HD wallet capable of properly syncing to the generated chain, 12 | creating new addresses, and crafting fully signed transactions paying to an 13 | arbitrary set of outputs. 14 | 15 | This package was designed specifically to act as an RPC testing harness for 16 | `ltcd`. However, the constructs presented are general enough to be adapted to 17 | any project wishing to programmatically drive a `ltcd` instance of its 18 | systems/integration tests. 19 | 20 | ## Installation and Updating 21 | 22 | ```bash 23 | $ go get -u github.com/ltcsuite/ltcd/integration/rpctest 24 | ``` 25 | 26 | ## License 27 | 28 | Package rpctest is licensed under the [copyfree](http://copyfree.org) ISC 29 | License. 30 | 31 | ======= 32 | rpctest 33 | ======= 34 | 35 | [![Build Status](http://img.shields.io/travis/ltcsuite/ltcd.svg)] 36 | (https://travis-ci.org/ltcsuite/ltcd) [![ISC License] 37 | (http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 38 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)] 39 | (http://godoc.org/github.com/ltcsuite/ltcd/rpctest) 40 | 41 | Package rpctest provides a ltcd-specific RPC testing harness crafting and 42 | executing integration tests by driving a `ltcd` instance via the `RPC` 43 | interface. Each instance of an active harness comes equipped with a simple 44 | in-memory HD wallet capable of properly syncing to the generated chain, 45 | creating new addresses, and crafting fully signed transactions paying to an 46 | arbitrary set of outputs. 47 | 48 | This package was designed specifically to act as an RPC testing harness for 49 | `ltcd`. However, the constructs presented are general enough to be adapted to 50 | any project wishing to programmatically drive a `ltcd` instance of its 51 | systems/integration tests. 52 | 53 | ## Installation and Updating 54 | 55 | ```bash 56 | $ go get -u github.com/ltcsuite/ltcd/rpctest 57 | ``` 58 | 59 | ## License 60 | 61 | 62 | Package rpctest is licensed under the [copyfree](http://copyfree.org) ISC 63 | License. 64 | 65 | -------------------------------------------------------------------------------- /integration/rpctest/doc.go: -------------------------------------------------------------------------------- 1 | // Package rpctest provides a ltcd-specific RPC testing harness crafting and 2 | // executing integration tests by driving a `ltcd` instance via the `RPC` 3 | // interface. Each instance of an active harness comes equipped with a simple 4 | // in-memory HD wallet capable of properly syncing to the generated chain, 5 | // creating new addresses, and crafting fully signed transactions paying to an 6 | // arbitrary set of outputs. 7 | // 8 | // This package was designed specifically to act as an RPC testing harness for 9 | // `ltcd`. However, the constructs presented are general enough to be adapted to 10 | // any project wishing to programmatically drive a `ltcd` instance of its 11 | // systems/integration tests. 12 | package rpctest 13 | -------------------------------------------------------------------------------- /limits/limits_plan9.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package limits 6 | 7 | // SetLimits is a no-op on Plan 9 due to the lack of process accounting. 8 | func SetLimits() error { 9 | return nil 10 | } 11 | -------------------------------------------------------------------------------- /limits/limits_unix.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !windows,!plan9 6 | 7 | package limits 8 | 9 | import ( 10 | "fmt" 11 | "syscall" 12 | ) 13 | 14 | const ( 15 | fileLimitWant = 2048 16 | fileLimitMin = 1024 17 | ) 18 | 19 | // SetLimits raises some process limits to values which allow ltcd and 20 | // associated utilities to run. 21 | func SetLimits() error { 22 | var rLimit syscall.Rlimit 23 | 24 | err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) 25 | if err != nil { 26 | return err 27 | } 28 | if rLimit.Cur > fileLimitWant { 29 | return nil 30 | } 31 | if rLimit.Max < fileLimitMin { 32 | err = fmt.Errorf("need at least %v file descriptors", 33 | fileLimitMin) 34 | return err 35 | } 36 | if rLimit.Max < fileLimitWant { 37 | rLimit.Cur = rLimit.Max 38 | } else { 39 | rLimit.Cur = fileLimitWant 40 | } 41 | err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) 42 | if err != nil { 43 | // try min value 44 | rLimit.Cur = fileLimitMin 45 | err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) 46 | if err != nil { 47 | return err 48 | } 49 | } 50 | 51 | return nil 52 | } 53 | -------------------------------------------------------------------------------- /limits/limits_windows.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package limits 6 | 7 | // SetLimits is a no-op on Windows since it's not required there. 8 | func SetLimits() error { 9 | return nil 10 | } 11 | -------------------------------------------------------------------------------- /mempool/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package mempool 6 | 7 | import ( 8 | "github.com/btcsuite/btclog" 9 | ) 10 | 11 | // log is a logger that is initialized with no output filters. This 12 | // means the package will not perform any logging by default until the caller 13 | // requests it. 14 | var log btclog.Logger 15 | 16 | // The default amount of logging is none. 17 | func init() { 18 | DisableLog() 19 | } 20 | 21 | // DisableLog disables all library log output. Logging output is disabled 22 | // by default until either UseLogger or SetLogWriter are called. 23 | func DisableLog() { 24 | log = btclog.Disabled 25 | } 26 | 27 | // UseLogger uses a specified Logger to output package logging info. 28 | // This should be used in preference to SetLogWriter if the caller is also 29 | // using btclog. 30 | func UseLogger(logger btclog.Logger) { 31 | log = logger 32 | } 33 | 34 | // pickNoun returns the singular or plural form of a noun depending 35 | // on the count n. 36 | func pickNoun(n int, singular, plural string) string { 37 | if n == 1 { 38 | return singular 39 | } 40 | return plural 41 | } 42 | -------------------------------------------------------------------------------- /mining/README.md: -------------------------------------------------------------------------------- 1 | mining 2 | ====== 3 | 4 | [![Build Status](http://img.shields.io/travis/ltcsuite/ltcd.svg)] 5 | (https://travis-ci.org/ltcsuite/ltcd) [![ISC License] 6 | (http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 7 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)] 8 | (http://godoc.org/github.com/ltcsuite/ltcd/mining) 9 | 10 | ## Overview 11 | 12 | This package is currently a work in progress. 13 | 14 | ## Installation and Updating 15 | 16 | ```bash 17 | $ go get -u github.com/ltcsuite/ltcd/mining 18 | ``` 19 | 20 | ## License 21 | 22 | Package mining is licensed under the [copyfree](http://copyfree.org) ISC 23 | License. 24 | -------------------------------------------------------------------------------- /mining/cpuminer/README.md: -------------------------------------------------------------------------------- 1 | cpuminer 2 | ======== 3 | 4 | [![Build Status](http://img.shields.io/travis/ltcsuite/ltcd.svg)](https://travis-ci.org/ltcsuite/ltcd) 5 | [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 6 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/ltcsuite/ltcd/mining/cpuminer) 7 | 8 | ## Overview 9 | 10 | This package is currently a work in progress. It works without issue since it 11 | is used in several of the integration tests, but the API is not really ready for 12 | public consumption as it has simply been refactored out of the main codebase for 13 | now. 14 | 15 | ## Installation and Updating 16 | 17 | ```bash 18 | $ go get -u github.com/ltcsuite/ltcd/mining/cpuminer 19 | ``` 20 | 21 | ## License 22 | 23 | Package cpuminer is licensed under the [copyfree](http://copyfree.org) ISC 24 | License. 25 | -------------------------------------------------------------------------------- /mining/cpuminer/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpuminer 6 | 7 | import ( 8 | "github.com/btcsuite/btclog" 9 | ) 10 | 11 | // log is a logger that is initialized with no output filters. This 12 | // means the package will not perform any logging by default until the caller 13 | // requests it. 14 | var log btclog.Logger 15 | 16 | // The default amount of logging is none. 17 | func init() { 18 | DisableLog() 19 | } 20 | 21 | // DisableLog disables all library log output. Logging output is disabled 22 | // by default until UseLogger is called. 23 | func DisableLog() { 24 | log = btclog.Disabled 25 | } 26 | 27 | // UseLogger uses a specified Logger to output package logging info. 28 | func UseLogger(logger btclog.Logger) { 29 | log = logger 30 | } 31 | -------------------------------------------------------------------------------- /mining/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package mining 6 | 7 | import ( 8 | "github.com/btcsuite/btclog" 9 | ) 10 | 11 | // log is a logger that is initialized with no output filters. This 12 | // means the package will not perform any logging by default until the caller 13 | // requests it. 14 | var log btclog.Logger 15 | 16 | // The default amount of logging is none. 17 | func init() { 18 | DisableLog() 19 | } 20 | 21 | // DisableLog disables all library log output. Logging output is disabled 22 | // by default until UseLogger is called. 23 | func DisableLog() { 24 | log = btclog.Disabled 25 | } 26 | 27 | // UseLogger uses a specified Logger to output package logging info. 28 | func UseLogger(logger btclog.Logger) { 29 | log = logger 30 | } 31 | -------------------------------------------------------------------------------- /params.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "github.com/ltcsuite/ltcd/chaincfg" 9 | "github.com/ltcsuite/ltcd/wire" 10 | ) 11 | 12 | // activeNetParams is a pointer to the parameters specific to the 13 | // currently active bitcoin network. 14 | var activeNetParams = &mainNetParams 15 | 16 | // params is used to group parameters for various networks such as the main 17 | // network and test networks. 18 | type params struct { 19 | *chaincfg.Params 20 | rpcPort string 21 | } 22 | 23 | // mainNetParams contains parameters specific to the main network 24 | // (wire.MainNet). NOTE: The RPC port is intentionally different than the 25 | // reference implementation because ltcd does not handle wallet requests. The 26 | // separate wallet process listens on the well-known port and forwards requests 27 | // it does not handle on to ltcd. This approach allows the wallet process 28 | // to emulate the full reference implementation RPC API. 29 | var mainNetParams = params{ 30 | Params: &chaincfg.MainNetParams, 31 | rpcPort: "9334", 32 | } 33 | 34 | // regressionNetParams contains parameters specific to the regression test 35 | // network (wire.TestNet). NOTE: The RPC port is intentionally different 36 | // than the reference implementation - see the mainNetParams comment for 37 | // details. 38 | var regressionNetParams = params{ 39 | Params: &chaincfg.RegressionNetParams, 40 | rpcPort: "19334", 41 | } 42 | 43 | // testNet4Params contains parameters specific to the test network (version 4) 44 | // (wire.TestNet4). NOTE: The RPC port is intentionally different than the 45 | // reference implementation - see the mainNetParams comment for details. 46 | var testNet4Params = params{ 47 | Params: &chaincfg.TestNet4Params, 48 | rpcPort: "19334", 49 | } 50 | 51 | // simNetParams contains parameters specific to the simulation test network 52 | // (wire.SimNet). 53 | var simNetParams = params{ 54 | Params: &chaincfg.SimNetParams, 55 | rpcPort: "18556", 56 | } 57 | 58 | // netName returns the name used when referring to a bitcoin network. At the 59 | // time of writing, ltcd currently places blocks for testnet version 3 in the 60 | // data and log directory "testnet", which does not match the Name field of the 61 | // chaincfg parameters. This function can be used to override this directory 62 | // name as "testnet" when the passed active network matches wire.TestNet4. 63 | // 64 | // A proper upgrade to move the data and log directories for this network to 65 | // "testnet4" is planned for the future, at which point this function can be 66 | // removed and the network parameter's name used instead. 67 | func netName(chainParams *params) string { 68 | switch chainParams.Net { 69 | case wire.TestNet4: 70 | return "testnet" 71 | default: 72 | return chainParams.Name 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /peer/export_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | This test file is part of the peer package rather than than the peer_test 7 | package so it can bridge access to the internals to properly test cases which 8 | are either not possible or can't reliably be tested via the public interface. 9 | The functions are only exported while the tests are being run. 10 | */ 11 | 12 | package peer 13 | 14 | // TstAllowSelfConns allows the test package to allow self connections by 15 | // disabling the detection logic. 16 | func TstAllowSelfConns() { 17 | allowSelfConns = true 18 | } 19 | -------------------------------------------------------------------------------- /release/notes.sample: -------------------------------------------------------------------------------- 1 | - Each release note is preceded by a dash 2 | - Each release note must not exceed 74 characters per line 3 | - Release notes that require a longer explanation than will fit on a 4 | single line should be wrapped with the text indented as in this line 5 | - No periods at the end of each release note 6 | - Other minor cleanup and bug fixes 7 | -------------------------------------------------------------------------------- /rpcclient/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This is the list of people who have contributed code to the repository. 2 | # 3 | # Names should be added to this file only after verifying that the individual 4 | # or the individual's organization has agreed to the LICENSE. 5 | # 6 | # Names should be added to this file like so: 7 | # Name 8 | 9 | Dave Collins 10 | Geert-Johan Riemer 11 | Josh Rickmar 12 | Michalis Kargakis 13 | Ruben de Vries 0 { 56 | log.Printf("First utxo:\n%v", spew.Sdump(unspent[0])) 57 | } 58 | 59 | // For this example gracefully shutdown the client after 10 seconds. 60 | // Ordinarily when to shutdown the client is highly application 61 | // specific. 62 | log.Println("Client shutdown in 10 seconds...") 63 | time.AfterFunc(time.Second*10, func() { 64 | log.Println("Client shutting down...") 65 | client.Shutdown() 66 | log.Println("Client shutdown complete.") 67 | }) 68 | 69 | // Wait until the client either shuts down gracefully (or the user 70 | // terminates the process with Ctrl+C). 71 | client.WaitForShutdown() 72 | } 73 | -------------------------------------------------------------------------------- /rpcclient/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2017 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package rpcclient 6 | 7 | import ( 8 | "github.com/btcsuite/btclog" 9 | ) 10 | 11 | // log is a logger that is initialized with no output filters. This 12 | // means the package will not perform any logging by default until the caller 13 | // requests it. 14 | var log btclog.Logger 15 | 16 | // The default amount of logging is none. 17 | func init() { 18 | DisableLog() 19 | } 20 | 21 | // DisableLog disables all library log output. Logging output is disabled 22 | // by default until UseLogger is called. 23 | func DisableLog() { 24 | log = btclog.Disabled 25 | } 26 | 27 | // UseLogger uses a specified Logger to output package logging info. 28 | func UseLogger(logger btclog.Logger) { 29 | log = logger 30 | } 31 | 32 | // LogClosure is a closure that can be printed with %v to be used to 33 | // generate expensive-to-create data for a detailed log level and avoid doing 34 | // the work if the data isn't printed. 35 | type logClosure func() string 36 | 37 | // String invokes the log closure and returns the results string. 38 | func (c logClosure) String() string { 39 | return c() 40 | } 41 | 42 | // newLogClosure returns a new closure over the passed function which allows 43 | // it to be used as a parameter in a logging function that is only invoked when 44 | // the logging level is such that the message will actually be logged. 45 | func newLogClosure(c func() string) logClosure { 46 | return logClosure(c) 47 | } 48 | -------------------------------------------------------------------------------- /rpcclient/rawrequest.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2017 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package rpcclient 6 | 7 | import ( 8 | "encoding/json" 9 | "errors" 10 | 11 | "github.com/ltcsuite/ltcd/btcjson" 12 | ) 13 | 14 | // FutureRawResult is a future promise to deliver the result of a RawRequest RPC 15 | // invocation (or an applicable error). 16 | type FutureRawResult chan *response 17 | 18 | // Receive waits for the response promised by the future and returns the raw 19 | // response, or an error if the request was unsuccessful. 20 | func (r FutureRawResult) Receive() (json.RawMessage, error) { 21 | return receiveFuture(r) 22 | } 23 | 24 | // RawRequestAsync returns an instance of a type that can be used to get the 25 | // result of a custom RPC request at some future time by invoking the Receive 26 | // function on the returned instance. 27 | // 28 | // See RawRequest for the blocking version and more details. 29 | func (c *Client) RawRequestAsync(method string, params []json.RawMessage) FutureRawResult { 30 | // Method may not be empty. 31 | if method == "" { 32 | return newFutureError(errors.New("no method")) 33 | } 34 | 35 | // Marshal parameters as "[]" instead of "null" when no parameters 36 | // are passed. 37 | if params == nil { 38 | params = []json.RawMessage{} 39 | } 40 | 41 | // Create a raw JSON-RPC request using the provided method and params 42 | // and marshal it. This is done rather than using the sendCmd function 43 | // since that relies on marshalling registered btcjson commands rather 44 | // than custom commands. 45 | id := c.NextID() 46 | rawRequest := &btcjson.Request{ 47 | Jsonrpc: "1.0", 48 | ID: id, 49 | Method: method, 50 | Params: params, 51 | } 52 | marshalledJSON, err := json.Marshal(rawRequest) 53 | if err != nil { 54 | return newFutureError(err) 55 | } 56 | 57 | // Generate the request and send it along with a channel to respond on. 58 | responseChan := make(chan *response, 1) 59 | jReq := &jsonRequest{ 60 | id: id, 61 | method: method, 62 | cmd: nil, 63 | marshalledJSON: marshalledJSON, 64 | responseChan: responseChan, 65 | } 66 | c.sendRequest(jReq) 67 | 68 | return responseChan 69 | } 70 | 71 | // RawRequest allows the caller to send a raw or custom request to the server. 72 | // This method may be used to send and receive requests and responses for 73 | // requests that are not handled by this client package, or to proxy partially 74 | // unmarshaled requests to another JSON-RPC server if a request cannot be 75 | // handled directly. 76 | func (c *Client) RawRequest(method string, params []json.RawMessage) (json.RawMessage, error) { 77 | return c.RawRequestAsync(method, params).Receive() 78 | } 79 | -------------------------------------------------------------------------------- /rpcserverhelp_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import "testing" 8 | 9 | // TestHelp ensures the help is reasonably accurate by checking that every 10 | // command specified also has result types defined and the one-line usage and 11 | // help text can be generated for them. 12 | func TestHelp(t *testing.T) { 13 | // Ensure there are result types specified for every handler. 14 | for k := range rpcHandlers { 15 | if _, ok := rpcResultTypes[k]; !ok { 16 | t.Errorf("RPC handler defined for method '%v' without "+ 17 | "also specifying result types", k) 18 | continue 19 | } 20 | 21 | } 22 | for k := range wsHandlers { 23 | if _, ok := rpcResultTypes[k]; !ok { 24 | t.Errorf("RPC handler defined for method '%v' without "+ 25 | "also specifying result types", k) 26 | continue 27 | } 28 | 29 | } 30 | 31 | // Ensure the usage for every command can be generated without errors. 32 | helpCacher := newHelpCacher() 33 | if _, err := helpCacher.rpcUsage(true); err != nil { 34 | t.Fatalf("Failed to generate one-line usage: %v", err) 35 | } 36 | if _, err := helpCacher.rpcUsage(true); err != nil { 37 | t.Fatalf("Failed to generate one-line usage (cached): %v", err) 38 | } 39 | 40 | // Ensure the help for every command can be generated without errors. 41 | for k := range rpcHandlers { 42 | if _, err := helpCacher.rpcMethodHelp(k); err != nil { 43 | t.Errorf("Failed to generate help for method '%v': %v", 44 | k, err) 45 | continue 46 | } 47 | if _, err := helpCacher.rpcMethodHelp(k); err != nil { 48 | t.Errorf("Failed to generate help for method '%v'"+ 49 | "(cached): %v", k, err) 50 | continue 51 | } 52 | } 53 | for k := range wsHandlers { 54 | if _, err := helpCacher.rpcMethodHelp(k); err != nil { 55 | t.Errorf("Failed to generate help for method '%v': %v", 56 | k, err) 57 | continue 58 | } 59 | if _, err := helpCacher.rpcMethodHelp(k); err != nil { 60 | t.Errorf("Failed to generate help for method '%v'"+ 61 | "(cached): %v", k, err) 62 | continue 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /signal.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "os" 9 | "os/signal" 10 | ) 11 | 12 | // shutdownRequestChannel is used to initiate shutdown from one of the 13 | // subsystems using the same code paths as when an interrupt signal is received. 14 | var shutdownRequestChannel = make(chan struct{}) 15 | 16 | // interruptSignals defines the default signals to catch in order to do a proper 17 | // shutdown. This may be modified during init depending on the platform. 18 | var interruptSignals = []os.Signal{os.Interrupt} 19 | 20 | // interruptListener listens for OS Signals such as SIGINT (Ctrl+C) and shutdown 21 | // requests from shutdownRequestChannel. It returns a channel that is closed 22 | // when either signal is received. 23 | func interruptListener() <-chan struct{} { 24 | c := make(chan struct{}) 25 | go func() { 26 | interruptChannel := make(chan os.Signal, 1) 27 | signal.Notify(interruptChannel, interruptSignals...) 28 | 29 | // Listen for initial shutdown signal and close the returned 30 | // channel to notify the caller. 31 | select { 32 | case sig := <-interruptChannel: 33 | ltcdLog.Infof("Received signal (%s). Shutting down...", 34 | sig) 35 | 36 | case <-shutdownRequestChannel: 37 | ltcdLog.Info("Shutdown requested. Shutting down...") 38 | } 39 | close(c) 40 | 41 | // Listen for repeated signals and display a message so the user 42 | // knows the shutdown is in progress and the process is not 43 | // hung. 44 | for { 45 | select { 46 | case sig := <-interruptChannel: 47 | ltcdLog.Infof("Received signal (%s). Already "+ 48 | "shutting down...", sig) 49 | 50 | case <-shutdownRequestChannel: 51 | ltcdLog.Info("Shutdown requested. Already " + 52 | "shutting down...") 53 | } 54 | } 55 | }() 56 | 57 | return c 58 | } 59 | 60 | // interruptRequested returns true when the channel returned by 61 | // interruptListener was closed. This simplifies early shutdown slightly since 62 | // the caller can just use an if statement instead of a select. 63 | func interruptRequested(interrupted <-chan struct{}) bool { 64 | select { 65 | case <-interrupted: 66 | return true 67 | default: 68 | } 69 | 70 | return false 71 | } 72 | -------------------------------------------------------------------------------- /signalsigterm.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin dragonfly freebsd linux netbsd openbsd solaris 6 | 7 | package main 8 | 9 | import ( 10 | "os" 11 | "syscall" 12 | ) 13 | 14 | func init() { 15 | interruptSignals = []os.Signal{os.Interrupt, syscall.SIGTERM} 16 | } 17 | -------------------------------------------------------------------------------- /txscript/README.md: -------------------------------------------------------------------------------- 1 | txscript 2 | ======== 3 | 4 | [![Build Status](https://travis-ci.org/ltcsuite/ltcd.png?branch=master)] 5 | (https://travis-ci.org/ltcsuite/ltcd) [![ISC License] 6 | (http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) 7 | [![GoDoc](https://godoc.org/github.com/ltcsuite/ltcd/txscript?status.png)] 8 | (http://godoc.org/github.com/ltcsuite/ltcd/txscript) 9 | 10 | Package txscript implements the bitcoin transaction script language. There is 11 | a comprehensive test suite. 12 | 13 | This package has intentionally been designed so it can be used as a standalone 14 | package for any projects needing to use or validate bitcoin transaction scripts. 15 | 16 | ## Bitcoin Scripts 17 | 18 | Bitcoin provides a stack-based, FORTH-like language for the scripts in 19 | the bitcoin transactions. This language is not turing complete 20 | although it is still fairly powerful. A description of the language 21 | can be found at https://en.bitcoin.it/wiki/Script 22 | 23 | ## Installation and Updating 24 | 25 | ```bash 26 | $ go get -u github.com/ltcsuite/ltcd/txscript 27 | ``` 28 | 29 | ## Examples 30 | 31 | * [Standard Pay-to-pubkey-hash Script] 32 | (http://godoc.org/github.com/ltcsuite/ltcd/txscript#example-PayToAddrScript) 33 | Demonstrates creating a script which pays to a bitcoin address. It also 34 | prints the created script hex and uses the DisasmString function to display 35 | the disassembled script. 36 | 37 | * [Extracting Details from Standard Scripts] 38 | (http://godoc.org/github.com/ltcsuite/ltcd/txscript#example-ExtractPkScriptAddrs) 39 | Demonstrates extracting information from a standard public key script. 40 | 41 | * [Manually Signing a Transaction Output] 42 | (http://godoc.org/github.com/ltcsuite/ltcd/txscript#example-SignTxOutput) 43 | Demonstrates manually creating and signing a redeem transaction. 44 | 45 | ## GPG Verification Key 46 | 47 | All official release tags are signed by Conformal so users can ensure the code 48 | has not been tampered with and is coming from the btcsuite developers. To 49 | verify the signature perform the following: 50 | 51 | - Download the public key from the Conformal website at 52 | https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt 53 | 54 | - Import the public key into your GPG keyring: 55 | ```bash 56 | gpg --import GIT-GPG-KEY-conformal.txt 57 | ``` 58 | 59 | - Verify the release tag with the following command where `TAG_NAME` is a 60 | placeholder for the specific tag: 61 | ```bash 62 | git tag -v TAG_NAME 63 | ``` 64 | 65 | ## License 66 | 67 | Package txscript is licensed under the [copyfree](http://copyfree.org) ISC 68 | License. 69 | -------------------------------------------------------------------------------- /txscript/consensus.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package txscript 6 | 7 | const ( 8 | // LockTimeThreshold is the number below which a lock time is 9 | // interpreted to be a block number. Since an average of one block 10 | // is generated per 10 minutes, this allows blocks for about 9,512 11 | // years. 12 | LockTimeThreshold = 5e8 // Tue Nov 5 00:53:20 1985 UTC 13 | ) 14 | -------------------------------------------------------------------------------- /txscript/data/LICENSE: -------------------------------------------------------------------------------- 1 | The json files in this directory come from the bitcoind project 2 | (https://github.com/bitcoin/bitcoin) and is released under the following 3 | license: 4 | 5 | Copyright (c) 2012-2014 The Bitcoin Core developers 6 | Distributed under the MIT/X11 software license, see the accompanying 7 | file COPYING or http://www.opensource.org/licenses/mit-license.php. 8 | 9 | -------------------------------------------------------------------------------- /txscript/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2017 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package txscript implements the bitcoin transaction script language. 7 | 8 | A complete description of the script language used by bitcoin can be found at 9 | https://en.bitcoin.it/wiki/Script. The following only serves as a quick 10 | overview to provide information on how to use the package. 11 | 12 | This package provides data structures and functions to parse and execute 13 | bitcoin transaction scripts. 14 | 15 | Script Overview 16 | 17 | Bitcoin transaction scripts are written in a stack-base, FORTH-like language. 18 | 19 | The bitcoin script language consists of a number of opcodes which fall into 20 | several categories such pushing and popping data to and from the stack, 21 | performing basic and bitwise arithmetic, conditional branching, comparing 22 | hashes, and checking cryptographic signatures. Scripts are processed from left 23 | to right and intentionally do not provide loops. 24 | 25 | The vast majority of Bitcoin scripts at the time of this writing are of several 26 | standard forms which consist of a spender providing a public key and a signature 27 | which proves the spender owns the associated private key. This information 28 | is used to prove the the spender is authorized to perform the transaction. 29 | 30 | One benefit of using a scripting language is added flexibility in specifying 31 | what conditions must be met in order to spend bitcoins. 32 | 33 | Errors 34 | 35 | Errors returned by this package are of type txscript.Error. This allows the 36 | caller to programmatically determine the specific error by examining the 37 | ErrorCode field of the type asserted txscript.Error while still providing rich 38 | error messages with contextual information. A convenience function named 39 | IsErrorCode is also provided to allow callers to easily check for a specific 40 | error code. See ErrorCode in the package documentation for a full list. 41 | */ 42 | package txscript 43 | -------------------------------------------------------------------------------- /txscript/hashcache.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package txscript 6 | 7 | import ( 8 | "sync" 9 | 10 | "github.com/ltcsuite/ltcd/chaincfg/chainhash" 11 | "github.com/ltcsuite/ltcd/wire" 12 | ) 13 | 14 | // TxSigHashes houses the partial set of sighashes introduced within BIP0143. 15 | // This partial set of sighashes may be re-used within each input across a 16 | // transaction when validating all inputs. As a result, validation complexity 17 | // for SigHashAll can be reduced by a polynomial factor. 18 | type TxSigHashes struct { 19 | HashPrevOuts chainhash.Hash 20 | HashSequence chainhash.Hash 21 | HashOutputs chainhash.Hash 22 | } 23 | 24 | // NewTxSigHashes computes, and returns the cached sighashes of the given 25 | // transaction. 26 | func NewTxSigHashes(tx *wire.MsgTx) *TxSigHashes { 27 | return &TxSigHashes{ 28 | HashPrevOuts: calcHashPrevOuts(tx), 29 | HashSequence: calcHashSequence(tx), 30 | HashOutputs: calcHashOutputs(tx), 31 | } 32 | } 33 | 34 | // HashCache houses a set of partial sighashes keyed by txid. The set of partial 35 | // sighashes are those introduced within BIP0143 by the new more efficient 36 | // sighash digest calculation algorithm. Using this threadsafe shared cache, 37 | // multiple goroutines can safely re-use the pre-computed partial sighashes 38 | // speeding up validation time amongst all inputs found within a block. 39 | type HashCache struct { 40 | sigHashes map[chainhash.Hash]*TxSigHashes 41 | 42 | sync.RWMutex 43 | } 44 | 45 | // NewHashCache returns a new instance of the HashCache given a maximum number 46 | // of entries which may exist within it at anytime. 47 | func NewHashCache(maxSize uint) *HashCache { 48 | return &HashCache{ 49 | sigHashes: make(map[chainhash.Hash]*TxSigHashes, maxSize), 50 | } 51 | } 52 | 53 | // AddSigHashes computes, then adds the partial sighashes for the passed 54 | // transaction. 55 | func (h *HashCache) AddSigHashes(tx *wire.MsgTx) { 56 | h.Lock() 57 | h.sigHashes[tx.TxHash()] = NewTxSigHashes(tx) 58 | h.Unlock() 59 | } 60 | 61 | // ContainsHashes returns true if the partial sighashes for the passed 62 | // transaction currently exist within the HashCache, and false otherwise. 63 | func (h *HashCache) ContainsHashes(txid *chainhash.Hash) bool { 64 | h.RLock() 65 | _, found := h.sigHashes[*txid] 66 | h.RUnlock() 67 | 68 | return found 69 | } 70 | 71 | // GetSigHashes possibly returns the previously cached partial sighashes for 72 | // the passed transaction. This function also returns an additional boolean 73 | // value indicating if the sighashes for the passed transaction were found to 74 | // be present within the HashCache. 75 | func (h *HashCache) GetSigHashes(txid *chainhash.Hash) (*TxSigHashes, bool) { 76 | h.RLock() 77 | item, found := h.sigHashes[*txid] 78 | h.RUnlock() 79 | 80 | return item, found 81 | } 82 | 83 | // PurgeSigHashes removes all partial sighashes from the HashCache belonging to 84 | // the passed transaction. 85 | func (h *HashCache) PurgeSigHashes(txid *chainhash.Hash) { 86 | h.Lock() 87 | delete(h.sigHashes, *txid) 88 | h.Unlock() 89 | } 90 | -------------------------------------------------------------------------------- /txscript/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package txscript 6 | 7 | import ( 8 | "github.com/btcsuite/btclog" 9 | ) 10 | 11 | // log is a logger that is initialized with no output filters. This 12 | // means the package will not perform any logging by default until the caller 13 | // requests it. 14 | var log btclog.Logger 15 | 16 | // The default amount of logging is none. 17 | func init() { 18 | DisableLog() 19 | } 20 | 21 | // DisableLog disables all library log output. Logging output is disabled 22 | // by default until UseLogger is called. 23 | func DisableLog() { 24 | log = btclog.Disabled 25 | } 26 | 27 | // UseLogger uses a specified Logger to output package logging info. 28 | func UseLogger(logger btclog.Logger) { 29 | log = logger 30 | } 31 | 32 | // LogClosure is a closure that can be printed with %v to be used to 33 | // generate expensive-to-create data for a detailed log level and avoid doing 34 | // the work if the data isn't printed. 35 | type logClosure func() string 36 | 37 | func (c logClosure) String() string { 38 | return c() 39 | } 40 | 41 | func newLogClosure(c func() string) logClosure { 42 | return logClosure(c) 43 | } 44 | -------------------------------------------------------------------------------- /version.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "bytes" 9 | "fmt" 10 | "strings" 11 | ) 12 | 13 | // semanticAlphabet 14 | const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" 15 | 16 | // These constants define the application version and follow the semantic 17 | // versioning 2.0.0 spec (http://semver.org/). 18 | const ( 19 | appMajor uint = 0 20 | appMinor uint = 12 21 | appPatch uint = 0 22 | 23 | // appPreRelease MUST only contain characters from semanticAlphabet 24 | // per the semantic versioning spec. 25 | appPreRelease = "beta" 26 | ) 27 | 28 | // appBuild is defined as a variable so it can be overridden during the build 29 | // process with '-ldflags "-X main.appBuild foo' if needed. It MUST only 30 | // contain characters from semanticAlphabet per the semantic versioning spec. 31 | var appBuild string 32 | 33 | // version returns the application version as a properly formed string per the 34 | // semantic versioning 2.0.0 spec (http://semver.org/). 35 | func version() string { 36 | // Start with the major, minor, and patch versions. 37 | version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch) 38 | 39 | // Append pre-release version if there is one. The hyphen called for 40 | // by the semantic versioning spec is automatically appended and should 41 | // not be contained in the pre-release string. The pre-release version 42 | // is not appended if it contains invalid characters. 43 | preRelease := normalizeVerString(appPreRelease) 44 | if preRelease != "" { 45 | version = fmt.Sprintf("%s-%s", version, preRelease) 46 | } 47 | 48 | // Append build metadata if there is any. The plus called for 49 | // by the semantic versioning spec is automatically appended and should 50 | // not be contained in the build metadata string. The build metadata 51 | // string is not appended if it contains invalid characters. 52 | build := normalizeVerString(appBuild) 53 | if build != "" { 54 | version = fmt.Sprintf("%s+%s", version, build) 55 | } 56 | 57 | return version 58 | } 59 | 60 | // normalizeVerString returns the passed string stripped of all characters which 61 | // are not valid according to the semantic versioning guidelines for pre-release 62 | // version and build metadata strings. In particular they MUST only contain 63 | // characters in semanticAlphabet. 64 | func normalizeVerString(str string) string { 65 | var result bytes.Buffer 66 | for _, r := range str { 67 | if strings.ContainsRune(semanticAlphabet, r) { 68 | result.WriteRune(r) 69 | } 70 | } 71 | return result.String() 72 | } 73 | -------------------------------------------------------------------------------- /wire/error.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "fmt" 9 | ) 10 | 11 | // MessageError describes an issue with a message. 12 | // An example of some potential issues are messages from the wrong bitcoin 13 | // network, invalid commands, mismatched checksums, and exceeding max payloads. 14 | // 15 | // This provides a mechanism for the caller to type assert the error to 16 | // differentiate between general io errors such as io.EOF and issues that 17 | // resulted from malformed messages. 18 | type MessageError struct { 19 | Func string // Function name 20 | Description string // Human readable description of the issue 21 | } 22 | 23 | // Error satisfies the error interface and prints human-readable errors. 24 | func (e *MessageError) Error() string { 25 | if e.Func != "" { 26 | return fmt.Sprintf("%v: %v", e.Func, e.Description) 27 | } 28 | return e.Description 29 | } 30 | 31 | // messageError creates an error for the given function and description. 32 | func messageError(f string, desc string) *MessageError { 33 | return &MessageError{Func: f, Description: desc} 34 | } 35 | -------------------------------------------------------------------------------- /wire/fakemessage_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import "io" 8 | 9 | // fakeMessage implements the Message interface and is used to force encode 10 | // errors in messages. 11 | type fakeMessage struct { 12 | command string 13 | payload []byte 14 | forceEncodeErr bool 15 | forceLenErr bool 16 | } 17 | 18 | // BtcDecode doesn't do anything. It just satisfies the wire.Message 19 | // interface. 20 | func (msg *fakeMessage) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 21 | return nil 22 | } 23 | 24 | // BtcEncode writes the payload field of the fake message or forces an error 25 | // if the forceEncodeErr flag of the fake message is set. It also satisfies the 26 | // wire.Message interface. 27 | func (msg *fakeMessage) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 28 | if msg.forceEncodeErr { 29 | err := &MessageError{ 30 | Func: "fakeMessage.BtcEncode", 31 | Description: "intentional error", 32 | } 33 | return err 34 | } 35 | 36 | _, err := w.Write(msg.payload) 37 | return err 38 | } 39 | 40 | // Command returns the command field of the fake message and satisfies the 41 | // Message interface. 42 | func (msg *fakeMessage) Command() string { 43 | return msg.command 44 | } 45 | 46 | // MaxPayloadLength returns the length of the payload field of fake message 47 | // or a smaller value if the forceLenErr flag of the fake message is set. It 48 | // satisfies the Message interface. 49 | func (msg *fakeMessage) MaxPayloadLength(pver uint32) uint32 { 50 | lenp := uint32(len(msg.payload)) 51 | if msg.forceLenErr { 52 | return lenp - 1 53 | } 54 | 55 | return lenp 56 | } 57 | -------------------------------------------------------------------------------- /wire/fixedIO_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "bytes" 9 | "io" 10 | ) 11 | 12 | // fixedWriter implements the io.Writer interface and intentially allows 13 | // testing of error paths by forcing short writes. 14 | type fixedWriter struct { 15 | b []byte 16 | pos int 17 | } 18 | 19 | // Write writes the contents of p to w. When the contents of p would cause 20 | // the writer to exceed the maximum allowed size of the fixed writer, 21 | // io.ErrShortWrite is returned and the writer is left unchanged. 22 | // 23 | // This satisfies the io.Writer interface. 24 | func (w *fixedWriter) Write(p []byte) (n int, err error) { 25 | lenp := len(p) 26 | if w.pos+lenp > cap(w.b) { 27 | return 0, io.ErrShortWrite 28 | } 29 | n = lenp 30 | w.pos += copy(w.b[w.pos:], p) 31 | return 32 | } 33 | 34 | // Bytes returns the bytes already written to the fixed writer. 35 | func (w *fixedWriter) Bytes() []byte { 36 | return w.b 37 | } 38 | 39 | // newFixedWriter returns a new io.Writer that will error once more bytes than 40 | // the specified max have been written. 41 | func newFixedWriter(max int) io.Writer { 42 | b := make([]byte, max) 43 | fw := fixedWriter{b, 0} 44 | return &fw 45 | } 46 | 47 | // fixedReader implements the io.Reader interface and intentially allows 48 | // testing of error paths by forcing short reads. 49 | type fixedReader struct { 50 | buf []byte 51 | pos int 52 | iobuf *bytes.Buffer 53 | } 54 | 55 | // Read reads the next len(p) bytes from the fixed reader. When the number of 56 | // bytes read would exceed the maximum number of allowed bytes to be read from 57 | // the fixed writer, an error is returned. 58 | // 59 | // This satisfies the io.Reader interface. 60 | func (fr *fixedReader) Read(p []byte) (n int, err error) { 61 | n, err = fr.iobuf.Read(p) 62 | fr.pos += n 63 | return 64 | } 65 | 66 | // newFixedReader returns a new io.Reader that will error once more bytes than 67 | // the specified max have been read. 68 | func newFixedReader(max int, buf []byte) io.Reader { 69 | b := make([]byte, max) 70 | if buf != nil { 71 | copy(b[:], buf) 72 | } 73 | 74 | iobuf := bytes.NewBuffer(b) 75 | fr := fixedReader{b, 0, iobuf} 76 | return &fr 77 | } 78 | -------------------------------------------------------------------------------- /wire/invvect.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | 11 | "github.com/ltcsuite/ltcd/chaincfg/chainhash" 12 | ) 13 | 14 | const ( 15 | // MaxInvPerMsg is the maximum number of inventory vectors that can be in a 16 | // single bitcoin inv message. 17 | MaxInvPerMsg = 50000 18 | 19 | // Maximum payload size for an inventory vector. 20 | maxInvVectPayload = 4 + chainhash.HashSize 21 | 22 | // InvWitnessFlag denotes that the inventory vector type is requesting, 23 | // or sending a version which includes witness data. 24 | InvWitnessFlag = 1 << 30 25 | ) 26 | 27 | // InvType represents the allowed types of inventory vectors. See InvVect. 28 | type InvType uint32 29 | 30 | // These constants define the various supported inventory vector types. 31 | const ( 32 | InvTypeError InvType = 0 33 | InvTypeTx InvType = 1 34 | InvTypeBlock InvType = 2 35 | InvTypeFilteredBlock InvType = 3 36 | InvTypeWitnessBlock InvType = InvTypeBlock | InvWitnessFlag 37 | InvTypeWitnessTx InvType = InvTypeTx | InvWitnessFlag 38 | InvTypeFilteredWitnessBlock InvType = InvTypeFilteredBlock | InvWitnessFlag 39 | ) 40 | 41 | // Map of service flags back to their constant names for pretty printing. 42 | var ivStrings = map[InvType]string{ 43 | InvTypeError: "ERROR", 44 | InvTypeTx: "MSG_TX", 45 | InvTypeBlock: "MSG_BLOCK", 46 | InvTypeFilteredBlock: "MSG_FILTERED_BLOCK", 47 | InvTypeWitnessBlock: "MSG_WITNESS_BLOCK", 48 | InvTypeWitnessTx: "MSG_WITNESS_TX", 49 | InvTypeFilteredWitnessBlock: "MSG_FILTERED_WITNESS_BLOCK", 50 | } 51 | 52 | // String returns the InvType in human-readable form. 53 | func (invtype InvType) String() string { 54 | if s, ok := ivStrings[invtype]; ok { 55 | return s 56 | } 57 | 58 | return fmt.Sprintf("Unknown InvType (%d)", uint32(invtype)) 59 | } 60 | 61 | // InvVect defines a bitcoin inventory vector which is used to describe data, 62 | // as specified by the Type field, that a peer wants, has, or does not have to 63 | // another peer. 64 | type InvVect struct { 65 | Type InvType // Type of data 66 | Hash chainhash.Hash // Hash of the data 67 | } 68 | 69 | // NewInvVect returns a new InvVect using the provided type and hash. 70 | func NewInvVect(typ InvType, hash *chainhash.Hash) *InvVect { 71 | return &InvVect{ 72 | Type: typ, 73 | Hash: *hash, 74 | } 75 | } 76 | 77 | // readInvVect reads an encoded InvVect from r depending on the protocol 78 | // version. 79 | func readInvVect(r io.Reader, pver uint32, iv *InvVect) error { 80 | return readElements(r, &iv.Type, &iv.Hash) 81 | } 82 | 83 | // writeInvVect serializes an InvVect to w depending on the protocol version. 84 | func writeInvVect(w io.Writer, pver uint32, iv *InvVect) error { 85 | return writeElements(w, iv.Type, &iv.Hash) 86 | } 87 | -------------------------------------------------------------------------------- /wire/msgfeefilter.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | ) 11 | 12 | // MsgFeeFilter implements the Message interface and represents a bitcoin 13 | // feefilter message. It is used to request the receiving peer does not 14 | // announce any transactions below the specified minimum fee rate. 15 | // 16 | // This message was not added until protocol versions starting with 17 | // FeeFilterVersion. 18 | type MsgFeeFilter struct { 19 | MinFee int64 20 | } 21 | 22 | // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 23 | // This is part of the Message interface implementation. 24 | func (msg *MsgFeeFilter) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 25 | if pver < FeeFilterVersion { 26 | str := fmt.Sprintf("feefilter message invalid for protocol "+ 27 | "version %d", pver) 28 | return messageError("MsgFeeFilter.BtcDecode", str) 29 | } 30 | 31 | return readElement(r, &msg.MinFee) 32 | } 33 | 34 | // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 35 | // This is part of the Message interface implementation. 36 | func (msg *MsgFeeFilter) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 37 | if pver < FeeFilterVersion { 38 | str := fmt.Sprintf("feefilter message invalid for protocol "+ 39 | "version %d", pver) 40 | return messageError("MsgFeeFilter.BtcEncode", str) 41 | } 42 | 43 | return writeElement(w, msg.MinFee) 44 | } 45 | 46 | // Command returns the protocol command string for the message. This is part 47 | // of the Message interface implementation. 48 | func (msg *MsgFeeFilter) Command() string { 49 | return CmdFeeFilter 50 | } 51 | 52 | // MaxPayloadLength returns the maximum length the payload can be for the 53 | // receiver. This is part of the Message interface implementation. 54 | func (msg *MsgFeeFilter) MaxPayloadLength(pver uint32) uint32 { 55 | return 8 56 | } 57 | 58 | // NewMsgFeeFilter returns a new bitcoin feefilter message that conforms to 59 | // the Message interface. See MsgFeeFilter for details. 60 | func NewMsgFeeFilter(minfee int64) *MsgFeeFilter { 61 | return &MsgFeeFilter{ 62 | MinFee: minfee, 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /wire/msgfilteradd.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | ) 11 | 12 | const ( 13 | // MaxFilterAddDataSize is the maximum byte size of a data 14 | // element to add to the Bloom filter. It is equal to the 15 | // maximum element size of a script. 16 | MaxFilterAddDataSize = 520 17 | ) 18 | 19 | // MsgFilterAdd implements the Message interface and represents a bitcoin 20 | // filteradd message. It is used to add a data element to an existing Bloom 21 | // filter. 22 | // 23 | // This message was not added until protocol version BIP0037Version. 24 | type MsgFilterAdd struct { 25 | Data []byte 26 | } 27 | 28 | // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 29 | // This is part of the Message interface implementation. 30 | func (msg *MsgFilterAdd) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 31 | if pver < BIP0037Version { 32 | str := fmt.Sprintf("filteradd message invalid for protocol "+ 33 | "version %d", pver) 34 | return messageError("MsgFilterAdd.BtcDecode", str) 35 | } 36 | 37 | var err error 38 | msg.Data, err = ReadVarBytes(r, pver, MaxFilterAddDataSize, 39 | "filteradd data") 40 | return err 41 | } 42 | 43 | // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 44 | // This is part of the Message interface implementation. 45 | func (msg *MsgFilterAdd) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 46 | if pver < BIP0037Version { 47 | str := fmt.Sprintf("filteradd message invalid for protocol "+ 48 | "version %d", pver) 49 | return messageError("MsgFilterAdd.BtcEncode", str) 50 | } 51 | 52 | size := len(msg.Data) 53 | if size > MaxFilterAddDataSize { 54 | str := fmt.Sprintf("filteradd size too large for message "+ 55 | "[size %v, max %v]", size, MaxFilterAddDataSize) 56 | return messageError("MsgFilterAdd.BtcEncode", str) 57 | } 58 | 59 | return WriteVarBytes(w, pver, msg.Data) 60 | } 61 | 62 | // Command returns the protocol command string for the message. This is part 63 | // of the Message interface implementation. 64 | func (msg *MsgFilterAdd) Command() string { 65 | return CmdFilterAdd 66 | } 67 | 68 | // MaxPayloadLength returns the maximum length the payload can be for the 69 | // receiver. This is part of the Message interface implementation. 70 | func (msg *MsgFilterAdd) MaxPayloadLength(pver uint32) uint32 { 71 | return uint32(VarIntSerializeSize(MaxFilterAddDataSize)) + 72 | MaxFilterAddDataSize 73 | } 74 | 75 | // NewMsgFilterAdd returns a new bitcoin filteradd message that conforms to the 76 | // Message interface. See MsgFilterAdd for details. 77 | func NewMsgFilterAdd(data []byte) *MsgFilterAdd { 78 | return &MsgFilterAdd{ 79 | Data: data, 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /wire/msgfilterclear.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | ) 11 | 12 | // MsgFilterClear implements the Message interface and represents a bitcoin 13 | // filterclear message which is used to reset a Bloom filter. 14 | // 15 | // This message was not added until protocol version BIP0037Version and has 16 | // no payload. 17 | type MsgFilterClear struct{} 18 | 19 | // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 20 | // This is part of the Message interface implementation. 21 | func (msg *MsgFilterClear) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 22 | if pver < BIP0037Version { 23 | str := fmt.Sprintf("filterclear message invalid for protocol "+ 24 | "version %d", pver) 25 | return messageError("MsgFilterClear.BtcDecode", str) 26 | } 27 | 28 | return nil 29 | } 30 | 31 | // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 32 | // This is part of the Message interface implementation. 33 | func (msg *MsgFilterClear) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 34 | if pver < BIP0037Version { 35 | str := fmt.Sprintf("filterclear message invalid for protocol "+ 36 | "version %d", pver) 37 | return messageError("MsgFilterClear.BtcEncode", str) 38 | } 39 | 40 | return nil 41 | } 42 | 43 | // Command returns the protocol command string for the message. This is part 44 | // of the Message interface implementation. 45 | func (msg *MsgFilterClear) Command() string { 46 | return CmdFilterClear 47 | } 48 | 49 | // MaxPayloadLength returns the maximum length the payload can be for the 50 | // receiver. This is part of the Message interface implementation. 51 | func (msg *MsgFilterClear) MaxPayloadLength(pver uint32) uint32 { 52 | return 0 53 | } 54 | 55 | // NewMsgFilterClear returns a new bitcoin filterclear message that conforms to the Message 56 | // interface. See MsgFilterClear for details. 57 | func NewMsgFilterClear() *MsgFilterClear { 58 | return &MsgFilterClear{} 59 | } 60 | -------------------------------------------------------------------------------- /wire/msggetaddr.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "io" 9 | ) 10 | 11 | // MsgGetAddr implements the Message interface and represents a bitcoin 12 | // getaddr message. It is used to request a list of known active peers on the 13 | // network from a peer to help identify potential nodes. The list is returned 14 | // via one or more addr messages (MsgAddr). 15 | // 16 | // This message has no payload. 17 | type MsgGetAddr struct{} 18 | 19 | // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 20 | // This is part of the Message interface implementation. 21 | func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 22 | return nil 23 | } 24 | 25 | // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 26 | // This is part of the Message interface implementation. 27 | func (msg *MsgGetAddr) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 28 | return nil 29 | } 30 | 31 | // Command returns the protocol command string for the message. This is part 32 | // of the Message interface implementation. 33 | func (msg *MsgGetAddr) Command() string { 34 | return CmdGetAddr 35 | } 36 | 37 | // MaxPayloadLength returns the maximum length the payload can be for the 38 | // receiver. This is part of the Message interface implementation. 39 | func (msg *MsgGetAddr) MaxPayloadLength(pver uint32) uint32 { 40 | return 0 41 | } 42 | 43 | // NewMsgGetAddr returns a new bitcoin getaddr message that conforms to the 44 | // Message interface. See MsgGetAddr for details. 45 | func NewMsgGetAddr() *MsgGetAddr { 46 | return &MsgGetAddr{} 47 | } 48 | -------------------------------------------------------------------------------- /wire/msggetcfilter.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "io" 9 | 10 | "github.com/ltcsuite/ltcd/chaincfg/chainhash" 11 | ) 12 | 13 | type MsgGetCFilter struct { 14 | BlockHash chainhash.Hash 15 | Extended bool 16 | } 17 | 18 | func (msg *MsgGetCFilter) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error { 19 | err := readElement(r, &msg.BlockHash) 20 | if err != nil { 21 | return err 22 | } 23 | return readElement(r, &msg.Extended) 24 | } 25 | 26 | // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 27 | // This is part of the Message interface implementation. 28 | func (msg *MsgGetCFilter) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error { 29 | err := writeElement(w, &msg.BlockHash) 30 | if err != nil { 31 | return err 32 | } 33 | return writeElement(w, msg.Extended) 34 | } 35 | 36 | // Command returns the protocol command string for the message. This is part 37 | // of the Message interface implementation. 38 | func (msg *MsgGetCFilter) Command() string { 39 | return CmdGetCFilter 40 | } 41 | 42 | // MaxPayloadLength returns the maximum length the payload can be for the 43 | // receiver. This is part of the Message interface implementation. 44 | func (msg *MsgGetCFilter) MaxPayloadLength(pver uint32) uint32 { 45 | // Block hash + Extended flag. 46 | return chainhash.HashSize + 1 47 | } 48 | 49 | // NewMsgGetCFilter returns a new bitcoin getcfilter message that conforms to 50 | // the Message interface using the passed parameters and defaults for the 51 | // remaining fields. 52 | func NewMsgGetCFilter(blockHash *chainhash.Hash, extended bool) *MsgGetCFilter { 53 | return &MsgGetCFilter{ 54 | BlockHash: *blockHash, 55 | Extended: extended, 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /wire/msgmempool.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | ) 11 | 12 | // MsgMemPool implements the Message interface and represents a bitcoin mempool 13 | // message. It is used to request a list of transactions still in the active 14 | // memory pool of a relay. 15 | // 16 | // This message has no payload and was not added until protocol versions 17 | // starting with BIP0035Version. 18 | type MsgMemPool struct{} 19 | 20 | // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 21 | // This is part of the Message interface implementation. 22 | func (msg *MsgMemPool) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 23 | if pver < BIP0035Version { 24 | str := fmt.Sprintf("mempool message invalid for protocol "+ 25 | "version %d", pver) 26 | return messageError("MsgMemPool.BtcDecode", str) 27 | } 28 | 29 | return nil 30 | } 31 | 32 | // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 33 | // This is part of the Message interface implementation. 34 | func (msg *MsgMemPool) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 35 | if pver < BIP0035Version { 36 | str := fmt.Sprintf("mempool message invalid for protocol "+ 37 | "version %d", pver) 38 | return messageError("MsgMemPool.BtcEncode", str) 39 | } 40 | 41 | return nil 42 | } 43 | 44 | // Command returns the protocol command string for the message. This is part 45 | // of the Message interface implementation. 46 | func (msg *MsgMemPool) Command() string { 47 | return CmdMemPool 48 | } 49 | 50 | // MaxPayloadLength returns the maximum length the payload can be for the 51 | // receiver. This is part of the Message interface implementation. 52 | func (msg *MsgMemPool) MaxPayloadLength(pver uint32) uint32 { 53 | return 0 54 | } 55 | 56 | // NewMsgMemPool returns a new bitcoin pong message that conforms to the Message 57 | // interface. See MsgPong for details. 58 | func NewMsgMemPool() *MsgMemPool { 59 | return &MsgMemPool{} 60 | } 61 | -------------------------------------------------------------------------------- /wire/msgmempool_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "bytes" 9 | "testing" 10 | ) 11 | 12 | func TestMemPool(t *testing.T) { 13 | pver := ProtocolVersion 14 | enc := BaseEncoding 15 | 16 | // Ensure the command is expected value. 17 | wantCmd := "mempool" 18 | msg := NewMsgMemPool() 19 | if cmd := msg.Command(); cmd != wantCmd { 20 | t.Errorf("NewMsgMemPool: wrong command - got %v want %v", 21 | cmd, wantCmd) 22 | } 23 | 24 | // Ensure max payload is expected value. 25 | wantPayload := uint32(0) 26 | maxPayload := msg.MaxPayloadLength(pver) 27 | if maxPayload != wantPayload { 28 | t.Errorf("MaxPayloadLength: wrong max payload length for "+ 29 | "protocol version %d - got %v, want %v", pver, 30 | maxPayload, wantPayload) 31 | } 32 | 33 | // Test encode with latest protocol version. 34 | var buf bytes.Buffer 35 | err := msg.BtcEncode(&buf, pver, enc) 36 | if err != nil { 37 | t.Errorf("encode of MsgMemPool failed %v err <%v>", msg, err) 38 | } 39 | 40 | // Older protocol versions should fail encode since message didn't 41 | // exist yet. 42 | oldPver := BIP0035Version - 1 43 | err = msg.BtcEncode(&buf, oldPver, enc) 44 | if err == nil { 45 | s := "encode of MsgMemPool passed for old protocol version %v err <%v>" 46 | t.Errorf(s, msg, err) 47 | } 48 | 49 | // Test decode with latest protocol version. 50 | readmsg := NewMsgMemPool() 51 | err = readmsg.BtcDecode(&buf, pver, enc) 52 | if err != nil { 53 | t.Errorf("decode of MsgMemPool failed [%v] err <%v>", buf, err) 54 | } 55 | 56 | // Older protocol versions should fail decode since message didn't 57 | // exist yet. 58 | err = readmsg.BtcDecode(&buf, oldPver, enc) 59 | if err == nil { 60 | s := "decode of MsgMemPool passed for old protocol version %v err <%v>" 61 | t.Errorf(s, msg, err) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /wire/msgping.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "io" 9 | ) 10 | 11 | // MsgPing implements the Message interface and represents a bitcoin ping 12 | // message. 13 | // 14 | // For versions BIP0031Version and earlier, it is used primarily to confirm 15 | // that a connection is still valid. A transmission error is typically 16 | // interpreted as a closed connection and that the peer should be removed. 17 | // For versions AFTER BIP0031Version it contains an identifier which can be 18 | // returned in the pong message to determine network timing. 19 | // 20 | // The payload for this message just consists of a nonce used for identifying 21 | // it later. 22 | type MsgPing struct { 23 | // Unique value associated with message that is used to identify 24 | // specific ping message. 25 | Nonce uint64 26 | } 27 | 28 | // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 29 | // This is part of the Message interface implementation. 30 | func (msg *MsgPing) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 31 | // There was no nonce for BIP0031Version and earlier. 32 | // NOTE: > is not a mistake here. The BIP0031 was defined as AFTER 33 | // the version unlike most others. 34 | if pver > BIP0031Version { 35 | err := readElement(r, &msg.Nonce) 36 | if err != nil { 37 | return err 38 | } 39 | } 40 | 41 | return nil 42 | } 43 | 44 | // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 45 | // This is part of the Message interface implementation. 46 | func (msg *MsgPing) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 47 | // There was no nonce for BIP0031Version and earlier. 48 | // NOTE: > is not a mistake here. The BIP0031 was defined as AFTER 49 | // the version unlike most others. 50 | if pver > BIP0031Version { 51 | err := writeElement(w, msg.Nonce) 52 | if err != nil { 53 | return err 54 | } 55 | } 56 | 57 | return nil 58 | } 59 | 60 | // Command returns the protocol command string for the message. This is part 61 | // of the Message interface implementation. 62 | func (msg *MsgPing) Command() string { 63 | return CmdPing 64 | } 65 | 66 | // MaxPayloadLength returns the maximum length the payload can be for the 67 | // receiver. This is part of the Message interface implementation. 68 | func (msg *MsgPing) MaxPayloadLength(pver uint32) uint32 { 69 | plen := uint32(0) 70 | // There was no nonce for BIP0031Version and earlier. 71 | // NOTE: > is not a mistake here. The BIP0031 was defined as AFTER 72 | // the version unlike most others. 73 | if pver > BIP0031Version { 74 | // Nonce 8 bytes. 75 | plen += 8 76 | } 77 | 78 | return plen 79 | } 80 | 81 | // NewMsgPing returns a new bitcoin ping message that conforms to the Message 82 | // interface. See MsgPing for details. 83 | func NewMsgPing(nonce uint64) *MsgPing { 84 | return &MsgPing{ 85 | Nonce: nonce, 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /wire/msgpong.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | ) 11 | 12 | // MsgPong implements the Message interface and represents a bitcoin pong 13 | // message which is used primarily to confirm that a connection is still valid 14 | // in response to a bitcoin ping message (MsgPing). 15 | // 16 | // This message was not added until protocol versions AFTER BIP0031Version. 17 | type MsgPong struct { 18 | // Unique value associated with message that is used to identify 19 | // specific ping message. 20 | Nonce uint64 21 | } 22 | 23 | // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 24 | // This is part of the Message interface implementation. 25 | func (msg *MsgPong) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 26 | // NOTE: <= is not a mistake here. The BIP0031 was defined as AFTER 27 | // the version unlike most others. 28 | if pver <= BIP0031Version { 29 | str := fmt.Sprintf("pong message invalid for protocol "+ 30 | "version %d", pver) 31 | return messageError("MsgPong.BtcDecode", str) 32 | } 33 | 34 | return readElement(r, &msg.Nonce) 35 | } 36 | 37 | // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 38 | // This is part of the Message interface implementation. 39 | func (msg *MsgPong) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 40 | // NOTE: <= is not a mistake here. The BIP0031 was defined as AFTER 41 | // the version unlike most others. 42 | if pver <= BIP0031Version { 43 | str := fmt.Sprintf("pong message invalid for protocol "+ 44 | "version %d", pver) 45 | return messageError("MsgPong.BtcEncode", str) 46 | } 47 | 48 | return writeElement(w, msg.Nonce) 49 | } 50 | 51 | // Command returns the protocol command string for the message. This is part 52 | // of the Message interface implementation. 53 | func (msg *MsgPong) Command() string { 54 | return CmdPong 55 | } 56 | 57 | // MaxPayloadLength returns the maximum length the payload can be for the 58 | // receiver. This is part of the Message interface implementation. 59 | func (msg *MsgPong) MaxPayloadLength(pver uint32) uint32 { 60 | plen := uint32(0) 61 | // The pong message did not exist for BIP0031Version and earlier. 62 | // NOTE: > is not a mistake here. The BIP0031 was defined as AFTER 63 | // the version unlike most others. 64 | if pver > BIP0031Version { 65 | // Nonce 8 bytes. 66 | plen += 8 67 | } 68 | 69 | return plen 70 | } 71 | 72 | // NewMsgPong returns a new bitcoin pong message that conforms to the Message 73 | // interface. See MsgPong for details. 74 | func NewMsgPong(nonce uint64) *MsgPong { 75 | return &MsgPong{ 76 | Nonce: nonce, 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /wire/msgsendheaders.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | ) 11 | 12 | // MsgSendHeaders implements the Message interface and represents a bitcoin 13 | // sendheaders message. It is used to request the peer send block headers 14 | // rather than inventory vectors. 15 | // 16 | // This message has no payload and was not added until protocol versions 17 | // starting with SendHeadersVersion. 18 | type MsgSendHeaders struct{} 19 | 20 | // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 21 | // This is part of the Message interface implementation. 22 | func (msg *MsgSendHeaders) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 23 | if pver < SendHeadersVersion { 24 | str := fmt.Sprintf("sendheaders message invalid for protocol "+ 25 | "version %d", pver) 26 | return messageError("MsgSendHeaders.BtcDecode", str) 27 | } 28 | 29 | return nil 30 | } 31 | 32 | // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 33 | // This is part of the Message interface implementation. 34 | func (msg *MsgSendHeaders) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 35 | if pver < SendHeadersVersion { 36 | str := fmt.Sprintf("sendheaders message invalid for protocol "+ 37 | "version %d", pver) 38 | return messageError("MsgSendHeaders.BtcEncode", str) 39 | } 40 | 41 | return nil 42 | } 43 | 44 | // Command returns the protocol command string for the message. This is part 45 | // of the Message interface implementation. 46 | func (msg *MsgSendHeaders) Command() string { 47 | return CmdSendHeaders 48 | } 49 | 50 | // MaxPayloadLength returns the maximum length the payload can be for the 51 | // receiver. This is part of the Message interface implementation. 52 | func (msg *MsgSendHeaders) MaxPayloadLength(pver uint32) uint32 { 53 | return 0 54 | } 55 | 56 | // NewMsgSendHeaders returns a new bitcoin sendheaders message that conforms to 57 | // the Message interface. See MsgSendHeaders for details. 58 | func NewMsgSendHeaders() *MsgSendHeaders { 59 | return &MsgSendHeaders{} 60 | } 61 | -------------------------------------------------------------------------------- /wire/msgverack.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import ( 8 | "io" 9 | ) 10 | 11 | // MsgVerAck defines a bitcoin verack message which is used for a peer to 12 | // acknowledge a version message (MsgVersion) after it has used the information 13 | // to negotiate parameters. It implements the Message interface. 14 | // 15 | // This message has no payload. 16 | type MsgVerAck struct{} 17 | 18 | // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 19 | // This is part of the Message interface implementation. 20 | func (msg *MsgVerAck) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 21 | return nil 22 | } 23 | 24 | // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 25 | // This is part of the Message interface implementation. 26 | func (msg *MsgVerAck) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 27 | return nil 28 | } 29 | 30 | // Command returns the protocol command string for the message. This is part 31 | // of the Message interface implementation. 32 | func (msg *MsgVerAck) Command() string { 33 | return CmdVerAck 34 | } 35 | 36 | // MaxPayloadLength returns the maximum length the payload can be for the 37 | // receiver. This is part of the Message interface implementation. 38 | func (msg *MsgVerAck) MaxPayloadLength(pver uint32) uint32 { 39 | return 0 40 | } 41 | 42 | // NewMsgVerAck returns a new bitcoin verack message that conforms to the 43 | // Message interface. 44 | func NewMsgVerAck() *MsgVerAck { 45 | return &MsgVerAck{} 46 | } 47 | -------------------------------------------------------------------------------- /wire/protocol_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Use of this source code is governed by an ISC 3 | // license that can be found in the LICENSE file. 4 | 5 | package wire 6 | 7 | import "testing" 8 | 9 | // TestServiceFlagStringer tests the stringized output for service flag types. 10 | func TestServiceFlagStringer(t *testing.T) { 11 | tests := []struct { 12 | in ServiceFlag 13 | want string 14 | }{ 15 | {0, "0x0"}, 16 | {SFNodeNetwork, "SFNodeNetwork"}, 17 | {SFNodeGetUTXO, "SFNodeGetUTXO"}, 18 | {SFNodeBloom, "SFNodeBloom"}, 19 | {SFNodeWitness, "SFNodeWitness"}, 20 | {SFNodeCF, "SFNodeCF"}, 21 | {0xffffffff, "SFNodeNetwork|SFNodeGetUTXO|SFNodeBloom|SFNodeWitness|SFNodeCF|0xffffffe0"}, 22 | } 23 | 24 | t.Logf("Running %d tests", len(tests)) 25 | for i, test := range tests { 26 | result := test.in.String() 27 | if result != test.want { 28 | t.Errorf("String #%d\n got: %s want: %s", i, result, 29 | test.want) 30 | continue 31 | } 32 | } 33 | } 34 | 35 | // TestBitcoinNetStringer tests the stringized output for bitcoin net types. 36 | func TestBitcoinNetStringer(t *testing.T) { 37 | tests := []struct { 38 | in BitcoinNet 39 | want string 40 | }{ 41 | {MainNet, "MainNet"}, 42 | {TestNet, "TestNet"}, 43 | {TestNet4, "TestNet4"}, 44 | {SimNet, "SimNet"}, 45 | {0xffffffff, "Unknown BitcoinNet (4294967295)"}, 46 | } 47 | 48 | t.Logf("Running %d tests", len(tests)) 49 | for i, test := range tests { 50 | result := test.in.String() 51 | if result != test.want { 52 | t.Errorf("String #%d\n got: %s want: %s", i, result, 53 | test.want) 54 | continue 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /wire/testdata/megatx.bin.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ltcsuite-archive/ltcd/01737289d815e0e32c91e55593ba2fbd8d090b2c/wire/testdata/megatx.bin.bz2 --------------------------------------------------------------------------------