Skip to content

Commit

Permalink
Revise BlockHeader Validators for compatible with staking block heade…
Browse files Browse the repository at this point in the history
…r rules
  • Loading branch information
AionJayT committed Sep 18, 2019
1 parent 9ab609a commit 241877e
Show file tree
Hide file tree
Showing 19 changed files with 230 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.aion.equihash.OptimizedEquiValidator;
import org.aion.mcf.blockchain.BlockHeader.BlockSealType;
import org.aion.zero.impl.core.UnityBlockDiffCalculator;
import org.aion.zero.impl.types.IBlockConstants;
import org.aion.zero.impl.core.IDifficultyCalculator;
import org.aion.zero.impl.core.IRewardsCalculator;
import org.aion.zero.impl.valid.BlockHeaderRule;
import org.aion.zero.impl.valid.BlockHeaderValidator;
import org.aion.zero.impl.valid.BlockNumberRule;
import org.aion.zero.impl.valid.DependentBlockHeaderRule;
import org.aion.zero.impl.valid.GrandParentBlockHeaderValidator;
import org.aion.zero.impl.valid.GrandParentDependantBlockHeaderRule;
import org.aion.zero.impl.valid.ParentBlockHeaderValidator;
import org.aion.zero.impl.valid.TimeStampRule;
import org.aion.zero.impl.api.BlockConstants;
Expand Down Expand Up @@ -90,27 +97,39 @@ protected OptimizedEquiValidator getEquihashValidator() {
}

public BlockHeaderValidator createBlockHeaderValidator() {
return new BlockHeaderValidator(
Arrays.asList(
new AionExtraDataRule(this.getConstants().getMaximumExtraDataSize()),
new EnergyConsumedRule(),
new AionPOWRule(),
new EquihashSolutionRule(this.getEquihashValidator()),
new AionHeaderVersionRule()));
List<BlockHeaderRule> powRules = Arrays.asList(
new AionExtraDataRule(this.getConstants().getMaximumExtraDataSize()),
new EnergyConsumedRule(),
new AionPOWRule(),
new EquihashSolutionRule(this.getEquihashValidator()),
new AionHeaderVersionRule());

Map<Byte, List<BlockHeaderRule>> unityRules= new HashMap<>();
unityRules.put(BlockSealType.SEAL_POW_BLOCK.getSealId(), powRules);

return new BlockHeaderValidator(unityRules);
}

public ParentBlockHeaderValidator createParentHeaderValidator() {
return new ParentBlockHeaderValidator(
List<DependentBlockHeaderRule> powRules =
Arrays.asList(
new BlockNumberRule(),
new TimeStampRule(),
new EnergyLimitRule(
this.getConstants().getEnergyDivisorLimitLong(),
this.getConstants().getEnergyLowerBoundLong())));
this.getConstants().getEnergyLowerBoundLong()));

Map<Byte, List<DependentBlockHeaderRule>> unityRules= new HashMap<>();
unityRules.put(BlockSealType.SEAL_POW_BLOCK.getSealId(), powRules);
return new ParentBlockHeaderValidator(unityRules);
}

public GrandParentBlockHeaderValidator createGrandParentHeaderValidator() {
return new GrandParentBlockHeaderValidator(
Collections.singletonList(new AionDifficultyRule(this)));
List<GrandParentDependantBlockHeaderRule> powRules =
Collections.singletonList(new AionDifficultyRule(this));

Map<Byte, List<GrandParentDependantBlockHeaderRule>> unityRules= new HashMap<>();
unityRules.put(BlockSealType.SEAL_POW_BLOCK.getSealId(), powRules);
return new GrandParentBlockHeaderValidator(unityRules);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
import org.aion.db.impl.DatabaseFactory;
import org.aion.mcf.blockchain.Block;
import org.aion.mcf.blockchain.BlockHeader;
import org.aion.mcf.blockchain.BlockHeader.BlockSealType;
import org.aion.mcf.config.CfgPrune;
import org.aion.mcf.db.InternalVmType;
import org.aion.mcf.config.PruneConfig;
import org.aion.mcf.db.RepositoryCache;
import org.aion.zero.impl.core.ImportResult;
import org.aion.zero.impl.types.AionGenesis;
import org.aion.zero.impl.valid.BlockHeaderRule;
import org.aion.zero.impl.valid.BlockHeaderValidator;
import org.aion.util.types.DataWord;
import org.aion.zero.impl.db.RepositoryConfig;
Expand Down Expand Up @@ -343,15 +345,19 @@ public boolean isInternalStakingEnabled() {
* generated are valid.
*/
@Override
public BlockHeaderValidator
createBlockHeaderValidator() {
return new BlockHeaderValidator(
Arrays.asList(
new AionExtraDataRule(
this.constants
.getMaximumExtraDataSize()),
new EnergyConsumedRule(),
new AionHeaderVersionRule()));
public BlockHeaderValidator createBlockHeaderValidator() {

List<BlockHeaderRule> powRules = Arrays.asList(
new AionExtraDataRule(
this.getConstants().getMaximumExtraDataSize()),
new EnergyConsumedRule(),
new AionHeaderVersionRule());

Map<Byte, List<BlockHeaderRule>> unityRules = new HashMap<>();
unityRules
.put(BlockSealType.SEAL_POW_BLOCK.getSealId(), powRules);

return new BlockHeaderValidator(unityRules);
}
};
} else {
Expand Down
10 changes: 0 additions & 10 deletions modAionImpl/src/org/aion/zero/impl/valid/AbstractValidRule.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import org.aion.zero.impl.core.IDifficultyCalculator;

/** Checks block's difficulty against calculated difficulty value */
public class AionDifficultyRule extends GrandParentDependantBlockHeaderRule {
public class AionDifficultyRule implements GrandParentDependantBlockHeaderRule {

private IDifficultyCalculator diffCalc;

Expand Down Expand Up @@ -41,7 +41,8 @@ public boolean validate(

if (parent.getNumber() == 0L) {
if (!isEqual(parent.getDifficultyBI(), currDiff)) {
addError(formatError(parent.getDifficultyBI(), currDiff), errors);
BlockHeaderValidatorUtil.addError(
formatError(parent.getDifficultyBI(), currDiff), this.getClass(), errors);
return false;
}
return true;
Expand All @@ -50,7 +51,8 @@ public boolean validate(
BigInteger calcDifficulty = this.diffCalc.calculateDifficulty(parent, grandParent);

if (!isEqual(calcDifficulty, currDiff)) {
addError(formatError(calcDifficulty, currDiff), errors);
BlockHeaderValidatorUtil.addError(
formatError(calcDifficulty, currDiff), this.getClass(), errors);
return false;
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import org.aion.mcf.blockchain.BlockHeader;

public class AionExtraDataRule extends BlockHeaderRule {
public class AionExtraDataRule implements BlockHeaderRule {

private final int maximumExtraDataSize;

Expand All @@ -19,10 +19,11 @@ public AionExtraDataRule(int maximumExtraDataSize) {
public boolean validate(BlockHeader header, List<RuleError> errors) {
if (header.getExtraData() != null
&& header.getExtraData().length > this.maximumExtraDataSize) {
addError(
BlockHeaderValidatorUtil.addError(
String.format(
"extraData (%d) > MAXIMUM_EXTRA_DATA_SIZE (%d)",
header.getExtraData().length, this.maximumExtraDataSize),
this.getClass(),
errors);
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@
import org.aion.mcf.blockchain.BlockHeader;
import org.aion.zero.impl.types.A0BlockHeaderVersion;

public class AionHeaderVersionRule extends BlockHeaderRule {
public class AionHeaderVersionRule implements BlockHeaderRule {

@Override
public boolean validate(BlockHeader header, List<RuleError> errors) {
if (!A0BlockHeaderVersion.isActive(header.getSealType().getSealId())) { //TODO: [unity] Revise this rule in the following commits
addError(
if (!A0BlockHeaderVersion.isActive(
header.getSealType()
.getSealId())) { // TODO: [unity] Revise this rule in the following commits
BlockHeaderValidatorUtil.addError(
"Invalid header version, found version "
+ header.getSealType()
+ " expected one of "
+ A0BlockHeaderVersion.activeVersions(),
this.getClass(),
errors);
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions modAionImpl/src/org/aion/zero/impl/valid/AionPOWRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import org.aion.zero.impl.types.A0BlockHeader;

/** Checks proof value against its boundary for the block header */
public class AionPOWRule extends BlockHeaderRule {
public class AionPOWRule implements BlockHeaderRule {

@Override
public boolean validate(BlockHeader header, List<RuleError> errors) {
Expand All @@ -29,7 +29,7 @@ public boolean validate(A0BlockHeader header, List<RuleError> errors) {
BigInteger hash = new BigInteger(1, HashUtil.h256(input));

if (hash.compareTo(boundary) >= 0) {
addError(formatError(hash, boundary), errors);
BlockHeaderValidatorUtil.addError(formatError(hash, boundary), this.getClass(), errors);
return false;
}
return true;
Expand Down
4 changes: 2 additions & 2 deletions modAionImpl/src/org/aion/zero/impl/valid/BlockHeaderRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
* Block header rules.
*
*/
public abstract class BlockHeaderRule extends AbstractValidRule {
public abstract boolean validate(BlockHeader header, List<RuleError> errors);
public interface BlockHeaderRule {
boolean validate(BlockHeader header, List<RuleError> errors);
}
38 changes: 29 additions & 9 deletions modAionImpl/src/org/aion/zero/impl/valid/BlockHeaderValidator.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,45 @@
package org.aion.zero.impl.valid;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import java.util.Map;
import org.aion.mcf.blockchain.BlockHeader;
import org.slf4j.Logger;

public class BlockHeaderValidator extends AbstractBlockHeaderValidator {
public class BlockHeaderValidator {

private List<BlockHeaderRule> rules;
private Map<Byte, List<BlockHeaderRule>> chainRules;

public BlockHeaderValidator(List<BlockHeaderRule> rules) {
this.rules = rules;
public BlockHeaderValidator(Map<Byte, List<BlockHeaderRule>> rules) {
if (rules == null) {
throw new NullPointerException("The blockHeaderRule can not be null");
}
chainRules = rules;
}

public boolean validate(BlockHeader header, Logger logger) {
List<RuleError> errors = new LinkedList<>();
for (BlockHeaderRule rule : rules) {
if (!rule.validate(header, errors)) {
if (logger != null) logErrors(logger, errors);
return false;
if (header == null) {
RuleError err = new RuleError(this.getClass(),"the input header is null");
BlockHeaderValidatorUtil.logErrors(
logger, this.getClass().getSimpleName(), Collections.singletonList(err));
return false;
}

List<BlockHeaderRule> rules = chainRules.get(header.getSealType().getSealId());
if (rules == null) {
return false;
} else {
List<RuleError> errors = new LinkedList<>();
for (BlockHeaderRule rule : rules) {
if (!rule.validate(header, errors)) {
if (logger != null) {
BlockHeaderValidatorUtil.logErrors(
logger, this.getClass().getSimpleName(), errors);
}
return false;
}
}
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
import java.util.List;
import org.slf4j.Logger;

public class AbstractBlockHeaderValidator {
class BlockHeaderValidatorUtil {

public void logErrors(final Logger logger, final List<RuleError> errors) {
if (errors.isEmpty()) return;
static void logErrors(final Logger logger, String className, final List<RuleError> errors) {
if (errors.isEmpty()) {
return;
}

if (logger.isErrorEnabled()) {
StringBuilder builder = new StringBuilder();
builder.append(this.getClass().getSimpleName());
builder.append(className);
builder.append(" raised errors: \n");
for (RuleError error : errors) {
builder.append(error.errorClass.getSimpleName());
Expand All @@ -21,4 +23,8 @@ public void logErrors(final Logger logger, final List<RuleError> errors) {
logger.error(builder.toString());
}
}

static void addError(String error, Class cls, List<RuleError> errors) {
errors.add(new RuleError(cls, error));
}
}
11 changes: 9 additions & 2 deletions modAionImpl/src/org/aion/zero/impl/valid/BlockNumberRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,24 @@
import java.util.List;
import org.aion.mcf.blockchain.BlockHeader;

public class BlockNumberRule extends DependentBlockHeaderRule {
public class BlockNumberRule implements DependentBlockHeaderRule {

@Override
public boolean validate(BlockHeader header, BlockHeader parent, List<RuleError> errors) {
if (header.getNumber() != (parent.getNumber() + 1)) {
addError(formatError(header.getNumber(), parent.getNumber()), errors);
BlockHeaderValidatorUtil.addError(
formatError(header.getNumber(), parent.getNumber()), this.getClass(), errors);
return false;
}
return true;
}

@Override
public boolean validate(
BlockHeader header, BlockHeader dependency, List<RuleError> errors, Object arg) {
return validate(header, dependency, errors);
}

private static String formatError(long headerNumber, long parentNumber) {
return "blockNumber ("
+ headerNumber
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@
import org.aion.mcf.blockchain.BlockHeader;

/** A class of rules that requires memory of the previous block */
public abstract class DependentBlockHeaderRule {
public interface DependentBlockHeaderRule {

/**
* Validates a dependant rule, where {@code header} represents the current block, and {@code
* dependency} represents the {@code memory} required to validate whether the current block is
* correct. Most likely the {@code memory} refers to the previous block
*/
public abstract boolean validate(BlockHeader header, BlockHeader dependency, List<RuleError> errors);
boolean validate(BlockHeader header, BlockHeader dependency, List<RuleError> errors);

public void addError(String error, List<RuleError> errors) {
errors.add(new RuleError(this.getClass(), error));
}
}
boolean validate(BlockHeader header, BlockHeader dependency, List<RuleError> errors, Object arg);

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
* Rule for checking that energyConsumed does not exceed energyLimit:
* assert(blockHeader.energyConsumed <= blockHeader.energyLimit)
*/
public class EnergyConsumedRule extends BlockHeaderRule {
public class EnergyConsumedRule implements BlockHeaderRule {

@Override
public boolean validate(BlockHeader blockHeader, List<RuleError> error) {
if (blockHeader.getEnergyConsumed() > blockHeader.getEnergyLimit()) {
addError(
BlockHeaderValidatorUtil.addError(
formatError(blockHeader.getEnergyConsumed(), blockHeader.getEnergyLimit()),
this.getClass(),
error);
return false;
}
Expand Down
Loading

0 comments on commit 241877e

Please sign in to comment.