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 bnPoWBase = CBigNum(uint256("0x00000000ffff0000000000000000000000000000000000000000000000000000")); // difficulty-1 target
CBigNum bnProofOfWorkLimitTestNet(~uint256(0) >> 16);
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)
+ // NovaCoin: enforce minimum output amount for user transactions
+ // (and for all transactions until 20 Sep 2013)
+ if ((!IsCoinBase() || nTime < CHAINCHECKS_SWITCH_TIME)
+ && (!txout.IsEmpty()) && txout.nValue < MIN_TXOUT_AMOUNT)
return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue below minimum"));
if (txout.nValue > MAX_MONEY)
if (IsCoinBase())
{
if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100)
- return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size"));
+ return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size is invalid"));
}
else
{
}
int64 nSubsidy = bnUpperBound.getuint64();
+
nSubsidy = (nSubsidy / CENT) * CENT;
if (fDebug && GetBoolArg("-printcreation"))
printf("GetProofOfWorkReward() : create=%s nBits=0x%08x nSubsidy=%"PRI64d"\n", FormatMoney(nSubsidy).c_str(), nBits, nSubsidy);
}
// miner's coin stake reward based on nBits and coin age spent (coin-days)
-int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime)
+int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, bool bCoinYearOnly)
{
int64 nRewardCoinYear;
nRewardCoinYear = 5 * CENT;
}
+ if(bCoinYearOnly)
+ return nRewardCoinYear;
+
int64 nSubsidy = nCoinAge * 33 / (365 * 33 + 8) * nRewardCoinYear;
+
if (fDebug && GetBoolArg("-printcreation"))
printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d" nBits=%d\n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBits);
return nSubsidy;
}
else
{
+ // Coinbase fee paid until 20 Sep 2013
+ int64 nFee = GetBlockTime() < CHAINCHECKS_SWITCH_TIME ? vtx[0].GetMinFee() - MIN_TX_FEE : 0;
+
// Check coinbase reward
- if (vtx[0].GetValueOut() > (GetProofOfWorkReward(nBits) - vtx[0].GetMinFee() + MIN_TX_FEE))
+ if (vtx[0].GetValueOut() > (GetProofOfWorkReward(nBits) - nFee))
return DoS(50, error("CheckBlock() : coinbase reward exceeded %s > %s",
FormatMoney(vtx[0].GetValueOut()).c_str(),
- FormatMoney(IsProofOfWork()? GetProofOfWorkReward(nBits) : 0).c_str()));
+ FormatMoney(GetProofOfWorkReward(nBits) - nFee).c_str()));
}
// Check transactions
CBigNum CBlockIndex::GetBlockTrust() const
{
CBigNum bnTarget;
+ bnTarget.SetCompact(nBits);
- // Old protocol
- if (!fTestNet && GetBlockTime() < CHAINCHECKS_SWITCH_TIME)
- {
- CBigNum bnTarget;
- bnTarget.SetCompact(nBits);
+ if (bnTarget <= 0)
+ return 0;
- if (bnTarget <= 0)
- return 0;
+ /* Old protocol, will be removed later */
+ if (!fTestNet && GetBlockTime() < CHAINCHECKS_SWITCH_TIME)
return (IsProofOfStake()? (CBigNum(1)<<256) / (bnTarget+1) : 1);
- }
- // New protocol
- if (pprev == NULL || pprev->nHeight < 10)
- return 1;
+ /* New protocol */
+
+ // Calculate work amount for block
+ CBigNum bnPoWTrust = bnPoWBase / (bnTarget+1);
+
+ // Set bnPowTrust to 1 if we are checking PoS block or PoW difficulty is too low
+ bnPoWTrust = (IsProofOfStake() || bnPoWTrust < 1) ? 1 : bnPoWTrust;
+
+ // Return bnPoWTrust for the first 12 blocks
+ if (pprev == NULL || pprev->nHeight < 12)
+ return bnPoWTrust;
const CBlockIndex* currentIndex = pprev;
if(IsProofOfStake())
{
- bnTarget.SetCompact(nBits);
- if (bnTarget <= 0)
- return 0;
-
+ // Return 1/3 of score if parent block is not the PoW block
if (!pprev->IsProofOfWork())
return (CBigNum(1)<<256) / (3 * (bnTarget+1));
}
else
{
+ // Return bnPoWTrust + 2/3 of previous block score if two parent blocks are not PoS blocks
if (!(pprev->IsProofOfStake() && pprev->pprev->IsProofOfStake()))
- return 1 + (2 * (pprev->bnChainTrust - pprev->pprev->bnChainTrust) / 3);
+ return bnPoWTrust + (2 * (pprev->bnChainTrust - pprev->pprev->bnChainTrust) / 3);
int nPoSCount = 0;
currentIndex = currentIndex->pprev;
}
- // Return 2/3 of previous block score if less than 7 PoS blocks found
+ // Return bnPoWTrust + 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 bnPoWTrust + (2 * (pprev->bnChainTrust - pprev->pprev->bnChainTrust) / 3);
- return (pprev->bnChainTrust - pprev->pprev->bnChainTrust);
+ bnTarget.SetCompact(pprev->nBits);
+
+ if (bnTarget <= 0)
+ return 0;
+
+ // Return bnPoWTrust + full trust score for previous block nBits
+ return bnPoWTrust + (CBigNum(1)<<256) / (bnTarget+1);
}
}
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))
{
return true;
}
-void static ThreadBitcoinMiner(void* parg);
-
-static bool fGenerateBitcoins = false;
-static bool fLimitProcessors = false;
-static int nLimitProcessors = -1;
-
void BitcoinMiner(CWallet *pwallet, bool fProofOfStake)
{
SetThreadPriority(THREAD_PRIORITY_LOWEST);
}
}
-void static ThreadBitcoinMiner(void* parg)
-{
- CWallet* pwallet = (CWallet*)parg;
- try
- {
- vnThreadsRunning[THREAD_MINER]++;
- BitcoinMiner(pwallet, false);
- vnThreadsRunning[THREAD_MINER]--;
- }
- catch (std::exception& e) {
- vnThreadsRunning[THREAD_MINER]--;
- PrintException(&e, "ThreadBitcoinMiner()");
- } catch (...) {
- vnThreadsRunning[THREAD_MINER]--;
- PrintException(NULL, "ThreadBitcoinMiner()");
- }
- nHPSTimerStart = 0;
- if (vnThreadsRunning[THREAD_MINER] == 0)
- dHashesPerSec = 0;
- printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[THREAD_MINER]);
-}
-
-
-void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
-{
- fGenerateBitcoins = fGenerate;
- nLimitProcessors = GetArg("-genproclimit", -1);
- if (nLimitProcessors == 0)
- fGenerateBitcoins = false;
- fLimitProcessors = (nLimitProcessors != -1);
-
- if (fGenerate)
- {
- int nProcessors = boost::thread::hardware_concurrency();
- printf("%d processors\n", nProcessors);
- if (nProcessors < 1)
- nProcessors = 1;
- if (fLimitProcessors && nProcessors > nLimitProcessors)
- nProcessors = nLimitProcessors;
- int nAddThreads = nProcessors - vnThreadsRunning[THREAD_MINER];
- printf("Starting %d BitcoinMiner threads\n", nAddThreads);
- for (int i = 0; i < nAddThreads; i++)
- {
- if (!NewThread(ThreadBitcoinMiner, pwallet))
- printf("Error: NewThread(ThreadBitcoinMiner) failed\n");
- Sleep(10);
- }
- }
-}