aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp104
1 files changed, 41 insertions, 63 deletions
diff --git a/src/main.cpp b/src/main.cpp
index f3ce43660..d35891440 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -99,9 +99,16 @@ void UnregisterWallet(CWallet* pwalletIn)
}
}
+void UnregisterAllWallets()
+{
+ LOCK(cs_setpwalletRegistered);
+ setpwalletRegistered.clear();
+}
+
// get the wallet transaction with the given hash (if it exists)
bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx)
{
+ LOCK(cs_setpwalletRegistered);
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
if (pwallet->GetTransaction(hashTx,wtx))
return true;
@@ -111,6 +118,7 @@ bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx)
// erases transaction with the given hash from all wallets
void static EraseFromWallets(uint256 hash)
{
+ LOCK(cs_setpwalletRegistered);
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->EraseFromWallet(hash);
}
@@ -118,6 +126,7 @@ void static EraseFromWallets(uint256 hash)
// make sure all wallets know about the given transaction, in the given block
void SyncWithWallets(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate)
{
+ LOCK(cs_setpwalletRegistered);
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->AddToWalletIfInvolvingMe(hash, tx, pblock, fUpdate);
}
@@ -125,6 +134,7 @@ void SyncWithWallets(const uint256 &hash, const CTransaction& tx, const CBlock*
// notify wallets about a new best chain
void static SetBestChain(const CBlockLocator& loc)
{
+ LOCK(cs_setpwalletRegistered);
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->SetBestChain(loc);
}
@@ -132,6 +142,7 @@ void static SetBestChain(const CBlockLocator& loc)
// notify wallets about an updated transaction
void static UpdatedTransaction(const uint256& hashTx)
{
+ LOCK(cs_setpwalletRegistered);
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->UpdatedTransaction(hashTx);
}
@@ -139,6 +150,7 @@ void static UpdatedTransaction(const uint256& hashTx)
// dump all wallets
void static PrintWallets(const CBlock& block)
{
+ LOCK(cs_setpwalletRegistered);
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->PrintWallet(block);
}
@@ -146,6 +158,7 @@ void static PrintWallets(const CBlock& block)
// notify wallets about an incoming inventory (for request counts)
void static Inventory(const uint256& hash)
{
+ LOCK(cs_setpwalletRegistered);
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->Inventory(hash);
}
@@ -153,6 +166,7 @@ void static Inventory(const uint256& hash)
// ask wallets to resend their transactions
void static ResendWalletTransactions()
{
+ LOCK(cs_setpwalletRegistered);
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->ResendWalletTransactions();
}
@@ -457,38 +471,53 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
-bool IsStandardTx(const CTransaction& tx)
+bool IsStandardTx(const CTransaction& tx, string& reason)
{
- if (tx.nVersion > CTransaction::CURRENT_VERSION)
+ if (tx.nVersion > CTransaction::CURRENT_VERSION) {
+ reason = "version";
return false;
+ }
- if (!IsFinalTx(tx))
+ if (!IsFinalTx(tx)) {
+ reason = "non-final";
return false;
+ }
// Extremely large transactions with lots of inputs can cost the network
// almost as much to process as they cost the sender in fees, because
// computing signature hashes is O(ninputs*txsize). Limiting transactions
// to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks.
unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
- if (sz >= MAX_STANDARD_TX_SIZE)
+ if (sz >= MAX_STANDARD_TX_SIZE) {
+ reason = "tx-size";
return false;
+ }
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
// Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG
// pay-to-script-hash, which is 3 ~80-byte signatures, 3
// ~65-byte public keys, plus a few script ops.
- if (txin.scriptSig.size() > 500)
+ if (txin.scriptSig.size() > 500) {
+ reason = "scriptsig-size";
return false;
- if (!txin.scriptSig.IsPushOnly())
+ }
+ if (!txin.scriptSig.IsPushOnly()) {
+ reason = "scriptsig-not-pushonly";
return false;
+ }
}
BOOST_FOREACH(const CTxOut& txout, tx.vout) {
- if (!::IsStandard(txout.scriptPubKey))
+ if (!::IsStandard(txout.scriptPubKey)) {
+ reason = "scriptpubkey";
return false;
- if (txout.IsDust(CTransaction::nMinRelayTxFee))
+ }
+ if (txout.IsDust(CTransaction::nMinRelayTxFee)) {
+ reason = "dust";
return false;
+ }
}
+
return true;
}
@@ -782,8 +811,10 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fLimitFr
return error("CTxMemPool::accept() : not accepting nLockTime beyond 2038 yet");
// Rather not work on nonstandard transactions (unless -testnet)
- if (!TestNet() && !IsStandardTx(tx))
- return error("CTxMemPool::accept() : nonstandard transaction type");
+ string reason;
+ if (!TestNet() && !IsStandardTx(tx, reason))
+ return error("CTxMemPool::accept() : nonstandard transaction: %s",
+ reason.c_str());
// is it already in the memory pool?
uint256 hash = tx.GetHash();
@@ -4747,59 +4778,6 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet));
}
-// Amount compression:
-// * If the amount is 0, output 0
-// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9)
-// * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10)
-// * call the result n
-// * output 1 + 10*(9*n + d - 1) + e
-// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9
-// (this is decodable, as d is in [1-9] and e is in [0-9])
-
-uint64 CTxOutCompressor::CompressAmount(uint64 n)
-{
- if (n == 0)
- return 0;
- int e = 0;
- while (((n % 10) == 0) && e < 9) {
- n /= 10;
- e++;
- }
- if (e < 9) {
- int d = (n % 10);
- assert(d >= 1 && d <= 9);
- n /= 10;
- return 1 + (n*9 + d - 1)*10 + e;
- } else {
- return 1 + (n - 1)*10 + 9;
- }
-}
-
-uint64 CTxOutCompressor::DecompressAmount(uint64 x)
-{
- // x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9
- if (x == 0)
- return 0;
- x--;
- // x = 10*(9*n + d - 1) + e
- int e = x % 10;
- x /= 10;
- uint64 n = 0;
- if (e < 9) {
- // x = 9*n + d - 1
- int d = (x % 9) + 1;
- x /= 9;
- // x = n
- n = x*10 + d;
- } else {
- n = x+1;
- }
- while (e) {
- n *= 10;
- e--;
- }
- return n;
-}
class CMainCleanup