aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--doc/build-unix.txt39
-rw-r--r--doc/release-notes.txt101
-rw-r--r--share/setup.nsi2
-rw-r--r--src/addrman.cpp4
-rw-r--r--src/addrman.h2
-rw-r--r--src/base58.h2
-rw-r--r--src/bitcoinrpc.cpp27
-rw-r--r--src/clientversion.h2
-rw-r--r--src/db.cpp4
-rw-r--r--src/key.h2
-rw-r--r--src/main.cpp65
-rw-r--r--src/main.h50
-rw-r--r--src/makefile.linux-mingw2
-rw-r--r--src/makefile.mingw6
-rw-r--r--src/makefile.osx5
-rw-r--r--src/makefile.unix5
-rw-r--r--src/netbase.cpp8
-rw-r--r--src/qt/transactionrecord.cpp14
-rw-r--r--src/rpcnet.cpp2
-rw-r--r--src/rpcwallet.cpp4
-rw-r--r--src/serialize.h52
-rw-r--r--src/sync.cpp2
-rw-r--r--src/test/accounting_tests.cpp2
-rw-r--r--src/test/data/tx_invalid.json40
-rw-r--r--src/test/data/tx_valid.json21
-rw-r--r--src/test/transaction_tests.cpp10
-rw-r--r--src/util.h4
-rw-r--r--src/wallet.cpp11
-rw-r--r--src/wallet.h9
-rw-r--r--src/walletdb.cpp4
-rw-r--r--src/walletdb.h6
32 files changed, 240 insertions, 268 deletions
diff --git a/.gitignore b/.gitignore
index 2b70e2cca5..95152ce4fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,6 @@ src/*.exe
src/bitcoin
src/bitcoind
src/test_bitcoin
-src/build.h
.*.swp
*.*~*
*.bak
diff --git a/doc/build-unix.txt b/doc/build-unix.txt
index 784d86e63d..b02a20a760 100644
--- a/doc/build-unix.txt
+++ b/doc/build-unix.txt
@@ -28,7 +28,6 @@ Dependencies
libdb4.8 Berkeley DB Blockchain & wallet storage
libboost Boost C++ Library
miniupnpc UPnP Support Optional firewall-jumping support
- libqrencode QRCode generation Optional QRCode generation
miniupnpc may be used for UPnP port mapping. It can be downloaded from
http://miniupnp.tuxfamily.org/files/. UPnP support is compiled in and
@@ -37,13 +36,7 @@ turned off by default. Set USE_UPNP to a different value to control this:
USE_UPNP=0 (the default) UPnP support turned off by default at runtime
USE_UPNP=1 UPnP support turned on by default at runtime
-libqrencode may be used for QRCode image generation. It can be downloaded
-from http://fukuchi.org/works/qrencode/index.html.en, or installed via
-your package manager. Set USE_QRCODE to control this:
- USE_QRCODE=0 (the default) No QRCode support - libqrcode not required
- USE_QRCODE=1 QRCode support enabled
-
-IPv6 support may be enabled by setting
+IPv6 support may be enabled by setting:
USE_IPV6=1 Enable IPv6 support
Licenses of statically linked libraries:
@@ -61,15 +54,27 @@ Versions used in this release:
Dependency Build Instructions: Ubuntu & Debian
----------------------------------------------
-sudo apt-get install build-essential
-sudo apt-get install libssl-dev
-sudo apt-get install libdb4.8-dev
-sudo apt-get install libdb4.8++-dev
- Boost 1.40+: sudo apt-get install libboost-all-dev
- or Boost 1.37: sudo apt-get install libboost1.37-dev
-sudo apt-get install libqrencode-dev
-
-If using Boost 1.37, append -mt to the boost libraries in the makefile.
+Build requirements:
+ sudo apt-get install build-essential
+ sudo apt-get install libssl-dev
+
+for Ubuntu 12.04:
+ sudo apt-get install libboost-all-dev
+
+ db4.8 packages are available at:
+ https://launchpad.net/~bitcoin/+archive/bitcoin
+
+ Ubuntu precise has packages for libdb5.1-dev and libdb5.1++-dev,
+ but using these will break binary wallet compatibility, and is not recommended.
+
+for other Ubuntu & Debian:
+ sudo apt-get install libdb4.8-dev
+ sudo apt-get install libdb4.8++-dev
+ sudo apt-get install libboost1.37-dev
+ (If using Boost 1.37, append -mt to the boost libraries in the makefile)
+
+Optional:
+ sudo apt-get install libminiupnpc-dev (see USE_UPNP compile flag)
Dependency Build Instructions: Gentoo
diff --git a/doc/release-notes.txt b/doc/release-notes.txt
index c2fdc425fd..3c975af92f 100644
--- a/doc/release-notes.txt
+++ b/doc/release-notes.txt
@@ -3,7 +3,7 @@ release time)
Building this from
- $ git shortlog --no-merges v0.6.3..
+ $ git shortlog --no-merges v0.7.0..
How to Upgrade
--------------
@@ -19,99 +19,8 @@ Ubuntu PPA version), then run the old version again with the -detachdb
argument and shut it down; if you do not, then the new version will not
be able to read the database files and will exit with an error.
-Incompatible Changes
---------------------
-* Replaced the 'getmemorypool' RPC command with 'getblocktemplate/submitblock'
- and 'getrawmempool' commands.
-* Remove deprecated RPC 'getblocknumber'
+Bug fixes
+---------
+* Fixed an uninitialized variable bug that could cause transactions to
+ be reported out of order.
-Bitcoin Improvement Proposals implemented
------------------------------------------
-BIP 22 - 'getblocktemplate', 'submitblock' RPCs
-BIP 34 - block version 2, height in coinbase
-BIP 35 - 'mempool' message, extended 'getdata' message behavior
-
-
-Core bitcoin handling and blockchain database
----------------------------------------------
-* Reduced CPU usage, by eliminating some redundant hash calculations
-* Cache signature verifications, to eliminate redundant signature checks
-* Transactions with zero-value outputs are considered non-standard
-* Mining: when creating new blocks, sort 'paid' area by fee-per-kb
-* Database: better validation of on-disk stored data
-* Database: minor optimizations and reliability improvements
-* -loadblock=FILE will import an external block file
-* Additional DoS (denial-of-service) prevention measures
-* New blockchain checkpoint at block 193,000
-* (Windows only): enable ASLR and DEP for bitcoind.exe
-
-
-JSON-RPC API
-------------
-* Internal HTTP server is now thread-per-connection, rather than
- a single-threaded queue that would stall on network I/O.
-* Internal HTTP server supports HTTP/1.1, pipelined requests and
- connection keep-alive.
-* Support JSON-RPC 2.0 batches, to encapsulate multiple JSON-RPC requests
- within a single HTTP request.
-* IPv6 support
-* Added raw transaction API. See https://gist.github.com/2839617
-* Added 'getrawmempool', to list contents of TX memory pool
-* Added 'getpeerinfo', to list data about each connected network peer
-* Added 'listaddressgroupings' for better coin control
-* Rework gettransaction, getblock calls. 'gettransaction' responds for
- non-wallet TXs now.
-* Remove deprecated RPC 'getblocknumber'
-* Remove superceded RPC 'getmemorypool' (see BIP 22, above)
-* listtransactions output now displays "smart" times for transactions,
- and 'blocktime' and 'timereceived' fields were added
-
-
-P2P networking
---------------
-* IPv6 support
-* Tor hidden service support (see doc/Tor.txt)
-* Attempts to fix "stuck blockchain download" problems
-* Replace BDB database "addr.dat" with internally-managed "peers.dat"
- file containing peer address data.
-* Lower default send buffer from 10MB to 1MB
-* proxy: SOCKS5 by default
-* Support connecting by hostnames passed to proxy
-* Add -seednode connections, and use this instead of DNS seeds when proxied
-* Added -externalip and -discover
-* Add -onlynet to connect only to a given network (IPv4, IPv6, or Tor)
-* Separate listening sockets, -bind=<addr>
-
-
-Qt GUI
-------
-* Add UI RPC console / debug window
-* Re-Enable URI handling on Windows, add safety checks and tray-notifications
-* Harmonize the use of ellipsis ("...") to be used in menus, but not on buttons
-* Add 2 labels to the overviewpage that display Wallet and Transaction status (obsolete or current)
-* Extend the optionsdialog (e.g. language selection) and re-work it to a tabbed UI
-* Merge sign/verify message into a single window with tabbed UI
-* Ensure a changed bitcoin unit immediately updates all GUI elements that use units
-* Update QR Code dialog
-* Improve error reporting at startup
-* Fine-grained UI updates for a much smoother UI during block downloads
-* Remove autocorrection of 0/i in addresses in UI
-* Reorganize tray icon menu into more logical order
-* Persistently poll for balance change when number of blocks changed
-* Much better translations
-* Override progress bar design on platforms with segmented progress bars to assist with readability
-* Added 'immature balance' display on the overview page
-* (Windows only): enable ASLR and DEP for bitcoin-qt.exe
-* (Windows only): add meta-data to bitcoin-qt.exe (e.g. description and version)
-
-Internal codebase
------------------
-* Additional unit tests
-* Compile warning fixes
-
-
-Miscellaneous
--------------
-* Reopen debug.log upon SIGHUP
-* Bash programmable completion for bitcoind(1)
-* On supported OSes, each thread is given a useful name
diff --git a/share/setup.nsi b/share/setup.nsi
index d46e1e68ae..4e48718a49 100644
--- a/share/setup.nsi
+++ b/share/setup.nsi
@@ -51,7 +51,7 @@ CRCCheck on
XPStyle on
BrandingText " "
ShowInstDetails show
-VIProductVersion 0.7.0.2
+VIProductVersion 0.7.0.3
VIAddVersionKey ProductName Bitcoin
VIAddVersionKey ProductVersion "${VERSION}"
VIAddVersionKey CompanyName "${COMPANY}"
diff --git a/src/addrman.cpp b/src/addrman.cpp
index 321ebd1e2b..4428cd169a 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -187,7 +187,7 @@ int CAddrMan::ShrinkNew(int nUBucket)
}
assert(mapInfo.count(nOldest) == 1);
CAddrInfo &info = mapInfo[nOldest];
- if (--info.nRefCount == 0)
+ if (--info.nRefCount == 0)
{
SwapRandom(info.nRandomPos, vRandom.size()-1);
vRandom.pop_back();
@@ -241,7 +241,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
infoOld.nRefCount = 1;
// do not update nTried, as we are going to move something else there immediately
- // check whether there is place in that one,
+ // check whether there is place in that one,
if (vNew.size() < ADDRMAN_NEW_BUCKET_SIZE)
{
// if so, move it back there
diff --git a/src/addrman.h b/src/addrman.h
index 7c141c427b..7af6afd78f 100644
--- a/src/addrman.h
+++ b/src/addrman.h
@@ -214,7 +214,7 @@ protected:
// This is the only place where actual deletes occur.
// They are never deleted while in the "tried" table, only possibly evicted back to the "new" table.
int ShrinkNew(int nUBucket);
-
+
// Move an entry from the "new" table(s) to the "tried" table
// @pre vvUnkown[nOrigin].count(nId) != 0
void MakeTried(CAddrInfo& info, int nId, int nOrigin);
diff --git a/src/base58.h b/src/base58.h
index fc8c8aa5de..9dfea86ff5 100644
--- a/src/base58.h
+++ b/src/base58.h
@@ -403,7 +403,7 @@ class CBitcoinSecret : public CBase58Data
{
public:
void SetSecret(const CSecret& vchSecret, bool fCompressed)
- {
+ {
assert(vchSecret.size() == 32);
SetData(fTestNet ? 239 : 128, &vchSecret[0], vchSecret.size());
if (fCompressed)
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index 84a6d6f896..1a3f51ea4d 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -761,17 +761,19 @@ void ThreadRPCServer2(void* parg)
const bool loopback = !mapArgs.count("-rpcallowip");
asio::ip::address bindAddress = loopback ? asio::ip::address_v6::loopback() : asio::ip::address_v6::any();
ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332));
+ boost::system::error_code v6_only_error;
+ boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(io_service));
boost::signals2::signal<void ()> StopRequests;
+ bool fListening = false;
+ std::string strerr;
try
{
- boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(io_service));
acceptor->open(endpoint.protocol());
acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
// Try making the socket dual IPv6/IPv4 (if listening on the "any" address)
- boost::system::error_code v6_only_error;
acceptor->set_option(boost::asio::ip::v6_only(loopback), v6_only_error);
acceptor->bind(endpoint);
@@ -783,8 +785,16 @@ void ThreadRPCServer2(void* parg)
static_cast<void (ip::tcp::acceptor::*)()>(&ip::tcp::acceptor::close), acceptor.get())
.track(acceptor));
+ fListening = true;
+ }
+ catch(boost::system::system_error &e)
+ {
+ strerr = strprintf(_("An error occurred while setting up the RPC port %i for listening on IPv6, falling back to IPv4: %s"), endpoint.port(), e.what());
+ }
+
+ try {
// If dual IPv6/IPv4 failed (or we're opening loopback interfaces only), open IPv4 separately
- if (loopback || v6_only_error)
+ if (!fListening || loopback || v6_only_error)
{
bindAddress = loopback ? asio::ip::address_v4::loopback() : asio::ip::address_v4::any();
endpoint.address(bindAddress);
@@ -800,12 +810,17 @@ void ThreadRPCServer2(void* parg)
StopRequests.connect(signals2::slot<void ()>(
static_cast<void (ip::tcp::acceptor::*)()>(&ip::tcp::acceptor::close), acceptor.get())
.track(acceptor));
+
+ fListening = true;
}
}
catch(boost::system::system_error &e)
{
- uiInterface.ThreadSafeMessageBox(strprintf(_("An error occurred while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()),
- _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL);
+ strerr = strprintf(_("An error occurred while setting up the RPC port %i for listening on IPv4: %s"), endpoint.port(), e.what());
+ }
+
+ if (!fListening) {
+ uiInterface.ThreadSafeMessageBox(strerr, _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL);
StartShutdown();
return;
}
@@ -968,7 +983,7 @@ void ThreadRPCServer3(void* parg)
strReply = JSONRPCExecBatch(valRequest.get_array());
else
throw JSONRPCError(-32700, "Top-level object parse error");
-
+
conn->stream() << HTTPReply(200, strReply, fRun) << std::flush;
}
catch (Object& objError)
diff --git a/src/clientversion.h b/src/clientversion.h
index 844eaa37bb..548105383c 100644
--- a/src/clientversion.h
+++ b/src/clientversion.h
@@ -9,7 +9,7 @@
#define CLIENT_VERSION_MAJOR 0
#define CLIENT_VERSION_MINOR 7
#define CLIENT_VERSION_REVISION 0
-#define CLIENT_VERSION_BUILD 2
+#define CLIENT_VERSION_BUILD 99
// Converts the parameter X to a string after macro replacement on X has been performed.
// Don't merge these into one macro!
diff --git a/src/db.cpp b/src/db.cpp
index 015e7ec2de..867703fbd2 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -281,7 +281,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
{ // surround usage of db with extra {}
CDB db(strFile.c_str(), "r");
Db* pdbCopy = new Db(&bitdb.dbenv, 0);
-
+
int ret = pdbCopy->open(NULL, // Txn pointer
strFileRes.c_str(), // Filename
"main", // Logical db name
@@ -293,7 +293,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
printf("Cannot create database file %s\n", strFileRes.c_str());
fSuccess = false;
}
-
+
Dbc* pcursor = db.GetCursor();
if (pcursor)
while (fSuccess)
diff --git a/src/key.h b/src/key.h
index 945c49989b..c98f52ed04 100644
--- a/src/key.h
+++ b/src/key.h
@@ -99,7 +99,7 @@ public:
};
-// secure_allocator is defined in serialize.h
+// secure_allocator is defined in allocators.h
// CPrivKey is a serialized private key, with all parameters included (279 bytes)
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
// CSecret is a serialization of just the secret parameter (32 bytes)
diff --git a/src/main.cpp b/src/main.cpp
index 302292ee29..fbaf05dfc7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -477,6 +477,55 @@ bool CTransaction::CheckTransaction() const
return true;
}
+int64 CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree,
+ enum GetMinFee_mode mode) const
+{
+ // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
+ int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
+
+ unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
+ unsigned int nNewBlockSize = nBlockSize + nBytes;
+ int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
+
+ if (fAllowFree)
+ {
+ if (nBlockSize == 1)
+ {
+ // Transactions under 10K are free
+ // (about 4500 BTC if made of 50 BTC inputs)
+ if (nBytes < 10000)
+ nMinFee = 0;
+ }
+ else
+ {
+ // Free transaction area
+ if (nNewBlockSize < 27000)
+ nMinFee = 0;
+ }
+ }
+
+ // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01
+ if (nMinFee < nBaseFee)
+ {
+ BOOST_FOREACH(const CTxOut& txout, vout)
+ if (txout.nValue < CENT)
+ nMinFee = nBaseFee;
+ }
+
+ // Raise the price as the block approaches full
+ if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
+ {
+ if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
+ return MAX_MONEY;
+ nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
+ }
+
+ if (!MoneyRange(nMinFee))
+ nMinFee = MAX_MONEY;
+ return nMinFee;
+}
+
+
bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs,
bool* pfMissingInputs)
{
@@ -563,8 +612,11 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs,
unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
// Don't accept it if it can't get into a block
- if (nFees < tx.GetMinFee(1000, true, GMF_RELAY))
- return error("CTxMemPool::accept() : not enough fees");
+ int64 txMinFee = tx.GetMinFee(1000, true, GMF_RELAY);
+ if (nFees < txMinFee)
+ return error("CTxMemPool::accept() : not enough fees %s, %"PRI64d" < %"PRI64d,
+ hash.ToString().c_str(),
+ nFees, txMinFee);
// Continuously rate-limit free transactions
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
@@ -1360,9 +1412,12 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
// See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information.
// This logic is not necessary for memory pool transactions, as AcceptToMemoryPool
// already refuses previously-known transaction ids entirely.
- // This rule applies to all blocks whose timestamp is after March 15, 2012, 0:00 UTC.
- int64 nBIP30SwitchTime = 1331769600;
- bool fEnforceBIP30 = (pindex->nTime > nBIP30SwitchTime);
+ // This rule was originally applied all blocks whose timestamp was after March 15, 2012, 0:00 UTC.
+ // Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
+ // two in the chain that violate it. This prevents exploiting the issue against nodes in their
+ // initial block download.
+ bool fEnforceBIP30 = !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
+ (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
// BIP16 didn't become active until Apr 1 2012
int64 nBIP16SwitchTime = 1333238400;
diff --git a/src/main.h b/src/main.h
index e61cbdd46b..2e208fed4f 100644
--- a/src/main.h
+++ b/src/main.h
@@ -540,53 +540,7 @@ public:
return dPriority > COIN * 144 / 250;
}
- int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, enum GetMinFee_mode mode=GMF_BLOCK) const
- {
- // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
- int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
-
- unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
- unsigned int nNewBlockSize = nBlockSize + nBytes;
- int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
-
- if (fAllowFree)
- {
- if (nBlockSize == 1)
- {
- // Transactions under 10K are free
- // (about 4500 BTC if made of 50 BTC inputs)
- if (nBytes < 10000)
- nMinFee = 0;
- }
- else
- {
- // Free transaction area
- if (nNewBlockSize < 27000)
- nMinFee = 0;
- }
- }
-
- // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01
- if (nMinFee < nBaseFee)
- {
- BOOST_FOREACH(const CTxOut& txout, vout)
- if (txout.nValue < CENT)
- nMinFee = nBaseFee;
- }
-
- // Raise the price as the block approaches full
- if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
- {
- if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
- return MAX_MONEY;
- nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
- }
-
- if (!MoneyRange(nMinFee))
- nMinFee = MAX_MONEY;
- return nMinFee;
- }
-
+ int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, enum GetMinFee_mode mode=GMF_BLOCK) const;
bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
{
@@ -799,7 +753,7 @@ public:
return !(a == b);
}
int GetDepthInMainChain() const;
-
+
};
diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw
index 4ba0cf06f0..2804f14055 100644
--- a/src/makefile.linux-mingw
+++ b/src/makefile.linux-mingw
@@ -111,6 +111,6 @@ clean:
-rm -f bitcoind.exe
-rm -f obj-test/*.o
-rm -f test_bitcoin.exe
- -rm -f src/build.h
+ -rm -f obj/build.h
FORCE:
diff --git a/src/makefile.mingw b/src/makefile.mingw
index 55c5b7e387..5cb2c84f4d 100644
--- a/src/makefile.mingw
+++ b/src/makefile.mingw
@@ -83,6 +83,9 @@ OBJS= \
all: bitcoind.exe
+test check: test_bitcoin.exe FORCE
+ test_bitcoin.exe
+
obj/%.o: %.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
@@ -101,4 +104,5 @@ clean:
-del /Q bitcoind test_bitcoin
-del /Q obj\*
-del /Q obj-test\*
- -del /Q build.h
+
+FORCE:
diff --git a/src/makefile.osx b/src/makefile.osx
index 2666caa918..359739bd5e 100644
--- a/src/makefile.osx
+++ b/src/makefile.osx
@@ -116,6 +116,9 @@ endif
all: bitcoind
+test check: test_bitcoin FORCE
+ ./test_bitcoin
+
# auto-generated dependencies:
-include obj/*.P
-include obj-test/*.P
@@ -153,6 +156,6 @@ clean:
-rm -f obj-test/*.o
-rm -f obj/*.P
-rm -f obj-test/*.P
- -rm -f src/build.h
+ -rm -f obj/build.h
FORCE:
diff --git a/src/makefile.unix b/src/makefile.unix
index 37a1917973..a41b57b4fc 100644
--- a/src/makefile.unix
+++ b/src/makefile.unix
@@ -132,6 +132,9 @@ OBJS= \
all: bitcoind
+test check: test_bitcoin FORCE
+ ./test_bitcoin
+
# auto-generated dependencies:
-include obj/*.P
-include obj-test/*.P
@@ -169,6 +172,6 @@ clean:
-rm -f obj-test/*.o
-rm -f obj/*.P
-rm -f obj-test/*.P
- -rm -f src/build.h
+ -rm -f obj/build.h
FORCE:
diff --git a/src/netbase.cpp b/src/netbase.cpp
index b66c366641..76a3d25d3a 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -246,7 +246,7 @@ bool static Socks5(string strDest, int port, SOCKET& hSocket)
string strSocks5("\5\1");
strSocks5 += '\000'; strSocks5 += '\003';
strSocks5 += static_cast<char>(std::min((int)strDest.size(), 255));
- strSocks5 += strDest;
+ strSocks5 += strDest;
strSocks5 += static_cast<char>((port >> 8) & 0xFF);
strSocks5 += static_cast<char>((port >> 0) & 0xFF);
ret = send(hSocket, strSocks5.c_str(), strSocks5.size(), MSG_NOSIGNAL);
@@ -478,7 +478,7 @@ bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
// first connect to proxy server
if (!ConnectSocketDirectly(proxy.first, hSocket, nTimeout))
return false;
-
+
// do socks negotiation
switch (proxy.second) {
case 4:
@@ -617,8 +617,8 @@ bool CNetAddr::IsIPv6() const
bool CNetAddr::IsRFC1918() const
{
return IsIPv4() && (
- GetByte(3) == 10 ||
- (GetByte(3) == 192 && GetByte(2) == 168) ||
+ GetByte(3) == 10 ||
+ (GetByte(3) == 192 && GetByte(2) == 168) ||
(GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31)));
}
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index cc60e2732b..4c3071984f 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -9,18 +9,8 @@ bool TransactionRecord::showTransaction(const CWalletTx &wtx)
{
if (wtx.IsCoinBase())
{
- // Don't show generated coin until confirmed by at least one block after it
- // so we don't get the user's hopes up until it looks like it's probably accepted.
- //
- // It is not an error when generated blocks are not accepted. By design,
- // some percentage of blocks, like 10% or more, will end up not accepted.
- // This is the normal mechanism by which the network copes with latency.
- //
- // We display regular transactions right away before any confirmation
- // because they can always get into some block eventually. Generated coins
- // are special because if their block is not accepted, they are not valid.
- //
- if (wtx.GetDepthInMainChain() < 2)
+ // Ensures we show generated coins / mined transactions at depth 1
+ if (!wtx.IsInMainChain())
{
return false;
}
diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp
index f0038dea9f..491297eb1d 100644
--- a/src/rpcnet.cpp
+++ b/src/rpcnet.cpp
@@ -61,7 +61,7 @@ Value getpeerinfo(const Array& params, bool fHelp)
ret.push_back(obj);
}
-
+
return ret;
}
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index 929dde9c15..3d0d05de84 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -573,7 +573,7 @@ Value movecmd(const Array& params, bool fHelp)
// Debit
CAccountingEntry debit;
- debit.nOrderPos = pwalletMain->nOrderPosNext++;
+ debit.nOrderPos = pwalletMain->IncOrderPosNext();
debit.strAccount = strFrom;
debit.nCreditDebit = -nAmount;
debit.nTime = nNow;
@@ -583,7 +583,7 @@ Value movecmd(const Array& params, bool fHelp)
// Credit
CAccountingEntry credit;
- credit.nOrderPos = pwalletMain->nOrderPosNext++;
+ credit.nOrderPos = pwalletMain->IncOrderPosNext();
credit.strAccount = strTo;
credit.nCreditDebit = nAmount;
credit.nTime = nNow;
diff --git a/src/serialize.h b/src/serialize.h
index abc4f04a0d..63df3160a6 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -243,7 +243,6 @@ uint64 ReadCompactSize(Stream& is)
#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
/** Wrapper for serializing arrays and POD.
- * There's a clever template way to make arrays serialize normally, but MSVC6 doesn't support it.
*/
class CFlatData
{
@@ -1010,57 +1009,6 @@ public:
}
};
-#ifdef TESTCDATASTREAM
-// VC6sp6
-// CDataStream:
-// n=1000 0 seconds
-// n=2000 0 seconds
-// n=4000 0 seconds
-// n=8000 0 seconds
-// n=16000 0 seconds
-// n=32000 0 seconds
-// n=64000 1 seconds
-// n=128000 1 seconds
-// n=256000 2 seconds
-// n=512000 4 seconds
-// n=1024000 8 seconds
-// n=2048000 16 seconds
-// n=4096000 32 seconds
-// stringstream:
-// n=1000 1 seconds
-// n=2000 1 seconds
-// n=4000 13 seconds
-// n=8000 87 seconds
-// n=16000 400 seconds
-// n=32000 1660 seconds
-// n=64000 6749 seconds
-// n=128000 27241 seconds
-// n=256000 109804 seconds
-#include <iostream>
-int main(int argc, char *argv[])
-{
- vector<unsigned char> vch(0xcc, 250);
- printf("CDataStream:\n");
- for (int n = 1000; n <= 4500000; n *= 2)
- {
- CDataStream ss;
- time_t nStart = time(NULL);
- for (int i = 0; i < n; i++)
- ss.write((char*)&vch[0], vch.size());
- printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);
- }
- printf("stringstream:\n");
- for (int n = 1000; n <= 4500000; n *= 2)
- {
- stringstream ss;
- time_t nStart = time(NULL);
- for (int i = 0; i < n; i++)
- ss.write((char*)&vch[0], vch.size());
- printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);
- }
-}
-#endif
-
diff --git a/src/sync.cpp b/src/sync.cpp
index 54ad7de4e6..1ac4403beb 100644
--- a/src/sync.cpp
+++ b/src/sync.cpp
@@ -105,7 +105,7 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
static void pop_lock()
{
- if (fDebug)
+ if (fDebug)
{
const CLockLocation& locklocation = (*lockstack).rbegin()->second;
printf("Unlocked: %s\n", locklocation.ToString().c_str());
diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp
index c474fd65c1..8ac657288b 100644
--- a/src/test/accounting_tests.cpp
+++ b/src/test/accounting_tests.cpp
@@ -60,7 +60,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
ae.nTime = 1333333330;
ae.strOtherAccount = "d";
- ae.nOrderPos = pwalletMain->nOrderPosNext++;
+ ae.nOrderPos = pwalletMain->IncOrderPosNext();
walletdb.WriteAccountingEntry(ae);
GetResults(walletdb, results);
diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json
index 432dd3f496..f01ee06cfa 100644
--- a/src/test/data/tx_invalid.json
+++ b/src/test/data/tx_invalid.json
@@ -21,6 +21,44 @@
["An invalid P2SH Transaction"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]],
-"010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", true]
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", true],
+["Tests for CTransaction::CheckTransaction()"],
+["No inputs"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]],
+"0100000000010000000000000000015100000000", true],
+
+["No outputs"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x05ab9e14d983742513f0f451e105ffb4198d1dd4 EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022100f16703104aab4e4088317c862daec83440242411b039d14280e03dd33b487ab802201318a7be236672c5c56083eb7a5a195bc57a40af7923ff8545016cd3b571e2a601232103c40e5d339df3f30bf753e7e04450ae4ef76c9e45587d1d993bdc4cd06f0651c7acffffffff0000000000", true],
+
+["Negative output"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xae609aca8061d77c5e111f6bb62501a6bbe2bfdb EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d4830450220063222cbb128731fc09de0d7323746539166544d6c1df84d867ccea84bcc8903022100bf568e8552844de664cd41648a031554327aa8844af34b4f27397c65b92c04de0123210243ec37dee0e2e053a9c976f43147e79bc7d9dc606ea51010af1ac80db6b069e1acffffffff01ffffffffffffffff015100000000", true],
+
+["MAX_MONEY + 1 output"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x32afac281462b822adbec5094b8d4d337dd5bd6a EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbacffffffff010140075af0750700015100000000", true],
+
+["MAX_MONEY output + 1 output"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xb558cbf4930954aa6a344363a15668d7477ae716 EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022027deccc14aa6668e78a8c9da3484fbcd4f9dcc9bb7d1b85146314b21b9ae4d86022100d0b43dece8cfb07348de0ca8bc5b86276fa88f7f2138381128b7c36ab2e42264012321029bb13463ddd5d2cc05da6e84e37536cb9525703cfd8f43afdb414988987a92f6acffffffff020040075af075070001510001000000000000015100000000", true],
+
+["Duplicate inputs"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x236d0639db62b0773fd8ac34dc85ae19e9aba80a EQUAL"]],
+"01000000020001000000000000000000000000000000000000000000000000000000000000000000006c47304402204bb1197053d0d7799bf1b30cd503c44b58d6240cccbdc85b6fe76d087980208f02204beeed78200178ffc6c74237bb74b3f276bbb4098b5605d814304fe128bf1431012321039e8815e15952a7c3fada1905f8cf55419837133bd7756c0ef14fc8dfe50c0deaacffffffff0001000000000000000000000000000000000000000000000000000000000000000000006c47304402202306489afef52a6f62e90bf750bbcdf40c06f5c6b138286e6b6b86176bb9341802200dba98486ea68380f47ebb19a7df173b99e6bc9c681d6ccf3bde31465d1f16b3012321039e8815e15952a7c3fada1905f8cf55419837133bd7756c0ef14fc8dfe50c0deaacffffffff010000000000000000015100000000", true],
+
+["Coinbase of size 1"],
+["Note the input is just required to make the tester happy"],
+[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]],
+"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0151ffffffff010000000000000000015100000000", true],
+
+["Coinbase of size 101"],
+["Note the input is just required to make the tester happy"],
+[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]],
+"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff655151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000", true],
+
+["Null txin"],
+[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "HASH160 0x14 0x02dae7dbbda56097959cba59b1989dd3e47937bf EQUAL"]],
+"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6e49304602210086f39e028e46dafa8e1e3be63906465f4cf038fbe5ed6403dc3e74ae876e6431022100c4625c675cfc5c7e3a0e0d7eaec92ac24da20c73a88eb40d09253e51ac6def5201232103a183ddc41e84753aca47723c965d1b5c8b0e2b537963518355e6dd6cf8415e50acffffffff010000000000000000015100000000", true]
]
diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json
index cc4b28f6b4..5528ae7243 100644
--- a/src/test/data/tx_valid.json
+++ b/src/test/data/tx_valid.json
@@ -48,5 +48,24 @@
["A valid P2SH Transaction using the standard transaction type put forth in BIP 16"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x8febbed40483661de6958d957412f82deed8e2f7 EQUAL"]],
-"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100c66c9cdf4c43609586d15424c54707156e316d88b0a1534c9e6b0d4f311406310221009c0fe51dbc9c4ab7cc25d3fdbeccf6679fe6827f08edf2b4a9f16ee3eb0e438a0123210338e8034509af564c62644c07691942e0c056752008a173c89f60ab2a88ac2ebfacffffffff010000000000000000015100000000", true]
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100c66c9cdf4c43609586d15424c54707156e316d88b0a1534c9e6b0d4f311406310221009c0fe51dbc9c4ab7cc25d3fdbeccf6679fe6827f08edf2b4a9f16ee3eb0e438a0123210338e8034509af564c62644c07691942e0c056752008a173c89f60ab2a88ac2ebfacffffffff010000000000000000015100000000", true],
+
+["Tests for CTransaction::CheckTransaction()"],
+["MAX_MONEY output"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x32afac281462b822adbec5094b8d4d337dd5bd6a EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbacffffffff010040075af0750700015100000000", true],
+
+["MAX_MONEY output + 0 output"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xb558cbf4930954aa6a344363a15668d7477ae716 EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022027deccc14aa6668e78a8c9da3484fbcd4f9dcc9bb7d1b85146314b21b9ae4d86022100d0b43dece8cfb07348de0ca8bc5b86276fa88f7f2138381128b7c36ab2e42264012321029bb13463ddd5d2cc05da6e84e37536cb9525703cfd8f43afdb414988987a92f6acffffffff020040075af075070001510000000000000000015100000000", true],
+
+["Coinbase of size 2"],
+["Note the input is just required to make the tester happy"],
+[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]],
+"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025151ffffffff010000000000000000015100000000", true],
+
+["Coinbase of size 100"],
+["Note the input is just required to make the tester happy"],
+[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]],
+"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6451515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000", true]
]
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index de6e18f14d..c230458866 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -66,6 +66,8 @@ BOOST_AUTO_TEST_CASE(tx_valid)
CTransaction tx;
stream >> tx;
+ BOOST_CHECK_MESSAGE(tx.CheckTransaction(), strTest);
+
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout))
@@ -131,7 +133,9 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
CTransaction tx;
stream >> tx;
- for (unsigned int i = 0; i < tx.vin.size(); i++)
+ fValid = tx.CheckTransaction();
+
+ for (unsigned int i = 0; i < tx.vin.size() && fValid; i++)
{
if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout))
{
@@ -139,8 +143,10 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
break;
}
- BOOST_CHECK_MESSAGE(!VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], tx, i, test[2].get_bool(), 0), strTest);
+ fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], tx, i, test[2].get_bool(), 0);
}
+
+ BOOST_CHECK_MESSAGE(!fValid, strTest);
}
}
}
diff --git a/src/util.h b/src/util.h
index 65923e68a3..2409ccb79c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -483,7 +483,7 @@ inline uint160 Hash160(const std::vector<unsigned char>& vch)
}
-/** Median filter over a stream of values.
+/** Median filter over a stream of values.
* Returns the median of the last N numbers
*/
template <typename T> class CMedianFilter
@@ -500,7 +500,7 @@ public:
vValues.push_back(initial_value);
vSorted = vValues;
}
-
+
void input(T value)
{
if(vValues.size() == nSize)
diff --git a/src/wallet.cpp b/src/wallet.cpp
index f88a0e1413..a10f187309 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -291,6 +291,13 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
return true;
}
+int64 CWallet::IncOrderPosNext()
+{
+ int64 nRet = nOrderPosNext;
+ CWalletDB(strWalletFile).WriteOrderPosNext(++nOrderPosNext);
+ return nRet;
+}
+
CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
{
CWalletDB walletdb(strWalletFile);
@@ -362,7 +369,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
if (fInsertedNew)
{
wtx.nTimeReceived = GetAdjustedTime();
- wtx.nOrderPos = nOrderPosNext++;
+ wtx.nOrderPos = IncOrderPosNext();
wtx.nTimeSmart = wtx.nTimeReceived;
if (wtxIn.hashBlock != 0)
@@ -953,7 +960,7 @@ int64 CWallet::GetImmatureBalance() const
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
const CWalletTx& pcoin = (*it).second;
- if (pcoin.IsCoinBase() && pcoin.GetBlocksToMaturity() > 0 && pcoin.GetDepthInMainChain() >= 2)
+ if (pcoin.IsCoinBase() && pcoin.GetBlocksToMaturity() > 0 && pcoin.IsInMainChain())
nTotal += GetCredit(pcoin);
}
}
diff --git a/src/wallet.h b/src/wallet.h
index 7fd33629fe..22795b75ba 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -98,6 +98,7 @@ public:
fFileBacked = false;
nMasterKeyMaxID = 0;
pwalletdbEncryption = NULL;
+ nOrderPosNext = 0;
}
CWallet(std::string strWalletFileIn)
{
@@ -107,6 +108,7 @@ public:
fFileBacked = true;
nMasterKeyMaxID = 0;
pwalletdbEncryption = NULL;
+ nOrderPosNext = 0;
}
std::map<uint256, CWalletTx> mapWallet;
@@ -144,6 +146,11 @@ public:
bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
bool EncryptWallet(const SecureString& strWalletPassphrase);
+ /** Increment the next transaction order id
+ @return next transaction order id
+ */
+ int64 IncOrderPosNext();
+
typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;
typedef std::multimap<int64, TxPair > TxItems;
@@ -346,7 +353,7 @@ static void WriteOrderPos(const int64& nOrderPos, mapValue_t& mapValue)
}
-/** A transaction with a bunch of additional info that only the owner cares about.
+/** A transaction with a bunch of additional info that only the owner cares about.
* It includes any unrecorded transactions needed to link it back to the block chain.
*/
class CWalletTx : public CMerkleTx
diff --git a/src/walletdb.cpp b/src/walletdb.cpp
index 164b68e11f..0fac0109c8 100644
--- a/src/walletdb.cpp
+++ b/src/walletdb.cpp
@@ -392,6 +392,10 @@ int CWalletDB::LoadWallet(CWallet* pwallet)
return DB_CORRUPT;
}
}
+ else if (strType == "orderposnext")
+ {
+ ssValue >> pwallet->nOrderPosNext;
+ }
}
pcursor->close();
}
diff --git a/src/walletdb.h b/src/walletdb.h
index 187be65a97..d339d4c3f1 100644
--- a/src/walletdb.h
+++ b/src/walletdb.h
@@ -115,6 +115,12 @@ public:
return Read(std::string("bestblock"), locator);
}
+ bool WriteOrderPosNext(int64 nOrderPosNext)
+ {
+ nWalletDBUpdated++;
+ return Write(std::string("orderposnext"), nOrderPosNext);
+ }
+
bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey)
{
vchPubKey.clear();