aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bitcoind.cpp23
-rw-r--r--src/init.cpp2
-rw-r--r--src/main.cpp9
-rw-r--r--src/net.cpp6
-rw-r--r--src/protocol.cpp4
-rw-r--r--src/protocol.h10
-rw-r--r--src/rpc/protocol.cpp7
-rw-r--r--src/test/README.md8
-rw-r--r--src/test/bctest.py3
-rwxr-xr-xsrc/test/bitcoin-util-test.py22
-rw-r--r--src/test/data/txcreate2.json19
-rw-r--r--src/wallet/wallet.cpp78
-rw-r--r--src/wallet/wallet.h1
13 files changed, 118 insertions, 74 deletions
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index 322298d1b..25d720e1e 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -9,6 +9,7 @@
#include "chainparams.h"
#include "clientversion.h"
+#include "compat.h"
#include "rpc/server.h"
#include "init.h"
#include "noui.h"
@@ -127,29 +128,21 @@ bool AppInit(int argc, char* argv[])
fprintf(stderr, "Error: There is no RPC client functionality in bitcoind anymore. Use the bitcoin-cli utility instead.\n");
exit(1);
}
-#ifndef WIN32
if (GetBoolArg("-daemon", false))
{
+#if HAVE_DECL_DAEMON
fprintf(stdout, "Bitcoin server starting\n");
// Daemonize
- pid_t pid = fork();
- if (pid < 0)
- {
- fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
+ if (daemon(1, 0)) { // don't chdir (1), do close FDs (0)
+ fprintf(stderr, "Error: daemon() failed: %s\n", strerror(errno));
return false;
}
- if (pid > 0) // Parent process, pid is child process id
- {
- return true;
- }
- // Child process falls through to rest of initialization
-
- pid_t sid = setsid();
- if (sid < 0)
- fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
+#else
+ fprintf(stderr, "Error: -daemon is not supported on this operating system\n");
+ return false;
+#endif // HAVE_DECL_DAEMON
}
-#endif
SoftSetBoolArg("-server", true);
// Set this early so that parameter interactions go to console
diff --git a/src/init.cpp b/src/init.cpp
index cb8da06d6..cf9234795 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -324,7 +324,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME));
if (mode == HMM_BITCOIND)
{
-#ifndef WIN32
+#if HAVE_DECL_DAEMON
strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands"));
#endif
}
diff --git a/src/main.cpp b/src/main.cpp
index c33b41ac4..ab6721971 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -6253,11 +6253,12 @@ bool ProcessMessages(CNode* pfrom, CConnman& connman)
// Checksum
CDataStream& vRecv = msg.vRecv;
uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
- unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
- if (nChecksum != hdr.nChecksum)
+ if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0)
{
- LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__,
- SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
+ LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR expected %s was %s\n", __func__,
+ SanitizeString(strCommand), nMessageSize,
+ HexStr(hash.begin(), hash.begin()+CMessageHeader::CHECKSUM_SIZE),
+ HexStr(hdr.pchChecksum, hdr.pchChecksum+CMessageHeader::CHECKSUM_SIZE));
continue;
}
diff --git a/src/net.cpp b/src/net.cpp
index cce06f2d6..770e2d295 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2661,10 +2661,8 @@ void CNode::EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend)
// Set the checksum
uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
- unsigned int nChecksum = 0;
- memcpy(&nChecksum, &hash, sizeof(nChecksum));
- assert(ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
- memcpy((char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum, sizeof(nChecksum));
+ assert(ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + CMessageHeader::CHECKSUM_SIZE);
+ memcpy((char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], hash.begin(), CMessageHeader::CHECKSUM_SIZE);
LogPrint("net", "(%d bytes) peer=%d\n", nSize, id);
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 247c6c212..54ad62b1a 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -79,7 +79,7 @@ CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn)
memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
memset(pchCommand, 0, sizeof(pchCommand));
nMessageSize = -1;
- nChecksum = 0;
+ memset(pchChecksum, 0, CHECKSUM_SIZE);
}
CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
@@ -88,7 +88,7 @@ CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const
memset(pchCommand, 0, sizeof(pchCommand));
strncpy(pchCommand, pszCommand, COMMAND_SIZE);
nMessageSize = nMessageSizeIn;
- nChecksum = 0;
+ memset(pchChecksum, 0, CHECKSUM_SIZE);
}
std::string CMessageHeader::GetCommand() const
diff --git a/src/protocol.h b/src/protocol.h
index 9b474ec79..1bc1c25b3 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -45,15 +45,15 @@ public:
READWRITE(FLATDATA(pchMessageStart));
READWRITE(FLATDATA(pchCommand));
READWRITE(nMessageSize);
- READWRITE(nChecksum);
+ READWRITE(FLATDATA(pchChecksum));
}
// TODO: make private (improves encapsulation)
public:
enum {
COMMAND_SIZE = 12,
- MESSAGE_SIZE_SIZE = sizeof(int),
- CHECKSUM_SIZE = sizeof(int),
+ MESSAGE_SIZE_SIZE = 4,
+ CHECKSUM_SIZE = 4,
MESSAGE_SIZE_OFFSET = MESSAGE_START_SIZE + COMMAND_SIZE,
CHECKSUM_OFFSET = MESSAGE_SIZE_OFFSET + MESSAGE_SIZE_SIZE,
@@ -61,8 +61,8 @@ public:
};
char pchMessageStart[MESSAGE_START_SIZE];
char pchCommand[COMMAND_SIZE];
- unsigned int nMessageSize;
- unsigned int nChecksum;
+ uint32_t nMessageSize;
+ uint8_t pchChecksum[CHECKSUM_SIZE];
};
/**
diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp
index f5275062a..bb885bb5a 100644
--- a/src/rpc/protocol.cpp
+++ b/src/rpc/protocol.cpp
@@ -77,9 +77,10 @@ boost::filesystem::path GetAuthCookieFile()
bool GenerateAuthCookie(std::string *cookie_out)
{
- unsigned char rand_pwd[32];
- GetRandBytes(rand_pwd, 32);
- std::string cookie = COOKIEAUTH_USER + ":" + EncodeBase64(&rand_pwd[0],32);
+ const size_t COOKIE_SIZE = 32;
+ unsigned char rand_pwd[COOKIE_SIZE];
+ GetRandBytes(rand_pwd, COOKIE_SIZE);
+ std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd, rand_pwd+COOKIE_SIZE);
/** the umask determines what permissions are used to create this file -
* these are set to 077 in init.cpp unless overridden with -sysperms.
diff --git a/src/test/README.md b/src/test/README.md
index 61462642b..3afdefe5f 100644
--- a/src/test/README.md
+++ b/src/test/README.md
@@ -30,3 +30,11 @@ example, to run just the getarg_tests verbosely:
Run `test_bitcoin --help` for the full list.
+### bitcoin-util-test.py
+
+The test directory also contains the bitcoin-util-test.py tool, which tests bitcoin utils (currently just bitcoin-tx). This test gets run automatically during the `make check` build process. It is also possible to run the test manually from the src directory:
+
+```
+test/bitcoin-util-test.py --srcdir=[current directory]
+
+``` \ No newline at end of file
diff --git a/src/test/bctest.py b/src/test/bctest.py
index 8105b87ff..39a27fcd0 100644
--- a/src/test/bctest.py
+++ b/src/test/bctest.py
@@ -24,6 +24,9 @@ def bctest(testDir, testObj, exeext):
if "output_cmp" in testObj:
outputFn = testObj['output_cmp']
outputData = open(testDir + "/" + outputFn).read()
+ if not outputData:
+ print("Output data missing for " + outputFn)
+ sys.exit(1)
proc = subprocess.Popen(execrun, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True)
try:
outs = proc.communicate(input=inputData)
diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py
index 882b5c67b..225b3324e 100755
--- a/src/test/bitcoin-util-test.py
+++ b/src/test/bitcoin-util-test.py
@@ -6,8 +6,24 @@ from __future__ import division,print_function,unicode_literals
import os
import bctest
import buildenv
+import argparse
-if __name__ == '__main__':
- bctest.bctester(os.environ["srcdir"] + "/test/data",
- "bitcoin-util-test.json",buildenv)
+help_text="""Test framework for bitcoin utils.
+
+Runs automatically during `make check`.
+
+Can also be run manually from the src directory by specifiying the source directory:
+test/bitcoin-util-test.py --src=[srcdir]
+"""
+
+
+if __name__ == '__main__':
+ try:
+ srcdir = os.environ["srcdir"]
+ except:
+ parser = argparse.ArgumentParser(description=help_text)
+ parser.add_argument('-s', '--srcdir')
+ args = parser.parse_args()
+ srcdir = args.srcdir
+ bctest.bctester(srcdir + "/test/data", "bitcoin-util-test.json", buildenv)
diff --git a/src/test/data/txcreate2.json b/src/test/data/txcreate2.json
index e69de29bb..c56293eaf 100644
--- a/src/test/data/txcreate2.json
+++ b/src/test/data/txcreate2.json
@@ -0,0 +1,19 @@
+{
+ "txid": "cf90229625e9eb10f6be8156bf6aa5ec2eca19a42b1e05c11f3029b560a32e13",
+ "version": 1,
+ "locktime": 0,
+ "vin": [
+ ],
+ "vout": [
+ {
+ "value": 0.00,
+ "n": 0,
+ "scriptPubKey": {
+ "asm": "",
+ "hex": "",
+ "type": "nonstandard"
+ }
+ }
+ ],
+ "hex": "01000000000100000000000000000000000000"
+}
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 43e22383f..a1f69dd94 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -100,43 +100,7 @@ CPubKey CWallet::GenerateNewKey()
// use HD key derivation if HD was enabled during wallet creation
if (IsHDEnabled()) {
- // for now we use a fixed keypath scheme of m/0'/0'/k
- CKey key; //master key seed (256bit)
- CExtKey masterKey; //hd master key
- CExtKey accountKey; //key at m/0'
- CExtKey externalChainChildKey; //key at m/0'/0'
- CExtKey childKey; //key at m/0'/0'/<n>'
-
- // try to get the master key
- if (!GetKey(hdChain.masterKeyID, key))
- throw std::runtime_error(std::string(__func__) + ": Master key not found");
-
- masterKey.SetMaster(key.begin(), key.size());
-
- // derive m/0'
- // use hardened derivation (child keys >= 0x80000000 are hardened after bip32)
- masterKey.Derive(accountKey, BIP32_HARDENED_KEY_LIMIT);
-
- // derive m/0'/0'
- accountKey.Derive(externalChainChildKey, BIP32_HARDENED_KEY_LIMIT);
-
- // derive child key at next index, skip keys already known to the wallet
- do
- {
- // always derive hardened keys
- // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range
- // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649
- externalChainChildKey.Derive(childKey, hdChain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
- metadata.hdKeypath = "m/0'/0'/"+std::to_string(hdChain.nExternalChainCounter)+"'";
- metadata.hdMasterKeyID = hdChain.masterKeyID;
- // increment childkey index
- hdChain.nExternalChainCounter++;
- } while(HaveKey(childKey.key.GetPubKey().GetID()));
- secret = childKey.key;
-
- // update the chain model in the database
- if (!CWalletDB(strWalletFile).WriteHDChain(hdChain))
- throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed");
+ DeriveNewChildKey(metadata, secret);
} else {
secret.MakeNewKey(fCompressed);
}
@@ -157,6 +121,46 @@ CPubKey CWallet::GenerateNewKey()
return pubkey;
}
+void CWallet::DeriveNewChildKey(CKeyMetadata& metadata, CKey& secret)
+{
+ // for now we use a fixed keypath scheme of m/0'/0'/k
+ CKey key; //master key seed (256bit)
+ CExtKey masterKey; //hd master key
+ CExtKey accountKey; //key at m/0'
+ CExtKey externalChainChildKey; //key at m/0'/0'
+ CExtKey childKey; //key at m/0'/0'/<n>'
+
+ // try to get the master key
+ if (!GetKey(hdChain.masterKeyID, key))
+ throw std::runtime_error(std::string(__func__) + ": Master key not found");
+
+ masterKey.SetMaster(key.begin(), key.size());
+
+ // derive m/0'
+ // use hardened derivation (child keys >= 0x80000000 are hardened after bip32)
+ masterKey.Derive(accountKey, BIP32_HARDENED_KEY_LIMIT);
+
+ // derive m/0'/0'
+ accountKey.Derive(externalChainChildKey, BIP32_HARDENED_KEY_LIMIT);
+
+ // derive child key at next index, skip keys already known to the wallet
+ do {
+ // always derive hardened keys
+ // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range
+ // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649
+ externalChainChildKey.Derive(childKey, hdChain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
+ metadata.hdKeypath = "m/0'/0'/" + std::to_string(hdChain.nExternalChainCounter) + "'";
+ metadata.hdMasterKeyID = hdChain.masterKeyID;
+ // increment childkey index
+ hdChain.nExternalChainCounter++;
+ } while (HaveKey(childKey.key.GetPubKey().GetID()));
+ secret = childKey.key;
+
+ // update the chain model in the database
+ if (!CWalletDB(strWalletFile).WriteHDChain(hdChain))
+ throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed");
+}
+
bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
{
AssertLockHeld(cs_wallet); // mapKeyMetadata
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index c700e0ca7..077edcab2 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -698,6 +698,7 @@ public:
* Generate a new key
*/
CPubKey GenerateNewKey();
+ void DeriveNewChildKey(CKeyMetadata& metadata, CKey& secret);
//! Adds a key to the store, and saves it to disk.
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
//! Adds a key to the store, without saving it to disk (used by LoadWallet)