|
|
@ -74,6 +74,7 @@ public class Block { |
|
|
|
TIMESTAMP_OLDER_THAN_PARENT(20), |
|
|
|
TIMESTAMP_OLDER_THAN_PARENT(20), |
|
|
|
TIMESTAMP_IN_FUTURE(21), |
|
|
|
TIMESTAMP_IN_FUTURE(21), |
|
|
|
TIMESTAMP_MS_INCORRECT(22), |
|
|
|
TIMESTAMP_MS_INCORRECT(22), |
|
|
|
|
|
|
|
TIMESTAMP_TOO_SOON(23), |
|
|
|
VERSION_INCORRECT(30), |
|
|
|
VERSION_INCORRECT(30), |
|
|
|
FEATURE_NOT_YET_RELEASED(31), |
|
|
|
FEATURE_NOT_YET_RELEASED(31), |
|
|
|
GENERATING_BALANCE_INCORRECT(40), |
|
|
|
GENERATING_BALANCE_INCORRECT(40), |
|
|
@ -207,21 +208,35 @@ public class Block { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
long timestamp = parentBlock.calcNextBlockTimestamp(version, generatorSignature, generator); |
|
|
|
long timestamp = parentBlock.calcNextBlockTimestamp(version, generatorSignature, generator); |
|
|
|
|
|
|
|
long maximumTimestamp = parentBlock.getBlockData().getTimestamp() + BlockChain.getInstance().getMaxBlockTime(); |
|
|
|
|
|
|
|
if (timestamp > maximumTimestamp) |
|
|
|
|
|
|
|
timestamp = maximumTimestamp; |
|
|
|
|
|
|
|
|
|
|
|
int transactionCount = 0; |
|
|
|
int transactionCount = 0; |
|
|
|
byte[] transactionsSignature = null; |
|
|
|
byte[] transactionsSignature = null; |
|
|
|
int height = parentBlockData.getHeight() + 1; |
|
|
|
int height = parentBlockData.getHeight() + 1; |
|
|
|
|
|
|
|
|
|
|
|
this.executeATs(); |
|
|
|
this.transactions = new ArrayList<Transaction>(); |
|
|
|
|
|
|
|
|
|
|
|
int atCount = this.ourAtStates.size(); |
|
|
|
int atCount = 0; |
|
|
|
BigDecimal atFees = this.ourAtFees; |
|
|
|
BigDecimal atFees = BigDecimal.ZERO.setScale(8); |
|
|
|
BigDecimal totalFees = atFees; |
|
|
|
BigDecimal totalFees = atFees; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This instance used for AT processing
|
|
|
|
this.blockData = new BlockData(version, reference, transactionCount, totalFees, transactionsSignature, height, timestamp, generatingBalance, |
|
|
|
this.blockData = new BlockData(version, reference, transactionCount, totalFees, transactionsSignature, height, timestamp, generatingBalance, |
|
|
|
generator.getPublicKey(), generatorSignature, atCount, atFees); |
|
|
|
generator.getPublicKey(), generatorSignature, atCount, atFees); |
|
|
|
|
|
|
|
|
|
|
|
this.transactions = new ArrayList<Transaction>(); |
|
|
|
// Requires this.blockData and this.transactions, sets this.ourAtStates and this.ourAtFees
|
|
|
|
|
|
|
|
this.executeATs(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
atCount = this.ourAtStates.size(); |
|
|
|
this.atStates = this.ourAtStates; |
|
|
|
this.atStates = this.ourAtStates; |
|
|
|
|
|
|
|
atFees = this.ourAtFees; |
|
|
|
|
|
|
|
totalFees = atFees; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Rebuild blockData using post-AT-execute data
|
|
|
|
|
|
|
|
this.blockData = new BlockData(version, reference, transactionCount, totalFees, transactionsSignature, height, timestamp, generatingBalance, |
|
|
|
|
|
|
|
generator.getPublicKey(), generatorSignature, atCount, atFees); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Getters/setters
|
|
|
|
// Getters/setters
|
|
|
@ -681,6 +696,10 @@ public class Block { |
|
|
|
if (this.blockData.getTimestamp() % 1000 != parentBlockData.getTimestamp() % 1000) |
|
|
|
if (this.blockData.getTimestamp() % 1000 != parentBlockData.getTimestamp() % 1000) |
|
|
|
return ValidationResult.TIMESTAMP_MS_INCORRECT; |
|
|
|
return ValidationResult.TIMESTAMP_MS_INCORRECT; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Too early to forge block?
|
|
|
|
|
|
|
|
if (this.blockData.getTimestamp() < parentBlock.getBlockData().getTimestamp() + BlockChain.getInstance().getMinBlockTime()) |
|
|
|
|
|
|
|
return ValidationResult.TIMESTAMP_TOO_SOON; |
|
|
|
|
|
|
|
|
|
|
|
// Check block version
|
|
|
|
// Check block version
|
|
|
|
if (this.blockData.getVersion() != parentBlock.getNextBlockVersion()) |
|
|
|
if (this.blockData.getVersion() != parentBlock.getNextBlockVersion()) |
|
|
|
return ValidationResult.VERSION_INCORRECT; |
|
|
|
return ValidationResult.VERSION_INCORRECT; |
|
|
@ -691,7 +710,9 @@ public class Block { |
|
|
|
if (this.blockData.getGeneratingBalance().compareTo(parentBlock.calcNextBlockGeneratingBalance()) != 0) |
|
|
|
if (this.blockData.getGeneratingBalance().compareTo(parentBlock.calcNextBlockGeneratingBalance()) != 0) |
|
|
|
return ValidationResult.GENERATING_BALANCE_INCORRECT; |
|
|
|
return ValidationResult.GENERATING_BALANCE_INCORRECT; |
|
|
|
|
|
|
|
|
|
|
|
// Check generator is allowed to forge this block at this time
|
|
|
|
// After maximum block period, then generator checks are relaxed
|
|
|
|
|
|
|
|
if (this.blockData.getTimestamp() < parentBlock.getBlockData().getTimestamp() + BlockChain.getInstance().getMaxBlockTime()) { |
|
|
|
|
|
|
|
// Check generator is allowed to forge this block
|
|
|
|
BigInteger hashValue = this.calcBlockHash(); |
|
|
|
BigInteger hashValue = this.calcBlockHash(); |
|
|
|
BigInteger target = parentBlock.calcGeneratorsTarget(this.generator); |
|
|
|
BigInteger target = parentBlock.calcGeneratorsTarget(this.generator); |
|
|
|
|
|
|
|
|
|
|
@ -708,6 +729,7 @@ public class Block { |
|
|
|
// Each second elapsed allows generator to test a new "target" window against hashValue
|
|
|
|
// Each second elapsed allows generator to test a new "target" window against hashValue
|
|
|
|
if (hashValue.compareTo(lowerTarget) < 0) |
|
|
|
if (hashValue.compareTo(lowerTarget) < 0) |
|
|
|
return ValidationResult.GENERATOR_NOT_ACCEPTED; |
|
|
|
return ValidationResult.GENERATOR_NOT_ACCEPTED; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// CIYAM ATs
|
|
|
|
// CIYAM ATs
|
|
|
|
if (this.blockData.getATCount() != 0) { |
|
|
|
if (this.blockData.getATCount() != 0) { |
|
|
@ -720,6 +742,8 @@ public class Block { |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// Generate local AT states for comparison
|
|
|
|
// Generate local AT states for comparison
|
|
|
|
this.executeATs(); |
|
|
|
this.executeATs(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// XXX do we need to revalidate signatures if transactions list has changed?
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Check locally generated AT states against ones received from elsewhere
|
|
|
|
// Check locally generated AT states against ones received from elsewhere
|
|
|
|