return true;
}
- bool AcceptPendingSyncCheckpoint(uint256 hashAcceptedBlock)
+ bool AcceptPendingSyncCheckpoint()
{
- if (!mapBlockIndex.count(hashAcceptedBlock))
- return false;
-
CRITICAL_BLOCK(cs_hashSyncCheckpoint)
- if ((!checkpointMessagePending.IsNull()) && checkpointMessagePending.hashCheckpoint == hashAcceptedBlock)
+ if ((!checkpointMessagePending.IsNull()) && mapBlockIndex.count(checkpointMessagePending.hashCheckpoint))
{
if (!ValidateSyncCheckpoint(checkpointMessagePending.hashCheckpoint))
{
checkpointMessagePending.SetNull();
return false;
}
+
+ CTxDB txdb;
+ if (!txdb.WriteSyncCheckpoint(checkpointMessagePending.hashCheckpoint))
+ return error("AcceptPendingSyncCheckpoint() : failed to write to db sync checkpoint %s\n", checkpointMessagePending.hashCheckpoint.ToString().c_str());
+ txdb.Close();
+
hashSyncCheckpoint = checkpointMessagePending.hashCheckpoint;
checkpointMessage = checkpointMessagePending;
checkpointMessagePending.SetNull();
return pindex->GetBlockHash();
}
+ // Check against synchronized checkpoint
+ bool CheckSync(int nHeight, const uint256& hashBlock)
+ {
+ if (fTestNet) return true; // Testnet has no checkpoints
+
+ CRITICAL_BLOCK(cs_hashSyncCheckpoint)
+ {
+ CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint];
+ if (nHeight == pindexSync->nHeight && hashBlock != hashSyncCheckpoint)
+ return false; // same height with sync-checkpoint
+ if (nHeight < pindexSync->nHeight && !mapBlockIndex.count(hashBlock))
+ return false; // lower height than sync-checkpoint
+ }
+ return true;
+ }
+
// ppcoin: automatic checkpoint (represented by height of checkpoint)
int nAutoCheckpoint = 0;
int nBranchPoint = 0; // branch point to alternative branch
}
if (!Checkpoints::ValidateSyncCheckpoint(hashCheckpoint))
return false;
+
+ CTxDB txdb;
+ if (!txdb.WriteSyncCheckpoint(this->hashCheckpoint))
+ return error("ProcessSyncCheckpoint() : failed to write to db sync checkpoint %s\n", this->hashCheckpoint.ToString().c_str());
+ txdb.Close();
+
Checkpoints::hashSyncCheckpoint = this->hashCheckpoint;
Checkpoints::checkpointMessage = *this;
Checkpoints::checkpointMessagePending.SetNull();
extern CSyncCheckpoint checkpointMessage;
extern CCriticalSection cs_hashSyncCheckpoint;
- bool AcceptPendingSyncCheckpoint(uint256 hashAcceptedBlock);
+ bool AcceptPendingSyncCheckpoint();
uint256 AutoSelectSyncCheckpoint();
+ bool CheckSync(int nHeight, const uint256& hashBlock);
// ppcoin: automatic checkpoint
extern int nAutoCheckpoint;
if (!Checkpoints::CheckAuto(pindexPrev))
return DoS(100, error("AcceptBlock() : rejected by automatic checkpoint at %d", Checkpoints::nAutoCheckpoint));
+ // ppcoin: check that the block satisfies synchronized checkpoint
+ if (!Checkpoints::CheckSync(nHeight, hash))
+ return DoS(100, error("AcceptBlock() : rejected by synchronized checkpoint"));
+
// Write block to history file
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
return error("AcceptBlock() : out of disk space");
pnode->PushInventory(CInv(MSG_BLOCK, hash));
// ppcoin: check pending sync-checkpoint
- Checkpoints::AcceptPendingSyncCheckpoint(hash);
+ Checkpoints::AcceptPendingSyncCheckpoint();
return true;
}