Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR tries to implement fast finality mechanism introduced by BEP-126.
Abstract
BEP-126 Proposal describes a fast finality mechanism to finalize a block, once the block has been finalized, it won't be
reverted forever.
It takes several steps to finalize a block:
The finality of a block can be achieved within two blocks in most cases, this is expected to reduce the chance
of chain re-organization and stabilize the block producing further.
Motivation
Finality is critical for blockchain security, once the block is finalized, it would not be reverted anymore. The fast
finality feature is very useful, users can make sure they get the accurate information from the latest finalized block,
then they can decide what to do next instantly.
Currently, on BNB Smart chain, all the full nodes and validators need to wait until enough blocks have been produced
to ensure a probabilistic finality. According to the whitepaper, with 21 validators, full nodes and validators can
wait ⅔*21+1=15 blocks to ensure a relatively secure finality, it would be quite long time for some critical applications.
Specification
The vote message is signed by validators’ private key through the BLS algorithm, however the BLS private and public keys are different from traditional BSC/Ethereum account’s private and public keys, so use a new key manager to manage BLS related keys.
In order to collect the vote information, we use another vote pool to gather the votes from validators, this vote pool is similar to txpool but independent.
Validators can vote for blocks they received under the above three rules. Once the parent block’s votes in the vote pool are more than ⅔+ validators, the validator will aggregate the votes message and write them to the proposed block’s header when it proposes new blocks.
The block receivers, either full nodes or non-proposer validators, download the block from p2p node, verify the votes from valid validators and verify the BLS aggregated signature if exist, insert the block into the blockchain, write the new attestation info to the consensus snapshot, distribute reward in finalize function if reward requirements meet.
The slash related function is implemented in a stand alone slash contract, anyone can get a vote message from the vote pool, once they find the malicious behavior, they can submit the assembled evidence to slash contract, and slash contract will do the detailed verification and slash actions. The evidence format, verification procedure and slash actions will be designed in slash component design.
BLS and BLS Key Manager
BLS is used to sign the vote for fast finality, aggregate the votes from different validators, verify the signature from different validators and verify the aggregated signatures, in order to format the vote data, in our design, we sign the hash of the vote data, not the data itself.
Since the BLS private key and public key are different from current Ethereum accounts’ key, we introduce another key manager to manage the BLS private key and public key. The BLS key manager is designed to store the BLS private key, since the private key shouldn’t be stored as plain text to avoid leaking, we introduce BLS wallet, BLS key manager and BLS accounts here. Each account is a pair of BLS private key and BLS public key, it will be stored as an encrypted keystore Json file. There will be a singleton wallet while running the Geth client, the wallet can manage several BLS accounts, actually, we just need one account in general. Users can create a new account or import existing Json keystore accounts.
The BLS wallet is bound with a singleton key manager, through the key manager, we can get all the public keys in the BLS wallet, and once the validator needs to sign a vote, call the key manager’s sign method.
Vote Pool
The votepool is used to gather votes from different validators, propagating votes to other nodes. All active validators can vote for the fast finality of blocks under the above three rules, the vote data will be {SourceNumber, SourceHash, TargetNumber, TargetHash}. Validators use their BLS private key to sign the hash of the vote data, so the vote message is {BLSPubKey, {SourceNumber, SourceHash, TargetNumber, TargetHash}, Signature}, once the receivers see the vote message, they can verify it easily.
As we know propagating messages is the duty of P2P protocols, in order to propagate the vote message, we will define new message types based on current ETH67 protocol.
In order to finalize blocks, the miner should assemble the vote messages for the direct parent block once its valid votes have more than ⅔+ validators, and write them to the block header as an attestation. The assembled signature should be {ValidatorsIndexBitmap, {SourceNumber, SourceHash, TargetNumber, TargetHash}, AggregatedSignature}, the bitmap indicates the validators that voted for the block, aggregate their vote signatures into aggregated signature, the aggregated signature is the same length with each common signature.
Once the validators or full nodes receive a block, they should verify the block header, for this fast finality feature, they should verify the assembled attestation information.
As the consensus engine can get validators’ information from the snapshot, the BLS public key should be recorded as a part of validator, through the ValidatorsIndexBitmap we can easily get their BLS public keys, then we can use the BLS FastAggregateVerify function to verify the aggregated signature.
Reward
Distributing reward should be a part of the consensus engine, in order to make the consensus lighter, we would distribute the reward by batch, once an epoch. As the vote attestation has been recorded in the headers, so we can iterate the headers from the first block to the last block of the previous epoch, find out the attested blocks and which validators have voted for them.
Through the iteration, we can get two arrays {validators[], accumulatedWeights[]}, then call the distributeFinalityReward method of ValidatorSet contract and pass these two parameters.
The total reward for validators of this epoch would be a part balance of the SystemReward contract, the partial would be set to 10% initially and can be governed. Once we get the total reward, then distribute the total reward to each validator by the accumulatedWeights.
Slash
Anyone can get validators’ vote message from vote pool, if they find some validators’ vote message violate one of the rules described in BEP-126, they can assemble the evidence and submit to the slash contract, slash contract will verify the submitted evidence, once the evidence has been verified, the malicious validator will be slashed and the submitter will be rewarded.