mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-01-11 07:17:53 +00:00
cleanup,
catch some recoverable exceptions and continue git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@148 1a98c847-1fd6-4fd8-948a-caf3550aa51b
This commit is contained in:
parent
d743f03552
commit
f1e1fb4bde
@ -184,7 +184,8 @@ public:
|
|||||||
|
|
||||||
void deallocate(void *p, size_type n)
|
void deallocate(void *p, size_type n)
|
||||||
{
|
{
|
||||||
assert(false);
|
//// Bitcoin: can't figure out why this is tripping on a few compiles.
|
||||||
|
//assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type max_size() const {return 0;}
|
size_type max_size() const {return 0;}
|
||||||
|
7
db.cpp
7
db.cpp
@ -820,10 +820,15 @@ void BackupWallet(const string& strDest)
|
|||||||
mapFileUseCount.erase(strFile);
|
mapFileUseCount.erase(strFile);
|
||||||
|
|
||||||
// Copy wallet.dat
|
// Copy wallet.dat
|
||||||
|
filesystem::path pathSrc(GetDataDir() + "/" + strFile);
|
||||||
filesystem::path pathDest(strDest);
|
filesystem::path pathDest(strDest);
|
||||||
if (filesystem::is_directory(pathDest))
|
if (filesystem::is_directory(pathDest))
|
||||||
pathDest = pathDest / strFile;
|
pathDest = pathDest / strFile;
|
||||||
filesystem::copy_file(filesystem::path(GetDataDir() + "/" + strFile), pathDest, filesystem::copy_option::overwrite_if_exists);
|
#if BOOST_VERSION >= 104000
|
||||||
|
filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists);
|
||||||
|
#else
|
||||||
|
filesystem::copy_file(pathSrc, pathDest);
|
||||||
|
#endif
|
||||||
printf("copied wallet.dat to %s\n", pathDest.string().c_str());
|
printf("copied wallet.dat to %s\n", pathDest.string().c_str());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
4
init.cpp
4
init.cpp
@ -297,7 +297,7 @@ bool AppInit2(int argc, char* argv[])
|
|||||||
|
|
||||||
if (!strErrors.empty())
|
if (!strErrors.empty())
|
||||||
{
|
{
|
||||||
wxMessageBox(strErrors, "Bitcoin");
|
wxMessageBox(strErrors, "Bitcoin", wxOK | wxICON_ERROR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,7 +374,7 @@ bool AppInit2(int argc, char* argv[])
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (nTransactionFee > 1 * COIN)
|
if (nTransactionFee > 1 * COIN)
|
||||||
wxMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), "Bitcoin");
|
wxMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), "Bitcoin", wxOK | wxICON_EXCLAMATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
20
irc.cpp
20
irc.cpp
@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
int nGotIRCAddresses = 0;
|
int nGotIRCAddresses = 0;
|
||||||
|
|
||||||
|
void ThreadIRCSeed2(void* parg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
@ -128,6 +131,7 @@ int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const cha
|
|||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
string strLine;
|
string strLine;
|
||||||
|
strLine.reserve(10000);
|
||||||
if (!RecvLineIRC(hSocket, strLine))
|
if (!RecvLineIRC(hSocket, strLine))
|
||||||
return 0;
|
return 0;
|
||||||
printf("IRC %s\n", strLine.c_str());
|
printf("IRC %s\n", strLine.c_str());
|
||||||
@ -157,6 +161,21 @@ bool Wait(int nSeconds)
|
|||||||
|
|
||||||
|
|
||||||
void ThreadIRCSeed(void* parg)
|
void ThreadIRCSeed(void* parg)
|
||||||
|
{
|
||||||
|
IMPLEMENT_RANDOMIZE_STACK(ThreadIRCSeed(parg));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ThreadIRCSeed2(parg);
|
||||||
|
}
|
||||||
|
catch (std::exception& e) {
|
||||||
|
PrintExceptionContinue(&e, "ThreadIRCSeed()");
|
||||||
|
} catch (...) {
|
||||||
|
PrintExceptionContinue(NULL, "ThreadIRCSeed()");
|
||||||
|
}
|
||||||
|
printf("ThreadIRCSeed exiting\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadIRCSeed2(void* parg)
|
||||||
{
|
{
|
||||||
if (mapArgs.count("-connect"))
|
if (mapArgs.count("-connect"))
|
||||||
return;
|
return;
|
||||||
@ -236,6 +255,7 @@ void ThreadIRCSeed(void* parg)
|
|||||||
|
|
||||||
int64 nStart = GetTime();
|
int64 nStart = GetTime();
|
||||||
string strLine;
|
string strLine;
|
||||||
|
strLine.reserve(10000);
|
||||||
while (!fShutdown && RecvLineIRC(hSocket, strLine))
|
while (!fShutdown && RecvLineIRC(hSocket, strLine))
|
||||||
{
|
{
|
||||||
if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
|
if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
|
||||||
|
99
main.cpp
99
main.cpp
@ -91,7 +91,7 @@ vector<unsigned char> GenerateNewKey()
|
|||||||
CKey key;
|
CKey key;
|
||||||
key.MakeNewKey();
|
key.MakeNewKey();
|
||||||
if (!AddKey(key))
|
if (!AddKey(key))
|
||||||
throw runtime_error("GenerateNewKey() : AddKey failed\n");
|
throw runtime_error("GenerateNewKey() : AddKey failed");
|
||||||
return key.GetPubKey();
|
return key.GetPubKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,21 +487,25 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs)
|
bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs)
|
||||||
{
|
{
|
||||||
if (pfMissingInputs)
|
if (pfMissingInputs)
|
||||||
*pfMissingInputs = false;
|
*pfMissingInputs = false;
|
||||||
|
|
||||||
// Coinbase is only valid in a block, not as a loose transaction
|
// Coinbase is only valid in a block, not as a loose transaction
|
||||||
if (IsCoinBase())
|
if (IsCoinBase())
|
||||||
return error("AcceptTransaction() : coinbase as individual tx");
|
return error("AcceptToMemoryPool() : coinbase as individual tx");
|
||||||
|
|
||||||
if (!CheckTransaction())
|
if (!CheckTransaction())
|
||||||
return error("AcceptTransaction() : CheckTransaction failed");
|
return error("AcceptToMemoryPool() : CheckTransaction failed");
|
||||||
|
|
||||||
// To help v0.1.5 clients who would see it as a negative number
|
// To help v0.1.5 clients who would see it as a negative number
|
||||||
if ((int64)nLockTime > INT_MAX)
|
if ((int64)nLockTime > INT_MAX)
|
||||||
return error("AcceptTransaction() : not accepting nLockTime beyond 2038 yet");
|
return error("AcceptToMemoryPool() : not accepting nLockTime beyond 2038 yet");
|
||||||
|
|
||||||
|
// Rather not work on nonstandard transactions
|
||||||
|
if (GetSigOpCount() > 2 || ::GetSerializeSize(*this, SER_NETWORK) < 100)
|
||||||
|
return error("AcceptToMemoryPool() : nonstandard transaction");
|
||||||
|
|
||||||
// Do we already have it?
|
// Do we already have it?
|
||||||
uint256 hash = GetHash();
|
uint256 hash = GetHash();
|
||||||
@ -545,7 +549,7 @@ bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMis
|
|||||||
{
|
{
|
||||||
if (pfMissingInputs)
|
if (pfMissingInputs)
|
||||||
*pfMissingInputs = true;
|
*pfMissingInputs = true;
|
||||||
return error("AcceptTransaction() : ConnectInputs failed %s", hash.ToString().substr(0,6).c_str());
|
return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,6).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store transaction in memory
|
// Store transaction in memory
|
||||||
@ -553,10 +557,10 @@ bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMis
|
|||||||
{
|
{
|
||||||
if (ptxOld)
|
if (ptxOld)
|
||||||
{
|
{
|
||||||
printf("AcceptTransaction() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
|
printf("AcceptToMemoryPool() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
|
||||||
ptxOld->RemoveFromMemoryPool();
|
ptxOld->RemoveFromMemoryPool();
|
||||||
}
|
}
|
||||||
AddToMemoryPool();
|
AddToMemoryPoolUnchecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
///// are we sure this is ok when loading transactions or restoring block txes
|
///// are we sure this is ok when loading transactions or restoring block txes
|
||||||
@ -564,15 +568,15 @@ bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMis
|
|||||||
if (ptxOld)
|
if (ptxOld)
|
||||||
EraseFromWallet(ptxOld->GetHash());
|
EraseFromWallet(ptxOld->GetHash());
|
||||||
|
|
||||||
printf("AcceptTransaction(): accepted %s\n", hash.ToString().substr(0,6).c_str());
|
printf("AcceptToMemoryPool(): accepted %s\n", hash.ToString().substr(0,6).c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CTransaction::AddToMemoryPool()
|
bool CTransaction::AddToMemoryPoolUnchecked()
|
||||||
{
|
{
|
||||||
// Add to memory pool without checking anything. Don't call this directly,
|
// Add to memory pool without checking anything. Don't call this directly,
|
||||||
// call AcceptTransaction to properly check the transaction first.
|
// call AcceptToMemoryPool to properly check the transaction first.
|
||||||
CRITICAL_BLOCK(cs_mapTransactions)
|
CRITICAL_BLOCK(cs_mapTransactions)
|
||||||
{
|
{
|
||||||
uint256 hash = GetHash();
|
uint256 hash = GetHash();
|
||||||
@ -637,17 +641,17 @@ int CMerkleTx::GetBlocksToMaturity() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CMerkleTx::AcceptTransaction(CTxDB& txdb, bool fCheckInputs)
|
bool CMerkleTx::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs)
|
||||||
{
|
{
|
||||||
if (fClient)
|
if (fClient)
|
||||||
{
|
{
|
||||||
if (!IsInMainChain() && !ClientConnectInputs())
|
if (!IsInMainChain() && !ClientConnectInputs())
|
||||||
return false;
|
return false;
|
||||||
return CTransaction::AcceptTransaction(txdb, false);
|
return CTransaction::AcceptToMemoryPool(txdb, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return CTransaction::AcceptTransaction(txdb, fCheckInputs);
|
return CTransaction::AcceptToMemoryPool(txdb, fCheckInputs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,19 +661,19 @@ bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
|
|||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_mapTransactions)
|
CRITICAL_BLOCK(cs_mapTransactions)
|
||||||
{
|
{
|
||||||
|
// Add previous supporting transactions first
|
||||||
foreach(CMerkleTx& tx, vtxPrev)
|
foreach(CMerkleTx& tx, vtxPrev)
|
||||||
{
|
{
|
||||||
if (!tx.IsCoinBase())
|
if (!tx.IsCoinBase())
|
||||||
{
|
{
|
||||||
uint256 hash = tx.GetHash();
|
uint256 hash = tx.GetHash();
|
||||||
if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash))
|
if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash))
|
||||||
tx.AcceptTransaction(txdb, fCheckInputs);
|
tx.AcceptToMemoryPool(txdb, fCheckInputs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!IsCoinBase())
|
return AcceptToMemoryPool(txdb, fCheckInputs);
|
||||||
return AcceptTransaction(txdb, fCheckInputs);
|
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReacceptWalletTransactions()
|
void ReacceptWalletTransactions()
|
||||||
@ -1046,6 +1050,8 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo
|
|||||||
if (nTxFee < nMinFee)
|
if (nTxFee < nMinFee)
|
||||||
return false;
|
return false;
|
||||||
nFees += nTxFee;
|
nFees += nTxFee;
|
||||||
|
if (!MoneyRange(nFees))
|
||||||
|
return error("ConnectInputs() : nFees out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fBlock)
|
if (fBlock)
|
||||||
@ -1098,6 +1104,9 @@ bool CTransaction::ClientConnectInputs()
|
|||||||
// txPrev.vout[prevout.n].posNext = posThisTx;
|
// txPrev.vout[prevout.n].posNext = posThisTx;
|
||||||
|
|
||||||
nValueIn += txPrev.vout[prevout.n].nValue;
|
nValueIn += txPrev.vout[prevout.n].nValue;
|
||||||
|
|
||||||
|
if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
|
||||||
|
return error("ClientConnectInputs() : txin values out of range");
|
||||||
}
|
}
|
||||||
if (GetValueOut() > nValueIn)
|
if (GetValueOut() > nValueIn)
|
||||||
return false;
|
return false;
|
||||||
@ -1251,7 +1260,7 @@ bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
|
|||||||
|
|
||||||
// Resurrect memory transactions that were in the disconnected branch
|
// Resurrect memory transactions that were in the disconnected branch
|
||||||
foreach(CTransaction& tx, vResurrect)
|
foreach(CTransaction& tx, vResurrect)
|
||||||
tx.AcceptTransaction(txdb, false);
|
tx.AcceptToMemoryPool(txdb, false);
|
||||||
|
|
||||||
// Delete redundant memory transactions that are in the connected branch
|
// Delete redundant memory transactions that are in the connected branch
|
||||||
foreach(CTransaction& tx, vDelete)
|
foreach(CTransaction& tx, vDelete)
|
||||||
@ -1365,7 +1374,7 @@ bool CBlock::CheckBlock() const
|
|||||||
// that can be verified before saving an orphan block.
|
// that can be verified before saving an orphan block.
|
||||||
|
|
||||||
// Size limits
|
// Size limits
|
||||||
if (vtx.empty() || vtx.size() > MAX_SIZE || ::GetSerializeSize(*this, SER_DISK) > MAX_SIZE)
|
if (vtx.empty() || vtx.size() > MAX_SIZE || ::GetSerializeSize(*this, SER_NETWORK) > MAX_SIZE)
|
||||||
return error("CheckBlock() : size limits failed");
|
return error("CheckBlock() : size limits failed");
|
||||||
|
|
||||||
// Check timestamp
|
// Check timestamp
|
||||||
@ -1407,6 +1416,15 @@ bool CBlock::AcceptBlock()
|
|||||||
if (mi == mapBlockIndex.end())
|
if (mi == mapBlockIndex.end())
|
||||||
return error("AcceptBlock() : prev block not found");
|
return error("AcceptBlock() : prev block not found");
|
||||||
CBlockIndex* pindexPrev = (*mi).second;
|
CBlockIndex* pindexPrev = (*mi).second;
|
||||||
|
int nHeight = pindexPrev->nHeight+1;
|
||||||
|
|
||||||
|
// Check size
|
||||||
|
if (nHeight > 79400 && ::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
|
||||||
|
return error("AcceptBlock() : over size limit");
|
||||||
|
|
||||||
|
// Check that it's not full of nonstandard transactions
|
||||||
|
if (nHeight > 79400 && GetSigOpCount() > MAX_BLOCK_SIGOPS)
|
||||||
|
return error("AcceptBlock() : too many nonstandard transactions");
|
||||||
|
|
||||||
// Check timestamp against prev
|
// Check timestamp against prev
|
||||||
if (GetBlockTime() <= pindexPrev->GetMedianTimePast())
|
if (GetBlockTime() <= pindexPrev->GetMedianTimePast())
|
||||||
@ -1414,7 +1432,7 @@ bool CBlock::AcceptBlock()
|
|||||||
|
|
||||||
// Check that all transactions are finalized
|
// Check that all transactions are finalized
|
||||||
foreach(const CTransaction& tx, vtx)
|
foreach(const CTransaction& tx, vtx)
|
||||||
if (!tx.IsFinal(pindexPrev->nHeight+1, GetBlockTime()))
|
if (!tx.IsFinal(nHeight, GetBlockTime()))
|
||||||
return error("AcceptBlock() : contains a non-final transaction");
|
return error("AcceptBlock() : contains a non-final transaction");
|
||||||
|
|
||||||
// Check proof of work
|
// Check proof of work
|
||||||
@ -1422,12 +1440,12 @@ bool CBlock::AcceptBlock()
|
|||||||
return error("AcceptBlock() : incorrect proof of work");
|
return error("AcceptBlock() : incorrect proof of work");
|
||||||
|
|
||||||
// Check that the block chain matches the known block chain up to a checkpoint
|
// Check that the block chain matches the known block chain up to a checkpoint
|
||||||
if ((pindexPrev->nHeight+1 == 11111 && hash != uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) ||
|
if ((nHeight == 11111 && hash != uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) ||
|
||||||
(pindexPrev->nHeight+1 == 33333 && hash != uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) ||
|
(nHeight == 33333 && hash != uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) ||
|
||||||
(pindexPrev->nHeight+1 == 68555 && hash != uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a")) ||
|
(nHeight == 68555 && hash != uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a")) ||
|
||||||
(pindexPrev->nHeight+1 == 70567 && hash != uint256("0x00000000006a49b14bcf27462068f1264c961f11fa2e0eddd2be0791e1d4124a")) ||
|
(nHeight == 70567 && hash != uint256("0x00000000006a49b14bcf27462068f1264c961f11fa2e0eddd2be0791e1d4124a")) ||
|
||||||
(pindexPrev->nHeight+1 == 74000 && hash != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")))
|
(nHeight == 74000 && hash != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")))
|
||||||
return error("AcceptBlock() : rejected by checkpoint lockin at %d", pindexPrev->nHeight+1);
|
return error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight);
|
||||||
|
|
||||||
// Scanback checkpoint lockin
|
// Scanback checkpoint lockin
|
||||||
for (CBlockIndex* pindex = pindexPrev; pindex->nHeight >= 74000; pindex = pindex->pprev)
|
for (CBlockIndex* pindex = pindexPrev; pindex->nHeight >= 74000; pindex = pindex->pprev)
|
||||||
@ -2012,13 +2030,13 @@ bool ProcessMessages(CNode* pfrom)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PrintException(&e, "ProcessMessage()");
|
PrintExceptionContinue(&e, "ProcessMessage()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
PrintException(&e, "ProcessMessage()");
|
PrintExceptionContinue(&e, "ProcessMessage()");
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
PrintException(NULL, "ProcessMessage()");
|
PrintExceptionContinue(NULL, "ProcessMessage()");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fRet)
|
if (!fRet)
|
||||||
@ -2165,7 +2183,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
multimap<uint256, CNode*> mapMix;
|
multimap<uint256, CNode*> mapMix;
|
||||||
foreach(CNode* pnode, vNodes)
|
foreach(CNode* pnode, vNodes)
|
||||||
mapMix.insert(make_pair(hashRand = Hash(BEGIN(hashRand), END(hashRand)), pnode));
|
mapMix.insert(make_pair(hashRand = Hash(BEGIN(hashRand), END(hashRand)), pnode));
|
||||||
int nRelayNodes = 4;
|
int nRelayNodes = 2;
|
||||||
for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
|
for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
|
||||||
((*mi).second)->PushAddress(addr);
|
((*mi).second)->PushAddress(addr);
|
||||||
}
|
}
|
||||||
@ -2313,7 +2331,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
pfrom->AddInventoryKnown(inv);
|
pfrom->AddInventoryKnown(inv);
|
||||||
|
|
||||||
bool fMissingInputs = false;
|
bool fMissingInputs = false;
|
||||||
if (tx.AcceptTransaction(true, &fMissingInputs))
|
if (tx.AcceptToMemoryPool(true, &fMissingInputs))
|
||||||
{
|
{
|
||||||
AddToWalletIfMine(tx, NULL);
|
AddToWalletIfMine(tx, NULL);
|
||||||
RelayMessage(inv, vMsg);
|
RelayMessage(inv, vMsg);
|
||||||
@ -2333,7 +2351,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
CDataStream(vMsg) >> tx;
|
CDataStream(vMsg) >> tx;
|
||||||
CInv inv(MSG_TX, tx.GetHash());
|
CInv inv(MSG_TX, tx.GetHash());
|
||||||
|
|
||||||
if (tx.AcceptTransaction(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,6).c_str());
|
||||||
AddToWalletIfMine(tx, NULL);
|
AddToWalletIfMine(tx, NULL);
|
||||||
@ -2809,8 +2827,9 @@ void BitcoinMiner()
|
|||||||
map<uint256, CTxIndex> mapTestPool;
|
map<uint256, CTxIndex> mapTestPool;
|
||||||
vector<char> vfAlreadyAdded(mapTransactions.size());
|
vector<char> vfAlreadyAdded(mapTransactions.size());
|
||||||
bool fFoundSomething = true;
|
bool fFoundSomething = true;
|
||||||
uint64 nBlockSize = 0;
|
uint64 nBlockSize = 10000;
|
||||||
while (fFoundSomething && nBlockSize < MAX_SIZE/2)
|
int nBlockSigOps = 100;
|
||||||
|
while (fFoundSomething)
|
||||||
{
|
{
|
||||||
fFoundSomething = false;
|
fFoundSomething = false;
|
||||||
unsigned int n = 0;
|
unsigned int n = 0;
|
||||||
@ -2822,7 +2841,10 @@ void BitcoinMiner()
|
|||||||
if (tx.IsCoinBase() || !tx.IsFinal())
|
if (tx.IsCoinBase() || !tx.IsFinal())
|
||||||
continue;
|
continue;
|
||||||
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK);
|
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK);
|
||||||
if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE - 10000)
|
if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE)
|
||||||
|
continue;
|
||||||
|
int nTxSigOps = tx.GetSigOpCount();
|
||||||
|
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Transaction fee based on block size
|
// Transaction fee based on block size
|
||||||
@ -2835,6 +2857,7 @@ void BitcoinMiner()
|
|||||||
|
|
||||||
pblock->vtx.push_back(tx);
|
pblock->vtx.push_back(tx);
|
||||||
nBlockSize += nTxSize;
|
nBlockSize += nTxSize;
|
||||||
|
nBlockSigOps += nTxSigOps;
|
||||||
vfAlreadyAdded[n] = true;
|
vfAlreadyAdded[n] = true;
|
||||||
fFoundSomething = true;
|
fFoundSomething = true;
|
||||||
}
|
}
|
||||||
@ -3297,7 +3320,7 @@ bool CommitTransaction(CWalletTx& wtxNew, const CKey& key)
|
|||||||
|
|
||||||
// Add the change's private key to wallet
|
// Add the change's private key to wallet
|
||||||
if (!key.IsNull() && !AddKey(key))
|
if (!key.IsNull() && !AddKey(key))
|
||||||
throw runtime_error("CommitTransaction() : AddKey failed\n");
|
throw runtime_error("CommitTransaction() : AddKey failed");
|
||||||
|
|
||||||
// Add tx to wallet, because if it has change it's also ours,
|
// Add tx to wallet, because if it has change it's also ours,
|
||||||
// otherwise just for transaction history.
|
// otherwise just for transaction history.
|
||||||
@ -3320,7 +3343,7 @@ bool CommitTransaction(CWalletTx& wtxNew, const CKey& key)
|
|||||||
mapRequestCount[wtxNew.GetHash()] = 0;
|
mapRequestCount[wtxNew.GetHash()] = 0;
|
||||||
|
|
||||||
// Broadcast
|
// Broadcast
|
||||||
if (!wtxNew.AcceptTransaction())
|
if (!wtxNew.AcceptToMemoryPool())
|
||||||
{
|
{
|
||||||
// This must not fail. The transaction has already been signed and recorded.
|
// This must not fail. The transaction has already been signed and recorded.
|
||||||
printf("CommitTransaction() : Error: Transaction not valid");
|
printf("CommitTransaction() : Error: Transaction not valid");
|
||||||
|
50
main.h
50
main.h
@ -15,6 +15,7 @@ class CWalletTx;
|
|||||||
class CKeyItem;
|
class CKeyItem;
|
||||||
|
|
||||||
static const unsigned int MAX_BLOCK_SIZE = 1000000;
|
static const unsigned int MAX_BLOCK_SIZE = 1000000;
|
||||||
|
static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
|
||||||
static const int64 COIN = 100000000;
|
static const int64 COIN = 100000000;
|
||||||
static const int64 CENT = 1000000;
|
static const int64 CENT = 1000000;
|
||||||
static const int64 MAX_MONEY = 21000000 * COIN;
|
static const int64 MAX_MONEY = 21000000 * COIN;
|
||||||
@ -266,7 +267,7 @@ public:
|
|||||||
str += strprintf("CTxIn(");
|
str += strprintf("CTxIn(");
|
||||||
str += prevout.ToString();
|
str += prevout.ToString();
|
||||||
if (prevout.IsNull())
|
if (prevout.IsNull())
|
||||||
str += strprintf(", coinbase %s", HexStr(scriptSig.begin(), scriptSig.end(), false).c_str());
|
str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
|
||||||
else
|
else
|
||||||
str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
|
str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
|
||||||
if (nSequence != UINT_MAX)
|
if (nSequence != UINT_MAX)
|
||||||
@ -474,7 +475,7 @@ public:
|
|||||||
return error("CTransaction::CheckTransaction() : vin or vout empty");
|
return error("CTransaction::CheckTransaction() : vin or vout empty");
|
||||||
|
|
||||||
// Size limits
|
// Size limits
|
||||||
if (::GetSerializeSize(*this, SER_DISK) > MAX_SIZE)
|
if (::GetSerializeSize(*this, SER_NETWORK) > MAX_SIZE)
|
||||||
return error("CTransaction::CheckTransaction() : size limits failed");
|
return error("CTransaction::CheckTransaction() : size limits failed");
|
||||||
|
|
||||||
// Check for negative or overflow output values
|
// Check for negative or overflow output values
|
||||||
@ -505,6 +506,16 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetSigOpCount() const
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
foreach(const CTxIn& txin, vin)
|
||||||
|
n += txin.scriptSig.GetSigOpCount();
|
||||||
|
foreach(const CTxOut& txout, vout)
|
||||||
|
n += txout.scriptPubKey.GetSigOpCount();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsMine() const
|
bool IsMine() const
|
||||||
{
|
{
|
||||||
foreach(const CTxOut& txout, vout)
|
foreach(const CTxOut& txout, vout)
|
||||||
@ -570,11 +581,16 @@ public:
|
|||||||
if (txout.nValue < CENT)
|
if (txout.nValue < CENT)
|
||||||
nMinFee = CENT;
|
nMinFee = CENT;
|
||||||
|
|
||||||
|
// Raise the price as the block approaches full
|
||||||
|
if (MAX_BLOCK_SIZE/2 <= nBlockSize && nBlockSize < MAX_BLOCK_SIZE)
|
||||||
|
nMinFee *= MAX_BLOCK_SIZE / (MAX_BLOCK_SIZE - nBlockSize);
|
||||||
|
if (!MoneyRange(nMinFee))
|
||||||
|
nMinFee = MAX_MONEY;
|
||||||
|
|
||||||
return nMinFee;
|
return nMinFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
|
bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
|
||||||
{
|
{
|
||||||
CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
|
CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
|
||||||
@ -639,16 +655,16 @@ public:
|
|||||||
CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0);
|
CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0);
|
||||||
bool ClientConnectInputs();
|
bool ClientConnectInputs();
|
||||||
|
|
||||||
bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
|
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
|
||||||
|
|
||||||
bool AcceptTransaction(bool fCheckInputs=true, bool* pfMissingInputs=NULL)
|
bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL)
|
||||||
{
|
{
|
||||||
CTxDB txdb("r");
|
CTxDB txdb("r");
|
||||||
return AcceptTransaction(txdb, fCheckInputs, pfMissingInputs);
|
return AcceptToMemoryPool(txdb, fCheckInputs, pfMissingInputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool AddToMemoryPool();
|
bool AddToMemoryPoolUnchecked();
|
||||||
public:
|
public:
|
||||||
bool RemoveFromMemoryPool();
|
bool RemoveFromMemoryPool();
|
||||||
};
|
};
|
||||||
@ -721,8 +737,8 @@ public:
|
|||||||
int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
|
int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
|
||||||
bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
|
bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
|
||||||
int GetBlocksToMaturity() const;
|
int GetBlocksToMaturity() const;
|
||||||
bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true);
|
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
|
||||||
bool AcceptTransaction() { CTxDB txdb("r"); return AcceptTransaction(txdb); }
|
bool AcceptToMemoryPool() { CTxDB txdb("r"); return AcceptToMemoryPool(txdb); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -852,12 +868,8 @@ public:
|
|||||||
|
|
||||||
friend bool operator==(const CTxIndex& a, const CTxIndex& b)
|
friend bool operator==(const CTxIndex& a, const CTxIndex& b)
|
||||||
{
|
{
|
||||||
if (a.pos != b.pos || a.vSpent.size() != b.vSpent.size())
|
return (a.pos == b.pos &&
|
||||||
return false;
|
a.vSpent == b.vSpent);
|
||||||
for (int i = 0; i < a.vSpent.size(); i++)
|
|
||||||
if (a.vSpent[i] != b.vSpent[i])
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
|
friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
|
||||||
@ -948,6 +960,14 @@ public:
|
|||||||
return (int64)nTime;
|
return (int64)nTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetSigOpCount() const
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
foreach(const CTransaction& tx, vtx)
|
||||||
|
n += tx.GetSigOpCount();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint256 BuildMerkleTree() const
|
uint256 BuildMerkleTree() const
|
||||||
{
|
{
|
||||||
|
@ -7,11 +7,13 @@ INCLUDEPATHS= \
|
|||||||
-I"/usr/local/include/wx-2.9" \
|
-I"/usr/local/include/wx-2.9" \
|
||||||
-I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9"
|
-I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9"
|
||||||
|
|
||||||
|
# for wxWidgets 2.9.1, add -l Xxf86vm
|
||||||
WXLIBS= \
|
WXLIBS= \
|
||||||
-Wl,-Bstatic \
|
-Wl,-Bstatic \
|
||||||
-l wx_gtk2ud-2.9 \
|
-l wx_gtk2ud-2.9 \
|
||||||
-Wl,-Bdynamic \
|
-Wl,-Bdynamic \
|
||||||
-l gtk-x11-2.0 -l SM
|
-l gtk-x11-2.0 \
|
||||||
|
-l SM
|
||||||
|
|
||||||
# for boost 1.37, add -mt to the boost libraries
|
# for boost 1.37, add -mt to the boost libraries
|
||||||
LIBS= \
|
LIBS= \
|
||||||
|
53
net.cpp
53
net.cpp
@ -25,7 +25,6 @@ CNode* pnodeLocalHost = NULL;
|
|||||||
uint64 nLocalHostNonce = 0;
|
uint64 nLocalHostNonce = 0;
|
||||||
array<int, 10> vnThreadsRunning;
|
array<int, 10> vnThreadsRunning;
|
||||||
SOCKET hListenSocket = INVALID_SOCKET;
|
SOCKET hListenSocket = INVALID_SOCKET;
|
||||||
int64 nThreadSocketHandlerHeartbeat = INT64_MAX;
|
|
||||||
|
|
||||||
vector<CNode*> vNodes;
|
vector<CNode*> vNodes;
|
||||||
CCriticalSection cs_vNodes;
|
CCriticalSection cs_vNodes;
|
||||||
@ -789,7 +788,6 @@ void ThreadSocketHandler2(void* parg)
|
|||||||
pnode->Release();
|
pnode->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
nThreadSocketHandlerHeartbeat = GetTime();
|
|
||||||
Sleep(10);
|
Sleep(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1364,57 +1362,6 @@ void StartNode(void* parg)
|
|||||||
|
|
||||||
// Generate coins in the background
|
// Generate coins in the background
|
||||||
GenerateBitcoins(fGenerateBitcoins);
|
GenerateBitcoins(fGenerateBitcoins);
|
||||||
|
|
||||||
//
|
|
||||||
// Thread monitoring
|
|
||||||
// Not really needed anymore, the cause of the hanging was fixed
|
|
||||||
//
|
|
||||||
loop
|
|
||||||
{
|
|
||||||
Sleep(1000);
|
|
||||||
if (fShutdown)
|
|
||||||
return;
|
|
||||||
if (GetTime() - nThreadSocketHandlerHeartbeat > 15 * 60)
|
|
||||||
{
|
|
||||||
// First see if closing sockets will free it
|
|
||||||
printf("*** ThreadSocketHandler is stopped ***\n");
|
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
|
||||||
{
|
|
||||||
foreach(CNode* pnode, vNodes)
|
|
||||||
{
|
|
||||||
bool fGot = false;
|
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
|
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
|
|
||||||
fGot = true;
|
|
||||||
if (!fGot)
|
|
||||||
{
|
|
||||||
printf("*** closing socket\n");
|
|
||||||
pnode->CloseSocketDisconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Sleep(10000);
|
|
||||||
if (fShutdown)
|
|
||||||
return;
|
|
||||||
if (GetTime() - nThreadSocketHandlerHeartbeat < 60)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Hopefully it never comes to this.
|
|
||||||
// We know it'll always be hung in the recv or send call.
|
|
||||||
// cs_vRecv or cs_vSend may be left permanently unreleased,
|
|
||||||
// but we always only use TRY_CRITICAL_SECTION on them.
|
|
||||||
printf("*** Restarting ThreadSocketHandler ***\n");
|
|
||||||
TerminateThread(hThreadSocketHandler, 0);
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
CloseHandle(hThreadSocketHandler);
|
|
||||||
#endif
|
|
||||||
vnThreadsRunning[0] = 0;
|
|
||||||
|
|
||||||
// Restart
|
|
||||||
hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
|
|
||||||
nThreadSocketHandlerHeartbeat = GetTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StopNode()
|
bool StopNode()
|
||||||
|
5
net.h
5
net.h
@ -117,9 +117,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Message size
|
// Message size
|
||||||
if (nMessageSize > 0x10000000)
|
if (nMessageSize > MAX_SIZE)
|
||||||
{
|
{
|
||||||
printf("CMessageHeader::IsValid() : nMessageSize too large %u\n", nMessageSize);
|
printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,7 +466,6 @@ extern CNode* pnodeLocalHost;
|
|||||||
extern uint64 nLocalHostNonce;
|
extern uint64 nLocalHostNonce;
|
||||||
extern array<int, 10> vnThreadsRunning;
|
extern array<int, 10> vnThreadsRunning;
|
||||||
extern SOCKET hListenSocket;
|
extern SOCKET hListenSocket;
|
||||||
extern int64 nThreadSocketHandlerHeartbeat;
|
|
||||||
|
|
||||||
extern vector<CNode*> vNodes;
|
extern vector<CNode*> vNodes;
|
||||||
extern CCriticalSection cs_vNodes;
|
extern CCriticalSection cs_vNodes;
|
||||||
|
112
script.cpp
112
script.cpp
@ -59,6 +59,13 @@ void MakeSameSize(valtype& vch1, valtype& vch2)
|
|||||||
//
|
//
|
||||||
#define stacktop(i) (stack.at(stack.size()+(i)))
|
#define stacktop(i) (stack.at(stack.size()+(i)))
|
||||||
#define altstacktop(i) (altstack.at(altstack.size()+(i)))
|
#define altstacktop(i) (altstack.at(altstack.size()+(i)))
|
||||||
|
static inline void popstack(vector<valtype>& stack)
|
||||||
|
{
|
||||||
|
if (stack.empty())
|
||||||
|
throw runtime_error("popstack() : stack empty");
|
||||||
|
stack.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType)
|
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType)
|
||||||
{
|
{
|
||||||
@ -66,6 +73,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
CScript::const_iterator pc = script.begin();
|
CScript::const_iterator pc = script.begin();
|
||||||
CScript::const_iterator pend = script.end();
|
CScript::const_iterator pend = script.end();
|
||||||
CScript::const_iterator pbegincodehash = script.begin();
|
CScript::const_iterator pbegincodehash = script.begin();
|
||||||
|
opcodetype opcode;
|
||||||
|
valtype vchPushValue;
|
||||||
vector<bool> vfExec;
|
vector<bool> vfExec;
|
||||||
vector<valtype> altstack;
|
vector<valtype> altstack;
|
||||||
if (script.size() > 10000)
|
if (script.size() > 10000)
|
||||||
@ -82,13 +91,11 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
//
|
//
|
||||||
// Read instruction
|
// Read instruction
|
||||||
//
|
//
|
||||||
opcodetype opcode;
|
|
||||||
valtype vchPushValue;
|
|
||||||
if (!script.GetOp(pc, opcode, vchPushValue))
|
if (!script.GetOp(pc, opcode, vchPushValue))
|
||||||
return false;
|
return false;
|
||||||
if (vchPushValue.size() > 520)
|
if (vchPushValue.size() > 520)
|
||||||
return false;
|
return false;
|
||||||
if (opcode > OP_16 && nOpCount++ > 200)
|
if (opcode > OP_16 && ++nOpCount > 201)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (opcode == OP_CAT ||
|
if (opcode == OP_CAT ||
|
||||||
@ -108,7 +115,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
opcode == OP_RSHIFT)
|
opcode == OP_RSHIFT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fExec && opcode <= OP_PUSHDATA4)
|
if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4)
|
||||||
stack.push_back(vchPushValue);
|
stack.push_back(vchPushValue);
|
||||||
else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
|
else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
@ -149,14 +156,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
|
case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_VER:
|
|
||||||
case OP_VERIF:
|
|
||||||
case OP_VERNOTIF:
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OP_IF:
|
case OP_IF:
|
||||||
case OP_NOTIF:
|
case OP_NOTIF:
|
||||||
{
|
{
|
||||||
@ -170,7 +169,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
fValue = CastToBool(vch);
|
fValue = CastToBool(vch);
|
||||||
if (opcode == OP_NOTIF)
|
if (opcode == OP_NOTIF)
|
||||||
fValue = !fValue;
|
fValue = !fValue;
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
}
|
}
|
||||||
vfExec.push_back(fValue);
|
vfExec.push_back(fValue);
|
||||||
}
|
}
|
||||||
@ -200,7 +199,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
return false;
|
return false;
|
||||||
bool fValue = CastToBool(stacktop(-1));
|
bool fValue = CastToBool(stacktop(-1));
|
||||||
if (fValue)
|
if (fValue)
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -221,7 +220,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
if (stack.size() < 1)
|
if (stack.size() < 1)
|
||||||
return false;
|
return false;
|
||||||
altstack.push_back(stacktop(-1));
|
altstack.push_back(stacktop(-1));
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -230,15 +229,17 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
if (altstack.size() < 1)
|
if (altstack.size() < 1)
|
||||||
return false;
|
return false;
|
||||||
stack.push_back(altstacktop(-1));
|
stack.push_back(altstacktop(-1));
|
||||||
altstack.pop_back();
|
popstack(altstack);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_2DROP:
|
case OP_2DROP:
|
||||||
{
|
{
|
||||||
// (x1 x2 -- )
|
// (x1 x2 -- )
|
||||||
stack.pop_back();
|
if (stack.size() < 2)
|
||||||
stack.pop_back();
|
return false;
|
||||||
|
popstack(stack);
|
||||||
|
popstack(stack);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -327,7 +328,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
// (x -- )
|
// (x -- )
|
||||||
if (stack.size() < 1)
|
if (stack.size() < 1)
|
||||||
return false;
|
return false;
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -368,7 +369,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
if (stack.size() < 2)
|
if (stack.size() < 2)
|
||||||
return false;
|
return false;
|
||||||
int n = CastToBigNum(stacktop(-1)).getint();
|
int n = CastToBigNum(stacktop(-1)).getint();
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
if (n < 0 || n >= stack.size())
|
if (n < 0 || n >= stack.size())
|
||||||
return false;
|
return false;
|
||||||
valtype vch = stacktop(-n-1);
|
valtype vch = stacktop(-n-1);
|
||||||
@ -421,7 +422,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
valtype& vch1 = stacktop(-2);
|
valtype& vch1 = stacktop(-2);
|
||||||
valtype& vch2 = stacktop(-1);
|
valtype& vch2 = stacktop(-1);
|
||||||
vch1.insert(vch1.end(), vch2.begin(), vch2.end());
|
vch1.insert(vch1.end(), vch2.begin(), vch2.end());
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
if (stacktop(-1).size() > 520)
|
if (stacktop(-1).size() > 520)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -443,8 +444,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
nEnd = vch.size();
|
nEnd = vch.size();
|
||||||
vch.erase(vch.begin() + nEnd, vch.end());
|
vch.erase(vch.begin() + nEnd, vch.end());
|
||||||
vch.erase(vch.begin(), vch.begin() + nBegin);
|
vch.erase(vch.begin(), vch.begin() + nBegin);
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -464,7 +465,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
vch.erase(vch.begin() + nSize, vch.end());
|
vch.erase(vch.begin() + nSize, vch.end());
|
||||||
else
|
else
|
||||||
vch.erase(vch.begin(), vch.end() - nSize);
|
vch.erase(vch.begin(), vch.end() - nSize);
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -518,7 +519,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
for (int i = 0; i < vch1.size(); i++)
|
for (int i = 0; i < vch1.size(); i++)
|
||||||
vch1[i] ^= vch2[i];
|
vch1[i] ^= vch2[i];
|
||||||
}
|
}
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -537,13 +538,13 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
// zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
|
// zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
|
||||||
//if (opcode == OP_NOTEQUAL)
|
//if (opcode == OP_NOTEQUAL)
|
||||||
// fEqual = !fEqual;
|
// fEqual = !fEqual;
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.push_back(fEqual ? vchTrue : vchFalse);
|
stack.push_back(fEqual ? vchTrue : vchFalse);
|
||||||
if (opcode == OP_EQUALVERIFY)
|
if (opcode == OP_EQUALVERIFY)
|
||||||
{
|
{
|
||||||
if (fEqual)
|
if (fEqual)
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -578,7 +579,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
case OP_NOT: bn = (bn == bnZero); break;
|
case OP_NOT: bn = (bn == bnZero); break;
|
||||||
case OP_0NOTEQUAL: bn = (bn != bnZero); break;
|
case OP_0NOTEQUAL: bn = (bn != bnZero); break;
|
||||||
}
|
}
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.push_back(bn.getvch());
|
stack.push_back(bn.getvch());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -657,14 +658,14 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break;
|
case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break;
|
||||||
case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break;
|
case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break;
|
||||||
}
|
}
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.push_back(bn.getvch());
|
stack.push_back(bn.getvch());
|
||||||
|
|
||||||
if (opcode == OP_NUMEQUALVERIFY)
|
if (opcode == OP_NUMEQUALVERIFY)
|
||||||
{
|
{
|
||||||
if (CastToBool(stacktop(-1)))
|
if (CastToBool(stacktop(-1)))
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -680,9 +681,9 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
CBigNum bn2 = CastToBigNum(stacktop(-2));
|
CBigNum bn2 = CastToBigNum(stacktop(-2));
|
||||||
CBigNum bn3 = CastToBigNum(stacktop(-1));
|
CBigNum bn3 = CastToBigNum(stacktop(-1));
|
||||||
bool fValue = (bn2 <= bn1 && bn1 < bn3);
|
bool fValue = (bn2 <= bn1 && bn1 < bn3);
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.push_back(fValue ? vchTrue : vchFalse);
|
stack.push_back(fValue ? vchTrue : vchFalse);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -718,7 +719,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
uint256 hash = Hash(vch.begin(), vch.end());
|
uint256 hash = Hash(vch.begin(), vch.end());
|
||||||
memcpy(&vchHash[0], &hash, sizeof(hash));
|
memcpy(&vchHash[0], &hash, sizeof(hash));
|
||||||
}
|
}
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.push_back(vchHash);
|
stack.push_back(vchHash);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -752,13 +753,13 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
|
|
||||||
bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType);
|
bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType);
|
||||||
|
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.push_back(fSuccess ? vchTrue : vchFalse);
|
stack.push_back(fSuccess ? vchTrue : vchFalse);
|
||||||
if (opcode == OP_CHECKSIGVERIFY)
|
if (opcode == OP_CHECKSIGVERIFY)
|
||||||
{
|
{
|
||||||
if (fSuccess)
|
if (fSuccess)
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -822,13 +823,13 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (i-- > 0)
|
while (i-- > 0)
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
stack.push_back(fSuccess ? vchTrue : vchFalse);
|
stack.push_back(fSuccess ? vchTrue : vchFalse);
|
||||||
|
|
||||||
if (opcode == OP_CHECKMULTISIGVERIFY)
|
if (opcode == OP_CHECKMULTISIGVERIFY)
|
||||||
{
|
{
|
||||||
if (fSuccess)
|
if (fSuccess)
|
||||||
stack.pop_back();
|
popstack(stack);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -856,8 +857,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef top
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -945,10 +944,7 @@ bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CSc
|
|||||||
return false;
|
return false;
|
||||||
vchSig.pop_back();
|
vchSig.pop_back();
|
||||||
|
|
||||||
if (key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig))
|
return key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig);
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -986,21 +982,19 @@ bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSo
|
|||||||
CScript::const_iterator pc2 = script2.begin();
|
CScript::const_iterator pc2 = script2.begin();
|
||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
bool f1 = script1.GetOp(pc1, opcode1, vch1);
|
if (pc1 == script1.end() && pc2 == script2.end())
|
||||||
bool f2 = script2.GetOp(pc2, opcode2, vch2);
|
|
||||||
if (!f1 && !f2)
|
|
||||||
{
|
{
|
||||||
// Success
|
// Found a match
|
||||||
reverse(vSolutionRet.begin(), vSolutionRet.end());
|
reverse(vSolutionRet.begin(), vSolutionRet.end());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (f1 != f2)
|
if (!script1.GetOp(pc1, opcode1, vch1))
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
if (!script2.GetOp(pc2, opcode2, vch2))
|
||||||
else if (opcode2 == OP_PUBKEY)
|
break;
|
||||||
|
if (opcode2 == OP_PUBKEY)
|
||||||
{
|
{
|
||||||
if (vch1.size() <= sizeof(uint256))
|
if (vch1.size() < 33)
|
||||||
break;
|
break;
|
||||||
vSolutionRet.push_back(make_pair(opcode2, vch1));
|
vSolutionRet.push_back(make_pair(opcode2, vch1));
|
||||||
}
|
}
|
||||||
@ -1010,7 +1004,7 @@ bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSo
|
|||||||
break;
|
break;
|
||||||
vSolutionRet.push_back(make_pair(opcode2, vch1));
|
vSolutionRet.push_back(make_pair(opcode2, vch1));
|
||||||
}
|
}
|
||||||
else if (opcode1 != opcode2)
|
else if (opcode1 != opcode2 || vch1 != vch2)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1068,6 +1062,10 @@ bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& s
|
|||||||
scriptSigRet << vchSig << vchPubKey;
|
scriptSigRet << vchSig << vchPubKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
178
script.h
178
script.h
@ -150,18 +150,11 @@ enum opcodetype
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// multi-byte opcodes
|
|
||||||
OP_SINGLEBYTE_END = 0xF0,
|
|
||||||
OP_DOUBLEBYTE_BEGIN = 0xF000,
|
|
||||||
|
|
||||||
// template matching params
|
// template matching params
|
||||||
OP_PUBKEY,
|
OP_PUBKEYHASH = 0xfd,
|
||||||
OP_PUBKEYHASH,
|
OP_PUBKEY = 0xfe,
|
||||||
|
|
||||||
|
OP_INVALIDOPCODE = 0xff,
|
||||||
|
|
||||||
OP_INVALIDOPCODE = 0xFFFF,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -304,16 +297,13 @@ inline const char* GetOpName(opcodetype opcode)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// multi-byte opcodes
|
// template matching params
|
||||||
case OP_SINGLEBYTE_END : return "OP_SINGLEBYTE_END";
|
|
||||||
case OP_DOUBLEBYTE_BEGIN : return "OP_DOUBLEBYTE_BEGIN";
|
|
||||||
case OP_PUBKEY : return "OP_PUBKEY";
|
|
||||||
case OP_PUBKEYHASH : return "OP_PUBKEYHASH";
|
case OP_PUBKEYHASH : return "OP_PUBKEYHASH";
|
||||||
|
case OP_PUBKEY : return "OP_PUBKEY";
|
||||||
|
|
||||||
case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";
|
case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN_OPCODE";
|
return "OP_UNKNOWN";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -325,8 +315,7 @@ inline string ValueString(const vector<unsigned char>& vch)
|
|||||||
if (vch.size() <= 4)
|
if (vch.size() <= 4)
|
||||||
return strprintf("%d", CBigNum(vch).getint());
|
return strprintf("%d", CBigNum(vch).getint());
|
||||||
else
|
else
|
||||||
return HexNumStr(vch.begin(), vch.end());
|
return HexStr(vch);
|
||||||
//return string("(") + HexStr(vch.begin(), vch.end()) + string(")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline string StackString(const vector<vector<unsigned char> >& vStack)
|
inline string StackString(const vector<vector<unsigned char> >& vStack)
|
||||||
@ -363,12 +352,12 @@ protected:
|
|||||||
CBigNum bn(n);
|
CBigNum bn(n);
|
||||||
*this << bn.getvch();
|
*this << bn.getvch();
|
||||||
}
|
}
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScript& push_uint64(uint64 n)
|
CScript& push_uint64(uint64 n)
|
||||||
{
|
{
|
||||||
if (n == -1 || (n >= 1 && n <= 16))
|
if (n >= 1 && n <= 16)
|
||||||
{
|
{
|
||||||
push_back(n + (OP_1 - 1));
|
push_back(n + (OP_1 - 1));
|
||||||
}
|
}
|
||||||
@ -377,7 +366,7 @@ protected:
|
|||||||
CBigNum bn(n);
|
CBigNum bn(n);
|
||||||
*this << bn.getvch();
|
*this << bn.getvch();
|
||||||
}
|
}
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -398,7 +387,7 @@ public:
|
|||||||
{
|
{
|
||||||
CScript ret = a;
|
CScript ret = a;
|
||||||
ret += b;
|
ret += b;
|
||||||
return (ret);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -419,50 +408,43 @@ public:
|
|||||||
explicit CScript(const vector<unsigned char>& b) { operator<<(b); }
|
explicit CScript(const vector<unsigned char>& b) { operator<<(b); }
|
||||||
|
|
||||||
|
|
||||||
CScript& operator<<(char b) { return (push_int64(b)); }
|
CScript& operator<<(char b) { return push_int64(b); }
|
||||||
CScript& operator<<(short b) { return (push_int64(b)); }
|
CScript& operator<<(short b) { return push_int64(b); }
|
||||||
CScript& operator<<(int b) { return (push_int64(b)); }
|
CScript& operator<<(int b) { return push_int64(b); }
|
||||||
CScript& operator<<(long b) { return (push_int64(b)); }
|
CScript& operator<<(long b) { return push_int64(b); }
|
||||||
CScript& operator<<(int64 b) { return (push_int64(b)); }
|
CScript& operator<<(int64 b) { return push_int64(b); }
|
||||||
CScript& operator<<(unsigned char b) { return (push_uint64(b)); }
|
CScript& operator<<(unsigned char b) { return push_uint64(b); }
|
||||||
CScript& operator<<(unsigned int b) { return (push_uint64(b)); }
|
CScript& operator<<(unsigned int b) { return push_uint64(b); }
|
||||||
CScript& operator<<(unsigned short b) { return (push_uint64(b)); }
|
CScript& operator<<(unsigned short b) { return push_uint64(b); }
|
||||||
CScript& operator<<(unsigned long b) { return (push_uint64(b)); }
|
CScript& operator<<(unsigned long b) { return push_uint64(b); }
|
||||||
CScript& operator<<(uint64 b) { return (push_uint64(b)); }
|
CScript& operator<<(uint64 b) { return push_uint64(b); }
|
||||||
|
|
||||||
CScript& operator<<(opcodetype opcode)
|
CScript& operator<<(opcodetype opcode)
|
||||||
{
|
{
|
||||||
if (opcode <= OP_SINGLEBYTE_END)
|
if (opcode < 0 || opcode > 0xff)
|
||||||
{
|
throw runtime_error("CScript::operator<<() : invalid opcode");
|
||||||
insert(end(), (unsigned char)opcode);
|
insert(end(), (unsigned char)opcode);
|
||||||
}
|
return *this;
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(opcode >= OP_DOUBLEBYTE_BEGIN);
|
|
||||||
insert(end(), (unsigned char)(opcode >> 8));
|
|
||||||
insert(end(), (unsigned char)(opcode & 0xFF));
|
|
||||||
}
|
|
||||||
return (*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CScript& operator<<(const uint160& b)
|
CScript& operator<<(const uint160& b)
|
||||||
{
|
{
|
||||||
insert(end(), sizeof(b));
|
insert(end(), sizeof(b));
|
||||||
insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
|
insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScript& operator<<(const uint256& b)
|
CScript& operator<<(const uint256& b)
|
||||||
{
|
{
|
||||||
insert(end(), sizeof(b));
|
insert(end(), sizeof(b));
|
||||||
insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
|
insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScript& operator<<(const CBigNum& b)
|
CScript& operator<<(const CBigNum& b)
|
||||||
{
|
{
|
||||||
*this << b.getvch();
|
*this << b.getvch();
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScript& operator<<(const vector<unsigned char>& b)
|
CScript& operator<<(const vector<unsigned char>& b)
|
||||||
@ -476,14 +458,20 @@ public:
|
|||||||
insert(end(), OP_PUSHDATA1);
|
insert(end(), OP_PUSHDATA1);
|
||||||
insert(end(), (unsigned char)b.size());
|
insert(end(), (unsigned char)b.size());
|
||||||
}
|
}
|
||||||
else
|
else if (b.size() <= 0xffff)
|
||||||
{
|
{
|
||||||
insert(end(), OP_PUSHDATA2);
|
insert(end(), OP_PUSHDATA2);
|
||||||
unsigned short nSize = b.size();
|
unsigned short nSize = b.size();
|
||||||
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
|
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
insert(end(), OP_PUSHDATA4);
|
||||||
|
unsigned int nSize = b.size();
|
||||||
|
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
|
||||||
|
}
|
||||||
insert(end(), b.begin(), b.end());
|
insert(end(), b.begin(), b.end());
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScript& operator<<(const CScript& b)
|
CScript& operator<<(const CScript& b)
|
||||||
@ -491,7 +479,7 @@ public:
|
|||||||
// I'm not sure if this should push the script or concatenate scripts.
|
// I'm not sure if this should push the script or concatenate scripts.
|
||||||
// If there's ever a use for pushing a script onto a script, delete this member fn
|
// If there's ever a use for pushing a script onto a script, delete this member fn
|
||||||
assert(("warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate", false));
|
assert(("warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate", false));
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -499,41 +487,59 @@ public:
|
|||||||
{
|
{
|
||||||
// Wrapper so it can be called with either iterator or const_iterator
|
// Wrapper so it can be called with either iterator or const_iterator
|
||||||
const_iterator pc2 = pc;
|
const_iterator pc2 = pc;
|
||||||
bool fRet = GetOp(pc2, opcodeRet, vchRet);
|
bool fRet = GetOp2(pc2, opcodeRet, &vchRet);
|
||||||
|
pc = begin() + (pc2 - begin());
|
||||||
|
return fRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetOp(iterator& pc, opcodetype& opcodeRet)
|
||||||
|
{
|
||||||
|
const_iterator pc2 = pc;
|
||||||
|
bool fRet = GetOp2(pc2, opcodeRet, NULL);
|
||||||
pc = begin() + (pc2 - begin());
|
pc = begin() + (pc2 - begin());
|
||||||
return fRet;
|
return fRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) const
|
bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) const
|
||||||
|
{
|
||||||
|
return GetOp2(pc, opcodeRet, &vchRet);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetOp(const_iterator& pc, opcodetype& opcodeRet) const
|
||||||
|
{
|
||||||
|
return GetOp2(pc, opcodeRet, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetOp2(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>* pvchRet) const
|
||||||
{
|
{
|
||||||
opcodeRet = OP_INVALIDOPCODE;
|
opcodeRet = OP_INVALIDOPCODE;
|
||||||
vchRet.clear();
|
if (pvchRet)
|
||||||
|
pvchRet->clear();
|
||||||
if (pc >= end())
|
if (pc >= end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Read instruction
|
// Read instruction
|
||||||
|
if (end() - pc < 1)
|
||||||
|
return false;
|
||||||
unsigned int opcode = *pc++;
|
unsigned int opcode = *pc++;
|
||||||
if (opcode >= OP_SINGLEBYTE_END)
|
|
||||||
{
|
|
||||||
if (pc + 1 > end())
|
|
||||||
return false;
|
|
||||||
opcode <<= 8;
|
|
||||||
opcode |= *pc++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Immediate operand
|
// Immediate operand
|
||||||
if (opcode <= OP_PUSHDATA4)
|
if (opcode <= OP_PUSHDATA4)
|
||||||
{
|
{
|
||||||
unsigned int nSize = opcode;
|
unsigned int nSize;
|
||||||
if (opcode == OP_PUSHDATA1)
|
if (opcode < OP_PUSHDATA1)
|
||||||
{
|
{
|
||||||
if (pc + 1 > end())
|
nSize = opcode;
|
||||||
|
}
|
||||||
|
else if (opcode == OP_PUSHDATA1)
|
||||||
|
{
|
||||||
|
if (end() - pc < 1)
|
||||||
return false;
|
return false;
|
||||||
nSize = *pc++;
|
nSize = *pc++;
|
||||||
}
|
}
|
||||||
else if (opcode == OP_PUSHDATA2)
|
else if (opcode == OP_PUSHDATA2)
|
||||||
{
|
{
|
||||||
if (pc + 2 > end())
|
if (end() - pc < 2)
|
||||||
return false;
|
return false;
|
||||||
nSize = 0;
|
nSize = 0;
|
||||||
memcpy(&nSize, &pc[0], 2);
|
memcpy(&nSize, &pc[0], 2);
|
||||||
@ -541,14 +547,15 @@ public:
|
|||||||
}
|
}
|
||||||
else if (opcode == OP_PUSHDATA4)
|
else if (opcode == OP_PUSHDATA4)
|
||||||
{
|
{
|
||||||
if (pc + 4 > end())
|
if (end() - pc < 4)
|
||||||
return false;
|
return false;
|
||||||
memcpy(&nSize, &pc[0], 4);
|
memcpy(&nSize, &pc[0], 4);
|
||||||
pc += 4;
|
pc += 4;
|
||||||
}
|
}
|
||||||
if (pc + nSize > end())
|
if (end() - pc < nSize)
|
||||||
return false;
|
return false;
|
||||||
vchRet.assign(pc, pc + nSize);
|
if (pvchRet)
|
||||||
|
pvchRet->assign(pc, pc + nSize);
|
||||||
pc += nSize;
|
pc += nSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,20 +566,34 @@ public:
|
|||||||
|
|
||||||
void FindAndDelete(const CScript& b)
|
void FindAndDelete(const CScript& b)
|
||||||
{
|
{
|
||||||
|
if (b.empty())
|
||||||
|
return;
|
||||||
iterator pc = begin();
|
iterator pc = begin();
|
||||||
opcodetype opcode;
|
opcodetype opcode;
|
||||||
vector<unsigned char> vchPushValue;
|
|
||||||
int count = 0;
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0)
|
while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0)
|
||||||
{
|
|
||||||
erase(pc, pc + b.size());
|
erase(pc, pc + b.size());
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (GetOp(pc, opcode, vchPushValue));
|
while (GetOp(pc, opcode));
|
||||||
//printf("FindAndDeleted deleted %d items\n", count); /// debug
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GetSigOpCount() const
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
const_iterator pc = begin();
|
||||||
|
while (pc < end())
|
||||||
|
{
|
||||||
|
opcodetype opcode;
|
||||||
|
if (!GetOp(pc, opcode))
|
||||||
|
break;
|
||||||
|
if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY)
|
||||||
|
n++;
|
||||||
|
else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY)
|
||||||
|
n += 20;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -623,7 +644,7 @@ public:
|
|||||||
|
|
||||||
void PrintHex() const
|
void PrintHex() const
|
||||||
{
|
{
|
||||||
printf("CScript(%s)\n", HexStr(begin(), end()).c_str());
|
printf("CScript(%s)\n", HexStr(begin(), end(), true).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
string ToString() const
|
string ToString() const
|
||||||
@ -631,12 +652,17 @@ public:
|
|||||||
string str;
|
string str;
|
||||||
opcodetype opcode;
|
opcodetype opcode;
|
||||||
vector<unsigned char> vch;
|
vector<unsigned char> vch;
|
||||||
const_iterator it = begin();
|
const_iterator pc = begin();
|
||||||
while (GetOp(it, opcode, vch))
|
while (pc < end())
|
||||||
{
|
{
|
||||||
if (!str.empty())
|
if (!str.empty())
|
||||||
str += " ";
|
str += " ";
|
||||||
if (opcode <= OP_PUSHDATA4)
|
if (!GetOp(pc, opcode, vch))
|
||||||
|
{
|
||||||
|
str += "[error]";
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
if (0 <= opcode && opcode <= OP_PUSHDATA4)
|
||||||
str += ValueString(vch);
|
str += ValueString(vch);
|
||||||
else
|
else
|
||||||
str += GetOpName(opcode);
|
str += GetOpName(opcode);
|
||||||
|
@ -23,7 +23,7 @@ class CAutoFile;
|
|||||||
static const unsigned int MAX_SIZE = 0x02000000;
|
static const unsigned int MAX_SIZE = 0x02000000;
|
||||||
|
|
||||||
static const int VERSION = 312;
|
static const int VERSION = 312;
|
||||||
static const char* pszSubVer = ".0";
|
static const char* pszSubVer = ".1";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ RequestExecutionLevel highest
|
|||||||
|
|
||||||
# General Symbol Definitions
|
# General Symbol Definitions
|
||||||
!define REGKEY "SOFTWARE\$(^Name)"
|
!define REGKEY "SOFTWARE\$(^Name)"
|
||||||
!define VERSION 0.3.10
|
!define VERSION 0.3.12
|
||||||
!define COMPANY "Bitcoin project"
|
!define COMPANY "Bitcoin project"
|
||||||
!define URL http://www.bitcoin.org/
|
!define URL http://www.bitcoin.org/
|
||||||
|
|
||||||
@ -42,12 +42,12 @@ Var StartMenuGroup
|
|||||||
!insertmacro MUI_LANGUAGE English
|
!insertmacro MUI_LANGUAGE English
|
||||||
|
|
||||||
# Installer attributes
|
# Installer attributes
|
||||||
OutFile bitcoin-0.3.10-win32-setup.exe
|
OutFile bitcoin-0.3.12-win32-setup.exe
|
||||||
InstallDir $PROGRAMFILES\Bitcoin
|
InstallDir $PROGRAMFILES\Bitcoin
|
||||||
CRCCheck on
|
CRCCheck on
|
||||||
XPStyle on
|
XPStyle on
|
||||||
ShowInstDetails show
|
ShowInstDetails show
|
||||||
VIProductVersion 0.3.10.0
|
VIProductVersion 0.3.12.0
|
||||||
VIAddVersionKey ProductName Bitcoin
|
VIAddVersionKey ProductName Bitcoin
|
||||||
VIAddVersionKey ProductVersion "${VERSION}"
|
VIAddVersionKey ProductVersion "${VERSION}"
|
||||||
VIAddVersionKey CompanyName "${COMPANY}"
|
VIAddVersionKey CompanyName "${COMPANY}"
|
||||||
|
@ -87,6 +87,8 @@ static inline void dumpreg(__m128i x, char *msg) {
|
|||||||
#else
|
#else
|
||||||
#define dumpstate()
|
#define dumpstate()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void Double_BlockSHA256(const void* pin, void* pad, const void *pre, unsigned int thash[9][NPAR], const void *init)
|
void Double_BlockSHA256(const void* pin, void* pad, const void *pre, unsigned int thash[9][NPAR], const void *init)
|
||||||
{
|
{
|
||||||
unsigned int* In = (unsigned int*)pin;
|
unsigned int* In = (unsigned int*)pin;
|
||||||
|
3
ui.cpp
3
ui.cpp
@ -1031,9 +1031,6 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
|
|||||||
string strStatus = strprintf(_(" %d connections %d blocks %d transactions"), vNodes.size(), nBestHeight, nTransactionCount);
|
string strStatus = strprintf(_(" %d connections %d blocks %d transactions"), vNodes.size(), nBestHeight, nTransactionCount);
|
||||||
m_statusBar->SetStatusText(strStatus, 2);
|
m_statusBar->SetStatusText(strStatus, 2);
|
||||||
|
|
||||||
if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60)
|
|
||||||
m_statusBar->SetStatusText(" ERROR: ThreadSocketHandler has stopped", 0);
|
|
||||||
|
|
||||||
// Update receiving address
|
// Update receiving address
|
||||||
string strDefaultAddress = PubKeyToAddress(vchDefaultKey);
|
string strDefaultAddress = PubKeyToAddress(vchDefaultKey);
|
||||||
if (m_textCtrlAddress->GetValue() != strDefaultAddress)
|
if (m_textCtrlAddress->GetValue() != strDefaultAddress)
|
||||||
|
4
ui.h
4
ui.h
@ -305,8 +305,8 @@ public:
|
|||||||
y += 46 + wxString(strMessage2).Freq('\n') * 14;
|
y += 46 + wxString(strMessage2).Freq('\n') * 14;
|
||||||
}
|
}
|
||||||
#ifndef __WXMSW__
|
#ifndef __WXMSW__
|
||||||
x *= 1.14;
|
x = x * 114 / 100;
|
||||||
y *= 1.14;
|
y = y * 114 / 100;
|
||||||
#endif
|
#endif
|
||||||
SetSize(x, y);
|
SetSize(x, y);
|
||||||
}
|
}
|
||||||
|
36
util.cpp
36
util.cpp
@ -79,7 +79,7 @@ instance_of_cinit;
|
|||||||
void RandAddSeed()
|
void RandAddSeed()
|
||||||
{
|
{
|
||||||
// Seed with CPU performance counter
|
// Seed with CPU performance counter
|
||||||
int64 nCounter = PerformanceCounter();
|
int64 nCounter = GetPerformanceCounter();
|
||||||
RAND_add(&nCounter, sizeof(nCounter), 1.5);
|
RAND_add(&nCounter, sizeof(nCounter), 1.5);
|
||||||
memset(&nCounter, 0, sizeof(nCounter));
|
memset(&nCounter, 0, sizeof(nCounter));
|
||||||
}
|
}
|
||||||
@ -499,23 +499,47 @@ void FormatException(char* pszMessage, std::exception* pex, const char* pszThrea
|
|||||||
|
|
||||||
void LogException(std::exception* pex, const char* pszThread)
|
void LogException(std::exception* pex, const char* pszThread)
|
||||||
{
|
{
|
||||||
char pszMessage[1000];
|
char pszMessage[10000];
|
||||||
FormatException(pszMessage, pex, pszThread);
|
FormatException(pszMessage, pex, pszThread);
|
||||||
printf("\n%s", pszMessage);
|
printf("\n%s", pszMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintException(std::exception* pex, const char* pszThread)
|
void PrintException(std::exception* pex, const char* pszThread)
|
||||||
{
|
{
|
||||||
char pszMessage[1000];
|
char pszMessage[10000];
|
||||||
FormatException(pszMessage, pex, pszThread);
|
FormatException(pszMessage, pex, pszThread);
|
||||||
printf("\n\n************************\n%s\n", pszMessage);
|
printf("\n\n************************\n%s\n", pszMessage);
|
||||||
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
|
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
|
||||||
|
strMiscWarning = pszMessage;
|
||||||
#ifdef GUI
|
#ifdef GUI
|
||||||
if (wxTheApp && !fDaemon)
|
if (wxTheApp && !fDaemon)
|
||||||
MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
|
MyMessageBox(pszMessage, "Bitcoin", wxOK | wxICON_ERROR);
|
||||||
#endif
|
#endif
|
||||||
throw;
|
throw;
|
||||||
//DebugBreak();
|
}
|
||||||
|
|
||||||
|
void ThreadOneMessageBox(string strMessage)
|
||||||
|
{
|
||||||
|
// Skip message boxes if one is already open
|
||||||
|
static bool fMessageBoxOpen;
|
||||||
|
if (fMessageBoxOpen)
|
||||||
|
return;
|
||||||
|
fMessageBoxOpen = true;
|
||||||
|
ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION);
|
||||||
|
fMessageBoxOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintExceptionContinue(std::exception* pex, const char* pszThread)
|
||||||
|
{
|
||||||
|
char pszMessage[10000];
|
||||||
|
FormatException(pszMessage, pex, pszThread);
|
||||||
|
printf("\n\n************************\n%s\n", pszMessage);
|
||||||
|
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
|
||||||
|
strMiscWarning = pszMessage;
|
||||||
|
#ifdef GUI
|
||||||
|
if (wxTheApp && !fDaemon)
|
||||||
|
boost::thread(bind(ThreadOneMessageBox, string(pszMessage)));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -749,7 +773,7 @@ void AddTimeData(unsigned int ip, int64 nTime)
|
|||||||
if (!fMatch && !fDone)
|
if (!fMatch && !fDone)
|
||||||
{
|
{
|
||||||
fDone = true;
|
fDone = true;
|
||||||
string strMessage = _("Warning: Check your system date and time, you may not be able to generate or receive the most recent blocks!");
|
string strMessage = _("Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly.");
|
||||||
strMiscWarning = strMessage;
|
strMiscWarning = strMessage;
|
||||||
printf("*** %s\n", strMessage.c_str());
|
printf("*** %s\n", strMessage.c_str());
|
||||||
boost::thread(bind(ThreadSafeMessageBox, strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION, (wxWindow*)NULL, -1, -1));
|
boost::thread(bind(ThreadSafeMessageBox, strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION, (wxWindow*)NULL, -1, -1));
|
||||||
|
40
util.h
40
util.h
@ -151,8 +151,9 @@ int OutputDebugStringF(const char* pszFormat, ...);
|
|||||||
int my_snprintf(char* buffer, size_t limit, const char* format, ...);
|
int my_snprintf(char* buffer, size_t limit, const char* format, ...);
|
||||||
string strprintf(const char* format, ...);
|
string strprintf(const char* format, ...);
|
||||||
bool error(const char* format, ...);
|
bool error(const char* format, ...);
|
||||||
void PrintException(std::exception* pex, const char* pszThread);
|
|
||||||
void LogException(std::exception* pex, const char* pszThread);
|
void LogException(std::exception* pex, const char* pszThread);
|
||||||
|
void PrintException(std::exception* pex, const char* pszThread);
|
||||||
|
void PrintExceptionContinue(std::exception* pex, const char* pszThread);
|
||||||
void ParseString(const string& str, char c, vector<string>& v);
|
void ParseString(const string& str, char c, vector<string>& v);
|
||||||
string FormatMoney(int64 n, bool fPlus=false);
|
string FormatMoney(int64 n, bool fPlus=false);
|
||||||
bool ParseMoney(const string& str, int64& nRet);
|
bool ParseMoney(const string& str, int64& nRet);
|
||||||
@ -305,19 +306,20 @@ inline int64 abs64(int64 n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
string HexStr(const T itbegin, const T itend, bool fSpaces=true)
|
string HexStr(const T itbegin, const T itend, bool fSpaces=false)
|
||||||
{
|
{
|
||||||
if (itbegin == itend)
|
if (itbegin == itend)
|
||||||
return "";
|
return "";
|
||||||
const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
|
const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
|
||||||
const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
|
const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
|
||||||
string str;
|
string str;
|
||||||
|
str.reserve((pend-pbegin) * (fSpaces ? 3 : 2));
|
||||||
for (const unsigned char* p = pbegin; p != pend; p++)
|
for (const unsigned char* p = pbegin; p != pend; p++)
|
||||||
str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);
|
str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline string HexStr(vector<unsigned char> vch, bool fSpaces=true)
|
inline string HexStr(const vector<unsigned char>& vch, bool fSpaces=false)
|
||||||
{
|
{
|
||||||
return HexStr(vch.begin(), vch.end(), fSpaces);
|
return HexStr(vch.begin(), vch.end(), fSpaces);
|
||||||
}
|
}
|
||||||
@ -330,23 +332,29 @@ string HexNumStr(const T itbegin, const T itend, bool f0x=true)
|
|||||||
const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
|
const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
|
||||||
const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
|
const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
|
||||||
string str = (f0x ? "0x" : "");
|
string str = (f0x ? "0x" : "");
|
||||||
|
str.reserve(str.size() + (pend-pbegin) * 2);
|
||||||
for (const unsigned char* p = pend-1; p >= pbegin; p--)
|
for (const unsigned char* p = pend-1; p >= pbegin; p--)
|
||||||
str += strprintf("%02X", *p);
|
str += strprintf("%02x", *p);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline string HexNumStr(const vector<unsigned char>& vch, bool f0x=true)
|
||||||
|
{
|
||||||
|
return HexNumStr(vch.begin(), vch.end(), f0x);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
|
void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
|
||||||
{
|
{
|
||||||
printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
|
printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PrintHex(vector<unsigned char> vch, const char* pszFormat="%s", bool fSpaces=true)
|
inline void PrintHex(const vector<unsigned char>& vch, const char* pszFormat="%s", bool fSpaces=true)
|
||||||
{
|
{
|
||||||
printf(pszFormat, HexStr(vch, fSpaces).c_str());
|
printf(pszFormat, HexStr(vch, fSpaces).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int64 PerformanceCounter()
|
inline int64 GetPerformanceCounter()
|
||||||
{
|
{
|
||||||
int64 nCounter = 0;
|
int64 nCounter = 0;
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
@ -409,16 +417,16 @@ inline void heapchk()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Randomize the stack to help protect against buffer overrun exploits
|
// Randomize the stack to help protect against buffer overrun exploits
|
||||||
#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \
|
#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \
|
||||||
{ \
|
{ \
|
||||||
static char nLoops; \
|
static char nLoops; \
|
||||||
if (nLoops <= 0) \
|
if (nLoops <= 0) \
|
||||||
nLoops = GetRand(20) + 1; \
|
nLoops = GetRand(20) + 1; \
|
||||||
if (nLoops-- > 1) \
|
if (nLoops-- > 1) \
|
||||||
{ \
|
{ \
|
||||||
ThreadFn; \
|
ThreadFn; \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CATCH_PRINT_EXCEPTION(pszFn) \
|
#define CATCH_PRINT_EXCEPTION(pszFn) \
|
||||||
|
Loading…
Reference in New Issue
Block a user