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 17, 2019
1 parent 27b2048 commit 8cc7519
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 60 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,15 @@
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.AionPOWRule;
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 All @@ -44,6 +47,7 @@
import org.aion.zero.impl.valid.AionExtraDataRule;
import org.aion.zero.impl.valid.AionHeaderVersionRule;
import org.aion.zero.impl.valid.EnergyConsumedRule;
import org.aion.zero.impl.valid.EquihashSolutionRule;
import org.aion.zero.impl.valid.TXValidator;
import org.aion.zero.impl.types.A0BlockHeader;
import org.apache.commons.lang3.tuple.Pair;
Expand Down Expand Up @@ -343,15 +347,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
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import java.util.List;
import org.slf4j.Logger;

public class AbstractBlockHeaderValidator {
class AbstractBlockHeaderValidator {

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

if (logger.isErrorEnabled()) {
Expand Down
34 changes: 26 additions & 8 deletions modAionImpl/src/org/aion/zero/impl/valid/BlockHeaderValidator.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
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 {

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");
logErrors(logger, 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) {
logErrors(logger, errors);
}
return false;
}
}
}
return true;
Expand Down
6 changes: 6 additions & 0 deletions modAionImpl/src/org/aion/zero/impl/valid/BlockNumberRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ public boolean validate(BlockHeader header, BlockHeader parent, List<RuleError>
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,7 +4,7 @@
import org.aion.mcf.blockchain.BlockHeader;

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

/**
* Validates a dependant rule, where {@code header} represents the current block, and {@code
Expand All @@ -13,7 +13,6 @@ public abstract class DependentBlockHeaderRule {
*/
public abstract boolean validate(BlockHeader header, BlockHeader dependency, List<RuleError> errors);

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

}
6 changes: 6 additions & 0 deletions modAionImpl/src/org/aion/zero/impl/valid/EnergyLimitRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,10 @@ public boolean validate(BlockHeader header, BlockHeader parent, List<RuleError>
}
return true;
}

@Override
public boolean validate(
BlockHeader header, BlockHeader dependency, List<RuleError> errors, Object arg) {
return validate(header, dependency, errors);
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,52 @@
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 GrandParentBlockHeaderValidator
extends AbstractBlockHeaderValidator {
public class GrandParentBlockHeaderValidator extends AbstractBlockHeaderValidator {

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

public GrandParentBlockHeaderValidator(List<GrandParentDependantBlockHeaderRule> rules) {
this.rules = rules;
public GrandParentBlockHeaderValidator(
Map<Byte, List<GrandParentDependantBlockHeaderRule>> rules) {
if (rules == null) {
throw new NullPointerException();
}
chainRules = rules;
}

public boolean validate(BlockHeader grandParent, BlockHeader parent, BlockHeader current, Logger logger) {
List<RuleError> errors = new LinkedList<>();
public boolean validate(
BlockHeader grandParent, BlockHeader parent, BlockHeader current, Logger logger) {
if (parent == null) {
RuleError err = new RuleError(this.getClass(),"the input parent header is null");
logErrors(logger, Collections.singletonList(err));
return false;
}

if (current == null) {
RuleError err = new RuleError(this.getClass(),"the input header is null");
logErrors(logger, Collections.singletonList(err));
return false;
}

List<GrandParentDependantBlockHeaderRule> rules = chainRules.get(current.getSealType().getSealId());

for (GrandParentDependantBlockHeaderRule rule : rules) {
if (!rule.validate(grandParent, parent, current, errors)) {
if (logger != null) logErrors(logger, errors);
return false;
if (rules == null) {
return false;
} else {
List<RuleError> errors = new LinkedList<>();
for (GrandParentDependantBlockHeaderRule rule : rules) {
if (!rule.validate(grandParent, parent, current, errors)) {
if (logger != null) logErrors(logger, errors);
return false;
}
}
}

return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import java.util.List;
import org.aion.mcf.blockchain.BlockHeader;

public abstract class GrandParentDependantBlockHeaderRule
extends AbstractValidRule {
public abstract class GrandParentDependantBlockHeaderRule extends AbstractValidRule {

/**
* A separate class of rules that infer a relationship between the current block, the block
* preceding (parent) and the block preceding that block (grandparent)
*/
public abstract boolean validate(BlockHeader grandParent, BlockHeader parent, BlockHeader current, List<RuleError> errors);
public abstract boolean validate(
BlockHeader grandParent,
BlockHeader parent,
BlockHeader current,
List<RuleError> errors);
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,59 @@
package org.aion.zero.impl.valid;

import java.util.Collection;
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;

/** validation rules depending on parent's block header */
public class ParentBlockHeaderValidator
extends AbstractBlockHeaderValidator {
public class ParentBlockHeaderValidator extends AbstractBlockHeaderValidator {

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

public ParentBlockHeaderValidator(List<DependentBlockHeaderRule> rules) {
this.rules = rules;
public ParentBlockHeaderValidator(Map<Byte, List<DependentBlockHeaderRule>> rules) {
if (rules == null) {
throw new NullPointerException();
}
chainRules = rules;
}

public boolean validate(BlockHeader header, BlockHeader parent, Logger logger) {
List<RuleError> errors = new LinkedList<>();
return validate(header, parent, logger, null);
}

public boolean validate(
BlockHeader header, BlockHeader parent, Logger logger, Object extraArg) {
if (header == null) {
RuleError err = new RuleError(this.getClass(),"the input header is null");
logErrors(logger, Collections.singletonList(err));
return false;
}

for (DependentBlockHeaderRule rule : rules) {
if (!rule.validate(header, parent, errors)) {
if (logger != null) logErrors(logger, errors);
return false;
if (parent == null) {
RuleError err = new RuleError(this.getClass(),"the input parent header is null");
logErrors(logger, Collections.singletonList(err));
return false;
}

List<DependentBlockHeaderRule> rules = chainRules.get(header.getSealType().getSealId());

if (rules == null) {
return false;
} else {
List<RuleError> errors = new LinkedList<>();
for (DependentBlockHeaderRule rule : rules) {
if (!rule.validate(header, parent, errors, extraArg)) {
if (logger != null) {
logErrors(logger, errors);
}
return false;
}
}
}

return true;
}
}
Loading

0 comments on commit 8cc7519

Please sign in to comment.