Merge remote branch 'refs/remotes/svn/trunk' into svn

This commit is contained in:
Gavin Andresen 2010-10-05 23:27:30 -04:00
commit 1b5e57e935
4 changed files with 83 additions and 52 deletions

View File

@ -143,7 +143,7 @@ bool AddToWallet(const CWalletTx& wtxIn)
} }
//// debug print //// debug print
printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : "")); printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,10).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
// Write to disk // Write to disk
if (fInsertedNew || fUpdated) if (fInsertedNew || fUpdated)
@ -587,7 +587,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
{ {
if (pfMissingInputs) if (pfMissingInputs)
*pfMissingInputs = true; *pfMissingInputs = true;
return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,6).c_str()); return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
} }
// Store transaction in memory // Store transaction in memory
@ -606,7 +606,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
if (ptxOld) if (ptxOld)
EraseFromWallet(ptxOld->GetHash()); EraseFromWallet(ptxOld->GetHash());
printf("AcceptToMemoryPool(): accepted %s\n", hash.ToString().substr(0,6).c_str()); printf("AcceptToMemoryPool(): accepted %s\n", hash.ToString().substr(0,10).c_str());
return true; return true;
} }
@ -775,7 +775,7 @@ void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
uint256 hash = GetHash(); uint256 hash = GetHash();
if (!txdb.ContainsTx(hash)) if (!txdb.ContainsTx(hash))
{ {
printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str()); printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this); RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
} }
} }
@ -985,7 +985,8 @@ bool CTransaction::DisconnectInputs(CTxDB& txdb)
txindex.vSpent[prevout.n].SetNull(); txindex.vSpent[prevout.n].SetNull();
// Write back // Write back
txdb.UpdateTxIndex(prevout.hash, txindex); if (!txdb.UpdateTxIndex(prevout.hash, txindex))
return error("DisconnectInputs() : UpdateTxIndex failed");
} }
} }
@ -1022,7 +1023,7 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo
fFound = txdb.ReadTxIndex(prevout.hash, txindex); fFound = txdb.ReadTxIndex(prevout.hash, txindex);
} }
if (!fFound && (fBlock || fMiner)) if (!fFound && (fBlock || fMiner))
return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
// Read txPrev // Read txPrev
CTransaction txPrev; CTransaction txPrev;
@ -1032,7 +1033,7 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo
CRITICAL_BLOCK(cs_mapTransactions) CRITICAL_BLOCK(cs_mapTransactions)
{ {
if (!mapTransactions.count(prevout.hash)) if (!mapTransactions.count(prevout.hash))
return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
txPrev = mapTransactions[prevout.hash]; txPrev = mapTransactions[prevout.hash];
} }
if (!fFound) if (!fFound)
@ -1042,11 +1043,11 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo
{ {
// Get prev tx from disk // Get prev tx from disk
if (!txPrev.ReadFromDisk(txindex.pos)) if (!txPrev.ReadFromDisk(txindex.pos))
return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
} }
if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
return error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,6).c_str(), txPrev.ToString().c_str()); return 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 prev is coinbase, check that it's matured
if (txPrev.IsCoinBase()) if (txPrev.IsCoinBase())
@ -1056,11 +1057,11 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo
// Verify signature // Verify signature
if (!VerifySignature(txPrev, *this, i)) if (!VerifySignature(txPrev, *this, i))
return error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,6).c_str()); return error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str());
// Check for conflicts // Check for conflicts
if (!txindex.vSpent[prevout.n].IsNull()) if (!txindex.vSpent[prevout.n].IsNull())
return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,6).c_str(), txindex.vSpent[prevout.n].ToString().c_str()); 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 // Check for negative or overflow input values
nValueIn += txPrev.vout[prevout.n].nValue; nValueIn += txPrev.vout[prevout.n].nValue;
@ -1072,18 +1073,23 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo
// Write back // Write back
if (fBlock) if (fBlock)
txdb.UpdateTxIndex(prevout.hash, txindex); {
if (!txdb.UpdateTxIndex(prevout.hash, txindex))
return error("ConnectInputs() : UpdateTxIndex failed");
}
else if (fMiner) else if (fMiner)
{
mapTestPool[prevout.hash] = txindex; mapTestPool[prevout.hash] = txindex;
}
} }
if (nValueIn < GetValueOut()) if (nValueIn < GetValueOut())
return error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,6).c_str()); return error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,10).c_str());
// Tally transaction fees // Tally transaction fees
int64 nTxFee = nValueIn - GetValueOut(); int64 nTxFee = nValueIn - GetValueOut();
if (nTxFee < 0) if (nTxFee < 0)
return error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,6).c_str()); return error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str());
if (nTxFee < nMinFee) if (nTxFee < nMinFee)
return false; return false;
nFees += nTxFee; nFees += nTxFee;
@ -1168,7 +1174,8 @@ bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
{ {
CDiskBlockIndex blockindexPrev(pindex->pprev); CDiskBlockIndex blockindexPrev(pindex->pprev);
blockindexPrev.hashNext = 0; blockindexPrev.hashNext = 0;
txdb.WriteBlockIndex(blockindexPrev); if (!txdb.WriteBlockIndex(blockindexPrev))
return error("DisconnectBlock() : WriteBlockIndex failed");
} }
return true; return true;
@ -1203,7 +1210,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
{ {
CDiskBlockIndex blockindexPrev(pindex->pprev); CDiskBlockIndex blockindexPrev(pindex->pprev);
blockindexPrev.hashNext = pindex->GetBlockHash(); blockindexPrev.hashNext = pindex->GetBlockHash();
txdb.WriteBlockIndex(blockindexPrev); if (!txdb.WriteBlockIndex(blockindexPrev))
return error("ConnectBlock() : WriteBlockIndex failed");
} }
// Watch for transactions paying to me // Watch for transactions paying to me
@ -1282,8 +1290,9 @@ bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash())) if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash()))
return error("Reorganize() : WriteHashBestChain failed"); return error("Reorganize() : WriteHashBestChain failed");
// Commit now because resurrecting could take some time // Make sure it's successfully written to disk before changing memory structure
txdb.TxnCommit(); if (!txdb.TxnCommit())
return error("Reorganize() : TxnCommit failed");
// Disconnect shorter branch // Disconnect shorter branch
foreach(CBlockIndex* pindex, vDisconnect) foreach(CBlockIndex* pindex, vDisconnect)
@ -1314,8 +1323,10 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
txdb.TxnBegin(); txdb.TxnBegin();
if (pindexGenesisBlock == NULL && hash == hashGenesisBlock) if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
{ {
pindexGenesisBlock = pindexNew;
txdb.WriteHashBestChain(hash); txdb.WriteHashBestChain(hash);
if (!txdb.TxnCommit())
return error("SetBestChain() : TxnCommit failed");
pindexGenesisBlock = pindexNew;
} }
else if (hashPrevBlock == hashBestChain) else if (hashPrevBlock == hashBestChain)
{ {
@ -1326,7 +1337,10 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
InvalidChainFound(pindexNew); InvalidChainFound(pindexNew);
return error("SetBestChain() : ConnectBlock failed"); return error("SetBestChain() : ConnectBlock failed");
} }
txdb.TxnCommit(); if (!txdb.TxnCommit())
return error("SetBestChain() : TxnCommit failed");
// Add to current best branch
pindexNew->pprev->pnext = pindexNew; pindexNew->pprev->pnext = pindexNew;
// Delete redundant memory transactions // Delete redundant memory transactions
@ -1343,7 +1357,6 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
return error("SetBestChain() : Reorganize failed"); return error("SetBestChain() : Reorganize failed");
} }
} }
txdb.TxnCommit();
// New best block // New best block
hashBestChain = hash; hashBestChain = hash;
@ -2126,6 +2139,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// Disconnect if we connected to ourself // Disconnect if we connected to ourself
if (nNonce == nLocalHostNonce && nNonce > 1) if (nNonce == nLocalHostNonce && nNonce > 1)
{ {
printf("connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str());
pfrom->fDisconnect = true; pfrom->fDisconnect = true;
return true; return true;
} }
@ -2386,7 +2400,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (tx.AcceptToMemoryPool(true)) if (tx.AcceptToMemoryPool(true))
{ {
printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str()); printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
AddToWalletIfMine(tx, NULL); AddToWalletIfMine(tx, NULL);
RelayMessage(inv, vMsg); RelayMessage(inv, vMsg);
mapAlreadyAskedFor.erase(inv); mapAlreadyAskedFor.erase(inv);
@ -2400,7 +2414,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
} }
else if (fMissingInputs) else if (fMissingInputs)
{ {
printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str()); printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
AddOrphanTx(vMsg); AddOrphanTx(vMsg);
} }
} }
@ -3208,9 +3222,7 @@ int64 GetBalance()
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{ {
CWalletTx* pcoin = &(*it).second; CWalletTx* pcoin = &(*it).second;
if (!pcoin->IsFinal() || pcoin->fSpent) if (!pcoin->IsFinal() || pcoin->fSpent || !pcoin->IsConfirmed())
continue;
if (pcoin->GetDepthInMainChain() < 1 && pcoin->GetDebit() <= 0)
continue; continue;
nTotal += pcoin->GetCredit(true); nTotal += pcoin->GetCredit(true);
} }
@ -3241,9 +3253,7 @@ bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
foreach(CWalletTx* pcoin, vCoins) foreach(CWalletTx* pcoin, vCoins)
{ {
if (!pcoin->IsFinal() || pcoin->fSpent) if (!pcoin->IsFinal() || pcoin->fSpent || !pcoin->IsConfirmed())
continue;
if (pcoin->GetDepthInMainChain() < 1 && pcoin->GetDebit() <= 0)
continue; continue;
int64 n = pcoin->GetCredit(); int64 n = pcoin->GetCredit();
if (n <= 0) if (n <= 0)

41
main.h
View File

@ -195,7 +195,7 @@ public:
string ToString() const string ToString() const
{ {
return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,6).c_str(), n); return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n);
} }
void print() const void print() const
@ -599,7 +599,7 @@ public:
{ {
string str; string str;
str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n", str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
GetHash().ToString().substr(0,6).c_str(), GetHash().ToString().substr(0,10).c_str(),
nVersion, nVersion,
vin.size(), vin.size(),
vout.size(), vout.size(),
@ -787,6 +787,37 @@ public:
return nCreditCached; return nCreditCached;
} }
bool IsConfirmed() const
{
map<uint256, const CMerkleTx*> mapPrev;
vector<const CMerkleTx*> vWorkQueue;
vWorkQueue.reserve(vtxPrev.size()+1);
vWorkQueue.push_back(this);
for (int i = 0; i < vWorkQueue.size(); i++)
{
const CMerkleTx* ptx = vWorkQueue[i];
if (!ptx->IsFinal())
return false;
if (ptx->GetDepthInMainChain() >= 1)
return true;
if (ptx->GetDebit() <= 0)
return false;
if (mapPrev.empty())
foreach(const CMerkleTx& tx, vtxPrev)
mapPrev[tx.GetHash()] = &tx;
foreach(const CTxIn& txin, ptx->vin)
{
if (!mapPrev.count(txin.prevout.hash))
return false;
vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
}
}
return true;
}
bool WriteToDisk() bool WriteToDisk()
{ {
return CWalletDB().WriteTx(GetHash(), *this); return CWalletDB().WriteTx(GetHash(), *this);
@ -1065,7 +1096,7 @@ public:
GetHash().ToString().substr(0,20).c_str(), GetHash().ToString().substr(0,20).c_str(),
nVersion, nVersion,
hashPrevBlock.ToString().substr(0,20).c_str(), hashPrevBlock.ToString().substr(0,20).c_str(),
hashMerkleRoot.ToString().substr(0,6).c_str(), hashMerkleRoot.ToString().substr(0,10).c_str(),
nTime, nBits, nNonce, nTime, nBits, nNonce,
vtx.size()); vtx.size());
for (int i = 0; i < vtx.size(); i++) for (int i = 0; i < vtx.size(); i++)
@ -1075,7 +1106,7 @@ public:
} }
printf(" vMerkleTree: "); printf(" vMerkleTree: ");
for (int i = 0; i < vMerkleTree.size(); i++) for (int i = 0; i < vMerkleTree.size(); i++)
printf("%s ", vMerkleTree[i].ToString().substr(0,6).c_str()); printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
printf("\n"); printf("\n");
} }
@ -1233,7 +1264,7 @@ public:
{ {
return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
pprev, pnext, nFile, nBlockPos, nHeight, pprev, pnext, nFile, nBlockPos, nHeight,
hashMerkleRoot.ToString().substr(0,6).c_str(), hashMerkleRoot.ToString().substr(0,10).c_str(),
GetBlockHash().ToString().substr(0,20).c_str()); GetBlockHash().ToString().substr(0,20).c_str());
} }

View File

@ -22,7 +22,7 @@ class CDataStream;
class CAutoFile; class CAutoFile;
static const unsigned int MAX_SIZE = 0x02000000; static const unsigned int MAX_SIZE = 0x02000000;
static const int VERSION = 31300; static const int VERSION = 31302;
static const char* pszSubVer = ""; static const char* pszSubVer = "";

24
ui.cpp
View File

@ -502,10 +502,9 @@ bool CMainFrame::DeleteLine(uint256 hashKey)
return nIndex != -1; return nIndex != -1;
} }
string FormatTxStatus(const CWalletTx& wtx, bool& fConfirmed) string FormatTxStatus(const CWalletTx& wtx)
{ {
// Status // Status
fConfirmed = false;
if (!wtx.IsFinal()) if (!wtx.IsFinal())
{ {
if (wtx.nLockTime < 500000000) if (wtx.nLockTime < 500000000)
@ -516,8 +515,6 @@ string FormatTxStatus(const CWalletTx& wtx, bool& fConfirmed)
else else
{ {
int nDepth = wtx.GetDepthInMainChain(); int nDepth = wtx.GetDepthInMainChain();
if (nDepth >= 1 || wtx.GetDebit() > 0)
fConfirmed = true;
if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
return strprintf(_("%d/offline?"), nDepth); return strprintf(_("%d/offline?"), nDepth);
else if (nDepth < 6) else if (nDepth < 6)
@ -527,12 +524,6 @@ string FormatTxStatus(const CWalletTx& wtx, bool& fConfirmed)
} }
} }
string FormatTxStatus(const CWalletTx& wtx)
{
bool fConfirmed;
return FormatTxStatus(wtx, fConfirmed);
}
string SingleLine(const string& strIn) string SingleLine(const string& strIn)
{ {
string strOut; string strOut;
@ -561,9 +552,8 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
int64 nDebit = wtx.GetDebit(); int64 nDebit = wtx.GetDebit();
int64 nNet = nCredit - nDebit; int64 nNet = nCredit - nDebit;
uint256 hash = wtx.GetHash(); uint256 hash = wtx.GetHash();
bool fConfirmed; string strStatus = FormatTxStatus(wtx);
string strStatus = FormatTxStatus(wtx, fConfirmed); bool fConfirmed = wtx.fConfirmedDisplayed = wtx.IsConfirmed();
wtx.fConfirmedDisplayed = fConfirmed;
wxColour colour = (fConfirmed ? wxColour(0,0,0) : wxColour(128,128,128)); wxColour colour = (fConfirmed ? wxColour(0,0,0) : wxColour(128,128,128));
map<string, string> mapValue = wtx.mapValue; map<string, string> mapValue = wtx.mapValue;
wtx.nLinesDisplayed = 1; wtx.nLinesDisplayed = 1;
@ -914,16 +904,16 @@ void CMainFrame::RefreshStatusColumn()
continue; continue;
} }
CWalletTx& wtx = (*mi).second; CWalletTx& wtx = (*mi).second;
bool fConfirmed; if (wtx.IsCoinBase() ||
string strStatus = FormatTxStatus(wtx, fConfirmed); wtx.GetTxTime() != wtx.nTimeDisplayed ||
if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed || fConfirmed != wtx.fConfirmedDisplayed) wtx.IsConfirmed() != wtx.fConfirmedDisplayed)
{ {
if (!InsertTransaction(wtx, false, nIndex)) if (!InsertTransaction(wtx, false, nIndex))
m_listCtrl->DeleteItem(nIndex--); m_listCtrl->DeleteItem(nIndex--);
} }
else else
{ {
m_listCtrl->SetItem(nIndex, 2, strStatus); m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx));
} }
} }
} }