mirror of
https://github.com/Qortal/qortal.git
synced 2025-05-07 10:17:51 +00:00
Minor code tidying
This commit is contained in:
parent
319bfc8d75
commit
6ba24e1820
@ -89,7 +89,7 @@ public class Block {
|
|||||||
|
|
||||||
public final int value;
|
public final int value;
|
||||||
|
|
||||||
private final static Map<Integer, ValidationResult> map = stream(ValidationResult.values()).collect(toMap(result -> result.value, result -> result));
|
private static final Map<Integer, ValidationResult> map = stream(ValidationResult.values()).collect(toMap(result -> result.value, result -> result));
|
||||||
|
|
||||||
ValidationResult(int value) {
|
ValidationResult(int value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
@ -237,7 +237,7 @@ public class Block {
|
|||||||
public Block(Repository repository, BlockData blockData, List<TransactionData> transactions, List<ATStateData> atStates) throws DataException {
|
public Block(Repository repository, BlockData blockData, List<TransactionData> transactions, List<ATStateData> atStates) throws DataException {
|
||||||
this(repository, blockData);
|
this(repository, blockData);
|
||||||
|
|
||||||
this.transactions = new ArrayList<Transaction>();
|
this.transactions = new ArrayList<>();
|
||||||
|
|
||||||
BigDecimal totalFees = BigDecimal.ZERO.setScale(8);
|
BigDecimal totalFees = BigDecimal.ZERO.setScale(8);
|
||||||
|
|
||||||
@ -327,7 +327,7 @@ public class Block {
|
|||||||
byte[] transactionsSignature = null;
|
byte[] transactionsSignature = null;
|
||||||
int height = parentBlockData.getHeight() + 1;
|
int height = parentBlockData.getHeight() + 1;
|
||||||
|
|
||||||
this.transactions = new ArrayList<Transaction>();
|
this.transactions = new ArrayList<>();
|
||||||
|
|
||||||
int atCount = 0;
|
int atCount = 0;
|
||||||
BigDecimal atFees = BigDecimal.ZERO.setScale(8);
|
BigDecimal atFees = BigDecimal.ZERO.setScale(8);
|
||||||
@ -471,7 +471,7 @@ public class Block {
|
|||||||
if (transactionsData.size() != this.blockData.getTransactionCount())
|
if (transactionsData.size() != this.blockData.getTransactionCount())
|
||||||
throw new IllegalStateException("Block's transactions from repository do not match block's transaction count");
|
throw new IllegalStateException("Block's transactions from repository do not match block's transaction count");
|
||||||
|
|
||||||
this.transactions = new ArrayList<Transaction>();
|
this.transactions = new ArrayList<>();
|
||||||
|
|
||||||
for (TransactionData transactionData : transactionsData)
|
for (TransactionData transactionData : transactionsData)
|
||||||
this.transactions.add(Transaction.fromData(this.repository, transactionData));
|
this.transactions.add(Transaction.fromData(this.repository, transactionData));
|
||||||
@ -520,7 +520,7 @@ public class Block {
|
|||||||
return this.cachedExpandedAccounts;
|
return this.cachedExpandedAccounts;
|
||||||
|
|
||||||
ConciseSet accountIndexes = BlockTransformer.decodeOnlineAccounts(this.blockData.getEncodedOnlineAccounts());
|
ConciseSet accountIndexes = BlockTransformer.decodeOnlineAccounts(this.blockData.getEncodedOnlineAccounts());
|
||||||
List<ExpandedAccount> expandedAccounts = new ArrayList<ExpandedAccount>();
|
List<ExpandedAccount> expandedAccounts = new ArrayList<>();
|
||||||
|
|
||||||
IntIterator iterator = accountIndexes.iterator();
|
IntIterator iterator = accountIndexes.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
@ -721,14 +721,12 @@ public class Block {
|
|||||||
byte[] idealKey = calcIdealGeneratorPublicKey(parentHeight, parentBlockSignature);
|
byte[] idealKey = calcIdealGeneratorPublicKey(parentHeight, parentBlockSignature);
|
||||||
byte[] perturbedKey = calcHeightPerturbedPublicKey(parentHeight + 1, publicKey);
|
byte[] perturbedKey = calcHeightPerturbedPublicKey(parentHeight + 1, publicKey);
|
||||||
|
|
||||||
BigInteger keyDistance = MAX_DISTANCE.subtract(new BigInteger(idealKey).subtract(new BigInteger(perturbedKey)).abs());
|
return MAX_DISTANCE.subtract(new BigInteger(idealKey).subtract(new BigInteger(perturbedKey)).abs());
|
||||||
return keyDistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BigInteger calcBlockWeight(int parentHeight, byte[] parentBlockSignature, BlockSummaryData blockSummaryData) {
|
public static BigInteger calcBlockWeight(int parentHeight, byte[] parentBlockSignature, BlockSummaryData blockSummaryData) {
|
||||||
BigInteger keyDistance = calcKeyDistance(parentHeight, parentBlockSignature, blockSummaryData.getGeneratorPublicKey());
|
BigInteger keyDistance = calcKeyDistance(parentHeight, parentBlockSignature, blockSummaryData.getGeneratorPublicKey());
|
||||||
BigInteger weight = BigInteger.valueOf(blockSummaryData.getOnlineAccountsCount()).shiftLeft(ACCOUNTS_COUNT_SHIFT).add(keyDistance);
|
return BigInteger.valueOf(blockSummaryData.getOnlineAccountsCount()).shiftLeft(ACCOUNTS_COUNT_SHIFT).add(keyDistance);
|
||||||
return weight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BigInteger calcChainWeight(int commonBlockHeight, byte[] commonBlockSignature, List<BlockSummaryData> blockSummaries) {
|
public static BigInteger calcChainWeight(int commonBlockHeight, byte[] commonBlockSignature, List<BlockSummaryData> blockSummaries) {
|
||||||
@ -767,7 +765,7 @@ public class Block {
|
|||||||
// Use power transform on ratio to spread out smaller values for bigger effect
|
// Use power transform on ratio to spread out smaller values for bigger effect
|
||||||
double transformed = Math.pow(ratio, blockTiming.power);
|
double transformed = Math.pow(ratio, blockTiming.power);
|
||||||
|
|
||||||
long timeOffset = Double.valueOf(blockTiming.deviation * 2.0 * transformed).longValue();
|
long timeOffset = (long) (blockTiming.deviation * 2.0 * transformed);
|
||||||
|
|
||||||
return parentBlockData.getTimestamp() + blockTiming.target - blockTiming.deviation + timeOffset;
|
return parentBlockData.getTimestamp() + blockTiming.target - blockTiming.deviation + timeOffset;
|
||||||
}
|
}
|
||||||
@ -953,44 +951,21 @@ public class Block {
|
|||||||
return onlineAccountsResult;
|
return onlineAccountsResult;
|
||||||
|
|
||||||
// CIYAM ATs
|
// CIYAM ATs
|
||||||
if (this.blockData.getATCount() != 0) {
|
ValidationResult ciyamAtResult = this.areAtsValid();
|
||||||
// Locally generated AT states should be valid so no need to re-execute them
|
if (ciyamAtResult != ValidationResult.OK)
|
||||||
if (this.ourAtStates != this.getATStates()) {
|
return ciyamAtResult;
|
||||||
// For old v1 CIYAM ATs we blindly accept them
|
|
||||||
if (this.blockData.getVersion() < 4) {
|
|
||||||
this.ourAtStates = this.atStates;
|
|
||||||
this.ourAtFees = this.blockData.getATFees();
|
|
||||||
} else {
|
|
||||||
// Generate local AT states for comparison
|
|
||||||
this.executeATs();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check locally generated AT states against ones received from elsewhere
|
|
||||||
|
|
||||||
if (this.ourAtStates.size() != this.blockData.getATCount())
|
|
||||||
return ValidationResult.AT_STATES_MISMATCH;
|
|
||||||
|
|
||||||
if (this.ourAtFees.compareTo(this.blockData.getATFees()) != 0)
|
|
||||||
return ValidationResult.AT_STATES_MISMATCH;
|
|
||||||
|
|
||||||
// Note: this.atStates fully loaded thanks to this.getATStates() call above
|
|
||||||
for (int s = 0; s < this.atStates.size(); ++s) {
|
|
||||||
ATStateData ourAtState = this.ourAtStates.get(s);
|
|
||||||
ATStateData theirAtState = this.atStates.get(s);
|
|
||||||
|
|
||||||
if (!ourAtState.getATAddress().equals(theirAtState.getATAddress()))
|
|
||||||
return ValidationResult.AT_STATES_MISMATCH;
|
|
||||||
|
|
||||||
if (!ourAtState.getStateHash().equals(theirAtState.getStateHash()))
|
|
||||||
return ValidationResult.AT_STATES_MISMATCH;
|
|
||||||
|
|
||||||
if (ourAtState.getFees().compareTo(theirAtState.getFees()) != 0)
|
|
||||||
return ValidationResult.AT_STATES_MISMATCH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check transactions
|
// Check transactions
|
||||||
|
ValidationResult transactionsResult = this.areTransactionsValid();
|
||||||
|
if (transactionsResult != ValidationResult.OK)
|
||||||
|
return transactionsResult;
|
||||||
|
|
||||||
|
// Block is valid
|
||||||
|
return ValidationResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether block's transactions are valid. */
|
||||||
|
private ValidationResult areTransactionsValid() throws DataException {
|
||||||
try {
|
try {
|
||||||
// Create repository savepoint here so we can rollback to it after testing transactions
|
// Create repository savepoint here so we can rollback to it after testing transactions
|
||||||
repository.setSavepoint();
|
repository.setSavepoint();
|
||||||
@ -1013,7 +988,7 @@ public class Block {
|
|||||||
|
|
||||||
// Check transaction has correct reference, etc.
|
// Check transaction has correct reference, etc.
|
||||||
if (!transaction.hasValidReference()) {
|
if (!transaction.hasValidReference()) {
|
||||||
LOGGER.debug("Error during transaction validation, tx " + Base58.encode(transactionData.getSignature()) + ": INVALID_REFERENCE");
|
LOGGER.debug(String.format("Error during transaction validation, tx %s: INVALID_REFERENCE", Base58.encode(transactionData.getSignature())));
|
||||||
return ValidationResult.TRANSACTION_INVALID;
|
return ValidationResult.TRANSACTION_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1021,16 +996,14 @@ public class Block {
|
|||||||
// NOTE: in Gen1 there was an extra block height passed to DeployATTransaction.isValid
|
// NOTE: in Gen1 there was an extra block height passed to DeployATTransaction.isValid
|
||||||
Transaction.ValidationResult validationResult = transaction.isValid();
|
Transaction.ValidationResult validationResult = transaction.isValid();
|
||||||
if (validationResult != Transaction.ValidationResult.OK) {
|
if (validationResult != Transaction.ValidationResult.OK) {
|
||||||
LOGGER.debug("Error during transaction validation, tx " + Base58.encode(transactionData.getSignature()) + ": "
|
LOGGER.debug(String.format("Error during transaction validation, tx %s: %s", Base58.encode(transactionData.getSignature()), validationResult.name()));
|
||||||
+ validationResult.name());
|
|
||||||
return ValidationResult.TRANSACTION_INVALID;
|
return ValidationResult.TRANSACTION_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check transaction can even be processed
|
// Check transaction can even be processed
|
||||||
validationResult = transaction.isProcessable();
|
validationResult = transaction.isProcessable();
|
||||||
if (validationResult != Transaction.ValidationResult.OK) {
|
if (validationResult != Transaction.ValidationResult.OK) {
|
||||||
LOGGER.debug("Error during transaction validation, tx " + Base58.encode(transactionData.getSignature()) + ": "
|
LOGGER.debug(String.format("Error during transaction validation, tx %s: %s", Base58.encode(transactionData.getSignature()), validationResult.name()));
|
||||||
+ validationResult.name());
|
|
||||||
return ValidationResult.TRANSACTION_INVALID;
|
return ValidationResult.TRANSACTION_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1044,8 +1017,7 @@ public class Block {
|
|||||||
// Regardless of group-approval, update relevant info for creator (e.g. lastReference)
|
// Regardless of group-approval, update relevant info for creator (e.g. lastReference)
|
||||||
transaction.processReferencesAndFees();
|
transaction.processReferencesAndFees();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error("Exception during transaction validation, tx " + Base58.encode(transactionData.getSignature()), e);
|
LOGGER.error(String.format("Exception during transaction validation, tx %s", Base58.encode(transactionData.getSignature())), e);
|
||||||
e.printStackTrace();
|
|
||||||
return ValidationResult.TRANSACTION_PROCESSING_FAILED;
|
return ValidationResult.TRANSACTION_PROCESSING_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1062,7 +1034,58 @@ public class Block {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block is valid
|
return ValidationResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether blocks' ATs are valid.
|
||||||
|
* <p>
|
||||||
|
* NOTE: will execute ATs locally if not already done.<br>
|
||||||
|
* This is so we have locally-generated AT states for comparison.
|
||||||
|
*
|
||||||
|
* @return OK, or some AT-related validation result
|
||||||
|
* @throws DataException
|
||||||
|
*/
|
||||||
|
private ValidationResult areAtsValid() throws DataException {
|
||||||
|
if (this.blockData.getATCount() == 0)
|
||||||
|
return ValidationResult.OK;
|
||||||
|
|
||||||
|
// Locally generated AT states should be valid so no need to re-execute them
|
||||||
|
if (this.ourAtStates == this.getATStates()) // Note object reference compare
|
||||||
|
return ValidationResult.OK;
|
||||||
|
|
||||||
|
// For old v1 CIYAM ATs we blindly accept them
|
||||||
|
if (this.blockData.getVersion() < 4) {
|
||||||
|
this.ourAtStates = this.atStates;
|
||||||
|
this.ourAtFees = this.blockData.getATFees();
|
||||||
|
} else {
|
||||||
|
// Generate local AT states for comparison
|
||||||
|
this.executeATs();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check locally generated AT states against ones received from elsewhere
|
||||||
|
|
||||||
|
if (this.ourAtStates.size() != this.blockData.getATCount())
|
||||||
|
return ValidationResult.AT_STATES_MISMATCH;
|
||||||
|
|
||||||
|
if (this.ourAtFees.compareTo(this.blockData.getATFees()) != 0)
|
||||||
|
return ValidationResult.AT_STATES_MISMATCH;
|
||||||
|
|
||||||
|
// Note: this.atStates fully loaded thanks to this.getATStates() call above
|
||||||
|
for (int s = 0; s < this.atStates.size(); ++s) {
|
||||||
|
ATStateData ourAtState = this.ourAtStates.get(s);
|
||||||
|
ATStateData theirAtState = this.atStates.get(s);
|
||||||
|
|
||||||
|
if (!ourAtState.getATAddress().equals(theirAtState.getATAddress()))
|
||||||
|
return ValidationResult.AT_STATES_MISMATCH;
|
||||||
|
|
||||||
|
if (!Arrays.equals(ourAtState.getStateHash(), theirAtState.getStateHash()))
|
||||||
|
return ValidationResult.AT_STATES_MISMATCH;
|
||||||
|
|
||||||
|
if (ourAtState.getFees().compareTo(theirAtState.getFees()) != 0)
|
||||||
|
return ValidationResult.AT_STATES_MISMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
return ValidationResult.OK;
|
return ValidationResult.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1091,9 +1114,9 @@ public class Block {
|
|||||||
throw new IllegalStateException("Attempted to execute ATs when block's local AT state data already exists");
|
throw new IllegalStateException("Attempted to execute ATs when block's local AT state data already exists");
|
||||||
|
|
||||||
// AT-Transactions generated by running ATs, to be prepended to block's transactions
|
// AT-Transactions generated by running ATs, to be prepended to block's transactions
|
||||||
List<AtTransaction> allATTransactions = new ArrayList<AtTransaction>();
|
List<AtTransaction> allATTransactions = new ArrayList<>();
|
||||||
|
|
||||||
this.ourAtStates = new ArrayList<ATStateData>();
|
this.ourAtStates = new ArrayList<>();
|
||||||
this.ourAtFees = BigDecimal.ZERO.setScale(8);
|
this.ourAtFees = BigDecimal.ZERO.setScale(8);
|
||||||
|
|
||||||
// Find all executable ATs, ordered by earliest creation date first
|
// Find all executable ATs, ordered by earliest creation date first
|
||||||
@ -1323,7 +1346,7 @@ public class Block {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// APPROVED, in which case do transaction.process();
|
// APPROVED, process transaction
|
||||||
transactionData.setApprovalStatus(ApprovalStatus.APPROVED);
|
transactionData.setApprovalStatus(ApprovalStatus.APPROVED);
|
||||||
transactionRepository.save(transactionData);
|
transactionRepository.save(transactionData);
|
||||||
|
|
||||||
@ -1376,7 +1399,7 @@ public class Block {
|
|||||||
transactionRepository.confirmTransaction(transactionData.getSignature());
|
transactionRepository.confirmTransaction(transactionData.getSignature());
|
||||||
|
|
||||||
List<Account> participants = transaction.getInvolvedAccounts();
|
List<Account> participants = transaction.getInvolvedAccounts();
|
||||||
List<String> participantAddresses = participants.stream().map(account -> account.getAddress()).collect(Collectors.toList());
|
List<String> participantAddresses = participants.stream().map(Account::getAddress).collect(Collectors.toList());
|
||||||
transactionRepository.saveParticipants(transactionData, participantAddresses);
|
transactionRepository.saveParticipants(transactionData, participantAddresses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ public class BlockChain {
|
|||||||
StreamSource jsonSource;
|
StreamSource jsonSource;
|
||||||
|
|
||||||
if (filename != null) {
|
if (filename != null) {
|
||||||
LOGGER.info("Using blockchain config file: " + path + filename);
|
LOGGER.info(String.format("Using blockchain config file: %s%s", path, filename));
|
||||||
|
|
||||||
File jsonFile = new File(path + filename);
|
File jsonFile = new File(path + filename);
|
||||||
|
|
||||||
@ -221,8 +221,8 @@ public class BlockChain {
|
|||||||
blockchain.validateConfig();
|
blockchain.validateConfig();
|
||||||
|
|
||||||
// Minor fix-up
|
// Minor fix-up
|
||||||
blockchain.maxBytesPerUnitFee.setScale(8);
|
blockchain.maxBytesPerUnitFee = blockchain.maxBytesPerUnitFee.setScale(8);
|
||||||
blockchain.unitFee.setScale(8);
|
blockchain.unitFee = blockchain.unitFee.setScale(8);
|
||||||
blockchain.minFeePerByte = blockchain.unitFee.divide(blockchain.maxBytesPerUnitFee, MathContext.DECIMAL32);
|
blockchain.minFeePerByte = blockchain.unitFee.divide(blockchain.maxBytesPerUnitFee, MathContext.DECIMAL32);
|
||||||
|
|
||||||
// Successfully read config now in effect
|
// Successfully read config now in effect
|
||||||
@ -509,8 +509,7 @@ public class BlockChain {
|
|||||||
|
|
||||||
repository.saveChanges();
|
repository.saveChanges();
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
LOGGER.warn("Repository issue trying to trim old online accounts signatures: " + e.getMessage());
|
LOGGER.warn(String.format("Repository issue trying to trim old online accounts signatures: %s", e.getMessage()));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user