mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-09 06:09:48 +02:00
Merge branch '0.5.x' into 0.6.0.x
Conflicts: doc/unit-tests.txt src/serialize.h
This commit is contained in:
16
src/bignum.h
16
src/bignum.h
@@ -122,16 +122,22 @@ public:
|
||||
return (n > std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
|
||||
}
|
||||
|
||||
void setint64(int64 n)
|
||||
void setint64(int64 sn)
|
||||
{
|
||||
unsigned char pch[sizeof(n) + 6];
|
||||
unsigned char pch[sizeof(sn) + 6];
|
||||
unsigned char* p = pch + 4;
|
||||
bool fNegative = false;
|
||||
if (n < (int64)0)
|
||||
bool fNegative;
|
||||
uint64 n;
|
||||
|
||||
if (sn < (int64)0)
|
||||
{
|
||||
n = -n;
|
||||
n = -sn;
|
||||
fNegative = true;
|
||||
} else {
|
||||
n = sn;
|
||||
fNegative = false;
|
||||
}
|
||||
|
||||
bool fLeadingZeroes = true;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
|
||||
81
src/main.cpp
81
src/main.cpp
@@ -51,7 +51,7 @@ map<uint256, CBlock*> mapOrphanBlocks;
|
||||
multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
|
||||
|
||||
map<uint256, CDataStream*> mapOrphanTransactions;
|
||||
multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
|
||||
map<uint256, map<uint256, CDataStream*> > mapOrphanTransactionsByPrev;
|
||||
|
||||
// Constant stuff for coinbase transactions we create:
|
||||
CScript COINBASE_FLAGS;
|
||||
@@ -168,17 +168,37 @@ void static ResendWalletTransactions()
|
||||
// mapOrphanTransactions
|
||||
//
|
||||
|
||||
void AddOrphanTx(const CDataStream& vMsg)
|
||||
bool AddOrphanTx(const CDataStream& vMsg)
|
||||
{
|
||||
CTransaction tx;
|
||||
CDataStream(vMsg) >> tx;
|
||||
uint256 hash = tx.GetHash();
|
||||
if (mapOrphanTransactions.count(hash))
|
||||
return;
|
||||
return false;
|
||||
|
||||
CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);
|
||||
CDataStream* pvMsg = new CDataStream(vMsg);
|
||||
|
||||
// Ignore big transactions, to avoid a
|
||||
// send-big-orphans memory exhaustion attack. If a peer has a legitimate
|
||||
// large transaction with a missing parent then we assume
|
||||
// it will rebroadcast it later, after the parent transaction(s)
|
||||
// have been mined or received.
|
||||
// 10,000 orphans, each of which is at most 5,000 bytes big is
|
||||
// at most 500 megabytes of orphans:
|
||||
if (pvMsg->size() > 5000)
|
||||
{
|
||||
printf("ignoring large orphan tx (size: %u, hash: %s)\n", pvMsg->size(), hash.ToString().substr(0,10).c_str());
|
||||
delete pvMsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
mapOrphanTransactions[hash] = pvMsg;
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
|
||||
mapOrphanTransactionsByPrev[txin.prevout.hash].insert(make_pair(hash, pvMsg));
|
||||
|
||||
printf("stored orphan tx %s (mapsz %u)\n", hash.ToString().substr(0,10).c_str(),
|
||||
mapOrphanTransactions.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
void static EraseOrphanTx(uint256 hash)
|
||||
@@ -190,14 +210,9 @@ void static EraseOrphanTx(uint256 hash)
|
||||
CDataStream(*pvMsg) >> tx;
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
{
|
||||
for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash);
|
||||
mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);)
|
||||
{
|
||||
if ((*mi).second == pvMsg)
|
||||
mapOrphanTransactionsByPrev.erase(mi++);
|
||||
else
|
||||
mi++;
|
||||
}
|
||||
mapOrphanTransactionsByPrev[txin.prevout.hash].erase(hash);
|
||||
if (mapOrphanTransactionsByPrev[txin.prevout.hash].empty())
|
||||
mapOrphanTransactionsByPrev.erase(txin.prevout.hash);
|
||||
}
|
||||
delete pvMsg;
|
||||
mapOrphanTransactions.erase(hash);
|
||||
@@ -1138,17 +1153,28 @@ bool CTransaction::ConnectInputs(MapPrevTx inputs,
|
||||
if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile)
|
||||
return error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight);
|
||||
|
||||
// Check for negative or overflow input values
|
||||
nValueIn += txPrev.vout[prevout.n].nValue;
|
||||
if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
|
||||
return DoS(100, error("ConnectInputs() : txin values out of range"));
|
||||
|
||||
}
|
||||
// The first loop above does all the inexpensive checks.
|
||||
// Only if ALL inputs pass do we perform expensive ECDSA signature checks.
|
||||
// Helps prevent CPU exhaustion attacks.
|
||||
for (unsigned int i = 0; i < vin.size(); i++)
|
||||
{
|
||||
COutPoint prevout = vin[i].prevout;
|
||||
assert(inputs.count(prevout.hash) > 0);
|
||||
CTxIndex& txindex = inputs[prevout.hash].first;
|
||||
CTransaction& txPrev = inputs[prevout.hash].second;
|
||||
|
||||
// Check for conflicts (double-spend)
|
||||
// This doesn't trigger the DoS code on purpose; if it did, it would make it easier
|
||||
// for an attacker to attempt to split the network.
|
||||
if (!txindex.vSpent[prevout.n].IsNull())
|
||||
return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,10).c_str(), txindex.vSpent[prevout.n].ToString().c_str());
|
||||
|
||||
// Check for negative or overflow input values
|
||||
nValueIn += txPrev.vout[prevout.n].nValue;
|
||||
if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
|
||||
return DoS(100, error("ConnectInputs() : txin values out of range"));
|
||||
|
||||
// Skip ECDSA signature verification when connecting blocks (fBlock=true)
|
||||
// before the last blockchain checkpoint. This is safe because block merkle hashes are
|
||||
// still computed and checked, and any change will be caught at the next checkpoint.
|
||||
@@ -2572,6 +2598,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
else if (strCommand == "tx")
|
||||
{
|
||||
vector<uint256> vWorkQueue;
|
||||
vector<uint256> vEraseQueue;
|
||||
CDataStream vMsg(vRecv);
|
||||
CTransaction tx;
|
||||
vRecv >> tx;
|
||||
@@ -2586,37 +2613,45 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
RelayMessage(inv, vMsg);
|
||||
mapAlreadyAskedFor.erase(inv);
|
||||
vWorkQueue.push_back(inv.hash);
|
||||
vEraseQueue.push_back(inv.hash);
|
||||
|
||||
// Recursively process any orphan transactions that depended on this one
|
||||
for (unsigned int i = 0; i < vWorkQueue.size(); i++)
|
||||
{
|
||||
uint256 hashPrev = vWorkQueue[i];
|
||||
for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev);
|
||||
mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev);
|
||||
for (map<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev[hashPrev].begin();
|
||||
mi != mapOrphanTransactionsByPrev[hashPrev].end();
|
||||
++mi)
|
||||
{
|
||||
const CDataStream& vMsg = *((*mi).second);
|
||||
CTransaction tx;
|
||||
CDataStream(vMsg) >> tx;
|
||||
CInv inv(MSG_TX, tx.GetHash());
|
||||
bool fMissingInputs2 = false;
|
||||
|
||||
if (tx.AcceptToMemoryPool(true))
|
||||
if (tx.AcceptToMemoryPool(true, &fMissingInputs2))
|
||||
{
|
||||
printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
|
||||
SyncWithWallets(tx, NULL, true);
|
||||
RelayMessage(inv, vMsg);
|
||||
mapAlreadyAskedFor.erase(inv);
|
||||
vWorkQueue.push_back(inv.hash);
|
||||
vEraseQueue.push_back(inv.hash);
|
||||
}
|
||||
else if (!fMissingInputs2)
|
||||
{
|
||||
// invalid orphan
|
||||
vEraseQueue.push_back(inv.hash);
|
||||
printf(" removed invalid orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(uint256 hash, vWorkQueue)
|
||||
BOOST_FOREACH(uint256 hash, vEraseQueue)
|
||||
EraseOrphanTx(hash);
|
||||
}
|
||||
else if (fMissingInputs)
|
||||
{
|
||||
printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
|
||||
AddOrphanTx(vMsg);
|
||||
|
||||
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded
|
||||
|
||||
@@ -26,7 +26,7 @@ class CInv;
|
||||
class CRequestTracker;
|
||||
class CNode;
|
||||
|
||||
static const int CLIENT_VERSION = 60008;
|
||||
static const int CLIENT_VERSION = 60009;
|
||||
static const bool VERSION_IS_BETA = true;
|
||||
extern const std::string CLIENT_NAME;
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ void OverviewPage::setNumTransactions(int count)
|
||||
void OverviewPage::setModel(WalletModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
if(model)
|
||||
if(model && model->getOptionsModel())
|
||||
{
|
||||
// Set up transaction list
|
||||
TransactionFilterProxy *filter = new TransactionFilterProxy();
|
||||
@@ -163,17 +163,23 @@ void OverviewPage::setModel(WalletModel *model)
|
||||
setNumTransactions(model->getNumTransactions());
|
||||
connect(model, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int)));
|
||||
|
||||
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(displayUnitChanged()));
|
||||
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
}
|
||||
|
||||
// update the display unit, to not use the default ("BTC")
|
||||
updateDisplayUnit();
|
||||
}
|
||||
|
||||
void OverviewPage::updateDisplayUnit()
|
||||
{
|
||||
if(model && model->getOptionsModel())
|
||||
{
|
||||
if(currentBalance != -1)
|
||||
setBalance(currentBalance, currentUnconfirmedBalance);
|
||||
|
||||
// Update txdelegate->unit with the current unit
|
||||
txdelegate->unit = model->getOptionsModel()->getDisplayUnit();
|
||||
|
||||
ui->listTransactions->update();
|
||||
}
|
||||
}
|
||||
|
||||
void OverviewPage::displayUnitChanged()
|
||||
{
|
||||
if(!model || !model->getOptionsModel())
|
||||
return;
|
||||
if(currentBalance != -1)
|
||||
setBalance(currentBalance, currentUnconfirmedBalance);
|
||||
|
||||
txdelegate->unit = model->getOptionsModel()->getDisplayUnit();
|
||||
ui->listTransactions->update();
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ private:
|
||||
TxViewDelegate *txdelegate;
|
||||
|
||||
private slots:
|
||||
void displayUnitChanged();
|
||||
void updateDisplayUnit();
|
||||
};
|
||||
|
||||
#endif // OVERVIEWPAGE_H
|
||||
|
||||
@@ -46,10 +46,11 @@ void SendCoinsDialog::setModel(WalletModel *model)
|
||||
entry->setModel(model);
|
||||
}
|
||||
}
|
||||
if(model)
|
||||
if(model && model->getOptionsModel())
|
||||
{
|
||||
setBalance(model->getBalance(), model->getUnconfirmedBalance());
|
||||
connect(model, SIGNAL(balanceChanged(qint64, qint64)), this, SLOT(setBalance(qint64, qint64)));
|
||||
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +203,7 @@ SendCoinsEntry *SendCoinsDialog::addEntry()
|
||||
ui->scrollAreaWidgetContents->resize(ui->scrollAreaWidgetContents->sizeHint());
|
||||
QCoreApplication::instance()->processEvents();
|
||||
QScrollBar* bar = ui->scrollArea->verticalScrollBar();
|
||||
if (bar)
|
||||
if(bar)
|
||||
bar->setSliderPosition(bar->maximum());
|
||||
return entry;
|
||||
}
|
||||
@@ -286,3 +287,12 @@ void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance)
|
||||
int unit = model->getOptionsModel()->getDisplayUnit();
|
||||
ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance));
|
||||
}
|
||||
|
||||
void SendCoinsDialog::updateDisplayUnit()
|
||||
{
|
||||
if(model && model->getOptionsModel())
|
||||
{
|
||||
// Update labelBalance with the current balance and the current unit
|
||||
ui->labelBalance->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), model->getBalance()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ private:
|
||||
|
||||
private slots:
|
||||
void on_sendButton_clicked();
|
||||
|
||||
void removeEntry(SendCoinsEntry* entry);
|
||||
void updateDisplayUnit();
|
||||
};
|
||||
|
||||
#endif // SENDCOINSDIALOG_H
|
||||
|
||||
@@ -68,6 +68,10 @@ void SendCoinsEntry::on_payTo_textChanged(const QString &address)
|
||||
void SendCoinsEntry::setModel(WalletModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
|
||||
if(model && model->getOptionsModel())
|
||||
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
@@ -82,10 +86,8 @@ void SendCoinsEntry::clear()
|
||||
ui->addAsLabel->clear();
|
||||
ui->payAmount->clear();
|
||||
ui->payTo->setFocus();
|
||||
if(model && model->getOptionsModel())
|
||||
{
|
||||
ui->payAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
|
||||
}
|
||||
// update the display unit, to not use the default ("BTC")
|
||||
updateDisplayUnit();
|
||||
}
|
||||
|
||||
void SendCoinsEntry::on_deleteButton_clicked()
|
||||
@@ -160,3 +162,11 @@ void SendCoinsEntry::setFocus()
|
||||
ui->payTo->setFocus();
|
||||
}
|
||||
|
||||
void SendCoinsEntry::updateDisplayUnit()
|
||||
{
|
||||
if(model && model->getOptionsModel())
|
||||
{
|
||||
// Update payAmount with the current unit
|
||||
ui->payAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ private slots:
|
||||
void on_payTo_textChanged(const QString &address);
|
||||
void on_addressBookButton_clicked();
|
||||
void on_pasteButton_clicked();
|
||||
void updateDisplayUnit();
|
||||
|
||||
private:
|
||||
Ui::SendCoinsEntry *ui;
|
||||
|
||||
@@ -354,7 +354,7 @@ inline int64 GetPerformanceCounter()
|
||||
#else
|
||||
timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
nCounter = t.tv_sec * 1000000 + t.tv_usec;
|
||||
nCounter = (int64) t.tv_sec * 1000000 + t.tv_usec;
|
||||
#endif
|
||||
return nCounter;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user