aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.gitignore3
-rw-r--r--src/Makefile.am78
-rw-r--r--src/Makefile.include65
-rw-r--r--src/addrman.cpp5
-rw-r--r--src/addrman.h6
-rw-r--r--src/alert.cpp10
-rw-r--r--src/bitcoind-res.rc36
-rw-r--r--src/bitcoinrpc.cpp194
-rw-r--r--src/bitcoinrpc.h13
-rw-r--r--src/clientversion.h5
-rw-r--r--src/compat.h1
-rw-r--r--src/core.cpp18
-rw-r--r--src/core.h12
-rw-r--r--src/db.cpp30
-rw-r--r--src/init.cpp111
-rw-r--r--src/key.cpp20
-rw-r--r--src/leveldb.cpp8
-rw-r--r--src/leveldb.h5
-rw-r--r--src/m4/ax_boost_base.m4258
-rw-r--r--src/m4/ax_boost_chrono.m4118
-rw-r--r--src/m4/ax_boost_filesystem.m4118
-rw-r--r--src/m4/ax_boost_program_options.m4108
-rw-r--r--src/m4/ax_boost_system.m4120
-rw-r--r--src/m4/ax_boost_thread.m4153
-rw-r--r--src/m4/ax_boost_unit_test_framework.m4137
-rw-r--r--src/m4/ax_check_compile_flag.m472
-rw-r--r--src/m4/ax_check_link_flag.m471
-rw-r--r--src/m4/ax_check_preproc_flag.m472
-rw-r--r--src/m4/ax_pthread.m4317
-rw-r--r--src/m4/bitcoin_find_bdb48.m466
-rw-r--r--src/m4/bitcoin_subdir_to_include.m414
-rw-r--r--src/main.cpp173
-rw-r--r--src/main.h16
-rw-r--r--src/makefile.linux-mingw135
-rw-r--r--src/makefile.mingw143
-rw-r--r--src/makefile.osx181
-rw-r--r--src/makefile.unix206
-rw-r--r--src/miner.cpp32
-rw-r--r--src/miner.h3
-rw-r--r--src/net.cpp102
-rw-r--r--src/net.h15
-rw-r--r--src/netbase.cpp30
-rw-r--r--src/netbase.h6
-rw-r--r--src/noui.cpp4
-rw-r--r--src/protocol.cpp4
-rw-r--r--src/qt/Makefile.am172
-rw-r--r--src/qt/addressbookpage.cpp4
-rw-r--r--src/qt/addresstablemodel.cpp72
-rw-r--r--src/qt/addresstablemodel.h2
-rw-r--r--src/qt/askpassphrasedialog.cpp1
-rw-r--r--src/qt/bitcoin.cpp29
-rw-r--r--src/qt/bitcoinaddressvalidator.h4
-rw-r--r--src/qt/bitcoingui.cpp48
-rw-r--r--src/qt/bitcoingui.h2
-rw-r--r--src/qt/clientmodel.cpp8
-rw-r--r--src/qt/clientmodel.h4
-rw-r--r--src/qt/csvmodelwriter.cpp1
-rw-r--r--src/qt/forms/optionsdialog.ui2
-rw-r--r--src/qt/forms/qrcodedialog.ui2
-rw-r--r--src/qt/forms/sendcoinsdialog.ui2
-rw-r--r--src/qt/forms/sendcoinsentry.ui32
-rw-r--r--src/qt/intro.cpp7
-rw-r--r--src/qt/intro.h2
-rw-r--r--src/qt/locale/bitcoin_en.ts197
-rw-r--r--src/qt/notificator.h4
-rw-r--r--src/qt/optionsdialog.cpp4
-rw-r--r--src/qt/optionsmodel.cpp4
-rw-r--r--src/qt/paymentrequestplus.cpp27
-rw-r--r--src/qt/paymentserver.cpp107
-rw-r--r--src/qt/paymentserver.h27
-rw-r--r--src/qt/res/bitcoin-qt-res.rc (renamed from src/qt/res/bitcoin-qt.rc)0
-rw-r--r--src/qt/sendcoinsdialog.cpp168
-rw-r--r--src/qt/sendcoinsdialog.h1
-rw-r--r--src/qt/sendcoinsentry.cpp7
-rw-r--r--src/qt/sendcoinsentry.h3
-rw-r--r--src/qt/test/Makefile.am26
-rw-r--r--src/qt/test/paymentservertests.cpp4
-rw-r--r--src/qt/transactiondesc.cpp31
-rw-r--r--src/qt/transactiondesc.h2
-rw-r--r--src/qt/transactionrecord.cpp9
-rw-r--r--src/qt/transactionrecord.h6
-rw-r--r--src/qt/transactiontablemodel.cpp42
-rw-r--r--src/qt/walletframe.cpp7
-rw-r--r--src/qt/walletmodel.cpp94
-rw-r--r--src/qt/walletmodel.h16
-rw-r--r--src/qt/walletmodeltransaction.cpp56
-rw-r--r--src/qt/walletmodeltransaction.h37
-rw-r--r--src/rpcblockchain.cpp8
-rw-r--r--src/rpcdump.cpp8
-rw-r--r--src/rpcmining.cpp67
-rw-r--r--src/rpcrawtransaction.cpp76
-rw-r--r--src/rpcwallet.cpp50
-rw-r--r--src/script.cpp4
-rw-r--r--src/script.h11
-rw-r--r--src/sync.cpp26
-rw-r--r--src/test/Makefile.am41
-rw-r--r--src/test/alert_tests.cpp26
-rw-r--r--src/test/base58_tests.cpp17
-rw-r--r--src/test/canonical_tests.cpp8
-rw-r--r--src/test/checkblock_tests.cpp2
-rw-r--r--src/test/data/alertTests.raw (renamed from src/test/data/alertTests)bin1283 -> 1283 bytes
-rw-r--r--src/test/miner_tests.cpp4
-rw-r--r--src/test/script_tests.cpp33
-rw-r--r--src/test/transaction_tests.cpp8
-rw-r--r--src/test/wallet_tests.cpp1
-rw-r--r--src/txdb.cpp2
-rw-r--r--src/uint256.h94
-rw-r--r--src/util.cpp50
-rw-r--r--src/util.h38
-rw-r--r--src/wallet.cpp74
-rw-r--r--src/wallet.h12
-rw-r--r--src/walletdb.cpp34
112 files changed, 3569 insertions, 1692 deletions
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644
index 0000000000..c45f62adf5
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1,3 @@
+
+test_bitcoin
+
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000000..c0687ae2e6
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,78 @@
+include Makefile.include
+AM_CPPFLAGS = $(INCLUDES) -I$(top_builddir)/src/obj \
+ -I$(top_srcdir)/src/leveldb/include -I$(top_srcdir)/src/leveldb/helpers \
+ -I$(builddir) $(BOOST_INCLUDES) $(BDB_CPPFLAGS)
+AM_LDFLAGS = $(PTHREAD_CFLAGS)
+
+noinst_LIBRARIES = libbitcoin.a
+
+bin_PROGRAMS = bitcoind
+
+SUBDIRS = . $(BUILD_QT) $(BUILD_TEST)
+DIST_SUBDIRS = . qt test
+.PHONY: FORCE
+# bitcoin core #
+BITCOIN_CORE_H = addrman.h alert.h allocators.h base58.h bignum.h \
+ bitcoinrpc.h bloom.h chainparams.h checkpoints.h checkqueue.h \
+ clientversion.h compat.h core.h crypter.h db.h hash.h init.h \
+ key.h keystore.h leveldb.h limitedmap.h main.h miner.h mruset.h \
+ netbase.h net.h protocol.h script.h serialize.h sync.h threadsafety.h \
+ txdb.h ui_interface.h uint256.h util.h version.h walletdb.h wallet.h
+
+JSON_H = json/json_spirit.h json/json_spirit_error_position.h \
+ json/json_spirit_reader.h json/json_spirit_reader_template.h \
+ json/json_spirit_stream_reader.h json/json_spirit_utils.h \
+ json/json_spirit_value.h json/json_spirit_writer.h \
+ json/json_spirit_writer_template.h
+
+obj/build.h: FORCE
+ @$(MKDIR_P) $(abs_top_builddir)/src/obj
+ @$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \
+ $(abs_top_srcdir)
+version.o: obj/build.h
+
+libbitcoin_a_SOURCES = addrman.cpp alert.cpp bitcoinrpc.cpp bloom.cpp \
+ chainparams.cpp checkpoints.cpp core.cpp crypter.cpp db.cpp hash.cpp \
+ init.cpp key.cpp keystore.cpp leveldb.cpp main.cpp miner.cpp \
+ netbase.cpp net.cpp noui.cpp protocol.cpp rpcblockchain.cpp rpcdump.cpp \
+ rpcmining.cpp rpcnet.cpp rpcrawtransaction.cpp rpcwallet.cpp script.cpp \
+ sync.cpp txdb.cpp util.cpp version.cpp wallet.cpp walletdb.cpp $(JSON_H) \
+ $(BITCOIN_CORE_H)
+
+nodist_libbitcoin_a_SOURCES = $(top_srcdir)/src/obj/build.h
+#
+
+# bitcoind binary #
+bitcoind_LDADD = libbitcoin.a leveldb/libleveldb.a leveldb/libmemenv.a \
+ $(BOOST_LIBS)
+bitcoind_SOURCES = bitcoind.cpp
+#
+
+if TARGET_WINDOWS
+bitcoind_SOURCES += bitcoind-res.rc
+endif
+
+AM_CPPFLAGS += $(BDB_CPPFLAGS)
+bitcoind_LDADD += $(BDB_LIBS)
+
+leveldb/libleveldb.a: leveldb/libmemenv.a
+
+leveldb/%.a:
+ @echo "Building LevelDB ..." && $(MAKE) -C $(@D) $(@F) CXX="$(CXX)" \
+ CC="$(CC)" PLATFORM=$(TARGET_OS) AR="$(AR)" $(LEVELDB_TARGET_FLAGS) \
+ OPT="$(CXXFLAGS) $(CPPFLAGS)"
+
+qt/bitcoinstrings.cpp: $(libbitcoin_a_SOURCES)
+ @test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
+ @cd $(top_srcdir); XGETTEXT=$(XGETTEXT) share/qt/extract_strings_qt.py
+
+CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno
+
+DISTCLEANFILES = obj/build.h
+
+EXTRA_DIST = leveldb Makefile.include
+
+clean-local:
+ -$(MAKE) -C leveldb clean
+ rm -f leveldb/port/*.gcno leveldb/db/*.gcno leveldb/table/*.gcno leveldb/helpers/*.gcno
+ rm -f leveldb/util/*.gcno leveldb/helpers/memenv/*.gcno
diff --git a/src/Makefile.include b/src/Makefile.include
new file mode 100644
index 0000000000..352471061d
--- /dev/null
+++ b/src/Makefile.include
@@ -0,0 +1,65 @@
+# Helper for rules and subdir Makefiles to find parent targets.
+# Flags and other non-target variables should not be set here.
+
+LIBBITCOIN=$(top_builddir)/src/libbitcoin.a
+LIBLEVELDB=$(top_builddir)/src/leveldb/libleveldb.a
+LIBMEMENV=$(top_builddir)/src/leveldb/libmemenv.a
+LIBBITCOINQT=$(top_builddir)/src/qt/libbitcoinqt.a
+
+$(LIBBITCOIN):
+ $(MAKE) -C $(top_builddir)/src $(@F)
+
+$(LIBLEVELDB) $(LIBMEMENV):
+ $(MAKE) -C $(top_builddir)/src leveldb/$(@F)
+
+$(LIBBITCOINQT):
+ $(MAKE) -C $(top_builddir)/src/qt $(@F)
+
+.mm.o:
+ $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CXXFLAGS) $(QT_INCLUDES) $(CXXFLAGS) -c -o $@ $<
+
+.rc.o:
+ @test -f $(WINDRES) && $(WINDRES) -i $< -o $@ || \
+ echo error: could not build $@
+
+ui_%.h: %.ui
+ @test -d $(abs_builddir)/$(@D) || $(MKDIR_P) $(abs_builddir)/$(@D)
+ @test -f $(UIC) && $(UIC) -o $(abs_builddir)/$@ $(abs_srcdir)/$< || echo error: could not build $(abs_builddir)/$@
+ $(SED) -i.bak -e '/^\*\*.*Created:/d' $(abs_builddir)/$@ && rm $(abs_builddir)/$@.bak
+ $(SED) -i.bak -e '/^\*\*.*by:/d' $(abs_builddir)/$@ && rm $(abs_builddir)/$@.bak
+
+%.moc: %.cpp
+ $(MOC) $(QT_INCLUDES) $(MOC_DEFS) -o $@ $<
+ $(SED) -i.bak -e '/^\*\*.*Created:/d' $@ && rm $@.bak
+ $(SED) -i.bak -e '/^\*\*.*by:/d' $@ && rm $@.bak
+
+moc_%.cpp: %.h
+ $(MOC) $(QT_INCLUDES) $(MOC_DEFS) -o $@ $<
+ $(SED) -i.bak -e '/^\*\*.*Created:/d' $@ && rm $@.bak
+ $(SED) -i.bak -e '/^\*\*.*by:/d' $@ && rm $@.bak
+
+%.qm: %.ts
+ @test -d $(abs_builddir)/$(@D) || $(MKDIR_P) $(abs_builddir)/$(@D)
+ @test -f $(LRELEASE) && $(LRELEASE) $(abs_srcdir)/$< -qm $(abs_builddir)/$@ || \
+ echo error: could not build $(abs_builddir)/$@
+
+%.pb.cc %.pb.h: %.proto
+ test -f $(PROTOC) && $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $(<D) $<) || \
+ echo error: could not build $@
+
+%.json.h: %.json
+ @$(MKDIR_P) $(@D)
+ @echo "namespace json_tests{" > $@
+ @echo "static unsigned const char $(*F)[] = {" >> $@
+ @$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' >> $@
+ @echo "};};" >> $@
+ @echo "Generated $@"
+
+%.raw.h: %.raw
+ @$(MKDIR_P) $(@D)
+ @echo "namespace alert_tests{" > $@
+ @echo "static unsigned const char $(*F)[] = {" >> $@
+ @$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' >> $@
+ @echo "};};" >> $@
+ @echo "Generated $@"
diff --git a/src/addrman.cpp b/src/addrman.cpp
index 780edde90f..731ff2abed 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -261,8 +261,6 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
void CAddrMan::Good_(const CService &addr, int64 nTime)
{
-// printf("Good: addr=%s\n", addr.ToString().c_str());
-
int nId;
CAddrInfo *pinfo = Find(addr, &nId);
@@ -304,7 +302,7 @@ void CAddrMan::Good_(const CService &addr, int64 nTime)
// TODO: maybe re-add the node, but for now, just bail out
if (nUBucket == -1) return;
- printf("Moving %s to tried\n", addr.ToString().c_str());
+ LogPrint("addrman", "Moving %s to tried\n", addr.ToString().c_str());
// move nId to the tried tables
MakeTried(info, nId, nUBucket);
@@ -351,7 +349,6 @@ bool CAddrMan::Add_(const CAddress &addr, const CNetAddr& source, int64 nTimePen
} else {
pinfo = Create(addr, source, &nId);
pinfo->nTime = max((int64)0, (int64)pinfo->nTime - nTimePenalty);
-// printf("Added %s [nTime=%fhr]\n", pinfo->ToString().c_str(), (GetAdjustedTime() - pinfo->nTime) / 3600.0);
nNew++;
fNew = true;
}
diff --git a/src/addrman.h b/src/addrman.h
index 7af6afd78f..081543ace4 100644
--- a/src/addrman.h
+++ b/src/addrman.h
@@ -403,7 +403,7 @@ public:
LOCK(cs);
int err;
if ((err=Check_()))
- printf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
+ LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
}
#endif
}
@@ -419,7 +419,7 @@ public:
Check();
}
if (fRet)
- printf("Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort().c_str(), source.ToString().c_str(), nTried, nNew);
+ LogPrint("addr", "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort().c_str(), source.ToString().c_str(), nTried, nNew);
return fRet;
}
@@ -435,7 +435,7 @@ public:
Check();
}
if (nAdd)
- printf("Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString().c_str(), nTried, nNew);
+ LogPrint("addr", "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString().c_str(), nTried, nNew);
return nAdd > 0;
}
diff --git a/src/alert.cpp b/src/alert.cpp
index e00847aadb..c9cde17955 100644
--- a/src/alert.cpp
+++ b/src/alert.cpp
@@ -76,7 +76,7 @@ std::string CUnsignedAlert::ToString() const
void CUnsignedAlert::print() const
{
- printf("%s", ToString().c_str());
+ LogPrintf("%s", ToString().c_str());
}
void CAlert::SetNull()
@@ -200,13 +200,13 @@ bool CAlert::ProcessAlert(bool fThread)
const CAlert& alert = (*mi).second;
if (Cancels(alert))
{
- printf("cancelling alert %d\n", alert.nID);
+ LogPrint("alert", "cancelling alert %d\n", alert.nID);
uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
mapAlerts.erase(mi++);
}
else if (!alert.IsInEffect())
{
- printf("expiring alert %d\n", alert.nID);
+ LogPrint("alert", "expiring alert %d\n", alert.nID);
uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
mapAlerts.erase(mi++);
}
@@ -220,7 +220,7 @@ bool CAlert::ProcessAlert(bool fThread)
const CAlert& alert = item.second;
if (alert.Cancels(*this))
{
- printf("alert already cancelled by %d\n", alert.nID);
+ LogPrint("alert", "alert already cancelled by %d\n", alert.nID);
return false;
}
}
@@ -258,6 +258,6 @@ bool CAlert::ProcessAlert(bool fThread)
}
}
- printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
+ LogPrint("alert", "accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
return true;
}
diff --git a/src/bitcoind-res.rc b/src/bitcoind-res.rc
new file mode 100644
index 0000000000..202b7ab352
--- /dev/null
+++ b/src/bitcoind-res.rc
@@ -0,0 +1,36 @@
+#include <windows.h> // needed for VERSIONINFO
+#include "clientversion.h" // holds the needed client version information
+
+#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD
+#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
+#define VER_FILEVERSION VER_PRODUCTVERSION
+#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
+#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin developers"
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION VER_FILEVERSION
+PRODUCTVERSION VER_PRODUCTVERSION
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_APP
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4" // U.S. English - multilingual (hex)
+ BEGIN
+ VALUE "CompanyName", "Bitcoin"
+ VALUE "FileDescription", "Bitcoind (OSS daemon/client for Bitcoin)"
+ VALUE "FileVersion", VER_FILEVERSION_STR
+ VALUE "InternalName", "bitcoind"
+ VALUE "LegalCopyright", COPYRIGHT_STR
+ VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
+ VALUE "OriginalFilename", "bitcoind.exe"
+ VALUE "ProductName", "Bitcoind"
+ VALUE "ProductVersion", VER_PRODUCTVERSION_STR
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
+ END
+END
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index d22809ce69..ef50ccd07f 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -113,6 +113,34 @@ std::string HexBits(unsigned int nBits)
return HexStr(BEGIN(uBits.cBits), END(uBits.cBits));
}
+uint256 ParseHashV(const Value& v, string strName)
+{
+ string strHex;
+ if (v.type() == str_type)
+ strHex = v.get_str();
+ if (!IsHex(strHex)) // Note: IsHex("") is false
+ throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
+ uint256 result;
+ result.SetHex(strHex);
+ return result;
+}
+uint256 ParseHashO(const Object& o, string strKey)
+{
+ return ParseHashV(find_value(o, strKey), strKey);
+}
+vector<unsigned char> ParseHexV(const Value& v, string strName)
+{
+ string strHex;
+ if (v.type() == str_type)
+ strHex = v.get_str();
+ if (!IsHex(strHex))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
+ return ParseHex(strHex);
+}
+vector<unsigned char> ParseHexO(const Object& o, string strKey)
+{
+ return ParseHexV(find_value(o, strKey), strKey);
+}
///
@@ -132,6 +160,9 @@ string CRPCTable::help(string strCommand) const
continue;
if (strCommand != "" && strMethod != strCommand)
continue;
+ if (pcmd->reqWallet && !pwalletMain)
+ continue;
+
try
{
Array params;
@@ -190,74 +221,77 @@ Value stop(const Array& params, bool fHelp)
static const CRPCCommand vRPCCommands[] =
-{ // name actor (function) okSafeMode threadSafe
- // ------------------------ ----------------------- ---------- ----------
- { "help", &help, true, true },
- { "stop", &stop, true, true },
- { "getblockcount", &getblockcount, true, false },
- { "getbestblockhash", &getbestblockhash, true, false },
- { "getconnectioncount", &getconnectioncount, true, false },
- { "getpeerinfo", &getpeerinfo, true, false },
- { "addnode", &addnode, true, true },
- { "getaddednodeinfo", &getaddednodeinfo, true, true },
- { "getdifficulty", &getdifficulty, true, false },
- { "getgenerate", &getgenerate, true, false },
- { "setgenerate", &setgenerate, true, false },
- { "gethashespersec", &gethashespersec, true, false },
- { "getinfo", &getinfo, true, false },
- { "getmininginfo", &getmininginfo, true, false },
- { "getnewaddress", &getnewaddress, true, false },
- { "getaccountaddress", &getaccountaddress, true, false },
- { "setaccount", &setaccount, true, false },
- { "getaccount", &getaccount, false, false },
- { "getaddressesbyaccount", &getaddressesbyaccount, true, false },
- { "sendtoaddress", &sendtoaddress, false, false },
- { "getreceivedbyaddress", &getreceivedbyaddress, false, false },
- { "getreceivedbyaccount", &getreceivedbyaccount, false, false },
- { "listreceivedbyaddress", &listreceivedbyaddress, false, false },
- { "listreceivedbyaccount", &listreceivedbyaccount, false, false },
- { "backupwallet", &backupwallet, true, false },
- { "keypoolrefill", &keypoolrefill, true, false },
- { "walletpassphrase", &walletpassphrase, true, false },
- { "walletpassphrasechange", &walletpassphrasechange, false, false },
- { "walletlock", &walletlock, true, false },
- { "encryptwallet", &encryptwallet, false, false },
- { "validateaddress", &validateaddress, true, false },
- { "getbalance", &getbalance, false, false },
- { "move", &movecmd, false, false },
- { "sendfrom", &sendfrom, false, false },
- { "sendmany", &sendmany, false, false },
- { "addmultisigaddress", &addmultisigaddress, false, false },
- { "createmultisig", &createmultisig, true, true },
- { "getrawmempool", &getrawmempool, true, false },
- { "getblock", &getblock, false, false },
- { "getblockhash", &getblockhash, false, false },
- { "gettransaction", &gettransaction, false, false },
- { "listtransactions", &listtransactions, false, false },
- { "listaddressgroupings", &listaddressgroupings, false, false },
- { "signmessage", &signmessage, false, false },
- { "verifymessage", &verifymessage, false, false },
- { "getwork", &getwork, true, false },
- { "listaccounts", &listaccounts, false, false },
- { "settxfee", &settxfee, false, false },
- { "getblocktemplate", &getblocktemplate, true, false },
- { "submitblock", &submitblock, false, false },
- { "listsinceblock", &listsinceblock, false, false },
- { "dumpprivkey", &dumpprivkey, true, false },
- { "dumpwallet", &dumpwallet, true, false },
- { "importprivkey", &importprivkey, false, false },
- { "importwallet", &importwallet, false, false },
- { "listunspent", &listunspent, false, false },
- { "getrawtransaction", &getrawtransaction, false, false },
- { "createrawtransaction", &createrawtransaction, false, false },
- { "decoderawtransaction", &decoderawtransaction, false, false },
- { "signrawtransaction", &signrawtransaction, false, false },
- { "sendrawtransaction", &sendrawtransaction, false, false },
- { "gettxoutsetinfo", &gettxoutsetinfo, true, false },
- { "gettxout", &gettxout, true, false },
- { "lockunspent", &lockunspent, false, false },
- { "listlockunspent", &listlockunspent, false, false },
- { "verifychain", &verifychain, true, false },
+{ // name actor (function) okSafeMode threadSafe reqWallet
+ // ------------------------ ----------------------- ---------- ---------- ---------
+ { "help", &help, true, true, false },
+ { "stop", &stop, true, true, false },
+ { "getblockcount", &getblockcount, true, false, false },
+ { "getbestblockhash", &getbestblockhash, true, false, false },
+ { "getconnectioncount", &getconnectioncount, true, false, false },
+ { "getpeerinfo", &getpeerinfo, true, false, false },
+ { "addnode", &addnode, true, true, false },
+ { "getaddednodeinfo", &getaddednodeinfo, true, true, false },
+ { "getdifficulty", &getdifficulty, true, false, false },
+ { "getnetworkhashps", &getnetworkhashps, true, false, false },
+ { "getgenerate", &getgenerate, true, false, false },
+ { "setgenerate", &setgenerate, true, false, true },
+ { "gethashespersec", &gethashespersec, true, false, false },
+ { "getinfo", &getinfo, true, false, false },
+ { "getmininginfo", &getmininginfo, true, false, false },
+ { "getnewaddress", &getnewaddress, true, false, true },
+ { "getaccountaddress", &getaccountaddress, true, false, true },
+ { "getrawchangeaddress", &getrawchangeaddress, true, false, true },
+ { "setaccount", &setaccount, true, false, true },
+ { "getaccount", &getaccount, false, false, true },
+ { "getaddressesbyaccount", &getaddressesbyaccount, true, false, true },
+ { "sendtoaddress", &sendtoaddress, false, false, true },
+ { "getreceivedbyaddress", &getreceivedbyaddress, false, false, true },
+ { "getreceivedbyaccount", &getreceivedbyaccount, false, false, true },
+ { "listreceivedbyaddress", &listreceivedbyaddress, false, false, true },
+ { "listreceivedbyaccount", &listreceivedbyaccount, false, false, true },
+ { "backupwallet", &backupwallet, true, false, true },
+ { "keypoolrefill", &keypoolrefill, true, false, true },
+ { "walletpassphrase", &walletpassphrase, true, false, true },
+ { "walletpassphrasechange", &walletpassphrasechange, false, false, true },
+ { "walletlock", &walletlock, true, false, true },
+ { "encryptwallet", &encryptwallet, false, false, true },
+ { "validateaddress", &validateaddress, true, false, false },
+ { "getbalance", &getbalance, false, false, true },
+ { "move", &movecmd, false, false, true },
+ { "sendfrom", &sendfrom, false, false, true },
+ { "sendmany", &sendmany, false, false, true },
+ { "addmultisigaddress", &addmultisigaddress, false, false, true },
+ { "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 },
+ { "listtransactions", &listtransactions, false, false, true },
+ { "listaddressgroupings", &listaddressgroupings, false, false, true },
+ { "signmessage", &signmessage, false, false, true },
+ { "verifymessage", &verifymessage, false, false, false },
+ { "getwork", &getwork, true, false, true },
+ { "listaccounts", &listaccounts, false, false, true },
+ { "settxfee", &settxfee, false, false, true },
+ { "getblocktemplate", &getblocktemplate, true, false, false },
+ { "submitblock", &submitblock, false, false, false },
+ { "listsinceblock", &listsinceblock, false, false, true },
+ { "dumpprivkey", &dumpprivkey, true, false, true },
+ { "dumpwallet", &dumpwallet, true, false, true },
+ { "importprivkey", &importprivkey, false, false, true },
+ { "importwallet", &importwallet, 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 },
+ { "listlockunspent", &listlockunspent, false, false, true },
+ { "verifychain", &verifychain, true, false, false },
};
CRPCTable::CRPCTable()
@@ -766,12 +800,12 @@ void StartRPCThreads()
filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile;
if (filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string());
- else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str());
+ else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str());
filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile;
if (filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem);
- else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str());
+ else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str());
string strCiphers = GetArg("-rpcsslciphers", "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str());
@@ -901,7 +935,7 @@ void JSONRequest::parse(const Value& valRequest)
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
strMethod = valMethod.get_str();
if (strMethod != "getwork" && strMethod != "getblocktemplate")
- printf("ThreadRPCServer method=%s\n", strMethod.c_str());
+ LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod.c_str());
// Parse params
Value valParams = find_value(request, "params");
@@ -975,10 +1009,10 @@ void ServiceConnection(AcceptedConnection *conn)
}
if (!HTTPAuthorized(mapHeaders))
{
- printf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string().c_str());
+ LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string().c_str());
/* Deter brute-forcing short passwords.
- If this results in a DOS the user really
- shouldn't have their RPC port exposed.*/
+ If this results in a DoS the user really
+ shouldn't have their RPC port exposed. */
if (mapArgs["-rpcpassword"].size() < 20)
MilliSleep(250);
@@ -1034,6 +1068,8 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
const CRPCCommand *pcmd = tableRPC[strMethod];
if (!pcmd)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
+ if (pcmd->reqWallet && !pwalletMain)
+ throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
// Observe safe mode
string strWarning = GetWarnings("rpc");
@@ -1048,7 +1084,10 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
{
if (pcmd->threadSafe)
result = pcmd->actor(params, false);
- else {
+ else if (!pwalletMain) {
+ LOCK(cs_main);
+ result = pcmd->actor(params, false);
+ } else {
LOCK2(cs_main, pwalletMain->cs_wallet);
result = pcmd->actor(params, false);
}
@@ -1158,6 +1197,8 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if (strMethod == "getaddednodeinfo" && n > 0) ConvertTo<bool>(params[0]);
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "getnetworkhashps" && n > 0) ConvertTo<boost::int64_t>(params[0]);
+ if (strMethod == "getnetworkhashps" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
if (strMethod == "settxfee" && n > 0) ConvertTo<double>(params[0]);
if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
@@ -1193,6 +1234,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1], true);
if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2], true);
+ if (strMethod == "sendrawtransaction" && n > 1) ConvertTo<bool>(params[1], true);
if (strMethod == "gettxout" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "gettxout" && n > 2) ConvertTo<bool>(params[2]);
if (strMethod == "lockunspent" && n > 0) ConvertTo<bool>(params[0]);
@@ -1289,7 +1331,7 @@ int main(int argc, char *argv[])
{
if (argc >= 2 && string(argv[1]) == "-server")
{
- printf("server ready\n");
+ LogPrintf("server ready\n");
ThreadRPCServer(NULL);
}
else
diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h
index 4d5599be84..ce1c0e68b7 100644
--- a/src/bitcoinrpc.h
+++ b/src/bitcoinrpc.h
@@ -104,6 +104,7 @@ public:
rpcfn_type actor;
bool okSafeMode;
bool threadSafe;
+ bool reqWallet;
};
/**
@@ -130,6 +131,15 @@ public:
extern const CRPCTable tableRPC;
+//
+// Utilities: convert hex-encoded Values
+// (throws error if not hex).
+//
+extern uint256 ParseHashV(const json_spirit::Value& v, std::string strName);
+extern uint256 ParseHashO(const json_spirit::Object& o, std::string strKey);
+extern std::vector<unsigned char> ParseHexV(const json_spirit::Value& v, std::string strName);
+extern std::vector<unsigned char> ParseHexO(const json_spirit::Object& o, std::string strKey);
+
extern void InitRPCMining();
extern void ShutdownRPCMining();
@@ -153,6 +163,7 @@ extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fH
extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp
extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp);
@@ -161,6 +172,7 @@ extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHe
extern json_spirit::Value getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
extern json_spirit::Value getaccountaddress(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getrawchangeaddress(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value setaccount(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getaccount(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getaddressesbyaccount(const json_spirit::Array& params, bool fHelp);
@@ -197,6 +209,7 @@ extern json_spirit::Value lockunspent(const json_spirit::Array& params, bool fHe
extern json_spirit::Value listlockunspent(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value createrawtransaction(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value decoderawtransaction(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value decodescript(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp);
diff --git a/src/clientversion.h b/src/clientversion.h
index 30c0c4072b..b376a67c8a 100644
--- a/src/clientversion.h
+++ b/src/clientversion.h
@@ -1,6 +1,9 @@
#ifndef CLIENTVERSION_H
#define CLIENTVERSION_H
+#if defined(HAVE_CONFIG_H)
+#include "bitcoin-config.h"
+#else
//
// client versioning and copyright year
//
@@ -18,6 +21,8 @@
// Todo: update this when changing our copyright comments in the source
#define COPYRIGHT_YEAR 2013
+#endif //HAVE_CONFIG_H
+
// Converts the parameter X to a string after macro replacement on X has been performed.
// Don't merge these into one macro!
#define STRINGIZE(X) DO_STRINGIZE(X)
diff --git a/src/compat.h b/src/compat.h
index 4e98b46c1c..9caf5e4810 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -26,7 +26,6 @@
#endif
#ifdef WIN32
-#define MSG_NOSIGNAL 0
#define MSG_DONTWAIT 0
#else
typedef u_int SOCKET;
diff --git a/src/core.cpp b/src/core.cpp
index afba0959cf..99b5c6641a 100644
--- a/src/core.cpp
+++ b/src/core.cpp
@@ -13,7 +13,7 @@ std::string COutPoint::ToString() const
void COutPoint::print() const
{
- printf("%s\n", ToString().c_str());
+ LogPrintf("%s\n", ToString().c_str());
}
CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, unsigned int nSequenceIn)
@@ -47,7 +47,7 @@ std::string CTxIn::ToString() const
void CTxIn::print() const
{
- printf("%s\n", ToString().c_str());
+ LogPrintf("%s\n", ToString().c_str());
}
CTxOut::CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
@@ -70,7 +70,7 @@ std::string CTxOut::ToString() const
void CTxOut::print() const
{
- printf("%s\n", ToString().c_str());
+ LogPrintf("%s\n", ToString().c_str());
}
uint256 CTransaction::GetHash() const
@@ -125,7 +125,7 @@ std::string CTransaction::ToString() const
void CTransaction::print() const
{
- printf("%s", ToString().c_str());
+ LogPrintf("%s", ToString().c_str());
}
// Amount compression:
@@ -282,7 +282,7 @@ uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMer
void CBlock::print() const
{
- printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%"PRIszu")\n",
+ LogPrintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%"PRIszu")\n",
GetHash().ToString().c_str(),
nVersion,
hashPrevBlock.ToString().c_str(),
@@ -291,11 +291,11 @@ void CBlock::print() const
vtx.size());
for (unsigned int i = 0; i < vtx.size(); i++)
{
- printf(" ");
+ LogPrintf(" ");
vtx[i].print();
}
- printf(" vMerkleTree: ");
+ LogPrintf(" vMerkleTree: ");
for (unsigned int i = 0; i < vMerkleTree.size(); i++)
- printf("%s ", vMerkleTree[i].ToString().c_str());
- printf("\n");
+ LogPrintf("%s ", vMerkleTree[i].ToString().c_str());
+ LogPrintf("\n");
}
diff --git a/src/core.h b/src/core.h
index 1b9d4dd765..ce21acd59e 100644
--- a/src/core.h
+++ b/src/core.h
@@ -389,7 +389,9 @@ public:
int nVersion;
// construct a CCoins from a CTransaction, at a given height
- CCoins(const CTransaction &tx, int nHeightIn) : fCoinBase(tx.IsCoinBase()), vout(tx.vout), nHeight(nHeightIn), nVersion(tx.nVersion) { }
+ CCoins(const CTransaction &tx, int nHeightIn) : fCoinBase(tx.IsCoinBase()), vout(tx.vout), nHeight(nHeightIn), nVersion(tx.nVersion) {
+ ClearUnspendable();
+ }
// empty constructor
CCoins() : fCoinBase(false), vout(0), nHeight(0), nVersion(0) { }
@@ -402,6 +404,14 @@ public:
std::vector<CTxOut>().swap(vout);
}
+ void ClearUnspendable() {
+ BOOST_FOREACH(CTxOut &txout, vout) {
+ if (txout.scriptPubKey.IsUnspendable())
+ txout.SetNull();
+ }
+ Cleanup();
+ }
+
void swap(CCoins &to) {
std::swap(to.fCoinBase, fCoinBase);
to.vout.swap(vout);
diff --git a/src/db.cpp b/src/db.cpp
index 03f46f3c26..f722c52e93 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -38,7 +38,7 @@ void CDBEnv::EnvShutdown()
fDbEnvInit = false;
int ret = dbenv.close(0);
if (ret != 0)
- printf("EnvShutdown exception: %s (%d)\n", DbEnv::strerror(ret), ret);
+ LogPrintf("EnvShutdown exception: %s (%d)\n", DbEnv::strerror(ret), ret);
if (!fMockDb)
DbEnv(0).remove(path.string().c_str(), 0);
}
@@ -70,7 +70,7 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn)
filesystem::path pathLogDir = path / "database";
filesystem::create_directory(pathLogDir);
filesystem::path pathErrorFile = path / "db.log";
- printf("dbenv.open LogDir=%s ErrorFile=%s\n", pathLogDir.string().c_str(), pathErrorFile.string().c_str());
+ LogPrintf("dbenv.open LogDir=%s ErrorFile=%s\n", pathLogDir.string().c_str(), pathErrorFile.string().c_str());
unsigned int nEnvFlags = 0;
if (GetBoolArg("-privdb", true))
@@ -111,7 +111,7 @@ void CDBEnv::MakeMock()
boost::this_thread::interruption_point();
- printf("CDBEnv::MakeMock()\n");
+ LogPrint("db", "CDBEnv::MakeMock()\n");
dbenv.set_cachesize(1, 0, 1);
dbenv.set_lg_bsize(10485760*4);
@@ -168,16 +168,16 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive,
int result = db.verify(strFile.c_str(), NULL, &strDump, flags);
if (result == DB_VERIFY_BAD)
{
- printf("Error: Salvage found errors, all data may not be recoverable.\n");
+ LogPrintf("Error: Salvage found errors, all data may not be recoverable.\n");
if (!fAggressive)
{
- printf("Error: Rerun with aggressive mode to ignore errors and continue.\n");
+ LogPrintf("Error: Rerun with aggressive mode to ignore errors and continue.\n");
return false;
}
}
if (result != 0 && result != DB_VERIFY_BAD)
{
- printf("ERROR: db salvage failed: %d\n",result);
+ LogPrintf("ERROR: db salvage failed: %d\n",result);
return false;
}
@@ -348,7 +348,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
bitdb.mapFileUseCount.erase(strFile);
bool fSuccess = true;
- printf("Rewriting %s...\n", strFile.c_str());
+ LogPrintf("Rewriting %s...\n", strFile.c_str());
string strFileRes = strFile + ".rewrite";
{ // surround usage of db with extra {}
CDB db(strFile.c_str(), "r");
@@ -362,7 +362,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
0);
if (ret > 0)
{
- printf("Cannot create database file %s\n", strFileRes.c_str());
+ LogPrintf("Cannot create database file %s\n", strFileRes.c_str());
fSuccess = false;
}
@@ -418,7 +418,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
fSuccess = false;
}
if (!fSuccess)
- printf("Rewriting of %s FAILED!\n", strFileRes.c_str());
+ LogPrintf("Rewriting of %s FAILED!\n", strFileRes.c_str());
return fSuccess;
}
}
@@ -433,7 +433,7 @@ void CDBEnv::Flush(bool fShutdown)
int64 nStart = GetTimeMillis();
// Flush log data to the actual data file
// on all files that are not in use
- printf("Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started");
+ LogPrint("db", "Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started");
if (!fDbEnvInit)
return;
{
@@ -443,23 +443,23 @@ void CDBEnv::Flush(bool fShutdown)
{
string strFile = (*mi).first;
int nRefCount = (*mi).second;
- printf("%s refcount=%d\n", strFile.c_str(), nRefCount);
+ LogPrint("db", "%s refcount=%d\n", strFile.c_str(), nRefCount);
if (nRefCount == 0)
{
// Move log data to the dat file
CloseDb(strFile);
- printf("%s checkpoint\n", strFile.c_str());
+ LogPrint("db", "%s checkpoint\n", strFile.c_str());
dbenv.txn_checkpoint(0, 0, 0);
- printf("%s detach\n", strFile.c_str());
+ LogPrint("db", "%s detach\n", strFile.c_str());
if (!fMockDb)
dbenv.lsn_reset(strFile.c_str(), 0);
- printf("%s closed\n", strFile.c_str());
+ LogPrint("db", "%s closed\n", strFile.c_str());
mapFileUseCount.erase(mi++);
}
else
mi++;
}
- printf("DBFlush(%s)%s ended %15"PRI64d"ms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started", GetTimeMillis() - nStart);
+ LogPrint("db", "DBFlush(%s)%s ended %15"PRI64d"ms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started", GetTimeMillis() - nStart);
if (fShutdown)
{
char** listp;
diff --git a/src/init.cpp b/src/init.cpp
index db368c7f53..e75e981a57 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -3,6 +3,10 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#if defined(HAVE_CONFIG_H)
+#include "bitcoin-config.h"
+#endif
+
#include "init.h"
#include "main.h"
#include "core.h"
@@ -96,6 +100,7 @@ static CCoinsViewDB *pcoinsdbview;
void Shutdown()
{
+ LogPrintf("Shutdown : In progress...\n");
static CCriticalSection cs_Shutdown;
TRY_LOCK(cs_Shutdown, lockShutdown);
if (!lockShutdown) return;
@@ -104,7 +109,8 @@ void Shutdown()
nTransactionsUpdated++;
StopRPCThreads();
ShutdownRPCMining();
- bitdb.Flush(false);
+ if (pwalletMain)
+ bitdb.Flush(false);
GenerateBitcoins(false, NULL);
StopNode();
{
@@ -119,10 +125,13 @@ void Shutdown()
delete pcoinsdbview; pcoinsdbview = NULL;
delete pblocktree; pblocktree = NULL;
}
- bitdb.Flush(true);
+ if (pwalletMain)
+ bitdb.Flush(true);
boost::filesystem::remove(GetPidFile());
UnregisterAllWallets();
- delete pwalletMain;
+ if (pwalletMain)
+ delete pwalletMain;
+ LogPrintf("Shutdown : done\n");
}
//
@@ -280,13 +289,13 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
FILE *file = OpenBlockFile(pos, true);
if (!file)
break;
- printf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
+ LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
LoadExternalBlockFile(file, &pos);
nFile++;
}
pblocktree->WriteReindexing(false);
fReindex = false;
- printf("Reindexing finished\n");
+ LogPrintf("Reindexing finished\n");
// To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
InitBlockIndex();
}
@@ -298,7 +307,7 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
if (file) {
CImportingNow imp;
filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
- printf("Importing bootstrap.dat...\n");
+ LogPrintf("Importing bootstrap.dat...\n");
LoadExternalBlockFile(file);
RenameOver(pathBootstrap, pathBootstrapOld);
}
@@ -309,7 +318,7 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
FILE *file = fopen(path.string().c_str(), "rb");
if (file) {
CImportingNow imp;
- printf("Importing %s...\n", path.string().c_str());
+ LogPrintf("Importing %s...\n", path.string().c_str());
LoadExternalBlockFile(file);
}
}
@@ -335,8 +344,8 @@ bool AppInit2(boost::thread_group& threadGroup)
// Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008
// A failure is non-critical and needs no further attention!
#ifndef PROCESS_DEP_ENABLE
-// We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7),
-// which is not correct. Can be removed, when GCCs winbase.h is fixed!
+ // We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7),
+ // which is not correct. Can be removed, when GCCs winbase.h is fixed!
#define PROCESS_DEP_ENABLE 0x00000001
#endif
typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD);
@@ -377,8 +386,6 @@ bool AppInit2(boost::thread_group& threadGroup)
// ********************************************************* Step 2: parameter interactions
- Checkpoints::fEnabled = GetBoolArg("-checkpoints", true);
-
if (mapArgs.count("-bind")) {
// when specifying an explicit binding address, you want to listen on it
// even when -connect or -proxy is specified
@@ -424,9 +431,10 @@ bool AppInit2(boost::thread_group& threadGroup)
// ********************************************************* Step 3: parameter-to-internal-flags
- fDebug = GetBoolArg("-debug", false);
+ if (mapMultiArgs.count("-debug")) fDebug = true;
fBenchmark = GetBoolArg("-benchmark", false);
mempool.fChecks = GetBoolArg("-checkmempool", RegTest());
+ Checkpoints::fEnabled = GetBoolArg("-checkpoints", true);
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
nScriptCheckThreads = GetArg("-par", 0);
@@ -519,21 +527,21 @@ bool AppInit2(boost::thread_group& threadGroup)
if (GetBoolArg("-shrinkdebugfile", !fDebug))
ShrinkDebugFile();
- printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
- printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
- printf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
+ LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
+ LogPrintf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
+ LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
if (!fLogTimestamps)
- printf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str());
- printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
- printf("Using data directory %s\n", strDataDir.c_str());
- printf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
+ LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str());
+ LogPrintf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
+ LogPrintf("Using data directory %s\n", strDataDir.c_str());
+ LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
std::ostringstream strErrors;
if (fDaemon)
fprintf(stdout, "Bitcoin server starting\n");
if (nScriptCheckThreads) {
- printf("Using %u threads for script verification\n", nScriptCheckThreads);
+ LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads);
for (int i=0; i<nScriptCheckThreads-1; i++)
threadGroup.create_thread(&ThreadScriptCheck);
}
@@ -551,7 +559,7 @@ bool AppInit2(boost::thread_group& threadGroup)
boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%"PRI64d".bak", GetTime());
try {
boost::filesystem::rename(pathDatabase, pathDatabaseBak);
- printf("Moved old %s to %s. Retrying.\n", pathDatabase.string().c_str(), pathDatabaseBak.string().c_str());
+ LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string().c_str(), pathDatabaseBak.string().c_str());
} catch(boost::filesystem::filesystem_error &error) {
// failure is ok (well, not really, but it's not worse than what we started with)
}
@@ -702,12 +710,12 @@ bool AppInit2(boost::thread_group& threadGroup)
filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
try {
filesystem::create_hard_link(source, dest);
- printf("Hardlinked %s -> %s\n", source.string().c_str(), dest.string().c_str());
+ LogPrintf("Hardlinked %s -> %s\n", source.string().c_str(), dest.string().c_str());
linked = true;
} catch (filesystem::filesystem_error & e) {
// Note: hardlink creation failing is not a disaster, it just means
// blocks will get re-downloaded from peers.
- printf("Error hardlinking blk%04u.dat : %s\n", i, e.what());
+ LogPrintf("Error hardlinking blk%04u.dat : %s\n", i, e.what());
break;
}
}
@@ -775,12 +783,12 @@ bool AppInit2(boost::thread_group& threadGroup)
uiInterface.InitMessage(_("Verifying blocks..."));
if (!VerifyDB(GetArg("-checklevel", 3),
- GetArg( "-checkblocks", 288))) {
+ GetArg("-checkblocks", 288))) {
strLoadError = _("Corrupted block database detected");
break;
}
} catch(std::exception &e) {
- if (fDebug) printf("%s\n", e.what());
+ if (fDebug) LogPrintf("%s\n", e.what());
strLoadError = _("Error opening block database");
break;
}
@@ -798,7 +806,7 @@ bool AppInit2(boost::thread_group& threadGroup)
fReindex = true;
fRequestShutdown = false;
} else {
- printf("Aborted block database rebuild. Exiting.\n");
+ LogPrintf("Aborted block database rebuild. Exiting.\n");
return false;
}
} else {
@@ -812,10 +820,10 @@ bool AppInit2(boost::thread_group& threadGroup)
// As the program has not fully started yet, Shutdown() is possibly overkill.
if (fRequestShutdown)
{
- printf("Shutdown requested. Exiting.\n");
+ LogPrintf("Shutdown requested. Exiting.\n");
return false;
}
- printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
+ LogPrintf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
if (GetBoolArg("-printblockindex", false) || GetBoolArg("-printblocktree", false))
{
@@ -837,12 +845,12 @@ bool AppInit2(boost::thread_group& threadGroup)
ReadBlockFromDisk(block, pindex);
block.BuildMerkleTree();
block.print();
- printf("\n");
+ LogPrintf("\n");
nFound++;
}
}
if (nFound == 0)
- printf("No blocks matching %s were found\n", strMatch.c_str());
+ LogPrintf("No blocks matching %s were found\n", strMatch.c_str());
return false;
}
@@ -869,7 +877,7 @@ bool AppInit2(boost::thread_group& threadGroup)
else if (nLoadWalletRet == DB_NEED_REWRITE)
{
strErrors << _("Wallet needed to be rewritten: restart Bitcoin to complete") << "\n";
- printf("%s", strErrors.str().c_str());
+ LogPrintf("%s", strErrors.str().c_str());
return InitError(strErrors.str());
}
else
@@ -881,12 +889,12 @@ bool AppInit2(boost::thread_group& threadGroup)
int nMaxVersion = GetArg("-upgradewallet", 0);
if (nMaxVersion == 0) // the -upgradewallet without argument case
{
- printf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
+ LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
nMaxVersion = CLIENT_VERSION;
pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
}
else
- printf("Allowing wallet upgrade up to %i\n", nMaxVersion);
+ LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
if (nMaxVersion < pwalletMain->GetVersion())
strErrors << _("Cannot downgrade wallet") << "\n";
pwalletMain->SetMaxVersion(nMaxVersion);
@@ -898,7 +906,7 @@ bool AppInit2(boost::thread_group& threadGroup)
RandAddSeedPerfmon();
CPubKey newDefaultKey;
- if (pwalletMain->GetKeyFromPool(newDefaultKey, false)) {
+ if (pwalletMain->GetKeyFromPool(newDefaultKey)) {
pwalletMain->SetDefaultKey(newDefaultKey);
if (!pwalletMain->SetAddressBook(pwalletMain->vchDefaultKey.GetID(), "", "receive"))
strErrors << _("Cannot write default address") << "\n";
@@ -907,8 +915,8 @@ bool AppInit2(boost::thread_group& threadGroup)
pwalletMain->SetBestChain(CBlockLocator(pindexBest));
}
- printf("%s", strErrors.str().c_str());
- printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
+ LogPrintf("%s", strErrors.str().c_str());
+ LogPrintf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
RegisterWallet(pwalletMain);
@@ -927,10 +935,10 @@ bool AppInit2(boost::thread_group& threadGroup)
if (pindexBest && pindexBest != pindexRescan)
{
uiInterface.InitMessage(_("Rescanning..."));
- printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
+ LogPrintf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
nStart = GetTimeMillis();
pwalletMain->ScanForWalletTransactions(pindexRescan, true);
- printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
+ LogPrintf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
pwalletMain->SetBestChain(CBlockLocator(pindexBest));
nWalletDBUpdated++;
}
@@ -959,10 +967,10 @@ bool AppInit2(boost::thread_group& threadGroup)
{
CAddrDB adb;
if (!adb.Read(addrman))
- printf("Invalid or missing peers.dat; recreating\n");
+ LogPrintf("Invalid or missing peers.dat; recreating\n");
}
- printf("Loaded %i addresses from peers.dat %"PRI64d"ms\n",
+ LogPrintf("Loaded %i addresses from peers.dat %"PRI64d"ms\n",
addrman.size(), GetTimeMillis() - nStart);
// ********************************************************* Step 11: start node
@@ -976,11 +984,11 @@ bool AppInit2(boost::thread_group& threadGroup)
RandAddSeedPerfmon();
//// debug print
- printf("mapBlockIndex.size() = %"PRIszu"\n", mapBlockIndex.size());
- printf("nBestHeight = %d\n", nBestHeight);
- printf("setKeyPool.size() = %"PRIszu"\n", pwalletMain->setKeyPool.size());
- printf("mapWallet.size() = %"PRIszu"\n", pwalletMain->mapWallet.size());
- printf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain->mapAddressBook.size());
+ LogPrintf("mapBlockIndex.size() = %"PRIszu"\n", mapBlockIndex.size());
+ LogPrintf("nBestHeight = %d\n", nBestHeight);
+ LogPrintf("setKeyPool.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0);
+ LogPrintf("mapWallet.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->mapWallet.size() : 0);
+ LogPrintf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0);
StartNode(threadGroup);
@@ -990,17 +998,20 @@ bool AppInit2(boost::thread_group& threadGroup)
StartRPCThreads();
// Generate coins in the background
- GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
+ if (pwalletMain)
+ GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
// ********************************************************* Step 12: finished
uiInterface.InitMessage(_("Done loading"));
- // Add wallet transactions that aren't already in a block to mapTransactions
- pwalletMain->ReacceptWalletTransactions();
+ if (pwalletMain) {
+ // Add wallet transactions that aren't already in a block to mapTransactions
+ pwalletMain->ReacceptWalletTransactions();
- // Run a thread to flush wallet periodically
- threadGroup.create_thread(boost::bind(&ThreadFlushWalletDB, boost::ref(pwalletMain->strWalletFile)));
+ // Run a thread to flush wallet periodically
+ threadGroup.create_thread(boost::bind(&ThreadFlushWalletDB, boost::ref(pwalletMain->strWalletFile)));
+ }
return !fRequestShutdown;
}
diff --git a/src/key.cpp b/src/key.cpp
index 85dc9cda2b..8ef1c414c4 100644
--- a/src/key.cpp
+++ b/src/key.cpp
@@ -199,17 +199,19 @@ public:
ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
if (sig == NULL)
return false;
- if (BN_is_odd(sig->s)) {
- // enforce even S values, by negating the value (modulo the order) if odd
- BN_CTX *ctx = BN_CTX_new();
- BN_CTX_start(ctx);
- const EC_GROUP *group = EC_KEY_get0_group(pkey);
- BIGNUM *order = BN_CTX_get(ctx);
- EC_GROUP_get_order(group, order, ctx);
+ BN_CTX *ctx = BN_CTX_new();
+ BN_CTX_start(ctx);
+ const EC_GROUP *group = EC_KEY_get0_group(pkey);
+ BIGNUM *order = BN_CTX_get(ctx);
+ BIGNUM *halforder = BN_CTX_get(ctx);
+ EC_GROUP_get_order(group, order, ctx);
+ BN_rshift1(halforder, order);
+ if (BN_cmp(sig->s, halforder) > 0) {
+ // enforce low S values, by negating the value (modulo the order) if above order/2.
BN_sub(sig->s, order, sig->s);
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
}
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
unsigned int nSize = ECDSA_size(pkey);
vchSig.resize(nSize); // Make sure it is big enough
unsigned char *pos = &vchSig[0];
diff --git a/src/leveldb.cpp b/src/leveldb.cpp
index 5e3fa08f5e..fb202367c4 100644
--- a/src/leveldb.cpp
+++ b/src/leveldb.cpp
@@ -15,7 +15,7 @@
void HandleError(const leveldb::Status &status) throw(leveldb_error) {
if (status.ok())
return;
- printf("%s\n", status.ToString().c_str());
+ LogPrintf("%s\n", status.ToString().c_str());
if (status.IsCorruption())
throw leveldb_error("Database corrupted");
if (status.IsIOError())
@@ -48,15 +48,15 @@ CLevelDB::CLevelDB(const boost::filesystem::path &path, size_t nCacheSize, bool
options.env = penv;
} else {
if (fWipe) {
- printf("Wiping LevelDB in %s\n", path.string().c_str());
+ LogPrintf("Wiping LevelDB in %s\n", path.string().c_str());
leveldb::DestroyDB(path.string(), options);
}
boost::filesystem::create_directory(path);
- printf("Opening LevelDB in %s\n", path.string().c_str());
+ LogPrintf("Opening LevelDB in %s\n", path.string().c_str());
}
leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb);
HandleError(status);
- printf("Opened LevelDB successfully\n");
+ LogPrintf("Opened LevelDB successfully\n");
}
CLevelDB::~CLevelDB() {
diff --git a/src/leveldb.h b/src/leveldb.h
index 79262edbb5..7daddeb493 100644
--- a/src/leveldb.h
+++ b/src/leveldb.h
@@ -5,6 +5,7 @@
#define BITCOIN_LEVELDB_H
#include "serialize.h"
+#include "util.h"
#include <leveldb/db.h>
#include <leveldb/write_batch.h>
@@ -91,7 +92,7 @@ public:
if (!status.ok()) {
if (status.IsNotFound())
return false;
- printf("LevelDB read failure: %s\n", status.ToString().c_str());
+ LogPrintf("LevelDB read failure: %s\n", status.ToString().c_str());
HandleError(status);
}
try {
@@ -120,7 +121,7 @@ public:
if (!status.ok()) {
if (status.IsNotFound())
return false;
- printf("LevelDB read failure: %s\n", status.ToString().c_str());
+ LogPrintf("LevelDB read failure: %s\n", status.ToString().c_str());
HandleError(status);
}
return true;
diff --git a/src/m4/ax_boost_base.m4 b/src/m4/ax_boost_base.m4
new file mode 100644
index 0000000000..54a2a1bee7
--- /dev/null
+++ b/src/m4/ax_boost_base.m4
@@ -0,0 +1,258 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_base.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_BASE([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# DESCRIPTION
+#
+# Test for the Boost C++ libraries of a particular version (or newer)
+#
+# If no path to the installed boost library is given the macro searchs
+# under /usr, /usr/local, /opt and /opt/local and evaluates the
+# $BOOST_ROOT environment variable. Further documentation is available at
+# <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
+#
+# And sets:
+#
+# HAVE_BOOST
+#
+# LICENSE
+#
+# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+# Copyright (c) 2009 Peter Adolphs
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 20
+
+AC_DEFUN([AX_BOOST_BASE],
+[
+AC_ARG_WITH([boost],
+ [AS_HELP_STRING([--with-boost@<:@=ARG@:>@],
+ [use Boost library from a standard location (ARG=yes),
+ from the specified location (ARG=<path>),
+ or disable it (ARG=no)
+ @<:@ARG=yes@:>@ ])],
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ac_boost_path=""
+ else
+ want_boost="yes"
+ ac_boost_path="$withval"
+ fi
+ ],
+ [want_boost="yes"])
+
+
+AC_ARG_WITH([boost-libdir],
+ AS_HELP_STRING([--with-boost-libdir=LIB_DIR],
+ [Force given directory for boost libraries. Note that this will override library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]),
+ [
+ if test -d "$withval"
+ then
+ ac_boost_lib_path="$withval"
+ else
+ AC_MSG_ERROR(--with-boost-libdir expected directory name)
+ fi
+ ],
+ [ac_boost_lib_path=""]
+)
+
+if test "x$want_boost" = "xyes"; then
+ boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
+ boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
+ boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
+ boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
+ boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
+ if test "x$boost_lib_version_req_sub_minor" = "x" ; then
+ boost_lib_version_req_sub_minor="0"
+ fi
+ WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
+ AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
+ succeeded=no
+
+ dnl On 64-bit systems check for system libraries in both lib64 and lib.
+ dnl The former is specified by FHS, but e.g. Debian does not adhere to
+ dnl this (as it rises problems for generic multi-arch support).
+ dnl The last entry in the list is chosen by default when no libraries
+ dnl are found, e.g. when only header-only libraries are installed!
+ libsubdirs="lib"
+ ax_arch=`uname -m`
+ if test $ax_arch = x86_64 -o $ax_arch = ppc64 -o $ax_arch = s390x -o $ax_arch = sparc64; then
+ libsubdirs="lib64 lib lib64"
+ fi
+
+ dnl first we check the system location for boost libraries
+ dnl this location ist chosen if boost libraries are installed with the --layout=system option
+ dnl or if you install boost with RPM
+ if test "$ac_boost_path" != ""; then
+ BOOST_CPPFLAGS="-I$ac_boost_path/include"
+ for ac_boost_path_tmp in $libsubdirs; do
+ if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then
+ BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp"
+ break
+ fi
+ done
+ elif test "$cross_compiling" != yes; then
+ for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
+ if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
+ for libsubdir in $libsubdirs ; do
+ if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
+ done
+ BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir"
+ BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
+ break;
+ fi
+ done
+ fi
+
+ dnl overwrite ld flags if we have required special directory with
+ dnl --with-boost-libdir parameter
+ if test "$ac_boost_lib_path" != ""; then
+ BOOST_LDFLAGS="-L$ac_boost_lib_path"
+ fi
+
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_REQUIRE([AC_PROG_CXX])
+ AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ @%:@include <boost/version.hpp>
+ ]], [[
+ #if BOOST_VERSION >= $WANT_BOOST_VERSION
+ // Everything is okay
+ #else
+ # error Boost version is too old
+ #endif
+ ]])],[
+ AC_MSG_RESULT(yes)
+ succeeded=yes
+ found_system=yes
+ ],[
+ ])
+ AC_LANG_POP([C++])
+
+
+
+ dnl if we found no boost with system layout we search for boost libraries
+ dnl built and installed without the --layout=system option or for a staged(not installed) version
+ if test "x$succeeded" != "xyes"; then
+ _version=0
+ if test "$ac_boost_path" != ""; then
+ if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
+ for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
+ _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
+ V_CHECK=`expr $_version_tmp \> $_version`
+ if test "$V_CHECK" = "1" ; then
+ _version=$_version_tmp
+ fi
+ VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
+ BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
+ done
+ fi
+ else
+ if test "$cross_compiling" != yes; then
+ for ac_boost_path in /usr /usr/local /opt /opt/local ; do
+ if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
+ for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
+ _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
+ V_CHECK=`expr $_version_tmp \> $_version`
+ if test "$V_CHECK" = "1" ; then
+ _version=$_version_tmp
+ best_path=$ac_boost_path
+ fi
+ done
+ fi
+ done
+
+ VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
+ BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
+ if test "$ac_boost_lib_path" = ""; then
+ for libsubdir in $libsubdirs ; do
+ if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
+ done
+ BOOST_LDFLAGS="-L$best_path/$libsubdir"
+ fi
+ fi
+
+ if test "x$BOOST_ROOT" != "x"; then
+ for libsubdir in $libsubdirs ; do
+ if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
+ done
+ if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then
+ version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
+ stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
+ stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
+ V_CHECK=`expr $stage_version_shorten \>\= $_version`
+ if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
+ AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
+ BOOST_CPPFLAGS="-I$BOOST_ROOT"
+ BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir"
+ fi
+ fi
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ @%:@include <boost/version.hpp>
+ ]], [[
+ #if BOOST_VERSION >= $WANT_BOOST_VERSION
+ // Everything is okay
+ #else
+ # error Boost version is too old
+ #endif
+ ]])],[
+ AC_MSG_RESULT(yes)
+ succeeded=yes
+ found_system=yes
+ ],[
+ ])
+ AC_LANG_POP([C++])
+ fi
+
+ if test "$succeeded" != "yes" ; then
+ if test "$_version" = "0" ; then
+ AC_MSG_NOTICE([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
+ else
+ AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).])
+ fi
+ # execute ACTION-IF-NOT-FOUND (if present):
+ ifelse([$3], , :, [$3])
+ else
+ AC_SUBST(BOOST_CPPFLAGS)
+ AC_SUBST(BOOST_LDFLAGS)
+ AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
+ # execute ACTION-IF-FOUND (if present):
+ ifelse([$2], , :, [$2])
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+fi
+
+])
diff --git a/src/m4/ax_boost_chrono.m4 b/src/m4/ax_boost_chrono.m4
new file mode 100644
index 0000000000..9b3958ec74
--- /dev/null
+++ b/src/m4/ax_boost_chrono.m4
@@ -0,0 +1,118 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_chrono.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_CHRONO
+#
+# DESCRIPTION
+#
+# Test for System library from the Boost C++ libraries. The macro requires
+# a preceding call to AX_BOOST_BASE. Further documentation is available at
+# <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_CHRONO_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_CHRONO
+#
+# LICENSE
+#
+# Copyright (c) 2012 Xiyue Deng <manphiz@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 1
+
+AC_DEFUN([AX_BOOST_CHRONO],
+[
+ AC_ARG_WITH([boost-chrono],
+ AS_HELP_STRING([--with-boost-chrono@<:@=special-lib@:>@],
+ [use the Chrono library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-chrono=boost_chrono-gcc-mt ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_chrono_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_chrono_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_BUILD])
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_CACHE_CHECK(whether the Boost::Chrono library is available,
+ ax_cv_boost_chrono,
+ [AC_LANG_PUSH([C++])
+ CXXFLAGS_SAVE=$CXXFLAGS
+
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/chrono.hpp>]],
+ [[boost::chrono::system_clock::time_point time;]])],
+ ax_cv_boost_chrono=yes, ax_cv_boost_chrono=no)
+ CXXFLAGS=$CXXFLAGS_SAVE
+ AC_LANG_POP([C++])
+ ])
+ if test "x$ax_cv_boost_chrono" = "xyes"; then
+ AC_SUBST(BOOST_CPPFLAGS)
+
+ AC_DEFINE(HAVE_BOOST_CHRONO,,[define if the Boost::Chrono library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+
+ LDFLAGS_SAVE=$LDFLAGS
+ if test "x$ax_boost_user_chrono_lib" = "x"; then
+ for libextension in `ls $BOOSTLIBDIR/libboost_chrono*.so* $BOOSTLIBDIR/libboost_chrono*.dylib* $BOOSTLIBDIR/libboost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_chrono.*\)\.so.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.a.*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break],
+ [link_chrono="no"])
+ done
+ if test "x$link_chrono" != "xyes"; then
+ for libextension in `ls $BOOSTLIBDIR/boost_chrono*.dll* $BOOSTLIBDIR/boost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_chrono.*\)\.dll.*$;\1;' -e 's;^\(boost_chrono.*\)\.a.*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break],
+ [link_chrono="no"])
+ done
+ fi
+
+ else
+ for ax_lib in $ax_boost_user_chrono_lib boost_chrono-$ax_boost_user_chrono_lib; do
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break],
+ [link_chrono="no"])
+ done
+
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the library!)
+ fi
+ if test "x$link_chrono" = "xno"; then
+ AC_MSG_ERROR(Could not link against $ax_lib !)
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ fi
+])
diff --git a/src/m4/ax_boost_filesystem.m4 b/src/m4/ax_boost_filesystem.m4
new file mode 100644
index 0000000000..2a62da8d89
--- /dev/null
+++ b/src/m4/ax_boost_filesystem.m4
@@ -0,0 +1,118 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_FILESYSTEM
+#
+# DESCRIPTION
+#
+# Test for Filesystem library from the Boost C++ libraries. The macro
+# requires a preceding call to AX_BOOST_BASE. Further documentation is
+# available at <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_FILESYSTEM_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_FILESYSTEM
+#
+# LICENSE
+#
+# Copyright (c) 2009 Thomas Porschberg <thomas@randspringer.de>
+# Copyright (c) 2009 Michael Tindal
+# Copyright (c) 2009 Roman Rybalko <libtorrent@romanr.info>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 21
+
+AC_DEFUN([AX_BOOST_FILESYSTEM],
+[
+ AC_ARG_WITH([boost-filesystem],
+ AS_HELP_STRING([--with-boost-filesystem@<:@=special-lib@:>@],
+ [use the Filesystem library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-filesystem=boost_filesystem-gcc-mt ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_filesystem_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_filesystem_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ LIBS_SAVED=$LIBS
+ LIBS="$LIBS $BOOST_SYSTEM_LIB"
+ export LIBS
+
+ AC_CACHE_CHECK(whether the Boost::Filesystem library is available,
+ ax_cv_boost_filesystem,
+ [AC_LANG_PUSH([C++])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/filesystem/path.hpp>]],
+ [[using namespace boost::filesystem;
+ path my_path( "foo/bar/data.txt" );
+ return 0;]])],
+ ax_cv_boost_filesystem=yes, ax_cv_boost_filesystem=no)
+ AC_LANG_POP([C++])
+ ])
+ if test "x$ax_cv_boost_filesystem" = "xyes"; then
+ AC_DEFINE(HAVE_BOOST_FILESYSTEM,,[define if the Boost::Filesystem library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+ if test "x$ax_boost_user_filesystem_lib" = "x"; then
+ for libextension in `ls $BOOSTLIBDIR/libboost_filesystem*.so* $BOOSTLIBDIR/libboost_filesystem*.dylib* $BOOSTLIBDIR/libboost_filesystem*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_filesystem.*\)\.so.*$;\1;' -e 's;^lib\(boost_filesystem.*\)\.a*$;\1;' -e 's;^lib\(boost_filesystem.*\)\.dylib$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break],
+ [link_filesystem="no"])
+ done
+ if test "x$link_program_options" != "xyes"; then
+ for libextension in `ls $BOOSTLIBDIR/boost_filesystem*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_filesystem.*\)\.dll.*$;\1;' -e 's;^\(boost_filesystem.*\)\.a*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break],
+ [link_filesystem="no"])
+ done
+ fi
+ else
+ for ax_lib in $ax_boost_user_filesystem_lib boost_filesystem-$ax_boost_user_filesystem_lib; do
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break],
+ [link_filesystem="no"])
+ done
+
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the library!)
+ fi
+ if test "x$link_filesystem" != "xyes"; then
+ AC_MSG_ERROR(Could not link against $ax_lib !)
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ LIBS="$LIBS_SAVED"
+ fi
+])
diff --git a/src/m4/ax_boost_program_options.m4 b/src/m4/ax_boost_program_options.m4
new file mode 100644
index 0000000000..d612f91da3
--- /dev/null
+++ b/src/m4/ax_boost_program_options.m4
@@ -0,0 +1,108 @@
+# ============================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_program_options.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_PROGRAM_OPTIONS
+#
+# DESCRIPTION
+#
+# Test for program options library from the Boost C++ libraries. The macro
+# requires a preceding call to AX_BOOST_BASE. Further documentation is
+# available at <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_PROGRAM_OPTIONS
+#
+# LICENSE
+#
+# Copyright (c) 2009 Thomas Porschberg <thomas@randspringer.de>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 20
+
+AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS],
+[
+ AC_ARG_WITH([boost-program-options],
+ AS_HELP_STRING([--with-boost-program-options@<:@=special-lib@:>@],
+ [use the program options library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-program-options=boost_program_options-gcc-mt-1_33_1 ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_program_options_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_program_options_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ export want_boost
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+ AC_CACHE_CHECK([whether the Boost::Program_Options library is available],
+ ax_cv_boost_program_options,
+ [AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/program_options.hpp>
+ ]],
+ [[boost::program_options::options_description generic("Generic options");
+ return 0;]])],
+ ax_cv_boost_program_options=yes, ax_cv_boost_program_options=no)
+ AC_LANG_POP([C++])
+ ])
+ if test "$ax_cv_boost_program_options" = yes; then
+ AC_DEFINE(HAVE_BOOST_PROGRAM_OPTIONS,,[define if the Boost::PROGRAM_OPTIONS library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+ if test "x$ax_boost_user_program_options_lib" = "x"; then
+ for libextension in `ls $BOOSTLIBDIR/libboost_program_options*.so* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.so.*$;\1;'` `ls $BOOSTLIBDIR/libboost_program_options*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.a*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break],
+ [link_program_options="no"])
+ done
+ if test "x$link_program_options" != "xyes"; then
+ for libextension in `ls $BOOSTLIBDIR/boost_program_options*.dll* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_program_options.*\)\.dll.*$;\1;'` `ls $BOOSTLIBDIR/boost_program_options*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_program_options.*\)\.a*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break],
+ [link_program_options="no"])
+ done
+ fi
+ else
+ for ax_lib in $ax_boost_user_program_options_lib boost_program_options-$ax_boost_user_program_options_lib; do
+ AC_CHECK_LIB($ax_lib, main,
+ [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break],
+ [link_program_options="no"])
+ done
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the library!)
+ fi
+ if test "x$link_program_options" != "xyes"; then
+ AC_MSG_ERROR([Could not link against [$ax_lib] !])
+ fi
+ fi
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ fi
+])
diff --git a/src/m4/ax_boost_system.m4 b/src/m4/ax_boost_system.m4
new file mode 100644
index 0000000000..7fbf6d360d
--- /dev/null
+++ b/src/m4/ax_boost_system.m4
@@ -0,0 +1,120 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_system.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_SYSTEM
+#
+# DESCRIPTION
+#
+# Test for System library from the Boost C++ libraries. The macro requires
+# a preceding call to AX_BOOST_BASE. Further documentation is available at
+# <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_SYSTEM_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_SYSTEM
+#
+# LICENSE
+#
+# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+# Copyright (c) 2008 Michael Tindal
+# Copyright (c) 2008 Daniel Casimiro <dan.casimiro@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 14
+
+AC_DEFUN([AX_BOOST_SYSTEM],
+[
+ AC_ARG_WITH([boost-system],
+ AS_HELP_STRING([--with-boost-system@<:@=special-lib@:>@],
+ [use the System library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-system=boost_system-gcc-mt ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_system_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_system_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_BUILD])
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_CACHE_CHECK(whether the Boost::System library is available,
+ ax_cv_boost_system,
+ [AC_LANG_PUSH([C++])
+ CXXFLAGS_SAVE=$CXXFLAGS
+
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/system/error_code.hpp>]],
+ [[boost::system::system_category]])],
+ ax_cv_boost_system=yes, ax_cv_boost_system=no)
+ CXXFLAGS=$CXXFLAGS_SAVE
+ AC_LANG_POP([C++])
+ ])
+ if test "x$ax_cv_boost_system" = "xyes"; then
+ AC_SUBST(BOOST_CPPFLAGS)
+
+ AC_DEFINE(HAVE_BOOST_SYSTEM,,[define if the Boost::System library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+
+ LDFLAGS_SAVE=$LDFLAGS
+ if test "x$ax_boost_user_system_lib" = "x"; then
+ for libextension in `ls $BOOSTLIBDIR/libboost_system*.so* $BOOSTLIBDIR/libboost_system*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_system.*\)\.so.*$;\1;' -e 's;^lib\(boost_system.*\)\.a*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break],
+ [link_system="no"])
+ done
+ if test "x$link_system" != "xyes"; then
+ for libextension in `ls $BOOSTLIBDIR/boost_system*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_system.*\)\.dll.*$;\1;' -e 's;^\(boost_system.*\)\.a*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break],
+ [link_system="no"])
+ done
+ fi
+
+ else
+ for ax_lib in $ax_boost_user_system_lib boost_system-$ax_boost_user_system_lib; do
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break],
+ [link_system="no"])
+ done
+
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the library!)
+ fi
+ if test "x$link_system" = "xno"; then
+ AC_MSG_ERROR(Could not link against $ax_lib !)
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ fi
+])
diff --git a/src/m4/ax_boost_thread.m4 b/src/m4/ax_boost_thread.m4
new file mode 100644
index 0000000000..d9cd8a1d1d
--- /dev/null
+++ b/src/m4/ax_boost_thread.m4
@@ -0,0 +1,153 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_thread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_THREAD
+#
+# DESCRIPTION
+#
+# Test for Thread library from the Boost C++ libraries. The macro requires
+# a preceding call to AX_BOOST_BASE. Further documentation is available at
+# <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_THREAD_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_THREAD
+#
+# LICENSE
+#
+# Copyright (c) 2009 Thomas Porschberg <thomas@randspringer.de>
+# Copyright (c) 2009 Michael Tindal
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 22
+
+AC_DEFUN([AX_BOOST_THREAD],
+[
+ AC_ARG_WITH([boost-thread],
+ AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@],
+ [use the Thread library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-thread=boost_thread-gcc-mt ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_thread_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_thread_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_BUILD])
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_CACHE_CHECK(whether the Boost::Thread library is available,
+ ax_cv_boost_thread,
+ [AC_LANG_PUSH([C++])
+ CXXFLAGS_SAVE=$CXXFLAGS
+
+ # let us handle platform dependent issues in
+ # configure.ac
+
+ # if test "x$build_os" = "xsolaris" ; then
+ # CXXFLAGS="-pthreads $CXXFLAGS"
+ # elif test "x$build_os" = "xming32" ; then
+ # CXXFLAGS="-mthreads $CXXFLAGS"
+ # else
+ # CXXFLAGS="-pthread $CXXFLAGS"
+ # fi
+
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/thread/thread.hpp>]],
+ [[boost::thread_group thrds;
+ return 0;]])],
+ ax_cv_boost_thread=yes, ax_cv_boost_thread=no)
+ CXXFLAGS=$CXXFLAGS_SAVE
+ AC_LANG_POP([C++])
+ ])
+ if test "x$ax_cv_boost_thread" = "xyes"; then
+ # if test "x$build_os" = "xsolaris" ; then
+ # BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS"
+ # elif test "x$build_os" = "xming32" ; then
+ # BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS"
+ # else
+ # BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS"
+ # fi
+
+ AC_SUBST(BOOST_CPPFLAGS)
+
+ AC_DEFINE(HAVE_BOOST_THREAD,,[define if the Boost::Thread library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+
+ LDFLAGS_SAVE=$LDFLAGS
+ # case "x$build_os" in
+ # *bsd* )
+ # LDFLAGS="-pthread $LDFLAGS"
+ # break;
+ # ;;
+ # esac
+ if test "x$ax_boost_user_thread_lib" = "x"; then
+ for libextension in `ls $BOOSTLIBDIR/libboost_thread*.so* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_thread.*\)\.so.*$;\1;'` `ls $BOOSTLIBDIR/libboost_thread*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_thread.*\)\.a*$;\1;'`; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break],
+ [link_thread="no"])
+ done
+ if test "x$link_thread" != "xyes"; then
+ for libextension in `ls $BOOSTLIBDIR/boost_thread*.dll* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_thread.*\)\.dll.*$;\1;'` `ls $BOOSTLIBDIR/boost_thread*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_thread.*\)\.a*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break],
+ [link_thread="no"])
+ done
+ fi
+
+ else
+ for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break],
+ [link_thread="no"])
+ done
+
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the library!)
+ fi
+ # if test "x$link_thread" = "xno"; then
+ # AC_MSG_ERROR(Could not link against $ax_lib !)
+ # else
+ # case "x$build_os" in
+ # *bsd* )
+ # BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS"
+ # break;
+ # ;;
+ # esac
+
+ # fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ fi
+])
diff --git a/src/m4/ax_boost_unit_test_framework.m4 b/src/m4/ax_boost_unit_test_framework.m4
new file mode 100644
index 0000000000..1115f55121
--- /dev/null
+++ b/src/m4/ax_boost_unit_test_framework.m4
@@ -0,0 +1,137 @@
+# ================================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_unit_test_framework.html
+# ================================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_UNIT_TEST_FRAMEWORK
+#
+# DESCRIPTION
+#
+# Test for Unit_Test_Framework library from the Boost C++ libraries. The
+# macro requires a preceding call to AX_BOOST_BASE. Further documentation
+# is available at <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_UNIT_TEST_FRAMEWORK
+#
+# LICENSE
+#
+# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 19
+
+AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK],
+[
+ AC_ARG_WITH([boost-unit-test-framework],
+ AS_HELP_STRING([--with-boost-unit-test-framework@<:@=special-lib@:>@],
+ [use the Unit_Test_Framework library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-unit-test-framework=boost_unit_test_framework-gcc ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_unit_test_framework_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_unit_test_framework_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_CACHE_CHECK(whether the Boost::Unit_Test_Framework library is available,
+ ax_cv_boost_unit_test_framework,
+ [AC_LANG_PUSH([C++])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/test/unit_test.hpp>]],
+ [[using boost::unit_test::test_suite;
+ test_suite* test= BOOST_TEST_SUITE( "Unit test example 1" ); return 0;]])],
+ ax_cv_boost_unit_test_framework=yes, ax_cv_boost_unit_test_framework=no)
+ AC_LANG_POP([C++])
+ ])
+ if test "x$ax_cv_boost_unit_test_framework" = "xyes"; then
+ AC_DEFINE(HAVE_BOOST_UNIT_TEST_FRAMEWORK,,[define if the Boost::Unit_Test_Framework library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+
+ if test "x$ax_boost_user_unit_test_framework_lib" = "x"; then
+ saved_ldflags="${LDFLAGS}"
+ for monitor_library in `ls $BOOSTLIBDIR/libboost_unit_test_framework*.so* $BOOSTLIBDIR/libboost_unit_test_framework*.dylib* $BOOSTLIBDIR/libboost_unit_test_framework*.a* 2>/dev/null` ; do
+ if test -r $monitor_library ; then
+ libextension=`echo $monitor_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_unit_test_framework.*\)\.so.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.a.*$;\1;'`
+ ax_lib=${libextension}
+ link_unit_test_framework="yes"
+ else
+ link_unit_test_framework="no"
+ fi
+
+ if test "x$link_unit_test_framework" = "xyes"; then
+ BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib"
+ AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB)
+ break
+ fi
+ done
+ if test "x$link_unit_test_framework" != "xyes"; then
+ for libextension in `ls $BOOSTLIBDIR/boost_unit_test_framework*.dll* $BOOSTLIBDIR/boost_unit_test_framework*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_unit_test_framework.*\)\.dll.*$;\1;' -e 's;^\(boost_unit_test_framework.*\)\.a.*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib"; AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) link_unit_test_framework="yes"; break],
+ [link_unit_test_framework="no"])
+ done
+ fi
+ else
+ link_unit_test_framework="no"
+ saved_ldflags="${LDFLAGS}"
+ for ax_lib in boost_unit_test_framework-$ax_boost_user_unit_test_framework_lib $ax_boost_user_unit_test_framework_lib ; do
+ if test "x$link_unit_test_framework" = "xyes"; then
+ break;
+ fi
+ for unittest_library in `ls $BOOSTLIBDIR/lib${ax_lib}.so* $BOOSTLIBDIR/lib${ax_lib}.a* 2>/dev/null` ; do
+ if test -r $unittest_library ; then
+ libextension=`echo $unittest_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_unit_test_framework.*\)\.so.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.a*$;\1;'`
+ ax_lib=${libextension}
+ link_unit_test_framework="yes"
+ else
+ link_unit_test_framework="no"
+ fi
+
+ if test "x$link_unit_test_framework" = "xyes"; then
+ BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib"
+ AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB)
+ break
+ fi
+ done
+ done
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the library!)
+ fi
+ if test "x$link_unit_test_framework" != "xyes"; then
+ AC_MSG_ERROR(Could not link against $ax_lib !)
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ fi
+])
diff --git a/src/m4/ax_check_compile_flag.m4 b/src/m4/ax_check_compile_flag.m4
new file mode 100644
index 0000000000..c3a8d695a1
--- /dev/null
+++ b/src/m4/ax_check_compile_flag.m4
@@ -0,0 +1,72 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the current language's compiler
+# or gives an error. (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/src/m4/ax_check_link_flag.m4 b/src/m4/ax_check_link_flag.m4
new file mode 100644
index 0000000000..e2d0d363e4
--- /dev/null
+++ b/src/m4/ax_check_link_flag.m4
@@ -0,0 +1,71 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the linker or gives an error.
+# (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the linker's default flags
+# when the check is done. The check is thus made with the flags: "LDFLAGS
+# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
+# issue an error when a bad flag is given.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_LINK_FLAG],
+[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
+AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
+ ax_check_save_flags=$LDFLAGS
+ LDFLAGS="$LDFLAGS $4 $1"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM()],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ LDFLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_LINK_FLAGS
diff --git a/src/m4/ax_check_preproc_flag.m4 b/src/m4/ax_check_preproc_flag.m4
new file mode 100644
index 0000000000..b1cfef6b86
--- /dev/null
+++ b/src/m4/ax_check_preproc_flag.m4
@@ -0,0 +1,72 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_preproc_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_PREPROC_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the current language's
+# preprocessor or gives an error. (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the preprocessor's default
+# flags when the check is done. The check is thus made with the flags:
+# "CPPFLAGS EXTRA-FLAGS FLAG". This can for example be used to force the
+# preprocessor to issue an error when a bad flag is given.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{COMPILE,LINK}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_PREPROC_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]cppflags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG preprocessor accepts $1], CACHEVAR, [
+ ax_check_save_flags=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $4 $1"
+ AC_PREPROC_IFELSE([AC_LANG_PROGRAM()],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ CPPFLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_PREPROC_FLAGS
diff --git a/src/m4/ax_pthread.m4 b/src/m4/ax_pthread.m4
new file mode 100644
index 0000000000..6d400ed4e8
--- /dev/null
+++ b/src/m4/ax_pthread.m4
@@ -0,0 +1,317 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+# This macro figures out how to build C programs using POSIX threads. It
+# sets the PTHREAD_LIBS output variable to the threads library and linker
+# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+# flags that are needed. (The user can also force certain compiler
+# flags/libs to be tested by setting these environment variables.)
+#
+# Also sets PTHREAD_CC to any special C compiler that is needed for
+# multi-threaded programs (defaults to the value of CC otherwise). (This
+# is necessary on AIX to use the special cc_r compiler alias.)
+#
+# NOTE: You are assumed to not only compile your program with these flags,
+# but also link it with them as well. e.g. you should link with
+# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+# If you are only building threads programs, you may wish to use these
+# variables in your default LIBS, CFLAGS, and CC:
+#
+# LIBS="$PTHREAD_LIBS $LIBS"
+# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+# CC="$PTHREAD_CC"
+#
+# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+# PTHREAD_CFLAGS.
+#
+# ACTION-IF-FOUND is a list of shell commands to run if a threads library
+# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+# is not found. If ACTION-IF-FOUND is not specified, the default action
+# will define HAVE_PTHREAD.
+#
+# Please let the authors know if this macro fails on any platform, or if
+# you have any other suggestions or comments. This macro was based on work
+# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+# Alejandro Forero Cuervo to the autoconf macro repository. We are also
+# grateful for the helpful feedback of numerous users.
+#
+# Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 20
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+ AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
+ AC_MSG_RESULT($ax_pthread_ok)
+ if test x"$ax_pthread_ok" = xno; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads too;
+# also defines -D_REENTRANT)
+# ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case ${host_os} in
+ solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (We need to link with -pthreads/-mt/
+ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
+ # a function called by this macro, so we could check for that, but
+ # who knows whether they'll stub that too in a future libc.) So,
+ # we'll just look for -pthreads and -lpthread first:
+
+ ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+ ;;
+
+ darwin*)
+ ax_pthread_flags="-pthread $ax_pthread_flags"
+ ;;
+esac
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+ case $flag in
+ none)
+ AC_MSG_CHECKING([whether pthreads work without any flags])
+ ;;
+
+ -*)
+ AC_MSG_CHECKING([whether pthreads work with $flag])
+ PTHREAD_CFLAGS="$flag"
+ ;;
+
+ pthread-config)
+ AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
+ if test x"$ax_pthread_config" = xno; then continue; fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ AC_MSG_CHECKING([for the pthreads library -l$flag])
+ PTHREAD_LIBS="-l$flag"
+ ;;
+ esac
+
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+ static void routine(void *a) { a = 0; }
+ static void *start_routine(void *a) { return a; }],
+ [pthread_t th; pthread_attr_t attr;
+ pthread_create(&th, 0, start_routine, 0);
+ pthread_join(th, 0);
+ pthread_attr_init(&attr);
+ pthread_cleanup_push(routine, 0);
+ pthread_cleanup_pop(0) /* ; */])],
+ [ax_pthread_ok=yes],
+ [])
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ AC_MSG_RESULT($ax_pthread_ok)
+ if test "x$ax_pthread_ok" = xyes; then
+ break;
+ fi
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ AC_MSG_CHECKING([for joinable pthread attribute])
+ attr_name=unknown
+ for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+ [int attr = $attr; return attr /* ; */])],
+ [attr_name=$attr; break],
+ [])
+ done
+ AC_MSG_RESULT($attr_name)
+ if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+ AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+ [Define to necessary symbol if this constant
+ uses a non-standard name on your system.])
+ fi
+
+ AC_MSG_CHECKING([if more special flags are required for pthreads])
+ flag=no
+ case ${host_os} in
+ aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
+ osf* | hpux*) flag="-D_REENTRANT";;
+ solaris*)
+ if test "$GCC" = "yes"; then
+ flag="-D_REENTRANT"
+ else
+ flag="-mt -D_REENTRANT"
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT(${flag})
+ if test "x$flag" != xno; then
+ PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+ fi
+
+ AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+ ax_cv_PTHREAD_PRIO_INHERIT, [
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
+ [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+ [ax_cv_PTHREAD_PRIO_INHERIT=no])
+ ])
+ AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
+ AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ # More AIX lossage: compile with *_r variant
+ if test "x$GCC" != xyes; then
+ case $host_os in
+ aix*)
+ AS_CASE(["x/$CC"],
+ [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+ [#handle absolute path differently from PATH based program lookup
+ AS_CASE(["x$CC"],
+ [x/*],
+ [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
+ [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
+ ;;
+ esac
+ fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+ ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+ :
+else
+ ax_pthread_ok=no
+ $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
diff --git a/src/m4/bitcoin_find_bdb48.m4 b/src/m4/bitcoin_find_bdb48.m4
new file mode 100644
index 0000000000..72ec49b635
--- /dev/null
+++ b/src/m4/bitcoin_find_bdb48.m4
@@ -0,0 +1,66 @@
+AC_DEFUN([BITCOIN_FIND_BDB48],[
+ AC_MSG_CHECKING([for Berkeley DB C++ headers])
+ BDB_CPPFLAGS=
+ BDB_LIBS=
+ bdbpath=X
+ bdb48path=X
+ bdbdirlist=
+ for _vn in 4.8 48 4 5 ''; do
+ for _pfx in b lib ''; do
+ bdbdirlist="$bdbdirlist ${_pfx}db${_vn}"
+ done
+ done
+ for searchpath in $bdbdirlist ''; do
+ test -n "${searchpath}" && searchpath="${searchpath}/"
+ AC_TRY_COMPILE([
+ #include <${searchpath}db_cxx.h>
+ ],[
+ #if !((DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 8) || DB_VERSION_MAJOR > 4)
+ #error "failed to find bdb 4.8+"
+ #endif
+ ],[
+ if test "x$bdbpath" = "xX"; then
+ bdbpath="${searchpath}"
+ fi
+ ],[
+ continue
+ ])
+ AC_TRY_COMPILE([
+ #include <${searchpath}db_cxx.h>
+ ],[
+ #if !(DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 8)
+ #error "failed to find bdb 4.8"
+ #endif
+ ],[
+ bdb48path="${searchpath}"
+ break
+ ])
+ done
+ if test "x$bdbpath" = "xX"; then
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR(libdb_cxx headers missing)
+ elif test "x$bdb48path" = "xX"; then
+ BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdbpath}],db_cxx)
+ AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 4.8])],[
+ AC_MSG_WARN([Found Berkeley DB other than 4.8; wallets opened by this build will not be portable!])
+ ],[
+ AC_MSG_ERROR([Found Berkeley DB other than 4.8, required for portable wallets (--with-incompatible-bdb to ignore)])
+ ])
+ else
+ BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdb48path}],db_cxx)
+ bdbpath="${bdb48path}"
+ fi
+ AC_SUBST(BDB_CPPFLAGS)
+
+ # TODO: Ideally this could find the library version and make sure it matches the headers being used
+ for searchlib in db_cxx-4.8 db_cxx; do
+ AC_CHECK_LIB([$searchlib],[main],[
+ BDB_LIBS="-l${searchlib}"
+ break
+ ])
+ done
+ if test "x$BDB_LIBS" = "x"; then
+ AC_MSG_ERROR(libdb_cxx missing)
+ fi
+ AC_SUBST(BDB_LIBS)
+])
diff --git a/src/m4/bitcoin_subdir_to_include.m4 b/src/m4/bitcoin_subdir_to_include.m4
new file mode 100644
index 0000000000..66f106c7d4
--- /dev/null
+++ b/src/m4/bitcoin_subdir_to_include.m4
@@ -0,0 +1,14 @@
+dnl BITCOIN_SUBDIR_TO_INCLUDE([CPPFLAGS-VARIABLE-NAME],[SUBDIRECTORY-NAME],[HEADER-FILE])
+dnl SUBDIRECTORY-NAME must end with a path separator
+AC_DEFUN([BITCOIN_SUBDIR_TO_INCLUDE],[
+ if test "x$2" = "x"; then
+ AC_MSG_RESULT([default])
+ else
+ echo "#include <$2$3.h>" >conftest.cpp
+ newinclpath=`${CXXCPP} ${CPPFLAGS} -M conftest.cpp 2>/dev/null | [ tr -d '\\n\\r\\\\' | sed -e 's/^.*[[:space:]:]\(\/[^[:space:]]*\)]$3[\.h[[:space:]].*$/\1/' -e t -e d`]
+ AC_MSG_RESULT([${newinclpath}])
+ if test "x${newinclpath}" != "x"; then
+ eval "$1=\"\$$1\"' -I${newinclpath}'"
+ fi
+ fi
+])
diff --git a/src/main.cpp b/src/main.cpp
index 557a01b8cf..8df288380a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -67,9 +67,6 @@ CScript COINBASE_FLAGS;
const string strMessageMagic = "Bitcoin Signed Message:\n";
-double dHashesPerSec = 0.0;
-int64 nHPSTimerStart = 0;
-
// Settings
int64 nTransactionFee = 0;
@@ -415,7 +412,7 @@ bool AddOrphanTx(const CTransaction& tx)
unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
if (sz > 5000)
{
- printf("ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString().c_str());
+ LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString().c_str());
return false;
}
@@ -423,7 +420,7 @@ bool AddOrphanTx(const CTransaction& tx)
BOOST_FOREACH(const CTxIn& txin, tx.vin)
mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
- printf("stored orphan tx %s (mapsz %"PRIszu")\n", hash.ToString().c_str(),
+ LogPrint("mempool", "stored orphan tx %s (mapsz %"PRIszu")\n", hash.ToString().c_str(),
mapOrphanTransactions.size());
return true;
}
@@ -466,7 +463,7 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
bool IsStandardTx(const CTransaction& tx, string& reason)
{
- if (tx.nVersion > CTransaction::CURRENT_VERSION) {
+ if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
reason = "version";
return false;
}
@@ -668,7 +665,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
{
vMerkleBranch.clear();
nIndex = -1;
- printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
+ LogPrintf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
return 0;
}
@@ -787,7 +784,7 @@ void CTxMemPool::pruneSpent(const uint256 &hashTx, CCoins &coins)
}
bool CTxMemPool::accept(CValidationState &state, const CTransaction &tx, bool fLimitFree,
- bool* pfMissingInputs)
+ bool* pfMissingInputs, bool fRejectInsaneFee)
{
if (pfMissingInputs)
*pfMissingInputs = false;
@@ -917,10 +914,15 @@ bool CTxMemPool::accept(CValidationState &state, const CTransaction &tx, bool fL
if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
return error("CTxMemPool::accept() : free transaction rejected by rate limiter");
if (fDebug)
- printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
+ LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
dFreeCount += nSize;
}
+ if (fRejectInsaneFee && nFees > CTransaction::nMinRelayTxFee * 10000)
+ return error("CTxMemPool::accept() : insane fees %s, %"PRI64d" > %"PRI64d,
+ hash.ToString().c_str(),
+ nFees, CTransaction::nMinRelayTxFee * 10000);
+
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
if (!CheckInputs(tx, state, view, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC))
@@ -934,7 +936,7 @@ bool CTxMemPool::accept(CValidationState &state, const CTransaction &tx, bool fL
LOCK(cs);
if (ptxOld)
{
- printf("CTxMemPool::accept() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
+ LogPrint("mempool", "CTxMemPool::accept() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
remove(*ptxOld);
}
addUnchecked(hash, tx);
@@ -946,7 +948,7 @@ bool CTxMemPool::accept(CValidationState &state, const CTransaction &tx, bool fL
EraseFromWallets(ptxOld->GetHash());
SyncWithWallets(hash, tx, NULL, true);
- printf("CTxMemPool::accept() : accepted %s (poolsz %"PRIszu")\n",
+ LogPrint("mempool", "CTxMemPool::accept() : accepted %s (poolsz %"PRIszu")\n",
hash.ToString().c_str(),
mapTx.size());
return true;
@@ -1021,7 +1023,7 @@ void CTxMemPool::check(CCoinsViewCache *pcoins) const
if (!fChecks)
return;
- printf("Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
+ LogPrintf("Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
LOCK(cs);
for (std::map<uint256, CTransaction>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
@@ -1354,7 +1356,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
// Limit adjustment step
int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
- printf(" nActualTimespan = %"PRI64d" before bounds\n", nActualTimespan);
+ LogPrintf(" nActualTimespan = %"PRI64d" before bounds\n", nActualTimespan);
if (nActualTimespan < nTargetTimespan/4)
nActualTimespan = nTargetTimespan/4;
if (nActualTimespan > nTargetTimespan*4)
@@ -1370,10 +1372,10 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
bnNew = Params().ProofOfWorkLimit();
/// debug print
- printf("GetNextWorkRequired RETARGET\n");
- printf("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan);
- printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
- printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
+ LogPrintf("GetNextWorkRequired RETARGET\n");
+ LogPrintf("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan);
+ LogPrintf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
+ LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
return bnNew.GetCompact();
}
@@ -1421,6 +1423,11 @@ CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;
void CheckForkWarningConditions()
{
+ // Before we get past initial download, we cannot reliably alert about forks
+ // (we assume we don't get stuck on a fork before the last checkpoint)
+ if (IsInitialBlockDownload())
+ return;
+
// If our best fork is no longer within 72 blocks (+/- 12 hours if no one mines it)
// of our head, drop it
if (pindexBestForkTip && nBestHeight - pindexBestForkTip->nHeight >= 72)
@@ -1441,14 +1448,14 @@ void CheckForkWarningConditions()
}
if (pindexBestForkTip)
{
- printf("CheckForkWarningConditions: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n",
+ LogPrintf("CheckForkWarningConditions: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n",
pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString().c_str(),
pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString().c_str());
fLargeWorkForkFound = true;
}
else
{
- printf("CheckForkWarningConditions: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n");
+ LogPrintf("CheckForkWarningConditions: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n");
fLargeWorkInvalidChainFound = true;
}
}
@@ -1499,11 +1506,11 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
pblocktree->WriteBestInvalidWork(CBigNum(nBestInvalidWork));
uiInterface.NotifyBlocksChanged();
}
- printf("InvalidChainFound: invalid block=%s height=%d log2_work=%.8g date=%s\n",
+ LogPrintf("InvalidChainFound: invalid block=%s height=%d log2_work=%.8g date=%s\n",
pindexNew->GetBlockHash().ToString().c_str(), pindexNew->nHeight,
log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
pindexNew->GetBlockTime()).c_str());
- printf("InvalidChainFound: current best=%s height=%d log2_work=%.8g date=%s\n",
+ LogPrintf("InvalidChainFound: current best=%s height=%d log2_work=%.8g date=%s\n",
hashBestChain.ToString().c_str(), nBestHeight, log(nBestChainWork.getdouble())/log(2.0),
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str());
CheckForkWarningConditions();
@@ -1771,8 +1778,14 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
view.SetCoins(hash, CCoins());
}
CCoins &outs = view.GetCoins(hash);
+ outs.ClearUnspendable();
CCoins outsBlock = CCoins(tx, pindex->nHeight);
+ // The CCoins serialization does not serialize negative numbers.
+ // No network rules currently depend on the version here, so an inconsistency is harmless
+ // but it must be corrected before txout nversion ever influences a network rule.
+ if (outsBlock.nVersion < 0)
+ outs.nVersion = outsBlock.nVersion;
if (outs != outsBlock)
fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted");
@@ -1957,7 +1970,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
}
int64 nTime = GetTimeMicros() - nStart;
if (fBenchmark)
- printf("- Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin)\n", (unsigned)block.vtx.size(), 0.001 * nTime, 0.001 * nTime / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * nTime / (nInputs-1));
+ LogPrintf("- Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin)\n", (unsigned)block.vtx.size(), 0.001 * nTime, 0.001 * nTime / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * nTime / (nInputs-1));
if (GetValueOut(block.vtx[0]) > GetBlockValue(pindex->nHeight, nFees))
return state.DoS(100, error("ConnectBlock() : coinbase pays too much (actual=%"PRI64d" vs limit=%"PRI64d")", GetValueOut(block.vtx[0]), GetBlockValue(pindex->nHeight, nFees)));
@@ -1966,7 +1979,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
return state.DoS(100, false);
int64 nTime2 = GetTimeMicros() - nStart;
if (fBenchmark)
- printf("- Verify %u txins: %.2fms (%.3fms/txin)\n", nInputs - 1, 0.001 * nTime2, nInputs <= 1 ? 0 : 0.001 * nTime2 / (nInputs-1));
+ LogPrintf("- Verify %u txins: %.2fms (%.3fms/txin)\n", nInputs - 1, 0.001 * nTime2, nInputs <= 1 ? 0 : 0.001 * nTime2 / (nInputs-1));
if (fJustCheck)
return true;
@@ -2042,8 +2055,8 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
reverse(vConnect.begin(), vConnect.end());
if (vDisconnect.size() > 0) {
- printf("REORGANIZE: Disconnect %"PRIszu" blocks; %s..\n", vDisconnect.size(), pfork->GetBlockHash().ToString().c_str());
- printf("REORGANIZE: Connect %"PRIszu" blocks; ..%s\n", vConnect.size(), pindexNew->GetBlockHash().ToString().c_str());
+ LogPrintf("REORGANIZE: Disconnect %"PRIszu" blocks; %s...\n", vDisconnect.size(), pfork->GetBlockHash().ToString().c_str());
+ LogPrintf("REORGANIZE: Connect %"PRIszu" blocks; ...%s\n", vConnect.size(), pindexNew->GetBlockHash().ToString().c_str());
}
// Disconnect shorter branch
@@ -2056,7 +2069,7 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
if (!DisconnectBlock(block, state, pindex, view))
return error("SetBestBlock() : DisconnectBlock %s failed", pindex->GetBlockHash().ToString().c_str());
if (fBenchmark)
- printf("- Disconnect: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
+ LogPrintf("- Disconnect: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
// Queue memory transactions to resurrect.
// We only do this for blocks after the last checkpoint (reorganisation before that
@@ -2081,7 +2094,7 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
return error("SetBestBlock() : ConnectBlock %s failed", pindex->GetBlockHash().ToString().c_str());
}
if (fBenchmark)
- printf("- Connect: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
+ LogPrintf("- Connect: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
// Queue memory transactions to delete
BOOST_FOREACH(const CTransaction& tx, block.vtx)
@@ -2094,7 +2107,7 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
assert(view.Flush());
int64 nTime = GetTimeMicros() - nStart;
if (fBenchmark)
- printf("- Flush %i transactions: %.2fms (%.4fms/tx)\n", nModified, 0.001 * nTime, 0.001 * nTime / nModified);
+ LogPrintf("- Flush %i transactions: %.2fms (%.4fms/tx)\n", nModified, 0.001 * nTime, 0.001 * nTime / nModified);
// Make sure it's successfully written to disk before changing memory structure
bool fIsInitialDownload = IsInitialBlockDownload();
@@ -2151,7 +2164,7 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
nBestChainWork = pindexNew->nChainWork;
nTimeBestReceived = GetTime();
nTransactionsUpdated++;
- printf("SetBestChain: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f\n",
+ LogPrintf("SetBestChain: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f\n",
hashBestChain.ToString().c_str(), nBestHeight, log(nBestChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx,
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str(),
Checkpoints::GuessVerificationProgress(pindexBest));
@@ -2168,7 +2181,7 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
pindex = pindex->pprev;
}
if (nUpgraded > 0)
- printf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, CBlock::CURRENT_VERSION);
+ LogPrintf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, CBlock::CURRENT_VERSION);
if (nUpgraded > 100/2)
// strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user:
strMiscWarning = _("Warning: This version is obsolete, upgrade required!");
@@ -2254,7 +2267,7 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd
}
} else {
while (infoLastBlockFile.nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
- printf("Leaving block file %i: %s\n", nLastBlockFile, infoLastBlockFile.ToString().c_str());
+ LogPrintf("Leaving block file %i: %s\n", nLastBlockFile, infoLastBlockFile.ToString().c_str());
FlushBlockFile(true);
nLastBlockFile++;
infoLastBlockFile.SetNull();
@@ -2275,7 +2288,7 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd
if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
FILE *file = OpenBlockFile(pos);
if (file) {
- printf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
+ LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
fclose(file);
}
@@ -2321,7 +2334,7 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne
if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
FILE *file = OpenUndoFile(pos);
if (file) {
- printf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
+ LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
fclose(file);
}
@@ -2539,7 +2552,7 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
// If we don't already have its previous block, shunt it off to holding area until we get it
if (pblock->hashPrevBlock != 0 && !mapBlockIndex.count(pblock->hashPrevBlock))
{
- printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().c_str());
+ LogPrintf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().c_str());
// Accept orphans as long as there is a node to request its parents from
if (pfrom) {
@@ -2578,7 +2591,7 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
mapOrphanBlocksByPrev.erase(hashPrev);
}
- printf("ProcessBlock: ACCEPTED\n");
+ LogPrintf("ProcessBlock: ACCEPTED\n");
return true;
}
@@ -2744,7 +2757,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
bool AbortNode(const std::string &strMessage) {
strMiscWarning = strMessage;
- printf("*** %s\n", strMessage.c_str());
+ LogPrintf("*** %s\n", strMessage.c_str());
uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_ERROR);
StartShutdown();
return false;
@@ -2775,12 +2788,12 @@ FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
if (!file && !fReadOnly)
file = fopen(path.string().c_str(), "wb+");
if (!file) {
- printf("Unable to open file %s\n", path.string().c_str());
+ LogPrintf("Unable to open file %s\n", path.string().c_str());
return NULL;
}
if (pos.nPos) {
if (fseek(file, pos.nPos, SEEK_SET)) {
- printf("Unable to seek to position %u of %s\n", pos.nPos, path.string().c_str());
+ LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string().c_str());
fclose(file);
return NULL;
}
@@ -2843,9 +2856,9 @@ bool static LoadBlockIndexDB()
// Load block file info
pblocktree->ReadLastBlockFile(nLastBlockFile);
- printf("LoadBlockIndexDB(): last block file = %i\n", nLastBlockFile);
+ LogPrintf("LoadBlockIndexDB(): last block file = %i\n", nLastBlockFile);
if (pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile))
- printf("LoadBlockIndexDB(): last block file info: %s\n", infoLastBlockFile.ToString().c_str());
+ LogPrintf("LoadBlockIndexDB(): last block file info: %s\n", infoLastBlockFile.ToString().c_str());
// Load nBestInvalidWork, OK if it doesn't exist
CBigNum bnBestInvalidWork;
@@ -2859,7 +2872,7 @@ bool static LoadBlockIndexDB()
// Check whether we have a transaction index
pblocktree->ReadFlag("txindex", fTxIndex);
- printf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled");
+ LogPrintf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled");
// Load hashBestChain pointer to end of best chain
pindexBest = pcoinsTip->GetBestBlock();
@@ -2876,7 +2889,7 @@ bool static LoadBlockIndexDB()
vBlockIndexByHeight[pindex->nHeight] = pindex;
pindex = pindex->pprev;
}
- printf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s\n",
+ LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s\n",
hashBestChain.ToString().c_str(), nBestHeight,
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str());
@@ -2894,7 +2907,7 @@ bool VerifyDB(int nCheckLevel, int nCheckDepth)
if (nCheckDepth > nBestHeight)
nCheckDepth = nBestHeight;
nCheckLevel = std::max(0, std::min(4, nCheckLevel));
- printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
+ LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
CCoinsViewCache coins(*pcoinsTip, true);
CBlockIndex* pindexState = pindexBest;
CBlockIndex* pindexFailure = NULL;
@@ -2951,7 +2964,7 @@ bool VerifyDB(int nCheckLevel, int nCheckDepth)
}
}
- printf("No coin database inconsistencies in last %i blocks (%i transactions)\n", pindexBest->nHeight - pindexState->nHeight, nGoodTransactions);
+ LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", pindexBest->nHeight - pindexState->nHeight, nGoodTransactions);
return true;
}
@@ -2985,7 +2998,7 @@ bool InitBlockIndex() {
// Use the provided setting for -txindex in the new database
fTxIndex = GetBoolArg("-txindex", false);
pblocktree->WriteFlag("txindex", fTxIndex);
- printf("Initializing databases...\n");
+ LogPrintf("Initializing databases...\n");
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
if (!fReindex) {
@@ -3038,25 +3051,25 @@ void PrintBlockTree()
if (nCol > nPrevCol)
{
for (int i = 0; i < nCol-1; i++)
- printf("| ");
- printf("|\\\n");
+ LogPrintf("| ");
+ LogPrintf("|\\\n");
}
else if (nCol < nPrevCol)
{
for (int i = 0; i < nCol; i++)
- printf("| ");
- printf("|\n");
+ LogPrintf("| ");
+ LogPrintf("|\n");
}
nPrevCol = nCol;
// print columns
for (int i = 0; i < nCol; i++)
- printf("| ");
+ LogPrintf("| ");
// print item
CBlock block;
ReadBlockFromDisk(block, pindex);
- printf("%d (blk%05u.dat:0x%x) %s tx %"PRIszu"",
+ LogPrintf("%d (blk%05u.dat:0x%x) %s tx %"PRIszu"",
pindex->nHeight,
pindex->GetBlockPos().nFile, pindex->GetBlockPos().nPos,
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", block.GetBlockTime()).c_str(),
@@ -3141,7 +3154,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
break;
}
} catch (std::exception &e) {
- printf("%s() : Deserialize or I/O error caught during load\n", __PRETTY_FUNCTION__);
+ LogPrintf("%s() : Deserialize or I/O error caught during load\n", __PRETTY_FUNCTION__);
}
}
fclose(fileIn);
@@ -3149,7 +3162,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
AbortNode(_("Error: system error: ") + e.what());
}
if (nLoaded > 0)
- printf("Loaded %i blocks from external file in %"PRI64d"ms\n", nLoaded, GetTimeMillis() - nStart);
+ LogPrintf("Loaded %i blocks from external file in %"PRI64d"ms\n", nLoaded, GetTimeMillis() - nStart);
return nLoaded > 0;
}
@@ -3371,11 +3384,10 @@ void static ProcessGetData(CNode* pfrom)
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{
RandAddSeedPerfmon();
- if (fDebug)
- printf("received: %s (%"PRIszu" bytes)\n", strCommand.c_str(), vRecv.size());
+ LogPrint("net", "received: %s (%"PRIszu" bytes)\n", strCommand.c_str(), vRecv.size());
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
{
- printf("dropmessagestest DROPPING RECV MESSAGE\n");
+ LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
return true;
}
@@ -3401,7 +3413,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{
// Since February 20, 2012, the protocol is initiated at version 209,
// and earlier versions are no longer supported
- printf("partner %s using obsolete version %i; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion);
+ LogPrintf("partner %s using obsolete version %i; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion);
pfrom->fDisconnect = true;
return false;
}
@@ -3428,7 +3440,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// Disconnect if we connected to ourself
if (nNonce == nLocalHostNonce && nNonce > 1)
{
- printf("connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str());
+ LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str());
pfrom->fDisconnect = true;
return true;
}
@@ -3479,7 +3491,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
pfrom->fSuccessfullyConnected = true;
- printf("receive version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString().c_str(), addrFrom.ToString().c_str(), pfrom->addr.ToString().c_str());
+ LogPrintf("receive version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString().c_str(), addrFrom.ToString().c_str(), pfrom->addr.ToString().c_str());
cPeerBlockCounts.input(pfrom->nStartingHeight);
}
@@ -3592,8 +3604,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
pfrom->AddInventoryKnown(inv);
bool fAlreadyHave = AlreadyHave(inv);
- if (fDebug)
- printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
+ LogPrint("net", " got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
if (!fAlreadyHave) {
if (!fImporting && !fReindex)
@@ -3606,7 +3617,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// this situation and push another getblocks to continue.
PushGetBlocks(pfrom, mapBlockIndex[inv.hash], uint256(0));
if (fDebug)
- printf("force request: %s\n", inv.ToString().c_str());
+ LogPrintf("force request: %s\n", inv.ToString().c_str());
}
// Track requests for our stuff
@@ -3626,10 +3637,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
if (fDebugNet || (vInv.size() != 1))
- printf("received getdata (%"PRIszu" invsz)\n", vInv.size());
+ LogPrint("net", "received getdata (%"PRIszu" invsz)\n", vInv.size());
if ((fDebugNet && vInv.size() > 0) || (vInv.size() == 1))
- printf("received getdata for: %s\n", vInv[0].ToString().c_str());
+ LogPrint("net", "received getdata for: %s\n", vInv[0].ToString().c_str());
pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
ProcessGetData(pfrom);
@@ -3649,12 +3660,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (pindex)
pindex = pindex->GetNextInMainChain();
int nLimit = 500;
- printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().c_str(), nLimit);
+ LogPrint("net", "getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().c_str(), nLimit);
for (; pindex; pindex = pindex->GetNextInMainChain())
{
if (pindex->GetBlockHash() == hashStop)
{
- printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
+ LogPrint("net", " getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
break;
}
pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
@@ -3662,7 +3673,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{
// When this block is requested, we'll send an inv that'll make them
// getblocks the next batch of inventory.
- printf(" getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
+ LogPrint("net", " getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
pfrom->hashContinue = pindex->GetBlockHash();
break;
}
@@ -3696,7 +3707,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
vector<CBlock> vHeaders;
int nLimit = 2000;
- printf("getheaders %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().c_str());
+ LogPrint("net", "getheaders %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().c_str());
for (; pindex; pindex = pindex->GetNextInMainChain())
{
vHeaders.push_back(pindex->GetBlockHeader());
@@ -3746,7 +3757,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (mempool.accept(stateDummy, orphanTx, true, &fMissingInputs2))
{
- printf(" accepted orphan tx %s\n", orphanHash.ToString().c_str());
+ LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString().c_str());
RelayTransaction(orphanTx, orphanHash);
mapAlreadyAskedFor.erase(CInv(MSG_TX, orphanHash));
vWorkQueue.push_back(orphanHash);
@@ -3756,7 +3767,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{
// invalid or too-little-fee orphan
vEraseQueue.push_back(orphanHash);
- printf(" removed orphan tx %s\n", orphanHash.ToString().c_str());
+ LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString().c_str());
}
mempool.check(pcoinsTip);
}
@@ -3772,7 +3783,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded
unsigned int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS);
if (nEvicted > 0)
- printf("mapOrphan overflow, removed %u tx\n", nEvicted);
+ LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
}
int nDoS;
if (state.IsInvalid(nDoS))
@@ -3785,7 +3796,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
CBlock block;
vRecv >> block;
- printf("received block %s\n", block.GetHash().ToString().c_str());
+ LogPrint("net", "received block %s\n", block.GetHash().ToString().c_str());
// block.print();
CInv inv(MSG_BLOCK, block.GetHash());
@@ -3948,7 +3959,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
bool ProcessMessages(CNode* pfrom)
{
//if (fDebug)
- // printf("ProcessMessages(%zu messages)\n", pfrom->vRecvMsg.size());
+ // LogPrintf("ProcessMessages(%zu messages)\n", pfrom->vRecvMsg.size());
//
// Message format
@@ -3973,7 +3984,7 @@ bool ProcessMessages(CNode* pfrom)
CNetMessage& msg = *it;
//if (fDebug)
- // printf("ProcessMessages(message %u msgsz, %zu bytes, complete:%s)\n",
+ // LogPrintf("ProcessMessages(message %u msgsz, %zu bytes, complete:%s)\n",
// msg.hdr.nMessageSize, msg.vRecv.size(),
// msg.complete() ? "Y" : "N");
@@ -3986,7 +3997,7 @@ bool ProcessMessages(CNode* pfrom)
// Scan for message start
if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
- printf("\n\nPROCESSMESSAGE: INVALID MESSAGESTART\n\n");
+ LogPrintf("\n\nPROCESSMESSAGE: INVALID MESSAGESTART\n\n");
fOk = false;
break;
}
@@ -3995,7 +4006,7 @@ bool ProcessMessages(CNode* pfrom)
CMessageHeader& hdr = msg.hdr;
if (!hdr.IsValid())
{
- printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());
+ LogPrintf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());
continue;
}
string strCommand = hdr.GetCommand();
@@ -4010,7 +4021,7 @@ bool ProcessMessages(CNode* pfrom)
memcpy(&nChecksum, &hash, sizeof(nChecksum));
if (nChecksum != hdr.nChecksum)
{
- printf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
+ LogPrintf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum);
continue;
}
@@ -4030,12 +4041,12 @@ bool ProcessMessages(CNode* pfrom)
if (strstr(e.what(), "end of data"))
{
// Allow exceptions from under-length message on vRecv
- printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what());
+ LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what());
}
else if (strstr(e.what(), "size too large"))
{
// Allow exceptions from over-long size
- printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
+ LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
}
else
{
@@ -4052,7 +4063,7 @@ bool ProcessMessages(CNode* pfrom)
}
if (!fRet)
- printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize);
+ LogPrintf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize);
}
// In case the connection got shut down, its receive buffer was wiped
@@ -4215,7 +4226,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
if (!AlreadyHave(inv))
{
if (fDebugNet)
- printf("sending getdata: %s\n", inv.ToString().c_str());
+ LogPrint("net", "sending getdata: %s\n", inv.ToString().c_str());
vGetData.push_back(inv);
if (vGetData.size() >= 1000)
{
diff --git a/src/main.h b/src/main.h
index a690a2bc9c..83b0d07f63 100644
--- a/src/main.h
+++ b/src/main.h
@@ -5,6 +5,10 @@
#ifndef BITCOIN_MAIN_H
#define BITCOIN_MAIN_H
+#if defined(HAVE_CONFIG_H)
+#include "bitcoin-config.h"
+#endif
+
#include "core.h"
#include "bignum.h"
#include "sync.h"
@@ -82,8 +86,6 @@ extern unsigned int nTransactionsUpdated;
extern uint64 nLastBlockTx;
extern uint64 nLastBlockSize;
extern const std::string strMessageMagic;
-extern double dHashesPerSec;
-extern int64 nHPSTimerStart;
extern int64 nTimeBestReceived;
extern CCriticalSection cs_setpwalletRegistered;
extern std::set<CWallet*> setpwalletRegistered;
@@ -651,7 +653,7 @@ public:
if (nBlocks==0 || nTimeFirst > nTimeIn)
nTimeFirst = nTimeIn;
nBlocks++;
- if (nHeightIn > nHeightFirst)
+ if (nHeightIn > nHeightLast)
nHeightLast = nHeightIn;
if (nTimeIn > nTimeLast)
nTimeLast = nTimeIn;
@@ -876,7 +878,7 @@ public:
void print() const
{
- printf("%s\n", ToString().c_str());
+ LogPrintf("%s\n", ToString().c_str());
}
};
@@ -958,7 +960,7 @@ public:
void print() const
{
- printf("%s\n", ToString().c_str());
+ LogPrintf("%s\n", ToString().c_str());
}
};
@@ -1082,7 +1084,7 @@ public:
std::map<uint256, CTransaction> mapTx;
std::map<COutPoint, CInPoint> mapNextTx;
- bool accept(CValidationState &state, const CTransaction &tx, bool fLimitFree, bool* pfMissingInputs);
+ bool accept(CValidationState &state, const CTransaction &tx, bool fLimitFree, bool* pfMissingInputs, bool fRejectInsaneFee = false);
bool addUnchecked(const uint256& hash, const CTransaction &tx);
bool remove(const CTransaction &tx, bool fRecursive = false);
bool removeConflicts(const CTransaction &tx);
@@ -1210,7 +1212,7 @@ public:
@see CTransaction::FetchInputs
*/
int64 GetValueIn(const CTransaction& tx);
-
+
// Check whether all prevouts of the transaction are present in the UTXO set represented by this view
bool HaveInputs(const CTransaction& tx);
diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw
deleted file mode 100644
index 51830f2342..0000000000
--- a/src/makefile.linux-mingw
+++ /dev/null
@@ -1,135 +0,0 @@
-# Copyright (c) 2009-2010 Satoshi Nakamoto
-# Distributed under the MIT/X11 software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-DEPSDIR:=/usr/i586-mingw32msvc
-
-CC := i586-mingw32msvc-gcc
-CXX := i586-mingw32msvc-g++
-
-USE_UPNP:=0
-USE_IPV6:=1
-
-INCLUDEPATHS= \
- -I"$(CURDIR)" \
- -I"$(CURDIR)"/obj \
- -I"$(DEPSDIR)/boost_1_50_0" \
- -I"$(DEPSDIR)/db-4.8.30.NC/build_unix" \
- -I"$(DEPSDIR)/openssl-1.0.1c/include" \
- -I"$(DEPSDIR)"
-
-LIBPATHS= \
- -L"$(DEPSDIR)/boost_1_50_0/stage/lib" \
- -L"$(DEPSDIR)/db-4.8.30.NC/build_unix" \
- -L"$(DEPSDIR)/openssl-1.0.1c"
-
-LIBS= \
- $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a \
- -l boost_system-mt-s \
- -l boost_filesystem-mt-s \
- -l boost_program_options-mt-s \
- -l boost_thread_win32-mt-s \
- -l boost_chrono-mt-s \
- -l db_cxx \
- -l ssl \
- -l crypto
-
-DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE
-DEBUGFLAGS=-g
-xCXXFLAGS=-O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) $(CXXFLAGS)
-# enable: ASLR, DEP and large address aware
-xLDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat -Wl,--large-address-aware $(LDFLAGS)
-
-TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
-
-ifndef USE_UPNP
- override USE_UPNP = -
-endif
-ifneq (${USE_UPNP}, -)
- LIBPATHS += -L"$(DEPSDIR)/miniupnpc"
- LIBS += -l miniupnpc -l iphlpapi
- DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP)
-endif
-
-ifneq (${USE_IPV6}, -)
- DEFS += -DUSE_IPV6=$(USE_IPV6)
-endif
-
-LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l mswsock -l shlwapi
-
-# TODO: make the mingw builds smarter about dependencies, like the linux/osx builds are
-HEADERS = $(wildcard *.h)
-
-OBJS= \
- leveldb/libleveldb.a \
- obj/alert.o \
- obj/version.o \
- obj/checkpoints.o \
- obj/netbase.o \
- obj/addrman.o \
- obj/crypter.o \
- obj/key.o \
- obj/db.o \
- obj/init.o \
- obj/bitcoind.o \
- obj/keystore.o \
- obj/core.o \
- obj/main.o \
- obj/miner.o \
- obj/net.o \
- obj/protocol.o \
- obj/bitcoinrpc.o \
- obj/rpcdump.o \
- obj/rpcnet.o \
- obj/rpcmining.o \
- obj/rpcwallet.o \
- obj/rpcblockchain.o \
- obj/rpcrawtransaction.o \
- obj/script.o \
- obj/sync.o \
- obj/util.o \
- obj/wallet.o \
- obj/walletdb.o \
- obj/noui.o \
- obj/hash.o \
- obj/bloom.o \
- obj/leveldb.o \
- obj/txdb.o \
- obj/chainparams.o
-
-all: bitcoind.exe
-
-DEFS += -I"$(CURDIR)/leveldb/include"
-DEFS += -I"$(CURDIR)/leveldb/helpers"
-leveldb/libleveldb.a:
- @echo "Building LevelDB ..." && cd leveldb && TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) CC=$(CC) CXX=$(CXX) OPT="$(xCXXFLAGS)" libleveldb.a libmemenv.a && i586-mingw32msvc-ranlib libleveldb.a && i586-mingw32msvc-ranlib libmemenv.a && cd ..
-
-obj/build.h: FORCE
- /bin/sh ../share/genbuild.sh obj/build.h
-version.cpp: obj/build.h
-DEFS += -DHAVE_BUILD_INFO
-
-obj/%.o: %.cpp $(HEADERS)
- $(CXX) -c $(xCXXFLAGS) -o $@ $<
-
-bitcoind.exe: $(OBJS:obj/%=obj/%)
- $(CXX) $(xCXXFLAGS) $(xLDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
-
-TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
-
-obj-test/%.o: test/%.cpp $(HEADERS)
- $(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -o $@ $<
-
-test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o obj/bitcoind.o,$(OBJS:obj/%=obj/%))
- $(CXX) $(xCXXFLAGS) $(xLDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework-mt-s $(LIBS)
-
-
-clean:
- -rm -f obj/*.o
- -rm -f bitcoind.exe
- -rm -f obj-test/*.o
- -rm -f test_bitcoin.exe
- -rm -f obj/build.h
- cd leveldb && TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) clean && cd ..
-
-FORCE:
diff --git a/src/makefile.mingw b/src/makefile.mingw
deleted file mode 100644
index cb989d8ae8..0000000000
--- a/src/makefile.mingw
+++ /dev/null
@@ -1,143 +0,0 @@
-# Copyright (c) 2009-2010 Satoshi Nakamoto
-# Distributed under the MIT/X11 software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-# Makefile for the MinGW g++ compiler/toolchain
-#
-# Assumes Berkeley DB, Boost, and OpenSSL have all been compiled and installed
-# into /usr/local (/usr/local/include, /usr/local/lib).
-#
-# If dependencies are somewhere else, run 'make DEPSDIR=/path/'
-#
-# Boost libraries are given wacky names that include the particular version of
-# boost you're using; set BOOST_SUFFIX appropriately.
-#
-# 'make clean' assumes it is running inside a MSYS shell, and uses 'rm'
-# to remove files.
-
-CXX ?= g++
-
-USE_UPNP:=-
-USE_IPV6:=1
-
-DEPSDIR?=/usr/local
-BOOST_SUFFIX?=-mgw46-mt-s-1_52
-
-INCLUDEPATHS= \
- -I"$(CURDIR)" \
- -I"$(DEPSDIR)/include"
-
-LIBPATHS= \
- -L"$(CURDIR)/leveldb" \
- -L"$(DEPSDIR)/lib"
-
-LIBS= \
- -l leveldb \
- -l memenv \
- -l boost_system$(BOOST_SUFFIX) \
- -l boost_filesystem$(BOOST_SUFFIX) \
- -l boost_program_options$(BOOST_SUFFIX) \
- -l boost_thread$(BOOST_SUFFIX) \
- -l boost_chrono$(BOOST_SUFFIX) \
- -l db_cxx \
- -l ssl \
- -l crypto
-
-DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE
-DEBUGFLAGS=-g
-CFLAGS=-mthreads -O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
-# enable: ASLR, DEP and large address aware
-LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat -Wl,--large-address-aware
-
-TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
-
-ifndef USE_UPNP
- override USE_UPNP = -
-endif
-ifneq (${USE_UPNP}, -)
- LIBS += -l miniupnpc -l iphlpapi
- DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP)
-endif
-
-ifneq (${USE_IPV6}, -)
- DEFS += -DUSE_IPV6=$(USE_IPV6)
-endif
-
-LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l mswsock -l shlwapi
-
-# TODO: make the mingw builds smarter about dependencies, like the linux/osx builds are
-HEADERS = $(wildcard *.h)
-
-OBJS= \
- leveldb/libleveldb.a \
- obj/alert.o \
- obj/version.o \
- obj/checkpoints.o \
- obj/netbase.o \
- obj/addrman.o \
- obj/crypter.o \
- obj/key.o \
- obj/db.o \
- obj/init.o \
- obj/bitcoind.o \
- obj/keystore.o \
- obj/core.o \
- obj/main.o \
- obj/miner.o \
- obj/net.o \
- obj/protocol.o \
- obj/bitcoinrpc.o \
- obj/rpcdump.o \
- obj/rpcnet.o \
- obj/rpcmining.o \
- obj/rpcwallet.o \
- obj/rpcblockchain.o \
- obj/rpcrawtransaction.o \
- obj/script.o \
- obj/sync.o \
- obj/util.o \
- obj/wallet.o \
- obj/walletdb.o \
- obj/hash.o \
- obj/bloom.o \
- obj/noui.o \
- obj/leveldb.o \
- obj/txdb.o \
- obj/chainparams.o
-
-
-all: bitcoind.exe
-
-test check: test_bitcoin.exe FORCE
- test_bitcoin.exe
-
-#
-# LevelDB support
-#
-DEFS += $(addprefix -I,$(CURDIR)/leveldb/include)
-DEFS += $(addprefix -I,$(CURDIR)/leveldb/helpers)
-
-leveldb/libleveldb.a:
- cd leveldb && $(MAKE) CC=$(CC) CXX=$(CXX) OPT="$(CFLAGS)" TARGET_OS=NATIVE_WINDOWS libleveldb.a libmemenv.a && cd ..
-
-obj/%.o: %.cpp $(HEADERS)
- $(CXX) -c $(CFLAGS) -o $@ $<
-
-bitcoind.exe: $(OBJS:obj/%=obj/%)
- $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
-
-TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
-
-obj-test/%.o: test/%.cpp $(HEADERS)
- $(CXX) -c $(TESTDEFS) $(CFLAGS) -o $@ $<
-
-test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o obj/bitcoind.o,$(OBJS:obj/%=obj/%))
- $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework$(BOOST_SUFFIX) $(LIBS)
-
-clean:
- rm -f bitcoind.exe test_bitcoin.exe
- rm -f obj/*
- rm -f obj-test/*
- cd leveldb && $(MAKE) TARGET_OS=NATIVE_WINDOWS clean && cd ..
-
-FORCE:
diff --git a/src/makefile.osx b/src/makefile.osx
deleted file mode 100644
index ee364f5c4a..0000000000
--- a/src/makefile.osx
+++ /dev/null
@@ -1,181 +0,0 @@
-# -*- mode: Makefile; -*-
-# Copyright (c) 2011 Bitcoin Developers
-# Distributed under the MIT/X11 software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-# Mac OS X makefile for bitcoin
-# Originally by Laszlo Hanyecz (solar@heliacal.net)
-
-CXX=llvm-g++
-DEPSDIR=/opt/local
-
-INCLUDEPATHS= \
- -I"$(CURDIR)" \
- -I"$(CURDIR)"/obj \
- -I"$(DEPSDIR)/include" \
- -I"$(DEPSDIR)/include/db48"
-
-LIBPATHS= \
- -L"$(DEPSDIR)/lib" \
- -L"$(DEPSDIR)/lib/db48"
-
-USE_UPNP:=1
-USE_IPV6:=1
-
-LIBS= -dead_strip
-
-TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
-
-ifdef STATIC
-# Build STATIC if you are redistributing the bitcoind binary
-TESTLIBS += \
- $(DEPSDIR)/lib/libboost_unit_test_framework-mt.a
-LIBS += \
- $(DEPSDIR)/lib/db48/libdb_cxx-4.8.a \
- $(DEPSDIR)/lib/libboost_system-mt.a \
- $(DEPSDIR)/lib/libboost_filesystem-mt.a \
- $(DEPSDIR)/lib/libboost_program_options-mt.a \
- $(DEPSDIR)/lib/libboost_thread-mt.a \
- $(DEPSDIR)/lib/libboost_chrono-mt.a \
- $(DEPSDIR)/lib/libssl.a \
- $(DEPSDIR)/lib/libcrypto.a \
- -lz
-else
-TESTLIBS += \
- -lboost_unit_test_framework-mt
-LIBS += \
- -ldb_cxx-4.8 \
- -lboost_system-mt \
- -lboost_filesystem-mt \
- -lboost_program_options-mt \
- -lboost_thread-mt \
- -lboost_chrono-mt \
- -lssl \
- -lcrypto \
- -lz
-TESTDEFS += -DBOOST_TEST_DYN_LINK
-endif
-
-DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0 -DBOOST_SPIRIT_THREADSAFE
-
-ifdef RELEASE
-# Compile for maximum compatibility and smallest size.
-# This requires that dependencies are compiled
-# the same way.
-CFLAGS = -mmacosx-version-min=10.5 -arch i386 -O3
-else
-DEBUGFLAGS = -g
-endif
-
-# ppc doesn't work because we don't support big-endian
-CFLAGS += -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \
- $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
-
-OBJS= \
- leveldb/libleveldb.a \
- obj/alert.o \
- obj/version.o \
- obj/checkpoints.o \
- obj/netbase.o \
- obj/addrman.o \
- obj/crypter.o \
- obj/key.o \
- obj/db.o \
- obj/init.o \
- obj/bitcoind.o \
- obj/keystore.o \
- obj/core.o \
- obj/main.o \
- obj/miner.o \
- obj/net.o \
- obj/protocol.o \
- obj/bitcoinrpc.o \
- obj/rpcdump.o \
- obj/rpcnet.o \
- obj/rpcmining.o \
- obj/rpcwallet.o \
- obj/rpcblockchain.o \
- obj/rpcrawtransaction.o \
- obj/script.o \
- obj/sync.o \
- obj/util.o \
- obj/wallet.o \
- obj/walletdb.o \
- obj/hash.o \
- obj/bloom.o \
- obj/noui.o \
- obj/leveldb.o \
- obj/txdb.o \
- obj/chainparams.o
-
-ifndef USE_UPNP
- override USE_UPNP = -
-endif
-ifneq (${USE_UPNP}, -)
- DEFS += -DUSE_UPNP=$(USE_UPNP)
-ifdef STATIC
- LIBS += $(DEPSDIR)/lib/libminiupnpc.a
-else
- LIBS += -lminiupnpc
-endif
-endif
-
-ifneq (${USE_IPV6}, -)
- DEFS += -DUSE_IPV6=$(USE_IPV6)
-endif
-
-all: bitcoind
-
-test check: test_bitcoin FORCE
- ./test_bitcoin
-
-#
-# LevelDB support
-#
-LIBS += $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a
-DEFS += $(addprefix -I,$(CURDIR)/leveldb/include)
-DEFS += $(addprefix -I,$(CURDIR)/leveldb/helpers)
-leveldb/libleveldb.a:
- @echo "Building LevelDB ..." && cd leveldb && $(MAKE) CC=$(CC) CXX=$(CXX) OPT="$(CFLAGS)" libleveldb.a libmemenv.a && cd ..
-
-# auto-generated dependencies:
--include obj/*.P
--include obj-test/*.P
-
-obj/build.h: FORCE
- /bin/sh ../share/genbuild.sh obj/build.h
-version.cpp: obj/build.h
-DEFS += -DHAVE_BUILD_INFO
-
-obj/%.o: %.cpp
- $(CXX) -c $(CFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
- @cp $(@:%.o=%.d) $(@:%.o=%.P); \
- sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
- -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
- rm -f $(@:%.o=%.d)
-
-bitcoind: $(OBJS:obj/%=obj/%)
- $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
-
-TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
-
-obj-test/%.o: test/%.cpp
- $(CXX) -c $(TESTDEFS) $(CFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
- @cp $(@:%.o=%.d) $(@:%.o=%.P); \
- sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
- -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
- rm -f $(@:%.o=%.d)
-
-test_bitcoin: $(TESTOBJS) $(filter-out obj/init.o obj/bitcoind.o,$(OBJS:obj/%=obj/%))
- $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(TESTLIBS)
-
-clean:
- -rm -f bitcoind test_bitcoin
- -rm -f obj/*.o
- -rm -f obj-test/*.o
- -rm -f obj/*.P
- -rm -f obj-test/*.P
- -rm -f obj/build.h
- -cd leveldb && $(MAKE) clean || true
-
-FORCE:
diff --git a/src/makefile.unix b/src/makefile.unix
deleted file mode 100644
index 55fd594f93..0000000000
--- a/src/makefile.unix
+++ /dev/null
@@ -1,206 +0,0 @@
-# Copyright (c) 2009-2010 Satoshi Nakamoto
-# Distributed under the MIT/X11 software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-# :=0 --> UPnP support turned off by default at runtime
-# :=1 --> UPnP support turned on by default at runtime
-# :=- --> No UPnP support - miniupnp not required
-USE_UPNP:=0
-
-# :=1 --> Enable IPv6 support
-# :=0 --> Disable IPv6 support
-USE_IPV6:=1
-
-LINK:=$(CXX)
-
-DEFS=-DBOOST_SPIRIT_THREADSAFE -DBOOST_NO_CXX11_VARIADIC_TEMPLATES -D_FILE_OFFSET_BITS=64
-
-DEFS += $(addprefix -I,$(CURDIR) $(CURDIR)/obj $(BOOST_INCLUDE_PATH) $(BDB_INCLUDE_PATH) $(OPENSSL_INCLUDE_PATH))
-LIBS = $(addprefix -L,$(BOOST_LIB_PATH) $(BDB_LIB_PATH) $(OPENSSL_LIB_PATH))
-
-TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
-
-LMODE = dynamic
-LMODE2 = dynamic
-ifdef STATIC
- LMODE = static
- ifeq (${STATIC}, all)
- LMODE2 = static
- endif
-else
- TESTDEFS += -DBOOST_TEST_DYN_LINK
-endif
-
-# for boost 1.37, add -mt to the boost libraries
-LIBS += \
- -Wl,-B$(LMODE) \
- -l boost_system$(BOOST_LIB_SUFFIX) \
- -l boost_filesystem$(BOOST_LIB_SUFFIX) \
- -l boost_program_options$(BOOST_LIB_SUFFIX) \
- -l boost_thread$(BOOST_LIB_SUFFIX) \
- -l db_cxx$(BDB_LIB_SUFFIX) \
- -l ssl \
- -l crypto
-
-TESTLIBS += \
- -Wl,-B$(LMODE) \
- -l boost_unit_test_framework$(BOOST_LIB_SUFFIX)
-
-ifndef USE_UPNP
- override USE_UPNP = -
-endif
-ifneq (${USE_UPNP}, -)
- LIBS += -l miniupnpc
- DEFS += -DUSE_UPNP=$(USE_UPNP)
-endif
-
-ifneq (${USE_IPV6}, -)
- DEFS += -DUSE_IPV6=$(USE_IPV6)
-endif
-
-LIBS+= \
- -Wl,-B$(LMODE2) \
- -l z \
- -l dl \
- -l pthread
-
-
-# Hardening
-# Make some classes of vulnerabilities unexploitable in case one is discovered.
-#
- # This is a workaround for Ubuntu bug #691722, the default -fstack-protector causes
- # -fstack-protector-all to be ignored unless -fno-stack-protector is used first.
- # see: https://bugs.launchpad.net/ubuntu/+source/gcc-4.5/+bug/691722
- HARDENING=-fno-stack-protector
-
- # Stack Canaries
- # Put numbers at the beginning of each stack frame and check that they are the same.
- # If a stack buffer if overflowed, it writes over the canary number and then on return
- # when that number is checked, it won't be the same and the program will exit with
- # a "Stack smashing detected" error instead of being exploited.
- HARDENING+=-fstack-protector-all -Wstack-protector
-
- # Make some important things such as the global offset table read only as soon as
- # the dynamic linker is finished building it. This will prevent overwriting of addresses
- # which would later be jumped to.
- LDHARDENING+=-Wl,-z,relro -Wl,-z,now
-
- # Build position independent code to take advantage of Address Space Layout Randomization
- # offered by some kernels.
- # see doc/build-unix.txt for more information.
- ifdef PIE
- HARDENING+=-fPIE
- LDHARDENING+=-pie
- endif
-
- # -D_FORTIFY_SOURCE=2 does some checking for potentially exploitable code patterns in
- # the source such overflowing a statically defined buffer.
- HARDENING+=-D_FORTIFY_SOURCE=2
-#
-
-
-DEBUGFLAGS=-g
-
-# CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only
-# adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work.
-xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \
- $(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS)
-
-# LDFLAGS can be specified on the make command line, so we use xLDFLAGS that only
-# adds some defaults in front. Unfortunately, LDFLAGS=... $(LDFLAGS) does not work.
-xLDFLAGS=$(LDHARDENING) $(LDFLAGS)
-
-OBJS= \
- leveldb/libleveldb.a \
- obj/alert.o \
- obj/version.o \
- obj/checkpoints.o \
- obj/netbase.o \
- obj/addrman.o \
- obj/crypter.o \
- obj/key.o \
- obj/db.o \
- obj/init.o \
- obj/bitcoind.o \
- obj/keystore.o \
- obj/core.o \
- obj/main.o \
- obj/miner.o \
- obj/net.o \
- obj/protocol.o \
- obj/bitcoinrpc.o \
- obj/rpcdump.o \
- obj/rpcnet.o \
- obj/rpcmining.o \
- obj/rpcwallet.o \
- obj/rpcblockchain.o \
- obj/rpcrawtransaction.o \
- obj/script.o \
- obj/sync.o \
- obj/util.o \
- obj/wallet.o \
- obj/walletdb.o \
- obj/hash.o \
- obj/bloom.o \
- obj/noui.o \
- obj/leveldb.o \
- obj/txdb.o \
- obj/chainparams.o
-
-
-all: bitcoind
-
-test check: test_bitcoin FORCE
- ./test_bitcoin
-
-#
-# LevelDB support
-#
-MAKEOVERRIDES =
-LIBS += $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a
-DEFS += $(addprefix -I,$(CURDIR)/leveldb/include)
-DEFS += $(addprefix -I,$(CURDIR)/leveldb/helpers)
-leveldb/libleveldb.a:
- @echo "Building LevelDB ..." && cd leveldb && $(MAKE) CC=$(CC) CXX=$(CXX) OPT="$(xCXXFLAGS)" libleveldb.a libmemenv.a && cd ..
-
-# auto-generated dependencies:
--include obj/*.P
--include obj-test/*.P
-
-obj/build.h: FORCE
- /bin/sh ../share/genbuild.sh obj/build.h
-version.cpp: obj/build.h
-DEFS += -DHAVE_BUILD_INFO
-
-obj/%.o: %.cpp
- $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
- @cp $(@:%.o=%.d) $(@:%.o=%.P); \
- sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
- -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
- rm -f $(@:%.o=%.d)
-
-bitcoind: $(OBJS:obj/%=obj/%)
- $(LINK) $(xCXXFLAGS) -o $@ $^ $(xLDFLAGS) $(LIBS)
-
-TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
-
-obj-test/%.o: test/%.cpp
- $(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
- @cp $(@:%.o=%.d) $(@:%.o=%.P); \
- sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
- -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
- rm -f $(@:%.o=%.d)
-
-test_bitcoin: $(TESTOBJS) $(filter-out obj/init.o obj/bitcoind.o,$(OBJS:obj/%=obj/%))
- $(LINK) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ $(TESTLIBS) $(xLDFLAGS) $(LIBS)
-
-clean:
- -rm -f bitcoind test_bitcoin
- -rm -f obj/*.o
- -rm -f obj-test/*.o
- -rm -f obj/*.P
- -rm -f obj-test/*.P
- -rm -f obj/build.h
- -cd leveldb && $(MAKE) clean || true
-
-FORCE:
diff --git a/src/miner.cpp b/src/miner.cpp
index 3ecf1609e1..30c600071f 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -3,15 +3,11 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "core.h"
-#include "wallet.h"
#include "miner.h"
#include "main.h"
-
-
-
-
+double dHashesPerSec = 0.0;
+int64 nHPSTimerStart = 0;
//////////////////////////////////////////////////////////////////////////////
//
@@ -106,10 +102,10 @@ public:
void print() const
{
- printf("COrphan(hash=%s, dPriority=%.1f, dFeePerKb=%.1f)\n",
+ LogPrintf("COrphan(hash=%s, dPriority=%.1f, dFeePerKb=%.1f)\n",
ptx->GetHash().ToString().c_str(), dPriority, dFeePerKb);
BOOST_FOREACH(uint256 hash, setDependsOn)
- printf(" setDependsOn %s\n", hash.ToString().c_str());
+ LogPrintf(" setDependsOn %s\n", hash.ToString().c_str());
}
};
@@ -211,7 +207,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
// or other transactions in the memory pool.
if (!mempool.mapTx.count(txin.prevout.hash))
{
- printf("ERROR: mempool transaction missing input\n");
+ LogPrintf("ERROR: mempool transaction missing input\n");
if (fDebug) assert("mempool transaction missing input" == 0);
fMissingInputs = true;
if (porphan)
@@ -331,7 +327,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
if (fPrintPriority)
{
- printf("priority %.1f feeperkb %.1f txid %s\n",
+ LogPrintf("priority %.1f feeperkb %.1f txid %s\n",
dPriority, dFeePerKb, tx.GetHash().ToString().c_str());
}
@@ -355,7 +351,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
nLastBlockTx = nBlockTx;
nLastBlockSize = nBlockSize;
- printf("CreateNewBlock(): total size %"PRI64u"\n", nBlockSize);
+ LogPrintf("CreateNewBlock(): total size %"PRI64u"\n", nBlockSize);
pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
pblocktemplate->vTxFees[0] = -nFees;
@@ -463,10 +459,10 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
return false;
//// debug print
- printf("BitcoinMiner:\n");
- printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
+ LogPrintf("BitcoinMiner:\n");
+ LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
pblock->print();
- printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
+ LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
// Found a solution
{
@@ -494,7 +490,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
void static BitcoinMiner(CWallet *pwallet)
{
- printf("BitcoinMiner started\n");
+ LogPrintf("BitcoinMiner started\n");
SetThreadPriority(THREAD_PRIORITY_LOWEST);
RenameThread("bitcoin-miner");
@@ -522,7 +518,7 @@ void static BitcoinMiner(CWallet *pwallet)
CBlock *pblock = &pblocktemplate->block;
IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
- printf("Running BitcoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(),
+ LogPrintf("Running BitcoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(),
::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
//
@@ -603,7 +599,7 @@ void static BitcoinMiner(CWallet *pwallet)
if (GetTime() - nLogTime > 30 * 60)
{
nLogTime = GetTime();
- printf("hashmeter %6.0f khash/s\n", dHashesPerSec/1000.0);
+ LogPrintf("hashmeter %6.0f khash/s\n", dHashesPerSec/1000.0);
}
}
}
@@ -633,7 +629,7 @@ void static BitcoinMiner(CWallet *pwallet)
} }
catch (boost::thread_interrupted)
{
- printf("BitcoinMiner terminated\n");
+ LogPrintf("BitcoinMiner terminated\n");
throw;
}
}
diff --git a/src/miner.h b/src/miner.h
index 36d58be00f..7e60b9e53b 100644
--- a/src/miner.h
+++ b/src/miner.h
@@ -22,4 +22,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
/** Base sha256 mining transform */
void SHA256Transform(void* pstate, void* pinput, const void* pinit);
+extern double dHashesPerSec;
+extern int64 nHPSTimerStart;
+
#endif // BITCOIN_MINER_H
diff --git a/src/net.cpp b/src/net.cpp
index 1f461e55db..781dbfadca 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -3,6 +3,10 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#if defined(HAVE_CONFIG_H)
+#include "bitcoin-config.h"
+#endif
+
#include "chainparams.h"
#include "db.h"
#include "net.h"
@@ -28,6 +32,9 @@
// Dump addresses to peers.dat every 15 minutes (900s)
#define DUMP_ADDRESSES_INTERVAL 900
+#if !defined(HAVE_MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
using namespace std;
using namespace boost;
@@ -166,14 +173,14 @@ bool RecvLine(SOCKET hSocket, string& strLine)
if (nBytes == 0)
{
// socket closed
- printf("socket closed\n");
+ LogPrint("net", "socket closed\n");
return false;
}
else
{
// socket error
int nErr = WSAGetLastError();
- printf("recv failed: %d\n", nErr);
+ LogPrint("net", "recv failed: %d\n", nErr);
return false;
}
}
@@ -219,7 +226,7 @@ bool AddLocal(const CService& addr, int nScore)
if (IsLimited(addr))
return false;
- printf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore);
+ LogPrintf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore);
{
LOCK(cs_mapLocalHost);
@@ -327,7 +334,7 @@ bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const cha
while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
strLine.resize(strLine.size()-1);
CService addr(strLine,0,true);
- printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
+ LogPrintf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
if (!addr.IsValid() || !addr.IsRoutable())
return false;
ipRet.SetIP(addr);
@@ -402,7 +409,7 @@ void ThreadGetMyExternalIP()
CNetAddr addrLocalHost;
if (GetMyExternalIP(addrLocalHost))
{
- printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
+ LogPrintf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
AddLocal(addrLocalHost, LOCAL_HTTP);
}
}
@@ -466,7 +473,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
/// debug print
- printf("trying connection %s lastseen=%.1fhrs\n",
+ LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
pszDest ? pszDest : addrConnect.ToString().c_str(),
pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
@@ -476,17 +483,16 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
{
addrman.Attempt(addrConnect);
- /// debug print
- printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str());
+ LogPrint("net", "connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str());
// Set to non-blocking
#ifdef WIN32
u_long nOne = 1;
if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
- printf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
+ LogPrintf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
#else
if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
- printf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno);
+ LogPrintf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno);
#endif
// Add node
@@ -512,7 +518,7 @@ void CNode::CloseSocketDisconnect()
fDisconnect = true;
if (hSocket != INVALID_SOCKET)
{
- printf("disconnecting node %s\n", addrName.c_str());
+ LogPrint("net", "disconnecting node %s\n", addrName.c_str());
closesocket(hSocket);
hSocket = INVALID_SOCKET;
}
@@ -539,7 +545,7 @@ void CNode::PushVersion()
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
CAddress addrMe = GetLocalAddress(&addr);
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
- printf("send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str());
+ LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str());
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true);
}
@@ -576,7 +582,7 @@ bool CNode::Misbehaving(int howmuch)
{
if (addr.IsLocal())
{
- printf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName.c_str(), howmuch);
+ LogPrintf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName.c_str(), howmuch);
return false;
}
@@ -584,7 +590,7 @@ bool CNode::Misbehaving(int howmuch)
if (nMisbehavior >= GetArg("-banscore", 100))
{
int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
- printf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
+ LogPrintf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
{
LOCK(cs_setBanned);
if (setBanned[addr] < banTime)
@@ -593,7 +599,7 @@ bool CNode::Misbehaving(int howmuch)
CloseSocketDisconnect();
return true;
} else
- printf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
+ LogPrintf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
return false;
}
@@ -724,7 +730,7 @@ void SocketSendData(CNode *pnode)
int nErr = WSAGetLastError();
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
{
- printf("socket send error %d\n", nErr);
+ LogPrintf("socket send error %d\n", nErr);
pnode->CloseSocketDisconnect();
}
}
@@ -884,7 +890,7 @@ void ThreadSocketHandler()
if (have_fds)
{
int nErr = WSAGetLastError();
- printf("socket select error %d\n", nErr);
+ LogPrintf("socket select error %d\n", nErr);
for (unsigned int i = 0; i <= hSocketMax; i++)
FD_SET(i, &fdsetRecv);
}
@@ -912,7 +918,7 @@ void ThreadSocketHandler()
if (hSocket != INVALID_SOCKET)
if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
- printf("Warning: Unknown socket family\n");
+ LogPrintf("Warning: Unknown socket family\n");
{
LOCK(cs_vNodes);
@@ -925,7 +931,7 @@ void ThreadSocketHandler()
{
int nErr = WSAGetLastError();
if (nErr != WSAEWOULDBLOCK)
- printf("socket error accept failed: %d\n", nErr);
+ LogPrintf("socket error accept failed: %d\n", nErr);
}
else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
{
@@ -937,12 +943,12 @@ void ThreadSocketHandler()
}
else if (CNode::IsBanned(addr))
{
- printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
+ LogPrintf("connection from %s dropped (banned)\n", addr.ToString().c_str());
closesocket(hSocket);
}
else
{
- printf("accepted connection %s\n", addr.ToString().c_str());
+ LogPrint("net", "accepted connection %s\n", addr.ToString().c_str());
CNode* pnode = new CNode(hSocket, addr, "", true);
pnode->AddRef();
{
@@ -992,7 +998,7 @@ void ThreadSocketHandler()
{
// socket closed gracefully
if (!pnode->fDisconnect)
- printf("socket closed\n");
+ LogPrint("net", "socket closed\n");
pnode->CloseSocketDisconnect();
}
else if (nBytes < 0)
@@ -1002,7 +1008,7 @@ void ThreadSocketHandler()
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
{
if (!pnode->fDisconnect)
- printf("socket recv error %d\n", nErr);
+ LogPrintf("socket recv error %d\n", nErr);
pnode->CloseSocketDisconnect();
}
}
@@ -1031,17 +1037,17 @@ void ThreadSocketHandler()
{
if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
{
- printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
+ LogPrint("net", "socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
pnode->fDisconnect = true;
}
else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
{
- printf("socket not sending\n");
+ LogPrintf("socket not sending\n");
pnode->fDisconnect = true;
}
else if (GetTime() - pnode->nLastRecv > 90*60)
{
- printf("socket inactivity timeout\n");
+ LogPrintf("socket inactivity timeout\n");
pnode->fDisconnect = true;
}
}
@@ -1093,16 +1099,16 @@ void ThreadMapPort()
char externalIPAddress[40];
r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
if(r != UPNPCOMMAND_SUCCESS)
- printf("UPnP: GetExternalIPAddress() returned %d\n", r);
+ LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
else
{
if(externalIPAddress[0])
{
- printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
+ LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
}
else
- printf("UPnP: GetExternalIPAddress failed.\n");
+ LogPrintf("UPnP: GetExternalIPAddress failed.\n");
}
}
@@ -1121,10 +1127,10 @@ void ThreadMapPort()
#endif
if(r!=UPNPCOMMAND_SUCCESS)
- printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
+ LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
port.c_str(), port.c_str(), lanaddr, r, strupnperror(r));
else
- printf("UPnP Port Mapping successful.\n");;
+ LogPrintf("UPnP Port Mapping successful.\n");;
MilliSleep(20*60*1000); // Refresh every 20 minutes
}
@@ -1132,13 +1138,13 @@ void ThreadMapPort()
catch (boost::thread_interrupted)
{
r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
- printf("UPNP_DeletePortMapping() returned : %d\n", r);
+ LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r);
freeUPNPDevlist(devlist); devlist = 0;
FreeUPNPUrls(&urls);
throw;
}
} else {
- printf("No valid UPnP IGDs found\n");
+ LogPrintf("No valid UPnP IGDs found\n");
freeUPNPDevlist(devlist); devlist = 0;
if (r != 0)
FreeUPNPUrls(&urls);
@@ -1183,7 +1189,7 @@ void ThreadDNSAddressSeed()
const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
int found = 0;
- printf("Loading addresses from DNS seeds (could take a while)\n");
+ LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) {
if (HaveNameProxy()) {
@@ -1206,7 +1212,7 @@ void ThreadDNSAddressSeed()
}
}
- printf("%d addresses found from DNS seeds\n", found);
+ LogPrintf("%d addresses found from DNS seeds\n", found);
}
@@ -1227,7 +1233,7 @@ void DumpAddresses()
CAddrDB adb;
adb.Write(addrman);
- printf("Flushed %d addresses to peers.dat %"PRI64d"ms\n",
+ LogPrint("net", "Flushed %d addresses to peers.dat %"PRI64d"ms\n",
addrman.size(), GetTimeMillis() - nStart);
}
@@ -1285,7 +1291,7 @@ void ThreadOpenConnections()
if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
static bool done = false;
if (!done) {
- printf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
+ LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
addrman.Add(Params().FixedSeeds(), CNetAddr("127.0.0.1"));
done = true;
}
@@ -1561,7 +1567,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
{
strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
- printf("%s\n", strError.c_str());
+ LogPrintf("%s\n", strError.c_str());
return false;
}
@@ -1569,7 +1575,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
if (hListenSocket == INVALID_SOCKET)
{
strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
- printf("%s\n", strError.c_str());
+ LogPrintf("%s\n", strError.c_str());
return false;
}
@@ -1593,7 +1599,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
#endif
{
strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
- printf("%s\n", strError.c_str());
+ LogPrintf("%s\n", strError.c_str());
return false;
}
@@ -1624,16 +1630,16 @@ bool BindListenPort(const CService &addrBind, string& strError)
strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin is probably already running."), addrBind.ToString().c_str());
else
strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
- printf("%s\n", strError.c_str());
+ LogPrintf("%s\n", strError.c_str());
return false;
}
- printf("Bound to %s\n", addrBind.ToString().c_str());
+ LogPrintf("Bound to %s\n", addrBind.ToString().c_str());
// Listen for incoming connections
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
{
strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
- printf("%s\n", strError.c_str());
+ LogPrintf("%s\n", strError.c_str());
return false;
}
@@ -1680,7 +1686,7 @@ void static Discover()
struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
CNetAddr addr(s4->sin_addr);
if (AddLocal(addr, LOCAL_IF))
- printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
+ LogPrintf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
}
#ifdef USE_IPV6
else if (ifa->ifa_addr->sa_family == AF_INET6)
@@ -1688,7 +1694,7 @@ void static Discover()
struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
CNetAddr addr(s6->sin6_addr);
if (AddLocal(addr, LOCAL_IF))
- printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
+ LogPrintf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
}
#endif
}
@@ -1719,7 +1725,7 @@ void StartNode(boost::thread_group& threadGroup)
//
if (!GetBoolArg("-dnsseed", true))
- printf("DNS seeding disabled\n");
+ LogPrintf("DNS seeding disabled\n");
else
threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "dnsseed", &ThreadDNSAddressSeed));
@@ -1746,7 +1752,7 @@ void StartNode(boost::thread_group& threadGroup)
bool StopNode()
{
- printf("StopNode()\n");
+ LogPrintf("StopNode()\n");
MapPort(false);
if (semOutbound)
for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
@@ -1772,7 +1778,7 @@ public:
BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
if (hListenSocket != INVALID_SOCKET)
if (closesocket(hListenSocket) == SOCKET_ERROR)
- printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
+ LogPrintf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
// clean up some globals (to help leak detection)
BOOST_FOREACH(CNode *pnode, vNodes)
diff --git a/src/net.h b/src/net.h
index 686861fbeb..49415f6502 100644
--- a/src/net.h
+++ b/src/net.h
@@ -372,8 +372,7 @@ public:
nRequestTime = it->second;
else
nRequestTime = 0;
- if (fDebugNet)
- printf("askfor %s %"PRI64d" (%s)\n", inv.ToString().c_str(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str());
+ LogPrint("net", "askfor %s %"PRI64d" (%s)\n", inv.ToString().c_str(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str());
// Make sure not to reuse time indexes to keep things in the same order
int64 nNow = (GetTime() - 1) * 1000000;
@@ -399,8 +398,7 @@ public:
ENTER_CRITICAL_SECTION(cs_vSend);
assert(ssSend.size() == 0);
ssSend << CMessageHeader(pszCommand, 0);
- if (fDebug)
- printf("sending: %s ", pszCommand);
+ LogPrint("net", "sending: %s ", pszCommand);
}
// TODO: Document the precondition of this function. Is cs_vSend locked?
@@ -410,8 +408,7 @@ public:
LEAVE_CRITICAL_SECTION(cs_vSend);
- if (fDebug)
- printf("(aborted)\n");
+ LogPrint("net", "(aborted)\n");
}
// TODO: Document the precondition of this function. Is cs_vSend locked?
@@ -419,7 +416,7 @@ public:
{
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
{
- printf("dropmessages DROPPING SEND MESSAGE\n");
+ LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
AbortMessage();
return;
}
@@ -438,9 +435,7 @@ public:
assert(ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
memcpy((char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum, sizeof(nChecksum));
- if (fDebug) {
- printf("(%d bytes)\n", nSize);
- }
+ LogPrint("net", "(%d bytes)\n", nSize);
std::deque<CSerializeData>::iterator it = vSendMsg.insert(vSendMsg.end(), CSerializeData());
ssSend.GetAndClear(*it);
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 348771375c..acc2ae32aa 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -15,6 +15,10 @@
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
#include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
+#if !defined(HAVE_MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
+
using namespace std;
// Settings
@@ -165,7 +169,7 @@ bool LookupNumeric(const char *pszName, CService& addr, int portDefault)
bool static Socks4(const CService &addrDest, SOCKET& hSocket)
{
- printf("SOCKS4 connecting %s\n", addrDest.ToString().c_str());
+ LogPrintf("SOCKS4 connecting %s\n", addrDest.ToString().c_str());
if (!addrDest.IsIPv4())
{
closesocket(hSocket);
@@ -200,16 +204,16 @@ bool static Socks4(const CService &addrDest, SOCKET& hSocket)
{
closesocket(hSocket);
if (pchRet[1] != 0x5b)
- printf("ERROR: Proxy returned error %d\n", pchRet[1]);
+ LogPrintf("ERROR: Proxy returned error %d\n", pchRet[1]);
return false;
}
- printf("SOCKS4 connected %s\n", addrDest.ToString().c_str());
+ LogPrintf("SOCKS4 connected %s\n", addrDest.ToString().c_str());
return true;
}
bool static Socks5(string strDest, int port, SOCKET& hSocket)
{
- printf("SOCKS5 connecting %s\n", strDest.c_str());
+ LogPrintf("SOCKS5 connecting %s\n", strDest.c_str());
if (strDest.size() > 255)
{
closesocket(hSocket);
@@ -305,7 +309,7 @@ bool static Socks5(string strDest, int port, SOCKET& hSocket)
closesocket(hSocket);
return error("Error reading from proxy");
}
- printf("SOCKS5 connected %s\n", strDest.c_str());
+ LogPrintf("SOCKS5 connected %s\n", strDest.c_str());
return true;
}
@@ -320,7 +324,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
#endif
socklen_t len = sizeof(sockaddr);
if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
- printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str());
+ LogPrintf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str());
return false;
}
@@ -359,13 +363,13 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
if (nRet == 0)
{
- printf("connection timeout\n");
+ LogPrint("net", "connection timeout\n");
closesocket(hSocket);
return false;
}
if (nRet == SOCKET_ERROR)
{
- printf("select() for connection failed: %i\n",WSAGetLastError());
+ LogPrintf("select() for connection failed: %i\n",WSAGetLastError());
closesocket(hSocket);
return false;
}
@@ -376,13 +380,13 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
#endif
{
- printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
+ LogPrintf("getsockopt() for connection failed: %i\n",WSAGetLastError());
closesocket(hSocket);
return false;
}
if (nRet != 0)
{
- printf("connect() failed after select(): %s\n",strerror(nRet));
+ LogPrintf("connect() failed after select(): %s\n",strerror(nRet));
closesocket(hSocket);
return false;
}
@@ -393,7 +397,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
else
#endif
{
- printf("connect() failed: %i\n",WSAGetLastError());
+ LogPrintf("connect() failed: %i\n",WSAGetLastError());
closesocket(hSocket);
return false;
}
@@ -889,7 +893,7 @@ uint64 CNetAddr::GetHash() const
void CNetAddr::print() const
{
- printf("CNetAddr(%s)\n", ToString().c_str());
+ LogPrintf("CNetAddr(%s)\n", ToString().c_str());
}
// private extensions to enum Network, only returned by GetExtNetwork,
@@ -1130,7 +1134,7 @@ std::string CService::ToString() const
void CService::print() const
{
- printf("CService(%s)\n", ToString().c_str());
+ LogPrintf("CService(%s)\n", ToString().c_str());
}
void CService::SetPort(unsigned short portIn)
diff --git a/src/netbase.h b/src/netbase.h
index e4ec4ef597..e1f80b4ee8 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -4,6 +4,10 @@
#ifndef BITCOIN_NETBASE_H
#define BITCOIN_NETBASE_H
+#if defined(HAVE_CONFIG_H)
+#include "bitcoin-config.h"
+#endif
+
#include <string>
#include <vector>
@@ -50,7 +54,7 @@ class CNetAddr
bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32)
bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16)
bool IsRFC3964() const; // IPv6 6to4 tunnelling (2002::/16)
- bool IsRFC4193() const; // IPv6 unique local (FC00::/15)
+ bool IsRFC4193() const; // IPv6 unique local (FC00::/7)
bool IsRFC4380() const; // IPv6 Teredo tunnelling (2001::/32)
bool IsRFC4843() const; // IPv6 ORCHID (2001:10::/28)
bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64)
diff --git a/src/noui.cpp b/src/noui.cpp
index c0e00c4715..67eac944c6 100644
--- a/src/noui.cpp
+++ b/src/noui.cpp
@@ -27,7 +27,7 @@ static bool noui_ThreadSafeMessageBox(const std::string& message, const std::str
strCaption += caption; // Use supplied caption (can be empty)
}
- printf("%s: %s\n", strCaption.c_str(), message.c_str());
+ LogPrintf("%s: %s\n", strCaption.c_str(), message.c_str());
fprintf(stderr, "%s: %s\n", strCaption.c_str(), message.c_str());
return false;
}
@@ -39,7 +39,7 @@ static bool noui_ThreadSafeAskFee(int64 /*nFeeRequired*/)
static void noui_InitMessage(const std::string &message)
{
- printf("init message: %s\n", message.c_str());
+ LogPrintf("init message: %s\n", message.c_str());
}
void noui_connect()
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 745b4338e4..ba254be3e1 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -67,7 +67,7 @@ bool CMessageHeader::IsValid() const
// Message size
if (nMessageSize > MAX_SIZE)
{
- printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize);
+ LogPrintf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize);
return false;
}
@@ -146,6 +146,6 @@ std::string CInv::ToString() const
void CInv::print() const
{
- printf("CInv(%s)\n", ToString().c_str());
+ LogPrintf("CInv(%s)\n", ToString().c_str());
}
diff --git a/src/qt/Makefile.am b/src/qt/Makefile.am
new file mode 100644
index 0000000000..248dcba0ec
--- /dev/null
+++ b/src/qt/Makefile.am
@@ -0,0 +1,172 @@
+include $(top_srcdir)/src/Makefile.include
+
+AM_CPPFLAGS = $(INCLUDES) -I$(top_builddir)/src/obj \
+ -I$(top_srcdir)/src/leveldb/include -I$(top_srcdir)/src \
+ -I$(top_srcdir)/src/leveldb/helpers -I$(top_builddir)/src/qt \
+ -I$(top_builddir)/src/qt/forms $(BOOST_INCLUDES) $(PROTOBUF_CFLAGS) \
+ $(QR_CFLAGS) $(BDB_CPPFLAGS)
+AM_LDFLAGS = $(PTHREAD_CFLAGS)
+bin_PROGRAMS = bitcoin-qt
+noinst_LIBRARIES = libbitcoinqt.a
+SUBDIRS = $(BUILD_TEST_QT)
+DIST_SUBDIRS = test
+
+# bitcoin qt core #
+QT_TS = locale/bitcoin_ach.ts locale/bitcoin_af_ZA.ts locale/bitcoin_ar.ts \
+ locale/bitcoin_be_BY.ts locale/bitcoin_bg.ts locale/bitcoin_bs.ts \
+ locale/bitcoin_ca_ES.ts locale/bitcoin_ca.ts locale/bitcoin_cs.ts \
+ locale/bitcoin_cy.ts locale/bitcoin_da.ts locale/bitcoin_de.ts \
+ locale/bitcoin_el_GR.ts locale/bitcoin_en.ts locale/bitcoin_eo.ts \
+ locale/bitcoin_es_CL.ts locale/bitcoin_es.ts locale/bitcoin_et.ts \
+ locale/bitcoin_eu_ES.ts locale/bitcoin_fa_IR.ts locale/bitcoin_fa.ts \
+ locale/bitcoin_fi.ts locale/bitcoin_fr_CA.ts locale/bitcoin_fr.ts \
+ locale/bitcoin_gu_IN.ts locale/bitcoin_he.ts locale/bitcoin_hi_IN.ts \
+ locale/bitcoin_hr.ts locale/bitcoin_hu.ts locale/bitcoin_id_ID.ts \
+ locale/bitcoin_it.ts locale/bitcoin_ja.ts locale/bitcoin_kk_KZ.ts \
+ locale/bitcoin_ko_KR.ts locale/bitcoin_la.ts locale/bitcoin_lt.ts \
+ locale/bitcoin_lv_LV.ts locale/bitcoin_ms_MY.ts locale/bitcoin_nb.ts \
+ locale/bitcoin_nl.ts locale/bitcoin_pl.ts locale/bitcoin_pt_BR.ts \
+ locale/bitcoin_pt_PT.ts locale/bitcoin_ro_RO.ts locale/bitcoin_ru.ts \
+ locale/bitcoin_sk.ts locale/bitcoin_sq.ts locale/bitcoin_sr.ts \
+ locale/bitcoin_sv.ts locale/bitcoin_th_TH.ts locale/bitcoin_tr.ts \
+ locale/bitcoin_uk.ts locale/bitcoin_vi.ts locale/bitcoin_vi_VN.ts \
+ locale/bitcoin_zh_CN.ts locale/bitcoin_zh_TW.ts
+
+QT_FORMS_UI = forms/aboutdialog.ui forms/addressbookpage.ui \
+ forms/askpassphrasedialog.ui forms/editaddressdialog.ui forms/intro.ui \
+ forms/optionsdialog.ui forms/overviewpage.ui forms/qrcodedialog.ui \
+ forms/rpcconsole.ui forms/sendcoinsdialog.ui forms/sendcoinsentry.ui \
+ forms/signverifymessagedialog.ui forms/transactiondescdialog.ui
+
+QT_MOC_CPP = moc_aboutdialog.cpp moc_addressbookpage.cpp \
+ moc_addresstablemodel.cpp moc_askpassphrasedialog.cpp \
+ moc_bitcoinaddressvalidator.cpp moc_bitcoinamountfield.cpp \
+ moc_bitcoingui.cpp moc_bitcoinunits.cpp moc_clientmodel.cpp \
+ moc_csvmodelwriter.cpp moc_editaddressdialog.cpp moc_guiutil.cpp \
+ moc_intro.cpp moc_macdockiconhandler.cpp moc_macnotificationhandler.cpp \
+ moc_monitoreddatamapper.cpp moc_notificator.cpp moc_optionsdialog.cpp \
+ moc_optionsmodel.cpp moc_overviewpage.cpp moc_paymentserver.cpp \
+ moc_qrcodedialog.cpp moc_qvalidatedlineedit.cpp moc_qvaluecombobox.cpp \
+ moc_rpcconsole.cpp moc_sendcoinsdialog.cpp moc_sendcoinsentry.cpp \
+ moc_signverifymessagedialog.cpp moc_splashscreen.cpp moc_transactiondesc.cpp \
+ moc_transactiondescdialog.cpp moc_transactionfilterproxy.cpp \
+ moc_transactiontablemodel.cpp moc_transactionview.cpp moc_walletframe.cpp \
+ moc_walletmodel.cpp moc_walletstack.cpp moc_walletview.cpp
+
+BITCOIN_MM = macdockiconhandler.mm macnotificationhandler.mm
+QR_CPP = qrcodedialog.cpp
+
+QT_MOC = intro.moc overviewpage.moc rpcconsole.moc
+
+QT_QRC_CPP = qrc_bitcoin.cpp
+QT_QRC = bitcoin.qrc
+
+PROTOBUF_CC = paymentrequest.pb.cc
+PROTOBUF_H = paymentrequest.pb.h
+PROTOBUF_PROTO = paymentrequest.proto
+
+BITCOIN_QT_H = aboutdialog.h addressbookpage.h addresstablemodel.h \
+ askpassphrasedialog.h bitcoinaddressvalidator.h bitcoinamountfield.h \
+ bitcoingui.h bitcoinunits.h clientmodel.h csvmodelwriter.h \
+ editaddressdialog.h guiconstants.h guiutil.h intro.h macdockiconhandler.h \
+ macnotificationhandler.h monitoreddatamapper.h notificator.h optionsdialog.h \
+ optionsmodel.h overviewpage.h paymentrequestplus.h paymentserver.h \
+ qrcodedialog.h qvalidatedlineedit.h qvaluecombobox.h rpcconsole.h \
+ sendcoinsdialog.h sendcoinsentry.h signverifymessagedialog.h splashscreen.h \
+ transactiondescdialog.h transactiondesc.h transactionfilterproxy.h \
+ transactionrecord.h transactiontablemodel.h transactionview.h walletframe.h \
+ walletmodel.h walletmodeltransaction.h walletstack.h walletview.h
+
+RES_ICONS = res/icons/bitcoin.png res/icons/address-book.png \
+ res/icons/quit.png res/icons/send.png res/icons/toolbar.png \
+ res/icons/connect0_16.png res/icons/connect1_16.png \
+ res/icons/connect2_16.png res/icons/connect3_16.png \
+ res/icons/connect4_16.png res/icons/transaction0.png \
+ res/icons/transaction2.png res/icons/clock1.png res/icons/clock2.png \
+ res/icons/clock3.png res/icons/clock4.png res/icons/clock5.png \
+ res/icons/configure.png res/icons/receive.png res/icons/editpaste.png \
+ res/icons/editcopy.png res/icons/add.png res/icons/bitcoin_testnet.png \
+ res/icons/toolbar_testnet.png res/icons/edit.png res/icons/history.png \
+ res/icons/overview.png res/icons/export.png res/icons/synced.png \
+ res/icons/remove.png res/icons/tx_mined.png res/icons/tx_input.png \
+ res/icons/tx_output.png res/icons/tx_inout.png res/icons/lock_closed.png \
+ res/icons/lock_open.png res/icons/key.png res/icons/filesave.png \
+ res/icons/qrcode.png res/icons/debugwindow.png res/icons/bitcoin.ico \
+ res/icons/bitcoin_testnet.ico
+
+BITCOIN_QT_CPP = aboutdialog.cpp addressbookpage.cpp \
+ addresstablemodel.cpp askpassphrasedialog.cpp bitcoinaddressvalidator.cpp \
+ bitcoinamountfield.cpp bitcoin.cpp bitcoingui.cpp \
+ bitcoinunits.cpp clientmodel.cpp csvmodelwriter.cpp editaddressdialog.cpp \
+ guiutil.cpp intro.cpp monitoreddatamapper.cpp notificator.cpp \
+ optionsdialog.cpp optionsmodel.cpp overviewpage.cpp paymentrequestplus.cpp \
+ paymentserver.cpp qvalidatedlineedit.cpp qvaluecombobox.cpp \
+ rpcconsole.cpp sendcoinsdialog.cpp sendcoinsentry.cpp \
+ signverifymessagedialog.cpp splashscreen.cpp transactiondesc.cpp \
+ transactiondescdialog.cpp transactionfilterproxy.cpp transactionrecord.cpp \
+ transactiontablemodel.cpp transactionview.cpp walletframe.cpp \
+ walletmodel.cpp walletmodeltransaction.cpp walletstack.cpp walletview.cpp
+
+RES_IMAGES = res/images/about.png res/images/splash.png \
+ res/images/splash_testnet.png
+
+RES_MOVIES = res/movies/update_spinner.mng
+
+BITCOIN_RC = res/bitcoin-qt-res.rc
+
+libbitcoinqt_a_CPPFLAGS = $(AM_CPPFLAGS) $(QT_INCLUDES) \
+ -I$(top_srcdir)/src/qt/forms $(QT_DBUS_INCLUDES)
+libbitcoinqt_a_SOURCES = $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(QT_FORMS_UI) \
+ $(QT_QRC) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES)
+
+nodist_libbitcoinqt_a_SOURCES = $(QT_MOC_CPP) $(QT_MOC) $(PROTOBUF_CC) \
+ $(PROTOBUF_H) $(QT_QRC_CPP)
+
+BUILT_SOURCES = $(nodist_libbitcoinqt_a_SOURCES)
+
+#Generating these with a half-written protobuf header leads to wacky results.
+#This makes sure it's done.
+$(QT_MOC): $(PROTOBUF_H)
+$(QT_MOC_CPP): $(PROTOBUF_H)
+
+if TARGET_DARWIN
+ libbitcoinqt_a_SOURCES += $(BITCOIN_MM)
+endif
+if TARGET_WINDOWS
+ libbitcoinqt_a_SOURCES += $(BITCOIN_RC)
+endif
+if USE_QRCODE
+ libbitcoinqt_a_SOURCES += $(QR_CPP)
+endif
+#
+
+# bitcoin-qt binary #
+bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(QT_INCLUDES) \
+ -I$(top_srcdir)/src/qt/forms
+bitcoin_qt_SOURCES = bitcoin.cpp
+bitcoin_qt_LDADD = libbitcoinqt.a $(LIBBITCOIN) $(LIBLEVELDB) $(LIBMEMENV) \
+ $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
+
+# forms/foo.h -> forms/ui_foo.h
+QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI:.ui=.h))))
+
+#locale/foo.ts -> locale/foo.qm
+QT_QM=$(QT_TS:.ts=.qm)
+
+.PHONY: FORCE
+.SECONDARY: $(QT_QM)
+
+bitcoinstrings.cpp: FORCE
+ $(MAKE) -C $(top_srcdir)/src qt/bitcoinstrings.cpp
+
+translate: bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) $(QR_CPP)
+ @test -n $(LUPDATE) || echo "lupdate is required for updating translations"
+ @$(LUPDATE) $^ -locations relative -no-obsolete -ts locale/bitcoin_en.ts
+
+$(QT_QRC_CPP): $(QT_QRC) $(QT_QM) $(QT_FORMS_H) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) $(PROTOBUF_H)
+ @cd $(abs_srcdir); test -f $(RCC) && $(RCC) -name bitcoin -o $(abs_builddir)/$@ $< || \
+ echo error: could not build $@
+ $(SED) -i.bak -e '/^\*\*.*Created:/d' $@ && rm $@.bak
+ $(SED) -i.bak -e '/^\*\*.*by:/d' $@ && rm $@.bak
+
+CLEANFILES = $(BUILT_SOURCES) $(QT_QM) $(QT_FORMS_H) *.gcda *.gcno
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp
index 8906174d7d..5b8d44481e 100644
--- a/src/qt/addressbookpage.cpp
+++ b/src/qt/addressbookpage.cpp
@@ -1,3 +1,7 @@
+#if defined(HAVE_CONFIG_H)
+#include "bitcoin-config.h"
+#endif
+
#include "addressbookpage.h"
#include "ui_addressbookpage.h"
diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
index dcc70222cc..921c4443a9 100644
--- a/src/qt/addresstablemodel.cpp
+++ b/src/qt/addresstablemodel.cpp
@@ -7,6 +7,7 @@
#include "base58.h"
#include <QFont>
+#include <QDebug>
const QString AddressTableModel::Send = "S";
const QString AddressTableModel::Receive = "R";
@@ -15,7 +16,8 @@ struct AddressTableEntry
{
enum Type {
Sending,
- Receiving
+ Receiving,
+ Hidden /* QSortFilterProxyModel will filter these out */
};
Type type;
@@ -43,6 +45,20 @@ struct AddressTableEntryLessThan
}
};
+/* Determine address type from address purpose */
+static AddressTableEntry::Type translateTransactionType(const QString &strPurpose, bool isMine)
+{
+ AddressTableEntry::Type addressType = AddressTableEntry::Hidden;
+ // "refund" addresses aren't shown, and change addresses aren't in mapAddressBook at all.
+ if (strPurpose == "send")
+ addressType = AddressTableEntry::Sending;
+ else if (strPurpose == "receive")
+ addressType = AddressTableEntry::Receiving;
+ else if (strPurpose == "unknown" || strPurpose == "") // if purpose not set, guess
+ addressType = (isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending);
+ return addressType;
+}
+
// Private implementation
class AddressTablePriv
{
@@ -62,17 +78,9 @@ public:
BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, wallet->mapAddressBook)
{
const CBitcoinAddress& address = item.first;
-
- AddressTableEntry::Type addressType;
- const std::string& strPurpose = item.second.purpose;
- if (strPurpose == "send") addressType = AddressTableEntry::Sending;
- else if (strPurpose == "receive") addressType = AddressTableEntry::Receiving;
- else if (strPurpose == "unknown") {
- bool fMine = IsMine(*wallet, address.Get());
- addressType = (fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending);
- }
- else continue; // "refund" addresses aren't shown, and change addresses aren't in mapAddressBook at all.
-
+ bool fMine = IsMine(*wallet, address.Get());
+ AddressTableEntry::Type addressType = translateTransactionType(
+ QString::fromStdString(item.second.purpose), fMine);
const std::string& strName = item.second.name;
cachedAddressTable.append(AddressTableEntry(addressType,
QString::fromStdString(strName),
@@ -80,10 +88,12 @@ public:
}
}
// qLowerBound() and qUpperBound() require our cachedAddressTable list to be sorted in asc order
+ // Even though the map is already sorted this re-sorting step is needed because the originating map
+ // is sorted by binary address, not by base58() address.
qSort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan());
}
- void updateEntry(const QString &address, const QString &label, bool isMine, int status)
+ void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
{
// Find address / label in model
QList<AddressTableEntry>::iterator lower = qLowerBound(
@@ -93,14 +103,14 @@ public:
int lowerIndex = (lower - cachedAddressTable.begin());
int upperIndex = (upper - cachedAddressTable.begin());
bool inModel = (lower != upper);
- AddressTableEntry::Type newEntryType = isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending;
+ AddressTableEntry::Type newEntryType = translateTransactionType(purpose, isMine);
switch(status)
{
case CT_NEW:
if(inModel)
{
- OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_NOW, but entry is already in model\n");
+ qDebug() << "AddressTablePriv::updateEntry : Warning: Got CT_NOW, but entry is already in model";
break;
}
parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
@@ -110,7 +120,7 @@ public:
case CT_UPDATED:
if(!inModel)
{
- OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_UPDATED, but entry is not in model\n");
+ qDebug() << "AddressTablePriv::updateEntry : Warning: Got CT_UPDATED, but entry is not in model";
break;
}
lower->type = newEntryType;
@@ -120,7 +130,7 @@ public:
case CT_DELETED:
if(!inModel)
{
- OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_DELETED, but entry is not in model\n");
+ qDebug() << "AddressTablePriv::updateEntry : Warning: Got CT_DELETED, but entry is not in model";
break;
}
parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
@@ -322,10 +332,11 @@ QModelIndex AddressTableModel::index(int row, int column, const QModelIndex &par
}
}
-void AddressTableModel::updateEntry(const QString &address, const QString &label, bool isMine, int status)
+void AddressTableModel::updateEntry(const QString &address,
+ const QString &label, bool isMine, const QString &purpose, int status)
{
// Update address book model from Bitcoin core
- priv->updateEntry(address, label, isMine, status);
+ priv->updateEntry(address, label, isMine, purpose, status);
}
QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address)
@@ -355,18 +366,21 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
else if(type == Receive)
{
// Generate a new address to associate with given label
- WalletModel::UnlockContext ctx(walletModel->requestUnlock());
- if(!ctx.isValid())
- {
- // Unlock wallet failed or was cancelled
- editStatus = WALLET_UNLOCK_FAILURE;
- return QString();
- }
CPubKey newKey;
- if(!wallet->GetKeyFromPool(newKey, true))
+ if(!wallet->GetKeyFromPool(newKey))
{
- editStatus = KEY_GENERATION_FAILURE;
- return QString();
+ WalletModel::UnlockContext ctx(walletModel->requestUnlock());
+ if(!ctx.isValid())
+ {
+ // Unlock wallet failed or was cancelled
+ editStatus = WALLET_UNLOCK_FAILURE;
+ return QString();
+ }
+ if(!wallet->GetKeyFromPool(newKey))
+ {
+ editStatus = KEY_GENERATION_FAILURE;
+ return QString();
+ }
}
strAddress = CBitcoinAddress(newKey.GetID()).ToString();
}
diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h
index 48baff5e54..6f532087fe 100644
--- a/src/qt/addresstablemodel.h
+++ b/src/qt/addresstablemodel.h
@@ -85,7 +85,7 @@ signals:
public slots:
/* Update address list from core.
*/
- void updateEntry(const QString &address, const QString &label, bool isMine, int status);
+ void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
friend class AddressTablePriv;
};
diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp
index f165c11cb1..2b7671f209 100644
--- a/src/qt/askpassphrasedialog.cpp
+++ b/src/qt/askpassphrasedialog.cpp
@@ -16,6 +16,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
fCapsLock(false)
{
ui->setupUi(this);
+
ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE);
ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE);
ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE);
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index e7cf440044..78693971da 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -62,7 +62,7 @@ static bool ThreadSafeMessageBox(const std::string& message, const std::string&
}
else
{
- printf("%s: %s\n", caption.c_str(), message.c_str());
+ LogPrintf("%s: %s\n", caption.c_str(), message.c_str());
fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
return false;
}
@@ -91,7 +91,7 @@ static void InitMessage(const std::string &message)
splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(55,55,55));
qApp->processEvents();
}
- printf("init message: %s\n", message.c_str());
+ LogPrintf("init message: %s\n", message.c_str());
}
/*
@@ -155,12 +155,15 @@ static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTrans
#if QT_VERSION < 0x050000
void DebugMessageHandler(QtMsgType type, const char * msg)
{
- OutputDebugStringF("%s\n", msg);
+ Q_UNUSED(type);
+ LogPrint("qt", "Bitcoin-Qt: %s\n", msg);
}
#else
void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg)
{
- OutputDebugStringF("%s\n", qPrintable(msg));
+ Q_UNUSED(type);
+ Q_UNUSED(context);
+ LogPrint("qt", "Bitcoin-Qt: %s\n", qPrintable(msg));
}
#endif
@@ -232,10 +235,16 @@ int main(int argc, char *argv[])
PaymentServer* paymentServer = new PaymentServer(&app);
// User language is set up: pick a data directory
- Intro::pickDataDirectory();
+ Intro::pickDataDirectory(TestNet());
// Install global event filter that makes sure that long tooltips can be word-wrapped
app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
+ // Install qDebug() message handler to route to debug.log
+#if QT_VERSION < 0x050000
+ qInstallMsgHandler(DebugMessageHandler);
+#else
+ qInstallMessageHandler(DebugMessageHandler);
+#endif
// ... now GUI settings:
OptionsModel optionsModel;
@@ -255,13 +264,6 @@ int main(int argc, char *argv[])
return 1;
}
- // Install qDebug() message handler to route to debug.log:
-#if QT_VERSION < 0x050000
- qInstallMsgHandler(DebugMessageHandler);
-#else
- qInstallMessageHandler(DebugMessageHandler);
-#endif
-
SplashScreen splash(QPixmap(), 0);
if (GetBoolArg("-splash", true) && !GetBoolArg("-min", false))
{
@@ -300,7 +302,8 @@ int main(int argc, char *argv[])
optionsModel.Upgrade(); // Must be done after AppInit2
PaymentServer::LoadRootCAs();
- paymentServer->initNetManager(optionsModel);
+ paymentServer->setOptionsModel(&optionsModel);
+ paymentServer->initNetManager();
if (splashref)
splash.finish(&window);
diff --git a/src/qt/bitcoinaddressvalidator.h b/src/qt/bitcoinaddressvalidator.h
index 2b6a59367d..b7f4dfee96 100644
--- a/src/qt/bitcoinaddressvalidator.h
+++ b/src/qt/bitcoinaddressvalidator.h
@@ -3,8 +3,8 @@
#include <QValidator>
-/** Base48 entry widget validator.
- Corrects near-miss characters and refuses characters that are no part of base48.
+/** Base58 entry widget validator.
+ Corrects near-miss characters and refuses characters that are not part of base58.
*/
class BitcoinAddressValidator : public QValidator
{
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index ad32c9ea68..5afd93957b 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -590,21 +590,28 @@ void BitcoinGUI::message(const QString &title, const QString &message, unsigned
int nMBoxIcon = QMessageBox::Information;
int nNotifyIcon = Notificator::Information;
- // Override title based on style
QString msgType;
- switch (style) {
- case CClientUIInterface::MSG_ERROR:
- msgType = tr("Error");
- break;
- case CClientUIInterface::MSG_WARNING:
- msgType = tr("Warning");
- break;
- case CClientUIInterface::MSG_INFORMATION:
- msgType = tr("Information");
- break;
- default:
- msgType = title; // Use supplied title
+
+ // Prefer supplied title over style based title
+ if (!title.isEmpty()) {
+ msgType = title;
}
+ else {
+ switch (style) {
+ case CClientUIInterface::MSG_ERROR:
+ msgType = tr("Error");
+ break;
+ case CClientUIInterface::MSG_WARNING:
+ msgType = tr("Warning");
+ break;
+ case CClientUIInterface::MSG_INFORMATION:
+ msgType = tr("Information");
+ break;
+ default:
+ break;
+ }
+ }
+ // Append title to "Bitcoin - "
if (!msgType.isEmpty())
strTitle += " - " + msgType;
@@ -625,7 +632,7 @@ void BitcoinGUI::message(const QString &title, const QString &message, unsigned
if (!(buttons = (QMessageBox::StandardButton)(style & CClientUIInterface::BTN_MASK)))
buttons = QMessageBox::Ok;
- QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons);
+ QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons, this);
int r = mBox.exec();
if (ret != NULL)
*ret = r == QMessageBox::Ok;
@@ -670,9 +677,12 @@ void BitcoinGUI::closeEvent(QCloseEvent *event)
void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee)
{
+ if (!clientModel || !clientModel->getOptionsModel())
+ return;
+
QString strMessage = tr("This transaction is over the size limit. You can still send it for a fee of %1, "
"which goes to the nodes that process your transaction and helps to support the network. "
- "Do you want to pay the fee?").arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nFeeRequired));
+ "Do you want to pay the fee?").arg(BitcoinUnits::formatWithUnit(clientModel->getOptionsModel()->getDisplayUnit(), nFeeRequired));
QMessageBox::StandardButton retval = QMessageBox::question(
this, tr("Confirm transaction fee"), strMessage,
QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes);
@@ -741,13 +751,9 @@ void BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient)
walletFrame->handlePaymentRequest(recipient);
}
-void BitcoinGUI::showPaymentACK(QString msg)
+void BitcoinGUI::showPaymentACK(const QString& msg)
{
-#if QT_VERSION < 0x050000
- message(tr("Payment acknowledged"), Qt::escape(msg), CClientUIInterface::MODAL);
-#else
- message(tr("Payment acknowledged"), msg.toHtmlEscaped(), CClientUIInterface::MODAL);
-#endif
+ message(tr("Payment acknowledged"), GUIUtil::HtmlEscape(msg), CClientUIInterface::MODAL);
}
void BitcoinGUI::setEncryptionStatus(int status)
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index fc25e867fc..e2dd5dc6bc 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -154,7 +154,7 @@ public slots:
void askFee(qint64 nFeeRequired, bool *payFee);
void handlePaymentRequest(const SendCoinsRecipient& recipient);
- void showPaymentACK(QString msg);
+ void showPaymentACK(const QString& msg);
/** Show incoming transaction notification for new transactions. */
void incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address);
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 5cf4dd8111..b33f534f7c 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -13,6 +13,7 @@
#include <QDateTime>
#include <QTimer>
+#include <QDebug>
static const int64 nClientStartupTime = GetTime();
@@ -23,9 +24,8 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
numBlocksAtStartup(-1), pollTimer(0)
{
pollTimer = new QTimer(this);
- pollTimer->setInterval(MODEL_UPDATE_DELAY);
- pollTimer->start();
connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
+ pollTimer->start(MODEL_UPDATE_DELAY);
subscribeToCoreSignals();
}
@@ -180,14 +180,14 @@ static void NotifyBlocksChanged(ClientModel *clientmodel)
static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
{
- // Too noisy: OutputDebugStringF("NotifyNumConnectionsChanged %i\n", newNumConnections);
+ // Too noisy: qDebug() << "NotifyNumConnectionsChanged : " + QString::number(newNumConnections);
QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
Q_ARG(int, newNumConnections));
}
static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status)
{
- OutputDebugStringF("NotifyAlertChanged %s status=%i\n", hash.GetHex().c_str(), status);
+ qDebug() << "NotifyAlertChanged : " + QString::fromStdString(hash.GetHex()) + " status=" + QString::number(status);
QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(hash.GetHex())),
Q_ARG(int, status));
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index f9d491aa50..15074300b4 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -60,8 +60,8 @@ private:
int cachedNumBlocks;
int cachedNumBlocksOfPeers;
- bool cachedReindexing;
- bool cachedImporting;
+ bool cachedReindexing;
+ bool cachedImporting;
int numBlocksAtStartup;
diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp
index 8a50bbab3f..ad8e0d618a 100644
--- a/src/qt/csvmodelwriter.cpp
+++ b/src/qt/csvmodelwriter.cpp
@@ -85,4 +85,3 @@ bool CSVModelWriter::write()
return file.error() == QFile::NoError;
}
-
diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui
index bb53021cfd..1e4335c645 100644
--- a/src/qt/forms/optionsdialog.ui
+++ b/src/qt/forms/optionsdialog.ui
@@ -461,7 +461,7 @@
<customwidgets>
<customwidget>
<class>BitcoinAmountField</class>
- <extends>QSpinBox</extends>
+ <extends>QLineEdit</extends>
<header>bitcoinamountfield.h</header>
</customwidget>
<customwidget>
diff --git a/src/qt/forms/qrcodedialog.ui b/src/qt/forms/qrcodedialog.ui
index 52e9db3762..1cec9066f8 100644
--- a/src/qt/forms/qrcodedialog.ui
+++ b/src/qt/forms/qrcodedialog.ui
@@ -186,7 +186,7 @@
<customwidgets>
<customwidget>
<class>BitcoinAmountField</class>
- <extends>QSpinBox</extends>
+ <extends>QLineEdit</extends>
<header>bitcoinamountfield.h</header>
</customwidget>
</customwidgets>
diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui
index 6e17565ab0..2a00fc5455 100644
--- a/src/qt/forms/sendcoinsdialog.ui
+++ b/src/qt/forms/sendcoinsdialog.ui
@@ -28,7 +28,7 @@
<height>165</height>
</rect>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
+ <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
<property name="margin">
<number>0</number>
</property>
diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui
index a2ef9a0a38..2c1cec600c 100644
--- a/src/qt/forms/sendcoinsentry.ui
+++ b/src/qt/forms/sendcoinsentry.ui
@@ -10,19 +10,13 @@
<height>150</height>
</rect>
</property>
- <property name="windowTitle">
- <string>StackedWidget</string>
- </property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="currentIndex">
- <number>1</number>
+ <number>0</number>
</property>
<widget class="QFrame" name="SendCoinsInsecure">
- <property name="windowTitle">
- <string>Form</string>
- </property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
@@ -34,7 +28,7 @@
<number>12</number>
</property>
<item row="5" column="0">
- <widget class="QLabel" name="label">
+ <widget class="QLabel" name="amountLabel">
<property name="text">
<string>A&amp;mount:</string>
</property>
@@ -47,7 +41,7 @@
</widget>
</item>
<item row="3" column="0">
- <widget class="QLabel" name="label_2">
+ <widget class="QLabel" name="payToLabel">
<property name="text">
<string>Pay &amp;To:</string>
</property>
@@ -63,7 +57,7 @@
<widget class="BitcoinAmountField" name="payAmount"/>
</item>
<item row="4" column="0">
- <widget class="QLabel" name="label_4">
+ <widget class="QLabel" name="labellLabel">
<property name="text">
<string>&amp;Label:</string>
</property>
@@ -592,9 +586,6 @@
</disabled>
</palette>
</property>
- <property name="windowTitle">
- <string>SecureSend</string>
- </property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
@@ -609,7 +600,7 @@
<number>12</number>
</property>
<item row="4" column="0">
- <widget class="QLabel" name="label_s4">
+ <widget class="QLabel" name="memoLabel_s">
<property name="text">
<string>Memo:</string>
</property>
@@ -622,7 +613,7 @@
</widget>
</item>
<item row="5" column="0">
- <widget class="QLabel" name="label_s1">
+ <widget class="QLabel" name="amountLabel_s">
<property name="text">
<string>A&amp;mount:</string>
</property>
@@ -635,7 +626,7 @@
</widget>
</item>
<item row="3" column="0">
- <widget class="QLabel" name="label_s2">
+ <widget class="QLabel" name="payToLabel_s">
<property name="text">
<string>Pay &amp;To:</string>
</property>
@@ -667,14 +658,17 @@
</property>
<item>
<widget class="QLabel" name="payTo_s">
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
</widget>
</item>
</layout>
</item>
<item row="4" column="2">
- <widget class="QLabel" name="memo_s">
- <property name="text">
- <string>message from merchant</string>
+ <widget class="QLabel" name="memoTextLabel_s">
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
</property>
</widget>
</item>
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index 99db141c94..4a02ff89e7 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -142,7 +142,7 @@ QString Intro::getDefaultDataDirectory()
return QString::fromStdString(GetDefaultDataDir().string());
}
-void Intro::pickDataDirectory()
+void Intro::pickDataDirectory(bool fIsTestnet)
{
namespace fs = boost::filesystem;;
QSettings settings;
@@ -160,6 +160,11 @@ void Intro::pickDataDirectory()
/* If current default data directory does not exist, let the user choose one */
Intro intro;
intro.setDataDirectory(dataDir);
+ if (!fIsTestnet)
+ intro.setWindowIcon(QIcon(":icons/bitcoin"));
+ else
+ intro.setWindowIcon(QIcon(":icons/bitcoin_testnet"));
+
while(true)
{
if(!intro.exec())
diff --git a/src/qt/intro.h b/src/qt/intro.h
index 788799b7b0..8b09847abd 100644
--- a/src/qt/intro.h
+++ b/src/qt/intro.h
@@ -31,7 +31,7 @@ public:
* @note do NOT call global GetDataDir() before calling this function, this
* will cause the wrong path to be cached.
*/
- static void pickDataDirectory();
+ static void pickDataDirectory(bool fIsTestnet);
/**
* Determine default data directory for operating system.
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index 7d419b6bd9..4d1a8574d0 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -67,7 +67,7 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation>&amp;New Address</translation>
</message>
<message>
- <location filename="../addressbookpage.cpp" line="+63"/>
+ <location filename="../addressbookpage.cpp" line="+67"/>
<source>These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you.</source>
<translation>These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you.</translation>
</message>
@@ -165,7 +165,7 @@ This product includes software developed by the OpenSSL Project for use in the O
<context>
<name>AddressTableModel</name>
<message>
- <location filename="../addresstablemodel.cpp" line="+144"/>
+ <location filename="../addresstablemodel.cpp" line="+164"/>
<source>Label</source>
<translation>Label</translation>
</message>
@@ -203,7 +203,7 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation>Repeat new passphrase</translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="+33"/>
+ <location filename="../askpassphrasedialog.cpp" line="+34"/>
<source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;10 or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
<translation>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;10 or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</translation>
</message>
@@ -324,7 +324,7 @@ This product includes software developed by the OpenSSL Project for use in the O
<context>
<name>BitcoinGUI</name>
<message>
- <location filename="../bitcoingui.cpp" line="+254"/>
+ <location filename="../bitcoingui.cpp" line="+255"/>
<source>Sign &amp;message...</source>
<translation>Sign &amp;message...</translation>
</message>
@@ -623,12 +623,12 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation>Information</translation>
</message>
<message>
- <location line="+70"/>
+ <location line="+73"/>
<source>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</source>
<translation>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</translation>
</message>
<message>
- <location line="-140"/>
+ <location line="-143"/>
<source>Up to date</source>
<translation>Up to date</translation>
</message>
@@ -638,7 +638,7 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation>Catching up...</translation>
</message>
<message>
- <location line="+113"/>
+ <location line="+116"/>
<source>Confirm transaction fee</source>
<translation>Confirm transaction fee</translation>
</message>
@@ -666,18 +666,22 @@ Address: %4
</translation>
</message>
<message>
- <location line="+33"/>
- <location line="+23"/>
+ <location line="+34"/>
<source>URI handling</source>
<translation>URI handling</translation>
</message>
<message>
- <location line="-23"/>
- <location line="+23"/>
+ <location line="+0"/>
<source>URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
<translation>URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</translation>
</message>
<message>
+ <location line="+27"/>
+ <location line="+2"/>
+ <source>Payment acknowledged</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location line="+17"/>
<source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
<translation>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</translation>
@@ -696,7 +700,7 @@ Address: %4
<context>
<name>ClientModel</name>
<message>
- <location filename="../clientmodel.cpp" line="+105"/>
+ <location filename="../clientmodel.cpp" line="+106"/>
<source>Network Alert</source>
<translation>Network Alert</translation>
</message>
@@ -800,7 +804,7 @@ Address: %4
<context>
<name>GUIUtil::HelpMessageBox</name>
<message>
- <location filename="../guiutil.cpp" line="+517"/>
+ <location filename="../guiutil.cpp" line="+525"/>
<location line="+13"/>
<source>Bitcoin-Qt</source>
<translation>Bitcoin-Qt</translation>
@@ -879,7 +883,7 @@ Address: %4
<translation>Use a custom data directory:</translation>
</message>
<message>
- <location filename="../intro.cpp" line="+100"/>
+ <location filename="../intro.cpp" line="+105"/>
<source>Error</source>
<translation>Error</translation>
</message>
@@ -1067,7 +1071,7 @@ Address: %4
<translation>&amp;Apply</translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="+54"/>
+ <location filename="../optionsdialog.cpp" line="+58"/>
<source>default</source>
<translation>default</translation>
</message>
@@ -1177,29 +1181,68 @@ Address: %4
<context>
<name>PaymentServer</name>
<message>
- <location filename="../paymentserver.cpp" line="+108"/>
- <source>Cannot start bitcoin: click-to-pay handler</source>
- <translation>Cannot start bitcoin: click-to-pay handler</translation>
+ <location filename="../paymentserver.cpp" line="+450"/>
+ <location line="+41"/>
+ <source>Payment request error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Insecure requests to custom payment scripts unsupported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+38"/>
+ <source>Refund from</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+46"/>
+ <location line="+28"/>
+ <location line="+17"/>
+ <source>Network request error</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
- <location filename="../bitcoin.cpp" line="+92"/>
+ <location filename="../bitcoin.cpp" line="+111"/>
+ <location line="+5"/>
<location filename="../intro.cpp" line="-32"/>
<source>Bitcoin</source>
<translation>Bitcoin</translation>
</message>
<message>
- <location line="+1"/>
+ <location line="-4"/>
<source>Error: Specified data directory &quot;%1&quot; does not exist.</source>
<translation>Error: Specified data directory &quot;%1&quot; does not exist.</translation>
</message>
<message>
+ <location line="+4"/>
+ <source>Error: Invalid combination of -regtest and -testnet.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location filename="../intro.cpp" line="+1"/>
<source>Error: Specified data directory &quot;%1&quot; can not be created.</source>
<translation>Error: Specified data directory &quot;%1&quot; can not be created.</translation>
</message>
+ <message>
+ <location filename="../paymentserver.cpp" line="-175"/>
+ <source>Requested payment amount (%1) too small</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+126"/>
+ <source>Error communicating with %1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Bad response from server %1</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QRCodeDialog</name>
@@ -1410,13 +1453,15 @@ Address: %4
<name>SendCoinsDialog</name>
<message>
<location filename="../forms/sendcoinsdialog.ui" line="+14"/>
- <location filename="../sendcoinsdialog.cpp" line="+128"/>
+ <location filename="../sendcoinsdialog.cpp" line="+138"/>
<location line="+5"/>
<location line="+5"/>
<location line="+5"/>
<location line="+6"/>
<location line="+5"/>
- <location line="+5"/>
+ <location line="+50"/>
+ <location line="+145"/>
+ <location line="+9"/>
<source>Send Coins</source>
<translation>Send Coins</translation>
</message>
@@ -1461,25 +1506,19 @@ Address: %4
<translation>S&amp;end</translation>
</message>
<message>
- <location filename="../sendcoinsdialog.cpp" line="-62"/>
- <location line="+2"/>
- <source>&lt;b&gt;%1&lt;/b&gt; to %2 (%3)</source>
- <translation>&lt;b&gt;%1&lt;/b&gt; to %2 (%3)</translation>
- </message>
- <message>
- <location line="+6"/>
+ <location filename="../sendcoinsdialog.cpp" line="-170"/>
<source>Confirm send coins</source>
<translation>Confirm send coins</translation>
</message>
<message>
- <location line="+1"/>
- <source>Are you sure you want to send %1?</source>
- <translation>Are you sure you want to send %1?</translation>
+ <location line="-97"/>
+ <source>to</source>
+ <translation type="unfinished">to</translation>
</message>
<message>
- <location line="+0"/>
- <source> and </source>
- <translation> and </translation>
+ <location line="+15"/>
+ <source>&lt;b&gt;%1&lt;/b&gt; to %2</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<location line="+23"/>
@@ -1512,36 +1551,63 @@ Address: %4
<translation>Error: Transaction creation failed!</translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+15"/>
+ <source>Are you sure you want to send?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>added as transaction fee</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Total Amount %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+20"/>
<source>Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
<translation>Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</translation>
</message>
+ <message>
+ <location line="+145"/>
+ <source>Payment request expired</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Invalid payment address %1</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>SendCoinsEntry</name>
<message>
- <location filename="../forms/sendcoinsentry.ui" line="+14"/>
+ <location filename="../forms/sendcoinsentry.ui" line="+24"/>
<source>Form</source>
<translation>Form</translation>
</message>
<message>
<location line="+15"/>
+ <location line="+588"/>
<source>A&amp;mount:</source>
<translation>A&amp;mount:</translation>
</message>
<message>
- <location line="+13"/>
+ <location line="-575"/>
+ <location line="+588"/>
<source>Pay &amp;To:</source>
<translation>Pay &amp;To:</translation>
</message>
<message>
- <location line="+34"/>
+ <location line="-554"/>
<source>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
<translation>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
</message>
<message>
<location line="+60"/>
- <location filename="../sendcoinsentry.cpp" line="+26"/>
+ <location filename="../sendcoinsentry.cpp" line="+28"/>
<source>Enter a label for this address to add it to your address book</source>
<translation>Enter a label for this address to add it to your address book</translation>
</message>
@@ -1551,7 +1617,12 @@ Address: %4
<translation>&amp;Label:</translation>
</message>
<message>
- <location line="+28"/>
+ <location line="-54"/>
+ <source>StackedWidget</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+82"/>
<source>Choose address from address book</source>
<translation>Choose address from address book</translation>
</message>
@@ -1576,6 +1647,21 @@ Address: %4
<translation>Remove this recipient</translation>
</message>
<message>
+ <location line="+466"/>
+ <source>SecureSend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Memo:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+63"/>
+ <source>message from merchant</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location filename="../sendcoinsentry.cpp" line="+1"/>
<source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
<translation>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
@@ -1708,7 +1794,7 @@ Address: %4
<translation>Enter Bitcoin signature</translation>
</message>
<message>
- <location line="+82"/>
+ <location line="+85"/>
<location line="+81"/>
<source>The entered address is invalid.</source>
<translation>The entered address is invalid.</translation>
@@ -1777,7 +1863,7 @@ Address: %4
<context>
<name>SplashScreen</name>
<message>
- <location filename="../splashscreen.cpp" line="+22"/>
+ <location filename="../splashscreen.cpp" line="+23"/>
<source>The Bitcoin developers</source>
<translation>The Bitcoin developers</translation>
</message>
@@ -1790,7 +1876,7 @@ Address: %4
<context>
<name>TransactionDesc</name>
<message>
- <location filename="../transactiondesc.cpp" line="+20"/>
+ <location filename="../transactiondesc.cpp" line="+22"/>
<source>Open until %1</source>
<translation>Open until %1</translation>
</message>
@@ -1866,12 +1952,12 @@ Address: %4
<location line="+12"/>
<location line="+45"/>
<location line="+17"/>
- <location line="+30"/>
+ <location line="+45"/>
<source>Credit</source>
<translation>Credit</translation>
</message>
<message numerus="yes">
- <location line="-102"/>
+ <location line="-117"/>
<source>matures in %n more block(s)</source>
<translation>
<numerusform>matures in %n more block</numerusform>
@@ -1887,12 +1973,12 @@ Address: %4
<location line="+44"/>
<location line="+8"/>
<location line="+15"/>
- <location line="+30"/>
+ <location line="+45"/>
<source>Debit</source>
<translation>Debit</translation>
</message>
<message>
- <location line="-39"/>
+ <location line="-54"/>
<source>Transaction fee</source>
<translation>Transaction fee</translation>
</message>
@@ -1917,7 +2003,12 @@ Address: %4
<translation>Transaction ID</translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+13"/>
+ <source>Merchant</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
<source>Generated coins must mature 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to &quot;not accepted&quot; and it won&apos;t be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
<translation>Generated coins must mature 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to &quot;not accepted&quot; and it won&apos;t be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</translation>
</message>
@@ -1952,7 +2043,7 @@ Address: %4
<translation>false</translation>
</message>
<message>
- <location line="-209"/>
+ <location line="-224"/>
<source>, has not been successfully broadcast yet</source>
<translation>, has not been successfully broadcast yet</translation>
</message>
@@ -1986,7 +2077,7 @@ Address: %4
<context>
<name>TransactionTableModel</name>
<message>
- <location filename="../transactiontablemodel.cpp" line="+225"/>
+ <location filename="../transactiontablemodel.cpp" line="+227"/>
<source>Date</source>
<translation>Date</translation>
</message>
@@ -2279,7 +2370,7 @@ Address: %4
<context>
<name>WalletModel</name>
<message>
- <location filename="../walletmodel.cpp" line="+193"/>
+ <location filename="../walletmodel.cpp" line="+218"/>
<source>Send Coins</source>
<translation>Send Coins</translation>
</message>
@@ -2297,7 +2388,7 @@ Address: %4
<translation>Export the data in the current tab to a file</translation>
</message>
<message>
- <location line="+197"/>
+ <location line="+198"/>
<source>Backup Wallet</source>
<translation>Backup Wallet</translation>
</message>
diff --git a/src/qt/notificator.h b/src/qt/notificator.h
index d1fe37fea5..6c9a46bcf7 100644
--- a/src/qt/notificator.h
+++ b/src/qt/notificator.h
@@ -1,6 +1,10 @@
#ifndef NOTIFICATOR_H
#define NOTIFICATOR_H
+#if defined(HAVE_CONFIG_H)
+#include "bitcoin-config.h"
+#endif
+
#include <QObject>
#include <QIcon>
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index b2451aea31..7ccda6cdd4 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -1,3 +1,7 @@
+#if defined(HAVE_CONFIG_H)
+#include "bitcoin-config.h"
+#endif
+
#include "optionsdialog.h"
#include "ui_optionsdialog.h"
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index d93a60e1bc..95efc58320 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -1,3 +1,7 @@
+#if defined(HAVE_CONFIG_H)
+#include "bitcoin-config.h"
+#endif
+
#include "optionsmodel.h"
#include "bitcoinunits.h"
diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp
index 289ddabb92..f6a898ff7c 100644
--- a/src/qt/paymentrequestplus.cpp
+++ b/src/qt/paymentrequestplus.cpp
@@ -24,18 +24,18 @@ bool PaymentRequestPlus::parse(const QByteArray& data)
{
bool parseOK = paymentRequest.ParseFromArray(data.data(), data.size());
if (!parseOK) {
- qDebug() << "Error parsing payment request";
+ qDebug() << "PaymentRequestPlus::parse : Error parsing payment request";
return false;
}
if (paymentRequest.payment_details_version() > 1) {
- qDebug() << "Received up-version payment details, version=" << paymentRequest.payment_details_version();
+ qDebug() << "PaymentRequestPlus::parse : Received up-version payment details, version=" << paymentRequest.payment_details_version();
return false;
}
parseOK = details.ParseFromString(paymentRequest.serialized_payment_details());
if (!parseOK)
{
- qDebug() << "Error parsing payment details";
+ qDebug() << "PaymentRequestPlus::parse : Error parsing payment details";
paymentRequest.Clear();
return false;
}
@@ -75,17 +75,18 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
digestAlgorithm = EVP_sha1();
}
else if (paymentRequest.pki_type() == "none") {
- if (fDebug) qDebug() << "PaymentRequest: pki_type == none";
+ if (fDebug)
+ qDebug() << "PaymentRequestPlus::getMerchant : Payment request: pki_type == none";
return false;
}
else {
- qDebug() << "PaymentRequest: unknown pki_type " << paymentRequest.pki_type().c_str();
+ qDebug() << "PaymentRequestPlus::getMerchant : Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type());
return false;
}
payments::X509Certificates certChain;
if (!certChain.ParseFromString(paymentRequest.pki_data())) {
- qDebug() << "PaymentRequest: error parsing pki_data";
+ qDebug() << "PaymentRequestPlus::getMerchant : Payment request: error parsing pki_data";
return false;
}
@@ -95,12 +96,12 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
QByteArray certData(certChain.certificate(i).data(), certChain.certificate(i).size());
QSslCertificate qCert(certData, QSsl::Der);
if (currentTime < qCert.effectiveDate() || currentTime > qCert.expiryDate()) {
- qDebug() << "PaymentRequest: certificate expired or not yet active: " << qCert;
+ qDebug() << "PaymentRequestPlus::getMerchant : Payment request: certificate expired or not yet active: " << qCert;
return false;
}
#if QT_VERSION >= 0x050000
if (qCert.isBlacklisted()) {
- qDebug() << "PaymentRequest: certificate blacklisted: " << qCert;
+ qDebug() << "PaymentRequestPlus::getMerchant : Payment request: certificate blacklisted: " << qCert;
return false;
}
#endif
@@ -110,7 +111,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
certs.push_back(cert);
}
if (certs.empty()) {
- qDebug() << "PaymentRequest: empty certificate chain";
+ qDebug() << "PaymentRequestPlus::getMerchant : Payment request: empty certificate chain";
return false;
}
@@ -126,7 +127,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
// load the signing cert into it and verify.
X509_STORE_CTX *store_ctx = X509_STORE_CTX_new();
if (!store_ctx) {
- qDebug() << "PaymentRequest: error creating X509_STORE_CTX";
+ qDebug() << "PaymentRequestPlus::getMerchant : Payment request: error creating X509_STORE_CTX";
return false;
}
@@ -151,7 +152,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
// Valid cert; check signature:
payments::PaymentRequest rcopy(paymentRequest); // Copy
rcopy.set_signature(std::string(""));
- std::string data_to_verify; // Everything but the signature
+ std::string data_to_verify; // Everything but the signature
rcopy.SerializeToString(&data_to_verify);
EVP_MD_CTX ctx;
@@ -171,14 +172,14 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
merchant = website;
}
else {
- throw SSLVerifyError("Bad certificate, missing common name");
+ throw SSLVerifyError("Bad certificate, missing common name.");
}
// TODO: detect EV certificates and set merchant = business name instead of unfriendly NID_commonName ?
}
catch (SSLVerifyError& err)
{
fResult = false;
- qDebug() << "PaymentRequestPlus::getMerchant SSL err: " << err.what();
+ qDebug() << "PaymentRequestPlus::getMerchant : SSL error: " << err.what();
}
if (website)
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index a9f71315a9..72f75b42e6 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -44,10 +44,10 @@
#include "wallet.h"
#include "walletmodel.h"
-using namespace boost;
-
const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds
const QString BITCOIN_IPC_PREFIX("bitcoin:");
+const char* BITCOIN_REQUEST_MIMETYPE = "application/bitcoin-paymentrequest";
+const char* BITCOIN_PAYMENTACK_MIMETYPE = "application/bitcoin-paymentack";
X509_STORE* PaymentServer::certStore = NULL;
void PaymentServer::freeCertStore()
@@ -71,14 +71,14 @@ static QString ipcServerName()
// Append a simple hash of the datadir
// Note that GetDataDir(true) returns a different path
// for -testnet versus main net
- QString ddir(GetDataDir(true).string().c_str());
+ QString ddir(QString::fromStdString(GetDataDir(true).string()));
name.append(QString::number(qHash(ddir)));
return name;
}
//
-// We store payment URLs and requests received before
+// We store payment URIs and requests received before
// the main GUI window is up and ready to ask the user
// to send payment.
@@ -87,12 +87,12 @@ static QList<QString> savedPaymentRequests;
static void ReportInvalidCertificate(const QSslCertificate& cert)
{
if (fDebug) {
- qDebug() << "Invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName);
+ qDebug() << "ReportInvalidCertificate : Payment server found an invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName);
}
}
//
-// Load openSSL's list of root certificate authorities
+// Load OpenSSL's list of root certificate authorities
//
void PaymentServer::LoadRootCAs(X509_STORE* _store)
{
@@ -147,7 +147,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
const unsigned char *data = (const unsigned char *)certData.data();
X509* x509 = d2i_X509(0, &data, certData.size());
- if (x509 && X509_STORE_add_cert( PaymentServer::certStore, x509))
+ if (x509 && X509_STORE_add_cert(PaymentServer::certStore, x509))
{
// Note: X509_STORE_free will free the X509* objects when
// the PaymentServer is destroyed
@@ -160,7 +160,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
}
}
if (fDebug)
- qDebug() << "PaymentServer: loaded " << nRootCerts << " root certificates";
+ qDebug() << "PaymentServer::LoadRootCAs : Loaded " << nRootCerts << " root certificates";
// Project for another day:
// Fetch certificate revocation lists, and add them to certStore.
@@ -219,7 +219,7 @@ bool PaymentServer::ipcSendCommandLine(int argc, char* argv[])
}
else
{
- qDebug() << "Payment request file does not exist: " << argv[i];
+ qDebug() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << argv[i];
// Printing to debug.log is about the best we can do here, the
// GUI hasn't started yet so we can't pop up a message box.
}
@@ -248,8 +248,7 @@ bool PaymentServer::ipcSendCommandLine(int argc, char* argv[])
return fResult;
}
-PaymentServer::PaymentServer(QObject* parent,
- bool startLocalServer) : QObject(parent), saveURIs(true)
+PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : QObject(parent), saveURIs(true)
{
// Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
@@ -269,7 +268,7 @@ PaymentServer::PaymentServer(QObject* parent,
uriServer = new QLocalServer(this);
if (!uriServer->listen(name))
- qDebug() << "Cannot start bitcoin: click-to-pay handler";
+ qDebug() << "PaymentServer::PaymentServer : Cannot start bitcoin: click-to-pay handler";
else
connect(uriServer, SIGNAL(newConnection()), this, SLOT(handleURIConnection()));
}
@@ -284,12 +283,12 @@ PaymentServer::~PaymentServer()
}
//
-// OSX-specific way of handling bitcoin uris and
+// OSX-specific way of handling bitcoin: URIs and
// PaymentRequest mime types
//
bool PaymentServer::eventFilter(QObject *, QEvent *event)
{
- // clicking on bitcoin: URLs creates FileOpen events on the Mac:
+ // clicking on bitcoin: URIs creates FileOpen events on the Mac:
if (event->type() == QEvent::FileOpen)
{
QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event);
@@ -303,18 +302,20 @@ bool PaymentServer::eventFilter(QObject *, QEvent *event)
return false;
}
-void PaymentServer::initNetManager(const OptionsModel& options)
+void PaymentServer::initNetManager()
{
+ if (!optionsModel)
+ return;
if (netManager != NULL)
delete netManager;
// netManager is used to fetch paymentrequests given in bitcoin: URI's
netManager = new QNetworkAccessManager(this);
- // Use proxy settings from options:
+ // Use proxy settings from optionsModel:
QString proxyIP;
quint16 proxyPort;
- if (options.getProxySettings(proxyIP, proxyPort))
+ if (optionsModel->getProxySettings(proxyIP, proxyPort))
{
QNetworkProxy proxy;
proxy.setType(QNetworkProxy::Socks5Proxy);
@@ -352,22 +353,23 @@ void PaymentServer::handleURIOrFile(const QString& s)
if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin:
{
#if QT_VERSION >= 0x050000
- QUrlQuery url((QUrl(s)));
+ QUrlQuery uri((QUrl(s)));
#else
- QUrl url(s);
+ QUrl uri(s);
#endif
- if (url.hasQueryItem("request"))
+ if (uri.hasQueryItem("request"))
{
- QByteArray temp; temp.append(url.queryItemValue("request"));
+ QByteArray temp; temp.append(uri.queryItemValue("request"));
QString decoded = QUrl::fromPercentEncoding(temp);
QUrl fetchUrl(decoded, QUrl::StrictMode);
- if (fDebug) qDebug() << "PaymentServer::fetchRequest " << fetchUrl;
+ if (fDebug)
+ qDebug() << "PaymentServer::handleURIOrFile : fetchRequest(" << fetchUrl << ")";
if (fetchUrl.isValid())
fetchRequest(fetchUrl);
else
- qDebug() << "PaymentServer: invalid url: " << fetchUrl;
+ qDebug() << "PaymentServer::handleURIOrFile : Invalid url: " << fetchUrl;
return;
}
@@ -416,13 +418,13 @@ bool PaymentServer::readPaymentRequest(const QString& filename, PaymentRequestPl
QFile f(filename);
if (!f.open(QIODevice::ReadOnly))
{
- qDebug() << "PaymentServer::readPaymentRequest fail to open " << filename;
+ qDebug() << "PaymentServer::readPaymentRequest : Failed to open " << filename;
return false;
}
if (f.size() > MAX_PAYMENT_REQUEST_SIZE)
{
- qDebug() << "PaymentServer::readPaymentRequest " << filename << " too large";
+ qDebug() << "PaymentServer::readPaymentRequest : " << filename << " too large";
return false;
}
@@ -431,18 +433,20 @@ bool PaymentServer::readPaymentRequest(const QString& filename, PaymentRequestPl
return request.parse(data);
}
-bool
-PaymentServer::processPaymentRequest(PaymentRequestPlus& request,
- QList<SendCoinsRecipient>& recipients)
+bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, QList<SendCoinsRecipient>& recipients)
{
+ if (!optionsModel)
+ return false;
+
QList<std::pair<CScript,qint64> > sendingTos = request.getPayTo();
qint64 totalAmount = 0;
foreach(const PAIRTYPE(CScript, qint64)& sendingTo, sendingTos) {
CTxOut txOut(sendingTo.second, sendingTo.first);
if (txOut.IsDust(CTransaction::nMinRelayTxFee)) {
QString message = QObject::tr("Requested payment amount (%1) too small")
- .arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, sendingTo.second));
- qDebug() << message;
+ .arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second));
+
+ qDebug() << "PaymentServer::processPaymentRequest : " << message;
emit reportError(tr("Payment request error"), message, CClientUIInterface::MODAL);
return false;
}
@@ -455,7 +459,8 @@ PaymentServer::processPaymentRequest(PaymentRequestPlus& request,
if (request.getMerchant(PaymentServer::certStore, recipients[0].authenticatedMerchant)) {
recipients[0].paymentRequest = request;
recipients[0].amount = totalAmount;
- if (fDebug) qDebug() << "PaymentRequest from " << recipients[0].authenticatedMerchant;
+ if (fDebug)
+ qDebug() << "PaymentServer::processPaymentRequest : Payment request from " << recipients[0].authenticatedMerchant;
}
else {
recipients.clear();
@@ -476,13 +481,14 @@ PaymentServer::processPaymentRequest(PaymentRequestPlus& request,
if (i == 0) // Tie request to first pay-to, we don't want multiple ACKs
recipients[i].paymentRequest = request;
recipients[i].address = QString::fromStdString(CBitcoinAddress(dest).ToString());
- if (fDebug) qDebug() << "PaymentRequest, insecure " << recipients[i].address;
+ if (fDebug)
+ qDebug() << "PaymentServer::processPaymentRequest : Payment request, insecure " << recipients[i].address;
}
else {
// Insecure payments to custom bitcoin addresses are not supported
// (there is no good way to tell the user where they are paying in a way
// they'd have a chance of understanding).
- emit reportError(tr("Payment request error"),
+ emit reportError(tr("Payment request error"),
tr("Insecure requests to custom payment scripts unsupported"),
CClientUIInterface::MODAL);
return false;
@@ -493,18 +499,17 @@ PaymentServer::processPaymentRequest(PaymentRequestPlus& request,
return true;
}
-void
-PaymentServer::fetchRequest(const QUrl& url)
+void PaymentServer::fetchRequest(const QUrl& url)
{
QNetworkRequest netRequest;
netRequest.setAttribute(QNetworkRequest::User, "PaymentRequest");
netRequest.setUrl(url);
netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
+ netRequest.setRawHeader("Accept", BITCOIN_REQUEST_MIMETYPE);
netManager->get(netRequest);
}
-void
-PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction)
+void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction)
{
const payments::PaymentDetails& details = recipient.paymentRequest.getDetails();
if (!details.has_payment_url())
@@ -515,6 +520,7 @@ PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QB
netRequest.setUrl(QString::fromStdString(details.payment_url()));
netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/bitcoin-payment");
netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
+ netRequest.setRawHeader("Accept", BITCOIN_PAYMENTACK_MIMETYPE);
payments::Payment payment;
payment.set_merchant_data(details.merchant_data());
@@ -531,7 +537,7 @@ PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QB
}
else {
CPubKey newKey;
- if (wallet->GetKeyFromPool(newKey, false)) {
+ if (wallet->GetKeyFromPool(newKey)) {
CKeyID keyID = newKey.GetID();
wallet->SetAddressBook(keyID, strAccount, "refund");
@@ -542,7 +548,7 @@ PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QB
else {
// This should never happen, because sending coins should have just unlocked the wallet
// and refilled the keypool
- qDebug() << "Error getting refund key, refund_to not set";
+ qDebug() << "PaymentServer::fetchPaymentACK : Error getting refund key, refund_to not set";
}
}
@@ -554,12 +560,11 @@ PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QB
}
else {
// This should never happen, either:
- qDebug() << "Error serializing payment message";
+ qDebug() << "PaymentServer::fetchPaymentACK : Error serializing payment message";
}
}
-void
-PaymentServer::netRequestFinished(QNetworkReply* reply)
+void PaymentServer::netRequestFinished(QNetworkReply* reply)
{
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError)
@@ -567,7 +572,7 @@ PaymentServer::netRequestFinished(QNetworkReply* reply)
QString message = QObject::tr("Error communicating with %1: %2")
.arg(reply->request().url().toString())
.arg(reply->errorString());
- qDebug() << message;
+ qDebug() << "PaymentServer::netRequestFinished : " << message;
emit reportError(tr("Network request error"), message, CClientUIInterface::MODAL);
return;
}
@@ -585,7 +590,7 @@ PaymentServer::netRequestFinished(QNetworkReply* reply)
}
}
else
- qDebug() << "PaymentServer::netRequestFinished: error processing PaymentRequest";
+ qDebug() << "PaymentServer::netRequestFinished : Error processing payment request";
return;
}
else if (requestType == "PaymentACK")
@@ -595,7 +600,7 @@ PaymentServer::netRequestFinished(QNetworkReply* reply)
{
QString message = QObject::tr("Bad response from server %1")
.arg(reply->request().url().toString());
- qDebug() << message;
+ qDebug() << "PaymentServer::netRequestFinished : " << message;
emit reportError(tr("Network request error"), message, CClientUIInterface::MODAL);
}
else {
@@ -604,13 +609,19 @@ PaymentServer::netRequestFinished(QNetworkReply* reply)
}
}
-void
-PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError> &errs)
+void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError> &errs)
{
+ Q_UNUSED(reply);
+
QString errString;
foreach (const QSslError& err, errs) {
- qDebug() << err;
+ qDebug() << "PaymentServer::reportSslErrors : " << err;
errString += err.errorString() + "\n";
}
emit reportError(tr("Network request error"), errString, CClientUIInterface::MODAL);
}
+
+void PaymentServer::setOptionsModel(OptionsModel *optionsModel)
+{
+ this->optionsModel = optionsModel;
+}
diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h
index 7c6b2eabf0..f9d827204b 100644
--- a/src/qt/paymentserver.h
+++ b/src/qt/paymentserver.h
@@ -17,7 +17,7 @@
// received at or during startup in a list.
//
// When startup is finished and the main window is
-// show, a signal is sent to slot uiReady(), which
+// shown, a signal is sent to slot uiReady(), which
// emits a receivedURL() signal for any payment
// requests that happened during startup.
//
@@ -36,6 +36,8 @@
class CWallet;
class OptionsModel;
+
+QT_BEGIN_NAMESPACE
class QApplication;
class QByteArray;
class QLocalServer;
@@ -43,6 +45,7 @@ class QNetworkAccessManager;
class QNetworkReply;
class QSslError;
class QUrl;
+QT_END_NAMESPACE
class PaymentServer : public QObject
{
@@ -56,8 +59,8 @@ public:
// will be called so we startup in the right mode.
static bool ipcSendCommandLine(int argc, char *argv[]);
- PaymentServer(QObject* parent, // parent should be QApplication object
- bool startLocalServer=true);
+ // parent should be QApplication object
+ PaymentServer(QObject* parent, bool startLocalServer = true);
~PaymentServer();
// Load root certificate authorities. Pass NULL (default)
@@ -65,18 +68,21 @@ public:
// or, if that's not set, to use the system default root certificates.
// If you pass in a store, you should not X509_STORE_free it: it will be
// freed either at exit or when another set of CAs are loaded.
- static void LoadRootCAs(X509_STORE* store=NULL);
+ static void LoadRootCAs(X509_STORE* store = NULL);
// Return certificate store
static X509_STORE* getCertStore() { return certStore; }
- // Setup networking (options is used to get proxy settings)
- void initNetManager(const OptionsModel& options);
+ // Setup networking
+ void initNetManager();
// Constructor registers this on the parent QApplication to
// receive QEvent::FileOpen events
bool eventFilter(QObject *object, QEvent *event);
+ // OptionsModel is used for getting proxy settings and display unit
+ void setOptionsModel(OptionsModel *optionsModel);
+
signals:
// Fired when a valid payment request is received
void receivedPaymentRequest(SendCoinsRecipient);
@@ -106,12 +112,15 @@ private:
void handleURIOrFile(const QString& s);
void fetchRequest(const QUrl& url);
- bool saveURIs; // true during startup
+ bool saveURIs; // true during startup
QLocalServer* uriServer;
- static X509_STORE* certStore; // Trusted root certificates
+
+ static X509_STORE* certStore; // Trusted root certificates
static void freeCertStore();
- QNetworkAccessManager* netManager; // Used to fetch payment requests
+ QNetworkAccessManager* netManager; // Used to fetch payment requests
+
+ OptionsModel *optionsModel;
};
#endif // PAYMENTSERVER_H
diff --git a/src/qt/res/bitcoin-qt.rc b/src/qt/res/bitcoin-qt-res.rc
index 3e3672a835..3e3672a835 100644
--- a/src/qt/res/bitcoin-qt.rc
+++ b/src/qt/res/bitcoin-qt-res.rc
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 9086f6614e..00cea463ef 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -63,12 +63,12 @@ SendCoinsDialog::~SendCoinsDialog()
void SendCoinsDialog::on_sendButton_clicked()
{
+ if(!model || !model->getOptionsModel())
+ return;
+
QList<SendCoinsRecipient> recipients;
bool valid = true;
- if(!model)
- return;
-
for(int i = 0; i < ui->entries->count(); ++i)
{
SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
@@ -94,40 +94,37 @@ void SendCoinsDialog::on_sendButton_clicked()
QStringList formatted;
foreach(const SendCoinsRecipient &rcp, recipients)
{
- QString amount = BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, rcp.amount);
+ // generate bold amount string
+ QString amount = "<b>" + BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
+ amount.append("</b>");
+ // generate monospace address string
+ QString address = "<span style='font-family: monospace;'>" + rcp.address;
+ address.append("</span>");
+
+ QString recipientElement;
+
if (rcp.authenticatedMerchant.isEmpty())
{
- QString address = rcp.address;
-#if QT_VERSION < 0x050000
- QString to = Qt::escape(rcp.label);
-#else
- QString to = rcp.label.toHtmlEscaped();
-#endif
- formatted.append(tr("<b>%1</b> to %2 (%3)").arg(amount, to, address));
+ if(rcp.label.length() > 0) // label with address
+ {
+ recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.label));
+ recipientElement.append(QString(" (%1)").arg(address));
+ }
+ else // just address
+ {
+ recipientElement = tr("%1 to %2").arg(amount, address);
+ }
}
- else
+ else // just merchant
{
-#if QT_VERSION < 0x050000
- QString merchant = Qt::escape(rcp.authenticatedMerchant);
-#else
- QString merchant = rcp.authenticatedMerchant.toHtmlEscaped();
-#endif
- formatted.append(tr("<b>%1</b> to %2").arg(amount, merchant));
+ recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.authenticatedMerchant));
}
+
+ formatted.append(recipientElement);
}
fNewRecipientAllowed = false;
- QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"),
- tr("Are you sure you want to send %1?").arg(formatted.join(tr(" and "))),
- QMessageBox::Yes|QMessageBox::Cancel,
- QMessageBox::Cancel);
-
- if(retval != QMessageBox::Yes)
- {
- fNewRecipientAllowed = true;
- return;
- }
WalletModel::UnlockContext ctx(model->requestUnlock());
if(!ctx.isValid())
@@ -137,50 +134,94 @@ void SendCoinsDialog::on_sendButton_clicked()
return;
}
- WalletModel::SendCoinsReturn sendstatus = model->sendCoins(recipients);
- switch(sendstatus.status)
+ // prepare transaction for getting txFee earlier
+ WalletModelTransaction currentTransaction(recipients);
+ WalletModel::SendCoinsReturn prepareStatus = model->prepareTransaction(currentTransaction);
+
+ QString strSendCoins = tr("Send Coins");
+ switch(prepareStatus.status)
{
case WalletModel::InvalidAddress:
- QMessageBox::warning(this, tr("Send Coins"),
- tr("The recipient address is not valid, please recheck."),
- QMessageBox::Ok, QMessageBox::Ok);
+ QMessageBox::warning(this, strSendCoins,
+ tr("The recipient address is not valid, please recheck."));
break;
case WalletModel::InvalidAmount:
- QMessageBox::warning(this, tr("Send Coins"),
- tr("The amount to pay must be larger than 0."),
- QMessageBox::Ok, QMessageBox::Ok);
+ QMessageBox::warning(this, strSendCoins,
+ tr("The amount to pay must be larger than 0."));
break;
case WalletModel::AmountExceedsBalance:
- QMessageBox::warning(this, tr("Send Coins"),
- tr("The amount exceeds your balance."),
- QMessageBox::Ok, QMessageBox::Ok);
+ QMessageBox::warning(this, strSendCoins,
+ tr("The amount exceeds your balance."));
break;
case WalletModel::AmountWithFeeExceedsBalance:
- QMessageBox::warning(this, tr("Send Coins"),
+ QMessageBox::warning(this, strSendCoins,
tr("The total exceeds your balance when the %1 transaction fee is included.").
- arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, sendstatus.fee)),
- QMessageBox::Ok, QMessageBox::Ok);
+ arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee())));
break;
case WalletModel::DuplicateAddress:
- QMessageBox::warning(this, tr("Send Coins"),
- tr("Duplicate address found, can only send to each address once per send operation."),
- QMessageBox::Ok, QMessageBox::Ok);
+ QMessageBox::warning(this, strSendCoins,
+ tr("Duplicate address found, can only send to each address once per send operation."));
break;
case WalletModel::TransactionCreationFailed:
- QMessageBox::warning(this, tr("Send Coins"),
- tr("Error: Transaction creation failed!"),
- QMessageBox::Ok, QMessageBox::Ok);
+ QMessageBox::warning(this, strSendCoins,
+ tr("Error: Transaction creation failed!"));
break;
case WalletModel::TransactionCommitFailed:
- QMessageBox::warning(this, tr("Send Coins"),
- tr("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."),
- QMessageBox::Ok, QMessageBox::Ok);
- break;
+ case WalletModel::OK:
case WalletModel::Aborted: // User aborted, nothing to do
+ default:
+ break;
+ }
+
+ if(prepareStatus.status != WalletModel::OK) {
+ fNewRecipientAllowed = true;
+ return;
+ }
+
+ qint64 txFee = currentTransaction.getTransactionFee();
+ QString questionString = tr("Are you sure you want to send?");
+ questionString.append("<br /><br />%1");
+
+ if(txFee > 0)
+ {
+ // append fee string if a fee is required
+ questionString.append("<hr /><span style='color:#aa0000;'>");
+ questionString.append(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), txFee));
+ questionString.append("</span> ");
+ questionString.append(tr("added as transaction fee"));
+ }
+ if(txFee > 0 || recipients.count() > 1)
+ {
+ // add total amount string if there are more then one recipients or a fee is required
+ questionString.append("<hr />");
+ questionString.append(tr("Total Amount %1").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTotalTransactionAmount()+txFee)));
+ }
+
+ QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"),
+ questionString.arg(formatted.join("<br />")),
+ QMessageBox::Yes | QMessageBox::Cancel,
+ QMessageBox::Cancel);
+
+ if(retval != QMessageBox::Yes)
+ {
+ fNewRecipientAllowed = true;
+ return;
+ }
+
+ // now send the prepared transaction
+ WalletModel::SendCoinsReturn sendstatus = model->sendCoins(currentTransaction);
+ switch(sendstatus.status)
+ {
+ case WalletModel::TransactionCommitFailed:
+ QMessageBox::warning(this, strSendCoins,
+ tr("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."));
break;
case WalletModel::OK:
accept();
break;
+ case WalletModel::Aborted: // User aborted, nothing to do
+ default:
+ break;
}
fNewRecipientAllowed = true;
}
@@ -310,13 +351,14 @@ void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv)
bool SendCoinsDialog::handlePaymentRequest(const SendCoinsRecipient &rv)
{
+ QString strSendCoins = tr("Send Coins");
if (!rv.authenticatedMerchant.isEmpty()) {
// Expired payment request?
const payments::PaymentDetails& details = rv.paymentRequest.getDetails();
if (details.has_expires() && (int64)details.expires() < GetTime())
{
- QMessageBox::warning(this, tr("Send Coins"),
- tr("Payment request expired"));
+ QMessageBox::warning(this, strSendCoins,
+ tr("Payment request expired"));
return false;
}
}
@@ -324,8 +366,8 @@ bool SendCoinsDialog::handlePaymentRequest(const SendCoinsRecipient &rv)
CBitcoinAddress address(rv.address.toStdString());
if (!address.IsValid()) {
QString strAddress(address.ToString().c_str());
- QMessageBox::warning(this, tr("Send Coins"),
- tr("Invalid payment address %1").arg(strAddress));
+ QMessageBox::warning(this, strSendCoins,
+ tr("Invalid payment address %1").arg(strAddress));
return false;
}
}
@@ -338,18 +380,14 @@ void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint
{
Q_UNUSED(unconfirmedBalance);
Q_UNUSED(immatureBalance);
- if(!model || !model->getOptionsModel())
- return;
- int unit = model->getOptionsModel()->getDisplayUnit();
- ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance));
+ if(model && model->getOptionsModel())
+ {
+ ui->labelBalance->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), balance));
+ }
}
void SendCoinsDialog::updateDisplayUnit()
{
- if(model && model->getOptionsModel())
- {
- // Update labelBalance with the current balance and the current unit
- ui->labelBalance->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), model->getBalance()));
- }
+ setBalance(model->getBalance(), 0, 0);
}
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
index e75a003ba1..f4bffedc9b 100644
--- a/src/qt/sendcoinsdialog.h
+++ b/src/qt/sendcoinsdialog.h
@@ -10,6 +10,7 @@ namespace Ui {
class WalletModel;
class SendCoinsEntry;
class SendCoinsRecipient;
+class OptionsModel;
QT_BEGIN_NAMESPACE
class QUrl;
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index 75610f199e..ee84f7bc11 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -106,8 +106,8 @@ bool SendCoinsEntry::validate()
if (!recipient.authenticatedMerchant.isEmpty())
return retval;
- if(!ui->payTo->hasAcceptableInput() ||
- (model && !model->validateAddress(ui->payTo->text())))
+ if (!ui->payTo->hasAcceptableInput() ||
+ (model && !model->validateAddress(ui->payTo->text())))
{
ui->payTo->setValid(false);
retval = false;
@@ -163,8 +163,7 @@ void SendCoinsEntry::setValue(const SendCoinsRecipient &value)
const payments::PaymentDetails& details = value.paymentRequest.getDetails();
ui->payTo_s->setText(value.authenticatedMerchant);
- ui->memo_s->setTextFormat(Qt::PlainText);
- ui->memo_s->setText(QString::fromStdString(details.memo()));
+ ui->memoTextLabel_s->setText(QString::fromStdString(details.memo()));
ui->payAmount_s->setValue(value.amount);
setCurrentWidget(ui->SendCoinsSecure);
}
diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h
index 9c7bfe9521..49e622daf1 100644
--- a/src/qt/sendcoinsentry.h
+++ b/src/qt/sendcoinsentry.h
@@ -33,7 +33,8 @@ public:
void setValue(const SendCoinsRecipient &value);
void setAddress(const QString &address);
- /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907).
+ /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases
+ * (issue https://bugreports.qt-project.org/browse/QTBUG-10907).
*/
QWidget *setupTabChain(QWidget *prev);
diff --git a/src/qt/test/Makefile.am b/src/qt/test/Makefile.am
new file mode 100644
index 0000000000..f8fe97462b
--- /dev/null
+++ b/src/qt/test/Makefile.am
@@ -0,0 +1,26 @@
+include $(top_srcdir)/src/Makefile.include
+
+AM_CPPFLAGS = $(INCLUDES) -I$(top_builddir)/src/obj \
+ -I$(top_srcdir)/src/leveldb/include -I$(top_srcdir)/src \
+ -I$(top_srcdir)/src/leveldb/helpers -I$(top_srcdir)/src/qt \
+ -I$(top_builddir)/src/qt $(BOOST_INCLUDES) $(PROTOBUF_CFLAGS) \
+ $(QR_CFLAGS) $(BDB_CPPFLAGS)
+AM_LDFLAGS = $(PTHREAD_CFLAGS)
+bin_PROGRAMS = test_bitcoin-qt
+TESTS = test_bitcoin-qt
+
+TEST_QT_MOC_CPP = moc_uritests.cpp moc_paymentservertests.cpp
+
+TEST_QT_H = uritests.h paymentservertests.h paymentrequestdata.h
+
+BUILT_SOURCES = $(TEST_QT_MOC_CPP)
+
+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)
+nodist_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP)
+test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN) $(LIBLEVELDB) \
+ $(LIBMEMENV) $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) \
+ $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
+
+CLEANFILES = $(BUILT_SOURCES) *.gcda *.gcno
+
diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp
index 2e26ab0c9b..34079e94ff 100644
--- a/src/qt/test/paymentservertests.cpp
+++ b/src/qt/test/paymentservertests.cpp
@@ -2,6 +2,7 @@
#include <QDebug>
#include <QTemporaryFile>
#include <QVariant>
+#include <QFileOpenEvent>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
@@ -58,7 +59,8 @@ void PaymentServerTests::paymentServerTests()
X509_STORE* caStore = X509_STORE_new();
X509_STORE_add_cert(caStore, parse_b64der_cert(caCert_BASE64));
PaymentServer::LoadRootCAs(caStore);
- server->initNetManager(optionsModel);
+ server->setOptionsModel(&optionsModel);
+ server->initNetManager();
server->uiReady();
// Now feed PaymentRequests to server, and observe signals it produces:
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index 25ff3623c0..e27aa93a4a 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -8,6 +8,7 @@
#include "ui_interface.h"
#include "base58.h"
#include "paymentserver.h"
+#include "transactionrecord.h"
#include <string>
@@ -32,7 +33,7 @@ QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx)
}
}
-QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
+QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int unit)
{
QString strHTML;
@@ -129,7 +130,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
nUnmatured += wallet->GetCredit(txout);
strHTML += "<b>" + tr("Credit") + ":</b> ";
if (wtx.IsInMainChain())
- strHTML += BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", wtx.GetBlocksToMaturity()) + ")";
+ strHTML += BitcoinUnits::formatWithUnit(unit, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", wtx.GetBlocksToMaturity()) + ")";
else
strHTML += "(" + tr("not accepted") + ")";
strHTML += "<br>";
@@ -139,7 +140,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
//
// Credit
//
- strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nNet) + "<br>";
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, nNet) + "<br>";
}
else
{
@@ -175,7 +176,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
}
}
- strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -txout.nValue) + "<br>";
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -txout.nValue) + "<br>";
}
if (fAllToMe)
@@ -183,13 +184,13 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
// Payment to self
int64 nChange = wtx.GetChange();
int64 nValue = nCredit - nChange;
- strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -nValue) + "<br>";
- strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nValue) + "<br>";
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -nValue) + "<br>";
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, nValue) + "<br>";
}
int64 nTxFee = nDebit - GetValueOut(wtx);
if (nTxFee > 0)
- strHTML += "<b>" + tr("Transaction fee") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -nTxFee) + "<br>";
+ strHTML += "<b>" + tr("Transaction fee") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -nTxFee) + "<br>";
}
else
{
@@ -198,14 +199,14 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
//
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
if (wallet->IsMine(txin))
- strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -wallet->GetDebit(txin)) + "<br>";
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -wallet->GetDebit(txin)) + "<br>";
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
if (wallet->IsMine(txout))
- strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, wallet->GetCredit(txout)) + "<br>";
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, wallet->GetCredit(txout)) + "<br>";
}
}
- strHTML += "<b>" + tr("Net amount") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nNet, true) + "<br>";
+ strHTML += "<b>" + tr("Net amount") + ":</b> " + BitcoinUnits::formatWithUnit(unit, nNet, true) + "<br>";
//
// Message
@@ -215,7 +216,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
if (wtx.mapValue.count("comment") && !wtx.mapValue["comment"].empty())
strHTML += "<br><b>" + tr("Comment") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "<br>";
- strHTML += "<b>" + tr("Transaction ID") + ":</b> " + wtx.GetHash().ToString().c_str() + "<br>";
+ strHTML += "<b>" + tr("Transaction ID") + ":</b> " + TransactionRecord::formatSubTxId(wtx.GetHash(), vout) + "<br>";
//
// PaymentRequest info:
@@ -225,7 +226,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
if (r.first == "PaymentRequest")
{
PaymentRequestPlus req;
- req.parse(QByteArray::fromRawData(r.second.c_str(), r.second.size()));
+ req.parse(QByteArray::fromRawData(r.second.data(), r.second.size()));
QString merchant;
if (req.getMerchant(PaymentServer::getCertStore(), merchant))
strHTML += "<b>" + tr("Merchant") + ":</b> " + GUIUtil::HtmlEscape(merchant) + "<br>";
@@ -243,10 +244,10 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
strHTML += "<hr><br>" + tr("Debug information") + "<br><br>";
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
if(wallet->IsMine(txin))
- strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -wallet->GetDebit(txin)) + "<br>";
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -wallet->GetDebit(txin)) + "<br>";
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
if(wallet->IsMine(txout))
- strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, wallet->GetCredit(txout)) + "<br>";
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, wallet->GetCredit(txout)) + "<br>";
strHTML += "<br><b>" + tr("Transaction") + ":</b><br>";
strHTML += GUIUtil::HtmlEscape(wtx.ToString(), true);
@@ -274,7 +275,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + " ";
strHTML += QString::fromStdString(CBitcoinAddress(address).ToString());
}
- strHTML = strHTML + " " + tr("Amount") + "=" + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, vout.nValue);
+ strHTML = strHTML + " " + tr("Amount") + "=" + BitcoinUnits::formatWithUnit(unit, vout.nValue);
strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) ? tr("true") : tr("false")) + "</li>";
}
}
diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h
index cb0dda5b58..8b3684e961 100644
--- a/src/qt/transactiondesc.h
+++ b/src/qt/transactiondesc.h
@@ -14,7 +14,7 @@ class TransactionDesc: public QObject
Q_OBJECT
public:
- static QString toHTML(CWallet *wallet, CWalletTx &wtx);
+ static QString toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int unit);
private:
TransactionDesc() {}
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index e954508769..ea2c1f0a5c 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -224,8 +224,13 @@ bool TransactionRecord::statusUpdateNeeded()
return status.cur_num_blocks != nBestHeight;
}
-std::string TransactionRecord::getTxID()
+QString TransactionRecord::getTxID() const
{
- return hash.ToString() + strprintf("-%03d", idx);
+ return formatSubTxId(hash, idx);
+}
+
+QString TransactionRecord::formatSubTxId(const uint256 &hash, int vout)
+{
+ return QString::fromStdString(hash.ToString() + strprintf("-%03d", vout));
}
diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h
index d760d47c89..480e7a7f2c 100644
--- a/src/qt/transactionrecord.h
+++ b/src/qt/transactionrecord.h
@@ -4,6 +4,7 @@
#include "uint256.h"
#include <QList>
+#include <QString>
class CWallet;
class CWalletTx;
@@ -117,7 +118,10 @@ public:
TransactionStatus status;
/** Return the unique identifier for this transaction (part) */
- std::string getTxID();
+ QString getTxID() const;
+
+ /** Format subtransaction id */
+ static QString formatSubTxId(const uint256 &hash, int vout);
/** Update status from core wallet tx.
*/
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index baf1e16483..07f6a62150 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -17,14 +17,15 @@
#include <QTimer>
#include <QIcon>
#include <QDateTime>
+#include <QDebug>
// Amount column is right-aligned it contains numbers
static int column_alignments[] = {
- Qt::AlignLeft|Qt::AlignVCenter,
- Qt::AlignLeft|Qt::AlignVCenter,
- Qt::AlignLeft|Qt::AlignVCenter,
- Qt::AlignLeft|Qt::AlignVCenter,
- Qt::AlignRight|Qt::AlignVCenter
+ Qt::AlignLeft|Qt::AlignVCenter, /* status */
+ Qt::AlignLeft|Qt::AlignVCenter, /* date */
+ Qt::AlignLeft|Qt::AlignVCenter, /* type */
+ Qt::AlignLeft|Qt::AlignVCenter, /* address */
+ Qt::AlignRight|Qt::AlignVCenter /* amount */
};
// Comparison operator for sort/binary search of model tx list
@@ -48,11 +49,12 @@ struct TxLessThan
class TransactionTablePriv
{
public:
- TransactionTablePriv(CWallet *wallet, TransactionTableModel *parent):
- wallet(wallet),
- parent(parent)
+ TransactionTablePriv(CWallet *wallet, TransactionTableModel *parent) :
+ wallet(wallet),
+ parent(parent)
{
}
+
CWallet *wallet;
TransactionTableModel *parent;
@@ -66,7 +68,7 @@ public:
*/
void refreshWallet()
{
- OutputDebugStringF("refreshWallet\n");
+ qDebug() << "TransactionTablePriv::refreshWallet";
cachedWallet.clear();
{
LOCK(wallet->cs_wallet);
@@ -85,7 +87,7 @@ public:
*/
void updateWallet(const uint256 &hash, int status)
{
- OutputDebugStringF("updateWallet %s %i\n", hash.ToString().c_str(), status);
+ qDebug() << "TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.ToString()) + " " + QString::number(status);
{
LOCK(wallet->cs_wallet);
@@ -113,20 +115,21 @@ public:
status = CT_DELETED; /* In model, but want to hide, treat as deleted */
}
- OutputDebugStringF(" inWallet=%i inModel=%i Index=%i-%i showTransaction=%i derivedStatus=%i\n",
- inWallet, inModel, lowerIndex, upperIndex, showTransaction, status);
+ qDebug() << " inWallet=" + QString::number(inWallet) + " inModel=" + QString::number(inModel) +
+ " Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) +
+ " showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status);
switch(status)
{
case CT_NEW:
if(inModel)
{
- OutputDebugStringF("Warning: updateWallet: Got CT_NEW, but transaction is already in model\n");
+ qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model";
break;
}
if(!inWallet)
{
- OutputDebugStringF("Warning: updateWallet: Got CT_NEW, but transaction is not in wallet\n");
+ qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet";
break;
}
if(showTransaction)
@@ -150,7 +153,7 @@ public:
case CT_DELETED:
if(!inModel)
{
- OutputDebugStringF("Warning: updateWallet: Got CT_DELETED, but transaction is not in model\n");
+ qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model";
break;
}
// Removed -- remove entire transaction from table
@@ -200,19 +203,18 @@ public:
}
}
- QString describe(TransactionRecord *rec)
+ QString describe(TransactionRecord *rec, int unit)
{
{
LOCK(wallet->cs_wallet);
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
if(mi != wallet->mapWallet.end())
{
- return TransactionDesc::toHTML(wallet, mi->second);
+ return TransactionDesc::toHTML(wallet, mi->second, rec->idx, unit);
}
}
return QString("");
}
-
};
TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *parent):
@@ -561,7 +563,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
case DateRole:
return QDateTime::fromTime_t(static_cast<uint>(rec->time));
case LongDescriptionRole:
- return priv->describe(rec);
+ return priv->describe(rec, walletModel->getOptionsModel()->getDisplayUnit());
case AddressRole:
return QString::fromStdString(rec->address);
case LabelRole:
@@ -569,7 +571,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
case AmountRole:
return rec->credit + rec->debit;
case TxIDRole:
- return QString::fromStdString(rec->getTxID());
+ return rec->getTxID();
case ConfirmedRole:
// Return True if transaction counts for balance
return rec->status.confirmed && !(rec->type == TransactionRecord::Generated &&
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index 99a6647a65..8d6a1b387e 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -56,12 +56,9 @@ bool WalletFrame::handlePaymentRequest(const SendCoinsRecipient &recipient)
void WalletFrame::showOutOfSyncWarning(bool fShow)
{
- if (!walletStack) {
- QMessageBox box;
- box.setText("walletStack is null");
- box.exec();
+ if (!walletStack)
return;
- }
+
walletStack->showOutOfSyncWarning(fShow);
}
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 61357647b7..bda39b675f 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -5,12 +5,12 @@
#include "transactiontablemodel.h"
#include "ui_interface.h"
-#include "wallet.h"
#include "walletdb.h" // for BackupWallet
#include "base58.h"
#include <QSet>
#include <QTimer>
+#include <QDebug>
WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) :
QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0),
@@ -112,10 +112,11 @@ void WalletModel::updateTransaction(const QString &hash, int status)
}
}
-void WalletModel::updateAddressBook(const QString &address, const QString &label, bool isMine, int status)
+void WalletModel::updateAddressBook(const QString &address, const QString &label,
+ bool isMine, const QString &purpose, int status)
{
if(addressTableModel)
- addressTableModel->updateEntry(address, label, isMine, status);
+ addressTableModel->updateEntry(address, label, isMine, purpose, status);
}
bool WalletModel::validateAddress(const QString &address)
@@ -124,11 +125,11 @@ bool WalletModel::validateAddress(const QString &address)
return addressParsed.IsValid();
}
-WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients)
+WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction)
{
qint64 total = 0;
+ QList<SendCoinsRecipient> recipients = transaction.getRecipients();
std::vector<std::pair<CScript, int64> > vecSend;
- QByteArray transaction;
if(recipients.empty())
{
@@ -142,7 +143,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
foreach(const SendCoinsRecipient &rcp, recipients)
{
if (rcp.paymentRequest.IsInitialized())
- { // PaymentRequest...
+ { // PaymentRequest...
int64 subtotal = 0;
const payments::PaymentDetails& details = rcp.paymentRequest.getDetails();
for (int i = 0; i < details.outputs_size(); i++)
@@ -192,58 +193,70 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
if((total + nTransactionFee) > getBalance())
{
- return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee);
+ transaction.setTransactionFee(nTransactionFee);
+ return SendCoinsReturn(AmountWithFeeExceedsBalance);
}
{
LOCK2(cs_main, wallet->cs_wallet);
- CReserveKey keyChange(wallet);
+ transaction.newPossibleKeyChange(wallet);
int64 nFeeRequired = 0;
std::string strFailReason;
- CWalletTx wtx;
- bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, strFailReason);
+
+ CWalletTx *newTx = transaction.getTransaction();
+ CReserveKey *keyChange = transaction.getPossibleKeyChange();
+ bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, strFailReason);
+ transaction.setTransactionFee(nFeeRequired);
if(!fCreated)
{
if((total + nFeeRequired) > wallet->GetBalance())
{
- return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired);
+ return SendCoinsReturn(AmountWithFeeExceedsBalance);
}
emit message(tr("Send Coins"), QString::fromStdString(strFailReason),
CClientUIInterface::MSG_ERROR);
return TransactionCreationFailed;
}
+ }
+
+ return SendCoinsReturn(OK);
+}
+
+WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &transaction)
+{
+ QByteArray transaction_array; /* store serialized transaction */
+
+ {
+ LOCK2(cs_main, wallet->cs_wallet);
+ CWalletTx *newTx = transaction.getTransaction();
+
// Store PaymentRequests in wtx.vOrderForm in wallet.
- foreach(const SendCoinsRecipient &rcp, recipients)
+ foreach(const SendCoinsRecipient &rcp, transaction.getRecipients())
{
if (rcp.paymentRequest.IsInitialized())
{
std::string key("PaymentRequest");
std::string value;
rcp.paymentRequest.SerializeToString(&value);
- wtx.vOrderForm.push_back(make_pair(key, value));
+ newTx->vOrderForm.push_back(make_pair(key, value));
}
- }
-
- if(!uiInterface.ThreadSafeAskFee(nFeeRequired))
- {
- return Aborted;
}
- if(!wallet->CommitTransaction(wtx, keyChange))
- {
+
+ CReserveKey *keyChange = transaction.getPossibleKeyChange();
+ if(!wallet->CommitTransaction(*newTx, *keyChange))
return TransactionCommitFailed;
- }
- CTransaction* t = (CTransaction*)&wtx;
+ CTransaction* t = (CTransaction*)newTx;
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << *t;
- transaction.append(&(ssTx[0]), ssTx.size());
+ transaction_array.append(&(ssTx[0]), ssTx.size());
}
// Add addresses / update labels that we've sent to to the address book,
- // and emit coinsSent signal
- foreach(const SendCoinsRecipient &rcp, recipients)
+ // and emit coinsSent signal for each recipient
+ foreach(const SendCoinsRecipient &rcp, transaction.getRecipients())
{
std::string strAddress = rcp.address.toStdString();
CTxDestination dest = CBitcoinAddress(strAddress).Get();
@@ -263,10 +276,10 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
wallet->SetAddressBook(dest, strLabel, ""); // "" means don't change purpose
}
}
- emit coinsSent(wallet, rcp, transaction);
+ emit coinsSent(wallet, rcp, transaction_array);
}
- return SendCoinsReturn(OK, 0);
+ return SendCoinsReturn(OK);
}
OptionsModel *WalletModel::getOptionsModel()
@@ -347,25 +360,34 @@ bool WalletModel::backupWallet(const QString &filename)
// Handlers for core signals
static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStore *wallet)
{
- OutputDebugStringF("NotifyKeyStoreStatusChanged\n");
+ qDebug() << "NotifyKeyStoreStatusChanged";
QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
}
-static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status)
+static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
+ const CTxDestination &address, const std::string &label, bool isMine,
+ const std::string &purpose, ChangeType status)
{
- OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i status=%i\n", CBitcoinAddress(address).ToString().c_str(), label.c_str(), isMine, status);
+ QString strAddress = QString::fromStdString(CBitcoinAddress(address).ToString());
+ QString strLabel = QString::fromStdString(label);
+ QString strPurpose = QString::fromStdString(purpose);
+
+ qDebug() << "NotifyAddressBookChanged : " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + strPurpose + " status=" + QString::number(status);
QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
- Q_ARG(QString, QString::fromStdString(CBitcoinAddress(address).ToString())),
- Q_ARG(QString, QString::fromStdString(label)),
+ Q_ARG(QString, strAddress),
+ Q_ARG(QString, strLabel),
Q_ARG(bool, isMine),
+ Q_ARG(QString, strPurpose),
Q_ARG(int, status));
}
static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
{
- OutputDebugStringF("NotifyTransactionChanged %s status=%i\n", hash.GetHex().c_str(), status);
+ QString strHash = QString::fromStdString(hash.GetHex());
+
+ qDebug() << "NotifyTransactionChanged : " + strHash + " status= " + QString::number(status);
QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection,
- Q_ARG(QString, QString::fromStdString(hash.GetHex())),
+ Q_ARG(QString, strHash),
Q_ARG(int, status));
}
@@ -373,7 +395,7 @@ void WalletModel::subscribeToCoreSignals()
{
// Connect signals to wallet
wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
- wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5));
+ wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
}
@@ -381,7 +403,7 @@ void WalletModel::unsubscribeFromCoreSignals()
{
// Disconnect signals from wallet
wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
- wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5));
+ wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
}
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 8cba10f5d2..6abcdaf8cb 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -4,12 +4,15 @@
#include <QObject>
#include "allocators.h" /* for SecureString */
+#include "wallet.h"
+#include "walletmodeltransaction.h"
#include "paymentrequestplus.h"
class OptionsModel;
class AddressTableModel;
class TransactionTableModel;
class CWallet;
+class WalletModelTransaction;
QT_BEGIN_NAMESPACE
class QTimer;
@@ -74,15 +77,16 @@ public:
// Return status record for SendCoins, contains error id + information
struct SendCoinsReturn
{
- SendCoinsReturn(StatusCode status,
- qint64 fee=0):
- status(status), fee(fee) {}
+ SendCoinsReturn(StatusCode status):
+ status(status) {}
StatusCode status;
- qint64 fee; // is used in case status is "AmountWithFeeExceedsBalance"
};
+ // prepare transaction for getting txfee before sending coins
+ SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction);
+
// Send coins to a list of recipients
- SendCoinsReturn sendCoins(const QList<SendCoinsRecipient> &recipients);
+ SendCoinsReturn sendCoins(WalletModelTransaction &transaction);
// Wallet encryption
bool setWalletEncrypted(bool encrypted, const SecureString &passphrase);
@@ -165,7 +169,7 @@ public slots:
/* New transaction, or transaction changed status */
void updateTransaction(const QString &hash, int status);
/* New, updated or removed address book entry */
- void updateAddressBook(const QString &address, const QString &label, bool isMine, int status);
+ void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
/* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
void pollBalanceChanged();
};
diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp
new file mode 100644
index 0000000000..706ed60b77
--- /dev/null
+++ b/src/qt/walletmodeltransaction.cpp
@@ -0,0 +1,56 @@
+#include "walletmodeltransaction.h"
+
+WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &recipients) :
+ recipients(recipients),
+ walletTransaction(0),
+ keyChange(0),
+ fee(0)
+{
+ walletTransaction = new CWalletTx();
+}
+
+WalletModelTransaction::~WalletModelTransaction()
+{
+ delete keyChange;
+ delete walletTransaction;
+}
+
+QList<SendCoinsRecipient> WalletModelTransaction::getRecipients()
+{
+ return recipients;
+}
+
+CWalletTx *WalletModelTransaction::getTransaction()
+{
+ return walletTransaction;
+}
+
+qint64 WalletModelTransaction::getTransactionFee()
+{
+ return fee;
+}
+
+void WalletModelTransaction::setTransactionFee(qint64 newFee)
+{
+ fee = newFee;
+}
+
+qint64 WalletModelTransaction::getTotalTransactionAmount()
+{
+ qint64 totalTransactionAmount = 0;
+ foreach(const SendCoinsRecipient &rcp, recipients)
+ {
+ totalTransactionAmount += rcp.amount;
+ }
+ return totalTransactionAmount;
+}
+
+void WalletModelTransaction::newPossibleKeyChange(CWallet *wallet)
+{
+ keyChange = new CReserveKey(wallet);
+}
+
+CReserveKey *WalletModelTransaction::getPossibleKeyChange()
+{
+ return keyChange;
+}
diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h
new file mode 100644
index 0000000000..c4848fb12d
--- /dev/null
+++ b/src/qt/walletmodeltransaction.h
@@ -0,0 +1,37 @@
+#ifndef WALLETMODELTRANSACTION_H
+#define WALLETMODELTRANSACTION_H
+
+#include "walletmodel.h"
+
+class SendCoinsRecipient;
+
+/** Data model for a walletmodel transaction. */
+class WalletModelTransaction
+{
+public:
+ explicit WalletModelTransaction(const QList<SendCoinsRecipient> &recipients);
+ ~WalletModelTransaction();
+
+ QList<SendCoinsRecipient> getRecipients();
+
+ CWalletTx *getTransaction();
+
+ void setTransactionFee(qint64 newFee);
+ qint64 getTransactionFee();
+
+ qint64 getTotalTransactionAmount();
+
+ void newPossibleKeyChange(CWallet *wallet);
+ CReserveKey *getPossibleKeyChange();
+
+private:
+ const QList<SendCoinsRecipient> recipients;
+ CWalletTx *walletTransaction;
+ CReserveKey *keyChange;
+ qint64 fee;
+
+public slots:
+
+};
+
+#endif // WALLETMODELTRANSACTION_H
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index ba346f19d9..398f33605a 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -9,7 +9,7 @@
using namespace json_spirit;
using namespace std;
-void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out);
+void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex);
double GetDifficulty(const CBlockIndex* blockindex)
{
@@ -108,8 +108,8 @@ Value settxfee(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 1)
throw runtime_error(
- "settxfee <amount>\n"
- "<amount> is a real and is rounded to the nearest 0.00000001");
+ "settxfee <amount btc/kb>\n"
+ "<amount> is a real and is rounded to the nearest 0.00000001 btc per kb");
// Amount
int64 nAmount = 0;
@@ -245,7 +245,7 @@ Value gettxout(const Array& params, bool fHelp)
ret.push_back(Pair("confirmations", pcoinsTip->GetBestBlock()->nHeight - coins.nHeight + 1));
ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
Object o;
- ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o);
+ ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
ret.push_back(Pair("scriptPubKey", o));
ret.push_back(Pair("version", coins.nVersion));
ret.push_back(Pair("coinbase", coins.fCoinBase));
diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp
index e166f76bf1..842910c7e0 100644
--- a/src/rpcdump.cpp
+++ b/src/rpcdump.cpp
@@ -15,8 +15,6 @@
#include <boost/variant/get.hpp>
#include <boost/algorithm/string.hpp>
-#define printf OutputDebugStringF
-
using namespace json_spirit;
using namespace std;
@@ -147,7 +145,7 @@ Value importwallet(const Array& params, bool fHelp)
CPubKey pubkey = key.GetPubKey();
CKeyID keyid = pubkey.GetID();
if (pwalletMain->HaveKey(keyid)) {
- printf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString().c_str());
+ LogPrintf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString().c_str());
continue;
}
int64 nTime = DecodeDumpTime(vstr[1]);
@@ -165,7 +163,7 @@ Value importwallet(const Array& params, bool fHelp)
fLabel = true;
}
}
- printf("Importing %s...\n", CBitcoinAddress(keyid).ToString().c_str());
+ LogPrintf("Importing %s...\n", CBitcoinAddress(keyid).ToString().c_str());
if (!pwalletMain->AddKeyPubKey(key, pubkey)) {
fGood = false;
continue;
@@ -181,7 +179,7 @@ Value importwallet(const Array& params, bool fHelp)
while (pindex && pindex->pprev && pindex->nTime > nTimeBegin - 7200)
pindex = pindex->pprev;
- printf("Rescanning last %i blocks\n", pindexBest->nHeight - pindex->nHeight + 1);
+ LogPrintf("Rescanning last %i blocks\n", pindexBest->nHeight - pindex->nHeight + 1);
pwalletMain->ScanForWalletTransactions(pindex);
pwalletMain->ReacceptWalletTransactions();
pwalletMain->MarkDirty();
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index c7f516caa7..b013b4b200 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -18,15 +18,74 @@ static CReserveKey* pMiningKey = NULL;
void InitRPCMining()
{
+ if (!pwalletMain)
+ return;
+
// getwork/getblocktemplate mining rewards paid here:
pMiningKey = new CReserveKey(pwalletMain);
}
void ShutdownRPCMining()
{
+ if (!pMiningKey)
+ return;
+
delete pMiningKey; pMiningKey = NULL;
}
+// Return average network hashes per second based on the last 'lookup' blocks,
+// or from the last difficulty change if 'lookup' is nonpositive.
+// If 'height' is nonnegative, compute the estimate at the time when a given block was found.
+Value GetNetworkHashPS(int lookup, int height) {
+ CBlockIndex *pb = pindexBest;
+
+ if (height >= 0 && height < nBestHeight)
+ pb = FindBlockByHeight(height);
+
+ if (pb == NULL || !pb->nHeight)
+ return 0;
+
+ // If lookup is -1, then use blocks since last difficulty change.
+ if (lookup <= 0)
+ lookup = pb->nHeight % 2016 + 1;
+
+ // If lookup is larger than chain, then set it to chain length.
+ if (lookup > pb->nHeight)
+ lookup = pb->nHeight;
+
+ CBlockIndex *pb0 = pb;
+ int64 minTime = pb0->GetBlockTime();
+ int64 maxTime = minTime;
+ for (int i = 0; i < lookup; i++) {
+ pb0 = pb0->pprev;
+ int64 time = pb0->GetBlockTime();
+ minTime = std::min(time, minTime);
+ maxTime = std::max(time, maxTime);
+ }
+
+ // In case there's a situation where minTime == maxTime, we don't want a divide by zero exception.
+ if (minTime == maxTime)
+ return 0;
+
+ uint256 workDiff = pb->nChainWork - pb0->nChainWork;
+ int64 timeDiff = maxTime - minTime;
+
+ return (boost::int64_t)(workDiff.getdouble() / timeDiff);
+}
+
+Value getnetworkhashps(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() > 2)
+ throw runtime_error(
+ "getnetworkhashps [blocks] [height]\n"
+ "Returns the estimated network hashes per second based on the last 120 blocks.\n"
+ "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
+ "Pass in [height] to estimate the network speed at the time when a certain block was found.");
+
+ return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
+}
+
+
Value getgenerate(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
@@ -34,6 +93,9 @@ Value getgenerate(const Array& params, bool fHelp)
"getgenerate\n"
"Returns true or false.");
+ if (!pMiningKey)
+ return false;
+
return GetBoolArg("-gen", false);
}
@@ -59,6 +121,7 @@ Value setgenerate(const Array& params, bool fHelp)
}
mapArgs["-gen"] = (fGenerate ? "1" : "0");
+ assert(pwalletMain != NULL);
GenerateBitcoins(fGenerate, pwalletMain);
return Value::null;
}
@@ -90,9 +153,10 @@ Value getmininginfo(const Array& params, bool fHelp)
obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx));
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
- obj.push_back(Pair("generate", GetBoolArg("-gen", false)));
+ obj.push_back(Pair("generate", getgenerate(params, false)));
obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
+ obj.push_back(Pair("networkhashps", getnetworkhashps(params, false)));
obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
obj.push_back(Pair("testnet", TestNet()));
return obj;
@@ -207,6 +271,7 @@ Value getwork(const Array& params, bool fHelp)
pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
+ assert(pwalletMain != NULL);
return CheckWork(pblock, *pwalletMain, *pMiningKey);
}
}
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index 580120f2a2..fcc5359dd6 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -17,47 +17,15 @@ using namespace boost;
using namespace boost::assign;
using namespace json_spirit;
-//
-// Utilities: convert hex-encoded Values
-// (throws error if not hex).
-//
-uint256 ParseHashV(const Value& v, string strName)
-{
- string strHex;
- if (v.type() == str_type)
- strHex = v.get_str();
- if (!IsHex(strHex)) // Note: IsHex("") is false
- throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
- uint256 result;
- result.SetHex(strHex);
- return result;
-}
-uint256 ParseHashO(const Object& o, string strKey)
-{
- return ParseHashV(find_value(o, strKey), strKey);
-}
-vector<unsigned char> ParseHexV(const Value& v, string strName)
-{
- string strHex;
- if (v.type() == str_type)
- strHex = v.get_str();
- if (!IsHex(strHex))
- throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
- return ParseHex(strHex);
-}
-vector<unsigned char> ParseHexO(const Object& o, string strKey)
-{
- return ParseHexV(find_value(o, strKey), strKey);
-}
-
-void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out)
+void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex)
{
txnouttype type;
vector<CTxDestination> addresses;
int nRequired;
out.push_back(Pair("asm", scriptPubKey.ToString()));
- out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
+ if (fIncludeHex)
+ out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired))
{
@@ -106,7 +74,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
out.push_back(Pair("n", (boost::int64_t)i));
Object o;
- ScriptPubKeyToJSON(txout.scriptPubKey, o);
+ ScriptPubKeyToJSON(txout.scriptPubKey, o, false);
out.push_back(Pair("scriptPubKey", o));
vout.push_back(out);
}
@@ -203,6 +171,7 @@ Value listunspent(const Array& params, bool fHelp)
Array results;
vector<COutput> vecOutputs;
+ assert(pwalletMain != NULL);
pwalletMain->AvailableCoins(vecOutputs, false);
BOOST_FOREACH(const COutput& out, vecOutputs)
{
@@ -334,6 +303,29 @@ Value decoderawtransaction(const Array& params, bool fHelp)
return result;
}
+Value decodescript(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "decodescript <hex string>\n"
+ "Decode a hex-encoded script.");
+
+ RPCTypeCheck(params, list_of(str_type));
+
+ Object r;
+ CScript script;
+ if (params[0].get_str().size() > 0){
+ vector<unsigned char> scriptData(ParseHexV(params[0], "argument"));
+ script = CScript(scriptData.begin(), scriptData.end());
+ } else {
+ // Empty scripts are valid
+ }
+ ScriptPubKeyToJSON(script, r, false);
+
+ r.push_back(Pair("p2sh", CBitcoinAddress(script.GetID()).ToString()));
+ return r;
+}
+
Value signrawtransaction(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 4)
@@ -467,7 +459,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
}
}
- const CKeyStore& keystore = (fGivenKeys ? tempKeystore : *pwalletMain);
+ const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
int nHashType = SIGHASH_ALL;
if (params.size() > 3 && params[3].type() != null_type)
@@ -527,9 +519,9 @@ Value signrawtransaction(const Array& params, bool fHelp)
Value sendrawtransaction(const Array& params, bool fHelp)
{
- if (fHelp || params.size() < 1 || params.size() > 1)
+ if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
- "sendrawtransaction <hex string>\n"
+ "sendrawtransaction <hex string> [allowhighfees=false]\n"
"Submits raw transaction (serialized, hex-encoded) to local node and network.");
// parse hex string from parameter
@@ -537,6 +529,10 @@ Value sendrawtransaction(const Array& params, bool fHelp)
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
CTransaction tx;
+ bool fOverrideFees = false;
+ if (params.size() > 1)
+ fOverrideFees = params[1].get_bool();
+
// deserialize binary data stream
try {
ssData >> tx;
@@ -554,7 +550,7 @@ Value sendrawtransaction(const Array& params, bool fHelp)
if (!fHave) {
// push to local node
CValidationState state;
- if (!mempool.accept(state, tx, false, NULL))
+ if (!mempool.accept(state, tx, false, NULL, !fOverrideFees))
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected"); // TODO: report validation state
}
}
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index d07d3408b9..cafb6db9b1 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -21,7 +21,7 @@ static CCriticalSection cs_nWalletUnlockTime;
std::string HelpRequiringPassphrase()
{
- return pwalletMain->IsCrypted()
+ return pwalletMain && pwalletMain->IsCrypted()
? "\nrequires wallet passphrase to be set with walletpassphrase first"
: "";
}
@@ -72,18 +72,22 @@ Value getinfo(const Array& params, bool fHelp)
Object obj;
obj.push_back(Pair("version", (int)CLIENT_VERSION));
obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
- obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
- obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
+ if (pwalletMain) {
+ obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
+ obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
+ }
obj.push_back(Pair("blocks", (int)nBestHeight));
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()));
- obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
- obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
+ 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->IsCrypted())
+ if (pwalletMain && pwalletMain->IsCrypted())
obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
return obj;
@@ -110,7 +114,7 @@ Value getnewaddress(const Array& params, bool fHelp)
// Generate a new key that is added to wallet
CPubKey newKey;
- if (!pwalletMain->GetKeyFromPool(newKey, false))
+ if (!pwalletMain->GetKeyFromPool(newKey))
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
CKeyID keyID = newKey.GetID();
@@ -148,7 +152,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
// Generate a new key
if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed)
{
- if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
+ if (!pwalletMain->GetKeyFromPool(account.vchPubKey))
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, "receive");
@@ -176,6 +180,29 @@ Value getaccountaddress(const Array& params, bool fHelp)
}
+Value getrawchangeaddress(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() > 1)
+ throw runtime_error(
+ "getrawchangeaddress\n"
+ "Returns a new Bitcoin address, for receiving change. "
+ "This is for use with raw transactions, NOT normal use.");
+
+ if (!pwalletMain->IsLocked())
+ pwalletMain->TopUpKeyPool();
+
+ CReserveKey reservekey(pwalletMain);
+ CPubKey vchPubKey;
+ if (!reservekey.GetReservedKey(vchPubKey))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error: Unable to obtain key for change");
+
+ reservekey.KeepKey();
+
+ CKeyID keyID = vchPubKey.GetID();
+
+ return CBitcoinAddress(keyID).ToString();
+}
+
Value setaccount(const Array& params, bool fHelp)
{
@@ -715,7 +742,7 @@ static CScript _createmultisig(const Array& params)
// Case 1: Bitcoin address and we have full public key:
CBitcoinAddress address(ks);
- if (address.IsValid())
+ if (pwalletMain && address.IsValid())
{
CKeyID keyID;
if (!address.GetKeyID(keyID))
@@ -1424,6 +1451,7 @@ public:
int nRequired;
ExtractDestinations(subscript, whichType, addresses, nRequired);
obj.push_back(Pair("script", GetTxnOutputType(whichType)));
+ obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
Array a;
BOOST_FOREACH(const CTxDestination& addr, addresses)
a.push_back(CBitcoinAddress(addr).ToString());
@@ -1451,13 +1479,13 @@ Value validateaddress(const Array& params, bool fHelp)
CTxDestination dest = address.Get();
string currentAddress = address.ToString();
ret.push_back(Pair("address", currentAddress));
- bool fMine = IsMine(*pwalletMain, dest);
+ bool fMine = pwalletMain ? IsMine(*pwalletMain, dest) : false;
ret.push_back(Pair("ismine", fMine));
if (fMine) {
Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
ret.insert(ret.end(), detail.begin(), detail.end());
}
- if (pwalletMain->mapAddressBook.count(dest))
+ if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
}
return ret;
diff --git a/src/script.cpp b/src/script.cpp
index 3c3e9cf3bf..0fe2953548 100644
--- a/src/script.cpp
+++ b/src/script.cpp
@@ -977,7 +977,7 @@ uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int
{
if (nIn >= txTo.vin.size())
{
- printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
+ LogPrintf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
return 1;
}
CTransaction txTmp(txTo);
@@ -1008,7 +1008,7 @@ uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int
unsigned int nOut = nIn;
if (nOut >= txTmp.vout.size())
{
- printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
+ LogPrintf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
return 1;
}
txTmp.vout.resize(nOut+1);
diff --git a/src/script.h b/src/script.h
index 0ab47678e8..842b8512eb 100644
--- a/src/script.h
+++ b/src/script.h
@@ -553,6 +553,13 @@ public:
return true;
}
+ // Returns whether the script is guaranteed to fail at execution,
+ // regardless of the initial stack. This allows outputs to be pruned
+ // instantly when entering the UTXO set.
+ bool IsUnspendable() const
+ {
+ return (size() > 0 && *begin() == OP_RETURN);
+ }
void SetDestination(const CTxDestination& address);
void SetMultisig(int nRequired, const std::vector<CPubKey>& keys);
@@ -560,7 +567,7 @@ public:
void PrintHex() const
{
- printf("CScript(%s)\n", HexStr(begin(), end(), true).c_str());
+ LogPrintf("CScript(%s)\n", HexStr(begin(), end(), true).c_str());
}
std::string ToString() const
@@ -588,7 +595,7 @@ public:
void print() const
{
- printf("%s\n", ToString().c_str());
+ LogPrintf("%s\n", ToString().c_str());
}
CScriptID GetID() const
diff --git a/src/sync.cpp b/src/sync.cpp
index 1ac4403beb..29a455f9b2 100644
--- a/src/sync.cpp
+++ b/src/sync.cpp
@@ -10,8 +10,8 @@
#ifdef DEBUG_LOCKCONTENTION
void PrintLockContention(const char* pszName, const char* pszFile, int nLine)
{
- printf("LOCKCONTENTION: %s\n", pszName);
- printf("Locker: %s:%d\n", pszFile, nLine);
+ LogPrintf("LOCKCONTENTION: %s\n", pszName);
+ LogPrintf("Locker: %s:%d\n", pszFile, nLine);
}
#endif /* DEBUG_LOCKCONTENTION */
@@ -56,20 +56,20 @@ static boost::thread_specific_ptr<LockStack> lockstack;
static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
{
- printf("POTENTIAL DEADLOCK DETECTED\n");
- printf("Previous lock order was:\n");
+ LogPrintf("POTENTIAL DEADLOCK DETECTED\n");
+ LogPrintf("Previous lock order was:\n");
BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2)
{
- if (i.first == mismatch.first) printf(" (1)");
- if (i.first == mismatch.second) printf(" (2)");
- printf(" %s\n", i.second.ToString().c_str());
+ if (i.first == mismatch.first) LogPrintf(" (1)");
+ if (i.first == mismatch.second) LogPrintf(" (2)");
+ LogPrintf(" %s\n", i.second.ToString().c_str());
}
- printf("Current lock order is:\n");
+ LogPrintf("Current lock order is:\n");
BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1)
{
- if (i.first == mismatch.first) printf(" (1)");
- if (i.first == mismatch.second) printf(" (2)");
- printf(" %s\n", i.second.ToString().c_str());
+ if (i.first == mismatch.first) LogPrintf(" (1)");
+ if (i.first == mismatch.second) LogPrintf(" (2)");
+ LogPrintf(" %s\n", i.second.ToString().c_str());
}
}
@@ -78,7 +78,7 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
if (lockstack.get() == NULL)
lockstack.reset(new LockStack);
- if (fDebug) printf("Locking: %s\n", locklocation.ToString().c_str());
+ if (fDebug) LogPrintf("Locking: %s\n", locklocation.ToString().c_str());
dd_mutex.lock();
(*lockstack).push_back(std::make_pair(c, locklocation));
@@ -108,7 +108,7 @@ static void pop_lock()
if (fDebug)
{
const CLockLocation& locklocation = (*lockstack).rbegin()->second;
- printf("Unlocked: %s\n", locklocation.ToString().c_str());
+ LogPrintf("Unlocked: %s\n", locklocation.ToString().c_str());
}
dd_mutex.lock();
(*lockstack).pop_back();
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
new file mode 100644
index 0000000000..a859eb1de8
--- /dev/null
+++ b/src/test/Makefile.am
@@ -0,0 +1,41 @@
+include $(top_srcdir)/src/Makefile.include
+
+AM_CPPFLAGS = $(INCLUDES) -I$(top_builddir)/src/obj \
+ -I$(top_srcdir)/src/leveldb/include -I$(top_srcdir)/src/leveldb/helpers \
+ -I$(top_srcdir)/src $(BOOST_INCLUDES) $(BDB_CPPFLAGS)
+
+AM_LDFLAGS = $(PTHREAD_CFLAGS)
+
+bin_PROGRAMS = test_bitcoin
+
+TESTS = test_bitcoin
+
+JSON_TEST_FILES= data/script_valid.json \
+ data/base58_keys_valid.json data/sig_canonical.json \
+ data/sig_noncanonical.json \
+ data/base58_encode_decode.json \
+ data/base58_keys_invalid.json \
+ data/script_invalid.json data/tx_invalid.json \
+ data/tx_valid.json
+
+RAW_TEST_FILES = data/alertTests.raw
+
+BUILT_SOURCES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h)
+
+# test_bitcoin binary #
+test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(TESTDEFS)
+test_bitcoin_LDADD = $(LIBBITCOIN) $(LIBLEVELDB) $(LIBMEMENV) \
+ $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(BDB_LIBS)
+test_bitcoin_SOURCES = accounting_tests.cpp alert_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 \
+ Checkpoints_tests.cpp compress_tests.cpp DoS_tests.cpp getarg_tests.cpp \
+ key_tests.cpp miner_tests.cpp mruset_tests.cpp multisig_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 \
+ transaction_tests.cpp uint160_tests.cpp uint256_tests.cpp util_tests.cpp \
+ wallet_tests.cpp $(JSON_TEST_FILES) $(RAW_TEST_FILES)
+
+nodist_test_bitcoin_SOURCES = $(BUILT_SOURCES)
+
+CLEANFILES = *.gcda *.gcno $(BUILT_SOURCES)
diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp
index f7a11376d3..cb941943f7 100644
--- a/src/test/alert_tests.cpp
+++ b/src/test/alert_tests.cpp
@@ -9,6 +9,7 @@
#include "alert.h"
#include "serialize.h"
#include "util.h"
+#include "data/alertTests.raw.h"
#if 0
//
@@ -71,27 +72,13 @@ struct ReadAlerts
{
ReadAlerts()
{
- std::string filename("alertTests");
- namespace fs = boost::filesystem;
- fs::path testFile = fs::current_path() / "test" / "data" / filename;
-#ifdef TEST_DATA_DIR
- if (!fs::exists(testFile))
- {
- testFile = fs::path(BOOST_PP_STRINGIZE(TEST_DATA_DIR)) / filename;
- }
-#endif
- FILE* fp = fopen(testFile.string().c_str(), "rb");
- if (!fp) return;
-
-
- CAutoFile filein = CAutoFile(fp, SER_DISK, CLIENT_VERSION);
- if (!filein) return;
-
+ std::vector<unsigned char> vch(alert_tests::alertTests, alert_tests::alertTests + sizeof(alert_tests::alertTests));
+ CDataStream stream(vch, SER_DISK, CLIENT_VERSION);
try {
- while (!feof(filein))
+ while (stream.good())
{
CAlert alert;
- filein >> alert;
+ stream >> alert;
alerts.push_back(alert);
}
}
@@ -125,6 +112,9 @@ BOOST_AUTO_TEST_CASE(AlertApplies)
{
BOOST_CHECK(alert.CheckSignature());
}
+
+ BOOST_CHECK(alerts.size() >= 3);
+
// Matches:
BOOST_CHECK(alerts[0].AppliesTo(1, ""));
BOOST_CHECK(alerts[0].AppliesTo(70001, ""));
diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp
index af65416485..05675685bd 100644
--- a/src/test/base58_tests.cpp
+++ b/src/test/base58_tests.cpp
@@ -2,20 +2,21 @@
#include "json/json_spirit_reader_template.h"
#include "json/json_spirit_writer_template.h"
#include "json/json_spirit_utils.h"
+#include "data/base58_encode_decode.json.h"
+#include "data/base58_keys_invalid.json.h"
+#include "data/base58_keys_valid.json.h"
#include "base58.h"
#include "util.h"
-
using namespace json_spirit;
-extern Array read_json(const std::string& filename);
+extern Array read_json(const std::string& jsondata);
BOOST_AUTO_TEST_SUITE(base58_tests)
// Goal: test low-level base58 encoding functionality
BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
{
- Array tests = read_json("base58_encode_decode.json");
-
+ Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode)));
BOOST_FOREACH(Value& tv, tests)
{
Array test = tv.get_array();
@@ -36,7 +37,7 @@ BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
// Goal: test low-level base58 decoding functionality
BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
{
- Array tests = read_json("base58_encode_decode.json");
+ Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode)));
std::vector<unsigned char> result;
BOOST_FOREACH(Value& tv, tests)
@@ -104,7 +105,7 @@ public:
// Goal: check that parsed keys match test payload
BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
{
- Array tests = read_json("base58_keys_valid.json");
+ Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
std::vector<unsigned char> result;
CBitcoinSecret secret;
CBitcoinAddress addr;
@@ -163,7 +164,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
// Goal: check that generated keys match test vectors
BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
{
- Array tests = read_json("base58_keys_valid.json");
+ Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
std::vector<unsigned char> result;
BOOST_FOREACH(Value& tv, tests)
{
@@ -231,7 +232,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
// Goal: check that base58 parsing code is robust against a variety of corrupted data
BOOST_AUTO_TEST_CASE(base58_keys_invalid)
{
- Array tests = read_json("base58_keys_invalid.json"); // Negative testcases
+ Array tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases
std::vector<unsigned char> result;
CBitcoinSecret secret;
CBitcoinAddress addr;
diff --git a/src/test/canonical_tests.cpp b/src/test/canonical_tests.cpp
index 09988da259..ec32ceb8a4 100644
--- a/src/test/canonical_tests.cpp
+++ b/src/test/canonical_tests.cpp
@@ -8,13 +8,15 @@
#include "key.h"
#include "script.h"
#include "util.h"
+#include "data/sig_noncanonical.json.h"
+#include "data/sig_canonical.json.h"
using namespace std;
using namespace json_spirit;
// In script_tests.cpp
-extern Array read_json(const std::string& filename);
+extern Array read_json(const std::string& jsondata);
BOOST_AUTO_TEST_SUITE(canonical_tests)
@@ -58,7 +60,7 @@ bool static IsCanonicalSignature_OpenSSL(const std::vector<unsigned char> &vchSi
BOOST_AUTO_TEST_CASE(script_canon)
{
- Array tests = read_json("sig_canonical.json");
+ Array tests = read_json(std::string(json_tests::sig_canonical, json_tests::sig_canonical + sizeof(json_tests::sig_canonical)));
BOOST_FOREACH(Value &tv, tests) {
string test = tv.get_str();
@@ -72,7 +74,7 @@ BOOST_AUTO_TEST_CASE(script_canon)
BOOST_AUTO_TEST_CASE(script_noncanon)
{
- Array tests = read_json("sig_noncanonical.json");
+ Array tests = read_json(std::string(json_tests::sig_noncanonical, json_tests::sig_noncanonical + sizeof(json_tests::sig_noncanonical)));
BOOST_FOREACH(Value &tv, tests) {
string test = tv.get_str();
diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp
index 5675c40e76..e34680db99 100644
--- a/src/test/checkblock_tests.cpp
+++ b/src/test/checkblock_tests.cpp
@@ -19,7 +19,7 @@ bool
read_block(const std::string& filename, CBlock& block)
{
namespace fs = boost::filesystem;
- fs::path testFile = fs::current_path() / "test" / "data" / filename;
+ fs::path testFile = fs::current_path() / "data" / filename;
#ifdef TEST_DATA_DIR
if (!fs::exists(testFile))
{
diff --git a/src/test/data/alertTests b/src/test/data/alertTests.raw
index 7fc4528961..7fc4528961 100644
--- a/src/test/data/alertTests
+++ b/src/test/data/alertTests.raw
Binary files differ
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index 8183504147..eeeacb0ad4 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -83,6 +83,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
// Just to make sure we can still make simple blocks
BOOST_CHECK(pblocktemplate = CreateNewBlockWithKey(reservekey));
+ delete pblocktemplate;
// block sigops > limit: 1000 CHECKMULTISIG + 1
tx.vin.resize(1);
@@ -200,6 +201,9 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
BOOST_CHECK(pblocktemplate = CreateNewBlockWithKey(reservekey));
delete pblocktemplate;
pindexBest->nHeight = nHeight;
+
+ BOOST_FOREACH(CTransaction *tx, txFirst)
+ delete tx;
}
BOOST_AUTO_TEST_CASE(sha256transform_equality)
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index c1f6f178db..dfa5529b87 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -14,6 +14,8 @@
#include "main.h"
#include "wallet.h"
+#include "data/script_invalid.json.h"
+#include "data/script_valid.json.h"
using namespace std;
using namespace json_spirit;
@@ -90,34 +92,15 @@ ParseScript(string s)
}
Array
-read_json(const std::string& filename)
+read_json(const std::string& jsondata)
{
- namespace fs = boost::filesystem;
- fs::path testFile = fs::current_path() / "test" / "data" / filename;
-
-#ifdef TEST_DATA_DIR
- if (!fs::exists(testFile))
- {
- testFile = fs::path(BOOST_PP_STRINGIZE(TEST_DATA_DIR)) / filename;
- }
-#endif
-
- ifstream ifs(testFile.string().c_str(), ifstream::in);
Value v;
- if (!read_stream(ifs, v))
- {
- if (ifs.fail())
- BOOST_ERROR("Cound not find/open " << filename);
- else
- BOOST_ERROR("JSON syntax error in " << filename);
- return Array();
- }
- if (v.type() != array_type)
+
+ if (!read_string(jsondata, v) || v.type() != array_type)
{
- BOOST_ERROR(filename << " does not contain a json array");
+ BOOST_ERROR("Parse error.");
return Array();
}
-
return v.get_array();
}
@@ -130,7 +113,7 @@ BOOST_AUTO_TEST_CASE(script_valid)
// Inner arrays are [ "scriptSig", "scriptPubKey" ]
// ... where scriptSig and scriptPubKey are stringified
// scripts.
- Array tests = read_json("script_valid.json");
+ Array tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid)));
BOOST_FOREACH(Value& tv, tests)
{
@@ -154,7 +137,7 @@ BOOST_AUTO_TEST_CASE(script_valid)
BOOST_AUTO_TEST_CASE(script_invalid)
{
// Scripts that should evaluate as invalid
- Array tests = read_json("script_invalid.json");
+ Array tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid)));
BOOST_FOREACH(Value& tv, tests)
{
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 0c7475b4f2..416b93ab33 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -5,12 +5,14 @@
#include "main.h"
#include "wallet.h"
+#include "data/tx_invalid.json.h"
+#include "data/tx_valid.json.h"
using namespace std;
using namespace json_spirit;
// In script_tests.cpp
-extern Array read_json(const std::string& filename);
+extern Array read_json(const std::string& jsondata);
extern CScript ParseScript(string s);
BOOST_AUTO_TEST_SUITE(transaction_tests)
@@ -22,7 +24,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
// Inner arrays are either [ "comment" ]
// or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, enforceP2SH
// ... where all scripts are stringified scripts.
- Array tests = read_json("tx_valid.json");
+ Array tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid)));
BOOST_FOREACH(Value& tv, tests)
{
@@ -91,7 +93,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
// Inner arrays are either [ "comment" ]
// or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, enforceP2SH
// ... where all scripts are stringified scripts.
- Array tests = read_json("tx_invalid.json");
+ Array tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid)));
BOOST_FOREACH(Value& tv, tests)
{
diff --git a/src/test/wallet_tests.cpp b/src/test/wallet_tests.cpp
index a14f6b2b70..51f3b27c8b 100644
--- a/src/test/wallet_tests.cpp
+++ b/src/test/wallet_tests.cpp
@@ -289,6 +289,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests)
BOOST_CHECK_NE(fails, RANDOM_REPEATS);
}
}
+ empty_wallet();
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/txdb.cpp b/src/txdb.cpp
index 34836eaa97..0d2fdc2887 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -55,7 +55,7 @@ bool CCoinsViewDB::SetBestBlock(CBlockIndex *pindex) {
}
bool CCoinsViewDB::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) {
- printf("Committing %u changed transactions to coin database...\n", (unsigned int)mapCoins.size());
+ LogPrint("coindb", "Committing %u changed transactions to coin database...\n", (unsigned int)mapCoins.size());
CLevelDBBatch batch;
for (std::map<uint256, CCoins>::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
diff --git a/src/uint256.h b/src/uint256.h
index 2a252c94f3..45ab8abb5e 100644
--- a/src/uint256.h
+++ b/src/uint256.h
@@ -654,39 +654,39 @@ inline int Testuint256AdHoc(std::vector<std::string> vArg)
uint256 g(0);
- printf("%s\n", g.ToString().c_str());
- g--; printf("g--\n");
- printf("%s\n", g.ToString().c_str());
- g--; printf("g--\n");
- printf("%s\n", g.ToString().c_str());
- g++; printf("g++\n");
- printf("%s\n", g.ToString().c_str());
- g++; printf("g++\n");
- printf("%s\n", g.ToString().c_str());
- g++; printf("g++\n");
- printf("%s\n", g.ToString().c_str());
- g++; printf("g++\n");
- printf("%s\n", g.ToString().c_str());
+ LogPrintf("%s\n", g.ToString().c_str());
+ g--; LogPrintf("g--\n");
+ LogPrintf("%s\n", g.ToString().c_str());
+ g--; LogPrintf("g--\n");
+ LogPrintf("%s\n", g.ToString().c_str());
+ g++; LogPrintf("g++\n");
+ LogPrintf("%s\n", g.ToString().c_str());
+ g++; LogPrintf("g++\n");
+ LogPrintf("%s\n", g.ToString().c_str());
+ g++; LogPrintf("g++\n");
+ LogPrintf("%s\n", g.ToString().c_str());
+ g++; LogPrintf("g++\n");
+ LogPrintf("%s\n", g.ToString().c_str());
uint256 a(7);
- printf("a=7\n");
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("a=7\n");
+ LogPrintf("%s\n", a.ToString().c_str());
uint256 b;
- printf("b undefined\n");
- printf("%s\n", b.ToString().c_str());
+ LogPrintf("b undefined\n");
+ LogPrintf("%s\n", b.ToString().c_str());
int c = 3;
a = c;
a.pn[3] = 15;
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
uint256 k(c);
a = 5;
a.pn[3] = 15;
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
b = 1;
b <<= 52;
@@ -694,86 +694,86 @@ inline int Testuint256AdHoc(std::vector<std::string> vArg)
a ^= 0x500;
- printf("a %s\n", a.ToString().c_str());
+ LogPrintf("a %s\n", a.ToString().c_str());
a = a | b | (uint256)0x1000;
- printf("a %s\n", a.ToString().c_str());
- printf("b %s\n", b.ToString().c_str());
+ LogPrintf("a %s\n", a.ToString().c_str());
+ LogPrintf("b %s\n", b.ToString().c_str());
a = 0xfffffffe;
a.pn[4] = 9;
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
a++;
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
a++;
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
a++;
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
a++;
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
a--;
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
a--;
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
a--;
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
uint256 d = a--;
- printf("%s\n", d.ToString().c_str());
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", d.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
a--;
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
a--;
- printf("%s\n", a.ToString().c_str());
+ LogPrintf("%s\n", a.ToString().c_str());
d = a;
- printf("%s\n", d.ToString().c_str());
- for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n");
+ LogPrintf("%s\n", d.ToString().c_str());
+ for (int i = uint256::WIDTH-1; i >= 0; i--) LogPrintf("%08x", d.pn[i]); LogPrintf("\n");
uint256 neg = d;
neg = ~neg;
- printf("%s\n", neg.ToString().c_str());
+ LogPrintf("%s\n", neg.ToString().c_str());
uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111");
- printf("\n");
- printf("%s\n", e.ToString().c_str());
+ LogPrintf("\n");
+ LogPrintf("%s\n", e.ToString().c_str());
- printf("\n");
+ LogPrintf("\n");
uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111");
uint256 x2;
- printf("%s\n", x1.ToString().c_str());
+ LogPrintf("%s\n", x1.ToString().c_str());
for (int i = 0; i < 270; i += 4)
{
x2 = x1 << i;
- printf("%s\n", x2.ToString().c_str());
+ LogPrintf("%s\n", x2.ToString().c_str());
}
- printf("\n");
- printf("%s\n", x1.ToString().c_str());
+ LogPrintf("\n");
+ LogPrintf("%s\n", x1.ToString().c_str());
for (int i = 0; i < 270; i += 4)
{
x2 = x1;
x2 >>= i;
- printf("%s\n", x2.ToString().c_str());
+ LogPrintf("%s\n", x2.ToString().c_str());
}
for (int i = 0; i < 100; i++)
{
uint256 k = (~uint256(0) >> i);
- printf("%s\n", k.ToString().c_str());
+ LogPrintf("%s\n", k.ToString().c_str());
}
for (int i = 0; i < 100; i++)
{
uint256 k = (~uint256(0) << i);
- printf("%s\n", k.ToString().c_str());
+ LogPrintf("%s\n", k.ToString().c_str());
}
return (0);
diff --git a/src/util.cpp b/src/util.cpp
index 136a035485..73428b4c22 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -166,7 +166,7 @@ void RandAddSeedPerfmon()
{
RAND_add(pdata, nSize, nSize/100.0);
OPENSSL_cleanse(pdata, nSize);
- printf("RandAddSeed() %lu bytes\n", nSize);
+ LogPrint("rand", "RandAddSeed() %lu bytes\n", nSize);
}
#endif
}
@@ -198,15 +198,7 @@ uint256 GetRandHash()
return hash;
}
-
-
-
-
-
-
-//
-// OutputDebugStringF (aka printf -- there is a #define that we really
-// should get rid of one day) has been broken a couple of times now
+// LogPrintf() has been broken a couple of times now
// by well-meaning people adding mutexes in the most straightforward way.
// It breaks because it may be called by global destructors during shutdown.
// Since the order of destruction of static/global objects is undefined,
@@ -233,8 +225,16 @@ static void DebugPrintInit()
mutexDebugLog = new boost::mutex();
}
-int OutputDebugStringF(const char* pszFormat, ...)
+int LogPrint(const char* category, const char* pszFormat, ...)
{
+ if (category != NULL)
+ {
+ if (!fDebug) return 0;
+ const vector<string>& categories = mapMultiArgs["-debug"];
+ if (find(categories.begin(), categories.end(), string(category)) == categories.end())
+ return 0;
+ }
+
int ret = 0; // Returns total number of characters written
if (fPrintToConsole)
{
@@ -360,7 +360,7 @@ bool error(const char *format, ...)
va_start(arg_ptr, format);
std::string str = vstrprintf(format, arg_ptr);
va_end(arg_ptr);
- printf("ERROR: %s\n", str.c_str());
+ LogPrintf("ERROR: %s\n", str.c_str());
return false;
}
@@ -994,13 +994,13 @@ static std::string FormatException(std::exception* pex, const char* pszThread)
void LogException(std::exception* pex, const char* pszThread)
{
std::string message = FormatException(pex, pszThread);
- printf("\n%s", message.c_str());
+ LogPrintf("\n%s", message.c_str());
}
void PrintException(std::exception* pex, const char* pszThread)
{
std::string message = FormatException(pex, pszThread);
- printf("\n\n************************\n%s\n", message.c_str());
+ LogPrintf("\n\n************************\n%s\n", message.c_str());
fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
strMiscWarning = message;
throw;
@@ -1009,7 +1009,7 @@ void PrintException(std::exception* pex, const char* pszThread)
void PrintExceptionContinue(std::exception* pex, const char* pszThread)
{
std::string message = FormatException(pex, pszThread);
- printf("\n\n************************\n%s\n", message.c_str());
+ LogPrintf("\n\n************************\n%s\n", message.c_str());
fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
strMiscWarning = message;
}
@@ -1057,7 +1057,7 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
fs::path &path = pathCached[nNet];
- // This can be called during exceptions by printf, so we cache the
+ // This can be called during exceptions by LogPrintf(), so we cache the
// value so we don't have to do memory allocations after that.
if (!path.empty())
return path;
@@ -1156,6 +1156,8 @@ void FileCommit(FILE *fileout)
#else
#if defined(__linux__) || defined(__NetBSD__)
fdatasync(fileno(fileout));
+ #elif defined(__APPLE__) && defined(F_FULLFSYNC)
+ fcntl(fileno(fileout), F_FULLFSYNC, 0);
#else
fsync(fileno(fileout));
#endif
@@ -1320,7 +1322,7 @@ void AddTimeData(const CNetAddr& ip, int64 nTime)
// Add data
vTimeOffsets.input(nOffsetSample);
- printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
+ LogPrintf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
{
int64 nMedian = vTimeOffsets.median();
@@ -1348,17 +1350,17 @@ void AddTimeData(const CNetAddr& ip, int64 nTime)
fDone = true;
string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin will not work properly.");
strMiscWarning = strMessage;
- printf("*** %s\n", strMessage.c_str());
+ LogPrintf("*** %s\n", strMessage.c_str());
uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
}
}
}
if (fDebug) {
BOOST_FOREACH(int64 n, vSorted)
- printf("%+"PRI64d" ", n);
- printf("| ");
+ LogPrintf("%+"PRI64d" ", n);
+ LogPrintf("| ");
}
- printf("nTimeOffset = %+"PRI64d" (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60);
+ LogPrintf("nTimeOffset = %+"PRI64d" (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60);
}
}
@@ -1420,7 +1422,7 @@ boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate)
return fs::path(pszPath);
}
- printf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n");
+ LogPrintf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n");
return fs::path("");
}
#endif
@@ -1440,7 +1442,7 @@ boost::filesystem::path GetTempPath() {
path = boost::filesystem::path("/tmp");
#endif
if (path.empty() || !boost::filesystem::is_directory(path)) {
- printf("GetTempPath(): failed to find temp path\n");
+ LogPrintf("GetTempPath(): failed to find temp path\n");
return boost::filesystem::path("");
}
return path;
@@ -1451,7 +1453,7 @@ void runCommand(std::string strCommand)
{
int nErr = ::system(strCommand.c_str());
if (nErr)
- printf("runCommand error: system(%s) returned %d\n", strCommand.c_str(), nErr);
+ LogPrintf("runCommand error: system(%s) returned %d\n", strCommand.c_str(), nErr);
}
void RenameThread(const char* name)
diff --git a/src/util.h b/src/util.h
index f246412de0..a216aacdc9 100644
--- a/src/util.h
+++ b/src/util.h
@@ -91,7 +91,6 @@ T* alignup(T* p)
}
#ifdef WIN32
-#define MSG_NOSIGNAL 0
#define MSG_DONTWAIT 0
#ifndef S_IRUSR
@@ -111,11 +110,13 @@ inline void MilliSleep(int64 n)
// Boost's sleep_for was uninterruptable when backed by nanosleep from 1.50
// until fixed in 1.52. Use the deprecated sleep method for the broken case.
// See: https://svn.boost.org/trac/boost/ticket/7238
-
-#if BOOST_VERSION >= 105000 && (!defined(BOOST_HAS_NANOSLEEP) || BOOST_VERSION >= 105200)
+#if defined(HAVE_WORKING_BOOST_SLEEP_FOR)
boost::this_thread::sleep_for(boost::chrono::milliseconds(n));
-#else
+#elif defined(HAVE_WORKING_BOOST_SLEEP)
boost::this_thread::sleep(boost::posix_time::milliseconds(n));
+#else
+ //should never get here
+#error missing boost sleep implementation
#endif
}
@@ -152,7 +153,10 @@ extern volatile bool fReopenDebugLog;
void RandAddSeed();
void RandAddSeedPerfmon();
-int ATTR_WARN_PRINTF(1,2) OutputDebugStringF(const char* pszFormat, ...);
+
+// Print to debug.log if -debug=category switch is given OR category is NULL.
+int ATTR_WARN_PRINTF(2,3) LogPrint(const char* category, const char* pszFormat, ...);
+#define LogPrintf(...) LogPrint(NULL, __VA_ARGS__)
/*
Rationale for the real_strprintf / strprintf construction:
@@ -172,14 +176,6 @@ std::string vstrprintf(const char *format, va_list ap);
bool ATTR_WARN_PRINTF(1,2) error(const char *format, ...);
-/* Redefine printf so that it directs output to debug.log
- *
- * Do this *after* defining the other printf-like functions, because otherwise the
- * __attribute__((format(printf,X,Y))) gets expanded to __attribute__((format(OutputDebugStringF,X,Y)))
- * which confuses gcc.
- */
-#define printf OutputDebugStringF
-
void LogException(std::exception* pex, const char* pszThread);
void PrintException(std::exception* pex, const char* pszThread);
void PrintExceptionContinue(std::exception* pex, const char* pszThread);
@@ -316,12 +312,12 @@ inline std::string HexStr(const T& vch, bool fSpaces=false)
template<typename T>
void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
{
- printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
+ LogPrintf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
}
inline void PrintHex(const std::vector<unsigned char>& vch, const char* pszFormat="%s", bool fSpaces=true)
{
- printf(pszFormat, HexStr(vch, fSpaces).c_str());
+ LogPrintf(pszFormat, HexStr(vch, fSpaces).c_str());
}
inline int64 GetPerformanceCounter()
@@ -521,7 +517,7 @@ inline void SetThreadPriority(int nPriority)
// PRIO_MAX is not defined on Solaris
#ifndef PRIO_MAX
- #define PRIO_MAX 20
+#define PRIO_MAX 20
#endif
#define THREAD_PRIORITY_LOWEST PRIO_MAX
#define THREAD_PRIORITY_BELOW_NORMAL 2
@@ -559,7 +555,7 @@ template <typename Callable> void LoopForever(const char* name, Callable func,
{
std::string s = strprintf("bitcoin-%s", name);
RenameThread(s.c_str());
- printf("%s thread start\n", name);
+ LogPrintf("%s thread start\n", name);
try
{
while (1)
@@ -570,7 +566,7 @@ template <typename Callable> void LoopForever(const char* name, Callable func,
}
catch (boost::thread_interrupted)
{
- printf("%s thread stop\n", name);
+ LogPrintf("%s thread stop\n", name);
throw;
}
catch (std::exception& e) {
@@ -587,13 +583,13 @@ template <typename Callable> void TraceThread(const char* name, Callable func)
RenameThread(s.c_str());
try
{
- printf("%s thread start\n", name);
+ LogPrintf("%s thread start\n", name);
func();
- printf("%s thread exit\n", name);
+ LogPrintf("%s thread exit\n", name);
}
catch (boost::thread_interrupted)
{
- printf("%s thread interrupt\n", name);
+ LogPrintf("%s thread interrupt\n", name);
throw;
}
catch (std::exception& e) {
diff --git a/src/wallet.cpp b/src/wallet.cpp
index ddfd71efda..26ffc71e19 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -159,7 +159,7 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
if (pMasterKey.second.nDeriveIterations < 25000)
pMasterKey.second.nDeriveIterations = 25000;
- printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
+ LogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
return false;
@@ -267,7 +267,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
if (kMasterKey.nDeriveIterations < 25000)
kMasterKey.nDeriveIterations = 25000;
- printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
+ LogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
return false;
@@ -368,10 +368,10 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx)
{
CWalletTx& wtx = (*mi).second;
if (txin.prevout.n >= wtx.vout.size())
- printf("WalletUpdateSpent: bad wtx %s\n", wtx.GetHash().ToString().c_str());
+ LogPrintf("WalletUpdateSpent: bad wtx %s\n", wtx.GetHash().ToString().c_str());
else if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n]))
{
- printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
+ LogPrintf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
wtx.MarkSpent(txin.prevout.n);
wtx.WriteToDisk();
NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED);
@@ -446,9 +446,9 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
}
else
- printf("AddToWallet() : found %s in block %s not in index\n",
- wtxIn.GetHash().ToString().c_str(),
- wtxIn.hashBlock.ToString().c_str());
+ LogPrintf("AddToWallet() : found %s in block %s not in index\n",
+ wtxIn.GetHash().ToString().c_str(),
+ wtxIn.hashBlock.ToString().c_str());
}
}
@@ -476,7 +476,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
}
//// debug print
- printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
+ LogPrintf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
// Write to disk
if (fInsertedNew || fUpdated)
@@ -493,7 +493,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
if (txout.scriptPubKey == scriptDefaultKey)
{
CPubKey newDefaultKey;
- if (GetKeyFromPool(newDefaultKey, false))
+ if (GetKeyFromPool(newDefaultKey))
{
SetDefaultKey(newDefaultKey);
SetAddressBook(vchDefaultKey.GetID(), "", "receive");
@@ -677,8 +677,8 @@ void CWalletTx::GetAmounts(list<pair<CTxDestination, int64> >& listReceived,
vector<unsigned char> vchPubKey;
if (!ExtractDestination(txout.scriptPubKey, address))
{
- printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
- this->GetHash().ToString().c_str());
+ LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
+ this->GetHash().ToString().c_str());
}
// Don't report 'change' txouts
@@ -849,7 +849,7 @@ void CWallet::ReacceptWalletTransactions()
}
if (fUpdated)
{
- printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
+ LogPrintf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
wtx.MarkDirty();
wtx.WriteToDisk();
}
@@ -882,7 +882,7 @@ void CWalletTx::RelayWalletTransaction()
{
if (GetDepthInMainChain() == 0) {
uint256 hash = GetHash();
- printf("Relaying wtx %s\n", hash.ToString().c_str());
+ LogPrintf("Relaying wtx %s\n", hash.ToString().c_str());
RelayTransaction((CTransaction)*this, hash);
}
}
@@ -905,7 +905,7 @@ void CWallet::ResendWalletTransactions()
nLastResend = GetTime();
// Rebroadcast any of our txes that aren't in a block yet
- printf("ResendWalletTransactions()\n");
+ LogPrintf("ResendWalletTransactions()\n");
{
LOCK(cs_wallet);
// Sort them in chronological order
@@ -1145,12 +1145,11 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe
nValueRet += vValue[i].first;
}
- //// debug print
- printf("SelectCoins() best subset: ");
+ LogPrint("selectcoins", "SelectCoins() best subset: ");
for (unsigned int i = 0; i < vValue.size(); i++)
if (vfBest[i])
- printf("%s ", FormatMoney(vValue[i].first).c_str());
- printf("total %s\n", FormatMoney(nBest).c_str());
+ LogPrint("selectcoins", "%s ", FormatMoney(vValue[i].first).c_str());
+ LogPrint("selectcoins", "total %s\n", FormatMoney(nBest).c_str());
}
return true;
@@ -1336,7 +1335,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
{
{
LOCK2(cs_main, cs_wallet);
- printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
+ LogPrintf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
{
// This is only to keep the database open to defeat the auto-flush for the
// duration of this scope. This is the only place where this optimization
@@ -1372,7 +1371,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
if (!wtxNew.AcceptToMemoryPool(false))
{
// This must not fail. The transaction has already been signed and recorded.
- printf("CommitTransaction() : Error: Transaction not valid");
+ LogPrintf("CommitTransaction() : Error: Transaction not valid");
return false;
}
wtxNew.RelayWalletTransaction();
@@ -1391,7 +1390,7 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew,
if (IsLocked())
{
string strError = _("Error: Wallet locked, unable to create transaction!");
- printf("SendMoney() : %s", strError.c_str());
+ LogPrintf("SendMoney() : %s", strError.c_str());
return strError;
}
string strError;
@@ -1399,7 +1398,7 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew,
{
if (nValue + nFeeRequired > GetBalance())
strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!"), FormatMoney(nFeeRequired).c_str());
- printf("SendMoney() : %s\n", strError.c_str());
+ LogPrintf("SendMoney() : %s\n", strError.c_str());
return strError;
}
@@ -1461,7 +1460,11 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const string& strNam
{
std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
mapAddressBook[address].name = strName;
- NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
+ if (!strPurpose.empty()) /* update purpose only if requested */
+ mapAddressBook[address].purpose = strPurpose;
+ NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address),
+ mapAddressBook[address].purpose,
+ (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
if (!fFileBacked)
return false;
if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
@@ -1472,7 +1475,7 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const string& strNam
bool CWallet::DelAddressBook(const CTxDestination& address)
{
mapAddressBook.erase(address);
- NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), CT_DELETED);
+ NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), "", CT_DELETED);
if (!fFileBacked)
return false;
CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
@@ -1486,10 +1489,10 @@ void CWallet::PrintWallet(const CBlock& block)
if (mapWallet.count(block.vtx[0].GetHash()))
{
CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
- printf(" mine: %d %d %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
+ LogPrintf(" mine: %d %d %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
}
}
- printf("\n");
+ LogPrintf("\n");
}
bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
@@ -1548,7 +1551,7 @@ bool CWallet::NewKeyPool()
walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
setKeyPool.insert(nIndex);
}
- printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys);
+ LogPrintf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys);
}
return true;
}
@@ -1578,7 +1581,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
throw runtime_error("TopUpKeyPool() : writing generated key failed");
setKeyPool.insert(nEnd);
- printf("keypool added key %"PRI64d", size=%"PRIszu"\n", nEnd, setKeyPool.size());
+ LogPrintf("keypool added key %"PRI64d", size=%"PRIszu"\n", nEnd, setKeyPool.size());
}
}
return true;
@@ -1607,7 +1610,7 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
if (!HaveKey(keypool.vchPubKey.GetID()))
throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
assert(keypool.vchPubKey.IsValid());
- printf("keypool reserve %"PRI64d"\n", nIndex);
+ LogPrintf("keypool reserve %"PRI64d"\n", nIndex);
}
}
@@ -1634,7 +1637,7 @@ void CWallet::KeepKey(int64 nIndex)
CWalletDB walletdb(strWalletFile);
walletdb.ErasePool(nIndex);
}
- printf("keypool keep %"PRI64d"\n", nIndex);
+ LogPrintf("keypool keep %"PRI64d"\n", nIndex);
}
void CWallet::ReturnKey(int64 nIndex)
@@ -1644,10 +1647,10 @@ void CWallet::ReturnKey(int64 nIndex)
LOCK(cs_wallet);
setKeyPool.insert(nIndex);
}
- printf("keypool return %"PRI64d"\n", nIndex);
+ LogPrintf("keypool return %"PRI64d"\n", nIndex);
}
-bool CWallet::GetKeyFromPool(CPubKey& result, bool fAllowReuse)
+bool CWallet::GetKeyFromPool(CPubKey& result)
{
int64 nIndex = 0;
CKeyPool keypool;
@@ -1656,11 +1659,6 @@ bool CWallet::GetKeyFromPool(CPubKey& result, bool fAllowReuse)
ReserveKeyFromKeyPool(nIndex, keypool);
if (nIndex == -1)
{
- if (fAllowReuse && vchDefaultKey.IsValid())
- {
- result = vchDefaultKey;
- return true;
- }
if (IsLocked()) return false;
result = GenerateNewKey();
return true;
@@ -1837,7 +1835,7 @@ bool CReserveKey::GetReservedKey(CPubKey& pubkey)
vchPubKey = keypool.vchPubKey;
else {
if (pwallet->vchDefaultKey.IsValid()) {
- printf("CReserveKey::GetReservedKey(): Warning: Using default key instead of a new key, top up your keypool!");
+ LogPrintf("CReserveKey::GetReservedKey(): Warning: Using default key instead of a new key, top up your keypool!");
vchPubKey = pwallet->vchDefaultKey;
} else
return false;
diff --git a/src/wallet.h b/src/wallet.h
index d47416d272..51bc9f67c4 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -220,7 +220,7 @@ public:
void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
void KeepKey(int64 nIndex);
void ReturnKey(int64 nIndex);
- bool GetKeyFromPool(CPubKey &key, bool fAllowReuse=true);
+ bool GetKeyFromPool(CPubKey &key);
int64 GetOldestKeyPoolTime();
void GetAllReserveKeys(std::set<CKeyID>& setAddress) const;
@@ -335,12 +335,16 @@ public:
/** Address book entry changed.
* @note called with lock cs_wallet held.
*/
- boost::signals2::signal<void (CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status)> NotifyAddressBookChanged;
+ boost::signals2::signal<void (CWallet *wallet, const CTxDestination
+ &address, const std::string &label, bool isMine,
+ const std::string &purpose,
+ ChangeType status)> NotifyAddressBookChanged;
/** Wallet transaction added, removed or updated.
* @note called with lock cs_wallet held.
*/
- boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged;
+ boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx,
+ ChangeType status)> NotifyTransactionChanged;
};
/** A key allocated from the key pool. */
@@ -741,7 +745,7 @@ public:
void print() const
{
- printf("%s\n", ToString().c_str());
+ LogPrintf("%s\n", ToString().c_str());
}
};
diff --git a/src/walletdb.cpp b/src/walletdb.cpp
index 554d140024..635fda1b42 100644
--- a/src/walletdb.cpp
+++ b/src/walletdb.cpp
@@ -271,8 +271,8 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
wss.fAnyUnordered = true;
//// debug print
- //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
- //printf(" %12"PRI64d" %s %s %s\n",
+ //LogPrintf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
+ //LogPrintf(" %12"PRI64d" %s %s %s\n",
// wtx.vout[0].nValue,
// DateTimeStrFormat("%Y-%m-%d %H:%M:%S", wtx.GetBlockTime()).c_str(),
// wtx.hashBlock.ToString().c_str(),
@@ -451,7 +451,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
Dbc* pcursor = GetCursor();
if (!pcursor)
{
- printf("Error getting wallet database cursor\n");
+ LogPrintf("Error getting wallet database cursor\n");
return DB_CORRUPT;
}
@@ -465,7 +465,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
break;
else if (ret != 0)
{
- printf("Error reading next record from wallet database\n");
+ LogPrintf("Error reading next record from wallet database\n");
return DB_CORRUPT;
}
@@ -487,7 +487,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
}
}
if (!strErr.empty())
- printf("%s\n", strErr.c_str());
+ LogPrintf("%s\n", strErr.c_str());
}
pcursor->close();
}
@@ -506,9 +506,9 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
if (result != DB_LOAD_OK)
return result;
- printf("nFileVersion = %d\n", wss.nFileVersion);
+ LogPrintf("nFileVersion = %d\n", wss.nFileVersion);
- printf("Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n",
+ LogPrintf("Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n",
wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys);
// nTimeFirstKey is only reliable if all keys have metadata
@@ -576,7 +576,7 @@ void ThreadFlushWalletDB(const string& strFile)
map<string, int>::iterator mi = bitdb.mapFileUseCount.find(strFile);
if (mi != bitdb.mapFileUseCount.end())
{
- printf("Flushing wallet.dat\n");
+ LogPrint("db", "Flushing wallet.dat\n");
nLastFlushed = nWalletDBUpdated;
int64 nStart = GetTimeMillis();
@@ -585,7 +585,7 @@ void ThreadFlushWalletDB(const string& strFile)
bitdb.CheckpointLSN(strFile);
bitdb.mapFileUseCount.erase(mi++);
- printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart);
+ LogPrint("db", "Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart);
}
}
}
@@ -620,10 +620,10 @@ bool BackupWallet(const CWallet& wallet, const string& strDest)
#else
filesystem::copy_file(pathSrc, pathDest);
#endif
- printf("copied wallet.dat to %s\n", pathDest.string().c_str());
+ LogPrintf("copied wallet.dat to %s\n", pathDest.string().c_str());
return true;
} catch(const filesystem::filesystem_error &e) {
- printf("error copying wallet.dat to %s - %s\n", pathDest.string().c_str(), e.what());
+ LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string().c_str(), e.what());
return false;
}
}
@@ -651,10 +651,10 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys)
int result = dbenv.dbenv.dbrename(NULL, filename.c_str(), NULL,
newFilename.c_str(), DB_AUTO_COMMIT);
if (result == 0)
- printf("Renamed %s to %s\n", filename.c_str(), newFilename.c_str());
+ LogPrintf("Renamed %s to %s\n", filename.c_str(), newFilename.c_str());
else
{
- printf("Failed to rename %s to %s\n", filename.c_str(), newFilename.c_str());
+ LogPrintf("Failed to rename %s to %s\n", filename.c_str(), newFilename.c_str());
return false;
}
@@ -662,10 +662,10 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys)
bool allOK = dbenv.Salvage(newFilename, true, salvagedData);
if (salvagedData.empty())
{
- printf("Salvage(aggressive) found no records in %s.\n", newFilename.c_str());
+ LogPrintf("Salvage(aggressive) found no records in %s.\n", newFilename.c_str());
return false;
}
- printf("Salvage(aggressive) found %"PRIszu" records\n", salvagedData.size());
+ LogPrintf("Salvage(aggressive) found %"PRIszu" records\n", salvagedData.size());
bool fSuccess = allOK;
Db* pdbCopy = new Db(&dbenv.dbenv, 0);
@@ -677,7 +677,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys)
0);
if (ret > 0)
{
- printf("Cannot create database file %s\n", filename.c_str());
+ LogPrintf("Cannot create database file %s\n", filename.c_str());
return false;
}
CWallet dummyWallet;
@@ -697,7 +697,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys)
continue;
if (!fReadOK)
{
- printf("WARNING: CWalletDB::Recover skipping %s: %s\n", strType.c_str(), strErr.c_str());
+ LogPrintf("WARNING: CWalletDB::Recover skipping %s: %s\n", strType.c_str(), strErr.c_str());
continue;
}
}