aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYING2
-rw-r--r--README.md37
-rw-r--r--doc/README.md2
-rw-r--r--doc/assets-attribution.md32
-rw-r--r--doc/developer-notes.md (renamed from doc/coding.md)48
-rw-r--r--doc/gitian-building.md2
-rw-r--r--src/Makefile.qt.include7
-rw-r--r--src/Makefile.test.include7
-rw-r--r--src/bitcoin-tx.cpp6
-rw-r--r--src/chainparams.cpp1
-rw-r--r--src/coins.cpp22
-rw-r--r--src/coins.h6
-rw-r--r--src/core_io.h1
-rw-r--r--src/core_read.cpp5
-rw-r--r--src/main.cpp149
-rw-r--r--src/main.h21
-rw-r--r--src/miner.cpp3
-rw-r--r--src/qt/forms/addressbookpage.ui2
-rw-r--r--src/qt/forms/optionsdialog.ui2
-rw-r--r--src/rpcmining.cpp3
-rw-r--r--src/rpcmisc.cpp5
-rw-r--r--src/rpcserver.cpp16
-rw-r--r--src/rpcwallet.cpp4
-rw-r--r--src/test/data/bitcoin-util-test.json10
-rw-r--r--src/test/data/txcreatesign.hex1
-rw-r--r--src/test/rpc_wallet_tests.cpp37
-rw-r--r--src/txmempool.cpp7
-rw-r--r--src/undo.h14
28 files changed, 257 insertions, 195 deletions
diff --git a/COPYING b/COPYING
index 6219bd75a6..9fd3266622 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Copyright (c) 2009-2014 Bitcoin Developers
+Copyright (c) 2009-2015 Bitcoin Developers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index cf650fe543..03a698996d 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ submitter will be asked to start a discussion (if they haven't already) on the
The patch will be accepted if there is broad consensus that it is a good thing.
Developers should expect to rework and resubmit patches if the code doesn't
-match the project's coding conventions (see [doc/coding.md](doc/coding.md)) or are
+match the project's coding conventions (see [doc/developer-notes.md](doc/developer-notes.md)) or are
controversial.
The `master` branch is regularly built and tested, but is not guaranteed to be
@@ -85,38 +85,3 @@ Translations are periodically pulled from Transifex and merged into the git repo
pull from Transifex would automatically overwrite them again.
Translators should also subscribe to the [mailing list](https://groups.google.com/forum/#!forum/bitcoin-translators).
-
-Development tips and tricks
----------------------------
-
-**compiling for debugging**
-
-Run configure with the --enable-debug option, then make. Or run configure with
-CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need.
-
-**debug.log**
-
-If the code is behaving strangely, take a look in the debug.log file in the data directory;
-error and debugging messages are written there.
-
-The -debug=... command-line option controls debugging; running with just -debug will turn
-on all categories (and give you a very large debug.log file).
-
-The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt
-to see it.
-
-**testnet and regtest modes**
-
-Run with the -testnet option to run with "play bitcoins" on the test network, if you
-are testing multi-machine code that needs to operate across the internet.
-
-If you are testing something that can run on one machine, run with the -regtest option.
-In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests
-that run in -regtest mode.
-
-**DEBUG_LOCKORDER**
-
-Bitcoin Core is a multithreaded application, and deadlocks or other multithreading bugs
-can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure
-CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of which locks
-are held, and adds warnings to the debug.log file if inconsistencies are detected.
diff --git a/doc/README.md b/doc/README.md
index ecb8dc80fd..1696518f87 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -51,7 +51,7 @@ Development
---------------------
The Bitcoin repo's [root README](https://github.com/bitcoin/bitcoin/blob/master/README.md) contains relevant information on the development process and automated testing.
-- [Coding Guidelines](coding.md)
+- [Developer Notes](developer-notes.md)
- [Multiwallet Qt Development](multiwallet-qt.md)
- [Release Notes](release-notes.md)
- [Release Process](release-process.md)
diff --git a/doc/assets-attribution.md b/doc/assets-attribution.md
index 6c5f91a834..31fe4e5b7a 100644
--- a/doc/assets-attribution.md
+++ b/doc/assets-attribution.md
@@ -1,14 +1,5 @@
The following is a list of assets used in the bitcoin source and their proper attribution.
-[Wladimir van der Laan](https://github.com/laanwj)
------------------------
-#### Info
-* License: MIT
-
-### Assets Used
- src/qt/res/icons/watch*.png, src/qt/res/icons/tx_in.png,
- src/qt/res/icons/tx_inout.png,
-
[Typicons/Stephen Hutchings](http://typicons.com)
-----------------------
@@ -30,7 +21,7 @@ The following is a list of assets used in the bitcoin source and their proper at
src/qt/res/icons/overview.png, src/qt/res/icons/quit.png,
src/qt/res/icons/receive.png, src/qt/res/icons/remove.png,
src/qt/res/icons/send.png, src/qt/res/icons/synced.png,
- src/qt/res/icons/transaction*.png, src/qt/res/icons/tx_input.png,
+ src/qt/res/icons/transaction*.png, src/qt/res/icons/tx_output.png,
Jonas Schnelli
-----------------------
@@ -38,18 +29,19 @@ Jonas Schnelli
### Info
* Designer: Jonas Schnelli
* Bitcoin Icon: (based on the original bitcoin logo from Bitboy)
-* Some icons are based on Stephan Hutchings Typicons
+* Some icons are based on Stephan Hutchings Typicons (these are under CC BY-SA license)
* License: MIT
### Assets Used
src/qt/res/icons/about.png, src/qt/res/icons/about_qt.png,
- src/qt/res/icons/clock*.png, src/qt/res/icons/connect[0-3].png,
- src/qt/res/icons/eye_minus.png, src/qt/res/icons/verify.png,
- src/qt/res/icons/eye_plus.png, src/qt/res/icons/tx_inout.png,
- src/qt/res/icons/tx_output.png, src/qt/res/icons/bitcoin.icns,
- src/qt/res/src/bitcoin.svg, src/qt/res/src/bitcoin.ico,
- src/qt/res/src/bitcoin.png, src/qt/res/src/bitcoin_testnet.png,
- docs/bitcoin_logo_doxygen.png, src/qt/res/src/tx*.svg,
- src/qt/res/src/connect*.svg, src/qt/res/src/clock*.svg,
- src/qt/res/src/mine.svg, src/qt/res/src/qt.svg,
+ src/qt/res/icons/bitcoin.icns, src/qt/res/icons/bitcoin.ico,
+ src/qt/res/icons/bitcoin.png, src/qt/res/icons/clock*.png,
+ src/qt/res/icons/connect[0-3].png, src/qt/res/icons/eye_minus.png,
+ src/qt/res/icons/eye_plus.png, src/qt/res/icons/verify.png,
+ src/qt/res/icons/tx_inout.png, src/qt/res/icons/tx_input.png,
+ src/qt/res/icons/unit_btc.png, src/qt/res/icons/unit_mbtc.png,
+ src/qt/res/icons/unit_ubtc.png, src/qt/res/src/verify.svg
+ src/qt/res/src/bitcoin.svg, src/qt/res/src/clock*.svg,
+ src/qt/res/src/connect*.svg, src/qt/res/src/mine.svg,
+ src/qt/res/src/qt.svg, src/qt/res/src/tx*.svg,
src/qt/res/src/verify.svg,
diff --git a/doc/coding.md b/doc/developer-notes.md
index 43294dbe4c..eaeb90da1d 100644
--- a/doc/coding.md
+++ b/doc/developer-notes.md
@@ -89,6 +89,41 @@ Not OK (used plenty in the current source, but not picked up):
A full list of comment syntaxes picked up by doxygen can be found at http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html,
but if possible use one of the above styles.
+Development tips and tricks
+---------------------------
+
+**compiling for debugging**
+
+Run configure with the --enable-debug option, then make. Or run configure with
+CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need.
+
+**debug.log**
+
+If the code is behaving strangely, take a look in the debug.log file in the data directory;
+error and debugging messages are written there.
+
+The -debug=... command-line option controls debugging; running with just -debug will turn
+on all categories (and give you a very large debug.log file).
+
+The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt
+to see it.
+
+**testnet and regtest modes**
+
+Run with the -testnet option to run with "play bitcoins" on the test network, if you
+are testing multi-machine code that needs to operate across the internet.
+
+If you are testing something that can run on one machine, run with the -regtest option.
+In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests
+that run in -regtest mode.
+
+**DEBUG_LOCKORDER**
+
+Bitcoin Core is a multithreaded application, and deadlocks or other multithreading bugs
+can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure
+CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of which locks
+are held, and adds warnings to the debug.log file if inconsistencies are detected.
+
Locking/mutex usage notes
-------------------------
@@ -136,3 +171,16 @@ Threads
- BitcoinMiner : Generates bitcoins (if wallet is enabled).
- Shutdown : Does an orderly shutdown of everything.
+
+Pull Request Terminology
+------------------------
+
+Concept ACK - Agree with the idea and overall direction, but haven't reviewed the code changes or tested them.
+
+utACK (untested ACK) - Reviewed and agree with the code changes but haven't actually tested them.
+
+Tested ACK - Reviewed the code changes and have verified the functionality or bug fix.
+
+ACK - A loose ACK can be confusing. It's best to avoid them unless it's a documentation/comment only change in which case there is nothing to test/verify; therefore the tested/untested distinction is not there.
+
+NACK - Disagree with the code changes/concept. Should be accompanied by an explanation.
diff --git a/doc/gitian-building.md b/doc/gitian-building.md
index defddedc6e..1312979cac 100644
--- a/doc/gitian-building.md
+++ b/doc/gitian-building.md
@@ -83,7 +83,7 @@ Unixy OSes by entering the following in a terminal:
After creating the VM, we need to configure it.
-- Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attacked to `NAT`.
+- Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attached to `NAT`.
![](gitian-building/network_settings.png)
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 806b4f9556..1192b7bd4e 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -278,8 +278,11 @@ BITCOIN_QT_CPP = \
qt/scicon.cpp \
qt/splashscreen.cpp \
qt/trafficgraphwidget.cpp \
- qt/utilitydialog.cpp \
- qt/winshutdownmonitor.cpp
+ qt/utilitydialog.cpp
+
+if TARGET_WINDOWS
+BITCOIN_QT_CPP += qt/winshutdownmonitor.cpp
+endif
if ENABLE_WALLET
BITCOIN_QT_CPP += \
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 9e9f478d8f..5f388e2806 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -1,4 +1,4 @@
-TESTS += test/test_bitcoin test/bitcoin-util-test.py
+TESTS += test/test_bitcoin
bin_PROGRAMS += test/test_bitcoin
TEST_SRCDIR = test
TEST_BINARY=test/test_bitcoin$(EXEEXT)
@@ -14,7 +14,8 @@ EXTRA_DIST += \
test/data/tt-locktime317000-out.hex \
test/data/tx394b54bb.hex \
test/data/txcreate1.hex \
- test/data/txcreate2.hex
+ test/data/txcreate2.hex \
+ test/data/txcreatesign.hex
JSON_TEST_FILES = \
test/data/script_valid.json \
@@ -105,6 +106,8 @@ bitcoin_test_clean : FORCE
rm -f $(CLEAN_BITCOIN_TEST) $(test_test_bitcoin_OBJECTS) $(TEST_BINARY)
check-local:
+ @echo "Running test/bitcoin-util-test.py..."
+ $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
%.json.h: %.json
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index 337cd44cd9..05a85810ec 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -368,7 +368,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
// Add previous txouts given in the RPC call:
if (!registers.count("prevtxs"))
throw runtime_error("prevtxs register variable must be set.");
- UniValue prevtxsObj = registers["privatekeys"];
+ UniValue prevtxsObj = registers["prevtxs"];
{
for (unsigned int previdx = 0; previdx < prevtxsObj.count(); previdx++) {
UniValue prevOut = prevtxsObj[previdx];
@@ -379,13 +379,13 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
if (!prevOut.checkObject(types))
throw runtime_error("prevtxs internal object typecheck fail");
- uint256 txid = ParseHashUV(prevOut, "txid");
+ uint256 txid = ParseHashUV(prevOut["txid"], "txid");
int nOut = atoi(prevOut["vout"].getValStr());
if (nOut < 0)
throw runtime_error("vout must be positive");
- vector<unsigned char> pkData(ParseHexUV(prevOut, "scriptPubKey"));
+ vector<unsigned char> pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey"));
CScript scriptPubKey(pkData.begin(), pkData.end());
{
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 7562509bd5..f4bc6e1d70 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -156,7 +156,6 @@ public:
vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me"));
vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org"));
vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com"));
- vSeeds.push_back(CDNSSeedData("bitnodes.io", "seed.bitnodes.io"));
vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org"));
base58Prefixes[PUBKEY_ADDRESS] = list_of(0);
diff --git a/src/coins.cpp b/src/coins.cpp
index bc430c9c7e..f4599ff39d 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -31,29 +31,15 @@ void CCoins::CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) con
nBytes += nLastUsedByte;
}
-bool CCoins::Spend(const COutPoint &out, CTxInUndo &undo) {
- if (out.n >= vout.size())
- return false;
- if (vout[out.n].IsNull())
+bool CCoins::Spend(uint32_t nPos)
+{
+ if (nPos >= vout.size() || vout[nPos].IsNull())
return false;
- undo = CTxInUndo(vout[out.n]);
- vout[out.n].SetNull();
+ vout[nPos].SetNull();
Cleanup();
- if (vout.size() == 0) {
- undo.nHeight = nHeight;
- undo.fCoinBase = fCoinBase;
- undo.nVersion = this->nVersion;
- }
return true;
}
-bool CCoins::Spend(int nPos) {
- CTxInUndo undo;
- COutPoint out(0, nPos);
- return Spend(out, undo);
-}
-
-
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
uint256 CCoinsView::GetBestBlock() const { return uint256(0); }
diff --git a/src/coins.h b/src/coins.h
index 9b73ae3a87..2be52ad171 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -9,7 +9,6 @@
#include "compressor.h"
#include "serialize.h"
#include "uint256.h"
-#include "undo.h"
#include <assert.h>
#include <stdint.h>
@@ -237,11 +236,8 @@ public:
Cleanup();
}
- //! mark an outpoint spent, and construct undo information
- bool Spend(const COutPoint &out, CTxInUndo &undo);
-
//! mark a vout spent
- bool Spend(int nPos);
+ bool Spend(uint32_t nPos);
//! check whether a particular output is still available
bool IsAvailable(unsigned int nPos) const {
diff --git a/src/core_io.h b/src/core_io.h
index e0620e86b6..0989cf7437 100644
--- a/src/core_io.h
+++ b/src/core_io.h
@@ -19,6 +19,7 @@ extern CScript ParseScript(std::string s);
extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx);
extern bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
extern uint256 ParseHashUV(const UniValue& v, const std::string& strName);
+extern uint256 ParseHashStr(const std::string&, const std::string& strName);
extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
// core_write.cpp
diff --git a/src/core_read.cpp b/src/core_read.cpp
index a49705e045..7999030662 100644
--- a/src/core_read.cpp
+++ b/src/core_read.cpp
@@ -131,6 +131,11 @@ uint256 ParseHashUV(const UniValue& v, const string& strName)
string strHex;
if (v.isStr())
strHex = v.getValStr();
+ return ParseHashStr(strHex, strName); // Note: ParseHashStr("") throws a runtime_error
+}
+
+uint256 ParseHashStr(const std::string& strHex, const std::string& strName)
+{
if (!IsHex(strHex)) // Note: IsHex("") is false
throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");
diff --git a/src/main.cpp b/src/main.cpp
index 2410230ef4..5c0f0116d6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -17,6 +17,7 @@
#include "txdb.h"
#include "txmempool.h"
#include "ui_interface.h"
+#include "undo.h"
#include "util.h"
#include "utilmoneystr.h"
@@ -926,11 +927,11 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
*pfMissingInputs = false;
if (!CheckTransaction(tx, state))
- return error("AcceptToMemoryPool: : CheckTransaction failed");
+ return error("AcceptToMemoryPool: CheckTransaction failed");
// Coinbase is only valid in a block, not as a loose transaction
if (tx.IsCoinBase())
- return state.DoS(100, error("AcceptToMemoryPool: : coinbase as individual tx"),
+ return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),
REJECT_INVALID, "coinbase");
// Rather not work on nonstandard transactions (unless -testnet/-regtest)
@@ -1000,7 +1001,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Check for non-standard pay-to-script-hash in inputs
if (Params().RequireStandard() && !AreInputsStandard(tx, view))
- return error("AcceptToMemoryPool: : nonstandard transaction input");
+ return error("AcceptToMemoryPool: nonstandard transaction input");
// Check that the transaction doesn't have an excessive number of
// sigops, making it impossible to mine. Since the coinbase transaction
@@ -1076,7 +1077,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// can be exploited as a DoS attack.
if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
{
- return error("AcceptToMemoryPool: : BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
+ return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
}
// Store transaction in memory
@@ -1383,9 +1384,20 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
if (!tx.IsCoinBase()) {
txundo.vprevout.reserve(tx.vin.size());
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
- txundo.vprevout.push_back(CTxInUndo());
- bool ret = inputs.ModifyCoins(txin.prevout.hash)->Spend(txin.prevout, txundo.vprevout.back());
- assert(ret);
+ CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
+ unsigned nPos = txin.prevout.n;
+
+ if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
+ assert(false);
+ // mark an outpoint spent, and construct undo information
+ txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
+ coins->Spend(nPos);
+ if (coins->vout.size() == 0) {
+ CTxInUndo& undo = txundo.vprevout.back();
+ undo.nHeight = coins->nHeight;
+ undo.fCoinBase = coins->fCoinBase;
+ undo.nVersion = coins->nVersion;
+ }
}
}
@@ -1393,6 +1405,12 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight);
}
+void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight)
+{
+ CTxUndo txundo;
+ UpdateCoins(tx, state, inputs, txundo, nHeight);
+}
+
bool CScriptCheck::operator()() {
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingSignatureChecker(*ptxTo, nIn, cacheStore), &error)) {
@@ -1503,7 +1521,63 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
return true;
}
+namespace {
+
+bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock)
+{
+ // Open history file to append
+ CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
+ if (fileout.IsNull())
+ return error("%s : OpenUndoFile failed", __func__);
+
+ // Write index header
+ unsigned int nSize = fileout.GetSerializeSize(blockundo);
+ fileout << FLATDATA(Params().MessageStart()) << nSize;
+
+ // Write undo data
+ long fileOutPos = ftell(fileout.Get());
+ if (fileOutPos < 0)
+ return error("%s : ftell failed", __func__);
+ pos.nPos = (unsigned int)fileOutPos;
+ fileout << blockundo;
+
+ // calculate & write checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << blockundo;
+ fileout << hasher.GetHash();
+ return true;
+}
+
+bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
+{
+ // Open history file to read
+ CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
+ if (filein.IsNull())
+ return error("%s : OpenBlockFile failed", __func__);
+
+ // Read block
+ uint256 hashChecksum;
+ try {
+ filein >> blockundo;
+ filein >> hashChecksum;
+ }
+ catch (const std::exception& e) {
+ return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ }
+
+ // Verify checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << blockundo;
+ if (hashChecksum != hasher.GetHash())
+ return error("%s : Checksum mismatch", __func__);
+
+ return true;
+}
+
+} // anon namespace
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
{
@@ -1518,7 +1592,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
CDiskBlockPos pos = pindex->GetUndoPos();
if (pos.IsNull())
return error("DisconnectBlock() : no undo data available");
- if (!blockUndo.ReadFromDisk(pos, pindex->pprev->GetBlockHash()))
+ if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
return error("DisconnectBlock() : failure reading undo data");
if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
@@ -1760,7 +1834,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
CDiskBlockPos pos;
if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
return error("ConnectBlock() : FindUndoPos failed");
- if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash()))
+ if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash()))
return state.Abort("Failed to write undo data");
// update nUndoPos in block index
@@ -2926,7 +3000,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
CBlockUndo undo;
CDiskBlockPos pos = pindex->GetUndoPos();
if (!pos.IsNull()) {
- if (!undo.ReadFromDisk(pos, pindex->pprev->GetBlockHash()))
+ if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
}
}
@@ -4491,61 +4565,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
return true;
}
-
-bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock)
-{
- // Open history file to append
- CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
- if (fileout.IsNull())
- return error("CBlockUndo::WriteToDisk : OpenUndoFile failed");
-
- // Write index header
- unsigned int nSize = fileout.GetSerializeSize(*this);
- fileout << FLATDATA(Params().MessageStart()) << nSize;
-
- // Write undo data
- long fileOutPos = ftell(fileout.Get());
- if (fileOutPos < 0)
- return error("CBlockUndo::WriteToDisk : ftell failed");
- pos.nPos = (unsigned int)fileOutPos;
- fileout << *this;
-
- // calculate & write checksum
- CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
- hasher << hashBlock;
- hasher << *this;
- fileout << hasher.GetHash();
-
- return true;
-}
-
-bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock)
-{
- // Open history file to read
- CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
- if (filein.IsNull())
- return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed");
-
- // Read block
- uint256 hashChecksum;
- try {
- filein >> *this;
- filein >> hashChecksum;
- }
- catch (const std::exception& e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
- }
-
- // Verify checksum
- CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
- hasher << hashBlock;
- hasher << *this;
- if (hashChecksum != hasher.GetHash())
- return error("CBlockUndo::ReadFromDisk : Checksum mismatch");
-
- return true;
-}
-
std::string CBlockFileInfo::ToString() const {
return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast));
}
diff --git a/src/main.h b/src/main.h
index 662d5756f7..9049f5bb7d 100644
--- a/src/main.h
+++ b/src/main.h
@@ -25,7 +25,6 @@
#include "tinyformat.h"
#include "txmempool.h"
#include "uint256.h"
-#include "undo.h"
#include <algorithm>
#include <exception>
@@ -290,7 +289,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks = NULL);
/** Apply the effects of this transaction on the UTXO set represented by view */
-void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight);
+void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight);
/** Context-independent validity checks */
bool CheckTransaction(const CTransaction& tx, CValidationState& state);
@@ -302,24 +301,6 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason);
bool IsFinalTx(const CTransaction &tx, int nBlockHeight = 0, int64_t nBlockTime = 0);
-/** Undo information for a CBlock */
-class CBlockUndo
-{
-public:
- std::vector<CTxUndo> vtxundo; // for all but the coinbase
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(vtxundo);
- }
-
- bool WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock);
- bool ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock);
-};
-
-
/**
* Closure representing one script verification
* Note that this stores references to the spending transaction
diff --git a/src/miner.cpp b/src/miner.cpp
index 2133b13e62..0ac974d6e1 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -279,8 +279,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
continue;
- CTxUndo txundo;
- UpdateCoins(tx, state, view, txundo, nHeight);
+ UpdateCoins(tx, state, view, nHeight);
// Added
pblock->vtx.push_back(tx);
diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui
index 52fdc6ef06..264edeb720 100644
--- a/src/qt/forms/addressbookpage.ui
+++ b/src/qt/forms/addressbookpage.ui
@@ -27,7 +27,7 @@
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="toolTip">
- <string>Double-click to edit address or label</string>
+ <string>Right-click to edit address or label</string>
</property>
<property name="tabKeyNavigation">
<bool>false</bool>
diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui
index 19421dc813..55c4f5ac58 100644
--- a/src/qt/forms/optionsdialog.ui
+++ b/src/qt/forms/optionsdialog.ui
@@ -330,7 +330,7 @@
<item>
<widget class="QCheckBox" name="minimizeOnClose">
<property name="toolTip">
- <string>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</string>
+ <string>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</string>
</property>
<property name="text">
<string>M&amp;inimize on close</string>
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index 17552bc388..35760f9af0 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -288,8 +288,7 @@ Value prioritisetransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
);
- uint256 hash;
- hash.SetHex(params[0].get_str());
+ uint256 hash = ParseHashStr(params[0].get_str(), "txid");
CAmount nAmount = params[2].get_int64();
diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp
index b8805b9d51..7c08a5c246 100644
--- a/src/rpcmisc.cpp
+++ b/src/rpcmisc.cpp
@@ -162,6 +162,7 @@ Value validateaddress(const Array& params, bool fHelp)
"{\n"
" \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
" \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
+ " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
" \"ismine\" : true|false, (boolean) If the address is yours or not\n"
" \"isscript\" : true|false, (boolean) If the key is a script\n"
" \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
@@ -183,6 +184,10 @@ Value validateaddress(const Array& params, bool fHelp)
CTxDestination dest = address.Get();
string currentAddress = address.ToString();
ret.push_back(Pair("address", currentAddress));
+
+ CScript scriptPubKey = GetScriptForDestination(dest);
+ ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
+
#ifdef ENABLE_WALLET
isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index c5d74afba9..210c7fe973 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -650,14 +650,16 @@ void StartRPCThreads()
bool fListening = false;
std::string strerr;
+ std::string straddress;
BOOST_FOREACH(const ip::tcp::endpoint &endpoint, vEndpoints)
{
- asio::ip::address bindAddress = endpoint.address();
- LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", bindAddress.to_string(), endpoint.port(), bBindAny);
- boost::system::error_code v6_only_error;
- boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
-
try {
+ asio::ip::address bindAddress = endpoint.address();
+ straddress = bindAddress.to_string();
+ LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", straddress, endpoint.port(), bBindAny);
+ boost::system::error_code v6_only_error;
+ boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
+
acceptor->open(endpoint.protocol());
acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
@@ -678,8 +680,8 @@ void StartRPCThreads()
}
catch (const boost::system::system_error& e)
{
- LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", bindAddress.to_string(), endpoint.port(), e.what());
- strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), bindAddress.to_string(), endpoint.port(), e.what());
+ LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", straddress, endpoint.port(), e.what());
+ strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), straddress, endpoint.port(), e.what());
}
}
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index 63da8a20b5..56be6dba13 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -1103,7 +1103,7 @@ Value listreceivedbyaddress(const Array& params, bool fHelp)
"\nResult:\n"
"[\n"
" {\n"
- " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n"
+ " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
" \"address\" : \"receivingaddress\", (string) The receiving address\n"
" \"account\" : \"accountname\", (string) The account of the receiving address. The default account is \"\".\n"
" \"amount\" : x.xxx, (numeric) The total amount in btc received by the address\n"
@@ -1135,7 +1135,7 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
"\nResult:\n"
"[\n"
" {\n"
- " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n"
+ " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
" \"account\" : \"accountname\", (string) The account name of the receiving account\n"
" \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
" \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n"
diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json
index f8424b72a3..6090421cb6 100644
--- a/src/test/data/bitcoin-util-test.json
+++ b/src/test/data/bitcoin-util-test.json
@@ -46,5 +46,15 @@
{ "exec": "./bitcoin-tx",
"args": ["-create", "outscript=0:"],
"output_cmp": "txcreate2.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
+ "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
+ "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\"}]",
+ "sign=ALL",
+ "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
+ "output_cmp": "txcreatesign.hex"
}
]
diff --git a/src/test/data/txcreatesign.hex b/src/test/data/txcreatesign.hex
new file mode 100644
index 0000000000..56ce28a865
--- /dev/null
+++ b/src/test/data/txcreatesign.hex
@@ -0,0 +1 @@
+01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d0000000000ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000
diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp
index a83bd120ca..57c49c2dfc 100644
--- a/src/test/rpc_wallet_tests.cpp
+++ b/src/test/rpc_wallet_tests.cpp
@@ -93,6 +93,13 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
/* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */
BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error);
+
+ /*********************************
+ * getbalance
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("getbalance"));
+ BOOST_CHECK_NO_THROW(CallRPC("getbalance " + demoAddress.ToString()));
+
/*********************************
* listunspent
*********************************/
@@ -125,6 +132,35 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error);
/*********************************
+ * listsinceblock
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listsinceblock"));
+
+ /*********************************
+ * listtransactions
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions"));
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString()));
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20"));
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20 0"));
+ BOOST_CHECK_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " not_int"), runtime_error);
+
+ /*********************************
+ * listlockunspent
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listlockunspent"));
+
+ /*********************************
+ * listaccounts
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listaccounts"));
+
+ /*********************************
+ * listaddressgroupings
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listaddressgroupings"));
+
+ /*********************************
* getrawchangeaddress
*********************************/
BOOST_CHECK_NO_THROW(CallRPC("getrawchangeaddress"));
@@ -179,5 +215,4 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get());
}
-
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 3071ab025c..01bf1ec080 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -585,9 +585,9 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
if (fDependsWait)
waitingOnDependants.push_back(&it->second);
else {
- CValidationState state; CTxUndo undo;
+ CValidationState state;
assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL));
- UpdateCoins(tx, state, mempoolDuplicate, undo, 1000000);
+ UpdateCoins(tx, state, mempoolDuplicate, 1000000);
}
}
unsigned int stepsSinceLastRemove = 0;
@@ -601,8 +601,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
assert(stepsSinceLastRemove < waitingOnDependants.size());
} else {
assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, NULL));
- CTxUndo undo;
- UpdateCoins(entry->GetTx(), state, mempoolDuplicate, undo, 1000000);
+ UpdateCoins(entry->GetTx(), state, mempoolDuplicate, 1000000);
stepsSinceLastRemove = 0;
}
}
diff --git a/src/undo.h b/src/undo.h
index e6d8fd5862..1c4ed95bf2 100644
--- a/src/undo.h
+++ b/src/undo.h
@@ -68,4 +68,18 @@ public:
}
};
+/** Undo information for a CBlock */
+class CBlockUndo
+{
+public:
+ std::vector<CTxUndo> vtxundo; // for all but the coinbase
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(vtxundo);
+ }
+};
+
#endif // BITCOIN_UNDO_H