set<pair<COutPoint, unsigned int> > setStakeSeenOrphan;
map<uint256, uint256> mapProofOfStake;
-map<uint256, CDataStream*> mapOrphanTransactions;
-map<uint256, map<uint256, CDataStream*> > mapOrphanTransactionsByPrev;
+map<uint256, CTransaction> mapOrphanTransactions;
+map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
// Constant stuff for coinbase transactions we create:
CScript COINBASE_FLAGS;
// Settings
int64 nTransactionFee = MIN_TX_FEE;
bool fStakeUsePooledKeys = false;
-
-// Used during database migration.
-bool fDisableSignatureChecking = false;
-
+extern enum Checkpoints::CPMode CheckpointsMode;
//////////////////////////////////////////////////////////////////////////////
//
// mapOrphanTransactions
//
-bool AddOrphanTx(const CDataStream& vMsg)
+bool AddOrphanTx(const CTransaction& tx)
{
- CTransaction tx;
- CDataStream(vMsg) >> tx;
uint256 hash = tx.GetHash();
if (mapOrphanTransactions.count(hash))
return false;
- CDataStream* pvMsg = new CDataStream(vMsg);
-
// Ignore big transactions, to avoid a
// send-big-orphans memory exhaustion attack. If a peer has a legitimate
// large transaction with a missing parent then we assume
// have been mined or received.
// 10,000 orphans, each of which is at most 5,000 bytes big is
// at most 500 megabytes of orphans:
- if (pvMsg->size() > 5000)
+
+ size_t nSize = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
+
+ if (nSize > 5000)
{
- printf("ignoring large orphan tx (size: %"PRIszu", hash: %s)\n", pvMsg->size(), hash.ToString().substr(0,10).c_str());
- delete pvMsg;
+ printf("ignoring large orphan tx (size: %"PRIszu", hash: %s)\n", nSize, hash.ToString().substr(0,10).c_str());
return false;
}
- mapOrphanTransactions[hash] = pvMsg;
+ mapOrphanTransactions[hash] = tx;
BOOST_FOREACH(const CTxIn& txin, tx.vin)
- mapOrphanTransactionsByPrev[txin.prevout.hash].insert(make_pair(hash, pvMsg));
+ mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
printf("stored orphan tx %s (mapsz %"PRIszu")\n", hash.ToString().substr(0,10).c_str(),
mapOrphanTransactions.size());
{
if (!mapOrphanTransactions.count(hash))
return;
- const CDataStream* pvMsg = mapOrphanTransactions[hash];
- CTransaction tx;
- CDataStream(*pvMsg) >> tx;
+ const CTransaction& tx = mapOrphanTransactions[hash];
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
mapOrphanTransactionsByPrev[txin.prevout.hash].erase(hash);
if (mapOrphanTransactionsByPrev[txin.prevout.hash].empty())
mapOrphanTransactionsByPrev.erase(txin.prevout.hash);
}
- delete pvMsg;
mapOrphanTransactions.erase(hash);
}
{
// Evict a random orphan:
uint256 randomhash = GetRandHash();
- map<uint256, CDataStream*>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
+ map<uint256, CTransaction>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
if (it == mapOrphanTransactions.end())
it = mapOrphanTransactions.begin();
EraseOrphanTx(it->first);
if (!Checkpoints::CheckHardened(nHeight, hash))
return DoS(100, error("AcceptBlock() : rejected by hardened checkpoint lock-in at %d", nHeight));
+ bool cpSatisfies = Checkpoints::CheckSync(hash, pindexPrev);
+
// Check that the block satisfies synchronized checkpoint
- if (!GetBoolArg("-nosynccheckpoints", false) && !Checkpoints::CheckSync(hash, pindexPrev))
+ if (CheckpointsMode == Checkpoints::STRICT && !cpSatisfies)
return error("AcceptBlock() : rejected by synchronized checkpoint");
+ if (CheckpointsMode == Checkpoints::ADVISORY && !cpSatisfies)
+ strMiscWarning = _("WARNING: syncronized checkpoint violation detected, but skipped!");
+
// Enforce rule that the coinbase starts with serialized block height
CScript expect = CScript() << nHeight;
- if (!std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin()))
+ if (vtx[0].vin[0].scriptSig.size() < expect.size() ||
+ !std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin()))
return DoS(100, error("AcceptBlock() : block height mismatch in coinbase"));
// Write block to history file
if ((!fTestNet) && !Checkpoints::ResetSyncCheckpoint())
return error("LoadBlockIndex() : failed to reset sync-checkpoint");
}
+#ifndef USE_LEVELDB
txdb.Close();
+#endif
+
}
return true;
}
}
-bool LoadExternalBlockFile(FILE* fileIn, ExternalBlockFileProgress *progress)
+bool LoadExternalBlockFile(FILE* fileIn)
{
int64 nStart = GetTimeMillis();
nPos += 4 + nSize;
}
}
- if (progress != NULL)
- (*progress)(4 + nSize);
}
}
catch (std::exception &e) {
// * Should not enter safe mode for longer invalid chain
// * If sync-checkpoint is too old do not enter safe mode
- // * Do not display warning if -nosynccheckpoints specified
- if (!GetBoolArg("-nosynccheckpoints", false) && Checkpoints::IsSyncCheckpointTooOld(60 * 60 * 24 * 10) && !fTestNet && !IsInitialBlockDownload())
+ // * Display warning only in the STRICT mode
+ if (CheckpointsMode == Checkpoints::STRICT && Checkpoints::IsSyncCheckpointTooOld(60 * 60 * 24 * 10) &&
+ !fTestNet && !IsInitialBlockDownload())
{
nPriority = 100;
- strStatusBar = "WARNING: Checkpoint is too old. Wait for block chain to download, or notify developers.";
+ strStatusBar = _("WARNING: Checkpoint is too old. Wait for block chain to download, or notify developers.");
}
// ppcoin: if detected invalid checkpoint enter safe mode
if (Checkpoints::hashInvalidCheckpoint != 0)
{
nPriority = 3000;
- strStatusBar = strRPC = "WARNING: Invalid checkpoint found! Displayed transactions may not be correct! You may need to upgrade, or notify developers.";
+ strStatusBar = strRPC = _("WARNING: Invalid checkpoint found! Displayed transactions may not be correct! You may need to upgrade, or notify developers.");
}
// Alerts
return true;
}
-
-
-
-
if (strCommand == "version")
{
// Each connection can only send one version message
return true;
}
- // ppcoin: record my external IP reported by peer
+ // record my external IP reported by peer
if (addrFrom.IsRoutable() && addrMe.IsRoutable())
addrSeenByPeer = addrMe;
item.second.RelayTo(pfrom);
}
- // ppcoin: relay sync-checkpoint
+ // Relay sync-checkpoint
{
LOCK(Checkpoints::cs_hashSyncCheckpoint);
if (!Checkpoints::checkpointMessage.IsNull())
pfrom->fDisconnect = true;
}
-
else if (strCommand == "inv")
{
vector<CInv> vInv;
CInv inv(MSG_TX, tx.GetHash());
pfrom->AddInventoryKnown(inv);
- // Truncate messages to the size of the tx in them
- unsigned int nSize = ::GetSerializeSize(tx,SER_NETWORK, PROTOCOL_VERSION);
- if (nSize < vMsg.size()){
- vMsg.resize(nSize);
- }
-
bool fMissingInputs = false;
if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs))
{
SyncWithWallets(tx, NULL, true);
- RelayMessage(inv, vMsg);
+ RelayTransaction(tx, inv.hash);
mapAlreadyAskedFor.erase(inv);
vWorkQueue.push_back(inv.hash);
vEraseQueue.push_back(inv.hash);
for (unsigned int i = 0; i < vWorkQueue.size(); i++)
{
uint256 hashPrev = vWorkQueue[i];
- for (map<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev[hashPrev].begin();
+ for (set<uint256>::iterator mi = mapOrphanTransactionsByPrev[hashPrev].begin();
mi != mapOrphanTransactionsByPrev[hashPrev].end();
++mi)
{
- const CDataStream& vMsg = *((*mi).second);
- CTransaction tx;
- CDataStream(vMsg) >> tx;
- CInv inv(MSG_TX, tx.GetHash());
+ const uint256& orphanTxHash = *mi;
+ CTransaction& orphanTx = mapOrphanTransactions[orphanTxHash];
bool fMissingInputs2 = false;
- if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs2))
+ if (orphanTx.AcceptToMemoryPool(txdb, true, &fMissingInputs2))
{
- printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
+ printf(" accepted orphan tx %s\n", orphanTxHash.ToString().substr(0,10).c_str());
SyncWithWallets(tx, NULL, true);
- RelayMessage(inv, vMsg);
- mapAlreadyAskedFor.erase(inv);
- vWorkQueue.push_back(inv.hash);
- vEraseQueue.push_back(inv.hash);
+ RelayTransaction(orphanTx, orphanTxHash);
+ mapAlreadyAskedFor.erase(CInv(MSG_TX, orphanTxHash));
+ vWorkQueue.push_back(orphanTxHash);
+ vEraseQueue.push_back(orphanTxHash);
}
else if (!fMissingInputs2)
{
// invalid orphan
- vEraseQueue.push_back(inv.hash);
- printf(" removed invalid orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
+ vEraseQueue.push_back(orphanTxHash);
+ printf(" removed invalid orphan tx %s\n", orphanTxHash.ToString().substr(0,10).c_str());
}
}
}
}
else if (fMissingInputs)
{
- AddOrphanTx(vMsg);
+ AddOrphanTx(tx);
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded
unsigned int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS);