aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuke Dashjr <luke-jr+git@utopios.org>2012-02-02 20:17:56 -0500
committerLuke Dashjr <luke-jr+git@utopios.org>2012-02-02 20:17:56 -0500
commit06e0f79ae5a4c2c7b3c8232c4544307d4d4940a5 (patch)
tree58feec8d8197ddf8d3c83ea52d55496159738833 /src
parent71208749839962c41b02101f27a2dd61fb1a7e73 (diff)
parent882e00e2159ce5e12170c7c1811236a039d8abfa (diff)
downloadbitcoin-06e0f79ae5a4c2c7b3c8232c4544307d4d4940a5.tar.xz
Merge branch '0.5.0.x' into 0.5.x
Diffstat (limited to 'src')
-rw-r--r--src/db.cpp4
-rw-r--r--src/init.cpp15
-rw-r--r--src/key.h11
-rw-r--r--src/main.cpp60
-rw-r--r--src/main.h3
-rw-r--r--src/makefile.osx21
-rw-r--r--src/makefile.unix16
-rw-r--r--src/net.cpp24
-rw-r--r--src/obj-test/.gitignore2
-rw-r--r--src/qt/bitcoingui.cpp5
-rw-r--r--src/qt/sendcoinsdialog.cpp7
-rw-r--r--src/qt/sendcoinsentry.cpp5
-rw-r--r--src/qt/sendcoinsentry.h2
13 files changed, 135 insertions, 40 deletions
diff --git a/src/db.cpp b/src/db.cpp
index 9ac93b3506..c2d18279da 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -861,12 +861,16 @@ int CWalletDB::LoadWallet(CWallet* pwallet)
CPrivKey pkey;
ssValue >> pkey;
key.SetPrivKey(pkey);
+ if (key.GetPubKey() != vchPubKey || !key.IsValid())
+ return DB_CORRUPT;
}
else
{
CWalletKey wkey;
ssValue >> wkey;
key.SetPrivKey(wkey.vchPrivKey);
+ if (key.GetPubKey() != vchPubKey || !key.IsValid())
+ return DB_CORRUPT;
}
if (!pwallet->LoadKey(key))
return DB_CORRUPT;
diff --git a/src/init.cpp b/src/init.cpp
index fc171cd48e..f8a63d26de 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -484,16 +484,11 @@ bool AppInit2(int argc, char* argv[])
fAllowDNS = GetBoolArg("-dns");
fNoListen = GetBoolArg("-nolisten");
- if (fHaveUPnP)
- {
-#if USE_UPNP
- if (GetBoolArg("-noupnp"))
- fUseUPnP = false;
-#else
- if (GetBoolArg("-upnp"))
- fUseUPnP = true;
-#endif
- }
+ // Command-line args override in-wallet settings:
+ if (mapArgs.count("-upnp"))
+ fUseUPnP = GetBoolArg("-upnp");
+ else if (mapArgs.count("-noupnp"))
+ fUseUPnP = !GetBoolArg("-noupnp");
if (!fNoListen)
{
diff --git a/src/key.h b/src/key.h
index df5cfeb32c..010591632e 100644
--- a/src/key.h
+++ b/src/key.h
@@ -387,6 +387,17 @@ public:
{
return CBitcoinAddress(GetPubKey());
}
+
+ bool IsValid()
+ {
+ if (!fSet)
+ return false;
+
+ CSecret secret = GetSecret();
+ CKey key2;
+ key2.SetSecret(secret);
+ return GetPubKey() == key2.GetPubKey();
+ }
};
#endif
diff --git a/src/main.cpp b/src/main.cpp
index 1f23844573..07b07447c1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -418,10 +418,11 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
// Check against previous transactions
map<uint256, CTxIndex> mapUnused;
int64 nFees = 0;
- if (!ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false))
+ bool fInvalid = false;
+ if (!ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false, 0, fInvalid))
{
- if (pfMissingInputs)
- *pfMissingInputs = true;
+ if (fInvalid)
+ return error("AcceptToMemoryPool() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str());
return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
}
@@ -668,6 +669,11 @@ static const int64 nInterval = nTargetTimespan / nTargetSpacing;
//
unsigned int ComputeMinWork(unsigned int nBase, int64 nTime)
{
+ // Testnet has min-difficulty blocks
+ // after nTargetSpacing*2 time between blocks:
+ if (fTestNet && nTime > nTargetSpacing*2)
+ return bnProofOfWorkLimit.GetCompact();
+
CBigNum bnResult;
bnResult.SetCompact(nBase);
while (nTime > 0 && bnResult < bnProofOfWorkLimit)
@@ -682,16 +688,36 @@ unsigned int ComputeMinWork(unsigned int nBase, int64 nTime)
return bnResult.GetCompact();
}
-unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast)
+unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlock *pblock)
{
+ unsigned int nProofOfWorkLimit = bnProofOfWorkLimit.GetCompact();
// Genesis block
if (pindexLast == NULL)
- return bnProofOfWorkLimit.GetCompact();
+ return nProofOfWorkLimit;
// Only change once per interval
if ((pindexLast->nHeight+1) % nInterval != 0)
+ {
+ // Special rules for testnet after 15 Feb 2012:
+ if (fTestNet && pblock->nTime > 1329264000)
+ {
+ // If the new block's timestamp is more than 2* 10 minutes
+ // then allow mining of a min-difficulty block.
+ if (pblock->nTime - pindexLast->nTime > nTargetSpacing*2)
+ return nProofOfWorkLimit;
+ else
+ {
+ // Return the last non-special-min-difficulty-rules-block
+ const CBlockIndex* pindex = pindexLast;
+ while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit)
+ pindex = pindex->pprev;
+ return pindex->nBits;
+ }
+ }
+
return pindexLast->nBits;
+ }
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
@@ -821,8 +847,15 @@ bool CTransaction::DisconnectInputs(CTxDB& txdb)
bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
- CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee)
+ CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
+ bool& fInvalid)
{
+ // FetchInputs can return false either because we just haven't seen some inputs
+ // (in which case the transaction should be stored as an orphan)
+ // or because the transaction is malformed (in which case the transaction should
+ // be dropped). If tx is definitely invalid, fInvalid will be set to true.
+ fInvalid = false;
+
// Take over previous transactions' spent pointers
// fBlock is true when this is called from AcceptBlock when a new best-block is added to the blockchain
// fMiner is true when called from the internal bitcoin miner
@@ -872,7 +905,12 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo
}
if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
+ {
+ // Revisit this if/when transaction replacement is implemented and allows
+ // adding inputs:
+ fInvalid = true;
return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str()));
+ }
// If prev is coinbase, check that it's matured
if (txPrev.IsCoinBase())
@@ -1022,7 +1060,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
nTxPos += ::GetSerializeSize(tx, SER_DISK);
- if (!tx.ConnectInputs(txdb, mapQueuedChanges, posThisTx, pindex, nFees, true, false))
+ bool fInvalid;
+ if (!tx.ConnectInputs(txdb, mapQueuedChanges, posThisTx, pindex, nFees, true, false, 0, fInvalid))
return false;
}
// Write queued txindex changes
@@ -1311,7 +1350,7 @@ bool CBlock::AcceptBlock()
int nHeight = pindexPrev->nHeight+1;
// Check proof of work
- if (nBits != GetNextWorkRequired(pindexPrev))
+ if (nBits != GetNextWorkRequired(pindexPrev, this))
return DoS(100, error("AcceptBlock() : incorrect proof of work"));
// Check timestamp against prev
@@ -2832,7 +2871,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
// Connecting shouldn't fail due to dependency on other memory pool transactions
// because we're already processing them in order of dependency
map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
- if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee))
+ bool fInvalid;
+ if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee, fInvalid))
continue;
swap(mapTestPool, mapTestPoolTmp);
@@ -2863,7 +2903,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
- pblock->nBits = GetNextWorkRequired(pindexPrev);
+ pblock->nBits = GetNextWorkRequired(pindexPrev, pblock.get());
pblock->nNonce = 0;
return pblock.release();
diff --git a/src/main.h b/src/main.h
index 3870cee864..47394ff8e9 100644
--- a/src/main.h
+++ b/src/main.h
@@ -637,7 +637,8 @@ public:
bool ReadFromDisk(COutPoint prevout);
bool DisconnectInputs(CTxDB& txdb);
bool ConnectInputs(CTxDB& txdb, std::map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
- CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0);
+ CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
+ bool& fInvalid);
bool ClientConnectInputs();
bool CheckTransaction() const;
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
diff --git a/src/makefile.osx b/src/makefile.osx
index de71887935..cbd51b049f 100644
--- a/src/makefile.osx
+++ b/src/makefile.osx
@@ -22,6 +22,8 @@ USE_UPNP:=1
LIBS= -dead_strip
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 \
@@ -29,8 +31,11 @@ LIBS += \
$(DEPSDIR)/lib/libboost_program_options-mt.a \
$(DEPSDIR)/lib/libboost_thread-mt.a \
$(DEPSDIR)/lib/libssl.a \
- $(DEPSDIR)/lib/libcrypto.a
+ $(DEPSDIR)/lib/libcrypto.a \
+ -lz
else
+TESTLIBS += \
+ -lboost_unit_test_framework-mt
LIBS += \
-ldb_cxx-4.8 \
-lboost_system-mt \
@@ -38,7 +43,9 @@ LIBS += \
-lboost_program_options-mt \
-lboost_thread-mt \
-lssl \
- -lcrypto
+ -lcrypto \
+ -lz
+TESTDEFS += -DBOOST_TEST_DYN_LINK
endif
DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0 -DUSE_SSL
@@ -98,7 +105,7 @@ all: bitcoind
# auto-generated dependencies:
-include obj/nogui/*.P
--include obj/test/*.P
+-include obj-test/*.P
obj/nogui/%.o: %.cpp
$(CXX) -c $(CFLAGS) -MMD -o $@ $<
@@ -111,20 +118,20 @@ bitcoind: $(OBJS:obj/%=obj/nogui/%)
$(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
obj/test/%.o: test/%.cpp
- $(CXX) -c $(CFLAGS) -MMD -o $@ $<
+ $(CXX) -c $(TESTDEFS) $(CFLAGS) -MMD -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: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%))
- $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(DEPSDIR)/lib/libboost_unit_test_framework-mt.a
+ $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(TESTLIBS)
clean:
-rm -f bitcoind test_bitcoin
-rm -f obj/*.o
-rm -f obj/nogui/*.o
- -rm -f obj/test/*.o
+ -rm -f obj-test/*.o
-rm -f obj/*.P
-rm -f obj/nogui/*.P
- -rm -f obj/test/*.P
+ -rm -f obj-test/*.P
diff --git a/src/makefile.unix b/src/makefile.unix
index 6c48199546..53948bcba6 100644
--- a/src/makefile.unix
+++ b/src/makefile.unix
@@ -16,6 +16,8 @@ ifdef STATIC
ifeq (${STATIC}, all)
LMODE2 = static
endif
+else
+ TESTDEFS += -DBOOST_TEST_DYN_LINK
endif
# for boost 1.37, add -mt to the boost libraries
@@ -127,7 +129,7 @@ all: bitcoind
# auto-generated dependencies:
-include obj/nogui/*.P
--include obj/test/*.P
+-include obj-test/*.P
obj/nogui/%.o: %.cpp
$(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
@@ -139,21 +141,21 @@ obj/nogui/%.o: %.cpp
bitcoind: $(OBJS:obj/%=obj/nogui/%)
$(CXX) $(xCXXFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
-obj/test/%.o: test/%.cpp
- $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+obj-test/%.o: test/%.cpp
+ $(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -MMD -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: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%))
- $(CXX) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-Bstatic -lboost_unit_test_framework $(LDFLAGS) $(LIBS)
+test_bitcoin: obj-test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%))
+ $(CXX) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-B$(LMODE) -lboost_unit_test_framework $(LDFLAGS) $(LIBS)
clean:
-rm -f bitcoind test_bitcoin
-rm -f obj/*.o
-rm -f obj/nogui/*.o
- -rm -f obj/test/*.o
+ -rm -f obj-test/*.o
-rm -f obj/*.P
-rm -f obj/nogui/*.P
- -rm -f obj/test/*.P
+ -rm -f obj-test/*.P
diff --git a/src/net.cpp b/src/net.cpp
index 10f7c62c15..7b92e874ac 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1156,11 +1156,11 @@ void ThreadMapPort2(void* parg)
{
string strDesc = "Bitcoin " + FormatFullVersion();
#ifndef UPNPDISCOVER_SUCCESS
- /* miniupnpc 1.5 */
+ /* miniupnpc 1.5 */
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
port, port, lanaddr, strDesc.c_str(), "TCP", 0);
#else
- /* miniupnpc 1.6 */
+ /* miniupnpc 1.6 */
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
#endif
@@ -1170,6 +1170,7 @@ void ThreadMapPort2(void* parg)
port, port, lanaddr, r, strupnperror(r));
else
printf("UPnP Port Mapping successful.\n");
+ int i = 1;
loop {
if (fShutdown || !fUseUPnP)
{
@@ -1179,7 +1180,26 @@ void ThreadMapPort2(void* parg)
FreeUPNPUrls(&urls);
return;
}
+ if (i % 600 == 0) // Refresh every 20 minutes
+ {
+#ifndef UPNPDISCOVER_SUCCESS
+ /* miniupnpc 1.5 */
+ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
+ port, port, lanaddr, strDesc.c_str(), "TCP", 0);
+#else
+ /* miniupnpc 1.6 */
+ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
+ port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
+#endif
+
+ if(r!=UPNPCOMMAND_SUCCESS)
+ printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
+ port, port, lanaddr, r, strupnperror(r));
+ else
+ printf("UPnP Port Mapping successful.\n");;
+ }
Sleep(2000);
+ i++;
}
} else {
printf("No valid UPnP IGDs found\n");
diff --git a/src/obj-test/.gitignore b/src/obj-test/.gitignore
new file mode 100644
index 0000000000..d6b7ef32c8
--- /dev/null
+++ b/src/obj-test/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 1c49683364..5d9c0d9f00 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -418,7 +418,6 @@ void BitcoinGUI::setNumBlocks(int count)
{
if(!clientModel)
return;
- int initTotal = clientModel->getNumBlocksAtStartup();
int total = clientModel->getNumBlocksOfPeers();
QString tooltip;
@@ -429,8 +428,8 @@ void BitcoinGUI::setNumBlocks(int count)
progressBarLabel->setVisible(true);
progressBarLabel->setText(tr("Synchronizing with network..."));
progressBar->setVisible(true);
- progressBar->setMaximum(total - initTotal);
- progressBar->setValue(count - initTotal);
+ progressBar->setMaximum(total);
+ progressBar->setValue(count);
}
else
{
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 762f27dfa6..6d32891172 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -11,6 +11,7 @@
#include <QMessageBox>
#include <QLocale>
#include <QTextDocument>
+#include <QScrollBar>
SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
QDialog(parent),
@@ -188,6 +189,12 @@ SendCoinsEntry *SendCoinsDialog::addEntry()
// Focus the field, so that entry can start immediately
entry->clear();
+ entry->setFocus();
+ ui->scrollAreaWidgetContents->resize(ui->scrollAreaWidgetContents->sizeHint());
+ QCoreApplication::instance()->processEvents();
+ QScrollBar* bar = ui->scrollArea->verticalScrollBar();
+ if (bar)
+ bar->setSliderPosition(bar->maximum());
return entry;
}
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index 23b11ccdde..ab5460f8c2 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -151,3 +151,8 @@ bool SendCoinsEntry::isClear()
return ui->payTo->text().isEmpty();
}
+void SendCoinsEntry::setFocus()
+{
+ ui->payTo->setFocus();
+}
+
diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h
index b7f4a0af3b..cdbf893264 100644
--- a/src/qt/sendcoinsentry.h
+++ b/src/qt/sendcoinsentry.h
@@ -31,6 +31,8 @@ public:
*/
QWidget *setupTabChain(QWidget *prev);
+ void setFocus();
+
public slots:
void setRemoveEnabled(bool enabled);
void clear();