Don't calculate hashes of signature for PoW blocks before #9689, use pregenerated table instead.
( 0, 0x0e00670bu )
;
+// Pregenerated entropy bits table (from genesis to #9689)
+//
+// Bits are packed into array of 256 bit integers:
+//
+// * array index calculated as nHeight / 256
+// * position of bit is calculated as nHeight & 0xFF.
+//
+const uint256 entropyStore[] = {
+ uint256("0x4555b4dcc1d690ddd9b810c90c66e82b18bf4f43cc887246c418383ec120a5ab"),
+ uint256("0xaa6d1198412fa77608addf6549c9198a22155e8afd7a9ded6179f6b7cfc66b0c"),
+ uint256("0x9442fabfa4116fb14a9769c2eea003845a1f5c3a0260f36b497d68f3a3cd4078"),
+ uint256("0x0e769042a9a98e42388195d699574b822d06515f7053ad884c53d7ee059f05b1"),
+ uint256("0x7005aac20baf70251aebfe3f1b95987d83ef1e3e6963de8fed601d4dd07bf7cf"),
+ uint256("0x58952c5c3de188f2e33c38d3f53d7bf44f9bc545a4289d266696273fa821be66"),
+ uint256("0x50b6c2ed780c08aaec3f7665b1b6004206243e3866456fc910b83b52d07eeb63"),
+ uint256("0x563841eefca85ba3384986c58100408ae3f1ba2ac727e1ac910ce154a06c702f"),
+ uint256("0x79275b03938b3e27a9b01a7f7953c6c487c58355f5d4169accfbb800213ffd13"),
+ uint256("0xd783f2538b3ed18f135af90adc687c5646d93aeaeaabc6667be94f7aa0a2d366"),
+ uint256("0xb441d0c175c40c8e88b09d88ea008af79cbed2d28219427d2e72fda682974db8"),
+ uint256("0x3204c43bd41f2e19628af3b0c9aca3db15bca4c8705d51056e7b17a319c04715"),
+ uint256("0x7e80e6ab7857d8f2f261a0a49c783bd800b365b8c9b85cc0e13f73904b0dcaa9"),
+ uint256("0xefaaee60ed82d2ad145c0e347941fdb131eb8fd289a45eef07121a93f283c5f1"),
+ uint256("0x3efc86e4334da332c1fd4c12513c40cff689f3efdc7f9913230822adacdda4f9"),
+ uint256("0xf0d6b8f38599a017fa35d1fbbf9ef51eca5ebc5b286aadba40c4c3e1d9bace0c"),
+ uint256("0x286a67f27323486036a0a92d35382fc8963c0c00bad331723318b4b9fdb2b56e"),
+ uint256("0xecbfaaa6567c54f08c4d5bd0118a2d7b58740f42cbfc73aa1536c1f5f76de87c"),
+ uint256("0xf9a4de1c5c46520de5aaf10d3796cf0e27ddce98b3398357f5726a949664e308"),
+ uint256("0xd75e6c4dc4be08401e3478d2467d9ab96a62af4f255c04a82c41af0de0a487bb"),
+ uint256("0x1a82c3bc6ad6047294c16571b5e2b7316c97bf8813e7da15798b9820d67e39f2"),
+ uint256("0xb49be0080de564e01829ded7e7971979565a741c5975dc9978dcc020192d396c"),
+ uint256("0x0d8eed113be67663b5a15a0625a9b49792b5ea59c005c4f405914877acab7000"),
+ uint256("0x8f9d46e2bc05a218ffa942965b747056197d393b097085523640cd59e07fe7c7"),
+ uint256("0x7a63ab40bc7f40ac2ebe9ede438d97b45fa6ed6f8419016da8d5f7a670111dda"),
+ uint256("0x63fbcc080448c43d6cf915c958314feff7a95a52ba43a68c05fc281d3a522d25"),
+ uint256("0xf834cf824c326d3ea861ea1e85dc3289265e37045981e28208e7344a7f8081d7"),
+ uint256("0xb4edc22ec98cc49b2f5af5bae3f52f5e6058280f74f2c432c2dd89ae49acceb8"),
+ uint256("0x0fe596037dcf81bf5c64f39755261c404ed088af5c8c31dd7549b6657ee92365"),
+ uint256("0xbbad51a0aeba254b01d18c328de9e932b9b859b61e622c325d64e2211b5e413d"),
+ uint256("0xabf0194cc787be938bc51c7fdf1cae4ec79e65ebab8fa8b8f40541c44ef384b0"),
+ uint256("0x83bc12d6fdbd3e854cb91c4ca7dfba3c38e8714121af88c8a8abdb33e5002438"),
+ uint256("0x71a2513026cabaedcbe55aeb6dc8049e5b763a3f54f10c33dd333624f764b38c"),
+ uint256("0xee6725632ff5c025dff6a18cd059875dcae20f399b03bccba13d9d5fcf6d9d9a"),
+ uint256("0xa168a2741d1e7e50cc74b79f695c25ffd3576e6bd61353c2a20e569fd63b2dac"),
+ uint256("0x6e462d2a87bfde9398b6747f94a8ed6a01e4d96c5b4372df5c910c106c48bd13"),
+ uint256("0x8eeb696181957c4b22434028990f49cb30006827c73860e77e2eecf5c38be99d"),
+ uint256("0x3188aaa65877b166f05cdc48f55b1f77a7d6fb221c395596d990ae5647e9ba96")
+};
+
// Whether the given block is subject to new modifier protocol
bool IsFixedModifierInterval(unsigned int nTimeBlock)
{
pindexNew->nChainTrust = (pindexNew->pprev ? pindexNew->pprev->nChainTrust : 0) + pindexNew->GetBlockTrust();
// ppcoin: compute stake entropy bit for stake modifier
- if (!pindexNew->SetStakeEntropyBit(GetStakeEntropyBit(pindexNew->nTime)))
+ if (!pindexNew->SetStakeEntropyBit(GetStakeEntropyBit(pindexNew->nHeight)))
return error("AddToBlockIndex() : SetStakeEntropyBit() failed");
// ppcoin: record proof-of-stake hash value
return DoS(50, error("CheckBlock() : coinstake timestamp violation nTimeBlock=%" PRId64 " nTimeTx=%u", GetBlockTime(), vtx[1].nTime));
// NovaCoin: check proof-of-stake block signature
- if (fCheckSig && !CheckBlockSignature(true))
+ if (fCheckSig && !CheckBlockSignature())
return DoS(100, error("CheckBlock() : bad proof-of-stake block signature"));
}
- else
- {
- // Should we check proof-of-work block signature or not?
- //
- // * Always skip on TestNet
- // * Perform checking for the first 9689 blocks
- // * Perform checking since last checkpoint until 20 Sep 2013 (will be removed after)
-
- if(!fTestNet && fCheckSig)
- {
- bool checkEntropySig = (GetBlockTime() < ENTROPY_SWITCH_TIME);
-
- // NovaCoin: check proof-of-work block signature
- if (checkEntropySig && !CheckBlockSignature(false))
- return DoS(100, error("CheckBlock() : bad proof-of-work block signature"));
- }
- }
// Check transactions
BOOST_FOREACH(const CTransaction& tx, vtx)
}
// ppcoin: check block signature
-bool CBlock::CheckBlockSignature(bool fProofOfStake) const
+bool CBlock::CheckBlockSignature() const
{
- if (GetHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet))
- return vchBlockSig.empty();
+ if (IsProofOfWork())
+ return true;
vector<valtype> vSolutions;
txnouttype whichType;
- if(fProofOfStake)
- {
- const CTxOut& txout = vtx[1].vout[1];
+ const CTxOut& txout = vtx[1].vout[1];
- if (!Solver(txout.scriptPubKey, whichType, vSolutions))
- return false;
- if (whichType == TX_PUBKEY)
- {
- valtype& vchPubKey = vSolutions[0];
- CKey key;
- if (!key.SetPubKey(vchPubKey))
- return false;
- if (vchBlockSig.empty())
- return false;
- return key.Verify(GetHash(), vchBlockSig);
- }
- }
- else
+ if (!Solver(txout.scriptPubKey, whichType, vSolutions))
+ return false;
+ if (whichType == TX_PUBKEY)
{
- for(unsigned int i = 0; i < vtx[0].vout.size(); i++)
- {
- const CTxOut& txout = vtx[0].vout[i];
-
- if (!Solver(txout.scriptPubKey, whichType, vSolutions))
- return false;
-
- if (whichType == TX_PUBKEY)
- {
- // Verify
- valtype& vchPubKey = vSolutions[0];
- CKey key;
- if (!key.SetPubKey(vchPubKey))
- continue;
- if (vchBlockSig.empty())
- continue;
- if(!key.Verify(GetHash(), vchBlockSig))
- continue;
-
- return true;
- }
- }
+ valtype& vchPubKey = vSolutions[0];
+ CKey key;
+ if (!key.SetPubKey(vchPubKey))
+ return false;
+ if (vchBlockSig.empty())
+ return false;
+ return key.Verify(GetHash(), vchBlockSig);
}
return false;
}
extern bool fUseFastIndex;
extern unsigned int nDerivationMethodIndex;
extern int nScriptCheckThreads;
+extern const uint256 entropyStore[38];
// Minimum disk space required - used in CheckDiskSpace()
static const uint64_t nMinDiskSpace = 52428800;
};
-
-
-
/** Nodes collect new transactions into a block, hash them into a hash tree,
* and scan through nonce values to make the block's hash satisfy proof-of-work
* requirements. When they solve the proof-of-work, they broadcast the block
void UpdateTime(const CBlockIndex* pindexPrev);
// ppcoin: entropy bit for stake modifier if chosen by modifier
- unsigned int GetStakeEntropyBit(unsigned int nTime) const
+ unsigned int GetStakeEntropyBit(unsigned int nHeight) const
{
// Protocol switch to support p2pool at novacoin block #9689
- if (nTime >= ENTROPY_SWITCH_TIME || fTestNet)
+ if (nHeight >= 9689 || fTestNet)
{
// Take last bit of block hash as entropy bit
unsigned int nEntropyBit = ((GetHash().Get64()) & 1ULL);
printf("GetStakeEntropyBit: nTime=%u hashBlock=%s nEntropyBit=%u\n", nTime, GetHash().ToString().c_str(), nEntropyBit);
return nEntropyBit;
}
- // Before novacoin block #9689 - old protocol
- uint160 hashSig = Hash160(vchBlockSig);
- if (fDebug && GetBoolArg("-printstakemodifier"))
- printf("GetStakeEntropyBit: hashSig=%s", hashSig.ToString().c_str());
- hashSig >>= 159; // take the first bit of the hash
+
+ // Before novacoin block #9689 - get from pregenerated table
+ int nBitNum = nHeight & 0xFF;
+ int nItemNum = nHeight / 0xFF;
+
+ unsigned int nEntropyBit = (unsigned int) ((entropyStore[nItemNum] & (uint256(1) << nBitNum)) >> nBitNum).Get64();
if (fDebug && GetBoolArg("-printstakemodifier"))
- printf(" entropybit=%" PRId64 "\n", hashSig.Get64());
- return (unsigned int)hashSig.Get64();
+ printf("GetStakeEntropyBit: from pregenerated table, nHeight=%d nEntropyBit=%u\n", nHeight, nEntropyBit);
+ return nEntropyBit;
}
// ppcoin: two types of block: proof-of-work or proof-of-stake
bool AcceptBlock();
bool GetCoinAge(uint64_t& nCoinAge) const; // ppcoin: calculate total coin age spent in block
bool SignBlock(CWallet& keystore);
- bool CheckBlockSignature(bool fProofOfStake) const;
+ bool CheckBlockSignature() const;
private:
bool SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew);