Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BEP-126: Introduce Fast Finality Mechanism #2

Closed
wants to merge 221 commits into from
Closed

Conversation

NashBC
Copy link

@NashBC NashBC commented Apr 20, 2022

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:

  1. A block is proposed by a validator and propagated to other validators.
  2. Validators use their BLS private key to sign for the block as a vote message.
  3. Gather the votes from validators into a pool.
  4. Aggregate the BLS signature if its direct parent block has gotten enough votes when proposing a new block.
  5. Set the aggregated vote attestation into the extra field of the new block's header.
  6. Validators and full nodes who received the new block with the direct parent block's attestation can justify the direct parent block.
  7. If there are two continuous blocks have been justified, then the previous one is finalized.

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.

@NashBC NashBC force-pushed the fast_finality branch 6 times, most recently from 8d1b513 to b580ff5 Compare April 24, 2022 03:34
cmd/geth/blsaccountcmd.go Outdated Show resolved Hide resolved
consensus/parlia/parlia.go Outdated Show resolved Hide resolved
consensus/parlia/parlia.go Outdated Show resolved Hide resolved
consensus/parlia/parlia.go Show resolved Hide resolved
consensus/parlia/parlia.go Show resolved Hide resolved
consensus/parlia/parlia_test.go Show resolved Hide resolved
consensus/parlia/parlia_test.go Outdated Show resolved Hide resolved
consensus/parlia/snapshot.go Outdated Show resolved Hide resolved
console/console_test.go Outdated Show resolved Hide resolved
eth/handler_eth_test.go Outdated Show resolved Hide resolved
eth/handler.go Outdated Show resolved Hide resolved
eth/handler.go Outdated Show resolved Hide resolved
eth/handler.go Outdated Show resolved Hide resolved
eth/backend.go Outdated Show resolved Hide resolved
node/config.go Outdated Show resolved Hide resolved
eth/backend.go Outdated Show resolved Hide resolved
consensus/consensus.go Outdated Show resolved Hide resolved
consensus/parlia/parlia.go Outdated Show resolved Hide resolved
core/vote/vote_pool.go Show resolved Hide resolved
core/vote/vote_pool.go Outdated Show resolved Hide resolved
core/vote/vote_pool.go Show resolved Hide resolved
core/vote/vote_pool.go Outdated Show resolved Hide resolved
core/vote/vote_pool.go Outdated Show resolved Hide resolved
@NashBC NashBC changed the title [WIP] BEP-126: Introduce Fast Finality Mechanism [R4R] BEP-126: Introduce Fast Finality Mechanism Apr 27, 2022
core/types/vote.go Outdated Show resolved Hide resolved
core/types/vote.go Outdated Show resolved Hide resolved
@@ -22,16 +22,18 @@ import (
"errors"
"math/big"

//lint:ignore SA1019 Needed for precompile
Copy link

@worldisreal worldisreal Apr 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sort imports

params/config.go Outdated Show resolved Hide resolved
NathanBSC and others added 28 commits March 16, 2023 15:13
fix vote attestation security flaw and enable new fork choice rule after Lynn fork
update depended version of btcd to v2.3.2 from v0.2x
enhance GetBlockByNumber by supporting 'safe' and 'finalized', following Geth
upgrade: update `BonehUpgrade` system contracts code
…-more-votes-than-needed

distribute additional reward for collecting redundant votes
@ghost
Copy link

ghost commented Oct 20, 2023

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:

  1. A block is proposed by a validator and propagated to other validators.
  2. Validators use their BLS private key to sign for the block as a vote message.
  3. Gather the votes from validators into a pool.
  4. Aggregate the BLS signature if its direct parent block has gotten enough votes when proposing a new block.
  5. Set the aggregated vote attestation into the extra field of the new block's header.
  6. Validators and full nodes who received the new block with the direct parent block's attestation can justify the direct parent block.
  7. If there are two continuous blocks have been justified, then the previous one is finalized.

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.

@NathanBSC NathanBSC closed this Aug 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.