use of org.aion.zero.impl.types.GenesisStakingBlock in project aion by aionnetwork.
the class AionBlockchainImpl method isValid.
public boolean isValid(BlockHeader header) {
/*
* The block header should already be validated at this point by P2P or mining,
* but we are including the validation in case future import paths forget to add it.
*/
if (!this.headerValidator.validate(header, LOG)) {
return false;
}
Block[] threeGenParents = repository.getBlockStore().getThreeGenerationBlocksByHashWithInfo(header.getParentHash());
Block parentBlock = threeGenParents[0];
if (parentBlock == null) {
return false;
}
Block grandparentBlock = threeGenParents[1];
Block greatGrandparentBlock = threeGenParents[2];
if (header.getSealType() == Seal.PROOF_OF_WORK) {
if (forkUtility.isUnityForkActive(header.getNumber())) {
if (grandparentBlock == null || greatGrandparentBlock == null) {
return false;
}
return unityParentBlockHeaderValidator.validate(header, parentBlock.getHeader(), LOG, null) && unityGreatGrandParentBlockHeaderValidator.validate(grandparentBlock.getHeader(), greatGrandparentBlock.getHeader(), header, LOG);
} else {
return preUnityParentBlockHeaderValidator.validate(header, parentBlock.getHeader(), LOG, null) && preUnityGrandParentBlockHeaderValidator.validate(parentBlock.getHeader(), grandparentBlock == null ? null : grandparentBlock.getHeader(), header, LOG);
}
} else if (header.getSealType() == Seal.PROOF_OF_STAKE) {
if (!forkUtility.isUnityForkActive(header.getNumber())) {
LOG.warn("Trying to import a Staking block when the Unity fork is not active.");
return false;
}
if (grandparentBlock == null) {
LOG.warn("Staking block {} cannot find its grandparent", header.getNumber());
return false;
}
if (forkUtility.isUnityForkBlock(parentBlock.getNumber())) {
BigInteger expectedDiff = calculateFirstPoSDifficultyAtBlock(parentBlock);
if (!expectedDiff.equals(header.getDifficultyBI())) {
return false;
}
grandparentBlock = new GenesisStakingBlock(expectedDiff);
} else if (forkUtility.isNonceForkBlock(parentBlock.getNumber())) {
BigInteger expectedDiff = calculateFirstPoSDifficultyAtBlock(parentBlock);
if (!expectedDiff.equals(header.getDifficultyBI())) {
return false;
}
}
BigInteger stake = null;
try {
stake = getStakingContractHelper().getEffectiveStake(new AionAddress(AddressSpecs.computeA0Address(((StakingBlockHeader) header).getSigningPublicKey())), ((StakingBlockHeader) header).getCoinbase(), parentBlock);
} catch (Exception e) {
LOG.error("Shutdown due to a fatal error encountered while getting the effective stake.", e);
System.exit(SystemExitCodes.FATAL_VM_ERROR);
}
boolean result = unityParentBlockHeaderValidator.validate(header, parentBlock.getHeader(), LOG, stake);
if (result) {
if (forkUtility.isSignatureSwapForkActive(header.getNumber())) {
result = vrfProofValidator.validate(parentBlock.getHeader(), grandparentBlock.getHeader(), header, LOG) && difficultyValidateAfterSeedNonceFork(grandparentBlock.getHeader(), greatGrandparentBlock.getHeader(), header);
} else if (forkUtility.isNonceForkActive(header.getNumber())) {
result = nonceSeedValidator.validate(grandparentBlock.getHeader(), parentBlock.getHeader(), header, LOG) && difficultyValidateAfterSeedNonceFork(grandparentBlock.getHeader(), greatGrandparentBlock.getHeader(), header);
} else {
result = unityGreatGrandParentBlockHeaderValidator.validate(grandparentBlock.getHeader(), greatGrandparentBlock.getHeader(), header, LOG);
}
}
return result;
} else {
LOG.debug("Invalid header seal type!");
return false;
}
}
Aggregations