ldpos-chain
Version:
LDPoS chain module
111 lines (102 loc) • 3.34 kB
JavaScript
const {
validateWalletAddress,
validateKeyIndex,
validateCount,
validateBlockId,
validatePublicKey,
validateTimestamp,
validateBlockHeight,
validateSignature
} = require('./primitives');
const { validateBlockSignatureSchema } = require('./block-signature-schema');
const { findInvalidProperty } = require('./find-invalid-property');
const validPropertyList = [
'id',
'height',
'timestamp',
'previousBlockId',
'numberOfTransactions',
'transactions',
'forgerAddress',
'forgingPublicKey',
'nextForgingPublicKey',
'nextForgingKeyIndex',
'forgerSignature',
'signatures'
];
function validateBlockSchema(block, minTransactionsPerBlock, maxTransactionsPerBlock, minSignatures, maxSignatures, networkSymbol) {
if (!block) {
throw new Error('Block was not specified');
}
validateBlockHeight('height', block);
validateTimestamp('timestamp', block);
if (block.previousBlockId != null) {
validateBlockId('previousBlockId', block);
}
if (!Array.isArray(block.transactions)) {
throw new Error('Block transactions must be an array');
}
if (block.transactions.length < minTransactionsPerBlock) {
throw new Error(
`Block did not contain enough transactions - Minimum allowed is ${minTransactionsPerBlock}`
);
}
if (block.transactions.length > maxTransactionsPerBlock) {
throw new Error(
`Block contained too many transactions - Maximum allowed is ${maxTransactionsPerBlock}`
);
}
validateCount('numberOfTransactions', block);
if (block.numberOfTransactions !== block.transactions.length) {
throw new Error(
`Block number of transactions count did not match the number of transactions in the block - Expected ${
block.transactions.length
}`
);
}
validateWalletAddress('forgerAddress', block, networkSymbol);
validateBlockId('id', block);
validatePublicKey('forgingPublicKey', block);
validatePublicKey('nextForgingPublicKey', block);
validateKeyIndex('nextForgingKeyIndex', block);
validateSignature('forgerSignature', block);
if (!Array.isArray(block.signatures)) {
throw new Error('Block signatures must be an array');
}
if (block.signatures.length > maxSignatures) {
throw new Error(
`Block contained more than the maximum number of ${maxSignatures} signatures`
);
}
let invalidProperty = findInvalidProperty(block, validPropertyList);
if (invalidProperty) {
throw new Error(
`Block had an invalid ${invalidProperty} property`
);
}
let signerSet = new Set();
for (let blockSignature of block.signatures) {
validateBlockSignatureSchema(blockSignature, networkSymbol);
if (blockSignature.signerAddress === block.forgerAddress) {
throw new Error(
`Block contained a second signature from the block forger ${block.forgerAddress}`
);
}
if (signerSet.has(blockSignature.signerAddress)) {
throw new Error(
`Block contained duplicate signatures`
);
}
signerSet.add(blockSignature.signerAddress);
}
if (signerSet.size < minSignatures) {
throw new Error(
`Block signatures did not refer to a sufficient number of unique signers - There were ${
signerSet.size
} signatures but ${minSignatures} were required`
);
}
}
module.exports = {
validateBlockSchema
};