map<uint256, CBlockIndex*> mapBlockIndex;
set<pair<COutPoint, unsigned int> > setStakeSeen;
-uint256 hashGenesisBlock = hashGenesisBlockOfficial;
-static CBigNum bnProofOfWorkLimit(~uint256(0) >> 20);
-static CBigNum bnProofOfStakeLimit(~uint256(0) >> 24);
-static CBigNum bnProofOfStakeHardLimit(~uint256(0) >> 30);
-static CBigNum bnInitialHashTarget(~uint256(0) >> 20);
-unsigned int nStakeMinAge = 60 * 60 * 24 * 30; // minimum age for coin age
-unsigned int nStakeMaxAge = 60 * 60 * 24 * 90; // stake age of full weight
-unsigned int nStakeTargetSpacing = 10 * 60; // 10-minute block spacing
+
+CBigNum bnProofOfWorkLimit(~uint256(0) >> 20); // "standard" scrypt target limit for proof of work, results with 0,000244140625 proof-of-work difficulty
+CBigNum bnProofOfStakeLegacyLimit(~uint256(0) >> 24); // proof of stake target limit from block #15000 and until 20 June 2013, results with 0,00390625 proof of stake difficulty
+CBigNum bnProofOfStakeLimit(~uint256(0) >> 27); // proof of stake target limit since 20 June 2013, equal to 0.03125 proof of stake difficulty
+CBigNum bnProofOfStakeHardLimit(~uint256(0) >> 30); // disabled temporarily, will be used in the future to fix minimal proof of stake difficulty at 0.25
+
+CBigNum bnProofOfWorkLimitTestNet(~uint256(0) >> 16);
+
+unsigned int nStakeMinAge = 60 * 60 * 24 * 30; // 30 days as minimum age for coin age
+unsigned int nStakeMaxAge = 60 * 60 * 24 * 90; // 90 days as stake age of full weight
+unsigned int nStakeTargetSpacing = 10 * 60; // 10-minute stakes spacing
+unsigned int nModifierInterval = 6 * 60 * 60; // time to elapse before new modifier is computed
+
int nCoinbaseMaturity = 500;
CBlockIndex* pindexGenesisBlock = NULL;
int nBestHeight = -1;
const CTxOut& txout = vout[i];
if (txout.IsEmpty() && !IsCoinBase() && !IsCoinStake())
return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction"));
+
// ppcoin: enforce minimum output amount
if ((!txout.IsEmpty()) && txout.nValue < MIN_TXOUT_AMOUNT)
return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue below minimum"));
+
if (txout.nValue > MAX_MONEY)
return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue too high"));
nValueOut += txout.nValue;
unsigned int nNewBlockSize = nBlockSize + nBytes;
int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
- if (fAllowFree)
- {
- if (nBlockSize == 1)
- {
- // Transactions under 10K are free
- // (about 4500 BTC if made of 50 BTC inputs)
- if (nBytes < 10000)
- nMinFee = 0;
- }
- else
- {
- // Free transaction area
- if (nNewBlockSize < 27000)
- nMinFee = 0;
- }
- }
-
// To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01
if (nMinFee < nBaseFee)
{
return pblockOrphan->hashPrevBlock;
}
+// select stake target limit according to hard-coded conditions
+CBigNum static GetProofOfStakeLimit(int nHeight, unsigned int nTime)
+{
+ if(fTestNet) // separate proof of stake target limit for testnet
+ return bnProofOfStakeLimit;
+ if(nTime > TARGETS_SWITCH_TIME) // 27 bits since 20 July 2013
+ return bnProofOfStakeLimit;
+ if(nHeight + 1 > 15000) // 24 bits since block 15000
+ return bnProofOfStakeLegacyLimit;
+ if(nHeight + 1 > 14060) // 31 bits since block 14060 until 15000
+ return bnProofOfStakeHardLimit;
+
+ return bnProofOfWorkLimit; // return bnProofOfWorkLimit of none matched
+}
+
+// miner's coin base reward based on nBits
int64 GetProofOfWorkReward(unsigned int nBits)
{
CBigNum bnSubsidyLimit = MAX_MINT_PROOF_OF_WORK;
+
CBigNum bnTarget;
bnTarget.SetCompact(nBits);
CBigNum bnTargetLimit = bnProofOfWorkLimit;
bnTargetLimit.SetCompact(bnTargetLimit.GetCompact());
- // ppcoin: subsidy is cut in half every 64x multiply of difficulty
+ // NovaCoin: subsidy is cut in half every 64x multiply of PoW difficulty
// A reasonably continuous curve is used to avoid shock to market
// (nSubsidyLimit / nSubsidy) ** 6 == bnProofOfWorkLimit / bnTarget
//
return min(nSubsidy, MAX_MINT_PROOF_OF_WORK);
}
-// ppcoin: miner's coin stake is rewarded based on coin age spent (coin-days)
-int64 GetProofOfStakeReward(int64 nCoinAge)
+// miner's coin stake reward based on nBits and coin age spent (coin-days)
+int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime)
{
- static int64 nRewardCoinYear = 5 * CENT; // creation amount per coin-year
+ int64 nRewardCoinYear;
+
+ if(fTestNet || nTime > STAKE_SWITCH_TIME)
+ {
+ // Stage 2 of emission process is PoS-based. It will be active on mainNet since 20 Jun 2013.
+
+ CBigNum bnRewardCoinYearLimit = MAX_MINT_PROOF_OF_STAKE; // Base stake mint rate, 100% year interest
+ CBigNum bnTarget;
+ bnTarget.SetCompact(nBits);
+ CBigNum bnTargetLimit = GetProofOfStakeLimit(0, nTime);
+ bnTargetLimit.SetCompact(bnTargetLimit.GetCompact());
+
+ // NovaCoin: reward for coin-year is cut in half every 64x multiply of PoS difficulty
+ // A reasonably continuous curve is used to avoid shock to market
+ // (nRewardCoinYearLimit / nRewardCoinYear) ** 6 == bnProofOfStakeLimit / bnTarget
+ //
+ // Human readable form:
+ //
+ // nRewardCoinYear = 1 / (posdiff ^ 1/6)
+
+ CBigNum bnLowerBound = 1 * CENT; // Lower interest bound is 1% per year
+ CBigNum bnUpperBound = bnRewardCoinYearLimit;
+ while (bnLowerBound + CENT <= bnUpperBound)
+ {
+ CBigNum bnMidValue = (bnLowerBound + bnUpperBound) / 2;
+ if (fDebug && GetBoolArg("-printcreation"))
+ printf("GetProofOfStakeReward() : lower=%"PRI64d" upper=%"PRI64d" mid=%"PRI64d"\n", bnLowerBound.getuint64(), bnUpperBound.getuint64(), bnMidValue.getuint64());
+ if (bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnTargetLimit > bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnTarget)
+ bnUpperBound = bnMidValue;
+ else
+ bnLowerBound = bnMidValue;
+ }
+
+ nRewardCoinYear = bnUpperBound.getuint64();
+ nRewardCoinYear = min((nRewardCoinYear / CENT) * CENT, MAX_MINT_PROOF_OF_STAKE);
+ }
+ else
+ {
+ // Old creation amount per coin-year, 5% fixed stake mint rate
+ nRewardCoinYear = 5 * CENT;
+ }
+
int64 nSubsidy = nCoinAge * 33 / (365 * 33 + 8) * nRewardCoinYear;
if (fDebug && GetBoolArg("-printcreation"))
- printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d"\n", FormatMoney(nSubsidy).c_str(), nCoinAge);
+ printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d" nBits=%d\n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBits);
return nSubsidy;
}
static const int64 nTargetTimespan = 7 * 24 * 60 * 60; // one week
-static const int64 nTargetSpacingWorkMax = 12 * nStakeTargetSpacing; // 2-hour
+
+// get proof of work blocks max spacing according to hard-coded conditions
+int64 static GetTargetSpacingWorkMax(int nHeight, unsigned int nTime)
+{
+ if(nTime > TARGETS_SWITCH_TIME)
+ return 3 * nStakeTargetSpacing; // 30 minutes on mainNet since 20 Jul 2013 00:00:00
+
+ if(fTestNet)
+ return 3 * nStakeTargetSpacing; // 15 minutes on testNet
+
+ return 12 * nStakeTargetSpacing; // 2 hours otherwise
+}
//
// minimum amount of work that could possibly be required nTime after
return pindex;
}
-unsigned int static GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake)
+unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake)
{
- CBigNum bnTargetLimit = bnProofOfWorkLimit;
-
- if(fProofOfStake)
- {
- // Proof-of-Stake blocks has own target limit since nVersion=3 supermajority on mainNet and always on testNet
- if(fTestNet)
- bnTargetLimit = bnProofOfStakeHardLimit;
- else
- {
- if(fTestNet || (pindexLast->nHeight + 1 > 15000))
- bnTargetLimit = bnProofOfStakeLimit;
- else if(pindexLast->nHeight + 1 > 14060)
- bnTargetLimit = bnProofOfStakeHardLimit;
- }
- }
+ CBigNum bnTargetLimit = !fProofOfStake ? bnProofOfWorkLimit : GetProofOfStakeLimit(pindexLast->nHeight, pindexLast->nTime);
if (pindexLast == NULL)
return bnTargetLimit.GetCompact(); // genesis block
const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake);
if (pindexPrev->pprev == NULL)
- return bnInitialHashTarget.GetCompact(); // first block
+ return bnTargetLimit.GetCompact(); // first block
const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake);
if (pindexPrevPrev->pprev == NULL)
- return bnInitialHashTarget.GetCompact(); // second block
+ return bnTargetLimit.GetCompact(); // second block
int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime();
// ppcoin: retarget with exponential moving toward target spacing
CBigNum bnNew;
bnNew.SetCompact(pindexPrev->nBits);
- int64 nTargetSpacing = fProofOfStake? nStakeTargetSpacing : min(nTargetSpacingWorkMax, (int64) nStakeTargetSpacing * (1 + pindexLast->nHeight - pindexPrev->nHeight));
+ int64 nTargetSpacing = fProofOfStake? nStakeTargetSpacing : min(GetTargetSpacingWorkMax(pindexLast->nHeight, pindexLast->nTime), (int64) nStakeTargetSpacing * (1 + pindexLast->nHeight - pindexPrev->nHeight));
int64 nInterval = nTargetTimespan / nTargetSpacing;
bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing);
bnNew /= ((nInterval + 1) * nTargetSpacing);
uiInterface.NotifyBlocksChanged();
}
- printf("InvalidChainFound: invalid block=%s height=%d trust=%s date=%s\n",
+ CBigNum bnBestInvalidBlockTrust = pindexNew->bnChainTrust - pindexNew->pprev->bnChainTrust;
+ CBigNum bnBestBlockTrust = pindexBest->nHeight != 0 ? (pindexBest->bnChainTrust - pindexBest->pprev->bnChainTrust) : pindexBest->bnChainTrust;
+
+ printf("InvalidChainFound: invalid block=%s height=%d trust=%s blocktrust=%s date=%s\n",
pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight,
- pindexNew->bnChainTrust.ToString().c_str(), DateTimeStrFormat("%x %H:%M:%S",
- pindexNew->GetBlockTime()).c_str());
- printf("InvalidChainFound: current best=%s height=%d trust=%s date=%s\n",
- hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainTrust.ToString().c_str(),
+ pindexNew->bnChainTrust.ToString().c_str(), bnBestInvalidBlockTrust.ToString().c_str(),
+ DateTimeStrFormat("%x %H:%M:%S", pindexNew->GetBlockTime()).c_str());
+ printf("InvalidChainFound: current best=%s height=%d trust=%s blocktrust=%s date=%s\n",
+ hashBestChain.ToString().substr(0,20).c_str(), nBestHeight,
+ bnBestChainTrust.ToString().c_str(),
+ bnBestBlockTrust.ToString().c_str(),
DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str());
}
+
void CBlock::UpdateTime(const CBlockIndex* pindexPrev)
{
nTime = max(GetBlockTime(), GetAdjustedTime());
if (!GetCoinAge(txdb, nCoinAge))
return error("ConnectInputs() : %s unable to get coin age for coinstake", GetHash().ToString().substr(0,10).c_str());
int64 nStakeReward = GetValueOut() - nValueIn;
- if (nStakeReward > GetProofOfStakeReward(nCoinAge) - GetMinFee() + MIN_TX_FEE)
+ if (nStakeReward > GetProofOfStakeReward(nCoinAge, pindexBlock->nBits, nTime) - GetMinFee() + MIN_TX_FEE)
return DoS(100, error("ConnectInputs() : %s stake reward exceeded", GetHash().ToString().substr(0,10).c_str()));
}
else
if (!txdb.TxnBegin())
return error("SetBestChain() : TxnBegin failed");
- if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
+ if (pindexGenesisBlock == NULL && hash == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet))
{
txdb.WriteHashBestChain(hash);
if (!txdb.TxnCommit())
bnBestChainTrust = pindexNew->bnChainTrust;
nTimeBestReceived = GetTime();
nTransactionsUpdated++;
- printf("SetBestChain: new best=%s height=%d trust=%s date=%s\n",
+
+ CBigNum bnBestBlockTrust = pindexBest->nHeight != 0 ? (pindexBest->bnChainTrust - pindexBest->pprev->bnChainTrust) : pindexBest->bnChainTrust;
+
+ printf("SetBestChain: new best=%s height=%d trust=%s blocktrust=%s date=%s\n",
hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainTrust.ToString().c_str(),
+ bnBestBlockTrust.ToString().c_str(),
DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str());
// Check the version of the last 100 blocks to see if we need to upgrade:
if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
return DoS(100, error("CheckBlock() : size limits failed"));
+ // Special short-term limits to avoid 10,000 BDB lock limit:
+ if (GetBlockTime() < LOCKS_SWITCH_TIME)
+ {
+ // Rule is: #unique txids referenced <= 4,500
+ // ... to prevent 10,000 BDB lock exhaustion on old clients
+ set<uint256> setTxIn;
+ for (size_t i = 0; i < vtx.size(); i++)
+ {
+ setTxIn.insert(vtx[i].GetHash());
+ if (i == 0) continue; // skip coinbase txin
+ BOOST_FOREACH(const CTxIn& txin, vtx[i].vin)
+ setTxIn.insert(txin.prevout.hash);
+ }
+ size_t nTxids = setTxIn.size();
+ if (nTxids > 4500)
+ return error("CheckBlock() : maxlocks violation");
+ }
+
// Check proof of work matches claimed amount
if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHash(), nBits))
return DoS(50, error("CheckBlock() : proof of work failed"));
if (fCheckMerkleRoot && hashMerkleRoot != BuildMerkleTree())
return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"));
- // ppcoin: check block signature
- if (!CheckBlockSignature())
- return DoS(100, error("CheckBlock() : bad block signature"));
+ // NovaCoin: check proof-of-stake block signature
+ if (IsProofOfStake() || (!fTestNet && GetBlockTime() < CHAINCHECKS_SWITCH_TIME))
+ {
+ if (!CheckBlockSignature())
+ return DoS(100, error("CheckBlock() : bad block signature"));
+ }
return true;
}
// ppcoin: check that the block satisfies synchronized checkpoint
if (!Checkpoints::CheckSync(hash, pindexPrev))
- return error("AcceptBlock() : rejected by synchronized checkpoint");
+ {
+ if(!GetBoolArg("-nosynccheckpoints", false))
+ {
+ return error("AcceptBlock() : rejected by synchronized checkpoint");
+ }
+ else
+ {
+ strMiscWarning = _("WARNING: syncronized checkpoint violation detected, but skipped!");
+ }
+ }
// Reject block.nVersion < 3 blocks since 95% threshold on mainNet and always on testNet:
if (nVersion < 3 && ((!fTestNet && nHeight > 14060) || (fTestNet && nHeight > 0)))
return true;
}
+CBigNum CBlockIndex::GetBlockTrust() const
+{
+ CBigNum bnTarget;
+
+ // Old protocol
+ if (!fTestNet && GetBlockTime() < CHAINCHECKS_SWITCH_TIME)
+ {
+ CBigNum bnTarget;
+ bnTarget.SetCompact(nBits);
+
+ if (bnTarget <= 0)
+ return 0;
+ return (IsProofOfStake()? (CBigNum(1)<<256) / (bnTarget+1) : 1);
+ }
+
+ // New protocol
+ if (pprev == NULL || pprev->nHeight < 10)
+ return 1;
+
+ const CBlockIndex* currentIndex = pprev;
+
+ if(IsProofOfStake())
+ {
+ bnTarget.SetCompact(nBits);
+ if (bnTarget <= 0)
+ return 0;
+
+ if (!pprev->IsProofOfWork())
+ return (CBigNum(1)<<256) / (3 * (bnTarget+1));
+
+ int nPoWCount = 0;
+
+ // Check last 12 blocks type
+ while (pprev->nHeight - currentIndex->nHeight < 12)
+ {
+ if (currentIndex->IsProofOfWork())
+ nPoWCount++;
+ currentIndex = currentIndex->pprev;
+ }
+
+ // Return 1/3 of score if less than 3 PoW blocks found
+ if (nPoWCount < 3)
+ return (CBigNum(1)<<256) / (3 * (bnTarget+1));
+
+ return (CBigNum(1)<<256) / (bnTarget+1);
+ }
+ else
+ {
+ if (!(pprev->IsProofOfStake() && pprev->pprev->IsProofOfStake()))
+ return 1 + (2 * (pprev->bnChainTrust - pprev->pprev->bnChainTrust) / 3);
+
+ int nPoSCount = 0;
+
+ // Check last 12 blocks type
+ while (pprev->nHeight - currentIndex->nHeight < 12)
+ {
+ if (currentIndex->IsProofOfStake())
+ nPoSCount++;
+ currentIndex = currentIndex->pprev;
+ }
+
+ // Return 2/3 of previous block score if less than 7 PoS blocks found
+ if (nPoSCount < 7)
+ return 1 + (2 * (pprev->bnChainTrust - pprev->pprev->bnChainTrust) / 3);
+
+ return (pprev->bnChainTrust - pprev->pprev->bnChainTrust);
+ }
+}
+
bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired, unsigned int nToCheck)
{
unsigned int nFound = 0;
// ppcoin: check block signature
bool CBlock::CheckBlockSignature() const
{
- if (GetHash() == hashGenesisBlock)
+ if (GetHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet))
return vchBlockSig.empty();
vector<valtype> vSolutions;
pchMessageStart[2] = 0xc0;
pchMessageStart[3] = 0xef;
-
- hashGenesisBlock = hashGenesisBlockTestNet;
- nStakeMinAge = 60 * 60 * 24; // test net min age is 1 day
- nCoinbaseMaturity = 60;
+ bnProofOfWorkLimit = bnProofOfWorkLimitTestNet; // 16 bits PoW target limit for testnet
+ nStakeMinAge = 2 * 60 * 60; // test net min age is 2 hours
+ nModifierInterval = 20 * 60; // test modifier interval is 20 minutes
+ nCoinbaseMaturity = 10; // test maturity is 10 blocks
+ nStakeTargetSpacing = 5 * 60; // test block spacing is 5 minutes
}
//
if (!fAllowNew)
return false;
- // Genesis Block:
- // CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
- // CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
- // CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
- // CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
- // vMerkleTree: 4a5e1e
-
// Genesis block
+
+ // MainNet:
+
+ //CBlock(hash=00000a060336cbb72fe969666d337b87198b1add2abaa59cca226820b32933a4, ver=1, hashPrevBlock=0000000000000000000000000000000000000000000000000000000000000000, hashMerkleRoot=4cb33b3b6a861dcbc685d3e614a9cafb945738d6833f182855679f2fad02057b, nTime=1360105017, nBits=1e0fffff, nNonce=1575379, vtx=1, vchBlockSig=)
+ // Coinbase(hash=4cb33b3b6a, nTime=1360105017, ver=1, vin.size=1, vout.size=1, nLockTime=0)
+ // CTxIn(COutPoint(0000000000, 4294967295), coinbase 04ffff001d020f274468747470733a2f2f626974636f696e74616c6b2e6f72672f696e6465782e7068703f746f7069633d3133343137392e6d736731353032313936236d736731353032313936)
+ // CTxOut(empty)
+ // vMerkleTree: 4cb33b3b6a
+
+ // TestNet:
+
+ //CBlock(hash=0000c763e402f2436da9ed36c7286f62c3f6e5dbafce9ff289bd43d7459327eb, ver=1, hashPrevBlock=0000000000000000000000000000000000000000000000000000000000000000, hashMerkleRoot=4cb33b3b6a861dcbc685d3e614a9cafb945738d6833f182855679f2fad02057b, nTime=1360105017, nBits=1f00ffff, nNonce=46534, vtx=1, vchBlockSig=)
+ // Coinbase(hash=4cb33b3b6a, nTime=1360105017, ver=1, vin.size=1, vout.size=1, nLockTime=0)
+ // CTxIn(COutPoint(0000000000, 4294967295), coinbase 04ffff001d020f274468747470733a2f2f626974636f696e74616c6b2e6f72672f696e6465782e7068703f746f7069633d3133343137392e6d736731353032313936236d736731353032313936)
+ // CTxOut(empty)
+ // vMerkleTree: 4cb33b3b6a
+
const char* pszTimestamp = "https://bitcointalk.org/index.php?topic=134179.msg1502196#msg1502196";
CTransaction txNew;
txNew.nTime = 1360105017;
block.nVersion = 1;
block.nTime = 1360105017;
block.nBits = bnProofOfWorkLimit.GetCompact();
- block.nNonce = 1575379;
+ block.nNonce = !fTestNet ? 1575379 : 46534;
//// debug print
assert(block.hashMerkleRoot == uint256("0x4cb33b3b6a861dcbc685d3e614a9cafb945738d6833f182855679f2fad02057b"));
block.print();
- assert(block.GetHash() == hashGenesisBlock);
+ assert(block.GetHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet));
assert(block.CheckBlock());
// Start new block file
return error("LoadBlockIndex() : genesis block not accepted");
// ppcoin: initialize synchronized checkpoint
- if (!Checkpoints::WriteSyncCheckpoint(hashGenesisBlock))
+ if (!Checkpoints::WriteSyncCheckpoint((!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)))
return error("LoadBlockIndex() : failed to init sync checkpoint");
}
if (GetBoolArg("-testsafemode"))
strRPC = "test";
-/*
+
// ppcoin: wallet lock warning for minting
if (strMintWarning != "")
{
nPriority = 0;
strStatusBar = strMintWarning;
}
-*/
// Misc warnings like out of disk space and clock is wrong
if (strMiscWarning != "")
// Add our coinbase tx as first transaction
pblock->vtx.push_back(txNew);
-
-
// Largest block you're willing to create:
unsigned int nBlockMaxSize = GetArg("-blockmaxsize", MAX_BLOCK_SIZE_GEN/2);
// Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity:
nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize));
+ // Special compatibility rule before 20 Aug: limit size to 500,000 bytes:
+ if (GetAdjustedTime() < LOCKS_SWITCH_TIME)
+ nBlockMaxSize = std::min(nBlockMaxSize, (unsigned int)(MAX_BLOCK_SIZE_GEN));
+
// How much of the block should be dedicated to high-priority transactions,
// included regardless of the fees they pay
unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", 27000);
static int64 nLastCoinStakeSearchTime = GetAdjustedTime(); // only initialized at startup
CBlockIndex* pindexPrev = pindexBest;
- if (fProofOfStake) // attemp to find a coinstake
+ if (fProofOfStake) // attempt to find a coinstake
{
pblock->nBits = GetNextTargetRequired(pindexPrev, true);
CTransaction txCoinStake;
nLastBlockTx = nBlockTx;
nLastBlockSize = nBlockSize;
- printf("CreateNewBlock(): total size %"PRI64u"\n", nBlockSize);
+
+ if (fDebug && GetBoolArg("-printpriority"))
+ printf("CreateNewBlock(): total size %"PRI64u"\n", nBlockSize);
if (pblock->IsProofOfWork())
pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pblock->nBits);