Block processing includes block and transactions validation, verification and applying into the blockchain. Each step is an expensive operation and should be called only once for each block. As part of BFT, we execute these steps at different stages, and block processing should allow calling these functions independently.
process.js file only exports applyBlock and processBlock functions which encapsulate all the work related to validating, verifying and applying a block. It does not allow executing these steps separately.
feature/introduce_bft_consensus
This could be a way of implementing this based on the steps defined in the section Processing Blocks of LIP-0014:
async _validateAndVerifyInMemory(block, lastBlock, broadcast) {
const enhancedBlock = !broadcast
? blocksUtils.addBlockProperties(block)
: block;
const normalizedBlock = blocksLogic.objectNormalize(
enhancedBlock,
this.exceptions
);
const { verified, errors } = this.blocksVerify.verifyBlock(
normalizedBlock,
lastBlock
);
await this.blocksVerify.validateBlockSlot(normalizedBlock);
}
async _verifyBlockAgainsState() {
await this.blocksVerify.checkExists(normalizedBlock); // Step 4
await this.blocksVerify.checkTransactions(normalizedBlock); // Step 4
}
async processValidatedBlock(block, lastBlock, broadcast) {
this.BFTConsensusManager.validateBlockHeader(block); //Step 2
if (typeof broadcast === 'function') {
broadcast(normalizedBlock); // Step3
}
await this.verifyBlockAgainsState(); // Step4
await this.blocksChain.applyBlock(normalizedBlock, true); // Step 5
this.BFTConsensusManager.addBlockHeader(
normalizedBlock
); // Step 6: Compute prevotes and precommits
this.channel.publish('chain:blocks:processing:succeeded', {
block: {
id: block.id,
height: block.height,
heightPrevoted: block.heightPrevoted
}
});
return normalizedBlock;
}
async processBlock(block, lastBlock, broadcast) {
const validatedVerifiedBlock = this._validateAndVerifyInMemory(block, lastBlock); // Step 1
this.processValidatedBlock(validatedVerifiedBlock, lastBlock, broadcast);
}
While at this I would also encapsulate this methods in different objects so we can switch between different processing models on the fly.
Absolutely, something like blocks processing v2 having processV2.js or similar to achieve what Pablo said.
Absolutely, something like
blocks processing v2having processV2.js or similar to achieve what Pablo said.
Check this out https://github.com/pablitovicente/random_experiments/tree/master/strategy_test (gist does not support folders so I just created a repo but we can move somewhere else :) )
processBlocks funciton does everything that applyBlock function does. So, can we get rid of applyBlock @SargeKhan ?
Most helpful comment
While at this I would also encapsulate this methods in different objects so we can switch between different processing models on the fly.