mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-23 13:24:18 +00:00
Merge pull request #3332
5094f8d Split off rpc_wallet_tests (Wladimir J. van der Laan) 829c920 Move CCryptoKeyStore to crypter.cpp (Wladimir J. van der Laan) ae6ea5a Update build-unix.md to mention --disable-wallet (Wladimir J. van der Laan) 4f9e993 Add --disable-wallet option to build system (Wladimir J. van der Laan) d004d72 Move CAddrDB frrom db to net (Wladimir J. van der Laan) 48ba56c Delimit code with #ifdef ENABLE_WALLET (Wladimir J. van der Laan) 991685d Move getinfo to rpcnet.cpp (Wladimir J. van der Laan) bbb0936 Move HelpExample* from rpcwallet to rpcserver (Wladimir J. van der Laan)
This commit is contained in:
commit
05e27c6641
28
configure.ac
28
configure.ac
@ -37,6 +37,13 @@ AM_MAINTAINER_MODE([enable])
|
|||||||
dnl make the compilation flags quiet unless V=1 is used
|
dnl make the compilation flags quiet unless V=1 is used
|
||||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||||
|
|
||||||
|
# Enable wallet
|
||||||
|
AC_ARG_ENABLE([wallet],
|
||||||
|
[AS_HELP_STRING([--enable-wallet],
|
||||||
|
[enable wallet (default is yes)])],
|
||||||
|
[enable_wallet=$enableval],
|
||||||
|
[enable_wallet=yes])
|
||||||
|
|
||||||
AC_ARG_WITH([miniupnpc],
|
AC_ARG_WITH([miniupnpc],
|
||||||
[AS_HELP_STRING([--with-miniupnpc],
|
[AS_HELP_STRING([--with-miniupnpc],
|
||||||
[enable UPNP (default is yes if libminiupnpc is found)])],
|
[enable UPNP (default is yes if libminiupnpc is found)])],
|
||||||
@ -362,8 +369,10 @@ AC_TRY_COMPILE([#include <sys/socket.h>],
|
|||||||
[ AC_MSG_RESULT(no)]
|
[ AC_MSG_RESULT(no)]
|
||||||
)
|
)
|
||||||
|
|
||||||
dnl Check for libdb_cxx
|
if test x$enable_wallet != xno; then
|
||||||
BITCOIN_FIND_BDB48
|
dnl Check for libdb_cxx only if wallet enabled
|
||||||
|
BITCOIN_FIND_BDB48
|
||||||
|
fi
|
||||||
|
|
||||||
dnl Check for libminiupnpc (optional)
|
dnl Check for libminiupnpc (optional)
|
||||||
if test x$use_upnp != xno; then
|
if test x$use_upnp != xno; then
|
||||||
@ -593,6 +602,20 @@ if test "x$use_ccache" != "xno"; then
|
|||||||
AC_MSG_RESULT($use_ccache)
|
AC_MSG_RESULT($use_ccache)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl enable wallet
|
||||||
|
AC_MSG_CHECKING([if wallet should be enabled])
|
||||||
|
if test x$enable_wallet != xno; then
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE_UNQUOTED([ENABLE_WALLET],[1],[Define to 1 to enable wallet functions])
|
||||||
|
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
|
if test "x$use_qt" != "xno"; then
|
||||||
|
AC_MSG_ERROR([Cannot currently build Qt GUI with wallet disabled. Use --without-qt.])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
dnl enable ipv6 support
|
dnl enable ipv6 support
|
||||||
AC_MSG_CHECKING([if ipv6 should be enabled])
|
AC_MSG_CHECKING([if ipv6 should be enabled])
|
||||||
if test x$have_ipv6 = xno; then
|
if test x$have_ipv6 = xno; then
|
||||||
@ -705,6 +728,7 @@ fi
|
|||||||
|
|
||||||
AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin])
|
AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin])
|
||||||
AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows])
|
AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows])
|
||||||
|
AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet == xyes])
|
||||||
AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes])
|
AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes])
|
||||||
AM_CONDITIONAL([USE_LCOV],[test x$use_lcov == xyes])
|
AM_CONDITIONAL([USE_LCOV],[test x$use_lcov == xyes])
|
||||||
AM_CONDITIONAL([USE_COMPARISON_TOOL],[test x$use_comparison_tool != xno])
|
AM_CONDITIONAL([USE_COMPARISON_TOOL],[test x$use_comparison_tool != xno])
|
||||||
|
@ -22,7 +22,7 @@ Dependencies
|
|||||||
Library Purpose Description
|
Library Purpose Description
|
||||||
------- ------- -----------
|
------- ------- -----------
|
||||||
libssl SSL Support Secure communications
|
libssl SSL Support Secure communications
|
||||||
libdb4.8 Berkeley DB Blockchain & wallet storage
|
libdb4.8 Berkeley DB Wallet storage
|
||||||
libboost Boost C++ Library
|
libboost Boost C++ Library
|
||||||
miniupnpc UPnP Support Optional firewall-jumping support
|
miniupnpc UPnP Support Optional firewall-jumping support
|
||||||
qt GUI GUI toolkit
|
qt GUI GUI toolkit
|
||||||
@ -178,3 +178,12 @@ Hardening enables the following features:
|
|||||||
RW- R-- RW-
|
RW- R-- RW-
|
||||||
|
|
||||||
The STK RW- means that the stack is readable and writeable but not executable.
|
The STK RW- means that the stack is readable and writeable but not executable.
|
||||||
|
|
||||||
|
Disable-wallet mode
|
||||||
|
--------------------
|
||||||
|
When the intention is to run only a P2P node without a wallet, bitcoin may be compiled in
|
||||||
|
disable-wallet mode with:
|
||||||
|
|
||||||
|
./configure --disable-wallet
|
||||||
|
|
||||||
|
In this case there is no dependency on Berkeley DB 4.8.
|
||||||
|
@ -4,6 +4,9 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/leveldb/helpers/memenv \
|
|||||||
-I$(builddir)
|
-I$(builddir)
|
||||||
|
|
||||||
noinst_LIBRARIES = libbitcoin_server.a libbitcoin_common.a libbitcoin_cli.a
|
noinst_LIBRARIES = libbitcoin_server.a libbitcoin_common.a libbitcoin_cli.a
|
||||||
|
if ENABLE_WALLET
|
||||||
|
noinst_LIBRARIES += libbitcoin_wallet.a
|
||||||
|
endif
|
||||||
|
|
||||||
bin_PROGRAMS = bitcoind bitcoin-cli
|
bin_PROGRAMS = bitcoind bitcoin-cli
|
||||||
|
|
||||||
@ -33,14 +36,37 @@ obj/build.h: FORCE
|
|||||||
$(abs_top_srcdir)
|
$(abs_top_srcdir)
|
||||||
version.o: obj/build.h
|
version.o: obj/build.h
|
||||||
|
|
||||||
libbitcoin_server_a_SOURCES = addrman.cpp alert.cpp \
|
libbitcoin_server_a_SOURCES = \
|
||||||
|
addrman.cpp \
|
||||||
|
alert.cpp \
|
||||||
rpcserver.cpp \
|
rpcserver.cpp \
|
||||||
bloom.cpp \
|
bloom.cpp \
|
||||||
chainparams.cpp checkpoints.cpp coins.cpp crypter.cpp db.cpp \
|
chainparams.cpp \
|
||||||
init.cpp keystore.cpp leveldbwrapper.cpp main.cpp miner.cpp \
|
checkpoints.cpp \
|
||||||
net.cpp noui.cpp rpcblockchain.cpp rpcdump.cpp \
|
coins.cpp \
|
||||||
rpcmining.cpp rpcnet.cpp rpcrawtransaction.cpp rpcwallet.cpp \
|
init.cpp \
|
||||||
txdb.cpp txmempool.cpp wallet.cpp walletdb.cpp $(JSON_H) \
|
keystore.cpp \
|
||||||
|
leveldbwrapper.cpp \
|
||||||
|
main.cpp \
|
||||||
|
net.cpp \
|
||||||
|
noui.cpp \
|
||||||
|
rpcblockchain.cpp \
|
||||||
|
rpcnet.cpp \
|
||||||
|
rpcrawtransaction.cpp \
|
||||||
|
txdb.cpp \
|
||||||
|
txmempool.cpp \
|
||||||
|
$(JSON_H) \
|
||||||
|
$(BITCOIN_CORE_H)
|
||||||
|
|
||||||
|
libbitcoin_wallet_a_SOURCES = \
|
||||||
|
db.cpp \
|
||||||
|
crypter.cpp \
|
||||||
|
miner.cpp \
|
||||||
|
rpcdump.cpp \
|
||||||
|
rpcmining.cpp \
|
||||||
|
rpcwallet.cpp \
|
||||||
|
wallet.cpp \
|
||||||
|
walletdb.cpp \
|
||||||
$(BITCOIN_CORE_H)
|
$(BITCOIN_CORE_H)
|
||||||
|
|
||||||
libbitcoin_common_a_SOURCES = \
|
libbitcoin_common_a_SOURCES = \
|
||||||
@ -68,6 +94,9 @@ nodist_libbitcoin_common_a_SOURCES = $(top_srcdir)/src/obj/build.h
|
|||||||
# bitcoind binary #
|
# bitcoind binary #
|
||||||
bitcoind_LDADD = libbitcoin_server.a libbitcoin_cli.a libbitcoin_common.a leveldb/libleveldb.a leveldb/libmemenv.a \
|
bitcoind_LDADD = libbitcoin_server.a libbitcoin_cli.a libbitcoin_common.a leveldb/libleveldb.a leveldb/libmemenv.a \
|
||||||
$(BOOST_LIBS)
|
$(BOOST_LIBS)
|
||||||
|
if ENABLE_WALLET
|
||||||
|
bitcoind_LDADD += libbitcoin_wallet.a
|
||||||
|
endif
|
||||||
bitcoind_SOURCES = bitcoind.cpp
|
bitcoind_SOURCES = bitcoind.cpp
|
||||||
#
|
#
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ AM_CPPFLAGS = $(INCLUDES) \
|
|||||||
AM_LDFLAGS = $(PTHREAD_CFLAGS)
|
AM_LDFLAGS = $(PTHREAD_CFLAGS)
|
||||||
|
|
||||||
LIBBITCOIN_SERVER=$(top_builddir)/src/libbitcoin_server.a
|
LIBBITCOIN_SERVER=$(top_builddir)/src/libbitcoin_server.a
|
||||||
|
LIBBITCOIN_WALLET=$(top_builddir)/src/libbitcoin_wallet.a
|
||||||
LIBBITCOIN_COMMON=$(top_builddir)/src/libbitcoin_common.a
|
LIBBITCOIN_COMMON=$(top_builddir)/src/libbitcoin_common.a
|
||||||
LIBBITCOIN_CLI=$(top_builddir)/src/libbitcoin_cli.a
|
LIBBITCOIN_CLI=$(top_builddir)/src/libbitcoin_cli.a
|
||||||
LIBLEVELDB=$(top_builddir)/src/leveldb/libleveldb.a
|
LIBLEVELDB=$(top_builddir)/src/leveldb/libleveldb.a
|
||||||
|
157
src/crypter.cpp
157
src/crypter.cpp
@ -4,9 +4,11 @@
|
|||||||
|
|
||||||
#include "crypter.h"
|
#include "crypter.h"
|
||||||
|
|
||||||
|
#include "script.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
#include <openssl/aes.h>
|
#include <openssl/aes.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
@ -117,3 +119,156 @@ bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned
|
|||||||
return false;
|
return false;
|
||||||
return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
|
return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CCryptoKeyStore::SetCrypted()
|
||||||
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
|
if (fUseCrypto)
|
||||||
|
return true;
|
||||||
|
if (!mapKeys.empty())
|
||||||
|
return false;
|
||||||
|
fUseCrypto = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCryptoKeyStore::Lock()
|
||||||
|
{
|
||||||
|
if (!SetCrypted())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
|
vMasterKey.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
NotifyStatusChanged(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
|
if (!SetCrypted())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
|
||||||
|
for (; mi != mapCryptedKeys.end(); ++mi)
|
||||||
|
{
|
||||||
|
const CPubKey &vchPubKey = (*mi).second.first;
|
||||||
|
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
||||||
|
CKeyingMaterial vchSecret;
|
||||||
|
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
||||||
|
return false;
|
||||||
|
if (vchSecret.size() != 32)
|
||||||
|
return false;
|
||||||
|
CKey key;
|
||||||
|
key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
|
||||||
|
if (key.GetPubKey() == vchPubKey)
|
||||||
|
break;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vMasterKey = vMasterKeyIn;
|
||||||
|
}
|
||||||
|
NotifyStatusChanged(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCryptoKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
|
if (!IsCrypted())
|
||||||
|
return CBasicKeyStore::AddKeyPubKey(key, pubkey);
|
||||||
|
|
||||||
|
if (IsLocked())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::vector<unsigned char> vchCryptedSecret;
|
||||||
|
CKeyingMaterial vchSecret(key.begin(), key.end());
|
||||||
|
if (!EncryptSecret(vMasterKey, vchSecret, pubkey.GetHash(), vchCryptedSecret))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!AddCryptedKey(pubkey, vchCryptedSecret))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
|
if (!SetCrypted())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
|
if (!IsCrypted())
|
||||||
|
return CBasicKeyStore::GetKey(address, keyOut);
|
||||||
|
|
||||||
|
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
||||||
|
if (mi != mapCryptedKeys.end())
|
||||||
|
{
|
||||||
|
const CPubKey &vchPubKey = (*mi).second.first;
|
||||||
|
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
||||||
|
CKeyingMaterial vchSecret;
|
||||||
|
if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
||||||
|
return false;
|
||||||
|
if (vchSecret.size() != 32)
|
||||||
|
return false;
|
||||||
|
keyOut.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
|
if (!IsCrypted())
|
||||||
|
return CKeyStore::GetPubKey(address, vchPubKeyOut);
|
||||||
|
|
||||||
|
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
||||||
|
if (mi != mapCryptedKeys.end())
|
||||||
|
{
|
||||||
|
vchPubKeyOut = (*mi).second.first;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
|
if (!mapCryptedKeys.empty() || IsCrypted())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
fUseCrypto = true;
|
||||||
|
BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
|
||||||
|
{
|
||||||
|
const CKey &key = mKey.second;
|
||||||
|
CPubKey vchPubKey = key.GetPubKey();
|
||||||
|
CKeyingMaterial vchSecret(key.begin(), key.end());
|
||||||
|
std::vector<unsigned char> vchCryptedSecret;
|
||||||
|
if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(), vchCryptedSecret))
|
||||||
|
return false;
|
||||||
|
if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mapKeys.clear();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "allocators.h"
|
#include "allocators.h"
|
||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
|
#include "keystore.h"
|
||||||
|
|
||||||
class uint256;
|
class uint256;
|
||||||
|
|
||||||
@ -106,4 +107,86 @@ public:
|
|||||||
bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext);
|
bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext);
|
||||||
bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext);
|
bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext);
|
||||||
|
|
||||||
|
/** Keystore which keeps the private keys encrypted.
|
||||||
|
* It derives from the basic key store, which is used if no encryption is active.
|
||||||
|
*/
|
||||||
|
class CCryptoKeyStore : public CBasicKeyStore
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
CryptedKeyMap mapCryptedKeys;
|
||||||
|
|
||||||
|
CKeyingMaterial vMasterKey;
|
||||||
|
|
||||||
|
// if fUseCrypto is true, mapKeys must be empty
|
||||||
|
// if fUseCrypto is false, vMasterKey must be empty
|
||||||
|
bool fUseCrypto;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool SetCrypted();
|
||||||
|
|
||||||
|
// will encrypt previously unencrypted keys
|
||||||
|
bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
|
||||||
|
|
||||||
|
bool Unlock(const CKeyingMaterial& vMasterKeyIn);
|
||||||
|
|
||||||
|
public:
|
||||||
|
CCryptoKeyStore() : fUseCrypto(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsCrypted() const
|
||||||
|
{
|
||||||
|
return fUseCrypto;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLocked() const
|
||||||
|
{
|
||||||
|
if (!IsCrypted())
|
||||||
|
return false;
|
||||||
|
bool result;
|
||||||
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
|
result = vMasterKey.empty();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lock();
|
||||||
|
|
||||||
|
virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
||||||
|
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
|
||||||
|
bool HaveKey(const CKeyID &address) const
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
|
if (!IsCrypted())
|
||||||
|
return CBasicKeyStore::HaveKey(address);
|
||||||
|
return mapCryptedKeys.count(address) > 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool GetKey(const CKeyID &address, CKey& keyOut) const;
|
||||||
|
bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
|
||||||
|
void GetKeys(std::set<CKeyID> &setAddress) const
|
||||||
|
{
|
||||||
|
if (!IsCrypted())
|
||||||
|
{
|
||||||
|
CBasicKeyStore::GetKeys(setAddress);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setAddress.clear();
|
||||||
|
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
|
||||||
|
while (mi != mapCryptedKeys.end())
|
||||||
|
{
|
||||||
|
setAddress.insert((*mi).first);
|
||||||
|
mi++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wallet status (encrypted, locked) changed.
|
||||||
|
* Note: Called without locks held.
|
||||||
|
*/
|
||||||
|
boost::signals2::signal<void (CCryptoKeyStore* wallet)> NotifyStatusChanged;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
110
src/db.cpp
110
src/db.cpp
@ -479,113 +479,3 @@ void CDBEnv::Flush(bool fShutdown)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// CAddrDB
|
|
||||||
//
|
|
||||||
|
|
||||||
CAddrDB::CAddrDB()
|
|
||||||
{
|
|
||||||
pathAddr = GetDataDir() / "peers.dat";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CAddrDB::Write(const CAddrMan& addr)
|
|
||||||
{
|
|
||||||
// Generate random temporary filename
|
|
||||||
unsigned short randv = 0;
|
|
||||||
RAND_bytes((unsigned char *)&randv, sizeof(randv));
|
|
||||||
std::string tmpfn = strprintf("peers.dat.%04x", randv);
|
|
||||||
|
|
||||||
// serialize addresses, checksum data up to that point, then append csum
|
|
||||||
CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
|
|
||||||
ssPeers << FLATDATA(Params().MessageStart());
|
|
||||||
ssPeers << addr;
|
|
||||||
uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
|
|
||||||
ssPeers << hash;
|
|
||||||
|
|
||||||
// open temp output file, and associate with CAutoFile
|
|
||||||
boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
|
|
||||||
FILE *file = fopen(pathTmp.string().c_str(), "wb");
|
|
||||||
CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION);
|
|
||||||
if (!fileout)
|
|
||||||
return error("CAddrman::Write() : open failed");
|
|
||||||
|
|
||||||
// Write and commit header, data
|
|
||||||
try {
|
|
||||||
fileout << ssPeers;
|
|
||||||
}
|
|
||||||
catch (std::exception &e) {
|
|
||||||
return error("CAddrman::Write() : I/O error");
|
|
||||||
}
|
|
||||||
FileCommit(fileout);
|
|
||||||
fileout.fclose();
|
|
||||||
|
|
||||||
// replace existing peers.dat, if any, with new peers.dat.XXXX
|
|
||||||
if (!RenameOver(pathTmp, pathAddr))
|
|
||||||
return error("CAddrman::Write() : Rename-into-place failed");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CAddrDB::Read(CAddrMan& addr)
|
|
||||||
{
|
|
||||||
// open input file, and associate with CAutoFile
|
|
||||||
FILE *file = fopen(pathAddr.string().c_str(), "rb");
|
|
||||||
CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION);
|
|
||||||
if (!filein)
|
|
||||||
return error("CAddrman::Read() : open failed");
|
|
||||||
|
|
||||||
// use file size to size memory buffer
|
|
||||||
int fileSize = GetFilesize(filein);
|
|
||||||
int dataSize = fileSize - sizeof(uint256);
|
|
||||||
//Don't try to resize to a negative number if file is small
|
|
||||||
if ( dataSize < 0 ) dataSize = 0;
|
|
||||||
vector<unsigned char> vchData;
|
|
||||||
vchData.resize(dataSize);
|
|
||||||
uint256 hashIn;
|
|
||||||
|
|
||||||
// read data and checksum from file
|
|
||||||
try {
|
|
||||||
filein.read((char *)&vchData[0], dataSize);
|
|
||||||
filein >> hashIn;
|
|
||||||
}
|
|
||||||
catch (std::exception &e) {
|
|
||||||
return error("CAddrman::Read() 2 : I/O error or stream data corrupted");
|
|
||||||
}
|
|
||||||
filein.fclose();
|
|
||||||
|
|
||||||
CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
|
|
||||||
|
|
||||||
// verify stored checksum matches input data
|
|
||||||
uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
|
|
||||||
if (hashIn != hashTmp)
|
|
||||||
return error("CAddrman::Read() : checksum mismatch; data corrupted");
|
|
||||||
|
|
||||||
unsigned char pchMsgTmp[4];
|
|
||||||
try {
|
|
||||||
// de-serialize file header (network specific magic number) and ..
|
|
||||||
ssPeers >> FLATDATA(pchMsgTmp);
|
|
||||||
|
|
||||||
// ... verify the network matches ours
|
|
||||||
if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
|
|
||||||
return error("CAddrman::Read() : invalid network magic number");
|
|
||||||
|
|
||||||
// de-serialize address data into one CAddrMan object
|
|
||||||
ssPeers >> addr;
|
|
||||||
}
|
|
||||||
catch (std::exception &e) {
|
|
||||||
return error("CAddrman::Read() : I/O error or stream data corrupted");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
18
src/db.h
18
src/db.h
@ -305,22 +305,4 @@ public:
|
|||||||
bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
|
bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Access to the (IP) address database (peers.dat) */
|
|
||||||
class CAddrDB
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
boost::filesystem::path pathAddr;
|
|
||||||
public:
|
|
||||||
CAddrDB();
|
|
||||||
bool Write(const CAddrMan& addr);
|
|
||||||
bool Read(CAddrMan& addr);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BITCOIN_DB_H
|
#endif // BITCOIN_DB_H
|
||||||
|
41
src/init.cpp
41
src/init.cpp
@ -10,6 +10,7 @@
|
|||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
|
||||||
#include "addrman.h"
|
#include "addrman.h"
|
||||||
|
#include "db.h"
|
||||||
#include "rpcserver.h"
|
#include "rpcserver.h"
|
||||||
#include "checkpoints.h"
|
#include "checkpoints.h"
|
||||||
#include "miner.h"
|
#include "miner.h"
|
||||||
@ -17,8 +18,10 @@
|
|||||||
#include "txdb.h"
|
#include "txdb.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
#include "wallet.h"
|
#include "wallet.h"
|
||||||
#include "walletdb.h"
|
#include "walletdb.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -35,8 +38,10 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
std::string strWalletFile;
|
std::string strWalletFile;
|
||||||
CWallet* pwalletMain;
|
CWallet* pwalletMain;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
|
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
|
||||||
@ -108,15 +113,19 @@ void Shutdown()
|
|||||||
RenameThread("bitcoin-shutoff");
|
RenameThread("bitcoin-shutoff");
|
||||||
mempool.AddTransactionsUpdated(1);
|
mempool.AddTransactionsUpdated(1);
|
||||||
StopRPCThreads();
|
StopRPCThreads();
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
ShutdownRPCMining();
|
ShutdownRPCMining();
|
||||||
if (pwalletMain)
|
if (pwalletMain)
|
||||||
bitdb.Flush(false);
|
bitdb.Flush(false);
|
||||||
GenerateBitcoins(false, NULL, 0);
|
GenerateBitcoins(false, NULL, 0);
|
||||||
|
#endif
|
||||||
StopNode();
|
StopNode();
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
if (pwalletMain)
|
if (pwalletMain)
|
||||||
pwalletMain->SetBestChain(chainActive.GetLocator());
|
pwalletMain->SetBestChain(chainActive.GetLocator());
|
||||||
|
#endif
|
||||||
if (pblocktree)
|
if (pblocktree)
|
||||||
pblocktree->Flush();
|
pblocktree->Flush();
|
||||||
if (pcoinsTip)
|
if (pcoinsTip)
|
||||||
@ -125,12 +134,16 @@ void Shutdown()
|
|||||||
delete pcoinsdbview; pcoinsdbview = NULL;
|
delete pcoinsdbview; pcoinsdbview = NULL;
|
||||||
delete pblocktree; pblocktree = NULL;
|
delete pblocktree; pblocktree = NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
if (pwalletMain)
|
if (pwalletMain)
|
||||||
bitdb.Flush(true);
|
bitdb.Flush(true);
|
||||||
|
#endif
|
||||||
boost::filesystem::remove(GetPidFile());
|
boost::filesystem::remove(GetPidFile());
|
||||||
UnregisterAllWallets();
|
UnregisterAllWallets();
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
if (pwalletMain)
|
if (pwalletMain)
|
||||||
delete pwalletMain;
|
delete pwalletMain;
|
||||||
|
#endif
|
||||||
LogPrintf("Shutdown : done\n");
|
LogPrintf("Shutdown : done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,7 +492,9 @@ bool AppInit2(boost::thread_group& threadGroup, bool fForceServer)
|
|||||||
fPrintToConsole = GetBoolArg("-printtoconsole", false);
|
fPrintToConsole = GetBoolArg("-printtoconsole", false);
|
||||||
fPrintToDebugger = GetBoolArg("-printtodebugger", false);
|
fPrintToDebugger = GetBoolArg("-printtodebugger", false);
|
||||||
fLogTimestamps = GetBoolArg("-logtimestamps", true);
|
fLogTimestamps = GetBoolArg("-logtimestamps", true);
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
bool fDisableWallet = GetBoolArg("-disablewallet", false);
|
bool fDisableWallet = GetBoolArg("-disablewallet", false);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mapArgs.count("-timeout"))
|
if (mapArgs.count("-timeout"))
|
||||||
{
|
{
|
||||||
@ -525,16 +540,17 @@ bool AppInit2(boost::thread_group& threadGroup, bool fForceServer)
|
|||||||
InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
|
InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
strWalletFile = GetArg("-wallet", "wallet.dat");
|
strWalletFile = GetArg("-wallet", "wallet.dat");
|
||||||
|
#endif
|
||||||
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
|
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
|
||||||
|
|
||||||
std::string strDataDir = GetDataDir().string();
|
std::string strDataDir = GetDataDir().string();
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
// Wallet file must be a plain filename without a directory
|
// Wallet file must be a plain filename without a directory
|
||||||
if (strWalletFile != boost::filesystem::basename(strWalletFile) + boost::filesystem::extension(strWalletFile))
|
if (strWalletFile != boost::filesystem::basename(strWalletFile) + boost::filesystem::extension(strWalletFile))
|
||||||
return InitError(strprintf(_("Wallet %s resides outside data directory %s"), strWalletFile.c_str(), strDataDir.c_str()));
|
return InitError(strprintf(_("Wallet %s resides outside data directory %s"), strWalletFile.c_str(), strDataDir.c_str()));
|
||||||
|
#endif
|
||||||
// Make sure only a single Bitcoin process is using the data directory.
|
// Make sure only a single Bitcoin process is using the data directory.
|
||||||
boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
|
boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
|
||||||
FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
|
FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
|
||||||
@ -567,7 +583,7 @@ bool AppInit2(boost::thread_group& threadGroup, bool fForceServer)
|
|||||||
int64_t nStart;
|
int64_t nStart;
|
||||||
|
|
||||||
// ********************************************************* Step 5: verify wallet database integrity
|
// ********************************************************* Step 5: verify wallet database integrity
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
if (!fDisableWallet) {
|
if (!fDisableWallet) {
|
||||||
uiInterface.InitMessage(_("Verifying wallet..."));
|
uiInterface.InitMessage(_("Verifying wallet..."));
|
||||||
|
|
||||||
@ -613,7 +629,7 @@ bool AppInit2(boost::thread_group& threadGroup, bool fForceServer)
|
|||||||
return InitError(_("wallet.dat corrupt, salvage failed"));
|
return InitError(_("wallet.dat corrupt, salvage failed"));
|
||||||
}
|
}
|
||||||
} // (!fDisableWallet)
|
} // (!fDisableWallet)
|
||||||
|
#endif // ENABLE_WALLET
|
||||||
// ********************************************************* Step 6: network initialization
|
// ********************************************************* Step 6: network initialization
|
||||||
|
|
||||||
RegisterNodeSignals(GetNodeSignals());
|
RegisterNodeSignals(GetNodeSignals());
|
||||||
@ -880,7 +896,7 @@ bool AppInit2(boost::thread_group& threadGroup, bool fForceServer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ********************************************************* Step 8: load wallet
|
// ********************************************************* Step 8: load wallet
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
if (fDisableWallet) {
|
if (fDisableWallet) {
|
||||||
pwalletMain = NULL;
|
pwalletMain = NULL;
|
||||||
LogPrintf("Wallet disabled!\n");
|
LogPrintf("Wallet disabled!\n");
|
||||||
@ -972,7 +988,9 @@ bool AppInit2(boost::thread_group& threadGroup, bool fForceServer)
|
|||||||
nWalletDBUpdated++;
|
nWalletDBUpdated++;
|
||||||
}
|
}
|
||||||
} // (!fDisableWallet)
|
} // (!fDisableWallet)
|
||||||
|
#else // ENABLE_WALLET
|
||||||
|
LogPrintf("No wallet compiled in!\n");
|
||||||
|
#endif // !ENABLE_WALLET
|
||||||
// ********************************************************* Step 9: import blocks
|
// ********************************************************* Step 9: import blocks
|
||||||
|
|
||||||
// scan for better chains in the block chain database, that are not yet connected in the active best chain
|
// scan for better chains in the block chain database, that are not yet connected in the active best chain
|
||||||
@ -1016,25 +1034,31 @@ bool AppInit2(boost::thread_group& threadGroup, bool fForceServer)
|
|||||||
//// debug print
|
//// debug print
|
||||||
LogPrintf("mapBlockIndex.size() = %"PRIszu"\n", mapBlockIndex.size());
|
LogPrintf("mapBlockIndex.size() = %"PRIszu"\n", mapBlockIndex.size());
|
||||||
LogPrintf("nBestHeight = %d\n", chainActive.Height());
|
LogPrintf("nBestHeight = %d\n", chainActive.Height());
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
LogPrintf("setKeyPool.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0);
|
LogPrintf("setKeyPool.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0);
|
||||||
LogPrintf("mapWallet.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->mapWallet.size() : 0);
|
LogPrintf("mapWallet.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->mapWallet.size() : 0);
|
||||||
LogPrintf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0);
|
LogPrintf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
StartNode(threadGroup);
|
StartNode(threadGroup);
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
// InitRPCMining is needed here so getwork/getblocktemplate in the GUI debug console works properly.
|
// InitRPCMining is needed here so getwork/getblocktemplate in the GUI debug console works properly.
|
||||||
InitRPCMining();
|
InitRPCMining();
|
||||||
|
#endif
|
||||||
if (fServer)
|
if (fServer)
|
||||||
StartRPCThreads();
|
StartRPCThreads();
|
||||||
|
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
// Generate coins in the background
|
// Generate coins in the background
|
||||||
if (pwalletMain)
|
if (pwalletMain)
|
||||||
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", -1));
|
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", -1));
|
||||||
|
#endif
|
||||||
|
|
||||||
// ********************************************************* Step 12: finished
|
// ********************************************************* Step 12: finished
|
||||||
|
|
||||||
uiInterface.InitMessage(_("Done loading"));
|
uiInterface.InitMessage(_("Done loading"));
|
||||||
|
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
if (pwalletMain) {
|
if (pwalletMain) {
|
||||||
// Add wallet transactions that aren't already in a block to mapTransactions
|
// Add wallet transactions that aren't already in a block to mapTransactions
|
||||||
pwalletMain->ReacceptWalletTransactions();
|
pwalletMain->ReacceptWalletTransactions();
|
||||||
@ -1042,6 +1066,7 @@ bool AppInit2(boost::thread_group& threadGroup, bool fForceServer)
|
|||||||
// Run a thread to flush wallet periodically
|
// Run a thread to flush wallet periodically
|
||||||
threadGroup.create_thread(boost::bind(&ThreadFlushWalletDB, boost::ref(pwalletMain->strWalletFile)));
|
threadGroup.create_thread(boost::bind(&ThreadFlushWalletDB, boost::ref(pwalletMain->strWalletFile)));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return !fRequestShutdown;
|
return !fRequestShutdown;
|
||||||
}
|
}
|
||||||
|
152
src/keystore.cpp
152
src/keystore.cpp
@ -56,155 +56,3 @@ bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCryptoKeyStore::SetCrypted()
|
|
||||||
{
|
|
||||||
LOCK(cs_KeyStore);
|
|
||||||
if (fUseCrypto)
|
|
||||||
return true;
|
|
||||||
if (!mapKeys.empty())
|
|
||||||
return false;
|
|
||||||
fUseCrypto = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCryptoKeyStore::Lock()
|
|
||||||
{
|
|
||||||
if (!SetCrypted())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
{
|
|
||||||
LOCK(cs_KeyStore);
|
|
||||||
vMasterKey.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
NotifyStatusChanged(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
LOCK(cs_KeyStore);
|
|
||||||
if (!SetCrypted())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
|
|
||||||
for (; mi != mapCryptedKeys.end(); ++mi)
|
|
||||||
{
|
|
||||||
const CPubKey &vchPubKey = (*mi).second.first;
|
|
||||||
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
|
||||||
CKeyingMaterial vchSecret;
|
|
||||||
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
|
||||||
return false;
|
|
||||||
if (vchSecret.size() != 32)
|
|
||||||
return false;
|
|
||||||
CKey key;
|
|
||||||
key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
|
|
||||||
if (key.GetPubKey() == vchPubKey)
|
|
||||||
break;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
vMasterKey = vMasterKeyIn;
|
|
||||||
}
|
|
||||||
NotifyStatusChanged(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCryptoKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
LOCK(cs_KeyStore);
|
|
||||||
if (!IsCrypted())
|
|
||||||
return CBasicKeyStore::AddKeyPubKey(key, pubkey);
|
|
||||||
|
|
||||||
if (IsLocked())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::vector<unsigned char> vchCryptedSecret;
|
|
||||||
CKeyingMaterial vchSecret(key.begin(), key.end());
|
|
||||||
if (!EncryptSecret(vMasterKey, vchSecret, pubkey.GetHash(), vchCryptedSecret))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!AddCryptedKey(pubkey, vchCryptedSecret))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
LOCK(cs_KeyStore);
|
|
||||||
if (!SetCrypted())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const
|
|
||||||
{
|
|
||||||
{
|
|
||||||
LOCK(cs_KeyStore);
|
|
||||||
if (!IsCrypted())
|
|
||||||
return CBasicKeyStore::GetKey(address, keyOut);
|
|
||||||
|
|
||||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
|
||||||
if (mi != mapCryptedKeys.end())
|
|
||||||
{
|
|
||||||
const CPubKey &vchPubKey = (*mi).second.first;
|
|
||||||
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
|
||||||
CKeyingMaterial vchSecret;
|
|
||||||
if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
|
||||||
return false;
|
|
||||||
if (vchSecret.size() != 32)
|
|
||||||
return false;
|
|
||||||
keyOut.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
|
|
||||||
{
|
|
||||||
{
|
|
||||||
LOCK(cs_KeyStore);
|
|
||||||
if (!IsCrypted())
|
|
||||||
return CKeyStore::GetPubKey(address, vchPubKeyOut);
|
|
||||||
|
|
||||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
|
||||||
if (mi != mapCryptedKeys.end())
|
|
||||||
{
|
|
||||||
vchPubKeyOut = (*mi).second.first;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
LOCK(cs_KeyStore);
|
|
||||||
if (!mapCryptedKeys.empty() || IsCrypted())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
fUseCrypto = true;
|
|
||||||
BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
|
|
||||||
{
|
|
||||||
const CKey &key = mKey.second;
|
|
||||||
CPubKey vchPubKey = key.GetPubKey();
|
|
||||||
CKeyingMaterial vchSecret(key.begin(), key.end());
|
|
||||||
std::vector<unsigned char> vchCryptedSecret;
|
|
||||||
if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(), vchCryptedSecret))
|
|
||||||
return false;
|
|
||||||
if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mapKeys.clear();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
@ -93,87 +93,4 @@ public:
|
|||||||
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
|
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
|
||||||
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
|
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
|
||||||
|
|
||||||
|
|
||||||
/** Keystore which keeps the private keys encrypted.
|
|
||||||
* It derives from the basic key store, which is used if no encryption is active.
|
|
||||||
*/
|
|
||||||
class CCryptoKeyStore : public CBasicKeyStore
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
CryptedKeyMap mapCryptedKeys;
|
|
||||||
|
|
||||||
CKeyingMaterial vMasterKey;
|
|
||||||
|
|
||||||
// if fUseCrypto is true, mapKeys must be empty
|
|
||||||
// if fUseCrypto is false, vMasterKey must be empty
|
|
||||||
bool fUseCrypto;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool SetCrypted();
|
|
||||||
|
|
||||||
// will encrypt previously unencrypted keys
|
|
||||||
bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
|
|
||||||
|
|
||||||
bool Unlock(const CKeyingMaterial& vMasterKeyIn);
|
|
||||||
|
|
||||||
public:
|
|
||||||
CCryptoKeyStore() : fUseCrypto(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsCrypted() const
|
|
||||||
{
|
|
||||||
return fUseCrypto;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsLocked() const
|
|
||||||
{
|
|
||||||
if (!IsCrypted())
|
|
||||||
return false;
|
|
||||||
bool result;
|
|
||||||
{
|
|
||||||
LOCK(cs_KeyStore);
|
|
||||||
result = vMasterKey.empty();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Lock();
|
|
||||||
|
|
||||||
virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
|
||||||
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
|
|
||||||
bool HaveKey(const CKeyID &address) const
|
|
||||||
{
|
|
||||||
{
|
|
||||||
LOCK(cs_KeyStore);
|
|
||||||
if (!IsCrypted())
|
|
||||||
return CBasicKeyStore::HaveKey(address);
|
|
||||||
return mapCryptedKeys.count(address) > 0;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool GetKey(const CKeyID &address, CKey& keyOut) const;
|
|
||||||
bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
|
|
||||||
void GetKeys(std::set<CKeyID> &setAddress) const
|
|
||||||
{
|
|
||||||
if (!IsCrypted())
|
|
||||||
{
|
|
||||||
CBasicKeyStore::GetKeys(setAddress);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setAddress.clear();
|
|
||||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
|
|
||||||
while (mi != mapCryptedKeys.end())
|
|
||||||
{
|
|
||||||
setAddress.insert((*mi).first);
|
|
||||||
mi++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wallet status (encrypted, locked) changed.
|
|
||||||
* Note: Called without locks held.
|
|
||||||
*/
|
|
||||||
boost::signals2::signal<void (CCryptoKeyStore* wallet)> NotifyStatusChanged;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
100
src/net.cpp
100
src/net.cpp
@ -1942,3 +1942,103 @@ void CNode::Fuzz(int nChance)
|
|||||||
// (more changes exponentially less likely):
|
// (more changes exponentially less likely):
|
||||||
Fuzz(2);
|
Fuzz(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CAddrDB
|
||||||
|
//
|
||||||
|
|
||||||
|
CAddrDB::CAddrDB()
|
||||||
|
{
|
||||||
|
pathAddr = GetDataDir() / "peers.dat";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAddrDB::Write(const CAddrMan& addr)
|
||||||
|
{
|
||||||
|
// Generate random temporary filename
|
||||||
|
unsigned short randv = 0;
|
||||||
|
RAND_bytes((unsigned char *)&randv, sizeof(randv));
|
||||||
|
std::string tmpfn = strprintf("peers.dat.%04x", randv);
|
||||||
|
|
||||||
|
// serialize addresses, checksum data up to that point, then append csum
|
||||||
|
CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
|
||||||
|
ssPeers << FLATDATA(Params().MessageStart());
|
||||||
|
ssPeers << addr;
|
||||||
|
uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
|
||||||
|
ssPeers << hash;
|
||||||
|
|
||||||
|
// open temp output file, and associate with CAutoFile
|
||||||
|
boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
|
||||||
|
FILE *file = fopen(pathTmp.string().c_str(), "wb");
|
||||||
|
CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION);
|
||||||
|
if (!fileout)
|
||||||
|
return error("CAddrman::Write() : open failed");
|
||||||
|
|
||||||
|
// Write and commit header, data
|
||||||
|
try {
|
||||||
|
fileout << ssPeers;
|
||||||
|
}
|
||||||
|
catch (std::exception &e) {
|
||||||
|
return error("CAddrman::Write() : I/O error");
|
||||||
|
}
|
||||||
|
FileCommit(fileout);
|
||||||
|
fileout.fclose();
|
||||||
|
|
||||||
|
// replace existing peers.dat, if any, with new peers.dat.XXXX
|
||||||
|
if (!RenameOver(pathTmp, pathAddr))
|
||||||
|
return error("CAddrman::Write() : Rename-into-place failed");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAddrDB::Read(CAddrMan& addr)
|
||||||
|
{
|
||||||
|
// open input file, and associate with CAutoFile
|
||||||
|
FILE *file = fopen(pathAddr.string().c_str(), "rb");
|
||||||
|
CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION);
|
||||||
|
if (!filein)
|
||||||
|
return error("CAddrman::Read() : open failed");
|
||||||
|
|
||||||
|
// use file size to size memory buffer
|
||||||
|
int fileSize = GetFilesize(filein);
|
||||||
|
int dataSize = fileSize - sizeof(uint256);
|
||||||
|
//Don't try to resize to a negative number if file is small
|
||||||
|
if ( dataSize < 0 ) dataSize = 0;
|
||||||
|
vector<unsigned char> vchData;
|
||||||
|
vchData.resize(dataSize);
|
||||||
|
uint256 hashIn;
|
||||||
|
|
||||||
|
// read data and checksum from file
|
||||||
|
try {
|
||||||
|
filein.read((char *)&vchData[0], dataSize);
|
||||||
|
filein >> hashIn;
|
||||||
|
}
|
||||||
|
catch (std::exception &e) {
|
||||||
|
return error("CAddrman::Read() 2 : I/O error or stream data corrupted");
|
||||||
|
}
|
||||||
|
filein.fclose();
|
||||||
|
|
||||||
|
CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
|
||||||
|
|
||||||
|
// verify stored checksum matches input data
|
||||||
|
uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
|
||||||
|
if (hashIn != hashTmp)
|
||||||
|
return error("CAddrman::Read() : checksum mismatch; data corrupted");
|
||||||
|
|
||||||
|
unsigned char pchMsgTmp[4];
|
||||||
|
try {
|
||||||
|
// de-serialize file header (network specific magic number) and ..
|
||||||
|
ssPeers >> FLATDATA(pchMsgTmp);
|
||||||
|
|
||||||
|
// ... verify the network matches ours
|
||||||
|
if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
|
||||||
|
return error("CAddrman::Read() : invalid network magic number");
|
||||||
|
|
||||||
|
// de-serialize address data into one CAddrMan object
|
||||||
|
ssPeers >> addr;
|
||||||
|
}
|
||||||
|
catch (std::exception &e) {
|
||||||
|
return error("CAddrman::Read() : I/O error or stream data corrupted");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
11
src/net.h
11
src/net.h
@ -690,4 +690,15 @@ class CTransaction;
|
|||||||
void RelayTransaction(const CTransaction& tx, const uint256& hash);
|
void RelayTransaction(const CTransaction& tx, const uint256& hash);
|
||||||
void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss);
|
void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss);
|
||||||
|
|
||||||
|
/** Access to the (IP) address database (peers.dat) */
|
||||||
|
class CAddrDB
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
boost::filesystem::path pathAddr;
|
||||||
|
public:
|
||||||
|
CAddrDB();
|
||||||
|
bool Write(const CAddrMan& addr);
|
||||||
|
bool Read(CAddrMan& addr);
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -197,7 +197,7 @@ endif
|
|||||||
bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(QT_INCLUDES) \
|
bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(QT_INCLUDES) \
|
||||||
-I$(top_srcdir)/src/qt/forms
|
-I$(top_srcdir)/src/qt/forms
|
||||||
bitcoin_qt_SOURCES = bitcoin.cpp
|
bitcoin_qt_SOURCES = bitcoin.cpp
|
||||||
bitcoin_qt_LDADD = libbitcoinqt.a $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) $(LIBMEMENV) \
|
bitcoin_qt_LDADD = libbitcoinqt.a $(LIBBITCOIN_SERVER) $(LIBBITCOIN_WALLET) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||||
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
|
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
|
||||||
|
|
||||||
# forms/foo.h -> forms/ui_foo.h
|
# forms/foo.h -> forms/ui_foo.h
|
||||||
|
@ -17,7 +17,7 @@ BUILT_SOURCES = $(TEST_QT_MOC_CPP)
|
|||||||
test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(QT_INCLUDES) $(QT_TEST_INCLUDES)
|
test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(QT_INCLUDES) $(QT_TEST_INCLUDES)
|
||||||
test_bitcoin_qt_SOURCES = test_main.cpp uritests.cpp paymentservertests.cpp $(TEST_QT_H)
|
test_bitcoin_qt_SOURCES = test_main.cpp uritests.cpp paymentservertests.cpp $(TEST_QT_H)
|
||||||
nodist_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP)
|
nodist_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP)
|
||||||
test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) \
|
test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER) $(LIBBITCOIN_WALLET) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) \
|
||||||
$(LIBMEMENV) $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) \
|
$(LIBMEMENV) $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) \
|
||||||
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
|
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
|
||||||
|
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
// Copyright (c) 2009-2013 The Bitcoin developers
|
// Copyright (c) 2009-2013 The Bitcoin developers
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "rpcserver.h"
|
#include "rpcserver.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "netbase.h"
|
#include "netbase.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
|
#include "wallet.h" // for getinfo
|
||||||
|
#include "init.h" // for getinfo
|
||||||
|
#endif
|
||||||
|
#include "main.h" // for getinfo
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
@ -329,3 +333,65 @@ Value getnettotals(const Array& params, bool fHelp)
|
|||||||
obj.push_back(Pair("timemillis", static_cast<boost::int64_t>(GetTimeMillis())));
|
obj.push_back(Pair("timemillis", static_cast<boost::int64_t>(GetTimeMillis())));
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value getinfo(const Array& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() != 0)
|
||||||
|
throw runtime_error(
|
||||||
|
"getinfo\n"
|
||||||
|
"Returns an object containing various state info.\n"
|
||||||
|
"\nResult:\n"
|
||||||
|
"{\n"
|
||||||
|
" \"version\": xxxxx, (numeric) the server version\n"
|
||||||
|
" \"protocolversion\": xxxxx, (numeric) the protocol version\n"
|
||||||
|
" \"walletversion\": xxxxx, (numeric) the wallet version\n"
|
||||||
|
" \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
|
||||||
|
" \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
|
||||||
|
" \"timeoffset\": xxxxx, (numeric) the time offset\n"
|
||||||
|
" \"connections\": xxxxx, (numeric) the number of connections\n"
|
||||||
|
" \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
|
||||||
|
" \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
|
||||||
|
" \"testnet\": true|false, (boolean) if the server is using testnet or not\n"
|
||||||
|
" \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
|
||||||
|
" \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
|
||||||
|
" \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc\n"
|
||||||
|
" \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
|
||||||
|
" \"errors\": \"...\" (string) any error messages\n"
|
||||||
|
"}\n"
|
||||||
|
"\nExamples:\n"
|
||||||
|
+ HelpExampleCli("getinfo", "")
|
||||||
|
+ HelpExampleRpc("getinfo", "")
|
||||||
|
);
|
||||||
|
|
||||||
|
proxyType proxy;
|
||||||
|
GetProxy(NET_IPV4, proxy);
|
||||||
|
|
||||||
|
Object obj;
|
||||||
|
obj.push_back(Pair("version", (int)CLIENT_VERSION));
|
||||||
|
obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
|
if (pwalletMain) {
|
||||||
|
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
|
||||||
|
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
obj.push_back(Pair("blocks", (int)chainActive.Height()));
|
||||||
|
obj.push_back(Pair("timeoffset", (boost::int64_t)GetTimeOffset()));
|
||||||
|
obj.push_back(Pair("connections", (int)vNodes.size()));
|
||||||
|
obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string())));
|
||||||
|
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
|
||||||
|
obj.push_back(Pair("testnet", TestNet()));
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
|
if (pwalletMain) {
|
||||||
|
obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
|
||||||
|
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
|
if (pwalletMain && pwalletMain->IsCrypted())
|
||||||
|
obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
|
||||||
|
#endif
|
||||||
|
obj.push_back(Pair("errors", GetWarnings("statusbar")));
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
@ -8,7 +8,12 @@
|
|||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
|
#include "core.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "keystore.h"
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
#include "wallet.h"
|
#include "wallet.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@ -190,6 +195,7 @@ Value getrawtransaction(const Array& params, bool fHelp)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
Value listunspent(const Array& params, bool fHelp)
|
Value listunspent(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() > 3)
|
if (fHelp || params.size() > 3)
|
||||||
@ -303,6 +309,7 @@ Value listunspent(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Value createrawtransaction(const Array& params, bool fHelp)
|
Value createrawtransaction(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
@ -508,7 +515,9 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
|||||||
"this transaction depends on but may not yet be in the block chain.\n"
|
"this transaction depends on but may not yet be in the block chain.\n"
|
||||||
"The third optional argument (may be null) is an array of base58-encoded private\n"
|
"The third optional argument (may be null) is an array of base58-encoded private\n"
|
||||||
"keys that, if given, will be the only keys used to sign the transaction.\n"
|
"keys that, if given, will be the only keys used to sign the transaction.\n"
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
+ HelpRequiringPassphrase() + "\n"
|
+ HelpRequiringPassphrase() + "\n"
|
||||||
|
#endif
|
||||||
|
|
||||||
"\nArguments:\n"
|
"\nArguments:\n"
|
||||||
"1. \"hexstring\" (string, required) The transaction hex string\n"
|
"1. \"hexstring\" (string, required) The transaction hex string\n"
|
||||||
@ -605,8 +614,10 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
|||||||
tempKeystore.AddKey(key);
|
tempKeystore.AddKey(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
else
|
else
|
||||||
EnsureWalletIsUnlocked();
|
EnsureWalletIsUnlocked();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Add previous txouts given in the RPC call:
|
// Add previous txouts given in the RPC call:
|
||||||
if (params.size() > 1 && params[1].type() != null_type)
|
if (params.size() > 1 && params[1].type() != null_type)
|
||||||
@ -662,7 +673,11 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
|
const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
|
||||||
|
#else
|
||||||
|
const CKeyStore& keystore = tempKeystore;
|
||||||
|
#endif
|
||||||
|
|
||||||
int nHashType = SIGHASH_ALL;
|
int nHashType = SIGHASH_ALL;
|
||||||
if (params.size() > 3 && params[3].type() != null_type)
|
if (params.size() > 3 && params[3].type() != null_type)
|
||||||
|
@ -9,7 +9,10 @@
|
|||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "ui_interface.h"
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
#include "wallet.h"
|
#include "wallet.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
@ -149,8 +152,10 @@ string CRPCTable::help(string strCommand) const
|
|||||||
continue;
|
continue;
|
||||||
if (strCommand != "" && strMethod != strCommand)
|
if (strCommand != "" && strMethod != strCommand)
|
||||||
continue;
|
continue;
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
if (pcmd->reqWallet && !pwalletMain)
|
if (pcmd->reqWallet && !pwalletMain)
|
||||||
continue;
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -228,11 +233,26 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "getaddednodeinfo", &getaddednodeinfo, true, true, false },
|
{ "getaddednodeinfo", &getaddednodeinfo, true, true, false },
|
||||||
{ "getnettotals", &getnettotals, true, true, false },
|
{ "getnettotals", &getnettotals, true, true, false },
|
||||||
{ "getdifficulty", &getdifficulty, true, false, false },
|
{ "getdifficulty", &getdifficulty, true, false, false },
|
||||||
|
{ "getinfo", &getinfo, true, false, false },
|
||||||
|
{ "getrawmempool", &getrawmempool, true, false, false },
|
||||||
|
{ "getblock", &getblock, false, false, false },
|
||||||
|
{ "getblockhash", &getblockhash, false, false, false },
|
||||||
|
{ "settxfee", &settxfee, false, false, true },
|
||||||
|
{ "getrawtransaction", &getrawtransaction, false, false, false },
|
||||||
|
{ "createrawtransaction", &createrawtransaction, false, false, false },
|
||||||
|
{ "decoderawtransaction", &decoderawtransaction, false, false, false },
|
||||||
|
{ "decodescript", &decodescript, false, false, false },
|
||||||
|
{ "signrawtransaction", &signrawtransaction, false, false, false },
|
||||||
|
{ "sendrawtransaction", &sendrawtransaction, false, false, false },
|
||||||
|
{ "gettxoutsetinfo", &gettxoutsetinfo, true, false, false },
|
||||||
|
{ "gettxout", &gettxout, true, false, false },
|
||||||
|
{ "verifychain", &verifychain, true, false, false },
|
||||||
|
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
{ "getnetworkhashps", &getnetworkhashps, true, false, false },
|
{ "getnetworkhashps", &getnetworkhashps, true, false, false },
|
||||||
{ "getgenerate", &getgenerate, true, false, false },
|
{ "getgenerate", &getgenerate, true, false, false },
|
||||||
{ "setgenerate", &setgenerate, true, true, false },
|
{ "setgenerate", &setgenerate, true, true, false },
|
||||||
{ "gethashespersec", &gethashespersec, true, false, false },
|
{ "gethashespersec", &gethashespersec, true, false, false },
|
||||||
{ "getinfo", &getinfo, true, false, false },
|
|
||||||
{ "getmininginfo", &getmininginfo, true, false, false },
|
{ "getmininginfo", &getmininginfo, true, false, false },
|
||||||
{ "getnewaddress", &getnewaddress, true, false, true },
|
{ "getnewaddress", &getnewaddress, true, false, true },
|
||||||
{ "getaccountaddress", &getaccountaddress, true, false, true },
|
{ "getaccountaddress", &getaccountaddress, true, false, true },
|
||||||
@ -258,9 +278,6 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "sendmany", &sendmany, false, false, true },
|
{ "sendmany", &sendmany, false, false, true },
|
||||||
{ "addmultisigaddress", &addmultisigaddress, false, false, true },
|
{ "addmultisigaddress", &addmultisigaddress, false, false, true },
|
||||||
{ "createmultisig", &createmultisig, true, true , false },
|
{ "createmultisig", &createmultisig, true, true , false },
|
||||||
{ "getrawmempool", &getrawmempool, true, false, false },
|
|
||||||
{ "getblock", &getblock, false, false, false },
|
|
||||||
{ "getblockhash", &getblockhash, false, false, false },
|
|
||||||
{ "gettransaction", &gettransaction, false, false, true },
|
{ "gettransaction", &gettransaction, false, false, true },
|
||||||
{ "listtransactions", &listtransactions, false, false, true },
|
{ "listtransactions", &listtransactions, false, false, true },
|
||||||
{ "listaddressgroupings", &listaddressgroupings, false, false, true },
|
{ "listaddressgroupings", &listaddressgroupings, false, false, true },
|
||||||
@ -268,7 +285,6 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "verifymessage", &verifymessage, false, false, false },
|
{ "verifymessage", &verifymessage, false, false, false },
|
||||||
{ "getwork", &getwork, true, false, true },
|
{ "getwork", &getwork, true, false, true },
|
||||||
{ "listaccounts", &listaccounts, false, false, true },
|
{ "listaccounts", &listaccounts, false, false, true },
|
||||||
{ "settxfee", &settxfee, false, false, true },
|
|
||||||
{ "getblocktemplate", &getblocktemplate, true, false, false },
|
{ "getblocktemplate", &getblocktemplate, true, false, false },
|
||||||
{ "submitblock", &submitblock, false, false, false },
|
{ "submitblock", &submitblock, false, false, false },
|
||||||
{ "listsinceblock", &listsinceblock, false, false, true },
|
{ "listsinceblock", &listsinceblock, false, false, true },
|
||||||
@ -277,17 +293,9 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "importprivkey", &importprivkey, false, false, true },
|
{ "importprivkey", &importprivkey, false, false, true },
|
||||||
{ "importwallet", &importwallet, false, false, true },
|
{ "importwallet", &importwallet, false, false, true },
|
||||||
{ "listunspent", &listunspent, false, false, true },
|
{ "listunspent", &listunspent, false, false, true },
|
||||||
{ "getrawtransaction", &getrawtransaction, false, false, false },
|
|
||||||
{ "createrawtransaction", &createrawtransaction, false, false, false },
|
|
||||||
{ "decoderawtransaction", &decoderawtransaction, false, false, false },
|
|
||||||
{ "decodescript", &decodescript, false, false, false },
|
|
||||||
{ "signrawtransaction", &signrawtransaction, false, false, false },
|
|
||||||
{ "sendrawtransaction", &sendrawtransaction, false, false, false },
|
|
||||||
{ "gettxoutsetinfo", &gettxoutsetinfo, true, false, false },
|
|
||||||
{ "gettxout", &gettxout, true, false, false },
|
|
||||||
{ "lockunspent", &lockunspent, false, false, true },
|
{ "lockunspent", &lockunspent, false, false, true },
|
||||||
{ "listlockunspent", &listlockunspent, false, false, true },
|
{ "listlockunspent", &listlockunspent, false, false, true },
|
||||||
{ "verifychain", &verifychain, true, false, false },
|
#endif // ENABLE_WALLET
|
||||||
};
|
};
|
||||||
|
|
||||||
CRPCTable::CRPCTable()
|
CRPCTable::CRPCTable()
|
||||||
@ -788,8 +796,10 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
|
|||||||
const CRPCCommand *pcmd = tableRPC[strMethod];
|
const CRPCCommand *pcmd = tableRPC[strMethod];
|
||||||
if (!pcmd)
|
if (!pcmd)
|
||||||
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
|
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
if (pcmd->reqWallet && !pwalletMain)
|
if (pcmd->reqWallet && !pwalletMain)
|
||||||
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
|
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
|
||||||
|
#endif
|
||||||
|
|
||||||
// Observe safe mode
|
// Observe safe mode
|
||||||
string strWarning = GetWarnings("rpc");
|
string strWarning = GetWarnings("rpc");
|
||||||
@ -804,6 +814,7 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
|
|||||||
{
|
{
|
||||||
if (pcmd->threadSafe)
|
if (pcmd->threadSafe)
|
||||||
result = pcmd->actor(params, false);
|
result = pcmd->actor(params, false);
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
else if (!pwalletMain) {
|
else if (!pwalletMain) {
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
result = pcmd->actor(params, false);
|
result = pcmd->actor(params, false);
|
||||||
@ -811,6 +822,12 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
|
|||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
result = pcmd->actor(params, false);
|
result = pcmd->actor(params, false);
|
||||||
}
|
}
|
||||||
|
#else // ENABLE_WALLET
|
||||||
|
else {
|
||||||
|
LOCK(cs_main);
|
||||||
|
result = pcmd->actor(params, false);
|
||||||
|
}
|
||||||
|
#endif // !ENABLE_WALLET
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -820,4 +837,13 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string HelpExampleCli(string methodname, string args){
|
||||||
|
return "> bitcoin-cli " + methodname + " " + args + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string HelpExampleRpc(string methodname, string args){
|
||||||
|
return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", "
|
||||||
|
"\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n";
|
||||||
|
}
|
||||||
|
|
||||||
const CRPCTable tableRPC;
|
const CRPCTable tableRPC;
|
||||||
|
@ -33,15 +33,6 @@ std::string HelpRequiringPassphrase()
|
|||||||
: "";
|
: "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HelpExampleCli(string methodname, string args){
|
|
||||||
return "> bitcoin-cli " + methodname + " " + args + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string HelpExampleRpc(string methodname, string args){
|
|
||||||
return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", "
|
|
||||||
"\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnsureWalletIsUnlocked()
|
void EnsureWalletIsUnlocked()
|
||||||
{
|
{
|
||||||
if (pwalletMain->IsLocked())
|
if (pwalletMain->IsLocked())
|
||||||
@ -75,64 +66,6 @@ string AccountFromValue(const Value& value)
|
|||||||
return strAccount;
|
return strAccount;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value getinfo(const Array& params, bool fHelp)
|
|
||||||
{
|
|
||||||
if (fHelp || params.size() != 0)
|
|
||||||
throw runtime_error(
|
|
||||||
"getinfo\n"
|
|
||||||
"Returns an object containing various state info.\n"
|
|
||||||
"\nResult:\n"
|
|
||||||
"{\n"
|
|
||||||
" \"version\": xxxxx, (numeric) the server version\n"
|
|
||||||
" \"protocolversion\": xxxxx, (numeric) the protocol version\n"
|
|
||||||
" \"walletversion\": xxxxx, (numeric) the wallet version\n"
|
|
||||||
" \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
|
|
||||||
" \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
|
|
||||||
" \"timeoffset\": xxxxx, (numeric) the time offset\n"
|
|
||||||
" \"connections\": xxxxx, (numeric) the number of connections\n"
|
|
||||||
" \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
|
|
||||||
" \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
|
|
||||||
" \"testnet\": true|false, (boolean) if the server is using testnet or not\n"
|
|
||||||
" \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
|
|
||||||
" \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
|
|
||||||
" \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc\n"
|
|
||||||
" \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
|
|
||||||
" \"errors\": \"...\" (string) any error messages\n"
|
|
||||||
"}\n"
|
|
||||||
"\nExamples:\n"
|
|
||||||
+ HelpExampleCli("getinfo", "")
|
|
||||||
+ HelpExampleRpc("getinfo", "")
|
|
||||||
);
|
|
||||||
|
|
||||||
proxyType proxy;
|
|
||||||
GetProxy(NET_IPV4, proxy);
|
|
||||||
|
|
||||||
Object obj;
|
|
||||||
obj.push_back(Pair("version", (int)CLIENT_VERSION));
|
|
||||||
obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
|
|
||||||
if (pwalletMain) {
|
|
||||||
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
|
|
||||||
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
|
|
||||||
}
|
|
||||||
obj.push_back(Pair("blocks", (int)chainActive.Height()));
|
|
||||||
obj.push_back(Pair("timeoffset", (boost::int64_t)GetTimeOffset()));
|
|
||||||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
|
||||||
obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string())));
|
|
||||||
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
|
|
||||||
obj.push_back(Pair("testnet", TestNet()));
|
|
||||||
if (pwalletMain) {
|
|
||||||
obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
|
|
||||||
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
|
|
||||||
}
|
|
||||||
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
|
|
||||||
if (pwalletMain && pwalletMain->IsCrypted())
|
|
||||||
obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
|
|
||||||
obj.push_back(Pair("errors", GetWarnings("statusbar")));
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Value getnewaddress(const Array& params, bool fHelp)
|
Value getnewaddress(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() > 1)
|
if (fHelp || params.size() > 1)
|
||||||
|
@ -21,16 +21,25 @@ BUILT_SOURCES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h)
|
|||||||
# test_bitcoin binary #
|
# test_bitcoin binary #
|
||||||
test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(TESTDEFS)
|
test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(TESTDEFS)
|
||||||
test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) $(LIBMEMENV) \
|
test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||||
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(BDB_LIBS)
|
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB)
|
||||||
test_bitcoin_SOURCES = accounting_tests.cpp alert_tests.cpp \
|
if ENABLE_WALLET
|
||||||
|
test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
|
||||||
|
endif
|
||||||
|
test_bitcoin_LDADD += $(BDB_LIBS)
|
||||||
|
|
||||||
|
test_bitcoin_SOURCES = alert_tests.cpp \
|
||||||
allocator_tests.cpp base32_tests.cpp base58_tests.cpp base64_tests.cpp \
|
allocator_tests.cpp base32_tests.cpp base58_tests.cpp base64_tests.cpp \
|
||||||
bignum_tests.cpp bloom_tests.cpp canonical_tests.cpp checkblock_tests.cpp \
|
bignum_tests.cpp bloom_tests.cpp canonical_tests.cpp checkblock_tests.cpp \
|
||||||
Checkpoints_tests.cpp compress_tests.cpp DoS_tests.cpp getarg_tests.cpp \
|
Checkpoints_tests.cpp compress_tests.cpp DoS_tests.cpp getarg_tests.cpp \
|
||||||
key_tests.cpp miner_tests.cpp mruset_tests.cpp multisig_tests.cpp \
|
key_tests.cpp mruset_tests.cpp multisig_tests.cpp \
|
||||||
netbase_tests.cpp pmt_tests.cpp rpc_tests.cpp script_P2SH_tests.cpp \
|
netbase_tests.cpp pmt_tests.cpp rpc_tests.cpp script_P2SH_tests.cpp \
|
||||||
script_tests.cpp serialize_tests.cpp sigopcount_tests.cpp test_bitcoin.cpp \
|
script_tests.cpp serialize_tests.cpp sigopcount_tests.cpp test_bitcoin.cpp \
|
||||||
transaction_tests.cpp uint160_tests.cpp uint256_tests.cpp util_tests.cpp \
|
transaction_tests.cpp uint160_tests.cpp uint256_tests.cpp util_tests.cpp \
|
||||||
wallet_tests.cpp sighash_tests.cpp $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
sighash_tests.cpp $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
||||||
|
|
||||||
|
if ENABLE_WALLET
|
||||||
|
test_bitcoin_SOURCES += accounting_tests.cpp wallet_tests.cpp miner_tests.cpp rpc_wallet_tests.cpp
|
||||||
|
endif
|
||||||
|
|
||||||
nodist_test_bitcoin_SOURCES = $(BUILT_SOURCES)
|
nodist_test_bitcoin_SOURCES = $(BUILT_SOURCES)
|
||||||
|
|
||||||
|
@ -9,9 +9,7 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace json_spirit;
|
using namespace json_spirit;
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(rpc_tests)
|
Array
|
||||||
|
|
||||||
static Array
|
|
||||||
createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL)
|
createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL)
|
||||||
{
|
{
|
||||||
Array result;
|
Array result;
|
||||||
@ -23,44 +21,7 @@ createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(rpc_addmultisig)
|
Value CallRPC(string args)
|
||||||
{
|
|
||||||
rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor;
|
|
||||||
|
|
||||||
// old, 65-byte-long:
|
|
||||||
const char address1Hex[] = "0434e3e09f49ea168c5bbf53f877ff4206923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8";
|
|
||||||
// new, compressed:
|
|
||||||
const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4";
|
|
||||||
|
|
||||||
Value v;
|
|
||||||
CBitcoinAddress address;
|
|
||||||
BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false));
|
|
||||||
address.SetString(v.get_str());
|
|
||||||
BOOST_CHECK(address.IsValid() && address.IsScript());
|
|
||||||
|
|
||||||
BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false));
|
|
||||||
address.SetString(v.get_str());
|
|
||||||
BOOST_CHECK(address.IsValid() && address.IsScript());
|
|
||||||
|
|
||||||
BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false));
|
|
||||||
address.SetString(v.get_str());
|
|
||||||
BOOST_CHECK(address.IsValid() && address.IsScript());
|
|
||||||
|
|
||||||
BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error);
|
|
||||||
BOOST_CHECK_THROW(addmultisig(createArgs(1), false), runtime_error);
|
|
||||||
BOOST_CHECK_THROW(addmultisig(createArgs(2, address1Hex), false), runtime_error);
|
|
||||||
|
|
||||||
BOOST_CHECK_THROW(addmultisig(createArgs(1, ""), false), runtime_error);
|
|
||||||
BOOST_CHECK_THROW(addmultisig(createArgs(1, "NotAValidPubkey"), false), runtime_error);
|
|
||||||
|
|
||||||
string short1(address1Hex, address1Hex+sizeof(address1Hex)-2); // last byte missing
|
|
||||||
BOOST_CHECK_THROW(addmultisig(createArgs(2, short1.c_str()), false), runtime_error);
|
|
||||||
|
|
||||||
string short2(address1Hex+1, address1Hex+sizeof(address1Hex)); // first byte missing
|
|
||||||
BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Value CallRPC(string args)
|
|
||||||
{
|
{
|
||||||
vector<string> vArgs;
|
vector<string> vArgs;
|
||||||
boost::split(vArgs, args, boost::is_any_of(" \t"));
|
boost::split(vArgs, args, boost::is_any_of(" \t"));
|
||||||
@ -79,34 +40,8 @@ static Value CallRPC(string args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(rpc_wallet)
|
|
||||||
{
|
|
||||||
// Test RPC calls for various wallet statistics
|
|
||||||
Value r;
|
|
||||||
|
|
||||||
BOOST_CHECK_NO_THROW(CallRPC("listunspent"));
|
|
||||||
BOOST_CHECK_THROW(CallRPC("listunspent string"), runtime_error);
|
|
||||||
BOOST_CHECK_THROW(CallRPC("listunspent 0 string"), runtime_error);
|
|
||||||
BOOST_CHECK_THROW(CallRPC("listunspent 0 1 not_array"), runtime_error);
|
|
||||||
BOOST_CHECK_THROW(CallRPC("listunspent 0 1 [] extra"), runtime_error);
|
|
||||||
BOOST_CHECK_NO_THROW(r=CallRPC("listunspent 0 1 []"));
|
|
||||||
BOOST_CHECK(r.get_array().empty());
|
|
||||||
|
|
||||||
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress"));
|
|
||||||
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0"));
|
|
||||||
BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress not_int"), runtime_error);
|
|
||||||
BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 not_bool"), runtime_error);
|
|
||||||
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0 true"));
|
|
||||||
BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 true extra"), runtime_error);
|
|
||||||
|
|
||||||
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount"));
|
|
||||||
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0"));
|
|
||||||
BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount not_int"), runtime_error);
|
|
||||||
BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 not_bool"), runtime_error);
|
|
||||||
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0 true"));
|
|
||||||
BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(rpc_tests)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(rpc_rawparams)
|
BOOST_AUTO_TEST_CASE(rpc_rawparams)
|
||||||
{
|
{
|
||||||
|
82
src/test/rpc_wallet_tests.cpp
Normal file
82
src/test/rpc_wallet_tests.cpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#include "rpcserver.h"
|
||||||
|
#include "rpcclient.h"
|
||||||
|
|
||||||
|
#include "base58.h"
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace json_spirit;
|
||||||
|
|
||||||
|
extern Array createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL);
|
||||||
|
extern Value CallRPC(string args);
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(rpc_wallet_tests)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(rpc_addmultisig)
|
||||||
|
{
|
||||||
|
rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor;
|
||||||
|
|
||||||
|
// old, 65-byte-long:
|
||||||
|
const char address1Hex[] = "0434e3e09f49ea168c5bbf53f877ff4206923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8";
|
||||||
|
// new, compressed:
|
||||||
|
const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4";
|
||||||
|
|
||||||
|
Value v;
|
||||||
|
CBitcoinAddress address;
|
||||||
|
BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false));
|
||||||
|
address.SetString(v.get_str());
|
||||||
|
BOOST_CHECK(address.IsValid() && address.IsScript());
|
||||||
|
|
||||||
|
BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false));
|
||||||
|
address.SetString(v.get_str());
|
||||||
|
BOOST_CHECK(address.IsValid() && address.IsScript());
|
||||||
|
|
||||||
|
BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false));
|
||||||
|
address.SetString(v.get_str());
|
||||||
|
BOOST_CHECK(address.IsValid() && address.IsScript());
|
||||||
|
|
||||||
|
BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error);
|
||||||
|
BOOST_CHECK_THROW(addmultisig(createArgs(1), false), runtime_error);
|
||||||
|
BOOST_CHECK_THROW(addmultisig(createArgs(2, address1Hex), false), runtime_error);
|
||||||
|
|
||||||
|
BOOST_CHECK_THROW(addmultisig(createArgs(1, ""), false), runtime_error);
|
||||||
|
BOOST_CHECK_THROW(addmultisig(createArgs(1, "NotAValidPubkey"), false), runtime_error);
|
||||||
|
|
||||||
|
string short1(address1Hex, address1Hex+sizeof(address1Hex)-2); // last byte missing
|
||||||
|
BOOST_CHECK_THROW(addmultisig(createArgs(2, short1.c_str()), false), runtime_error);
|
||||||
|
|
||||||
|
string short2(address1Hex+1, address1Hex+sizeof(address1Hex)); // first byte missing
|
||||||
|
BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(rpc_wallet)
|
||||||
|
{
|
||||||
|
// Test RPC calls for various wallet statistics
|
||||||
|
Value r;
|
||||||
|
|
||||||
|
BOOST_CHECK_NO_THROW(CallRPC("listunspent"));
|
||||||
|
BOOST_CHECK_THROW(CallRPC("listunspent string"), runtime_error);
|
||||||
|
BOOST_CHECK_THROW(CallRPC("listunspent 0 string"), runtime_error);
|
||||||
|
BOOST_CHECK_THROW(CallRPC("listunspent 0 1 not_array"), runtime_error);
|
||||||
|
BOOST_CHECK_THROW(CallRPC("listunspent 0 1 [] extra"), runtime_error);
|
||||||
|
BOOST_CHECK_NO_THROW(r=CallRPC("listunspent 0 1 []"));
|
||||||
|
BOOST_CHECK(r.get_array().empty());
|
||||||
|
|
||||||
|
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress"));
|
||||||
|
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0"));
|
||||||
|
BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress not_int"), runtime_error);
|
||||||
|
BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 not_bool"), runtime_error);
|
||||||
|
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0 true"));
|
||||||
|
BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 true extra"), runtime_error);
|
||||||
|
|
||||||
|
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount"));
|
||||||
|
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0"));
|
||||||
|
BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount not_int"), runtime_error);
|
||||||
|
BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 not_bool"), runtime_error);
|
||||||
|
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0 true"));
|
||||||
|
BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
@ -7,7 +7,9 @@
|
|||||||
#include "txdb.h"
|
#include "txdb.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
#include "wallet.h"
|
#include "wallet.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
@ -26,7 +28,9 @@ struct TestingSetup {
|
|||||||
TestingSetup() {
|
TestingSetup() {
|
||||||
fPrintToDebugger = true; // don't want to write to debug.log file
|
fPrintToDebugger = true; // don't want to write to debug.log file
|
||||||
noui_connect();
|
noui_connect();
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
bitdb.MakeMock();
|
bitdb.MakeMock();
|
||||||
|
#endif
|
||||||
pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000)));
|
pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000)));
|
||||||
boost::filesystem::create_directories(pathTemp);
|
boost::filesystem::create_directories(pathTemp);
|
||||||
mapArgs["-datadir"] = pathTemp.string();
|
mapArgs["-datadir"] = pathTemp.string();
|
||||||
@ -34,10 +38,12 @@ struct TestingSetup {
|
|||||||
pcoinsdbview = new CCoinsViewDB(1 << 23, true);
|
pcoinsdbview = new CCoinsViewDB(1 << 23, true);
|
||||||
pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
|
pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
|
||||||
InitBlockIndex();
|
InitBlockIndex();
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
bool fFirstRun;
|
bool fFirstRun;
|
||||||
pwalletMain = new CWallet("wallet.dat");
|
pwalletMain = new CWallet("wallet.dat");
|
||||||
pwalletMain->LoadWallet(fFirstRun);
|
pwalletMain->LoadWallet(fFirstRun);
|
||||||
RegisterWallet(pwalletMain);
|
RegisterWallet(pwalletMain);
|
||||||
|
#endif
|
||||||
nScriptCheckThreads = 3;
|
nScriptCheckThreads = 3;
|
||||||
for (int i=0; i < nScriptCheckThreads-1; i++)
|
for (int i=0; i < nScriptCheckThreads-1; i++)
|
||||||
threadGroup.create_thread(&ThreadScriptCheck);
|
threadGroup.create_thread(&ThreadScriptCheck);
|
||||||
@ -46,12 +52,16 @@ struct TestingSetup {
|
|||||||
{
|
{
|
||||||
threadGroup.interrupt_all();
|
threadGroup.interrupt_all();
|
||||||
threadGroup.join_all();
|
threadGroup.join_all();
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
delete pwalletMain;
|
delete pwalletMain;
|
||||||
pwalletMain = NULL;
|
pwalletMain = NULL;
|
||||||
|
#endif
|
||||||
delete pcoinsTip;
|
delete pcoinsTip;
|
||||||
delete pcoinsdbview;
|
delete pcoinsdbview;
|
||||||
delete pblocktree;
|
delete pblocktree;
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
bitdb.Flush(true);
|
bitdb.Flush(true);
|
||||||
|
#endif
|
||||||
boost::filesystem::remove_all(pathTemp);
|
boost::filesystem::remove_all(pathTemp);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user