| 4065 | } |
| 4066 | |
| 4067 | CBlockIndex* AddToBlockIndex(const CBlock& block) |
| 4068 | { |
| 4069 | CBlockIndex* pindexPrev = LookupBlockIndex(block.hashPrevBlock); |
| 4070 | |
| 4071 | int Height = pindexPrev ? pindexPrev->nHeight + 1 : 0; |
| 4072 | // Check for duplicate |
| 4073 | |
| 4074 | uint256 hash = /*(block.IsProofOfWork()) ? block.GetHash(Height,2):*/block.GetHash(Height); |
| 4075 | CBlockIndex* pindex = LookupBlockIndex(hash); |
| 4076 | if (pindex) |
| 4077 | return pindex; |
| 4078 | |
| 4079 | // Construct new block index object |
| 4080 | CBlockIndex* pindexNew = new CBlockIndex(block); |
| 4081 | assert(pindexNew); |
| 4082 | |
| 4083 | // We assign the sequence id to blocks only when the full data is available, |
| 4084 | // to avoid miners withholding blocks but broadcasting headers, to get a |
| 4085 | // competitive advantage. |
| 4086 | pindexNew->nSequenceId = 0; |
| 4087 | BlockMap::iterator mi = mapBlockIndex.emplace(hash, pindexNew).first; |
| 4088 | |
| 4089 | //mark as PoS seen |
| 4090 | if (pindexNew->IsProofOfStake()) |
| 4091 | stake->MarkStake(pindexNew->prevoutStake, pindexNew->nStakeTime); |
| 4092 | |
| 4093 | pindexNew->phashBlock = &((*mi).first); |
| 4094 | if (pindexPrev) { |
| 4095 | pindexNew->pprev = pindexPrev; |
| 4096 | pindexNew->nHeight = pindexNew->pprev->nHeight + 1; |
| 4097 | pindexNew->BuildSkip(); |
| 4098 | |
| 4099 | //update previous block pointer |
| 4100 | pindexNew->pprev->pnext = pindexNew; |
| 4101 | |
| 4102 | // ppcoin: compute chain trust score |
| 4103 | pindexNew->bnChainTrust = (pindexNew->pprev ? pindexNew->pprev->bnChainTrust : 0) + pindexNew->GetBlockTrust(); |
| 4104 | |
| 4105 | // ppcoin: compute stake entropy bit for stake modifier |
| 4106 | if (!pindexNew->SetStakeEntropyBit(pindexNew->GetStakeEntropyBit())) |
| 4107 | LogPrintf("%s: SetStakeEntropyBit() failed \n", __func__); |
| 4108 | |
| 4109 | // ppcoin: record proof-of-stake hash value |
| 4110 | if (pindexNew->IsProofOfStake()) { |
| 4111 | if (!stake->GetProof(hash, pindexNew->hashProofOfStake)) { |
| 4112 | LogPrintf("%s: zero stake (%s)\n", __func__, hash.GetHex()); |
| 4113 | } |
| 4114 | } |
| 4115 | |
| 4116 | // ppcoin: compute stake modifier |
| 4117 | uint64_t nStakeModifier = 0; |
| 4118 | bool fGeneratedStakeModifier = false; |
| 4119 | if (!stake->ComputeNextModifier(pindexNew->pprev, nStakeModifier, fGeneratedStakeModifier)) |
| 4120 | LogPrintf("%s: ComputeNextModifier() failed \n", __func__); |
| 4121 | |
| 4122 | pindexNew->SetStakeModifier(nStakeModifier, fGeneratedStakeModifier); |
| 4123 | pindexNew->nStakeModifierChecksum = stake->GetModifierChecksum(pindexNew); |
| 4124 | if (!stake->CheckModifierCheckpoints(pindexNew->nHeight, pindexNew->nStakeModifierChecksum)) |
no test coverage detected