├── .gitignore ├── CHANGELOG.md ├── 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 ├── autotx.py ├── blockchain ├── accept.go ├── bench_test.go ├── blocklocator.go ├── chain.go ├── chain_test.go ├── chaingen │ ├── doc.go │ ├── example_test.go │ └── generator.go ├── chainio.go ├── chainio_test.go ├── checkpoints.go ├── compress.go ├── compress_test.go ├── difficulty.go ├── difficulty_test.go ├── doc.go ├── error.go ├── error_test.go ├── example_test.go ├── fullblocks_test.go ├── fullblocksstakeversion_test.go ├── fullblocktests │ ├── generate.go │ └── params.go ├── indexers │ ├── addrindex.go │ ├── addrindex_test.go │ ├── common.go │ ├── existsaddrindex.go │ ├── log.go │ ├── manager.go │ └── txindex.go ├── internal │ ├── dbnamespace │ │ └── dbnamespace.go │ └── progresslog │ │ └── blocklogger.go ├── internal_test.go ├── log.go ├── mediantime.go ├── mediantime_test.go ├── merkle.go ├── merkle_test.go ├── notifications.go ├── process.go ├── prune.go ├── reorganization_test.go ├── scriptval.go ├── scriptval_test.go ├── sim_net_params.go ├── sim_net_utils.go ├── stake │ ├── doc.go │ ├── error.go │ ├── error_test.go │ ├── internal │ │ ├── dbnamespace │ │ │ └── dbnamespace.go │ │ ├── ticketdb │ │ │ ├── chainio.go │ │ │ ├── chainio_test.go │ │ │ ├── error.go │ │ │ └── error_test.go │ │ └── tickettreap │ │ │ ├── benchmark_test.go │ │ │ ├── common.go │ │ │ ├── common_test.go │ │ │ ├── doc.go │ │ │ ├── immutable.go │ │ │ ├── immutable_test.go │ │ │ ├── mutable.go │ │ │ └── mutable_test.go │ ├── log.go │ ├── lottery.go │ ├── lottery_test.go │ ├── staketx.go │ ├── staketx_test.go │ ├── tickets.go │ └── tickets_test.go ├── stakeext.go ├── stakenode.go ├── stakeversion.go ├── stakeversion_test.go ├── subsidy.go ├── subsidy_test.go ├── testdata │ ├── blocks0to168.bz2 │ ├── reorgto179.bz2 │ ├── reorgto180.bz2 │ └── testexpiry.bz2 ├── thresholdstate.go ├── thresholdstate_test.go ├── timesorter.go ├── timesorter_test.go ├── upgrade.go ├── utxoviewpoint.go ├── validate.go ├── validate_test.go ├── votebits.go └── votebits_test.go ├── blocklogger.go ├── blockmanager.go ├── chaincfg ├── chainec │ ├── chainec.go │ ├── doc.go │ ├── edwards.go │ ├── edwards_test.go │ ├── secp256k1.go │ ├── secp256k1_test.go │ └── secschnorr.go ├── chainhash │ ├── doc.go │ ├── hash.go │ ├── hash_test.go │ ├── hashfuncs.go │ └── hashfuncs_test.go ├── doc.go ├── genesis.go ├── genesis_test.go ├── init.go ├── init_test.go ├── internal_test.go ├── params.go ├── params_test.go ├── premine.go └── register_test.go ├── cmd ├── addblock │ ├── addblock.go │ ├── config.go │ └── import.go ├── checkdevpremine │ ├── config.go │ └── main.go ├── findcheckpoint │ ├── config.go │ └── findcheckpoint.go ├── gencerts │ └── gencerts.go ├── hcashctl │ ├── config.go │ ├── hcashctl.go │ ├── httpclient.go │ ├── sample-hcashctl.conf │ └── version.go └── promptsecret │ └── promptsecret.go ├── config.go ├── connmgr ├── connmanager.go ├── connmanager_test.go ├── doc.go ├── dynamicbanscore.go ├── dynamicbanscore_test.go ├── log.go ├── seed.go └── tor.go ├── cpuminer.go ├── crypto ├── bliss │ ├── bliss.go │ ├── bliss_test.go │ ├── dsa.go │ ├── privkey.go │ ├── privkey_test.go │ ├── pubkey.go │ ├── pubkey_test.go │ ├── signature.go │ └── signature_test.go ├── crypto.go ├── crypto_test.go └── lms │ ├── dsa.go │ ├── lms.go │ ├── lms_test.go │ ├── privkey.go │ ├── pubkey.go │ └── signature.go ├── database ├── 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 │ ├── 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 │ │ ├── common.go │ │ ├── common_test.go │ │ ├── doc.go │ │ ├── immutable.go │ │ ├── immutable_test.go │ │ ├── mutable.go │ │ ├── mutable_test.go │ │ ├── treapiter.go │ │ └── treapiter_test.go └── log.go ├── doc.go ├── docs ├── README.md ├── code_contribution_guidelines.md ├── configure_peer_server_listen_interfaces.md ├── configure_rpc_server_listen_interfaces.md ├── configuring_tor.md ├── crypto.md ├── default_ports.md ├── images │ ├── block.png │ └── research │ │ ├── probability-of-successful-attacks-under-alpha-hashing-power-and-beta-stake-rate.png │ │ └── the-schematic-framework-of-our-consensus-scheme.png ├── json_rpc_api.md ├── mining.md ├── post_quantum_api.md └── research │ ├── design-rationale-of-post-quantum-features-in-hcash.md │ ├── design-rationale-of-the-consensus-scheme-in-hcash.md │ └── post-quantum-signature-schemes-in-hcash.pdf ├── glide.lock ├── glide.yaml ├── hcashd.go ├── hcashec ├── edwards │ ├── ciphering.go │ ├── ciphering_test.go │ ├── const.go │ ├── curve.go │ ├── curve_test.go │ ├── ecdsa.go │ ├── ecdsa_benchmark_test.go │ ├── ecdsa_test.go │ ├── primitives.go │ ├── primitives_test.go │ ├── privkey.go │ ├── pubkey.go │ ├── signature.go │ ├── testdata │ │ ├── addpoints.py │ │ ├── decodeint.py │ │ ├── decodepoint.py │ │ ├── ed25519.py │ │ ├── encodeint.py │ │ ├── encodepoint.py │ │ ├── genscalarmult.py │ │ └── sign.input.gz │ ├── threshold.go │ ├── threshold_schnorr_test.go │ └── utils_for_test.go └── secp256k1 │ ├── 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 │ ├── schnorr │ ├── ecdsa.go │ ├── ecdsa_test.go │ ├── error.go │ ├── primitives.go │ ├── pubkey.go │ ├── signature.go │ ├── threshold.go │ └── threshold_test.go │ ├── secp256k1.go │ ├── signature.go │ └── signature_test.go ├── hcashjson ├── CONTRIBUTORS ├── btcdextcmds.go ├── btcdextcmds_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 ├── cmdinfo.go ├── cmdinfo_test.go ├── cmdparse.go ├── cmdparse_test.go ├── doc.go ├── error.go ├── error_test.go ├── example_test.go ├── export_test.go ├── hcashdcmds.go ├── hcashdcmds_test.go ├── hcashdresults.go ├── hcashwalletextcmds.go ├── hcashwalletextcmds_test.go ├── hcashwalletextresults.go ├── hcashwalletextwsntfns.go ├── hcashwalletextwsntfns_test.go ├── help.go ├── help_test.go ├── helpers.go ├── helpers_test.go ├── jsonerr.go ├── jsonrpc.go ├── jsonrpc_test.go ├── jsonrpcerr.go ├── parse.go ├── parse_test.go ├── register.go ├── register_test.go ├── walletsvrcmds.go ├── walletsvrcmds_test.go ├── walletsvrresults.go ├── walletsvrwscmds.go ├── walletsvrwscmds_test.go ├── walletsvrwsntfns.go └── walletsvrwsntfns_test.go ├── ipc.go ├── limits ├── limits_plan9.go ├── limits_unix.go └── limits_windows.go ├── log.go ├── mempool ├── error.go ├── log.go ├── mempool.go ├── mempool_test.go ├── policy.go └── policy_test.go ├── mining.go ├── mining ├── doc.go ├── mining.go └── policy.go ├── mining_test.go ├── miningerror.go ├── params.go ├── peer ├── 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 └── services │ ├── smf │ └── hcashd.xml │ └── systemd │ └── hcashd.service ├── rpcserver.go ├── rpcserver_test.go ├── rpcserverhelp.go ├── rpcserverhelp_test.go ├── rpctest ├── doc.go ├── memwallet.go ├── node.go ├── rpc_harness.go ├── rpc_harness_test.go └── utils.go ├── rpcwebsocket.go ├── run_tests.sh ├── sampleconfig ├── doc.go └── sampleconfig.go ├── server.go ├── service_windows.go ├── signal.go ├── signalsigterm.go ├── txscript ├── consensus.go ├── data │ ├── LICENSE │ ├── script_invalid.json │ ├── script_valid.json │ ├── tx_invalid.json │ └── tx_valid.json ├── doc.go ├── engine.go ├── engine_test.go ├── error.go ├── example_test.go ├── internal_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 ├── upnp.go ├── version.go └── wire ├── bench_test.go ├── blockheader.go ├── blockheader_test.go ├── common.go ├── common_test.go ├── doc.go ├── error.go ├── fakeconn_test.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 ├── 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 ├── msggetdata.go ├── msggetdata_test.go ├── msggetheaders.go ├── msggetheaders_test.go ├── msggetminingstate.go ├── msgheaders.go ├── msgheaders_test.go ├── msginv.go ├── msginv_test.go ├── msgmempool.go ├── msgmempool_test.go ├── msgmerkleblock.go ├── msgmerkleblock_test.go ├── msgminingstate.go ├── msgminingstate_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 /.gitignore: -------------------------------------------------------------------------------- 1 | # Temp files 2 | *~ 3 | 4 | # Log files 5 | *.log 6 | 7 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 8 | *.o 9 | *.a 10 | *.so 11 | 12 | # Folders 13 | _obj 14 | _test 15 | 16 | _testmain.go 17 | 18 | *.exe 19 | 20 | .travis.yml 21 | vendor 22 | .idea 23 | .vscode 24 | debug 25 | .metadata 26 | *.pyc 27 | 28 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Hcash Daemon 2 | 3 | ## [2017-11-13] 4 | + **Updated** 5 | - done all tests cases under package `hcashec/edward` 6 | 7 | ## [2017-11-10] 8 | + **Updated** 9 | - test cases under package `hcashec/edward` 10 | 11 | ## [2017-10-25] 12 | + **Fixed** 13 | - all test cases under package `blockchain` 14 | 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2013-2016 The btcsuite developers 4 | Copyright (c) 2015-2016 The Decred developers 5 | Copyright (c) 2017 The Hcash developers 6 | 7 | Permission to use, copy, modify, and distribute this software for any 8 | purpose with or without fee is hereby granted, provided that the above 9 | copyright notice and this permission notice appear in all copies. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 | -------------------------------------------------------------------------------- /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 | // 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 | /* 7 | Package addrmgr implements concurrency safe Hypercash address manager. 8 | 9 | Address Manager Overview 10 | 11 | In order maintain the peer-to-peer Hypercash network, there needs to be a source 12 | of addresses to connect to as nodes come and go. The Hypercash protocol provides 13 | a the getaddr and addr messages to allow peers to communicate known addresses 14 | with each other. However, there needs to a mechanism to store those results and 15 | select peers from them. It is also important to note that remote peers can't 16 | be trusted to send valid peers nor attempt to provide you with only peers they 17 | control with malicious intent. 18 | 19 | With that in mind, this package provides a concurrency safe address manager for 20 | caching and selecting peers in a non-determinstic manner. The general idea is 21 | the caller adds addresses to the address manager and notifies it when addresses 22 | are connected, known good, and attempted. The caller also requests addresses as 23 | it needs them. 24 | 25 | The address manager internally segregates the addresses into groups and 26 | non-deterministically selects groups in a cryptographically random manner. This 27 | reduce the chances multiple addresses from the same nets are selected which 28 | generally helps provide greater peer diversity, and perhaps more importantly, 29 | drastically reduces the chances an attacker is able to coerce your peer into 30 | only connecting to nodes they control. 31 | 32 | The address manager also understands routability and tor addresses and tries 33 | hard to only return routable addresses. In addition, it uses the information 34 | provided by the caller about connected, known good, and attempted addresses to 35 | periodically purge peers which no longer appear to be good peers as well as 36 | bias the selection toward known good peers. The general idea is to make a best 37 | effort at only providing usuable addresses. 38 | */ 39 | package addrmgr 40 | -------------------------------------------------------------------------------- /addrmgr/internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 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 addrmgr 7 | 8 | import ( 9 | "time" 10 | 11 | "github.com/HcashOrg/hcashd/wire" 12 | ) 13 | 14 | func TstKnownAddressIsBad(ka *KnownAddress) bool { 15 | return ka.isBad() 16 | } 17 | 18 | func TstKnownAddressChance(ka *KnownAddress) float64 { 19 | return ka.chance() 20 | } 21 | 22 | func TstNewKnownAddress(na *wire.NetAddress, attempts int, 23 | lastattempt, lastsuccess time.Time, tried bool, refs int) *KnownAddress { 24 | return &KnownAddress{na: na, attempts: attempts, lastattempt: lastattempt, 25 | lastsuccess: lastsuccess, tried: tried, refs: refs} 26 | } 27 | -------------------------------------------------------------------------------- /addrmgr/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 addrmgr 7 | 8 | import ( 9 | "github.com/btcsuite/btclog" 10 | ) 11 | 12 | // log is a logger that is initialized with no output filters. This 13 | // means the package will not perform any logging by default until the caller 14 | // requests it. 15 | var log btclog.Logger 16 | 17 | // The default amount of logging is none. 18 | func init() { 19 | DisableLog() 20 | } 21 | 22 | // DisableLog disables all library log output. Logging output is disabled 23 | // by default until either UseLogger or SetLogWriter are called. 24 | func DisableLog() { 25 | log = btclog.Disabled 26 | } 27 | 28 | // UseLogger uses a specified Logger to output package logging info. 29 | // This should be used in preference to SetLogWriter if the caller is also 30 | // using btclog. 31 | func UseLogger(logger btclog.Logger) { 32 | log = logger 33 | } 34 | -------------------------------------------------------------------------------- /autotx.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import sys 4 | import random 5 | import time 6 | 7 | 8 | count = 1000 9 | #account = "postquantum" 10 | if len(sys.argv) > 1: 11 | count = int(sys.argv[1]) 12 | 13 | def formatJson(json): 14 | json = json.replace("\n", "") 15 | return json 16 | 17 | def unlock(password): 18 | s = os.popen("hcashctl --wallet walletpassphrase " + password + " 0").read() 19 | 20 | def getbalance(): 21 | s = os.popen("hcashctl --wallet getbalance").read() 22 | balances = json.loads(formatJson(s)) 23 | for balance in balances["balances"]: 24 | if balance["accountname"] == account: 25 | return balance["spendable"] 26 | 27 | def tx(index, address, addrSize, amount, minconf): 28 | r = random.randint(0, addrSize - 1) 29 | #balance = getbalance() 30 | addr = address[r] 31 | 32 | amount = random.uniform(0, amount) + 0.1 33 | #if balance >= amount : 34 | #os.popen("hcashctl --wallet sendtoaddress " + addr + " " + str(amount)).read() 35 | p = os.system("hcashctl --wallet sendfrom " + account + " " + addr + " " + str(amount) + " 0 " + str(minconf)) 36 | 37 | print("[" + str(index) + "] send to " + addr + " amount: " + str(amount)) 38 | 39 | return p 40 | 41 | 42 | filename = "autotx.conf" 43 | 44 | file = open(filename, "r") 45 | 46 | s = formatJson(file.read()) 47 | 48 | conf = json.loads(s) 49 | 50 | password = conf["password"] 51 | address = conf["address"] 52 | txAmount = conf["maxtxamount"] 53 | minconf = conf["minconf"] 54 | account = conf["account"] 55 | 56 | addrSize = len(address) 57 | 58 | balance = getbalance() 59 | 60 | if txAmount <= 0: 61 | txAmount = balance / 1000 62 | 63 | unlock(password) 64 | print("unlocked") 65 | 66 | print("Tx count: " + str(count)) 67 | 68 | # for i in range(1,int(count)): 69 | # p = tx(i, address, addrSize, txAmount, minconf) 70 | # if p != 0: 71 | # break 72 | 73 | if count == 0: 74 | count = -1 75 | 76 | i = 0 77 | 78 | startTime = time.time() 79 | 80 | while i != count: 81 | p = tx(i, address, addrSize, txAmount, minconf) 82 | 83 | # if p != 0: 84 | # break 85 | 86 | i = i + 1 87 | 88 | #if balance == 0: 89 | # print("No spendable money in your wallet.") 90 | # break 91 | endTime = time.time() 92 | 93 | t = endTime - startTime 94 | txPerSec = i / t 95 | print("Time elapsed %.2fs" % t) 96 | print("Send %.2f tx per second" % txPerSec) 97 | -------------------------------------------------------------------------------- /blockchain/bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 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 blockchain_test 7 | 8 | // TODO Make benchmarking tests for various functions, such as sidechain 9 | // evaluation. 10 | -------------------------------------------------------------------------------- /blockchain/chaingen/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 The Decred 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 chaingen provides facilities for generating a full chain of blocks. 7 | 8 | Overview 9 | 10 | Many consensus-related tests require a full chain of valid blocks with several 11 | pieces of contextual information such as versions and votes. Generating such a 12 | chain is not a trivial task due to things such as the fact that tickets must be 13 | purchased (at the correct ticket price), the appropriate winning votes must be 14 | cast (which implies keeping track of all live tickets and implementing the 15 | lottery selection algorithm), and all of the state-specific header fields such 16 | as the pool size and the proof-of-work and proof-of-stake difficulties must be 17 | set properly. 18 | 19 | In order to simplify this complex process, this package provides a generator 20 | that keeps track of all of the necessary state and generates and solves blocks 21 | accordingly while allowing the caller to manipulate the blocks via munge 22 | functions. 23 | */ 24 | package chaingen 25 | -------------------------------------------------------------------------------- /blockchain/chaingen/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 The Decred 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 chaingen_test 6 | 7 | import ( 8 | "fmt" 9 | 10 | "github.com/HcashOrg/hcashd/blockchain/chaingen" 11 | "github.com/HcashOrg/hcashd/chaincfg" 12 | ) 13 | 14 | // This example demonstrates creating a new generator instance and using it to 15 | // generate the required premine block and enough blocks to have mature coinbase 16 | // outputs to work with along with asserting the generator state along the way. 17 | func Example_basicUsage() { 18 | params := &chaincfg.SimNetParams 19 | g, err := chaingen.MakeGenerator(params) 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } 24 | 25 | // Shorter versions of useful params for convenience. 26 | coinbaseMaturity := params.CoinbaseMaturity 27 | 28 | // --------------------------------------------------------------------- 29 | // Premine. 30 | // --------------------------------------------------------------------- 31 | 32 | // Add the required premine block. 33 | // 34 | // genesis -> bp 35 | g.CreatePremineBlock("bp", 0) 36 | g.AssertTipHeight(1) 37 | fmt.Println(g.TipName()) 38 | 39 | // --------------------------------------------------------------------- 40 | // Generate enough blocks to have mature coinbase outputs to work with. 41 | // 42 | // genesis -> bp -> bm0 -> bm1 -> ... -> bm# 43 | // --------------------------------------------------------------------- 44 | 45 | for i := uint16(0); i < coinbaseMaturity; i++ { 46 | blockName := fmt.Sprintf("bm%d", i) 47 | g.NextBlock(blockName, nil, nil) 48 | g.SaveTipCoinbaseOuts() 49 | fmt.Println(g.TipName()) 50 | } 51 | g.AssertTipHeight(uint32(coinbaseMaturity) + 1) 52 | 53 | // Output: 54 | // bp 55 | // bm0 56 | // bm1 57 | // bm2 58 | // bm3 59 | // bm4 60 | // bm5 61 | // bm6 62 | // bm7 63 | // bm8 64 | // bm9 65 | // bm10 66 | // bm11 67 | // bm12 68 | // bm13 69 | // bm14 70 | // bm15 71 | } 72 | -------------------------------------------------------------------------------- /blockchain/indexers/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Copyright (c) 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 indexers 7 | 8 | import "github.com/btcsuite/btclog" 9 | 10 | // log is a logger that is initialized with no output filters. This 11 | // means the package will not perform any logging by default until the caller 12 | // requests it. 13 | var log btclog.Logger 14 | 15 | // The default amount of logging is none. 16 | func init() { 17 | DisableLog() 18 | } 19 | 20 | // DisableLog disables all library log output. Logging output is disabled 21 | // by default until either UseLogger or SetLogWriter are called. 22 | func DisableLog() { 23 | log = btclog.Disabled 24 | } 25 | 26 | // UseLogger uses a specified Logger to output package logging info. 27 | // This should be used in preference to SetLogWriter if the caller is also 28 | // using btclog. 29 | func UseLogger(logger btclog.Logger) { 30 | log = logger 31 | } 32 | -------------------------------------------------------------------------------- /blockchain/internal/dbnamespace/dbnamespace.go: -------------------------------------------------------------------------------- 1 | // Package dbnamespace contains constants that define the database namespaces 2 | // for the purpose of the blockchain, so that external callers may easily access 3 | // this data. 4 | package dbnamespace 5 | 6 | import ( 7 | "encoding/binary" 8 | ) 9 | 10 | var ( 11 | // ByteOrder is the preferred byte order used for serializing numeric 12 | // fields for storage in the database. 13 | ByteOrder = binary.LittleEndian 14 | 15 | // BlockChainDbInfoBucketName is the name of the database bucket used to 16 | // house a single k->v that stores global versioning and date information for 17 | // the database. 18 | BlockChainDbInfoBucketName = []byte("dbinfo") 19 | 20 | // HashIndexBucketName is the name of the db bucket used to house to the 21 | // block hash -> block height index. 22 | HashIndexBucketName = []byte("hashidx") 23 | 24 | // HeightIndexBucketName is the name of the db bucket used to house to 25 | // the block height -> block hash index. 26 | HeightIndexBucketName = []byte("heightidx") 27 | 28 | // ChainStateKeyName is the name of the db key used to store the best 29 | // chain state. 30 | ChainStateKeyName = []byte("chainstate") 31 | 32 | // SpendJournalBucketName is the name of the db bucket used to house 33 | // transactions outputs that are spent in each block. 34 | SpendJournalBucketName = []byte("spendjournal") 35 | 36 | // UtxoSetBucketName is the name of the db bucket used to house the 37 | // unspent transaction output set. 38 | UtxoSetBucketName = []byte("utxoset") 39 | ) 40 | -------------------------------------------------------------------------------- /blockchain/internal/progresslog/blocklogger.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Copyright (c) 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 progresslog 7 | 8 | import ( 9 | "sync" 10 | "time" 11 | 12 | "github.com/btcsuite/btclog" 13 | 14 | "github.com/HcashOrg/hcashd/wire" 15 | "github.com/HcashOrg/hcashutil" 16 | ) 17 | 18 | // BlockProgressLogger provides periodic logging for other services in order 19 | // to show users progress of certain "actions" involving some or all current 20 | // blocks. Ex: syncing to best chain, indexing all blocks, etc. 21 | type BlockProgressLogger struct { 22 | receivedLogBlocks int64 23 | receivedLogTx int64 24 | lastBlockLogTime time.Time 25 | 26 | subsystemLogger btclog.Logger 27 | progressAction string 28 | sync.Mutex 29 | } 30 | 31 | // NewBlockProgressLogger returns a new block progress logger. 32 | // The progress message is templated as follows: 33 | // {progressAction} {numProcessed} {blocks|block} in the last {timePeriod} 34 | // ({numTxs}, height {lastBlockHeight}, {lastBlockTimeStamp}) 35 | func NewBlockProgressLogger(progressMessage string, logger btclog.Logger) *BlockProgressLogger { 36 | return &BlockProgressLogger{ 37 | lastBlockLogTime: time.Now(), 38 | progressAction: progressMessage, 39 | subsystemLogger: logger, 40 | } 41 | } 42 | 43 | // LogBlockHeight logs a new block height as an information message to show 44 | // progress to the user. In order to prevent spam, it limits logging to one 45 | // message every 10 seconds with duration and totals included. 46 | func (b *BlockProgressLogger) LogBlockHeight(block, parent *wire.MsgBlock) { 47 | b.Lock() 48 | defer b.Unlock() 49 | b.receivedLogBlocks++ 50 | regularTxTreeValid := hcashutil.IsFlagSet16(block.Header.VoteBits, 51 | hcashutil.BlockValid) 52 | if regularTxTreeValid { 53 | b.receivedLogTx += int64(len(parent.Transactions)) 54 | } 55 | b.receivedLogTx += int64(len(block.STransactions)) 56 | 57 | now := time.Now() 58 | duration := now.Sub(b.lastBlockLogTime) 59 | if duration < time.Second*10 { 60 | return 61 | } 62 | 63 | // Truncate the duration to 10s of milliseconds. 64 | durationMillis := int64(duration / time.Millisecond) 65 | tDuration := 10 * time.Millisecond * time.Duration(durationMillis/10) 66 | 67 | // Log information about new block height. 68 | blockStr := "blocks" 69 | if b.receivedLogBlocks == 1 { 70 | blockStr = "block" 71 | } 72 | txStr := "transactions" 73 | if b.receivedLogTx == 1 { 74 | txStr = "transaction" 75 | } 76 | b.subsystemLogger.Infof("%s %d %s in the last %s (%d %s, height %d, %s)", 77 | b.progressAction, b.receivedLogBlocks, blockStr, tDuration, 78 | b.receivedLogTx, txStr, block.Header.Height, 79 | block.Header.Timestamp) 80 | 81 | b.receivedLogBlocks = 0 82 | b.receivedLogTx = 0 83 | b.lastBlockLogTime = now 84 | } 85 | -------------------------------------------------------------------------------- /blockchain/internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 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 | /* 7 | This test file is part of the blockchain package rather than than the 8 | blockchain_test package so it can bridge access to the internals to properly 9 | test cases which are either not possible or can't reliably be tested via the 10 | public interface. The functions are only exported while the tests are being 11 | run. 12 | */ 13 | 14 | package blockchain 15 | 16 | /* 17 | // TstTimeSorter makes the internal timeSorter type available to the test 18 | // package. 19 | func TstTimeSorter(times []time.Time) sort.Interface { 20 | return timeSorter(times) 21 | } 22 | 23 | // TstSetMaxMedianTimeEntries makes the ability to set the maximum number of 24 | // median time entries available to the test package. 25 | func TstSetMaxMedianTimeEntries(val int) { 26 | maxMedianTimeEntries = val 27 | } 28 | 29 | // TstCheckBlockScripts makes the internal checkBlockScripts function available 30 | // to the test package. 31 | var TstCheckBlockScripts = checkBlockScripts 32 | 33 | // TstDeserializeUtxoEntry makes the internal deserializeUtxoEntry function 34 | // available to the test package. 35 | var TstDeserializeUtxoEntry = deserializeUtxoEntry 36 | 37 | // TstCheckBlockHeaderContext makes the internal checkBlockHeaderContext 38 | // function available to the test package. 39 | func (b *BlockChain) TstCheckBlockHeaderContext(header *wire.BlockHeader, prevNode *blockNode, flags BehaviorFlags) error { 40 | return b.checkBlockHeaderContext(header, prevNode, flags) 41 | } 42 | 43 | // TstNewBlockNode makes the internal newBlockNode function available to the 44 | // test package. 45 | func TstNewBlockNode(blockHeader *wire.BlockHeader, ticketsSpent []chainhash.Hash, ticketsRevoked []chainhash.Hash, voteBits []VoteVersionTuple) *blockNode { 46 | return newBlockNode(blockHeader, ticketsSpent, ticketsRevoked, voteBits) 47 | } 48 | */ 49 | -------------------------------------------------------------------------------- /blockchain/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 blockchain 7 | 8 | import ( 9 | "github.com/btcsuite/btclog" 10 | ) 11 | 12 | // log is a logger that is initialized with no output filters. This 13 | // means the package will not perform any logging by default until the caller 14 | // requests it. 15 | var log btclog.Logger 16 | 17 | // The default amount of logging is none. 18 | func init() { 19 | DisableLog() 20 | } 21 | 22 | // DisableLog disables all library log output. Logging output is disabled 23 | // by default until UseLogger is called. 24 | func DisableLog() { 25 | log = btclog.Disabled 26 | } 27 | 28 | // UseLogger uses a specified Logger to output package logging info. 29 | func UseLogger(logger btclog.Logger) { 30 | log = logger 31 | } 32 | -------------------------------------------------------------------------------- /blockchain/merkle_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 blockchain_test 7 | 8 | // TODO Make tests for merkle root calculation. Merkle root calculation and 9 | // corruption is already well tested in the blockchain error unit tests and 10 | // reorganization unit tests, but it'd be nice to have a specific test for 11 | // these functions and their error paths. 12 | -------------------------------------------------------------------------------- /blockchain/prune.go: -------------------------------------------------------------------------------- 1 | package blockchain 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // pruningIntervalInMinutes is the interval in which to prune the blockchain's 8 | // nodes and restore memory to the garbage collector. 9 | const pruningIntervalInMinutes = 5 10 | 11 | // chainPruner is used to occasionally prune the blockchain of old nodes that 12 | // can be freed to the garbage collector. 13 | type chainPruner struct { 14 | chain *BlockChain 15 | lastNodeInsertTime time.Time 16 | } 17 | 18 | // newChainPruner returns a new chain pruner. 19 | func newChainPruner(chain *BlockChain) *chainPruner { 20 | return &chainPruner{ 21 | chain: chain, 22 | lastNodeInsertTime: time.Now(), 23 | } 24 | } 25 | 26 | // pruneChainIfNeeded checks the current time versus the time of the last pruning. 27 | // If the blockchain hasn't been pruned in this time, it initiates a new pruning. 28 | // 29 | // pruneChainIfNeeded must be called with the chainLock held for writes. 30 | func (c *chainPruner) pruneChainIfNeeded() error { 31 | now := time.Now() 32 | duration := now.Sub(c.lastNodeInsertTime) 33 | if duration < time.Minute*pruningIntervalInMinutes { 34 | return nil 35 | } 36 | 37 | c.lastNodeInsertTime = now 38 | 39 | return c.chain.pruneNodes() 40 | } 41 | -------------------------------------------------------------------------------- /blockchain/scriptval_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 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 blockchain_test 7 | 8 | // "fmt" 9 | // "runtime" 10 | import ( 11 | "testing" 12 | ) 13 | 14 | // "github.com/HcashOrg/hcashd/blockchain" 15 | // "github.com/HcashOrg/hcashd/txscript" 16 | 17 | // TestCheckBlockScripts ensures that validating the all of the scripts in a 18 | // known-good block doesn't return an error. 19 | func TestCheckBlockScripts(t *testing.T) { 20 | /* 21 | // TODO In the future, add a block here with a lot of tx to validate. 22 | // The blockchain tests already validate a ton of scripts with signatures, 23 | // so we don't really need to make a new test for this immediately. 24 | runtime.GOMAXPROCS(runtime.NumCPU()) 25 | 26 | testBlockNum := 277647 27 | blockDataFile := fmt.Sprintf("%d.dat.bz2", testBlockNum) 28 | blocks, err := loadBlocks(blockDataFile) 29 | if err != nil { 30 | t.Errorf("Error loading file: %v\n", err) 31 | return 32 | } 33 | if len(blocks) > 1 { 34 | t.Errorf("The test block file must only have one block in it") 35 | return 36 | } 37 | if len(blocks) == 0 { 38 | t.Errorf("The test block file may not be empty") 39 | return 40 | } 41 | 42 | storeDataFile := fmt.Sprintf("%d.utxostore.bz2", testBlockNum) 43 | view, err := loadUtxoView(storeDataFile) 44 | if err != nil { 45 | t.Errorf("Error loading txstore: %v\n", err) 46 | return 47 | } 48 | 49 | scriptFlags := txscript.ScriptBip16 50 | err = blockchain.TstCheckBlockScripts(blocks[0], view, scriptFlags, 51 | nil) 52 | if err != nil { 53 | t.Errorf("Transaction script validation failed: %v\n", err) 54 | return 55 | } 56 | */ 57 | } 58 | -------------------------------------------------------------------------------- /blockchain/stake/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 | /* 7 | Package stake contains code for all of hcashd's stake 8 | transaction chain handling and other portions related to the 9 | Proof-of-Stake (PoS) system. 10 | 11 | At the heart of the PoS system are tickets, votes and revocations. 12 | These 3 pieces work together to determine if previous blocks are 13 | valid and their txs should be confirmed. 14 | 15 | Important Parts included in stake package: 16 | 17 | - Processing SSTx (tickets), SSGen (votes), SSRtx (revocations) 18 | - TicketDB 19 | - Stake Reward calculation 20 | - Stake transaction identification (IsSStx, IsSSGen, IsSSRtx) 21 | 22 | 23 | */ 24 | package stake 25 | -------------------------------------------------------------------------------- /blockchain/stake/internal/dbnamespace/dbnamespace.go: -------------------------------------------------------------------------------- 1 | // Package dbnamespace contains constants that define the database namespaces 2 | // for the purpose of the blockchain, so that external callers may easily access 3 | // this data. 4 | package dbnamespace 5 | 6 | import ( 7 | "encoding/binary" 8 | ) 9 | 10 | var ( 11 | // ByteOrder is the preferred byte order used for serializing numeric 12 | // fields for storage in the database. 13 | ByteOrder = binary.LittleEndian 14 | 15 | // StakeDbInfoBucketName is the name of the database bucket used to 16 | // house a single k->v that stores global versioning and date information for 17 | // the stake database. 18 | StakeDbInfoBucketName = []byte("stakedbinfo") 19 | 20 | // StakeChainStateKeyName is the name of the db key used to store the best 21 | // chain state from the perspective of the stake database. 22 | StakeChainStateKeyName = []byte("stakechainstate") 23 | 24 | // LiveTicketsBucketName is the name of the db bucket used to house the 25 | // list of live tickets keyed to their entry height. 26 | LiveTicketsBucketName = []byte("livetickets") 27 | 28 | // MissedTicketsBucketName is the name of the db bucket used to house the 29 | // list of missed tickets keyed to their entry height. 30 | MissedTicketsBucketName = []byte("missedtickets") 31 | 32 | // RevokedTicketsBucketName is the name of the db bucket used to house the 33 | // list of revoked tickets keyed to their entry height. 34 | RevokedTicketsBucketName = []byte("revokedtickets") 35 | 36 | // StakeBlockUndoDataBucketName is the name of the db bucket used to house the 37 | // information used to roll back the three main databases when regressing 38 | // backwards through the blockchain and restoring the stake information 39 | // to that of an earlier height. It is keyed to a mainchain height. 40 | StakeBlockUndoDataBucketName = []byte("stakeblockundo") 41 | 42 | // TicketsInBlockBucketName is the name of the db bucket used to house the 43 | // list of tickets in a block added to the mainchain, so that it can be 44 | // looked up later to insert new tickets into the live ticket database. 45 | TicketsInBlockBucketName = []byte("ticketsinblock") 46 | ) 47 | -------------------------------------------------------------------------------- /blockchain/stake/internal/ticketdb/error_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Conformal Systems LLC. 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 ticketdb_test 7 | 8 | import ( 9 | "testing" 10 | 11 | "github.com/HcashOrg/hcashd/blockchain/stake/internal/ticketdb" 12 | ) 13 | 14 | // TestErrorCodeStringer tests the stringized output for the ErrorCode type. 15 | func TestErrorCodeStringer(t *testing.T) { 16 | tests := []struct { 17 | in ticketdb.ErrorCode 18 | want string 19 | }{ 20 | {ticketdb.ErrUndoDataShortRead, "ErrUndoDataShortRead"}, 21 | {ticketdb.ErrUndoDataCorrupt, "ErrUndoDataCorrupt"}, 22 | {ticketdb.ErrTicketHashesShortRead, "ErrTicketHashesShortRead"}, 23 | {ticketdb.ErrTicketHashesCorrupt, "ErrTicketHashesCorrupt"}, 24 | {ticketdb.ErrUninitializedBucket, "ErrUninitializedBucket"}, 25 | {ticketdb.ErrMissingKey, "ErrMissingKey"}, 26 | {ticketdb.ErrChainStateShortRead, "ErrChainStateShortRead"}, 27 | {ticketdb.ErrDatabaseInfoShortRead, "ErrDatabaseInfoShortRead"}, 28 | {ticketdb.ErrLoadAllTickets, "ErrLoadAllTickets"}, 29 | {0xffff, "Unknown ErrorCode (65535)"}, 30 | } 31 | 32 | t.Logf("Running %d tests", len(tests)) 33 | for i, test := range tests { 34 | result := test.in.String() 35 | if result != test.want { 36 | t.Errorf("String #%d\n got: %s want: %s", i, result, 37 | test.want) 38 | continue 39 | } 40 | } 41 | } 42 | 43 | // TestRuleError tests the error output for the RuleError type. 44 | func TestRuleError(t *testing.T) { 45 | tests := []struct { 46 | in ticketdb.DBError 47 | want string 48 | }{ 49 | {ticketdb.DBError{Description: "duplicate block"}, 50 | "duplicate block", 51 | }, 52 | {ticketdb.DBError{Description: "human-readable error"}, 53 | "human-readable error", 54 | }, 55 | } 56 | 57 | t.Logf("Running %d tests", len(tests)) 58 | for i, test := range tests { 59 | result := test.in.Error() 60 | if result != test.want { 61 | t.Errorf("Error #%d\n got: %s want: %s", i, result, 62 | test.want) 63 | continue 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /blockchain/stake/internal/tickettreap/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Copyright (c) 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 | /* 7 | Package tickettreap implements a treap data structure that is used to hold 8 | live tickets ordered by their key along with some associated data using a 9 | combination of binary search tree and heap semantics. It is a self-organizing 10 | and randomized data structure that doesn't require complex operations to 11 | maintain balance. Search, insert, and delete operations are all O(log n). 12 | Both mutable and immutable variants are provided. 13 | 14 | The mutable variant is typically faster since it is able to simply update the 15 | treap when modifications are made. However, a mutable treap is not safe for 16 | concurrent access without careful use of locking by the caller and care must be 17 | taken when iterating since it can change out from under the iterator. 18 | 19 | The immutable variant works by creating a new version of the treap for all 20 | mutations by replacing modified nodes with new nodes that have updated values 21 | while sharing all unmodified nodes with the previous version. This is extremely 22 | useful in concurrent applications since the caller only has to atomically 23 | replace the treap pointer with the newly returned version after performing any 24 | mutations. All readers can simply use their existing pointer as a snapshot 25 | since the treap it points to is immutable. This effectively provides O(1) 26 | snapshot capability with efficient memory usage characteristics since the old 27 | nodes only remain allocated until there are no longer any references to them. 28 | */ 29 | package tickettreap 30 | -------------------------------------------------------------------------------- /blockchain/stake/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 stake 7 | 8 | import ( 9 | "github.com/btcsuite/btclog" 10 | ) 11 | 12 | // log is a logger that is initialized with no output filters. This 13 | // means the package will not perform any logging by default until the caller 14 | // requests it. 15 | var log btclog.Logger 16 | 17 | // The default amount of logging is none. 18 | func init() { 19 | DisableLog() 20 | } 21 | 22 | // DisableLog disables all library log output. Logging output is disabled 23 | // by default until UseLogger is called. 24 | func DisableLog() { 25 | log = btclog.Disabled 26 | } 27 | 28 | // UseLogger uses a specified Logger to output package logging info. 29 | func UseLogger(logger btclog.Logger) { 30 | log = logger 31 | } 32 | -------------------------------------------------------------------------------- /blockchain/subsidy_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 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 blockchain_test 7 | 8 | import ( 9 | "testing" 10 | 11 | "github.com/HcashOrg/hcashd/blockchain" 12 | "github.com/HcashOrg/hcashd/chaincfg" 13 | ) 14 | 15 | func TestBlockSubsidy(t *testing.T) { 16 | mainnet := &chaincfg.MainNetParams 17 | subsidyCache := blockchain.NewSubsidyCache(0, mainnet) 18 | 19 | totalSubsidy := mainnet.BlockOneSubsidy() 20 | for i := int64(0); ; i++ { 21 | // Genesis block or first block. 22 | if i == 0 || i == 1 { 23 | continue 24 | } 25 | 26 | if i%mainnet.SubsidyReductionInterval == 0 { 27 | numBlocks := mainnet.SubsidyReductionInterval 28 | // First reduction internal, which is reduction interval - 2 29 | // to skip the genesis block and block one. 30 | if i == mainnet.SubsidyReductionInterval { 31 | numBlocks -= 2 32 | } 33 | height := i - numBlocks 34 | 35 | work := blockchain.CalcBlockWorkSubsidy(subsidyCache, height, 36 | mainnet.TicketsPerBlock, mainnet) 37 | stake := blockchain.CalcStakeVoteSubsidy(subsidyCache, height, 38 | mainnet) * int64(mainnet.TicketsPerBlock) 39 | tax := blockchain.CalcBlockTaxSubsidy(subsidyCache, height, 40 | mainnet.TicketsPerBlock, mainnet) 41 | if (work + stake + tax) == 0 { 42 | break 43 | } 44 | totalSubsidy += ((work + stake + tax) * numBlocks) 45 | 46 | // First reduction internal, subtract the stake subsidy for 47 | // blocks before the staking system is enabled. 48 | if i == mainnet.SubsidyReductionInterval { 49 | totalSubsidy -= stake * (mainnet.StakeValidationHeight - 2) 50 | } 51 | } 52 | } 53 | 54 | if totalSubsidy != 1557556940340013 { 55 | t.Errorf("Bad total subsidy; want 1557556940340013, got %v", totalSubsidy) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /blockchain/testdata/blocks0to168.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HcashOrg/hcashd/ebc2982e38702b690eedc15f10a78f29426d3d65/blockchain/testdata/blocks0to168.bz2 -------------------------------------------------------------------------------- /blockchain/testdata/reorgto179.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HcashOrg/hcashd/ebc2982e38702b690eedc15f10a78f29426d3d65/blockchain/testdata/reorgto179.bz2 -------------------------------------------------------------------------------- /blockchain/testdata/reorgto180.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HcashOrg/hcashd/ebc2982e38702b690eedc15f10a78f29426d3d65/blockchain/testdata/reorgto180.bz2 -------------------------------------------------------------------------------- /blockchain/testdata/testexpiry.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HcashOrg/hcashd/ebc2982e38702b690eedc15f10a78f29426d3d65/blockchain/testdata/testexpiry.bz2 -------------------------------------------------------------------------------- /blockchain/timesorter.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 blockchain 7 | 8 | import ( 9 | "time" 10 | ) 11 | 12 | // timeSorter implements sort.Interface to allow a slice of timestamps to 13 | // be sorted. 14 | type timeSorter []time.Time 15 | 16 | // Len returns the number of timestamps in the slice. It is part of the 17 | // sort.Interface implementation. 18 | func (s timeSorter) Len() int { 19 | return len(s) 20 | } 21 | 22 | // Swap swaps the timestamps at the passed indices. It is part of the 23 | // sort.Interface implementation. 24 | func (s timeSorter) Swap(i, j int) { 25 | s[i], s[j] = s[j], s[i] 26 | } 27 | 28 | // Less returns whether the timstamp with index i should sort before the 29 | // timestamp with index j. It is part of the sort.Interface implementation. 30 | func (s timeSorter) Less(i, j int) bool { 31 | return s[i].Before(s[j]) 32 | } 33 | -------------------------------------------------------------------------------- /blockchain/timesorter_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 blockchain_test 7 | 8 | import ( 9 | "reflect" 10 | "sort" 11 | "testing" 12 | "time" 13 | 14 | bc "github.com/HcashOrg/hcashd/blockchain" 15 | ) 16 | 17 | // TestTimeSorter tests the timeSorter implementation. 18 | func TestTimeSorter(t *testing.T) { 19 | tests := []struct { 20 | in []time.Time 21 | want []time.Time 22 | }{ 23 | { 24 | in: []time.Time{ 25 | time.Unix(1351228575, 0), // Fri Oct 26 05:16:15 UTC 2012 (Block #205000) 26 | time.Unix(1351228575, 1), // Fri Oct 26 05:16:15 UTC 2012 (+1 nanosecond) 27 | time.Unix(1348310759, 0), // Sat Sep 22 10:45:59 UTC 2012 (Block #200000) 28 | time.Unix(1305758502, 0), // Wed May 18 22:41:42 UTC 2011 (Block #125000) 29 | time.Unix(1347777156, 0), // Sun Sep 16 06:32:36 UTC 2012 (Block #199000) 30 | time.Unix(1349492104, 0), // Sat Oct 6 02:55:04 UTC 2012 (Block #202000) 31 | }, 32 | want: []time.Time{ 33 | time.Unix(1305758502, 0), // Wed May 18 22:41:42 UTC 2011 (Block #125000) 34 | time.Unix(1347777156, 0), // Sun Sep 16 06:32:36 UTC 2012 (Block #199000) 35 | time.Unix(1348310759, 0), // Sat Sep 22 10:45:59 UTC 2012 (Block #200000) 36 | time.Unix(1349492104, 0), // Sat Oct 6 02:55:04 UTC 2012 (Block #202000) 37 | time.Unix(1351228575, 0), // Fri Oct 26 05:16:15 UTC 2012 (Block #205000) 38 | time.Unix(1351228575, 1), // Fri Oct 26 05:16:15 UTC 2012 (+1 nanosecond) 39 | }, 40 | }, 41 | } 42 | 43 | for i, test := range tests { 44 | result := make([]time.Time, len(test.in)) 45 | copy(result, test.in) 46 | sort.Sort(bc.ToTimeSorter(result)) 47 | if !reflect.DeepEqual(result, test.want) { 48 | t.Errorf("timeSorter #%d got %v want %v", i, result, 49 | test.want) 50 | continue 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /chaincfg/chainec/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The Decred 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 chainec provides wrapper functions to abstract the ec functions. 7 | 8 | Overview 9 | 10 | This package provides thin wrappers around the ec or crypto function used 11 | to make it easier to go from btcec (btcd) to ed25519 (hypercash) for example 12 | without changing the main body of the code. 13 | 14 | */ 15 | package chainec 16 | -------------------------------------------------------------------------------- /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-2016 The Decred developers 2 | // Copyright (c) 2016 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 ( 9 | "github.com/dchest/blake256" 10 | ) 11 | 12 | // HashFunc calculates the hash of the supplied bytes. 13 | // TODO(jcv) Should modify blake256 so it has the same interface as blake2 14 | // and sha256 so these function can look more like btcsuite. Then should 15 | // try to get it to the upstream blake256 repo 16 | func HashFunc(data []byte) [blake256.Size]byte { 17 | var outB [blake256.Size]byte 18 | a := blake256.New() 19 | a.Write(data) 20 | out := a.Sum(nil) 21 | for i, el := range out { 22 | outB[i] = el 23 | } 24 | 25 | return outB 26 | } 27 | 28 | // HashB calculates hash(b) and returns the resulting bytes. 29 | func HashB(b []byte) []byte { 30 | a := blake256.New() 31 | a.Write(b) 32 | out := a.Sum(nil) 33 | return out 34 | } 35 | 36 | // HashH calculates hash(b) and returns the resulting bytes as a Hash. 37 | func HashH(b []byte) Hash { 38 | var outB [blake256.Size]byte 39 | a := blake256.New() 40 | a.Write(b) 41 | out := a.Sum(nil) 42 | for i, el := range out { 43 | outB[i] = el 44 | } 45 | 46 | return Hash(outB) 47 | } 48 | 49 | // HashBlockSize is the block size of the hash algorithm in bytes. 50 | const HashBlockSize = blake256.BlockSize 51 | -------------------------------------------------------------------------------- /chaincfg/doc.go: -------------------------------------------------------------------------------- 1 | // Package chaincfg defines chain configuration parameters. 2 | // 3 | // In addition to the main Hypercash 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 0). 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.HypercashNet 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/HcashOrg/hcashutil" 29 | // "github.com/HcashOrg/hcashd/chaincfg" 30 | // ) 31 | // 32 | // var testnet = flag.Bool("testnet", false, "operate on the testnet Hypercash 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.TestNetParams 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 := hcashutil.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 Hypercash 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/internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The Decred 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 ( 8 | "testing" 9 | 10 | "github.com/HcashOrg/hcashd/chaincfg/chainhash" 11 | ) 12 | 13 | func TestInvalidHashStr(t *testing.T) { 14 | _, err := chainhash.NewHashFromStr("banana") 15 | if err == nil { 16 | t.Error("Invalid string should fail.") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chaincfg/params_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Copyright (c) 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 chaincfg 7 | 8 | import "testing" 9 | 10 | // TestMustRegisterPanic ensures the mustRegister function panics when used to 11 | // register an invalid network. 12 | func TestMustRegisterPanic(t *testing.T) { 13 | t.Parallel() 14 | 15 | // Setup a defer to catch the expected panic to ensure it actually 16 | // paniced. 17 | defer func() { 18 | if err := recover(); err == nil { 19 | t.Error("mustRegister did not panic as expected") 20 | } 21 | }() 22 | 23 | // Intentionally try to register duplicate params to force a panic. 24 | mustRegister(&MainNetParams) 25 | } 26 | -------------------------------------------------------------------------------- /chaincfg/premine.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 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 chaincfg 7 | 8 | // BlockOneLedgerMainNet is the block one output ledger for the main 9 | // network. 10 | var BlockOneLedgerMainNet = []*TokenPayout{ 11 | {"HsMNycPD277U4Zw2qNHNqY8r3MSsnhhiiGW", 10000 * 1e8}, //wancc 12 | {"HsN4DLc5n7kKyfUMKm5SW56J8LJGTK6u91h", 10000 * 1e8}, //fanlq 13 | {"HsF4tYLz9JpUFk9aPLC7U2AN8Deq6LkyoWc", 10000 * 1e8}, //shanyl 14 | {"HsZKbCUvcpjfHAJpDfWikD7E2oXUGR4ge6q", 10000 * 1e8}, //panc 15 | {"HsNu7JN9SeNb3cH7BJWMiSSpPqY6rz8BSXW", 10000 * 1e8}, //guxy 16 | {"HsamDEnZXPRczM4tNTrKbvUZA8fUSe2TqPk", 10000 * 1e8}, //dengcg 17 | {"HsLwT4E2ZdqMDwtrtaQKqp98wVaHrJfyEYM", 10000 * 1e8}, //lixm 18 | {"HsS6Hqt7yB5Fr2HDBz5gRhK75q7ciuxa7au", 10000 * 1e8}, //yaoyq 19 | } 20 | 21 | // BlockOneLedgerTestNet is the block one output ledger for the test 22 | // network. 23 | var BlockOneLedgerTestNet = []*TokenPayout{ 24 | } 25 | 26 | // BlockOneLedgerTestNet2 is the block one output ledger for the 2nd test 27 | // network. 28 | var BlockOneLedgerTestNet2 = []*TokenPayout{ 29 | } 30 | 31 | // BlockOneLedgerSimNet is the block one output ledger for the simulation 32 | // network. See under "Hypercash organization related parameters" in params.go 33 | // for information on how to spend these outputs. 34 | var BlockOneLedgerSimNet = []*TokenPayout{ 35 | {"HsMNycPD277U4Zw2qNHNqY8r3MSsnhhiiGW", 10000 * 1e8}, //wancc 36 | {"HsN4DLc5n7kKyfUMKm5SW56J8LJGTK6u91h", 10000 * 1e8}, //fanlq 37 | {"HsF4tYLz9JpUFk9aPLC7U2AN8Deq6LkyoWc", 10000 * 1e8}, //shanyl 38 | {"HsZKbCUvcpjfHAJpDfWikD7E2oXUGR4ge6q", 10000 * 1e8}, //panc 39 | {"HsNu7JN9SeNb3cH7BJWMiSSpPqY6rz8BSXW", 10000 * 1e8}, //guxy 40 | {"HsamDEnZXPRczM4tNTrKbvUZA8fUSe2TqPk", 10000 * 1e8}, //dengcg 41 | {"HsLwT4E2ZdqMDwtrtaQKqp98wVaHrJfyEYM", 10000 * 1e8}, //lixm 42 | {"HsS6Hqt7yB5Fr2HDBz5gRhK75q7ciuxa7au", 10000 * 1e8}, //yaoyq 43 | } 44 | -------------------------------------------------------------------------------- /cmd/hcashctl/sample-hcashctl.conf: -------------------------------------------------------------------------------- 1 | [Application Options] 2 | 3 | ; ------------------------------------------------------------------------------ 4 | ; Network settings 5 | ; ------------------------------------------------------------------------------ 6 | 7 | ; Use testnet (cannot be used with simnet=1). 8 | ; testnet=1 9 | 10 | ; Use simnet (cannot be used with testnet=1). 11 | ; simnet=1 12 | 13 | 14 | ; ------------------------------------------------------------------------------ 15 | ; RPC client settings 16 | ; ------------------------------------------------------------------------------ 17 | 18 | ; Connect via a SOCKS5 proxy. 19 | ; proxy=127.0.0.1:9050 20 | ; proxyuser= 21 | ; proxypass= 22 | 23 | ; Username and password to authenticate connections to a Hypercash RPC server 24 | ; (usually hcashd or hcashwallet) 25 | ; rpcuser= 26 | ; rpcpass= 27 | 28 | ; RPC server to connect to 29 | ; rpcserver=localhost 30 | 31 | ; Wallet RPC server to connect to 32 | ; walletrpcserver=localhost 33 | 34 | ; RPC server certificate chain file for validation 35 | ; rpccert=~/.hcashd/rpc.cert 36 | 37 | -------------------------------------------------------------------------------- /cmd/promptsecret/promptsecret.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 The Decred 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 | "fmt" 9 | "os" 10 | 11 | "golang.org/x/crypto/ssh/terminal" 12 | ) 13 | 14 | func zero(b []byte) { 15 | for i := 0; i < len(b); i++ { 16 | b[i] = 0x00 17 | } 18 | } 19 | 20 | func main() { 21 | fmt.Fprint(os.Stderr, "Secret: ") 22 | 23 | secret, err := terminal.ReadPassword(int(os.Stdin.Fd())) 24 | fmt.Fprint(os.Stderr, "\n") 25 | if err != nil { 26 | fmt.Fprintf(os.Stderr, "unable to read secret: %v\n", err) 27 | os.Exit(1) 28 | } 29 | 30 | _, err = os.Stdout.Write(secret) 31 | zero(secret) 32 | if err != nil { 33 | fmt.Fprintf(os.Stderr, "unable to write to stdout: %v\n", err) 34 | os.Exit(1) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /connmgr/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 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 | /* 7 | Package connmgr implements a generic Hypercash network connection manager. 8 | 9 | Connection Manager Overview 10 | 11 | Connection manager handles all the general connection concerns such as 12 | maintaining a set number of outbound connections, sourcing peers, banning, 13 | limiting max connections, tor lookup, etc. 14 | */ 15 | package connmgr 16 | -------------------------------------------------------------------------------- /connmgr/dynamicbanscore_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Copyright (c) 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 connmgr 7 | 8 | import ( 9 | "math" 10 | "testing" 11 | "time" 12 | ) 13 | 14 | // TestDynamicBanScoreDecay tests the exponential decay implemented in 15 | // DynamicBanScore. 16 | func TestDynamicBanScoreDecay(t *testing.T) { 17 | var bs DynamicBanScore 18 | base := time.Now() 19 | 20 | r := bs.increase(100, 50, base) 21 | if r != 150 { 22 | t.Errorf("Unexpected result %d after ban score increase.", r) 23 | } 24 | 25 | r = bs.int(base.Add(time.Minute)) 26 | if r != 125 { 27 | t.Errorf("Halflife check failed - %d instead of 125", r) 28 | } 29 | 30 | r = bs.int(base.Add(7 * time.Minute)) 31 | if r != 100 { 32 | t.Errorf("Decay after 7m - %d instead of 100", r) 33 | } 34 | } 35 | 36 | // TestDynamicBanScoreLifetime tests that DynamicBanScore properly yields zero 37 | // once the maximum age is reached. 38 | func TestDynamicBanScoreLifetime(t *testing.T) { 39 | var bs DynamicBanScore 40 | base := time.Now() 41 | 42 | r := bs.increase(0, math.MaxUint32, base) 43 | r = bs.int(base.Add(Lifetime * time.Second)) 44 | if r != 3 { // 3, not 4 due to precision loss and truncating 3.999... 45 | t.Errorf("Pre max age check with MaxUint32 failed - %d", r) 46 | } 47 | r = bs.int(base.Add((Lifetime + 1) * time.Second)) 48 | if r != 0 { 49 | t.Errorf("Zero after max age check failed - %d instead of 0", r) 50 | } 51 | } 52 | 53 | // TestDynamicBanScore tests exported functions of DynamicBanScore. Exponential 54 | // decay or other time based behavior is tested by other functions. 55 | func TestDynamicBanScoreReset(t *testing.T) { 56 | var bs DynamicBanScore 57 | if bs.Int() != 0 { 58 | t.Errorf("Initial state is not zero.") 59 | } 60 | bs.Increase(100, 0) 61 | r := bs.Int() 62 | if r != 100 { 63 | t.Errorf("Unexpected result %d after ban score increase.", r) 64 | } 65 | bs.Reset() 66 | if bs.Int() != 0 { 67 | t.Errorf("Failed to reset ban score.") 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /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 | mrand "math/rand" 9 | "net" 10 | "strconv" 11 | "time" 12 | 13 | "github.com/HcashOrg/hcashd/chaincfg" 14 | "github.com/HcashOrg/hcashd/wire" 15 | ) 16 | 17 | const ( 18 | // These constants are used by the DNS seed code to pick a random last 19 | // seen time. 20 | secondsIn3Days int32 = 24 * 60 * 60 * 3 21 | secondsIn4Days int32 = 24 * 60 * 60 * 4 22 | ) 23 | 24 | // OnSeed is the signature of the callback function which is invoked when DNS 25 | // seeding is succesfull. 26 | type OnSeed func(addrs []*wire.NetAddress) 27 | 28 | // LookupFunc is the signature of the DNS lookup function. 29 | type LookupFunc func(string) ([]net.IP, error) 30 | 31 | // SeedFromDNS uses DNS seeding to populate the address manager with peers. 32 | func SeedFromDNS(chainParams *chaincfg.Params, lookupFn LookupFunc, seedFn OnSeed) { 33 | for _, seeder := range chainParams.DNSSeeds { 34 | go func(seeder string) { 35 | randSource := mrand.New(mrand.NewSource(time.Now().UnixNano())) 36 | 37 | seedpeers, err := lookupFn(seeder) 38 | if err != nil { 39 | log.Infof("DNS discovery failed on seed %s: %v", seeder, err) 40 | return 41 | } 42 | numPeers := len(seedpeers) 43 | 44 | log.Infof("%d addresses found from DNS seed %s", numPeers, seeder) 45 | 46 | if numPeers == 0 { 47 | return 48 | } 49 | addresses := make([]*wire.NetAddress, len(seedpeers)) 50 | // if this errors then we have *real* problems 51 | intPort, _ := strconv.Atoi(chainParams.DefaultPort) 52 | for i, peer := range seedpeers { 53 | addresses[i] = wire.NewNetAddressTimestamp( 54 | // bitcoind seeds with addresses from 55 | // a time randomly selected between 3 56 | // and 7 days ago. 57 | time.Now().Add(-1*time.Second*time.Duration(secondsIn3Days+ 58 | randSource.Int31n(secondsIn4Days))), 59 | 0, peer, uint16(intPort)) 60 | } 61 | 62 | seedFn(addresses) 63 | }(seeder) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /crypto/bliss/bliss_test.go: -------------------------------------------------------------------------------- 1 | package bliss 2 | 3 | import "testing" 4 | 5 | func TestBliss(t *testing.T){ 6 | 7 | } -------------------------------------------------------------------------------- /crypto/bliss/privkey.go: -------------------------------------------------------------------------------- 1 | package bliss 2 | 3 | import ( 4 | "github.com/LoCCS/bliss" 5 | hcashcrypto "github.com/HcashOrg/hcashd/crypto" 6 | ) 7 | 8 | type PrivateKey struct{ 9 | hcashcrypto.PrivateKeyAdapter 10 | bliss.PrivateKey 11 | } 12 | 13 | 14 | // Public returns the PublicKey corresponding to this private key. 15 | func (p PrivateKey) PublicKey() (hcashcrypto.PublicKey) { 16 | blissPkp := p.PrivateKey.PublicKey() 17 | pk := &PublicKey{ 18 | PublicKey: *blissPkp, 19 | } 20 | return pk 21 | } 22 | 23 | // GetType satisfies the bliss PrivateKey interface. 24 | func (p PrivateKey) GetType() int { 25 | return pqcTypeBliss 26 | } 27 | 28 | func (p PrivateKey) Serialize() []byte{ 29 | return p.PrivateKey.Serialize() 30 | } -------------------------------------------------------------------------------- /crypto/bliss/privkey_test.go: -------------------------------------------------------------------------------- 1 | package bliss 2 | import ( 3 | "testing" 4 | _ "github.com/HcashOrg/hcashd/chaincfg/chainec" 5 | _ "github.com/HcashOrg/hcashd/crypto" 6 | "crypto/rand" 7 | "bytes" 8 | ) 9 | 10 | func TestPrivateKey(t *testing.T) { 11 | sk, pk, err := Bliss.GenerateKey(rand.Reader) 12 | if err != nil{ 13 | t.Fatal("Error in Generate keys") 14 | } 15 | 16 | pk2 := sk.PublicKey() 17 | pk3 := sk.(*PrivateKey).PrivateKey.PublicKey() 18 | pkBytes := pk.Serialize() 19 | pkBytes2 := pk2.Serialize() 20 | pkBytes3 := pk3.Serialize() 21 | skBytes := sk.Serialize() 22 | skBytes2 := sk.(*PrivateKey).PrivateKey.Serialize() 23 | 24 | if !bytes.Equal(pkBytes, pkBytes2){ 25 | t.Fatal("Error in PublicKey(), the result is not same as the result of Generatekey()") 26 | } 27 | 28 | if !bytes.Equal(pkBytes, pkBytes3){ 29 | t.Fatalf("Generated Public Key is not same as the result of the PublicKey() of bliss privateKey") 30 | } 31 | 32 | if !bytes.Equal(skBytes, skBytes2){ 33 | t.Fatalf("Error in Serialization(), the result is not same as the result of function in Bliss") 34 | } 35 | 36 | prk, _ := Bliss.PrivKeyFromBytes(skBytes) 37 | skBytes3 := prk.Serialize() 38 | 39 | if !bytes.Equal(skBytes, skBytes3){ 40 | t.Fatalf("serilization() and PrivKeyFromBytes() do not match") 41 | } 42 | 43 | tp := sk.GetType() 44 | if tp != pqcTypeBliss{ 45 | t.Fatal("GetType() result not matched") 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /crypto/bliss/pubkey.go: -------------------------------------------------------------------------------- 1 | package bliss 2 | 3 | import ( 4 | "github.com/LoCCS/bliss" 5 | hcashcrypto "github.com/HcashOrg/hcashd/crypto" 6 | ) 7 | 8 | type PublicKey struct{ 9 | hcashcrypto.PublicKeyAdapter 10 | bliss.PublicKey 11 | } 12 | 13 | func (p PublicKey) GetType() int { 14 | return pqcTypeBliss 15 | } 16 | 17 | func (p PublicKey) Serialize() []byte{ 18 | return p.PublicKey.Serialize() 19 | } 20 | 21 | func (p PublicKey) SerializeCompressed() []byte{ 22 | return p.Serialize() 23 | } 24 | 25 | func (p PublicKey) SerializeUnCompressed() []byte{ 26 | return p.Serialize() 27 | } 28 | 29 | -------------------------------------------------------------------------------- /crypto/bliss/pubkey_test.go: -------------------------------------------------------------------------------- 1 | package bliss 2 | 3 | import ( 4 | "testing" 5 | _ "github.com/HcashOrg/hcashd/chaincfg/chainec" 6 | _ "github.com/HcashOrg/hcashd/crypto" 7 | "crypto/rand" 8 | "bytes" 9 | ) 10 | 11 | func TestPublicKey(t *testing.T) { 12 | 13 | _, pk, err := Bliss.GenerateKey(rand.Reader) 14 | if err != nil{ 15 | t.Fatal("Error in Generate keys") 16 | } 17 | 18 | pkBytes := pk.Serialize() 19 | restoredPK, err := Bliss.ParsePubKey(pkBytes) 20 | if err != nil{ 21 | t.Fatal("Error in parsepubkey()") 22 | } 23 | pkBytes2 := restoredPK.Serialize() 24 | 25 | if !bytes.Equal(pkBytes, pkBytes2){ 26 | t.Fatal("Serialization() and ParsePubKey() do not match") 27 | } 28 | 29 | 30 | tp := pk.GetType() 31 | if tp != pqcTypeBliss{ 32 | t.Fatal("GetType() result not matched") 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /crypto/bliss/signature.go: -------------------------------------------------------------------------------- 1 | package bliss 2 | 3 | import ( 4 | "github.com/LoCCS/bliss" 5 | hcashcrypto "github.com/HcashOrg/hcashd/crypto" 6 | "github.com/LoCCS/bliss/sampler" 7 | "crypto/rand" 8 | ) 9 | 10 | type Signature struct{ 11 | hcashcrypto.SignatureAdapter 12 | bliss.Signature 13 | } 14 | 15 | func (s Signature) GetType() int { 16 | return pqcTypeBliss 17 | } 18 | 19 | func (s Signature) Serialize() []byte{ 20 | return s.Signature.Serialize() 21 | } 22 | 23 | func SignCompact(key hcashcrypto.PrivateKey, hash []byte)([]byte, error) { 24 | 25 | seed := make([]byte, sampler.SHA_512_DIGEST_LENGTH) 26 | rand.Read(seed) 27 | entropy, err := sampler.NewEntropy(seed) 28 | if err != nil{ 29 | return nil, err 30 | } 31 | var sig *bliss.Signature 32 | switch pv := key.(type){ 33 | case PrivateKey: 34 | sig, err = pv.Sign(hash, entropy) 35 | case *PrivateKey: 36 | sig, err = pv.Sign(hash, entropy) 37 | } 38 | 39 | if err != nil{ 40 | return nil, err 41 | } 42 | 43 | result := sig.Serialize() 44 | return result, err 45 | } 46 | 47 | func VerifyCompact(key hcashcrypto.PublicKey, messageHash, sign []byte) (bool, error){ 48 | 49 | sig,_ := bliss.DeserializeBlissSignature(sign) 50 | result, err := key.(*PublicKey).Verify(messageHash, sig) 51 | 52 | return result, err 53 | } -------------------------------------------------------------------------------- /crypto/bliss/signature_test.go: -------------------------------------------------------------------------------- 1 | package bliss 2 | 3 | import ( 4 | "testing" 5 | _ "github.com/HcashOrg/hcashd/chaincfg/chainec" 6 | _ "github.com/HcashOrg/hcashd/crypto" 7 | "crypto/rand" 8 | "bytes" 9 | "golang.org/x/crypto/sha3" 10 | "github.com/HcashOrg/hcashd/chaincfg/chainec" 11 | ) 12 | 13 | func TestSignature(t *testing.T) { 14 | 15 | sk, _, err := Bliss.GenerateKey(rand.Reader) 16 | if err != nil{ 17 | t.Fatal("Error in Generate keys") 18 | } 19 | 20 | message := make([]byte, 512) 21 | rand.Read(message) 22 | sha3.New512() 23 | hash := sha3.Sum512(message) 24 | 25 | var sig chainec.Signature 26 | sig, err = Bliss.Sign(sk, hash[:]) 27 | if err != nil{ 28 | t.Fatal("Error in Sign()") 29 | } 30 | 31 | sigBytes := sig.Serialize() 32 | restoredSig, err := Bliss.ParseSignature(sigBytes) 33 | if err != nil{ 34 | t.Fatal("Error in ParseSignature") 35 | } 36 | sigBytes2 := restoredSig.Serialize() 37 | 38 | if !bytes.Equal(sigBytes, sigBytes2){ 39 | t.Fatal("Serialization() and ParseSignature() do not match") 40 | } 41 | 42 | tp := sig.GetType() 43 | if tp != pqcTypeBliss{ 44 | t.Fatal("GetType() result not matched") 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /crypto/crypto.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "math/big" 5 | "crypto/ecdsa" 6 | "github.com/HcashOrg/hcashd/chaincfg/chainec" 7 | ) 8 | 9 | type PrivateKey interface{ 10 | chainec.PrivateKey 11 | PublicKey() PublicKey 12 | } 13 | 14 | type PublicKey interface{ 15 | chainec.PublicKey 16 | } 17 | 18 | type Signature interface{ 19 | chainec.Signature 20 | } 21 | 22 | type PublicKeyAdapter struct { 23 | } 24 | 25 | type PrivateKeyAdapter struct { 26 | } 27 | 28 | type SignatureAdapter struct { 29 | } 30 | 31 | //PrivateKeyAdapter 32 | func (pa PrivateKeyAdapter) Serialize() []byte{ 33 | return nil 34 | } 35 | 36 | func (pa PrivateKeyAdapter)SerializeSecret() []byte{ 37 | return nil 38 | } 39 | 40 | func (pa PrivateKeyAdapter) Public() (*big.Int, *big.Int){ 41 | return nil, nil 42 | } 43 | 44 | func (pa PrivateKeyAdapter) PublicKey() PublicKey{ 45 | return nil 46 | } 47 | 48 | func (pa PrivateKeyAdapter) GetD() *big.Int{ 49 | return nil 50 | } 51 | 52 | func (pa PrivateKeyAdapter) GetType() int{ 53 | return 0 54 | } 55 | 56 | //PublicKeyAdapter 57 | func (pa PublicKeyAdapter)Serialize() []byte{ 58 | return nil 59 | } 60 | 61 | func (pa PublicKeyAdapter) SerializeUncompressed() []byte{ 62 | return nil 63 | } 64 | 65 | func (pa PublicKeyAdapter) SerializeCompressed() []byte{ 66 | return nil 67 | } 68 | 69 | func (pa PublicKeyAdapter) SerializeHybrid() []byte{ 70 | return nil 71 | } 72 | 73 | func (pa PublicKeyAdapter) ToECDSA() *ecdsa.PublicKey{ 74 | return nil 75 | } 76 | 77 | func (pa PublicKeyAdapter) GetCurve() interface{}{ 78 | return nil 79 | } 80 | 81 | func (pa PublicKeyAdapter) GetX() *big.Int{ 82 | return nil 83 | } 84 | 85 | func (pa PublicKeyAdapter) GetY() *big.Int{ 86 | return nil 87 | } 88 | 89 | func (pa PublicKeyAdapter) GetType() int{ 90 | return 0 91 | } 92 | 93 | //SignatureAdapter 94 | func (s SignatureAdapter) Serialize() []byte{ 95 | return nil 96 | } 97 | 98 | func (s SignatureAdapter) GetR() *big.Int{ 99 | return nil 100 | } 101 | 102 | func (s SignatureAdapter ) GetS() *big.Int{ 103 | return nil 104 | } 105 | 106 | func GetType() int{ 107 | return 0 108 | } -------------------------------------------------------------------------------- /crypto/crypto_test.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | import ( 3 | "fmt" 4 | _"github.com/HcashOrg/hcashd/chaincfg/chainec" 5 | "testing" 6 | ) 7 | 8 | func TestCrypto(t *testing.T) { 9 | fmt.Println("test start") 10 | var pk PublicKey 11 | pk = new(PublicKeyAdapter) 12 | fmt.Println(pk.GetType()) 13 | } -------------------------------------------------------------------------------- /crypto/lms/dsa.go: -------------------------------------------------------------------------------- 1 | package lms 2 | 3 | import ( 4 | "io" 5 | hcashcrypto "github.com/HcashOrg/hcashd/crypto" 6 | ) 7 | 8 | type DSA interface { 9 | 10 | // ---------------------------------------------------------------------------- 11 | // Private keys 12 | // 13 | // NewPrivateKey instantiates a new private key for the given data 14 | NewPrivateKey() hcashcrypto.PrivateKey 15 | 16 | // PrivKeyFromBytes calculates the public key from serialized bytes, 17 | // and returns both it and the private key. 18 | PrivKeyFromBytes(pk []byte) (hcashcrypto.PrivateKey, hcashcrypto.PublicKey) 19 | 20 | // PrivKeyBytesLen returns the length of a serialized private key. 21 | PrivKeyBytesLen() int 22 | 23 | // ---------------------------------------------------------------------------- 24 | // Public keys 25 | // 26 | // NewPublicKey instantiates a new public key (point) for the given data. 27 | NewPublicKey() hcashcrypto.PublicKey 28 | 29 | // ParsePubKey parses a serialized public key for the given 30 | // curve and returns a public key. 31 | ParsePubKey(pubKeyStr []byte) (hcashcrypto.PublicKey, error) 32 | 33 | // PubKeyBytesLen returns the length of the default serialization 34 | // method for a public key. 35 | PubKeyBytesLen() int 36 | 37 | // ---------------------------------------------------------------------------- 38 | // Signatures 39 | // 40 | // NewSignature instantiates a new signature 41 | NewSignature() hcashcrypto.Signature 42 | 43 | // ParseDERSignature parses a DER encoded signature . 44 | // If the method doesn't support DER signatures, it 45 | // just parses with the default method. 46 | ParseDERSignature(sigStr []byte) (hcashcrypto.Signature, error) 47 | 48 | // ParseSignature a default encoded signature 49 | ParseSignature(sigStr []byte) (hcashcrypto.Signature, error) 50 | 51 | // RecoverCompact recovers a public key from an encoded signature 52 | // and message, then verifies the signature against the public 53 | // key. 54 | RecoverCompact(signature , hash []byte) (hcashcrypto.PublicKey, bool, error) 55 | 56 | // ---------------------------------------------------------------------------- 57 | // LMS 58 | // 59 | // GenerateKey generates a new private and public keypair from the 60 | // given reader. 61 | GenerateKey(rand io.Reader) (hcashcrypto.PrivateKey, hcashcrypto.PublicKey, error) 62 | 63 | // Sign produces a LMS signature using a private key and a message. 64 | Sign(priv hcashcrypto.PrivateKey, hash []byte) (hcashcrypto.Signature, error) 65 | 66 | // Verify verifies a LMS signature against a given message and 67 | // public key. 68 | Verify(pub hcashcrypto.PublicKey, hash []byte, sig hcashcrypto.Signature) bool 69 | } 70 | 71 | const ( 72 | LMSTypeLMS = 5 73 | 74 | LMSVersion = 1 75 | 76 | LMSPubKeyLen = 32 77 | 78 | LMSPrivKeyLen = 4691 79 | ) 80 | 81 | var LMS = newLMSDSA() -------------------------------------------------------------------------------- /crypto/lms/lms_test.go: -------------------------------------------------------------------------------- 1 | package lms 2 | import ( 3 | "testing" 4 | _ "github.com/HcashOrg/hcashd/chaincfg/chainec" 5 | _ "github.com/HcashOrg/hcashd/crypto" 6 | "time" 7 | "fmt" 8 | "github.com/LoCCS/lmots" 9 | "github.com/LoCCS/lms" 10 | "github.com/LoCCS/lmots/rand" 11 | "strings" 12 | ) 13 | 14 | const ( 15 | H = 8 // the height of the merkle tree 16 | ) 17 | // GenerateKey is not implemented in hcashd. So the merkle agent is generated by function in lms project of LoCCS 18 | // Sign and Verify are implemented in hcashd. 19 | func TestLMS(t *testing.T) { 20 | //seed, err := rand.RandSeed() 21 | seed := make([]byte, lmots.N) 22 | rand.Reader.Read(seed) 23 | agentStart := time.Now() 24 | merkleAgent, err := lms.NewMerkleAgent(H, seed) 25 | agentTime := time.Since(agentStart) 26 | 27 | if err != nil { 28 | fmt.Println(err) 29 | } 30 | fmt.Printf("Time on new merkle Agent with height %v : %v\n", H, agentTime) 31 | 32 | var signSum time.Duration 33 | var verifySum time.Duration 34 | var maxsig time.Duration 35 | var maxver time.Duration 36 | success := 0 37 | failure := 0 38 | for i := 0; i < 1<" 63 | } 64 | -------------------------------------------------------------------------------- /database/cmd/dbtool/fetchblockregion.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Copyright (c) 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 main 7 | 8 | import ( 9 | "encoding/hex" 10 | "errors" 11 | "strconv" 12 | "time" 13 | 14 | "github.com/HcashOrg/hcashd/chaincfg/chainhash" 15 | "github.com/HcashOrg/hcashd/database" 16 | ) 17 | 18 | // blockRegionCmd defines the configuration options for the fetchblockregion 19 | // command. 20 | type blockRegionCmd struct{} 21 | 22 | var ( 23 | // blockRegionCfg defines the configuration options for the command. 24 | blockRegionCfg = blockRegionCmd{} 25 | ) 26 | 27 | // Execute is the main entry point for the command. It's invoked by the parser. 28 | func (cmd *blockRegionCmd) Execute(args []string) error { 29 | // Setup the global config options and ensure they are valid. 30 | if err := setupGlobalConfig(); err != nil { 31 | return err 32 | } 33 | 34 | // Ensure expected arguments. 35 | if len(args) < 1 { 36 | return errors.New("required block hash parameter not specified") 37 | } 38 | if len(args) < 2 { 39 | return errors.New("required start offset parameter not " + 40 | "specified") 41 | } 42 | if len(args) < 3 { 43 | return errors.New("required region length parameter not " + 44 | "specified") 45 | } 46 | 47 | // Parse arguments. 48 | blockHash, err := chainhash.NewHashFromStr(args[0]) 49 | if err != nil { 50 | return err 51 | } 52 | startOffset, err := strconv.ParseUint(args[1], 10, 32) 53 | if err != nil { 54 | return err 55 | } 56 | regionLen, err := strconv.ParseUint(args[2], 10, 32) 57 | if err != nil { 58 | return err 59 | } 60 | 61 | // Load the block database. 62 | db, err := loadBlockDB() 63 | if err != nil { 64 | return err 65 | } 66 | defer db.Close() 67 | 68 | return db.View(func(tx database.Tx) error { 69 | log.Infof("Fetching block region %s<%d:%d>", blockHash, 70 | startOffset, startOffset+regionLen-1) 71 | region := database.BlockRegion{ 72 | Hash: blockHash, 73 | Offset: uint32(startOffset), 74 | Len: uint32(regionLen), 75 | } 76 | startTime := time.Now() 77 | regionBytes, err := tx.FetchBlockRegion(®ion) 78 | if err != nil { 79 | return err 80 | } 81 | log.Infof("Loaded block region in %v", time.Since(startTime)) 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 | // Copyright (c) 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 main 7 | 8 | import ( 9 | "time" 10 | 11 | "github.com/HcashOrg/hcashd/chaincfg/chainhash" 12 | "github.com/HcashOrg/hcashd/database" 13 | ) 14 | 15 | // headersCmd defines the configuration options for the loadheaders command. 16 | type headersCmd struct { 17 | Bulk bool `long:"bulk" description:"Use bulk loading of headers instead of one at a time"` 18 | } 19 | 20 | var ( 21 | // headersCfg defines the configuration options for the command. 22 | headersCfg = headersCmd{ 23 | Bulk: false, 24 | } 25 | ) 26 | 27 | // Execute is the main entry point for the command. It's invoked by the parser. 28 | func (cmd *headersCmd) Execute(args []string) error { 29 | // Setup the global config options and ensure they are valid. 30 | if err := setupGlobalConfig(); err != nil { 31 | return err 32 | } 33 | 34 | // Load the block database. 35 | db, err := loadBlockDB() 36 | if err != nil { 37 | return err 38 | } 39 | defer db.Close() 40 | 41 | // NOTE: This code will only work for ffldb. Ideally the package using 42 | // the database would keep a metadata index of its own. 43 | blockIdxName := []byte("ffldb-blockidx") 44 | if !headersCfg.Bulk { 45 | return db.View(func(tx database.Tx) error { 46 | totalHdrs := 0 47 | blockIdxBucket := tx.Metadata().Bucket(blockIdxName) 48 | blockIdxBucket.ForEach(func(k, v []byte) error { 49 | totalHdrs++ 50 | return nil 51 | }) 52 | log.Infof("Loading headers for %d blocks...", totalHdrs) 53 | numLoaded := 0 54 | startTime := time.Now() 55 | blockIdxBucket.ForEach(func(k, v []byte) error { 56 | var hash chainhash.Hash 57 | copy(hash[:], k) 58 | _, err := tx.FetchBlockHeader(&hash) 59 | if err != nil { 60 | return err 61 | } 62 | numLoaded++ 63 | return nil 64 | }) 65 | log.Infof("Loaded %d headers in %v", numLoaded, 66 | time.Since(startTime)) 67 | return nil 68 | }) 69 | } 70 | 71 | // Bulk load headers. 72 | return 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 | } 93 | -------------------------------------------------------------------------------- /database/cmd/dbtool/signal.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Copyright (c) 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 main 7 | 8 | import ( 9 | "os" 10 | "os/signal" 11 | ) 12 | 13 | // interruptChannel is used to receive SIGINT (Ctrl+C) signals. 14 | var interruptChannel chan os.Signal 15 | 16 | // addHandlerChannel is used to add an interrupt handler to the list of handlers 17 | // to be invoked on SIGINT (Ctrl+C) signals. 18 | var addHandlerChannel = make(chan func()) 19 | 20 | // mainInterruptHandler listens for SIGINT (Ctrl+C) signals on the 21 | // interruptChannel and invokes the registered interruptCallbacks accordingly. 22 | // It also listens for callback registration. It must be run as a goroutine. 23 | func mainInterruptHandler() { 24 | // interruptCallbacks is a list of callbacks to invoke when a 25 | // SIGINT (Ctrl+C) is received. 26 | var interruptCallbacks []func() 27 | 28 | // isShutdown is a flag which is used to indicate whether or not 29 | // the shutdown signal has already been received and hence any future 30 | // attempts to add a new interrupt handler should invoke them 31 | // immediately. 32 | var isShutdown bool 33 | 34 | for { 35 | select { 36 | case <-interruptChannel: 37 | // Ignore more than one shutdown signal. 38 | if isShutdown { 39 | log.Infof("Received SIGINT (Ctrl+C). " + 40 | "Already shutting down...") 41 | continue 42 | } 43 | 44 | isShutdown = true 45 | log.Infof("Received SIGINT (Ctrl+C). Shutting down...") 46 | 47 | // Run handlers in LIFO order. 48 | for i := range interruptCallbacks { 49 | idx := len(interruptCallbacks) - 1 - i 50 | callback := interruptCallbacks[idx] 51 | callback() 52 | } 53 | 54 | // Signal the main goroutine to shutdown. 55 | go func() { 56 | shutdownChannel <- nil 57 | }() 58 | 59 | case handler := <-addHandlerChannel: 60 | // The shutdown signal has already been received, so 61 | // just invoke and new handlers immediately. 62 | if isShutdown { 63 | handler() 64 | } 65 | 66 | interruptCallbacks = append(interruptCallbacks, handler) 67 | } 68 | } 69 | } 70 | 71 | // addInterruptHandler adds a handler to call when a SIGINT (Ctrl+C) is 72 | // received. 73 | func addInterruptHandler(handler func()) { 74 | // Create the channel and start the main interrupt handler which invokes 75 | // all other callbacks and exits if not already done. 76 | if interruptChannel == nil { 77 | interruptChannel = make(chan os.Signal, 1) 78 | signal.Notify(interruptChannel, os.Interrupt) 79 | go mainInterruptHandler() 80 | } 81 | 82 | addHandlerChannel <- handler 83 | } 84 | -------------------------------------------------------------------------------- /database/export_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Copyright (c) 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 | /* 7 | This test file is part of the database package rather than than the 8 | database_test package so it can bridge access to the internals to properly test 9 | cases which are either not possible or can't reliably be tested via the public 10 | interface. The functions, constants, and variables are only exported while the 11 | tests are being run. 12 | */ 13 | 14 | package database 15 | 16 | // TstNumErrorCodes makes the internal numErrorCodes parameter available to the 17 | // test package. 18 | const TstNumErrorCodes = numErrorCodes 19 | -------------------------------------------------------------------------------- /database/ffldb/bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Copyright (c) 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 ffldb 7 | 8 | import ( 9 | "os" 10 | "path/filepath" 11 | "testing" 12 | 13 | "github.com/HcashOrg/hcashd/chaincfg" 14 | "github.com/HcashOrg/hcashd/database" 15 | "github.com/HcashOrg/hcashutil" 16 | ) 17 | 18 | // BenchmarkBlockHeader benchmarks how long it takes to load the mainnet genesis 19 | // block header. 20 | func BenchmarkBlockHeader(b *testing.B) { 21 | // Start by creating a new database and populating it with the mainnet 22 | // genesis block. 23 | dbPath := filepath.Join(os.TempDir(), "ffldb-benchblkhdr") 24 | _ = os.RemoveAll(dbPath) 25 | db, err := database.Create("ffldb", dbPath, blockDataNet) 26 | if err != nil { 27 | b.Fatal(err) 28 | } 29 | defer os.RemoveAll(dbPath) 30 | defer db.Close() 31 | err = db.Update(func(tx database.Tx) error { 32 | block := hcashutil.NewBlock(chaincfg.MainNetParams.GenesisBlock) 33 | return tx.StoreBlock(block) 34 | }) 35 | if err != nil { 36 | b.Fatal(err) 37 | } 38 | 39 | b.ReportAllocs() 40 | b.ResetTimer() 41 | err = db.View(func(tx database.Tx) error { 42 | blockHash := chaincfg.MainNetParams.GenesisHash 43 | for i := 0; i < b.N; i++ { 44 | _, err := tx.FetchBlockHeader(blockHash) 45 | if err != nil { 46 | return err 47 | } 48 | } 49 | return nil 50 | }) 51 | if err != nil { 52 | b.Fatal(err) 53 | } 54 | 55 | // Don't benchmark teardown. 56 | b.StopTimer() 57 | } 58 | 59 | // BenchmarkBlockHeader benchmarks how long it takes to load the mainnet genesis 60 | // block. 61 | func BenchmarkBlock(b *testing.B) { 62 | // Start by creating a new database and populating it with the mainnet 63 | // genesis block. 64 | dbPath := filepath.Join(os.TempDir(), "ffldb-benchblk") 65 | _ = os.RemoveAll(dbPath) 66 | db, err := database.Create("ffldb", dbPath, blockDataNet) 67 | if err != nil { 68 | b.Fatal(err) 69 | } 70 | defer os.RemoveAll(dbPath) 71 | defer db.Close() 72 | err = db.Update(func(tx database.Tx) error { 73 | block := hcashutil.NewBlock(chaincfg.MainNetParams.GenesisBlock) 74 | return tx.StoreBlock(block) 75 | }) 76 | if err != nil { 77 | b.Fatal(err) 78 | } 79 | 80 | b.ReportAllocs() 81 | b.ResetTimer() 82 | err = db.View(func(tx database.Tx) error { 83 | blockHash := chaincfg.MainNetParams.GenesisHash 84 | for i := 0; i < b.N; i++ { 85 | _, err := tx.FetchBlock(blockHash) 86 | if err != nil { 87 | return err 88 | } 89 | } 90 | return nil 91 | }) 92 | if err != nil { 93 | b.Fatal(err) 94 | } 95 | 96 | // Don't benchmark teardown. 97 | b.StopTimer() 98 | } 99 | -------------------------------------------------------------------------------- /database/ffldb/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Copyright (c) 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 | /* 7 | Package ffldb implements a driver for the database package that uses leveldb 8 | for the backing metadata and flat files for block storage. 9 | 10 | This driver is the recommended driver for use with hcashd. It makes use leveldb 11 | for the metadata, flat files for block storage, and checksums in key areas to 12 | ensure data integrity. 13 | 14 | Usage 15 | 16 | This package is a driver to the database package and provides the database type 17 | of "ffldb". The parameters the Open and Create functions take are the 18 | database path as a string and the block network: 19 | 20 | db, err := database.Open("ffldb", "path/to/database", wire.MainNet) 21 | if err != nil { 22 | // Handle error 23 | } 24 | 25 | db, err := database.Create("ffldb", "path/to/database", wire.MainNet) 26 | if err != nil { 27 | // Handle error 28 | } 29 | */ 30 | package ffldb 31 | -------------------------------------------------------------------------------- /database/ffldb/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Copyright (c) 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 ffldb 7 | 8 | import ( 9 | "fmt" 10 | 11 | "github.com/btcsuite/btclog" 12 | "github.com/HcashOrg/hcashd/database" 13 | "github.com/HcashOrg/hcashd/wire" 14 | ) 15 | 16 | var log = btclog.Disabled 17 | 18 | const ( 19 | dbType = "ffldb" 20 | ) 21 | 22 | // parseArgs parses the arguments from the database Open/Create methods. 23 | func parseArgs(funcName string, args ...interface{}) (string, wire.CurrencyNet, error) { 24 | if len(args) != 2 { 25 | return "", 0, fmt.Errorf("invalid arguments to %s.%s -- "+ 26 | "expected database path and block network", dbType, 27 | funcName) 28 | } 29 | 30 | dbPath, ok := args[0].(string) 31 | if !ok { 32 | return "", 0, fmt.Errorf("first argument to %s.%s is invalid -- "+ 33 | "expected database path string", dbType, funcName) 34 | } 35 | 36 | network, ok := args[1].(wire.CurrencyNet) 37 | if !ok { 38 | return "", 0, fmt.Errorf("second argument to %s.%s is invalid -- "+ 39 | "expected block network", dbType, funcName) 40 | } 41 | 42 | return dbPath, network, nil 43 | } 44 | 45 | // openDBDriver is the callback provided during driver registration that opens 46 | // an existing database for use. 47 | func openDBDriver(args ...interface{}) (database.DB, error) { 48 | dbPath, network, err := parseArgs("Open", args...) 49 | if err != nil { 50 | return nil, err 51 | } 52 | 53 | return openDB(dbPath, network, false) 54 | } 55 | 56 | // createDBDriver is the callback provided during driver registration that 57 | // creates, initializes, and opens a database for use. 58 | func createDBDriver(args ...interface{}) (database.DB, error) { 59 | dbPath, network, err := parseArgs("Create", args...) 60 | if err != nil { 61 | return nil, err 62 | } 63 | 64 | return openDB(dbPath, network, true) 65 | } 66 | 67 | // useLogger is the callback provided during driver registration that sets the 68 | // current logger to the provided one. 69 | func useLogger(logger btclog.Logger) { 70 | log = logger 71 | } 72 | 73 | func init() { 74 | // Register the driver. 75 | driver := database.Driver{ 76 | DbType: dbType, 77 | Create: createDBDriver, 78 | Open: openDBDriver, 79 | UseLogger: useLogger, 80 | } 81 | if err := database.RegisterDriver(driver); err != nil { 82 | panic(fmt.Sprintf("Failed to regiser database driver '%s': %v", 83 | dbType, err)) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /database/ffldb/export_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Copyright (c) 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 | /* 7 | This test file is part of the ffldb package rather than than the ffldb_test 8 | package so it can bridge access to the internals to properly test cases which 9 | are either not possible or can't reliably be tested via the public interface. 10 | The functions are only exported while the tests are being run. 11 | */ 12 | 13 | package ffldb 14 | 15 | import "github.com/HcashOrg/hcashd/database" 16 | 17 | // TstRunWithMaxBlockFileSize runs the passed function with the maximum allowed 18 | // file size for the database set to the provided value. The value will be set 19 | // back to the original value upon completion. 20 | func TstRunWithMaxBlockFileSize(idb database.DB, size uint32, fn func()) { 21 | ffldb := idb.(*db) 22 | origSize := ffldb.store.maxBlockFileSize 23 | 24 | ffldb.store.maxBlockFileSize = size 25 | fn() 26 | ffldb.store.maxBlockFileSize = origSize 27 | } 28 | -------------------------------------------------------------------------------- /database/ffldb/ldbtreapiter.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Copyright (c) 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 ffldb 7 | 8 | import ( 9 | "github.com/btcsuite/goleveldb/leveldb/iterator" 10 | "github.com/btcsuite/goleveldb/leveldb/util" 11 | "github.com/HcashOrg/hcashd/database/internal/treap" 12 | ) 13 | 14 | // ldbTreapIter wraps a treap iterator to provide the additional functionality 15 | // needed to satisfy the leveldb iterator.Iterator interface. 16 | type ldbTreapIter struct { 17 | *treap.Iterator 18 | tx *transaction 19 | released bool 20 | } 21 | 22 | // Enforce ldbTreapIter implements the leveldb iterator.Iterator interface. 23 | var _ iterator.Iterator = (*ldbTreapIter)(nil) 24 | 25 | // Error is only provided to satisfy the iterator interface as there are no 26 | // errors for this memory-only structure. 27 | // 28 | // This is part of the leveldb iterator.Iterator interface implementation. 29 | func (iter *ldbTreapIter) Error() error { 30 | return nil 31 | } 32 | 33 | // SetReleaser is only provided to satisfy the iterator interface as there is no 34 | // need to override it. 35 | // 36 | // This is part of the leveldb iterator.Iterator interface implementation. 37 | func (iter *ldbTreapIter) SetReleaser(releaser util.Releaser) { 38 | } 39 | 40 | // Release releases the iterator by removing the underlying treap iterator from 41 | // the list of active iterators against the pending keys treap. 42 | // 43 | // This is part of the leveldb iterator.Iterator interface implementation. 44 | func (iter *ldbTreapIter) Release() { 45 | if !iter.released { 46 | iter.tx.removeActiveIter(iter.Iterator) 47 | iter.released = true 48 | } 49 | } 50 | 51 | // newLdbTreapIter creates a new treap iterator for the given slice against the 52 | // pending keys for the passed transaction and returns it wrapped in an 53 | // ldbTreapIter so it can be used as a leveldb iterator. It also adds the new 54 | // iterator to the list of active iterators for the transaction. 55 | func newLdbTreapIter(tx *transaction, slice *util.Range) *ldbTreapIter { 56 | iter := tx.pendingKeys.Iterator(slice.Start, slice.Limit) 57 | tx.addActiveIter(iter) 58 | return &ldbTreapIter{Iterator: iter, tx: tx} 59 | } 60 | -------------------------------------------------------------------------------- /database/internal/treap/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The btcsuite developers 2 | // Copyright (c) 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 | /* 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 29 | -------------------------------------------------------------------------------- /database/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Copyright (c) 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 database 7 | 8 | import ( 9 | "github.com/btcsuite/btclog" 10 | ) 11 | 12 | // log is a logger that is initialized with no output filters. This 13 | // means the package will not perform any logging by default until the caller 14 | // requests it. 15 | var log btclog.Logger 16 | 17 | // The default amount of logging is none. 18 | func init() { 19 | DisableLog() 20 | } 21 | 22 | // DisableLog disables all library log output. Logging output is disabled 23 | // by default until UseLogger is called. 24 | func DisableLog() { 25 | log = btclog.Disabled 26 | } 27 | 28 | // UseLogger uses a specified Logger to output package logging info. 29 | func UseLogger(logger btclog.Logger) { 30 | log = logger 31 | 32 | // Update the logger for the registered drivers. 33 | for _, drv := range drivers { 34 | if drv.UseLogger != nil { 35 | drv.UseLogger(logger) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # `hcashd`: daemon program for `hcash` 2 | 3 | ## Contents 4 | + [Mining](mining.md) 5 | + [Cryptography](crypto.md) 6 | 7 | -------------------------------------------------------------------------------- /docs/configure_peer_server_listen_interfaces.md: -------------------------------------------------------------------------------- 1 | hcashd 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=:14008|all interfaces on port 14008| 18 | |--listen=0.0.0.0:14008|all IPv4 interfaces on port 14008| 19 | |--listen=[::]:14008|all IPv6 interfaces on port 14008| 20 | |--listen=127.0.0.1:14008|only IPv4 localhost on port 14008| 21 | |--listen=[::1]:14008|only IPv6 localhost on port 14008| 22 | |--listen=:8336|all interfaces on non-standard port 8336| 23 | |--listen=0.0.0.0:8336|all IPv4 interfaces on non-standard port 8336| 24 | |--listen=[::]:8336|all IPv6 interfaces on non-standard port 8336| 25 | |--listen=127.0.0.1:8337 --listen=[::1]:14008|IPv4 localhost on port 8337 and IPv6 localhost on port 14008| 26 | |--listen=:14008 --listen=:8337|all interfaces on ports 14008 and 8337| 27 | 28 | The following config file would configure hcashd to only listen on localhost for both IPv4 and IPv6: 29 | 30 | ```text 31 | [Application Options] 32 | 33 | listen=127.0.0.1:14008 34 | listen=[::1]:14008 35 | ``` 36 | -------------------------------------------------------------------------------- /docs/configure_rpc_server_listen_interfaces.md: -------------------------------------------------------------------------------- 1 | hcashd 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=:14009|all interfaces on port 14009| 31 | |--rpclisten=0.0.0.0:14009|all IPv4 interfaces on port 14009| 32 | |--rpclisten=[::]:14009|all IPv6 interfaces on port 14009| 33 | |--rpclisten=127.0.0.1:14009|only IPv4 localhost on port 14009| 34 | |--rpclisten=[::1]:14009|only IPv6 localhost on port 14009| 35 | |--rpclisten=:8336|all interfaces on non-standard port 8336| 36 | |--rpclisten=0.0.0.0:8336|all IPv4 interfaces on non-standard port 8336| 37 | |--rpclisten=[::]:8336|all IPv6 interfaces on non-standard port 8336| 38 | |--rpclisten=127.0.0.1:8337 --listen=[::1]:14009|IPv4 localhost on port 8337 and IPv6 localhost on port 14009| 39 | |--rpclisten=:14009 --listen=:8337|all interfaces on ports 14009 and 8337| 40 | 41 | The following config file would configure the hcashd 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/crypto.md: -------------------------------------------------------------------------------- 1 | # Cryptography 2 | 3 | ## Overview 4 | This section mainly deals with documentation about cryptography in hcashd project, including 5 | + unit tests: reports progress for tests under different packages 6 | + ... 7 | 8 | ## Unit Tests 9 | ### package `hcashec/edwards` 10 | | file | brief | 11 | |-----:|:-----| 12 | | primitives_test.go | conversion among big integers, encoded bytes, field elements and curve points | 13 | | chiphering_test.go | ECDH simulation, encryption/decryption on elliptic curve, error handling | 14 | | ecdsa_benchmark_test.go | benchmarking of signing/verifying | 15 | | ecdsa_test.go | signing/verifying on bad pubkeys and signatures, validates signing/verifying against golden implementation, check key serialization/deserialization | 16 | | curve_test.go | curve points addition/recovery/multiplication | 17 | | threshold_schnorr_test.go | Schnorr threshold signature scheme | 18 | -------------------------------------------------------------------------------- /docs/default_ports.md: -------------------------------------------------------------------------------- 1 | While hcashd 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 | hcashd provides a `--upnp` flag which can be used to automatically map the Hypercash 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 Hypercash 8 | peer-to-peer port should be forwarded unless you specifically want to allow RPC 9 | access to your hcashd from external sources such as in more advanced network 10 | configurations. 11 | 12 | |Name|Port| 13 | |----|----| 14 | |Default Hypercash peer-to-peer port|TCP 14008| 15 | |Default RPC port|TCP 14009| 16 | -------------------------------------------------------------------------------- /docs/images/block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HcashOrg/hcashd/ebc2982e38702b690eedc15f10a78f29426d3d65/docs/images/block.png -------------------------------------------------------------------------------- /docs/images/research/probability-of-successful-attacks-under-alpha-hashing-power-and-beta-stake-rate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HcashOrg/hcashd/ebc2982e38702b690eedc15f10a78f29426d3d65/docs/images/research/probability-of-successful-attacks-under-alpha-hashing-power-and-beta-stake-rate.png -------------------------------------------------------------------------------- /docs/images/research/the-schematic-framework-of-our-consensus-scheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HcashOrg/hcashd/ebc2982e38702b690eedc15f10a78f29426d3d65/docs/images/research/the-schematic-framework-of-our-consensus-scheme.png -------------------------------------------------------------------------------- /docs/mining.md: -------------------------------------------------------------------------------- 1 | # Mining 2 | While working on some PoW, `hcashd` actually tries to build a block out of a prepared `BlockTemplate` consisting of 3 | 4 | + `Block`: block header + plain txs + stake txs 5 | + `Fee`: tx fees vector paid by each tx in `Block` 6 | + `SigOpCounts`: TBC 7 | + `Height`: block height of current block 8 | + `KeyHeight`: number of key blocks before current block 9 | + `ValidPayAddress`: TBC 10 | + `GenerateKey`: TBC 11 | 12 | ## `Block` 13 | The structure of `Block` go as follows figure 14 | ![block structure](images/block.png) 15 | 16 | ## Unit Tests 17 | Work on progress 18 | + [x] tx priority queue in `mining_test.go` 19 | -------------------------------------------------------------------------------- /docs/post_quantum_api.md: -------------------------------------------------------------------------------- 1 | # Hcashd Post quantum API 2 | 3 | ## Bliss algorithm 4 | 5 | #### location: crypto/bliss/bliss.go 6 | 7 | ``` 8 | func (sp blissDSA) GenerateKey(rand io.Reader) (hcashcrypto.PrivateKey, hcashcrypto.PublicKey, 9 | error) { 10 | return sp.generateKey(rand) 11 | } 12 | func (sp blissDSA) Sign(priv hcashcrypto.PrivateKey, hash []byte) (hcashcrypto.Signature, error) { 13 | return sp.sign(priv, hash) 14 | } 15 | func (sp blissDSA) Verify(pub hcashcrypto.PublicKey, hash []byte, sig hcashcrypto.Signature) bool { 16 | return sp.verify(pub, hash, sig) 17 | } 18 | ``` 19 | 20 | ## LMS algorithm 21 | 22 | ####location: crypto/lms/lms.go 23 | 24 | ``` 25 | func (sp lmsDSA) GenerateKey(rand io.Reader) (hcashcrypto.PrivateKey, hcashcrypto.PublicKey, 26 | error) { 27 | return sp.generateKey(rand) 28 | } 29 | func (sp lmsDSA) Sign(priv hcashcrypto.PrivateKey, hash []byte) (hcashcrypto.Signature, error) { 30 | return sp.sign(priv, hash) 31 | } 32 | func (sp lmsDSA) Verify(pub hcashcrypto.PublicKey, hash []byte, sig hcashcrypto.Signature) bool { 33 | return sp.verify(pub, hash, sig) 34 | } 35 | ``` 36 | 37 | 38 | 39 | 40 | 41 | # Post quantuam library API 42 | 43 | ## Bliss Algorithm 44 | 45 | #### Github: https://github.com/LoCCS/bliss 46 | 47 | #### location: key.go 48 | 49 | ```` 50 | func GeneratePrivateKey(version int, entropy *sampler.Entropy) (*PrivateKey, error) { 51 | ... 52 | } 53 | ```` 54 | 55 | #### location: sign.go 56 | 57 | ``` 58 | func GeneratePrivateKey(version int, entropy *sampler.Entropy) (*PrivateKey, error) { 59 | ... 60 | } 61 | 62 | func (key *PublicKey) Verify(msg []byte, sig *Signature) (bool, error) { 63 | ... 64 | } 65 | ``` 66 | 67 | 68 | 69 | ## LMS Algorithm 70 | 71 | #### Github: https://github.com/LoCCS/lms 72 | 73 | It is different from Bliss or ECDSA that LMS doesn't hava GeneratePrivateKey function. 74 | 75 | #### location: lms.go 76 | 77 | ``` 78 | func Sign(agent *MerkleAgent, hash []byte) (*lmots.PrivateKey, *MerkleSig, error) { 79 | ... 80 | } 81 | 82 | func Verify(root []byte, hash []byte, merkleSig *MerkleSig) bool { 83 | ... 84 | } 85 | ``` 86 | 87 | -------------------------------------------------------------------------------- /docs/research/post-quantum-signature-schemes-in-hcash.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HcashOrg/hcashd/ebc2982e38702b690eedc15f10a78f29426d3d65/docs/research/post-quantum-signature-schemes-in-hcash.pdf -------------------------------------------------------------------------------- /glide.lock: -------------------------------------------------------------------------------- 1 | hash: 02b5fdef2023f27917fe15c8bb3c3113a8a1ed7e593f395d83d2b7ea7f28a9ce 2 | updated: 2018-01-24T11:50:30.361722582+08:00 3 | imports: 4 | - name: github.com/agl/ed25519 5 | version: 5312a61534124124185d41f09206b9fef1d88403 6 | subpackages: 7 | - edwards25519 8 | - name: github.com/btcsuite/btclog 9 | version: 84c8d2346e9fc8c7b947e243b9c24e6df9fd206a 10 | - name: github.com/btcsuite/go-socks 11 | version: 4720035b7bfd2a9bb130b1c184f8bbe41b6f0d0f 12 | subpackages: 13 | - socks 14 | - name: github.com/btcsuite/goleveldb 15 | version: 7834afc9e8cd15233b6c3d97e12674a31ca24602 16 | subpackages: 17 | - leveldb 18 | - leveldb/cache 19 | - leveldb/comparer 20 | - leveldb/errors 21 | - leveldb/filter 22 | - leveldb/iterator 23 | - leveldb/journal 24 | - leveldb/memdb 25 | - leveldb/opt 26 | - leveldb/storage 27 | - leveldb/table 28 | - leveldb/util 29 | - name: github.com/btcsuite/snappy-go 30 | version: 0bdef8d067237991ddaa1bb6072a740bc40601ba 31 | - name: github.com/btcsuite/websocket 32 | version: 31079b6807923eb23992c421b114992b95131b55 33 | - name: github.com/btcsuite/winsvc 34 | version: f8fb11f83f7e860e3769a08e6811d1b399a43722 35 | subpackages: 36 | - eventlog 37 | - mgr 38 | - registry 39 | - svc 40 | - winapi 41 | - name: github.com/davecgh/go-spew 42 | version: ecdeabc65495df2dec95d7c4a4c3e021903035e5 43 | subpackages: 44 | - spew 45 | - name: github.com/dchest/blake256 46 | version: dee3fe6eb0e98dc774a94fc231f85baf7c29d360 47 | - name: github.com/HcashOrg/bitset 48 | version: 3b5f0c752dfbeeda856fd6af60e997257ca399fc 49 | - name: github.com/HcashOrg/hcashrpcclient 50 | version: ba3a18d6f9f2432068473bc8665bcb92045a3650 51 | - name: github.com/HcashOrg/hcashutil 52 | version: 0f46aaecda89f2784eda4549bf09e25be2f268b5 53 | subpackages: 54 | - base58 55 | - bloom 56 | - hdkeychain 57 | - name: github.com/jessevdk/go-flags 58 | version: 96dc06278ce32a0e9d957d590bb987c81ee66407 59 | - name: github.com/jrick/logrotate 60 | version: a93b200c26cbae3bb09dd0dc2c7c7fe1468a034a 61 | subpackages: 62 | - rotator 63 | - name: github.com/LoCCS/bliss 64 | version: ff6e5ed7483bbd2ad67146db5ceebf70b1b9e7bd 65 | subpackages: 66 | - huffman 67 | - params 68 | - poly 69 | - sampler 70 | - name: github.com/LoCCS/lmots 71 | version: f542ff0360776b396a6c50575ed89596e6eb3f93 72 | subpackages: 73 | - hash 74 | - rand 75 | - name: github.com/LoCCS/lms 76 | version: ec46abb5d7b5f0e6566ed518b026c8b92fb11563 77 | subpackages: 78 | - container/stack 79 | - name: golang.org/x/crypto 80 | version: 3d37316aaa6bd9929127ac9a527abf408178ea7b 81 | subpackages: 82 | - ripemd160 83 | - sha3 84 | - ssh/terminal 85 | - name: golang.org/x/sys 86 | version: af50095a40f9041b3b38960738837185c26e9419 87 | subpackages: 88 | - unix 89 | - windows 90 | testImports: [] 91 | -------------------------------------------------------------------------------- /glide.yaml: -------------------------------------------------------------------------------- 1 | package: github.com/HcashOrg/hcashd 2 | import: 3 | - package: github.com/agl/ed25519 4 | subpackages: 5 | - edwards25519 6 | - package: github.com/btcsuite/btclog 7 | - package: github.com/jessevdk/go-flags 8 | version: ^v1.3.0 9 | - package: github.com/btcsuite/go-socks 10 | subpackages: 11 | - socks 12 | - package: github.com/btcsuite/goleveldb 13 | subpackages: 14 | - leveldb 15 | - leveldb/comparer 16 | - leveldb/errors 17 | - leveldb/filter 18 | - leveldb/iterator 19 | - leveldb/opt 20 | - leveldb/util 21 | - package: github.com/btcsuite/websocket 22 | - package: github.com/btcsuite/winsvc 23 | subpackages: 24 | - eventlog 25 | - mgr 26 | - svc 27 | - package: github.com/davecgh/go-spew 28 | subpackages: 29 | - spew 30 | - package: github.com/dchest/blake256 31 | - package: github.com/HcashOrg/bitset 32 | - package: github.com/HcashOrg/hcashrpcclient 33 | version: dev 34 | - package: github.com/HcashOrg/hcashutil 35 | version: dev 36 | subpackages: 37 | - bloom 38 | - hdkeychain 39 | - package: github.com/jrick/logrotate 40 | subpackages: 41 | - rotator 42 | - package: golang.org/x/crypto 43 | subpackages: 44 | - ripemd160 45 | - ssh/terminal 46 | - package: github.com/LoCCS/bliss 47 | - package: github.com/LoCCS/lmots 48 | version: ^v1.5 49 | - package: github.com/LoCCS/lms 50 | version: ^v1.5 -------------------------------------------------------------------------------- /hcashec/edwards/const.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The Decred 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 edwards 6 | 7 | import ( 8 | "math/big" 9 | 10 | "github.com/agl/ed25519/edwards25519" 11 | ) 12 | 13 | var ( 14 | // zero through eight are big.Int numbers useful in 15 | // elliptical curve math. 16 | zero = new(big.Int).SetInt64(0) 17 | one = new(big.Int).SetInt64(1) 18 | two = new(big.Int).SetInt64(2) 19 | three = new(big.Int).SetInt64(3) 20 | four = new(big.Int).SetInt64(4) 21 | eight = new(big.Int).SetInt64(8) 22 | 23 | // fieldIntSize is the size of a field element encoded 24 | // as bytes. 25 | fieldIntSize = 32 26 | ) 27 | 28 | // feOne is the field element representation of one. This is 29 | // also the neutral (null) element. 30 | var feOne = edwards25519.FieldElement{ 31 | 1, 0, 0, 0, 0, 32 | 0, 0, 0, 0, 0, 33 | } 34 | 35 | // feA is the field element representation of one. 36 | var feA = edwards25519.FieldElement{ 37 | 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38 | } 39 | 40 | // fed is the field element representation of D. 41 | var fed = edwards25519.FieldElement{ 42 | -10913610, 13857413, -15372611, 6949391, 114729, 43 | -8787816, -6275908, -3247719, -18696448, -12055116, 44 | } 45 | 46 | // fed2 is the field element representation of D^2. 47 | var fed2 = edwards25519.FieldElement{ 48 | -21827239, -5839606, -30745221, 13898782, 229458, 49 | 15978800, -12551817, -6495438, 29715968, 9444199, 50 | } 51 | 52 | // feI is the field element representation of I. 53 | var feI = edwards25519.FieldElement{ 54 | -32595792, -7943725, 9377950, 3500415, 12389472, 55 | -272473, -25146209, -2005654, 326686, 11406482, 56 | } 57 | -------------------------------------------------------------------------------- /hcashec/edwards/ecdsa_benchmark_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The Decred developers 2 | // Copyright (c) 2017-2018 The Hcash developers@sammietocat 3 | // Use of this source code is governed by an ISC 4 | // license that can be found in the LICENSE file. 5 | 6 | package edwards 7 | 8 | import ( 9 | "math/rand" 10 | "testing" 11 | ) 12 | 13 | // BenchmarkSigning benchmarks the signing operation of ECC on TwistedEdwardsCurve 14 | func BenchmarkSigning(b *testing.B) { 15 | curve := new(TwistedEdwardsCurve) 16 | curve.InitParam25519() 17 | 18 | r := rand.New(rand.NewSource(54321)) 19 | msg := []byte{ 20 | 0xbe, 0x13, 0xae, 0xf4, 21 | 0xe8, 0xa2, 0x00, 0xb6, 22 | 0x45, 0x81, 0xc4, 0xd1, 23 | 0x0c, 0xf4, 0x1b, 0x5b, 24 | 0xe1, 0xd1, 0x81, 0xa7, 25 | 0xd3, 0xdc, 0x37, 0x55, 26 | 0x58, 0xc1, 0xbd, 0xa2, 27 | 0x98, 0x2b, 0xd9, 0xfb, 28 | } 29 | 30 | numKeys := 1024 31 | secKeys := mockUpSecKeysByBytes(curve, numKeys) 32 | 33 | for n := 0; n < b.N; n++ { 34 | randIndex := r.Intn(numKeys - 1) 35 | //_, _, err := Sign(curve, privKeyList[randIndex], msg) 36 | _, _, err := Sign(curve, secKeys[randIndex], msg) 37 | if err != nil { 38 | panic("sign failure") 39 | } 40 | } 41 | } 42 | 43 | // BenchmarkSigningNonStandard benchmarks signing operations 44 | // with secret keys derived random scalar 45 | func BenchmarkSigningNonStandard(b *testing.B) { 46 | curve := new(TwistedEdwardsCurve) 47 | curve.InitParam25519() 48 | 49 | r := rand.New(rand.NewSource(54321)) 50 | msg := []byte{ 51 | 0xbe, 0x13, 0xae, 0xf4, 52 | 0xe8, 0xa2, 0x00, 0xb6, 53 | 0x45, 0x81, 0xc4, 0xd1, 54 | 0x0c, 0xf4, 0x1b, 0x5b, 55 | 0xe1, 0xd1, 0x81, 0xa7, 56 | 0xd3, 0xdc, 0x37, 0x55, 57 | 0x58, 0xc1, 0xbd, 0xa2, 58 | 0x98, 0x2b, 0xd9, 0xfb, 59 | } 60 | 61 | numKeys := 250 62 | privKeyList := mockUpSecKeysByScalars(curve, numKeys) 63 | 64 | for n := 0; n < b.N; n++ { 65 | randIndex := r.Intn(numKeys - 1) 66 | _, _, err := Sign(curve, privKeyList[randIndex], msg) 67 | if err != nil { 68 | panic("sign failure") 69 | } 70 | } 71 | } 72 | 73 | // BenchmarkVerification benchmarks the verification operations 74 | // on TwistedEdwardsCurve 75 | func BenchmarkVerification(b *testing.B) { 76 | curve := new(TwistedEdwardsCurve) 77 | curve.InitParam25519() 78 | r := rand.New(rand.NewSource(54321)) 79 | 80 | numSigs := 1024 81 | sigList := mockUpSigList(curve, numSigs) 82 | 83 | for n := 0; n < b.N; n++ { 84 | randIndex := r.Intn(numSigs - 1) 85 | 86 | if !Verify(sigList[randIndex].pubkey, 87 | sigList[randIndex].msg, 88 | sigList[randIndex].sig.R, 89 | sigList[randIndex].sig.S) { 90 | 91 | b.Fatalf("verification on %s with pubkey=%s,r=%v,s=%v", 92 | sigList[randIndex].msg, 93 | sigList[randIndex].pubkey, 94 | *sigList[randIndex].sig.R, 95 | *sigList[randIndex].sig.S) 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /hcashec/edwards/testdata/addpoints.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from ed25519 import * 3 | 4 | s1 = sys.argv[1].decode("hex") 5 | P1 = decodepoint(s1) 6 | 7 | s2 = sys.argv[2].decode("hex") 8 | P2 = decodepoint(s2) 9 | 10 | P = edwards(P1, P2) 11 | encodepointhex(P) 12 | -------------------------------------------------------------------------------- /hcashec/edwards/testdata/decodeint.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from ed25519 import * 3 | 4 | decodeinthex(sys.argv[1]) 5 | -------------------------------------------------------------------------------- /hcashec/edwards/testdata/decodepoint.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from ed25519 import * 3 | 4 | decodepointhex(sys.argv[1]) 5 | 6 | -------------------------------------------------------------------------------- /hcashec/edwards/testdata/encodeint.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from ed25519 import * 3 | 4 | encodeinthex(int(sys.argv[1])) 5 | -------------------------------------------------------------------------------- /hcashec/edwards/testdata/encodepoint.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from ed25519 import * 3 | 4 | P = [] 5 | x = int(sys.argv[1]) 6 | P.append(x) 7 | y = int(sys.argv[2]) 8 | P.append(y) 9 | encodepointhex(P) 10 | -------------------------------------------------------------------------------- /hcashec/edwards/testdata/genscalarmult.py: -------------------------------------------------------------------------------- 1 | import os 2 | from ed25519 import * 3 | 4 | f = open("scalarmulttests.dat",'w') 5 | 6 | numTests = 50 7 | for i in range(0,numTests): 8 | rand_string = os.urandom(32) 9 | try: 10 | p = decodepoint(rand_string) 11 | except: 12 | continue 13 | rand_string = os.urandom(32) 14 | s = decodeint(rand_string) 15 | 16 | mult = scalarmult(p, s) 17 | 18 | f.write("ScalarMultVectorHex{") 19 | # Point to multiply 20 | f.write('\"') 21 | f.write("".join("{:02x}".format(ord(c)) for c in encodepoint(p))) 22 | f.write('\"') 23 | f.write(',') 24 | # Scalar to multiply by 25 | f.write('\"') 26 | f.write("".join("{:02x}".format(ord(c)) for c in encodeint(s))) 27 | f.write('\"') 28 | f.write(',') 29 | # Resulting point 30 | f.write('\"') 31 | f.write("".join("{:02x}".format(ord(c)) for c in encodepoint(mult))) 32 | f.write('\"') 33 | f.write('},\n') 34 | 35 | f.close() 36 | -------------------------------------------------------------------------------- /hcashec/edwards/testdata/sign.input.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HcashOrg/hcashd/ebc2982e38702b690eedc15f10a78f29426d3d65/hcashec/edwards/testdata/sign.input.gz -------------------------------------------------------------------------------- /hcashec/secp256k1/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 | /* 7 | Package secp256k1 implements support for the elliptic curves needed for hypercash. 8 | 9 | Hypercash uses elliptic curve cryptography using koblitz curves 10 | (specifically secp256k1) for cryptographic functions. See 11 | http://www.secg.org/collateral/sec2_final.pdf for details on the 12 | standard. 13 | 14 | This package provides the data structures and functions implementing the 15 | crypto/elliptic Curve interface in order to permit using these curves 16 | with the standard crypto/ecdsa package provided with go. Helper 17 | functionality is provided to parse signatures and public keys from 18 | standard formats. It was designed for use with hcashd, but should be 19 | general enough for other uses of elliptic curve crypto. It was originally based 20 | on some initial work by ThePiachu, but has significantly diverged since then. 21 | */ 22 | package secp256k1 23 | -------------------------------------------------------------------------------- /hcashec/secp256k1/genprecomps.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 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 | // This file is ignored during the regular build due to the following build tag. 7 | // It is called by go generate and used to automatically generate pre-computed 8 | // tables used to accelerate operations. 9 | // +build ignore 10 | 11 | package main 12 | 13 | import ( 14 | "bytes" 15 | "compress/zlib" 16 | "encoding/base64" 17 | "fmt" 18 | "log" 19 | "os" 20 | 21 | "github.com/HcashOrg/hcashd/hcashec/secp256k1" 22 | ) 23 | 24 | func main() { 25 | fi, err := os.Create("secp256k1.go") 26 | if err != nil { 27 | log.Fatal(err) 28 | } 29 | defer fi.Close() 30 | 31 | // Compress the serialized byte points. 32 | serialized := secp256k1.S256().SerializedBytePoints() 33 | var compressed bytes.Buffer 34 | w := zlib.NewWriter(&compressed) 35 | if _, err := w.Write(serialized); err != nil { 36 | fmt.Println(err) 37 | os.Exit(1) 38 | } 39 | w.Close() 40 | 41 | // Encode the compressed byte points with base64. 42 | encoded := make([]byte, base64.StdEncoding.EncodedLen(compressed.Len())) 43 | base64.StdEncoding.Encode(encoded, compressed.Bytes()) 44 | 45 | fmt.Fprintln(fi, "// Copyright (c) 2015 The btcsuite developers") 46 | fmt.Fprintln(fi, "// Use of this source code is governed by an ISC") 47 | fmt.Fprintln(fi, "// license that can be found in the LICENSE file.") 48 | fmt.Fprintln(fi) 49 | fmt.Fprintln(fi, "package secp256k1") 50 | fmt.Fprintln(fi) 51 | fmt.Fprintln(fi, "// Auto-generated file (see genprecomps.go)") 52 | fmt.Fprintln(fi, "// DO NOT EDIT") 53 | fmt.Fprintln(fi) 54 | fmt.Fprintf(fi, "var secp256k1BytePoints = %q\n", string(encoded)) 55 | 56 | a1, b1, a2, b2 := secp256k1.S256().EndomorphismVectors() 57 | fmt.Println("The following values are the computed linearly " + 58 | "independent vectors needed to make use of the secp256k1 " + 59 | "endomorphism:") 60 | fmt.Printf("a1: %x\n", a1) 61 | fmt.Printf("b1: %x\n", b1) 62 | fmt.Printf("a2: %x\n", a2) 63 | fmt.Printf("b2: %x\n", b2) 64 | } 65 | -------------------------------------------------------------------------------- /hcashec/secp256k1/precompute.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 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 secp256k1 7 | 8 | import ( 9 | "compress/zlib" 10 | "encoding/base64" 11 | "encoding/binary" 12 | "io/ioutil" 13 | "strings" 14 | ) 15 | 16 | //go:generate go run -tags gensecp256k1 genprecomps.go 17 | 18 | // loadS256BytePoints decompresses and deserializes the pre-computed byte points 19 | // used to accelerate scalar base multiplication for the secp256k1 curve. This 20 | // approach is used since it allows the compile to use significantly less ram 21 | // and be performed much faster than it is with hard-coding the final in-memory 22 | // data structure. At the same time, it is quite fast to generate the in-memory 23 | // data structure at init time with this approach versus computing the table. 24 | func loadS256BytePoints() error { 25 | // There will be no byte points to load when generating them. 26 | bp := secp256k1BytePoints 27 | if len(bp) == 0 { 28 | return nil 29 | } 30 | 31 | // Decompress the pre-computed table used to accelerate scalar base 32 | // multiplication. 33 | decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(bp)) 34 | r, err := zlib.NewReader(decoder) 35 | if err != nil { 36 | return err 37 | } 38 | serialized, err := ioutil.ReadAll(r) 39 | if err != nil { 40 | return err 41 | } 42 | 43 | // Deserialize the precomputed byte points and set the curve to them. 44 | offset := 0 45 | var bytePoints [32][256][3]fieldVal 46 | for byteNum := 0; byteNum < 32; byteNum++ { 47 | // All points in this window. 48 | for i := 0; i < 256; i++ { 49 | px := &bytePoints[byteNum][i][0] 50 | py := &bytePoints[byteNum][i][1] 51 | pz := &bytePoints[byteNum][i][2] 52 | for i := 0; i < 10; i++ { 53 | px.n[i] = binary.LittleEndian.Uint32(serialized[offset:]) 54 | offset += 4 55 | } 56 | for i := 0; i < 10; i++ { 57 | py.n[i] = binary.LittleEndian.Uint32(serialized[offset:]) 58 | offset += 4 59 | } 60 | for i := 0; i < 10; i++ { 61 | pz.n[i] = binary.LittleEndian.Uint32(serialized[offset:]) 62 | offset += 4 63 | } 64 | } 65 | } 66 | secp256k1.bytePoints = &bytePoints 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /hcashec/secp256k1/privkey_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 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 secp256k1 7 | 8 | import ( 9 | "bytes" 10 | "testing" 11 | ) 12 | 13 | func TestPrivKeys(t *testing.T) { 14 | tests := []struct { 15 | name string 16 | key []byte 17 | }{ 18 | { 19 | name: "check curve", 20 | key: []byte{ 21 | 0xea, 0xf0, 0x2c, 0xa3, 0x48, 0xc5, 0x24, 0xe6, 22 | 0x39, 0x26, 0x55, 0xba, 0x4d, 0x29, 0x60, 0x3c, 23 | 0xd1, 0xa7, 0x34, 0x7d, 0x9d, 0x65, 0xcf, 0xe9, 24 | 0x3c, 0xe1, 0xeb, 0xff, 0xdc, 0xa2, 0x26, 0x94, 25 | }, 26 | }, 27 | } 28 | 29 | for _, test := range tests { 30 | priv, pub := PrivKeyFromBytes(S256(), test.key) 31 | 32 | _, err := ParsePubKey(pub.SerializeUncompressed(), S256()) 33 | if err != nil { 34 | t.Errorf("%s privkey: %v", test.name, err) 35 | continue 36 | } 37 | 38 | hash := []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9} 39 | sig, err := priv.Sign(hash) 40 | if err != nil { 41 | t.Errorf("%s could not sign: %v", test.name, err) 42 | continue 43 | } 44 | 45 | if !sig.Verify(hash, pub) { 46 | t.Errorf("%s could not verify: %v", test.name, err) 47 | continue 48 | } 49 | 50 | serializedKey := priv.Serialize() 51 | if !bytes.Equal(serializedKey, test.key) { 52 | t.Errorf("%s unexpected serialized bytes - got: %x, "+ 53 | "want: %x", test.name, serializedKey, test.key) 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /hcashec/secp256k1/schnorr/primitives.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 The Decred 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 schnorr 6 | 7 | import ( 8 | "math/big" 9 | ) 10 | 11 | // copyBytes copies a byte slice to a 32 byte array. 12 | func copyBytes(aB []byte) *[32]byte { 13 | if aB == nil { 14 | return nil 15 | } 16 | s := new([32]byte) 17 | 18 | // If we have a short byte string, expand 19 | // it so that it's long enough. 20 | aBLen := len(aB) 21 | if aBLen < scalarSize { 22 | diff := scalarSize - aBLen 23 | for i := 0; i < diff; i++ { 24 | aB = append([]byte{0x00}, aB...) 25 | } 26 | } 27 | 28 | for i := 0; i < scalarSize; i++ { 29 | s[i] = aB[i] 30 | } 31 | 32 | return s 33 | } 34 | 35 | // BigIntToEncodedBytes converts a big integer into its corresponding 36 | // 32 byte little endian representation. 37 | func BigIntToEncodedBytes(a *big.Int) *[32]byte { 38 | s := new([32]byte) 39 | if a == nil { 40 | return s 41 | } 42 | // Caveat: a can be longer than 32 bytes. 43 | aB := a.Bytes() 44 | 45 | // If we have a short byte string, expand 46 | // it so that it's long enough. 47 | aBLen := len(aB) 48 | if aBLen < scalarSize { 49 | diff := scalarSize - aBLen 50 | for i := 0; i < diff; i++ { 51 | aB = append([]byte{0x00}, aB...) 52 | } 53 | } 54 | 55 | for i := 0; i < scalarSize; i++ { 56 | s[i] = aB[i] 57 | } 58 | 59 | return s 60 | } 61 | 62 | // EncodedBytesToBigInt converts a 32 byte big endian representation of 63 | // an integer into a big integer. 64 | func EncodedBytesToBigInt(s *[32]byte) *big.Int { 65 | // Use a copy so we don't screw up our original 66 | // memory. 67 | sCopy := new([32]byte) 68 | for i := 0; i < scalarSize; i++ { 69 | sCopy[i] = s[i] 70 | } 71 | 72 | bi := new(big.Int).SetBytes(sCopy[:]) 73 | 74 | return bi 75 | } 76 | -------------------------------------------------------------------------------- /hcashec/secp256k1/schnorr/pubkey.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 schnorr 7 | 8 | import ( 9 | "fmt" 10 | 11 | "github.com/HcashOrg/hcashd/hcashec/secp256k1" 12 | ) 13 | 14 | // These constants define the lengths of serialized public keys. 15 | const ( 16 | PubKeyBytesLen = 33 17 | ) 18 | 19 | const ( 20 | // pubkeyCompressed is the header byte for a compressed secp256k1 pubkey. 21 | pubkeyCompressed byte = 0x2 // y_bit + x coord 22 | ) 23 | 24 | // ParsePubKey parses a public key for a koblitz curve from a bytestring into a 25 | // ecdsa.Publickey, verifying that it is valid. It supports compressed, 26 | // uncompressed and hybrid signature formats. 27 | func ParsePubKey(curve *secp256k1.KoblitzCurve, 28 | pubKeyStr []byte) (key *secp256k1.PublicKey, err error) { 29 | if pubKeyStr == nil { 30 | err = fmt.Errorf("nil pubkey byte string") 31 | return 32 | } 33 | if len(pubKeyStr) != PubKeyBytesLen { 34 | err = fmt.Errorf("bad pubkey byte string size (want %v, have %v)", 35 | PubKeyBytesLen, len(pubKeyStr)) 36 | return 37 | } 38 | format := pubKeyStr[0] 39 | format &= ^byte(0x1) 40 | if format != pubkeyCompressed { 41 | err = fmt.Errorf("wrong pubkey type (not compressed)") 42 | return 43 | } 44 | 45 | return secp256k1.ParsePubKey(pubKeyStr, curve) 46 | } 47 | -------------------------------------------------------------------------------- /hcashec/secp256k1/schnorr/signature.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 schnorr 7 | 8 | import ( 9 | "fmt" 10 | "math/big" 11 | ) 12 | 13 | // Signature is a type representing a Schnorr signature. 14 | type Signature struct { 15 | R *big.Int 16 | S *big.Int 17 | } 18 | 19 | // SignatureSize is the size of an encoded Schnorr signature. 20 | const SignatureSize = 64 21 | 22 | // NewSignature instantiates a new signature given some R,S values. 23 | func NewSignature(r, s *big.Int) *Signature { 24 | return &Signature{r, s} 25 | } 26 | 27 | // Serialize returns the Schnorr signature in the more strict format. 28 | // 29 | // The signatures are encoded as 30 | // sig[0:32] R, a point encoded as big endian 31 | // sig[32:64] S, scalar multiplication/addition results = (ab+c) mod l 32 | // encoded also as big endian 33 | func (sig Signature) Serialize() []byte { 34 | rBytes := BigIntToEncodedBytes(sig.R) 35 | sBytes := BigIntToEncodedBytes(sig.S) 36 | 37 | all := append(rBytes[:], sBytes[:]...) 38 | 39 | return all 40 | } 41 | 42 | func parseSig(sigStr []byte) (*Signature, error) { 43 | if len(sigStr) != SignatureSize { 44 | return nil, fmt.Errorf("bad signature size; have %v, want %v", 45 | len(sigStr), SignatureSize) 46 | } 47 | 48 | rBytes := copyBytes(sigStr[0:32]) 49 | r := EncodedBytesToBigInt(rBytes) 50 | sBytes := copyBytes(sigStr[32:64]) 51 | s := EncodedBytesToBigInt(sBytes) 52 | 53 | return &Signature{r, s}, nil 54 | } 55 | 56 | // ParseSignature parses a signature in BER format for the curve type `curve' 57 | // into a Signature type, perfoming some basic sanity checks. 58 | func ParseSignature(sigStr []byte) (*Signature, error) { 59 | return parseSig(sigStr) 60 | } 61 | 62 | // GetR satisfies the chainec PublicKey interface. 63 | func (sig Signature) GetR() *big.Int { 64 | return sig.R 65 | } 66 | 67 | // GetS satisfies the chainec PublicKey interface. 68 | func (sig Signature) GetS() *big.Int { 69 | return sig.S 70 | } 71 | 72 | // GetType satisfies the chainec Signature interface. 73 | func (sig Signature) GetType() int { 74 | return ecTypeSecSchnorr 75 | } 76 | -------------------------------------------------------------------------------- /hcashjson/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 | -------------------------------------------------------------------------------- /hcashjson/btcwalletextcmds.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 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 | // NOTE: This file is intended to house the RPC commands that are supported by 7 | // a wallet server with btcwallet extensions. 8 | 9 | package hcashjson 10 | 11 | // CreateNewAccountCmd defines the createnewaccount JSON-RPC command. 12 | type CreateNewAccountCmd struct { 13 | Account string 14 | AccountType string 15 | } 16 | 17 | // NewCreateNewAccountCmd returns a new instance which can be used to issue a 18 | // createnewaccount JSON-RPC command. 19 | func NewCreateNewAccountCmd(account string, acctype string) *CreateNewAccountCmd { 20 | return &CreateNewAccountCmd{ 21 | Account: account, 22 | AccountType: acctype, 23 | } 24 | } 25 | 26 | // ImportAddressCmd defines the importaddress JSON-RPC command. 27 | type ImportAddressCmd struct { 28 | Address string 29 | Rescan *bool `jsonrpcdefault:"true"` 30 | } 31 | 32 | // NewImportAddressCmd returns a new instance which can be used to issue an 33 | // importaddress JSON-RPC command. 34 | func NewImportAddressCmd(address string, rescan *bool) *ImportAddressCmd { 35 | return &ImportAddressCmd{ 36 | Address: address, 37 | Rescan: rescan, 38 | } 39 | } 40 | 41 | // ImportPubKeyCmd defines the importpubkey JSON-RPC command. 42 | type ImportPubKeyCmd struct { 43 | PubKey string 44 | Rescan *bool `jsonrpcdefault:"true"` 45 | } 46 | 47 | // NewImportPubKeyCmd returns a new instance which can be used to issue an 48 | // importpubkey JSON-RPC command. 49 | func NewImportPubKeyCmd(pubKey string, rescan *bool) *ImportPubKeyCmd { 50 | return &ImportPubKeyCmd{ 51 | PubKey: pubKey, 52 | Rescan: rescan, 53 | } 54 | } 55 | 56 | // RenameAccountCmd defines the renameaccount JSON-RPC command. 57 | type RenameAccountCmd struct { 58 | OldAccount string 59 | NewAccount string 60 | } 61 | 62 | // NewRenameAccountCmd returns a new instance which can be used to issue a 63 | // renameaccount JSON-RPC command. 64 | func NewRenameAccountCmd(oldAccount, newAccount string) *RenameAccountCmd { 65 | return &RenameAccountCmd{ 66 | OldAccount: oldAccount, 67 | NewAccount: newAccount, 68 | } 69 | } 70 | 71 | func init() { 72 | // The commands in this file are only usable with a wallet server. 73 | flags := UFWalletOnly 74 | 75 | MustRegisterCmd("createnewaccount", (*CreateNewAccountCmd)(nil), flags) 76 | MustRegisterCmd("importaddress", (*ImportAddressCmd)(nil), flags) 77 | MustRegisterCmd("importpubkey", (*ImportPubKeyCmd)(nil), flags) 78 | MustRegisterCmd("renameaccount", (*RenameAccountCmd)(nil), flags) 79 | } 80 | -------------------------------------------------------------------------------- /hcashjson/chainsvrresults_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 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 hcashjson_test 7 | 8 | import ( 9 | "encoding/json" 10 | "testing" 11 | 12 | "github.com/HcashOrg/hcashd/hcashjson" 13 | ) 14 | 15 | // TestChainSvrCustomResults ensures any results that have custom marshalling 16 | // work as inteded. 17 | // and unmarshal code of results are as expected. 18 | func TestChainSvrCustomResults(t *testing.T) { 19 | t.Parallel() 20 | 21 | tests := []struct { 22 | name string 23 | result interface{} 24 | expected string 25 | }{ 26 | { 27 | name: "custom vin marshal with coinbase", 28 | result: &hcashjson.Vin{ 29 | Coinbase: "021234", 30 | Sequence: 4294967295, 31 | }, 32 | expected: `{"amountin":0,"blockheight":0,"blockindex":0,"coinbase":"021234","sequence":4294967295}`, 33 | }, 34 | { 35 | name: "custom vin marshal without coinbase", 36 | result: &hcashjson.Vin{ 37 | Txid: "123", 38 | Vout: 1, 39 | Tree: 0, 40 | ScriptSig: &hcashjson.ScriptSig{ 41 | Asm: "0", 42 | Hex: "00", 43 | }, 44 | Sequence: 4294967295, 45 | }, 46 | expected: `{"txid":"123","vout":1,"tree":0,"sequence":4294967295,"amountin":0,"blockheight":0,"blockindex":0,"scriptSig":{"asm":"0","hex":"00"}}`, 47 | }, 48 | { 49 | name: "custom vinprevout marshal with coinbase", 50 | result: &hcashjson.VinPrevOut{ 51 | Coinbase: "021234", 52 | Sequence: 4294967295, 53 | }, 54 | expected: `{"coinbase":"021234","sequence":4294967295}`, 55 | }, 56 | { 57 | name: "custom vinprevout marshal without coinbase", 58 | result: &hcashjson.VinPrevOut{ 59 | Txid: "123", 60 | Vout: 1, 61 | ScriptSig: &hcashjson.ScriptSig{ 62 | Asm: "0", 63 | Hex: "00", 64 | }, 65 | PrevOut: &hcashjson.PrevOut{ 66 | Addresses: []string{"addr1"}, 67 | Value: 0, 68 | }, 69 | Sequence: 4294967295, 70 | }, 71 | expected: `{"txid":"123","vout":1,"tree":0,"scriptSig":{"asm":"0","hex":"00"},"prevOut":{"addresses":["addr1"],"value":0},"sequence":4294967295}`, 72 | }, 73 | } 74 | 75 | t.Logf("Running %d tests", len(tests)) 76 | for i, test := range tests { 77 | marshalled, err := json.Marshal(test.result) 78 | if err != nil { 79 | t.Errorf("Test #%d (%s) unexpected error: %v", i, 80 | test.name, err) 81 | continue 82 | } 83 | if string(marshalled) != test.expected { 84 | t.Errorf("Test #%d (%s) unexpected marhsalled data - "+ 85 | "got %s, want %s", i, test.name, marshalled, 86 | test.expected) 87 | continue 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /hcashjson/chainsvrwsresults.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 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 hcashjson 7 | 8 | // SessionResult models the data from the session command. 9 | type SessionResult struct { 10 | SessionID uint64 `json:"sessionid"` 11 | } 12 | 13 | // RescanResult models the result object returned by the rescan RPC. 14 | type RescanResult struct { 15 | DiscoveredData []RescannedBlock `json:"discovereddata"` 16 | } 17 | 18 | // RescannedBlock contains the hash and all discovered transactions of a single 19 | // rescanned block. 20 | type RescannedBlock struct { 21 | Hash string `json:"hash"` 22 | Transactions []string `json:"transactions"` 23 | } 24 | -------------------------------------------------------------------------------- /hcashjson/error_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 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 hcashjson_test 7 | 8 | import ( 9 | "testing" 10 | 11 | "github.com/HcashOrg/hcashd/hcashjson" 12 | ) 13 | 14 | // TestErrorCodeStringer tests the stringized output for the ErrorCode type. 15 | func TestErrorCodeStringer(t *testing.T) { 16 | t.Parallel() 17 | 18 | tests := []struct { 19 | in hcashjson.ErrorCode 20 | want string 21 | }{ 22 | {hcashjson.ErrDuplicateMethod, "ErrDuplicateMethod"}, 23 | {hcashjson.ErrInvalidUsageFlags, "ErrInvalidUsageFlags"}, 24 | {hcashjson.ErrInvalidType, "ErrInvalidType"}, 25 | {hcashjson.ErrEmbeddedType, "ErrEmbeddedType"}, 26 | {hcashjson.ErrUnexportedField, "ErrUnexportedField"}, 27 | {hcashjson.ErrUnsupportedFieldType, "ErrUnsupportedFieldType"}, 28 | {hcashjson.ErrNonOptionalField, "ErrNonOptionalField"}, 29 | {hcashjson.ErrNonOptionalDefault, "ErrNonOptionalDefault"}, 30 | {hcashjson.ErrMismatchedDefault, "ErrMismatchedDefault"}, 31 | {hcashjson.ErrUnregisteredMethod, "ErrUnregisteredMethod"}, 32 | {hcashjson.ErrNumParams, "ErrNumParams"}, 33 | {hcashjson.ErrMissingDescription, "ErrMissingDescription"}, 34 | {0xffff, "Unknown ErrorCode (65535)"}, 35 | } 36 | 37 | // Detect additional error codes that don't have the stringer added. 38 | if len(tests)-1 != int(hcashjson.TstNumErrorCodes) { 39 | t.Errorf("It appears an error code was added without adding an " + 40 | "associated stringer test") 41 | } 42 | 43 | t.Logf("Running %d tests", len(tests)) 44 | for i, test := range tests { 45 | result := test.in.String() 46 | if result != test.want { 47 | t.Errorf("String #%d\n got: %s want: %s", i, result, 48 | test.want) 49 | continue 50 | } 51 | } 52 | } 53 | 54 | // TestError tests the error output for the Error type. 55 | func TestError(t *testing.T) { 56 | t.Parallel() 57 | 58 | tests := []struct { 59 | in hcashjson.Error 60 | want string 61 | }{ 62 | { 63 | hcashjson.Error{Message: "some error"}, 64 | "some error", 65 | }, 66 | { 67 | hcashjson.Error{Message: "human-readable error"}, 68 | "human-readable error", 69 | }, 70 | } 71 | 72 | t.Logf("Running %d tests", len(tests)) 73 | for i, test := range tests { 74 | result := test.in.Error() 75 | if result != test.want { 76 | t.Errorf("Error #%d\n got: %s want: %s", i, result, 77 | test.want) 78 | continue 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /hcashjson/export_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 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 hcashjson 7 | 8 | // TstHighestUsageFlagBit makes the internal highestUsageFlagBit parameter 9 | // available to the test package. 10 | var TstHighestUsageFlagBit = highestUsageFlagBit 11 | 12 | // TstNumErrorCodes makes the internal numErrorCodes parameter available to the 13 | // test package. 14 | var TstNumErrorCodes = numErrorCodes 15 | 16 | // TstAssignField makes the internal assignField function available to the test 17 | // package. 18 | var TstAssignField = assignField 19 | 20 | // TstFieldUsage makes the internal fieldUsage function available to the test 21 | // package. 22 | var TstFieldUsage = fieldUsage 23 | 24 | // TstReflectTypeToJSONType makes the internal reflectTypeToJSONType function 25 | // available to the test package. 26 | var TstReflectTypeToJSONType = reflectTypeToJSONType 27 | 28 | // TstResultStructHelp makes the internal resultStructHelp function available to 29 | // the test package. 30 | var TstResultStructHelp = resultStructHelp 31 | 32 | // TstReflectTypeToJSONExample makes the internal reflectTypeToJSONExample 33 | // function available to the test package. 34 | var TstReflectTypeToJSONExample = reflectTypeToJSONExample 35 | 36 | // TstResultTypeHelp makes the internal resultTypeHelp function available to the 37 | // test package. 38 | var TstResultTypeHelp = resultTypeHelp 39 | 40 | // TstArgHelp makes the internal argHelp function available to the test package. 41 | var TstArgHelp = argHelp 42 | 43 | // TestMethodHelp makes the internal methodHelp function available to the test 44 | // package. 45 | var TestMethodHelp = methodHelp 46 | 47 | // TstIsValidResultType makes the internal isValidResultType function available 48 | // to the test package. 49 | var TstIsValidResultType = isValidResultType 50 | -------------------------------------------------------------------------------- /hcashjson/helpers.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 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 hcashjson 7 | 8 | // Bool is a helper routine that allocates a new bool value to store v and 9 | // returns a pointer to it. This is useful when assigning optional parameters. 10 | func Bool(v bool) *bool { 11 | p := new(bool) 12 | *p = v 13 | return p 14 | } 15 | 16 | // Int is a helper routine that allocates a new int value to store v and 17 | // returns a pointer to it. This is useful when assigning optional parameters. 18 | func Int(v int) *int { 19 | p := new(int) 20 | *p = v 21 | return p 22 | } 23 | 24 | // Uint is a helper routine that allocates a new uint value to store v and 25 | // returns a pointer to it. This is useful when assigning optional parameters. 26 | func Uint(v uint) *uint { 27 | p := new(uint) 28 | *p = v 29 | return p 30 | } 31 | 32 | // Int32 is a helper routine that allocates a new int32 value to store v and 33 | // returns a pointer to it. This is useful when assigning optional parameters. 34 | func Int32(v int32) *int32 { 35 | p := new(int32) 36 | *p = v 37 | return p 38 | } 39 | 40 | // Uint32 is a helper routine that allocates a new uint32 value to store v and 41 | // returns a pointer to it. This is useful when assigning optional parameters. 42 | func Uint32(v uint32) *uint32 { 43 | p := new(uint32) 44 | *p = v 45 | return p 46 | } 47 | 48 | // Int64 is a helper routine that allocates a new int64 value to store v and 49 | // returns a pointer to it. This is useful when assigning optional parameters. 50 | func Int64(v int64) *int64 { 51 | p := new(int64) 52 | *p = v 53 | return p 54 | } 55 | 56 | // Uint64 is a helper routine that allocates a new uint64 value to store v and 57 | // returns a pointer to it. This is useful when assigning optional parameters. 58 | func Uint64(v uint64) *uint64 { 59 | p := new(uint64) 60 | *p = v 61 | return p 62 | } 63 | 64 | // Float64 is a helper routine that allocates a new float64 value to store v and 65 | // returns a pointer to it. This is useful when assigning optional parameters. 66 | func Float64(v float64) *float64 { 67 | p := new(float64) 68 | *p = v 69 | return p 70 | } 71 | 72 | // String is a helper routine that allocates a new string value to store v and 73 | // returns a pointer to it. This is useful when assigning optional parameters. 74 | func String(v string) *string { 75 | p := new(string) 76 | *p = v 77 | return p 78 | } 79 | -------------------------------------------------------------------------------- /hcashjson/helpers_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 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 hcashjson_test 7 | 8 | import ( 9 | "reflect" 10 | "testing" 11 | 12 | "github.com/HcashOrg/hcashd/hcashjson" 13 | ) 14 | 15 | // TestHelpers tests the various helper functions which create pointers to 16 | // primitive types. 17 | func TestHelpers(t *testing.T) { 18 | t.Parallel() 19 | 20 | tests := []struct { 21 | name string 22 | f func() interface{} 23 | expected interface{} 24 | }{ 25 | { 26 | name: "bool", 27 | f: func() interface{} { 28 | return hcashjson.Bool(true) 29 | }, 30 | expected: func() interface{} { 31 | val := true 32 | return &val 33 | }(), 34 | }, 35 | { 36 | name: "int", 37 | f: func() interface{} { 38 | return hcashjson.Int(5) 39 | }, 40 | expected: func() interface{} { 41 | val := int(5) 42 | return &val 43 | }(), 44 | }, 45 | { 46 | name: "uint", 47 | f: func() interface{} { 48 | return hcashjson.Uint(5) 49 | }, 50 | expected: func() interface{} { 51 | val := uint(5) 52 | return &val 53 | }(), 54 | }, 55 | { 56 | name: "int32", 57 | f: func() interface{} { 58 | return hcashjson.Int32(5) 59 | }, 60 | expected: func() interface{} { 61 | val := int32(5) 62 | return &val 63 | }(), 64 | }, 65 | { 66 | name: "uint32", 67 | f: func() interface{} { 68 | return hcashjson.Uint32(5) 69 | }, 70 | expected: func() interface{} { 71 | val := uint32(5) 72 | return &val 73 | }(), 74 | }, 75 | { 76 | name: "int64", 77 | f: func() interface{} { 78 | return hcashjson.Int64(5) 79 | }, 80 | expected: func() interface{} { 81 | val := int64(5) 82 | return &val 83 | }(), 84 | }, 85 | { 86 | name: "uint64", 87 | f: func() interface{} { 88 | return hcashjson.Uint64(5) 89 | }, 90 | expected: func() interface{} { 91 | val := uint64(5) 92 | return &val 93 | }(), 94 | }, 95 | { 96 | name: "string", 97 | f: func() interface{} { 98 | return hcashjson.String("abc") 99 | }, 100 | expected: func() interface{} { 101 | val := "abc" 102 | return &val 103 | }(), 104 | }, 105 | } 106 | 107 | t.Logf("Running %d tests", len(tests)) 108 | for i, test := range tests { 109 | result := test.f() 110 | if !reflect.DeepEqual(result, test.expected) { 111 | t.Errorf("Test #%d (%s) unexpected value - got %v, "+ 112 | "want %v", i, test.name, result, test.expected) 113 | continue 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /hcashjson/jsonrpcerr.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 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 hcashjson 7 | 8 | // Standard JSON-RPC 2.0 errors. 9 | var ( 10 | ErrRPCInvalidRequest = &RPCError{ 11 | Code: -32600, 12 | Message: "Invalid request", 13 | } 14 | ErrRPCMethodNotFound = &RPCError{ 15 | Code: -32601, 16 | Message: "Method not found", 17 | } 18 | ErrRPCInvalidParams = &RPCError{ 19 | Code: -32602, 20 | Message: "Invalid parameters", 21 | } 22 | ErrRPCInternal = &RPCError{ 23 | Code: -32603, 24 | Message: "Internal error", 25 | } 26 | ErrRPCParse = &RPCError{ 27 | Code: -32700, 28 | Message: "Parse error", 29 | } 30 | ) 31 | 32 | // General application defined JSON errors. 33 | const ( 34 | ErrRPCMisc RPCErrorCode = -1 35 | ErrRPCForbiddenBySafeMode RPCErrorCode = -2 36 | ErrRPCType RPCErrorCode = -3 37 | ErrRPCInvalidAddressOrKey RPCErrorCode = -5 38 | ErrRPCOutOfMemory RPCErrorCode = -7 39 | ErrRPCInvalidParameter RPCErrorCode = -8 40 | ErrRPCDatabase RPCErrorCode = -20 41 | ErrRPCDeserialization RPCErrorCode = -22 42 | ErrRPCVerify RPCErrorCode = -25 43 | ) 44 | 45 | // Peer-to-peer client errors. 46 | const ( 47 | ErrRPCClientNotConnected RPCErrorCode = -9 48 | ErrRPCClientInInitialDownload RPCErrorCode = -10 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 btcd. 81 | const ( 82 | ErrRPCNoWallet RPCErrorCode = -1 83 | ErrRPCUnimplemented RPCErrorCode = -1 84 | ) 85 | -------------------------------------------------------------------------------- /limits/limits_plan9.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 limits 7 | 8 | // SetLimits is a no-op on Plan 9 due to the lack of process accounting. 9 | func SetLimits() error { 10 | return nil 11 | } 12 | -------------------------------------------------------------------------------- /limits/limits_unix.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 | // +build !windows,!plan9 7 | 8 | package limits 9 | 10 | import ( 11 | "fmt" 12 | "syscall" 13 | ) 14 | 15 | const ( 16 | fileLimitWant = 2048 17 | fileLimitMin = 1024 18 | ) 19 | 20 | // SetLimits raises some process limits to values which allow hcashd and 21 | // associated utilities to run. 22 | func SetLimits() error { 23 | var rLimit syscall.Rlimit 24 | 25 | err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) 26 | if err != nil { 27 | return err 28 | } 29 | if rLimit.Cur > fileLimitWant { 30 | return nil 31 | } 32 | if rLimit.Max < fileLimitMin { 33 | err = fmt.Errorf("need at least %v file descriptors", 34 | fileLimitMin) 35 | return err 36 | } 37 | if rLimit.Max < fileLimitWant { 38 | rLimit.Cur = rLimit.Max 39 | } else { 40 | rLimit.Cur = fileLimitWant 41 | } 42 | err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) 43 | if err != nil { 44 | // try min value 45 | rLimit.Cur = fileLimitMin 46 | err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) 47 | if err != nil { 48 | return err 49 | } 50 | } 51 | 52 | return nil 53 | } 54 | -------------------------------------------------------------------------------- /limits/limits_windows.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 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 limits 7 | 8 | // SetLimits is a no-op on Windows since it's not required there. 9 | func SetLimits() error { 10 | return nil 11 | } 12 | -------------------------------------------------------------------------------- /mempool/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Copyright (c) 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 mempool 7 | 8 | import ( 9 | "github.com/btcsuite/btclog" 10 | ) 11 | 12 | // log is a logger that is initialized with no output filters. This 13 | // means the package will not perform any logging by default until the caller 14 | // requests it. 15 | var log btclog.Logger 16 | 17 | // The default amount of logging is none. 18 | func init() { 19 | DisableLog() 20 | } 21 | 22 | // DisableLog disables all library log output. Logging output is disabled 23 | // by default until either UseLogger or SetLogWriter are called. 24 | func DisableLog() { 25 | log = btclog.Disabled 26 | } 27 | 28 | // UseLogger uses a specified Logger to output package logging info. 29 | // This should be used in preference to SetLogWriter if the caller is also 30 | // using btclog. 31 | func UseLogger(logger btclog.Logger) { 32 | log = logger 33 | } 34 | -------------------------------------------------------------------------------- /mining/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The Decred 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 mining includes all mining and policy types, and will 7 | house all mining code in the future. 8 | 9 | Overview 10 | 11 | This package currently contains the 3 struct types 12 | for mining and policy. In the future it will contain all of the 13 | pieces of code pertaining to block template creation, CPU mining 14 | and other various mining code. 15 | 16 | */ 17 | package mining 18 | -------------------------------------------------------------------------------- /mining/mining.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2016 The btcsuite developers 2 | // Copyright (c) 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 mining 7 | 8 | import ( 9 | "time" 10 | 11 | "github.com/HcashOrg/hcashd/blockchain/stake" 12 | "github.com/HcashOrg/hcashd/chaincfg/chainhash" 13 | "github.com/HcashOrg/hcashutil" 14 | ) 15 | 16 | // TxDesc is a descriptor about a transaction in a transaction source along with 17 | // additional metadata. 18 | type TxDesc struct { 19 | // Tx is the transaction associated with the entry. 20 | Tx *hcashutil.Tx 21 | 22 | // Type is the type of the transaction associated with the entry. 23 | Type stake.TxType 24 | 25 | // Added is the time when the entry was added to the source pool. 26 | Added time.Time 27 | 28 | // Height is the block height when the entry was added to the the source 29 | // pool. 30 | Height int64 31 | 32 | // Fee is the total fee the transaction associated with the entry pays. 33 | Fee int64 34 | } 35 | 36 | // TxSource represents a source of transactions to consider for inclusion in 37 | // new blocks. 38 | // 39 | // The interface contract requires that all of these methods are safe for 40 | // concurrent access with respect to the source. 41 | type TxSource interface { 42 | // LastUpdated returns the last time a transaction was added to or 43 | // removed from the source pool. 44 | LastUpdated() time.Time 45 | 46 | // MiningDescs returns a slice of mining descriptors for all the 47 | // transactions in the source pool. 48 | MiningDescs() []*TxDesc 49 | 50 | // HaveTransaction returns whether or not the passed transaction hash 51 | // exists in the source pool. 52 | HaveTransaction(hash *chainhash.Hash) bool 53 | } 54 | -------------------------------------------------------------------------------- /mining/policy.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2015 The btcsuite developers 2 | // Copyright (c) 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 mining 7 | 8 | import "github.com/HcashOrg/hcashutil" 9 | 10 | // Policy houses the policy (configuration parameters) which is used to control 11 | // the generation of block templates. See the documentation for 12 | // NewBlockTemplate for more details on each of these parameters are used. 13 | type Policy struct { 14 | // BlockMinSize is the minimum block size in bytes to be used when 15 | // generating a block template. 16 | BlockMinSize uint32 17 | 18 | // BlockMaxSize is the maximum block size in bytes to be used when 19 | // generating a block template. 20 | BlockMaxSize uint32 21 | 22 | // BlockPrioritySize is the size in bytes for high-priority / low-fee 23 | // transactions to be used when generating a block template. 24 | BlockPrioritySize uint32 25 | 26 | // TxMinFreeFee is the minimum fee in Atoms/1000 bytes that is 27 | // required for a transaction to be treated as free for mining purposes 28 | // (block template generation). 29 | TxMinFreeFee hcashutil.Amount 30 | } 31 | -------------------------------------------------------------------------------- /params.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 The btcsuite developers 2 | // Copyright (c) 2015-2016 The Decred developers 3 | // Copyright (c) 2017 The Hcash developers 4 | // Use of this source code is governed by an ISC 5 | // license that can be found in the LICENSE file. 6 | 7 | package main 8 | 9 | import ( 10 | "github.com/HcashOrg/hcashd/chaincfg" 11 | "github.com/HcashOrg/hcashd/wire" 12 | ) 13 | 14 | // activeNetParams is a pointer to the parameters specific to the 15 | // currently active hypercash network. 16 | var activeNetParams = &mainNetParams 17 | 18 | // params is used to group parameters for various networks such as the main 19 | // network and test networks. 20 | type params struct { 21 | *chaincfg.Params 22 | rpcPort string 23 | } 24 | 25 | // mainNetParams contains parameters specific to the main network 26 | // (wire.MainNet). NOTE: The RPC port is intentionally different than the 27 | // reference implementation because hcashd does not handle wallet requests. The 28 | // separate wallet process listens on the well-known port and forwards requests 29 | // it does not handle on to hcashd. This approach allows the wallet process 30 | // to emulate the full reference implementation RPC API. 31 | var mainNetParams = params{ 32 | Params: &chaincfg.MainNetParams, 33 | rpcPort: "14009", 34 | } 35 | 36 | // testNet2Params contains parameters specific to the test network (version 2) 37 | // (wire.TestNet2). 38 | var testNet2Params = params{ 39 | Params: &chaincfg.TestNet2Params, 40 | rpcPort: "12009", 41 | } 42 | 43 | // simNetParams contains parameters specific to the simulation test network 44 | // (wire.SimNet). 45 | var simNetParams = params{ 46 | Params: &chaincfg.SimNetParams, 47 | rpcPort: "13009", 48 | } 49 | 50 | // netName returns the name used when referring to a hypercash network. At the 51 | // time of writing, hcashd currently places blocks for testnet version 0 in the 52 | // data and log directory "testnet", which does not match the Name field of the 53 | // chaincfg parameters. This function can be used to override this directory name 54 | // as "testnet2" when the passed active network matches wire.TestNet2. 55 | // 56 | // A proper upgrade to move the data and log directories for this network to 57 | // "testnet" is planned for the future, at which point this function can be 58 | // removed and the network parameter's name used instead. 59 | func netName(chainParams *params) string { 60 | switch chainParams.Net { 61 | case wire.TestNet2: 62 | return "testnet2" 63 | default: 64 | return chainParams.Name 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /peer/export_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The btcsuite developers 2 | // Copyright (c) 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 | /* 7 | This test file is part of the peer package rather than than the peer_test 8 | package so it can bridge access to the internals to properly test cases which 9 | are either not possible or can't reliably be tested via the public interface. 10 | The functions are only exported while the tests are being run. 11 | */ 12 | 13 | package peer 14 | 15 | // TstAllowSelfConns allows the test package to allow self connections by 16 | // disabling the detection logic. 17 | func TstAllowSelfConns() { 18 | allowSelfConns = true 19 | } 20 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /release/services/smf/hcashd.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /release/services/systemd/hcashd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Hypercash Full Node 3 | 4 | [Service] 5 | Type=simple 6 | User=hcashd 7 | Group=hcashd 8 | WorkingDirectory=/var/hcashd 9 | ExecStart=/opt/HcashOrg/bin/hcashd --appdata=/var/hcashd 10 | Restart=on-abnormal 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /rpcserverhelp_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 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 main 7 | 8 | import "testing" 9 | 10 | // TestHelp ensures the help is reasonably accurate by checking that every 11 | // command specified also has result types defined and the one-line usage and 12 | // help text can be generated for them. 13 | func TestHelp(t *testing.T) { 14 | // Ensure there are result types specified for every handler. 15 | for k := range rpcHandlers { 16 | if _, ok := rpcResultTypes[k]; !ok { 17 | t.Errorf("RPC handler defined for method '%v' without "+ 18 | "also specifying result types", k) 19 | continue 20 | } 21 | 22 | } 23 | for k := range wsHandlers { 24 | if _, ok := rpcResultTypes[k]; !ok { 25 | t.Errorf("RPC handler defined for method '%v' without "+ 26 | "also specifying result types", k) 27 | continue 28 | } 29 | 30 | } 31 | 32 | // Ensure the usage for every command can be generated without errors. 33 | helpCacher := newHelpCacher() 34 | if _, err := helpCacher.rpcUsage(true); err != nil { 35 | t.Fatalf("Failed to generate one-line usage: %v", err) 36 | } 37 | if _, err := helpCacher.rpcUsage(true); err != nil { 38 | t.Fatalf("Failed to generate one-line usage (cached): %v", err) 39 | } 40 | 41 | // Ensure the help for every command can be generated without errors. 42 | for k := range rpcHandlers { 43 | if _, err := helpCacher.rpcMethodHelp(k); err != nil { 44 | t.Errorf("Failed to generate help for method '%v': %v", 45 | k, err) 46 | continue 47 | } 48 | if _, err := helpCacher.rpcMethodHelp(k); err != nil { 49 | t.Errorf("Failed to generate help for method '%v'"+ 50 | "(cached): %v", k, err) 51 | continue 52 | } 53 | } 54 | for k := range wsHandlers { 55 | if _, err := helpCacher.rpcMethodHelp(k); err != nil { 56 | t.Errorf("Failed to generate help for method '%v': %v", 57 | k, err) 58 | continue 59 | } 60 | if _, err := helpCacher.rpcMethodHelp(k); err != nil { 61 | t.Errorf("Failed to generate help for method '%v'"+ 62 | "(cached): %v", k, err) 63 | continue 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /rpctest/doc.go: -------------------------------------------------------------------------------- 1 | // Package rpctest provides a hcashd-specific RPC testing harness crafting and 2 | // executing integration tests by driving a `hcashd` 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 | // `hcashd`. However, the constructs presented are general enough to be adapted to 10 | // any project wishing to programmatically drive a `hcashd` instance of its 11 | // systems/integration tests. 12 | package rpctest 13 | -------------------------------------------------------------------------------- /run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -ex 3 | 4 | # The script does automatic checking on a Go package and its sub-packages, 5 | # including: 6 | # 1. gofmt (http://golang.org/cmd/gofmt/) 7 | # 2. go vet (http://golang.org/cmd/vet) 8 | # 3. unconvert (https://github.com/mdempsky/unconvert) 9 | # 4. race detector (http://blog.golang.org/race-detector) 10 | 11 | # gometalinter (github.com/alecthomas/gometalinter) is used to run each each 12 | # static checker. 13 | 14 | # To run on docker on windows, symlink /mnt/c to /c and then execute the script 15 | # from the repo path under /c. See: 16 | # https://github.com/Microsoft/BashOnWindows/issues/1854 17 | # for more details. 18 | 19 | #Default GOVERSION 20 | GOVERSION=${1:-1.9} 21 | REPO=hcashd 22 | 23 | TESTCMD="test -z \"\$(gometalinter --disable-all \ 24 | --enable=gofmt \ 25 | --enable=vet \ 26 | --enable=unconvert \ 27 | --vendor \ 28 | --deadline=10m . | tee /dev/stderr)\"&& \ 29 | env GORACE='halt_on_error=1' go test -short -race \ 30 | -tags rpctest \ 31 | \$(glide novendor)" 32 | 33 | if [ $GOVERSION == "local" ]; then 34 | eval $TESTCMD 35 | exit 36 | fi 37 | 38 | DOCKER_IMAGE_TAG=hypercash-golang-builder-$GOVERSION 39 | 40 | docker pull HcashOrg/$DOCKER_IMAGE_TAG 41 | 42 | docker run --rm -it -v $(pwd):/src HcashOrg/$DOCKER_IMAGE_TAG /bin/bash -c "\ 43 | rsync -ra --filter=':- .gitignore' \ 44 | /src/ /go/src/github.com/HcashOrg/$REPO/ && \ 45 | cd github.com/HcashOrg/$REPO/ && \ 46 | glide install && \ 47 | go install \$(glide novendor) && \ 48 | $TESTCMD 49 | " 50 | 51 | echo "------------------------------------------" 52 | echo "Tests complete." 53 | -------------------------------------------------------------------------------- /sampleconfig/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 The Decred 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 sampleconfig provides a single constant that contains the contents of 7 | the sample configuration file for hcashd. This is provided for tools that perform 8 | automatic configuration and would like to ensure the generated configuration 9 | file not only includes the specifically configured values, but also provides 10 | samples of other configuration options. 11 | */ 12 | package sampleconfig 13 | -------------------------------------------------------------------------------- /signal.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 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 main 7 | 8 | import ( 9 | "os" 10 | "os/signal" 11 | ) 12 | 13 | // shutdownRequestChannel is used to initiate shutdown from one of the 14 | // subsystems using the same code paths as when an interrupt signal is received. 15 | var shutdownRequestChannel = make(chan struct{}) 16 | 17 | // interruptSignals defines the default signals to catch in order to do a proper 18 | // shutdown. This may be modified during init depending on the platform. 19 | var interruptSignals = []os.Signal{os.Interrupt} 20 | 21 | // interruptListener listens for OS Signals such as SIGINT (Ctrl+C) and shutdown 22 | // requests from shutdownRequestChannel. It returns a channel that is closed 23 | // when either signal is received. 24 | func interruptListener() <-chan struct{} { 25 | c := make(chan struct{}) 26 | go func() { 27 | interruptChannel := make(chan os.Signal, 1) 28 | signal.Notify(interruptChannel, interruptSignals...) 29 | 30 | // Listen for initial shutdown signal and close the returned 31 | // channel to notify the caller. 32 | select { 33 | case sig := <-interruptChannel: 34 | hcashdLog.Infof("Received signal (%s). Shutting down...", 35 | sig) 36 | 37 | case <-shutdownRequestChannel: 38 | hcashdLog.Infof("Shutdown requested. Shutting down...") 39 | } 40 | close(c) 41 | 42 | // Listen for repeated signals and display a message so the user 43 | // knows the shutdown is in progress and the process is not 44 | // hung. 45 | for { 46 | select { 47 | case sig := <-interruptChannel: 48 | hcashdLog.Infof("Received signal (%s). Already "+ 49 | "shutting down...", sig) 50 | 51 | case <-shutdownRequestChannel: 52 | hcashdLog.Info("Shutdown requested. Already " + 53 | "shutting down...") 54 | } 55 | } 56 | }() 57 | 58 | return c 59 | } 60 | 61 | // interruptRequested returns true when the channel returned by 62 | // interruptListener was closed. This simplifies early shutdown slightly since 63 | // the caller can just use an if statement instead of a select. 64 | func interruptRequested(interrupted <-chan struct{}) bool { 65 | select { 66 | case <-interrupted: 67 | return true 68 | default: 69 | } 70 | 71 | return false 72 | } 73 | -------------------------------------------------------------------------------- /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/consensus.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 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 txscript 7 | 8 | const ( 9 | // LockTimeThreshold is the number below which a lock time is 10 | // interpreted to be a block number. Since an average of one block 11 | // is generated per 10 minutes, this allows blocks for about 9,512 12 | // years. 13 | LockTimeThreshold = 5e8 // Tue Nov 5 00:53:20 1985 UTC 14 | ) 15 | -------------------------------------------------------------------------------- /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-2015 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 | /* 7 | Package txscript implements the hypercash transaction script language. 8 | 9 | This package provides data structures and functions to parse and execute 10 | hypercash transaction scripts. 11 | 12 | Script Overview 13 | 14 | Hypercash transaction scripts are written in a stack-base, FORTH-like language. 15 | 16 | The hypercash script language consists of a number of opcodes which fall into 17 | several categories such pushing and popping data to and from the stack, 18 | performing basic and bitwise arithmetic, conditional branching, comparing 19 | hashes, and checking cryptographic signatures. Scripts are processed from left 20 | to right and intentionally do not provide loops. 21 | 22 | The vast majority of Hypercash scripts at the time of this writing are of several 23 | standard forms which consist of a spender providing a public key and a signature 24 | which proves the spender owns the associated private key. This information 25 | is used to prove the the spender is authorized to perform the transaction. 26 | 27 | One benefit of using a scripting language is added flexibility in specifying 28 | what conditions must be met in order to spend hypercashs. 29 | 30 | Errors 31 | 32 | Errors returned by this package are of the form txscript.ErrStackX where X 33 | indicates the specific error. See Variables in the package documentation for a 34 | full list. 35 | */ 36 | package txscript 37 | -------------------------------------------------------------------------------- /txscript/log.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 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 txscript 7 | 8 | import ( 9 | "github.com/btcsuite/btclog" 10 | ) 11 | 12 | // log is a logger that is initialized with no output filters. This 13 | // means the package will not perform any logging by default until the caller 14 | // requests it. 15 | var log btclog.Logger 16 | 17 | // The default amount of logging is none. 18 | func init() { 19 | DisableLog() 20 | } 21 | 22 | // DisableLog disables all library log output. Logging output is disabled 23 | // by default until UseLogger is called. 24 | func DisableLog() { 25 | log = btclog.Disabled 26 | } 27 | 28 | // UseLogger uses a specified Logger to output package logging info. 29 | func UseLogger(logger btclog.Logger) { 30 | log = logger 31 | } 32 | 33 | // LogClosure is a closure that can be printed with %v to be used to 34 | // generate expensive-to-create data for a detailed log level and avoid doing 35 | // the work if the data isn't printed. 36 | type logClosure func() string 37 | 38 | func (c logClosure) String() string { 39 | return c() 40 | } 41 | 42 | func newLogClosure(c func() string) logClosure { 43 | return logClosure(c) 44 | } 45 | -------------------------------------------------------------------------------- /version.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2014 The btcsuite developers 2 | // Copyright (c) 2015-2017 The Decred developers 3 | // Copyright (c) 2017 The Hcash developers 4 | // Use of this source code is governed by an ISC 5 | // license that can be found in the LICENSE file. 6 | 7 | package main 8 | 9 | import ( 10 | "bytes" 11 | "fmt" 12 | "strings" 13 | ) 14 | 15 | // semanticAlphabet 16 | const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" 17 | 18 | // These constants define the application version and follow the semantic 19 | // versioning 2.0.0 spec (http://semver.org/). 20 | const ( 21 | appMajor uint = 0 22 | appMinor uint = 9 23 | appPatch uint = 0 24 | 25 | // appPreRelease MUST only contain characters from semanticAlphabet 26 | // per the semantic versioning spec. 27 | appPreRelease = "" 28 | ) 29 | 30 | // appBuild is defined as a variable so it can be overridden during the build 31 | // process with '-ldflags "-X main.appBuild=foo' if needed. It MUST only 32 | // contain characters from semanticAlphabet per the semantic versioning spec. 33 | var appBuild = "TestBeforeV1" 34 | 35 | // version returns the application version as a properly formed string per the 36 | // semantic versioning 2.0.0 spec (http://semver.org/). 37 | func version() string { 38 | // Start with the major, minor, and patch versions. 39 | version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch) 40 | 41 | // Append pre-release version if there is one. The hyphen called for 42 | // by the semantic versioning spec is automatically appended and should 43 | // not be contained in the pre-release string. The pre-release version 44 | // is not appended if it contains invalid characters. 45 | preRelease := normalizeVerString(appPreRelease) 46 | if preRelease != "" { 47 | version = fmt.Sprintf("%s-%s", version, preRelease) 48 | } 49 | 50 | // Append build metadata if there is any. The plus called for 51 | // by the semantic versioning spec is automatically appended and should 52 | // not be contained in the build metadata string. The build metadata 53 | // string is not appended if it contains invalid characters. 54 | build := normalizeVerString(appBuild) 55 | if build != "" { 56 | version = fmt.Sprintf("%s+%s", version, build) 57 | } 58 | 59 | return version 60 | } 61 | 62 | // normalizeVerString returns the passed string stripped of all characters which 63 | // are not valid according to the semantic versioning guidelines for pre-release 64 | // version and build metadata strings. In particular they MUST only contain 65 | // characters in semanticAlphabet. 66 | func normalizeVerString(str string) string { 67 | var result bytes.Buffer 68 | for _, r := range str { 69 | if strings.ContainsRune(semanticAlphabet, r) { 70 | result.WriteRune(r) 71 | } 72 | } 73 | return result.String() 74 | } 75 | -------------------------------------------------------------------------------- /wire/error.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 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 wire 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | // MessageError describes an issue with a message. 13 | // An example of some potential issues are messages from the wrong hypercash 14 | // network, invalid commands, mismatched checksums, and exceeding max payloads. 15 | // 16 | // This provides a mechanism for the caller to type assert the error to 17 | // differentiate between general io errors such as io.EOF and issues that 18 | // resulted from malformed messages. 19 | type MessageError struct { 20 | Func string // Function name 21 | Description string // Human readable description of the issue 22 | } 23 | 24 | // Error satisfies the error interface and prints human-readable errors. 25 | func (e *MessageError) Error() string { 26 | if e.Func != "" { 27 | return fmt.Sprintf("%v: %v", e.Func, e.Description) 28 | } 29 | return e.Description 30 | } 31 | 32 | // messageError creates an error for the given function and description. 33 | func messageError(f string, desc string) *MessageError { 34 | return &MessageError{Func: f, Description: desc} 35 | } 36 | -------------------------------------------------------------------------------- /wire/fakeconn_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 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 wire 7 | 8 | import ( 9 | "net" 10 | "time" 11 | ) 12 | 13 | // fakeConn implements the net.Conn interface and is used to test functions 14 | // which work with a net.Conn without having to actually make any real 15 | // connections. 16 | type fakeConn struct { 17 | localAddr net.Addr 18 | remoteAddr net.Addr 19 | } 20 | 21 | // Read doesn't do anything. It just satisfies the net.Conn interface. 22 | func (c *fakeConn) Read(b []byte) (n int, err error) { 23 | return 0, nil 24 | } 25 | 26 | // Write doesn't do anything. It just satisfies the net.Conn interface. 27 | func (c *fakeConn) Write(b []byte) (n int, err error) { 28 | return 0, nil 29 | } 30 | 31 | // Close doesn't do anything. It just satisfies the net.Conn interface. 32 | func (c *fakeConn) Close() error { 33 | return nil 34 | } 35 | 36 | // LocalAddr returns the localAddr field of the fake connection and satisfies 37 | // the net.Conn interface. 38 | func (c *fakeConn) LocalAddr() net.Addr { 39 | return c.localAddr 40 | } 41 | 42 | // RemoteAddr returns the remoteAddr field of the fake connection and satisfies 43 | // the net.Conn interface. 44 | func (c *fakeConn) RemoteAddr() net.Addr { 45 | return c.remoteAddr 46 | } 47 | 48 | // SetDeadline doesn't do anything. It just satisfies the net.Conn interface. 49 | func (c *fakeConn) SetDeadline(t time.Time) error { 50 | return nil 51 | } 52 | 53 | // SetReadDeadline doesn't do anything. It just satisfies the net.Conn 54 | // interface. 55 | func (c *fakeConn) SetReadDeadline(t time.Time) error { 56 | return nil 57 | } 58 | 59 | // SetWriteDeadline doesn't do anything. It just satisfies the net.Conn 60 | // interface. 61 | func (c *fakeConn) SetWriteDeadline(t time.Time) error { 62 | return nil 63 | } 64 | -------------------------------------------------------------------------------- /wire/fakemessage_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 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 wire 7 | 8 | import "io" 9 | 10 | // fakeMessage implements the Message interface and is used to force encode 11 | // errors in messages. 12 | type fakeMessage struct { 13 | command string 14 | payload []byte 15 | forceEncodeErr bool 16 | forceLenErr bool 17 | } 18 | 19 | // BtcDecode doesn't do anything. It just satisfies the Message interface. 20 | func (msg *fakeMessage) BtcDecode(r io.Reader, pver uint32) 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 | // Message interface. 27 | func (msg *fakeMessage) BtcEncode(w io.Writer, pver uint32) 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 | // 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 wire 7 | 8 | import ( 9 | "bytes" 10 | "io" 11 | ) 12 | 13 | // fixedWriter implements the io.Writer interface and intentially allows 14 | // testing of error paths by forcing short writes. 15 | type fixedWriter struct { 16 | b []byte 17 | pos int 18 | } 19 | 20 | // Write writes the contents of p to w. When the contents of p would cause 21 | // the writer to exceed the maximum allowed size of the fixed writer, 22 | // io.ErrShortWrite is returned and the writer is left unchanged. 23 | // 24 | // This satisfies the io.Writer interface. 25 | func (w *fixedWriter) Write(p []byte) (n int, err error) { 26 | lenp := len(p) 27 | if w.pos+lenp > cap(w.b) { 28 | return 0, io.ErrShortWrite 29 | } 30 | n = lenp 31 | w.pos += copy(w.b[w.pos:], p) 32 | return 33 | } 34 | 35 | // Bytes returns the bytes already written to the fixed writer. 36 | func (w *fixedWriter) Bytes() []byte { 37 | return w.b 38 | } 39 | 40 | // newFixedWriter returns a new io.Writer that will error once more bytes than 41 | // the specified max have been written. 42 | func newFixedWriter(max int) io.Writer { 43 | b := make([]byte, max, max) 44 | fw := fixedWriter{b, 0} 45 | return &fw 46 | } 47 | 48 | // fixedReader implements the io.Reader interface and intentially allows 49 | // testing of error paths by forcing short reads. 50 | type fixedReader struct { 51 | buf []byte 52 | pos int 53 | iobuf *bytes.Buffer 54 | } 55 | 56 | // Read reads the next len(p) bytes from the fixed reader. When the number of 57 | // bytes read would exceed the maximum number of allowed bytes to be read from 58 | // the fixed writer, an error is returned. 59 | // 60 | // This satisfies the io.Reader interface. 61 | func (fr *fixedReader) Read(p []byte) (n int, err error) { 62 | n, err = fr.iobuf.Read(p) 63 | fr.pos += n 64 | return 65 | } 66 | 67 | // newFixedReader returns a new io.Reader that will error once more bytes than 68 | // the specified max have been read. 69 | func newFixedReader(max int, buf []byte) io.Reader { 70 | b := make([]byte, max, max) 71 | if buf != nil { 72 | copy(b[:], buf) 73 | } 74 | 75 | iobuf := bytes.NewBuffer(b) 76 | fr := fixedReader{b, 0, iobuf} 77 | return &fr 78 | } 79 | -------------------------------------------------------------------------------- /wire/invvect.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 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 wire 7 | 8 | import ( 9 | "fmt" 10 | "io" 11 | 12 | "github.com/HcashOrg/hcashd/chaincfg/chainhash" 13 | ) 14 | 15 | const ( 16 | // MaxInvPerMsg is the maximum number of inventory vectors that can be in a 17 | // single hypercash inv message. 18 | MaxInvPerMsg = 50000 19 | 20 | // Maximum payload size for an inventory vector. 21 | maxInvVectPayload = 4 + chainhash.HashSize 22 | ) 23 | 24 | // InvType represents the allowed types of inventory vectors. See InvVect. 25 | type InvType uint32 26 | 27 | // These constants define the various supported inventory vector types. 28 | const ( 29 | InvTypeError InvType = 0 30 | InvTypeTx InvType = 1 31 | InvTypeBlock InvType = 2 32 | InvTypeFilteredBlock InvType = 3 33 | ) 34 | 35 | // Map of service flags back to their constant names for pretty printing. 36 | var ivStrings = map[InvType]string{ 37 | InvTypeError: "ERROR", 38 | InvTypeTx: "MSG_TX", 39 | InvTypeBlock: "MSG_BLOCK", 40 | InvTypeFilteredBlock: "MSG_FILTERED_BLOCK", 41 | } 42 | 43 | // String returns the InvType in human-readable form. 44 | func (invtype InvType) String() string { 45 | if s, ok := ivStrings[invtype]; ok { 46 | return s 47 | } 48 | 49 | return fmt.Sprintf("Unknown InvType (%d)", uint32(invtype)) 50 | } 51 | 52 | // InvVect defines a hypercash inventory vector which is used to describe data, 53 | // as specified by the Type field, that a peer wants, has, or does not have to 54 | // another peer. 55 | type InvVect struct { 56 | Type InvType // Type of data 57 | Hash chainhash.Hash // Hash of the data 58 | } 59 | 60 | // NewInvVect returns a new InvVect using the provided type and hash. 61 | func NewInvVect(typ InvType, hash *chainhash.Hash) *InvVect { 62 | return &InvVect{ 63 | Type: typ, 64 | Hash: *hash, 65 | } 66 | } 67 | 68 | // readInvVect reads an encoded InvVect from r depending on the protocol 69 | // version. 70 | func readInvVect(r io.Reader, pver uint32, iv *InvVect) error { 71 | return readElements(r, &iv.Type, &iv.Hash) 72 | } 73 | 74 | // writeInvVect serializes an InvVect to w depending on the protocol version. 75 | func writeInvVect(w io.Writer, pver uint32, iv *InvVect) error { 76 | return writeElements(w, iv.Type, &iv.Hash) 77 | } 78 | -------------------------------------------------------------------------------- /wire/msgfeefilter.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 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 wire 7 | 8 | import ( 9 | "fmt" 10 | "io" 11 | ) 12 | 13 | // MsgFeeFilter implements the Message interface and represents a feefilter 14 | // message. It is used to request the receiving peer does not announce any 15 | // transactions below the specified minimum fee rate. 16 | // 17 | // This message was not added until protocol versions starting with 18 | // FeeFilterVersion. 19 | type MsgFeeFilter struct { 20 | MinFee int64 21 | } 22 | 23 | // BtcDecode decodes r using the protocol encoding into the receiver. 24 | // This is part of the Message interface implementation. 25 | func (msg *MsgFeeFilter) BtcDecode(r io.Reader, pver uint32) error { 26 | if pver < FeeFilterVersion { 27 | str := fmt.Sprintf("feefilter message invalid for protocol "+ 28 | "version %d", pver) 29 | return messageError("MsgFeeFilter.BtcDecode", str) 30 | } 31 | 32 | err := readElement(r, &msg.MinFee) 33 | if err != nil { 34 | return err 35 | } 36 | 37 | return nil 38 | } 39 | 40 | // BtcEncode encodes the receiver to w using the protocol encoding. 41 | // This is part of the Message interface implementation. 42 | func (msg *MsgFeeFilter) BtcEncode(w io.Writer, pver uint32) error { 43 | if pver < FeeFilterVersion { 44 | str := fmt.Sprintf("feefilter message invalid for protocol "+ 45 | "version %d", pver) 46 | return messageError("MsgFeeFilter.BtcEncode", str) 47 | } 48 | 49 | err := writeElement(w, msg.MinFee) 50 | if err != nil { 51 | return err 52 | } 53 | 54 | return nil 55 | } 56 | 57 | // Command returns the protocol command string for the message. This is part 58 | // of the Message interface implementation. 59 | func (msg *MsgFeeFilter) Command() string { 60 | return CmdFeeFilter 61 | } 62 | 63 | // MaxPayloadLength returns the maximum length the payload can be for the 64 | // receiver. This is part of the Message interface implementation. 65 | func (msg *MsgFeeFilter) MaxPayloadLength(pver uint32) uint32 { 66 | // 8 bytes min fee. 67 | return 8 68 | } 69 | 70 | // NewMsgFeeFilter returns a new feefilter message that conforms to the Message 71 | // interface. See MsgFeeFilter for details. 72 | func NewMsgFeeFilter(minfee int64) *MsgFeeFilter { 73 | return &MsgFeeFilter{ 74 | MinFee: minfee, 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /wire/msgfilteradd.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2015 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 wire 7 | 8 | import ( 9 | "fmt" 10 | "io" 11 | ) 12 | 13 | const ( 14 | // MaxFilterAddDataSize is the maximum byte size of a data 15 | // element to add to the Bloom filter. It is equal to the 16 | // maximum element size of a script. 17 | MaxFilterAddDataSize = 520 18 | ) 19 | 20 | // MsgFilterAdd implements the Message interface and represents a hypercash 21 | // filteradd message. It is used to add a data element to an existing Bloom 22 | // filter. 23 | // 24 | // This message was not added until protocol version BIP0037Version. 25 | type MsgFilterAdd struct { 26 | Data []byte 27 | } 28 | 29 | // BtcDecode decodes r using the hypercash protocol encoding into the receiver. 30 | // This is part of the Message interface implementation. 31 | func (msg *MsgFilterAdd) BtcDecode(r io.Reader, pver uint32) error { 32 | var err error 33 | msg.Data, err = ReadVarBytes(r, pver, MaxFilterAddDataSize, 34 | "filteradd data") 35 | return err 36 | } 37 | 38 | // BtcEncode encodes the receiver to w using the hypercash protocol encoding. 39 | // This is part of the Message interface implementation. 40 | func (msg *MsgFilterAdd) BtcEncode(w io.Writer, pver uint32) error { 41 | size := len(msg.Data) 42 | if size > MaxFilterAddDataSize { 43 | str := fmt.Sprintf("filteradd size too large for message "+ 44 | "[size %v, max %v]", size, MaxFilterAddDataSize) 45 | return messageError("MsgFilterAdd.BtcEncode", str) 46 | } 47 | 48 | return WriteVarBytes(w, pver, msg.Data) 49 | } 50 | 51 | // Command returns the protocol command string for the message. This is part 52 | // of the Message interface implementation. 53 | func (msg *MsgFilterAdd) Command() string { 54 | return CmdFilterAdd 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 *MsgFilterAdd) MaxPayloadLength(pver uint32) uint32 { 60 | return uint32(VarIntSerializeSize(MaxFilterAddDataSize)) + 61 | MaxFilterAddDataSize 62 | } 63 | 64 | // NewMsgFilterAdd returns a new hypercash filteradd message that conforms to the 65 | // Message interface. See MsgFilterAdd for details. 66 | func NewMsgFilterAdd(data []byte) *MsgFilterAdd { 67 | return &MsgFilterAdd{ 68 | Data: data, 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /wire/msgfilterclear.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2015 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 wire 7 | 8 | import ( 9 | "io" 10 | ) 11 | 12 | // MsgFilterClear implements the Message interface and represents a hypercash 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 hypercash protocol encoding into the receiver. 20 | // This is part of the Message interface implementation. 21 | func (msg *MsgFilterClear) BtcDecode(r io.Reader, pver uint32) error { 22 | return nil 23 | } 24 | 25 | // BtcEncode encodes the receiver to w using the hypercash protocol encoding. 26 | // This is part of the Message interface implementation. 27 | func (msg *MsgFilterClear) BtcEncode(w io.Writer, pver uint32) 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 *MsgFilterClear) Command() string { 34 | return CmdFilterClear 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 *MsgFilterClear) MaxPayloadLength(pver uint32) uint32 { 40 | return 0 41 | } 42 | 43 | // NewMsgFilterClear returns a new hypercash filterclear message that conforms to the Message 44 | // interface. See MsgFilterClear for details. 45 | func NewMsgFilterClear() *MsgFilterClear { 46 | return &MsgFilterClear{} 47 | } 48 | -------------------------------------------------------------------------------- /wire/msgfilterclear_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2016 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 wire 7 | 8 | import ( 9 | "bytes" 10 | "reflect" 11 | "testing" 12 | 13 | "github.com/davecgh/go-spew/spew" 14 | ) 15 | 16 | // TestFilterCLearLatest tests the MsgFilterClear API against the latest 17 | // protocol version. 18 | func TestFilterClearLatest(t *testing.T) { 19 | pver := ProtocolVersion 20 | 21 | msg := NewMsgFilterClear() 22 | 23 | // Ensure the command is expected value. 24 | wantCmd := "filterclear" 25 | if cmd := msg.Command(); cmd != wantCmd { 26 | t.Errorf("NewMsgFilterClear: wrong command - got %v want %v", 27 | cmd, wantCmd) 28 | } 29 | 30 | // Ensure max payload is expected value for latest protocol version. 31 | wantPayload := uint32(0) 32 | maxPayload := msg.MaxPayloadLength(pver) 33 | if maxPayload != wantPayload { 34 | t.Errorf("MaxPayloadLength: wrong max payload length for "+ 35 | "protocol version %d - got %v, want %v", pver, 36 | maxPayload, wantPayload) 37 | } 38 | 39 | return 40 | } 41 | 42 | // TestFilterClearWire tests the MsgFilterClear wire encode and decode for 43 | // various protocol versions. 44 | func TestFilterClearWire(t *testing.T) { 45 | msgFilterClear := NewMsgFilterClear() 46 | msgFilterClearEncoded := []byte{} 47 | 48 | tests := []struct { 49 | in *MsgFilterClear // Message to encode 50 | out *MsgFilterClear // Expected decoded message 51 | buf []byte // Wire encoding 52 | pver uint32 // Protocol version for wire encoding 53 | }{ 54 | // Latest protocol version. 55 | { 56 | msgFilterClear, 57 | msgFilterClear, 58 | msgFilterClearEncoded, 59 | ProtocolVersion, 60 | }, 61 | } 62 | 63 | t.Logf("Running %d tests", len(tests)) 64 | for i, test := range tests { 65 | // Encode the message to wire format. 66 | var buf bytes.Buffer 67 | err := test.in.BtcEncode(&buf, test.pver) 68 | if err != nil { 69 | t.Errorf("BtcEncode #%d error %v", i, err) 70 | continue 71 | } 72 | if !bytes.Equal(buf.Bytes(), test.buf) { 73 | t.Errorf("BtcEncode #%d\n got: %s want: %s", i, 74 | spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) 75 | continue 76 | } 77 | 78 | // Decode the message from wire format. 79 | var msg MsgFilterClear 80 | rbuf := bytes.NewReader(test.buf) 81 | err = msg.BtcDecode(rbuf, test.pver) 82 | if err != nil { 83 | t.Errorf("BtcDecode #%d error %v", i, err) 84 | continue 85 | } 86 | if !reflect.DeepEqual(&msg, test.out) { 87 | t.Errorf("BtcDecode #%d\n got: %s want: %s", i, 88 | spew.Sdump(msg), spew.Sdump(test.out)) 89 | continue 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /wire/msggetaddr.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 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 wire 7 | 8 | import ( 9 | "io" 10 | ) 11 | 12 | // MsgGetAddr implements the Message interface and represents a hypercash 13 | // getaddr message. It is used to request a list of known active peers on the 14 | // network from a peer to help identify potential nodes. The list is returned 15 | // via one or more addr messages (MsgAddr). 16 | // 17 | // This message has no payload. 18 | type MsgGetAddr struct{} 19 | 20 | // BtcDecode decodes r using the hypercash protocol encoding into the receiver. 21 | // This is part of the Message interface implementation. 22 | func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32) error { 23 | return nil 24 | } 25 | 26 | // BtcEncode encodes the receiver to w using the hypercash protocol encoding. 27 | // This is part of the Message interface implementation. 28 | func (msg *MsgGetAddr) BtcEncode(w io.Writer, pver uint32) error { 29 | return nil 30 | } 31 | 32 | // Command returns the protocol command string for the message. This is part 33 | // of the Message interface implementation. 34 | func (msg *MsgGetAddr) Command() string { 35 | return CmdGetAddr 36 | } 37 | 38 | // MaxPayloadLength returns the maximum length the payload can be for the 39 | // receiver. This is part of the Message interface implementation. 40 | func (msg *MsgGetAddr) MaxPayloadLength(pver uint32) uint32 { 41 | return 0 42 | } 43 | 44 | // NewMsgGetAddr returns a new hypercash getaddr message that conforms to the 45 | // Message interface. See MsgGetAddr for details. 46 | func NewMsgGetAddr() *MsgGetAddr { 47 | return &MsgGetAddr{} 48 | } 49 | -------------------------------------------------------------------------------- /wire/msggetaddr_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 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 wire 7 | 8 | import ( 9 | "bytes" 10 | "reflect" 11 | "testing" 12 | 13 | "github.com/davecgh/go-spew/spew" 14 | ) 15 | 16 | // TestGetAddr tests the MsgGetAddr API. 17 | func TestGetAddr(t *testing.T) { 18 | pver := ProtocolVersion 19 | 20 | // Ensure the command is expected value. 21 | wantCmd := "getaddr" 22 | msg := NewMsgGetAddr() 23 | if cmd := msg.Command(); cmd != wantCmd { 24 | t.Errorf("NewMsgGetAddr: wrong command - got %v want %v", 25 | cmd, wantCmd) 26 | } 27 | 28 | // Ensure max payload is expected value for latest protocol version. 29 | // Num addresses (varInt) + max allowed addresses. 30 | wantPayload := uint32(0) 31 | maxPayload := msg.MaxPayloadLength(pver) 32 | if maxPayload != wantPayload { 33 | t.Errorf("MaxPayloadLength: wrong max payload length for "+ 34 | "protocol version %d - got %v, want %v", pver, 35 | maxPayload, wantPayload) 36 | } 37 | 38 | return 39 | } 40 | 41 | // TestGetAddrWire tests the MsgGetAddr wire encode and decode for various 42 | // protocol versions. 43 | func TestGetAddrWire(t *testing.T) { 44 | msgGetAddr := NewMsgGetAddr() 45 | msgGetAddrEncoded := []byte{} 46 | 47 | tests := []struct { 48 | in *MsgGetAddr // Message to encode 49 | out *MsgGetAddr // Expected decoded message 50 | buf []byte // Wire encoding 51 | pver uint32 // Protocol version for wire encoding 52 | }{ 53 | // Latest protocol version. 54 | { 55 | msgGetAddr, 56 | msgGetAddr, 57 | msgGetAddrEncoded, 58 | ProtocolVersion, 59 | }, 60 | } 61 | 62 | t.Logf("Running %d tests", len(tests)) 63 | for i, test := range tests { 64 | // Encode the message to wire format. 65 | var buf bytes.Buffer 66 | err := test.in.BtcEncode(&buf, test.pver) 67 | if err != nil { 68 | t.Errorf("BtcEncode #%d error %v", i, err) 69 | continue 70 | } 71 | if !bytes.Equal(buf.Bytes(), test.buf) { 72 | t.Errorf("BtcEncode #%d\n got: %s want: %s", i, 73 | spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) 74 | continue 75 | } 76 | 77 | // Decode the message from wire format. 78 | var msg MsgGetAddr 79 | rbuf := bytes.NewReader(test.buf) 80 | err = msg.BtcDecode(rbuf, test.pver) 81 | if err != nil { 82 | t.Errorf("BtcDecode #%d error %v", i, err) 83 | continue 84 | } 85 | if !reflect.DeepEqual(&msg, test.out) { 86 | t.Errorf("BtcDecode #%d\n got: %s want: %s", i, 87 | spew.Sdump(msg), spew.Sdump(test.out)) 88 | continue 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /wire/msggetminingstate.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 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 wire 7 | 8 | import ( 9 | "io" 10 | ) 11 | 12 | // MsgGetMiningState implements the Message interface and represents a 13 | // getminingstate message. It is used to request the current mining state 14 | // from a peer. 15 | type MsgGetMiningState struct{} 16 | 17 | // BtcDecode decodes r using the hypercash protocol encoding into the receiver. 18 | // This is part of the Message interface implementation. 19 | func (msg *MsgGetMiningState) BtcDecode(r io.Reader, pver uint32) error { 20 | return nil 21 | } 22 | 23 | // BtcEncode encodes the receiver to w using the hypercash protocol encoding. 24 | // This is part of the Message interface implementation. 25 | func (msg *MsgGetMiningState) BtcEncode(w io.Writer, pver uint32) error { 26 | return nil 27 | } 28 | 29 | // Command returns the protocol command string for the message. This is part 30 | // of the Message interface implementation. 31 | func (msg *MsgGetMiningState) Command() string { 32 | return CmdGetMiningState 33 | } 34 | 35 | // MaxPayloadLength returns the maximum length the payload can be for the 36 | // receiver. This is part of the Message interface implementation. 37 | func (msg *MsgGetMiningState) MaxPayloadLength(pver uint32) uint32 { 38 | return 0 39 | } 40 | 41 | // NewMsgGetMiningState returns a new hypercash pong message that conforms to the Message 42 | // interface. See MsgPong for details. 43 | func NewMsgGetMiningState() *MsgGetMiningState { 44 | return &MsgGetMiningState{} 45 | } 46 | -------------------------------------------------------------------------------- /wire/msgmempool.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 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 wire 7 | 8 | import ( 9 | "io" 10 | ) 11 | 12 | // MsgMemPool implements the Message interface and represents a hypercash 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 hypercash protocol encoding into the receiver. 21 | // This is part of the Message interface implementation. 22 | func (msg *MsgMemPool) BtcDecode(r io.Reader, pver uint32) error { 23 | return nil 24 | } 25 | 26 | // BtcEncode encodes the receiver to w using the hypercash protocol encoding. 27 | // This is part of the Message interface implementation. 28 | func (msg *MsgMemPool) BtcEncode(w io.Writer, pver uint32) error { 29 | return nil 30 | } 31 | 32 | // Command returns the protocol command string for the message. This is part 33 | // of the Message interface implementation. 34 | func (msg *MsgMemPool) Command() string { 35 | return CmdMemPool 36 | } 37 | 38 | // MaxPayloadLength returns the maximum length the payload can be for the 39 | // receiver. This is part of the Message interface implementation. 40 | func (msg *MsgMemPool) MaxPayloadLength(pver uint32) uint32 { 41 | return 0 42 | } 43 | 44 | // NewMsgMemPool returns a new hypercash pong message that conforms to the Message 45 | // interface. See MsgPong for details. 46 | func NewMsgMemPool() *MsgMemPool { 47 | return &MsgMemPool{} 48 | } 49 | -------------------------------------------------------------------------------- /wire/msgmempool_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 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 wire 7 | 8 | import ( 9 | "bytes" 10 | "testing" 11 | ) 12 | 13 | func TestMemPool(t *testing.T) { 14 | pver := ProtocolVersion 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) 36 | if err != nil { 37 | t.Errorf("encode of MsgMemPool failed %v err <%v>", msg, err) 38 | } 39 | 40 | // Test decode with latest protocol version. 41 | readmsg := NewMsgMemPool() 42 | err = readmsg.BtcDecode(&buf, pver) 43 | if err != nil { 44 | t.Errorf("decode of MsgMemPool failed [%v] err <%v>", buf, err) 45 | } 46 | 47 | return 48 | } 49 | -------------------------------------------------------------------------------- /wire/msgping.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 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 wire 7 | 8 | import ( 9 | "io" 10 | ) 11 | 12 | // MsgPing implements the Message interface and represents a hypercash ping 13 | // message. 14 | // 15 | // For versions BIP0031Version and earlier, it is used primarily to confirm 16 | // that a connection is still valid. A transmission error is typically 17 | // interpreted as a closed connection and that the peer should be removed. 18 | // For versions AFTER BIP0031Version it contains an identifier which can be 19 | // returned in the pong message to determine network timing. 20 | // 21 | // The payload for this message just consists of a nonce used for identifying 22 | // it later. 23 | type MsgPing struct { 24 | // Unique value associated with message that is used to identify 25 | // specific ping message. 26 | Nonce uint64 27 | } 28 | 29 | // BtcDecode decodes r using the hypercash protocol encoding into the receiver. 30 | // This is part of the Message interface implementation. 31 | func (msg *MsgPing) BtcDecode(r io.Reader, pver uint32) error { 32 | err := readElement(r, &msg.Nonce) 33 | return err 34 | } 35 | 36 | // BtcEncode encodes the receiver to w using the hypercash protocol encoding. 37 | // This is part of the Message interface implementation. 38 | func (msg *MsgPing) BtcEncode(w io.Writer, pver uint32) error { 39 | err := writeElement(w, msg.Nonce) 40 | return err 41 | } 42 | 43 | // Command returns the protocol command string for the message. This is part 44 | // of the Message interface implementation. 45 | func (msg *MsgPing) Command() string { 46 | return CmdPing 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 *MsgPing) MaxPayloadLength(pver uint32) uint32 { 52 | plen := uint32(0) 53 | 54 | // Nonce 8 bytes. 55 | plen += 8 56 | 57 | return plen 58 | } 59 | 60 | // NewMsgPing returns a new hypercash ping message that conforms to the Message 61 | // interface. See MsgPing for details. 62 | func NewMsgPing(nonce uint64) *MsgPing { 63 | return &MsgPing{ 64 | Nonce: nonce, 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /wire/msgpong.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 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 wire 7 | 8 | import ( 9 | "io" 10 | ) 11 | 12 | // MsgPong implements the Message interface and represents a hypercash pong 13 | // message which is used primarily to confirm that a connection is still valid 14 | // in response to a hypercash 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 hypercash protocol encoding into the receiver. 24 | // This is part of the Message interface implementation. 25 | func (msg *MsgPong) BtcDecode(r io.Reader, pver uint32) error { 26 | return readElement(r, &msg.Nonce) 27 | } 28 | 29 | // BtcEncode encodes the receiver to w using the hypercash protocol encoding. 30 | // This is part of the Message interface implementation. 31 | func (msg *MsgPong) BtcEncode(w io.Writer, pver uint32) error { 32 | return writeElement(w, msg.Nonce) 33 | } 34 | 35 | // Command returns the protocol command string for the message. This is part 36 | // of the Message interface implementation. 37 | func (msg *MsgPong) Command() string { 38 | return CmdPong 39 | } 40 | 41 | // MaxPayloadLength returns the maximum length the payload can be for the 42 | // receiver. This is part of the Message interface implementation. 43 | func (msg *MsgPong) MaxPayloadLength(pver uint32) uint32 { 44 | plen := uint32(0) 45 | 46 | // Nonce 8 bytes. 47 | plen += 8 48 | 49 | return plen 50 | } 51 | 52 | // NewMsgPong returns a new hypercash pong message that conforms to the Message 53 | // interface. See MsgPong for details. 54 | func NewMsgPong(nonce uint64) *MsgPong { 55 | return &MsgPong{ 56 | Nonce: nonce, 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /wire/msgsendheaders.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The btcsuite developers 2 | // Copyright (c) 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 wire 7 | 8 | import ( 9 | "fmt" 10 | "io" 11 | ) 12 | 13 | // MsgSendHeaders implements the Message interface and represents a bitcoin 14 | // sendheaders message. It is used to request the peer send block headers 15 | // rather than inventory vectors. 16 | // 17 | // This message has no payload and was not added until protocol versions 18 | // starting with SendHeadersVersion. 19 | type MsgSendHeaders struct{} 20 | 21 | // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 22 | // This is part of the Message interface implementation. 23 | func (msg *MsgSendHeaders) BtcDecode(r io.Reader, pver uint32) error { 24 | if pver < SendHeadersVersion { 25 | str := fmt.Sprintf("sendheaders message invalid for protocol "+ 26 | "version %d", pver) 27 | return messageError("MsgSendHeaders.BtcDecode", str) 28 | } 29 | 30 | return nil 31 | } 32 | 33 | // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 34 | // This is part of the Message interface implementation. 35 | func (msg *MsgSendHeaders) BtcEncode(w io.Writer, pver uint32) error { 36 | if pver < SendHeadersVersion { 37 | str := fmt.Sprintf("sendheaders message invalid for protocol "+ 38 | "version %d", pver) 39 | return messageError("MsgSendHeaders.BtcEncode", str) 40 | } 41 | 42 | return nil 43 | } 44 | 45 | // Command returns the protocol command string for the message. This is part 46 | // of the Message interface implementation. 47 | func (msg *MsgSendHeaders) Command() string { 48 | return CmdSendHeaders 49 | } 50 | 51 | // MaxPayloadLength returns the maximum length the payload can be for the 52 | // receiver. This is part of the Message interface implementation. 53 | func (msg *MsgSendHeaders) MaxPayloadLength(pver uint32) uint32 { 54 | return 0 55 | } 56 | 57 | // NewMsgSendHeaders returns a new bitcoin sendheaders message that conforms to 58 | // the Message interface. See MsgSendHeaders for details. 59 | func NewMsgSendHeaders() *MsgSendHeaders { 60 | return &MsgSendHeaders{} 61 | } 62 | -------------------------------------------------------------------------------- /wire/msgverack.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 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 wire 7 | 8 | import ( 9 | "io" 10 | ) 11 | 12 | // MsgVerAck defines a hypercash verack message which is used for a peer to 13 | // acknowledge a version message (MsgVersion) after it has used the information 14 | // to negotiate parameters. It implements the Message interface. 15 | // 16 | // This message has no payload. 17 | type MsgVerAck struct{} 18 | 19 | // BtcDecode decodes r using the hypercash protocol encoding into the receiver. 20 | // This is part of the Message interface implementation. 21 | func (msg *MsgVerAck) BtcDecode(r io.Reader, pver uint32) error { 22 | return nil 23 | } 24 | 25 | // BtcEncode encodes the receiver to w using the hypercash protocol encoding. 26 | // This is part of the Message interface implementation. 27 | func (msg *MsgVerAck) BtcEncode(w io.Writer, pver uint32) 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 *MsgVerAck) Command() string { 34 | return CmdVerAck 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 *MsgVerAck) MaxPayloadLength(pver uint32) uint32 { 40 | return 0 41 | } 42 | 43 | // NewMsgVerAck returns a new hypercash verack message that conforms to the 44 | // Message interface. 45 | func NewMsgVerAck() *MsgVerAck { 46 | return &MsgVerAck{} 47 | } 48 | -------------------------------------------------------------------------------- /wire/msgverack_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 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 wire 7 | 8 | import ( 9 | "bytes" 10 | "reflect" 11 | "testing" 12 | 13 | "github.com/davecgh/go-spew/spew" 14 | ) 15 | 16 | // TestVerAck tests the MsgVerAck API. 17 | func TestVerAck(t *testing.T) { 18 | pver := ProtocolVersion 19 | 20 | // Ensure the command is expected value. 21 | wantCmd := "verack" 22 | msg := NewMsgVerAck() 23 | if cmd := msg.Command(); cmd != wantCmd { 24 | t.Errorf("NewMsgVerAck: wrong command - got %v want %v", 25 | cmd, wantCmd) 26 | } 27 | 28 | // Ensure max payload is expected value. 29 | wantPayload := uint32(0) 30 | maxPayload := msg.MaxPayloadLength(pver) 31 | if maxPayload != wantPayload { 32 | t.Errorf("MaxPayloadLength: wrong max payload length for "+ 33 | "protocol version %d - got %v, want %v", pver, 34 | maxPayload, wantPayload) 35 | } 36 | 37 | return 38 | } 39 | 40 | // TestVerAckWire tests the MsgVerAck wire encode and decode for various 41 | // protocol versions. 42 | func TestVerAckWire(t *testing.T) { 43 | msgVerAck := NewMsgVerAck() 44 | msgVerAckEncoded := []byte{} 45 | 46 | tests := []struct { 47 | in *MsgVerAck // Message to encode 48 | out *MsgVerAck // Expected decoded message 49 | buf []byte // Wire encoding 50 | pver uint32 // Protocol version for wire encoding 51 | }{ 52 | // Latest protocol version. 53 | { 54 | msgVerAck, 55 | msgVerAck, 56 | msgVerAckEncoded, 57 | ProtocolVersion, 58 | }, 59 | } 60 | 61 | t.Logf("Running %d tests", len(tests)) 62 | for i, test := range tests { 63 | // Encode the message to wire format. 64 | var buf bytes.Buffer 65 | err := test.in.BtcEncode(&buf, test.pver) 66 | if err != nil { 67 | t.Errorf("BtcEncode #%d error %v", i, err) 68 | continue 69 | } 70 | if !bytes.Equal(buf.Bytes(), test.buf) { 71 | t.Errorf("BtcEncode #%d\n got: %s want: %s", i, 72 | spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) 73 | continue 74 | } 75 | 76 | // Decode the message from wire format. 77 | var msg MsgVerAck 78 | rbuf := bytes.NewReader(test.buf) 79 | err = msg.BtcDecode(rbuf, test.pver) 80 | if err != nil { 81 | t.Errorf("BtcDecode #%d error %v", i, err) 82 | continue 83 | } 84 | if !reflect.DeepEqual(&msg, test.out) { 85 | t.Errorf("BtcDecode #%d\n got: %s want: %s", i, 86 | spew.Sdump(msg), spew.Sdump(test.out)) 87 | continue 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /wire/protocol_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 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 wire 7 | 8 | import "testing" 9 | 10 | // TestServiceFlagStringer tests the stringized output for service flag types. 11 | func TestServiceFlagStringer(t *testing.T) { 12 | tests := []struct { 13 | in ServiceFlag 14 | want string 15 | }{ 16 | {0, "0x0"}, 17 | {SFNodeNetwork, "SFNodeNetwork"}, 18 | {SFNodeBloom, "SFNodeBloom"}, 19 | {0xffffffff, "SFNodeNetwork|SFNodeBloom|0xfffffffc"}, 20 | } 21 | 22 | t.Logf("Running %d tests", len(tests)) 23 | for i, test := range tests { 24 | result := test.in.String() 25 | if result != test.want { 26 | t.Errorf("String #%d\n got: %s want: %s", i, result, 27 | test.want) 28 | continue 29 | } 30 | } 31 | } 32 | 33 | // TestCurrencyNetStringer tests the stringized output for hypercash net types. 34 | func TestCurrencyNetStringer(t *testing.T) { 35 | tests := []struct { 36 | in CurrencyNet 37 | want string 38 | }{ 39 | {MainNet, "MainNet"}, 40 | {TestNet2, "TestNet2"}, 41 | {SimNet, "SimNet"}, 42 | {0xffffffff, "Unknown CurrencyNet (4294967295)"}, 43 | } 44 | 45 | t.Logf("Running %d tests", len(tests)) 46 | for i, test := range tests { 47 | result := test.in.String() 48 | if result != test.want { 49 | t.Errorf("String #%d\n got: %s want: %s", i, result, 50 | test.want) 51 | continue 52 | } 53 | } 54 | } 55 | --------------------------------------------------------------------------------