return false;
}
-// erases transaction with the given hash from all wallets
-void static EraseFromWallets(uint256 hash)
-{
- for(CWallet* pwallet : setpwalletRegistered)
- pwallet->EraseFromWallet(hash);
-}
-
// make sure all wallets know about the given transaction, in the given block
void SyncWithWallets(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fConnect)
{
return false;
// Check for conflicts with in-memory transactions
- CTransaction* ptxOld = NULL;
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
auto outpoint = tx.vin[i].prevout;
if (mapNextTx.count(outpoint))
{
- // Disable replacement feature for now
+ // Replacement feature isn't supported by Novacoin.
return false;
-
- // Allow replacing with a newer version of the same transaction
- if (i != 0)
- return false;
- ptxOld = mapNextTx[outpoint].ptx;
- if (ptxOld->IsFinal())
- return false;
- if (!tx.IsNewerThan(*ptxOld))
- return false;
- for (unsigned int i = 0; i < tx.vin.size(); i++)
- {
- auto outpoint = tx.vin[i].prevout;
- if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld)
- return false;
- }
- break;
}
}
// Store transaction in memory
{
LOCK(cs);
- if (ptxOld)
- {
- printf("CTxMemPool::accept() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
- remove(*ptxOld);
- }
addUnchecked(hash, tx);
}
- ///// are we sure this is ok when loading transactions or restoring block txes
- // If updated, erase old tx from wallet
- if (ptxOld)
- EraseFromWallets(ptxOld->GetHash());
-
printf("CTxMemPool::accept() : accepted %s (poolsz %" PRIszu ")\n",
hash.ToString().substr(0,10).c_str(),
mapTx.size());
bool cpSatisfies = Checkpoints::CheckSync(hash, pindexPrev);
// Check that the block satisfies synchronized checkpoint
- if (CheckpointsMode == Checkpoints::STRICT && !cpSatisfies)
+ if (CheckpointsMode == Checkpoints::CP_STRICT && !cpSatisfies)
return error("AcceptBlock() : rejected by synchronized checkpoint");
- if (CheckpointsMode == Checkpoints::ADVISORY && !cpSatisfies)
+ if (CheckpointsMode == Checkpoints::CP_ADVISORY && !cpSatisfies)
strMiscWarning = _("WARNING: syncronized checkpoint violation detected, but skipped!");
// Enforce rule that the coinbase starts with serialized block height
{
if (fTestNet)
{
- pchMessageStart[0] = 0xcd;
- pchMessageStart[1] = 0xf2;
- pchMessageStart[2] = 0xc0;
- pchMessageStart[3] = 0xef;
+ nNetworkID = 0xefc0f2cd;
bnProofOfWorkLimit = bnProofOfWorkLimitTestNet; // 16 bits PoW target limit for testnet
nStakeMinAge = 2 * nOneHour; // test net min age is 2 hours
auto nBlockLength = *reinterpret_cast<const uint32_t*>(&(*(it+4)));
auto SeekToNext = [&pchData, &it, &nPos, &nBlockLength]() {
auto previt = it;
- it = search(it+8, pchData.end(), BEGIN(pchMessageStart), END(pchMessageStart));
+ it = search(it+8, pchData.end(), BEGIN(nNetworkID), END(nNetworkID));
if (it != pchData.end())
nPos += (it - previt);
};
if (nBlockLength > 0)
{
- if (nBlockLength > distance(it, pchData.end()))
+ if (nBlockLength > (uint32_t)distance(it, pchData.end()))
{
SeekToNext();
break; // We've reached the end of buffer
}
catch (const std::exception&)
{
- printf("LoadExternalBlockFile() : Deserialize error caught at the position %" PRId64 ", this block may be truncated.", nPos);
+ printf("LoadExternalBlockFile() : Deserialize error caught at the position %" PRIu32 ", this block may be truncated.", nPos);
SeekToNext();
break;
}
bool static AlreadyHave(CTxDB& txdb, const CInv& inv)
{
- switch (inv.type)
+ int nType = inv.GetType();
+ auto nHash = inv.GetHash();
+
+ switch (nType)
{
case MSG_TX:
{
bool txInMap = false;
{
LOCK(mempool.cs);
- txInMap = (mempool.exists(inv.hash));
+ txInMap = (mempool.exists(nHash));
}
return txInMap ||
- mapOrphanTransactions.count(inv.hash) ||
- txdb.ContainsTx(inv.hash);
+ mapOrphanTransactions.count(nHash) ||
+ txdb.ContainsTx(nHash);
}
case MSG_BLOCK:
- return mapBlockIndex.count(inv.hash) ||
- mapOrphanBlocks.count(inv.hash);
+ return mapBlockIndex.count(nHash) ||
+ mapOrphanBlocks.count(nHash);
}
// Don't know what it is, just say we already got one
return true;
}
-
-
-
-// The message start string is designed to be unlikely to occur in normal data.
-// The characters are rarely used upper ASCII, not valid as UTF-8, and produce
-// a large 4-byte int at any alignment.
-uint8_t pchMessageStart[4] = { 0xe4, 0xe8, 0xe9, 0xe5 };
-
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{
static map<CService, CPubKey> mapReuseKey;
hashSalt = GetRandHash();
uint64_t hashAddr = addr.GetHash();
uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/nOneDay);
- hashRand = Hash(BEGIN(hashRand), END(hashRand));
+ hashRand = Hash(hashRand.begin(), hashRand.end());
multimap<uint256, CNode*> mapMix;
for(CNode* pnode : vNodes)
{
unsigned int nPointer;
memcpy(&nPointer, &pnode, sizeof(nPointer));
uint256 hashKey = hashRand ^ nPointer;
- hashKey = Hash(BEGIN(hashKey), END(hashKey));
+ hashKey = Hash(hashKey.begin(), hashKey.end());
mapMix.insert(make_pair(hashKey, pnode));
}
int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
}
// find last block in inv vector
- size_t nLastBlock = std::numeric_limits<size_t>::max();
+ int nLastBlock = -1;
for (size_t nInv = 0; nInv < vInv.size(); nInv++) {
- if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) {
- nLastBlock = vInv.size() - 1 - nInv;
+ if (vInv[vInv.size() - 1 - nInv].GetType() == MSG_BLOCK) {
+ nLastBlock = (int) (vInv.size() - 1 - nInv);
break;
}
}
for (size_t nInv = 0; nInv < vInv.size(); nInv++)
{
const CInv &inv = vInv[nInv];
+ int nType = inv.GetType();
+ auto nHash = inv.GetHash();
if (fShutdown)
return true;
if (!fAlreadyHave)
pfrom->AskFor(inv);
- else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) {
- pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
- } else if (nInv == nLastBlock) {
+ else if (nType == MSG_BLOCK && mapOrphanBlocks.count(nHash)) {
+ pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[nHash]));
+ } else if (nType == nLastBlock) {
// In case we are on a very long side-chain, it is possible that we already have
// the last block in an inv bundle sent in response to getblocks. Try to detect
// this situation and push another getblocks to continue.
- pfrom->PushGetBlocks(mapBlockIndex[inv.hash], uint256(0));
+ pfrom->PushGetBlocks(mapBlockIndex[nHash], uint256(0));
if (fDebug)
printf("force request: %s\n", inv.ToString().c_str());
}
// Track requests for our stuff
- Inventory(inv.hash);
+ Inventory(nHash);
}
}
if (fDebugNet || (vInv.size() == 1))
printf("received getdata for: %s\n", inv.ToString().c_str());
- if (inv.type == MSG_BLOCK)
+ int nType = inv.GetType();
+ auto nHash = inv.GetHash();
+
+ if (nType == MSG_BLOCK)
{
// Send block from disk
- auto mi = mapBlockIndex.find(inv.hash);
+ auto mi = mapBlockIndex.find(nHash);
if (mi != mapBlockIndex.end())
{
CBlock block;
pfrom->PushMessage("block", block);
// Trigger them to send a getblocks request for the next batch of inventory
- if (inv.hash == pfrom->hashContinue)
+ if (nHash == pfrom->hashContinue)
{
// ppcoin: send latest proof-of-work block to allow the
// download node to accept as orphan (proof-of-stake
pushed = true;
}
}
- if (!pushed && inv.type == MSG_TX) {
+ if (!pushed && nType == MSG_TX) {
LOCK(mempool.cs);
- if (mempool.exists(inv.hash)) {
- CTransaction tx = mempool.lookup(inv.hash);
+ if (mempool.exists(nHash)) {
+ CTransaction tx = mempool.lookup(nHash);
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000);
ss << tx;
}
// Track requests for our stuff
- Inventory(inv.hash);
+ Inventory(nHash);
}
}
bool fMissingInputs = false;
if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs))
{
+ auto nHash = inv.GetHash();
+
SyncWithWallets(tx, NULL, true);
- RelayTransaction(tx, inv.hash);
+ RelayTransaction(tx, nHash);
mapAlreadyAskedFor.erase(inv);
- vWorkQueue.push_back(inv.hash);
- vEraseQueue.push_back(inv.hash);
+ vWorkQueue.push_back(nHash);
+ vEraseQueue.push_back(nHash);
// Recursively process any orphan transactions that depended on this one
for (unsigned int i = 0; i < vWorkQueue.size(); i++)
break;
// Scan for message start
- CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart));
+ CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(nNetworkID), END(nNetworkID));
int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader());
if (vRecv.end() - pstart < nHeaderSize)
{
continue;
// trickle out tx inv to protect privacy
- if (inv.type == MSG_TX && !fSendTrickle)
+ if (inv.GetType() == MSG_TX && !fSendTrickle)
{
// 1/4 of tx invs blast to all immediately
static uint256 hashSalt;
if (hashSalt == 0)
hashSalt = GetRandHash();
- uint256 hashRand = inv.hash ^ hashSalt;
- hashRand = Hash(BEGIN(hashRand), END(hashRand));
+ uint256 hashRand = inv.GetHash() ^ hashSalt;
+ hashRand = Hash(hashRand.begin(), hashRand.end());
bool fTrickleWait = ((hashRand & 3) != 0);
if (fTrickleWait)