-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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
Istanbul Byzantine Fault Tolerance #650
Comments
Fantastic work, guys! |
Great work!
Can you explain when block insertion might fail? I'm struggling to see why block insertion would ever fail for a valid proposal.
Why not just accept zero-gasprice transactions?
Have you tried running the network with >=1/3 faulty nodes? If so, what does the result look like; what kinds of failures do you see in practice? |
Thanks @vbuterin
Before actually inserting the block into the chain, the consensus only validates the block header. Inserting will do more checks so it can fail with other reasons.
You're right. We've updated the EIP according.
Yes.
|
Theoretically it's also possible to finalize two conflicting blocks, if the proposer is one of the Byzantine nodes and makes two proposals and each get 2/3 prepares+commits. Though I guess that's fairly unlikely to happen in practice and so won't appear in that many random tests. |
I know the meaning of block validity, but outside the PoW this is a little bit ambiguous. |
pervious -> previous I like the structure, but for someone not accustomed to the terminology, |
Yes, I think you are right. Suppose there are f+1 faulty nodes, f+f good nodes, and the propose is among the faulty nodes. The proposer can send first f good nodes A block and second f good nodes B block. Then both groups can receive 2f+1 of prepares+commits for block A and B respectively. Thus two conflicting blocks can be finalized.
Each validator puts @ice09 |
Great! I was a little confuse through Valid block and Consensus Proof, your response is helpful also for the meaning of validation in Clique. Thank you. |
Can you clarify when this timer starts? Is there one timer for the whole round, like in PBFT (well, in PBFT the timer starts once the client request is received), or is there a new timer at each phase (pre-prepared, prepared, etc.) as the figure seems to suggest? Unless there is additional mechanism not described above (or perhaps I am just missing something), I think this protocol may have safety issues across round changes, as there does not seem to be anything stopping validators from committing a new block in a new round after others have committed in the previous round. This is what the "locking" mechanism in Tendermint addresses. In PBFT it's handled by broadcasting much more information during the round change. When you "blockchainify" PBFT, you can do away with this extra information if you're careful to introduce something like Tendermint's locking mechanism. I suspect that if you address these issues, you will end up with a protocol that is roughly identical (if not exactly identical) to Tendermint. Happy to discuss further and collaborate on this - great initiative! |
Yes, there is only one timer which is reset/triggered in every beginning of a new round.
Yes, in some extreme cases there might be safety issues. For example, say there is only one validator which receives |
Sticky proposer seems like it would be able to submit empty blocks or censorship transactions if it never passed through the RoundChange state. As long as they submit valid blocks, they can hold their Proposer role indefinitely. |
Seems like a strong claim considering there is no penalty to being a faulty node (e.g. voting on multiple forks) |
Yes, sticky proposer policy can lead to this issue. We've listed "faulty propose detection" in the remaining tasks section aiming to resolve it. One possible way is to switch to round robin policy whenever a validator sees an empty block. However, sticky proposer can still hack it by generating very small block every round.
Detecting faulty node deterministically is hard which makes penalize faulty nodes even harder. For simplicity, this PR doesn't dive into this topic. It might be worth looking in the follow up EIP and research. |
Awesome work! Can you give us a sense of performance benchmark in terms of throughput and latency? Thanks! |
In our preliminary testing result with 4 validators setup, the consensus time took around 10ms ~ 100ms, depending on how many transactions per block. In our testing, we allow each block to contain up to 2000 transactions. |
Update: 68cbcf
|
Is there any way to keep the nodekey (account private key) secured? Seems like it's left there unencrypted. |
Update: 0f066fb
|
Great work on developing Istanbul! One comment on "Does it still make sense to use gas?" I've developed a testnet (using Ethermint) and modified the client to not charge gas. I wanted to bounce this idea of others to see whether this it is valid... To avoid the infinite loop problem, the validators ensure the that smart contracts being published to the blockchain are sent from a small set of white-listed accounts. These accounts are trusted by the consortium to only publish smart contracts that have gone through a strict review process. I suppose in the extreme edge case that a computationally expensive slipped through and was published by mistake, then the validators stop and rollback to before the event. Does this sound reasonable? Appreciate any feedback on the faults with such an implementation. Thanks. |
The current implementation (as found in Quorum) breaks the concept of the "pending" block, used in several calls, but most notably in In Ethereum, the pending block means the latest confirmed block + all pending transactions the node is aware of. This means that directly after a transaction is sent to the node (through RPC), the transaction count (aka nonce) in the "pending" block is increased. A lot of tools, like abigen in this repo or any other tool where tx signing occurs at the application level instead of in geth, rely on this for making multiple transactions at once. After the first one, the result of With the current implementation of Istanbul, the definition of the "pending block" seem to be different. When submitting a transaction, the result for So this seems to mean that the "pending block" definition changed from "latest block + pending txs" to "the block that is currently being voted on". I consider this a bug; if this is done on purpose, it breaks with a lot of existing applications (all users of abigen, f.e.) and should be reconsidered. I originally reported about this issue in the Quorum repo, but there doesn't seem to be a good place to report bugs in Istanbul other than here. |
I'm sorry to disrupt the technical discussion here with a non-technical question: What is the intention for including this in the EIP repository? In particular I was wondering: (1) Is this proposal seeking public protocol adoption (it seems private chain focused, really at extending |
Hi, sorry, I would like to see if someone could give me details about the IBFT consensus mode. For example, if in each round IBFT chooses a random node as proposer? and also if IBFT chooses which nodes participate in each round or if it works with all nodes? |
Hi @RauleHernandeza, The node to be chosen as a proposer cannot be random it is deterministic. Proposer selection policy can either use a robin approach or use a sticky proposer. Which nodes participate in a round is determined by the voting process, so all nodes will use the same set of nodes for the validators for in a round. The "Validator list voting" section goes into more detail how this works. |
First of all thank you for answering my question. Now why can't you choose nodes randomly? you say that because it is not implemented? And secondly where can I see the index of sections? I was given the link to the repository but I still don't know how to guide me through it. I want to take a look at the Validator list voting. |
Hi @RauleHernandeza, Choosing random nodes is not implemented or part of the IBFT EIP. The validator list voting section I'm referring to is the "Validator list voting" heading in this issue which has some more details. |
Hello, how do you choose the proponent ?, and in the round participate all the nodes of the network? |
How do the round robin and sticky proponent methods work?, |
at what point do the validator nodes vote to remove or add a validator node to the network? |
@robertox186 the list of validators changes whit the transition block (epoch change) |
that is, not all nodes participate in the round? |
at what time do you vote to add or remove a node? |
@robertox186 for each non-epoch transition block, signers may cast one vote proposing a change in the validators list. Actually I need to correct myself, indeed IF a certain vote proposal reaches consensus it comes to effect immediately (you do not have to wait for epoch termination). Only the validator nodes participate in consensus rounds. |
the out of time that can happen in the diagram always take the same time? the default is always 10000 milliseconds? |
How does ibft pay the stake to the nodes? |
Good, how does ibft pay the stake and if you can tell me what part of the code it is in, also with the update of the validator lists? |
There has been no activity on this issue for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review. |
This issue was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment. |
Change log:
extraData
tools.Pull request
ethereum/go-ethereum#14674
Istanbul byzantine fault tolerant consensus protocol
Note, this work is deeply inspired by Clique POA. We've tried to design as similar a mechanism as possible in the protocol layer, such as with validator voting. We've also followed its EIP style of putting the background and rationale behind the proposed consensus protocol to help developers easily find technical references. This work is also inspired by Hyperledger's SBFT, Tendermint, HydraChain, and NCCU BFT.
Terminology
Consensus
Istanbul BFT is inspired by Castro-Liskov 99 paper. However, the original PBFT needed quite a bit of tweaking to make it work with blockchain. First off, there is no specific "client" which sends out requests and waits for the results. Instead, all of the validators can be seen as clients. Furthermore, to keep the blockchain progressing, a proposer will be continuously selected in each round to create block proposal for consensus. Also, for each consensus result, we expect to generate a verifiable new block rather than a bunch of read/write operations to the file system.
Istanbul BFT inherits from the original PBFT by using 3-phase consensus,
PRE-PREPARE
,PREPARE
, andCOMMIT
. The system can tolerate at most ofF
faulty nodes in aN
validator nodes network, whereN = 3F + 1
. Before each round, the validators will pick one of them as the proposer, by default, in a round robin fashion. The proposer will then propose a new block proposal and broadcast it along with thePRE-PREPARE
message. Upon receiving thePRE-PREPARE
message from the proposer, validators enter the state ofPRE-PREPARED
and then broadcastPREPARE
message. This step is to make sure all validators are working on the same sequence and the same round. While receiving2F + 1
ofPREPARE
messages, the validator enters the state ofPREPARED
and then broadcastsCOMMIT
message. This step is to inform its peers that it accepts the proposed block and is going to insert the block to the chain. Lastly, validators wait for2F + 1
ofCOMMIT
messages to enterCOMMITTED
state and then insert the block to the chain.Blocks in Istanbul BFT protocol are final, which means that there are no forks and any valid block must be somewhere in the main chain. To prevent a faulty node from generating a totally different chain from the main chain, each validator appends
2F + 1
receivedCOMMIT
signatures toextraData
field in the header before inserting it into the chain. Thus blocks are self-verifiable and light client can be supported as well. However, the dynamicextraData
would cause an issue on block hash calculation. Since the same block from different validators can have different set ofCOMMIT
signatures, the same block can have different block hashes as well. To solve this, we calculate the block hash by excluding theCOMMIT
signatures part. Therefore, we can still keep the block/block hash consistency as well as put the consensus proof in the block header.Consensus states
Istanbul BFT is a state machine replication algorithm. Each validator maintains a state machine replica in order reach block consensus.
States:
NEW ROUND
: Proposer to send new block proposal. Validators wait forPRE-PREPARE
message.PRE-PREPARED
: A validator has receivedPRE-PREPARE
message and broadcastsPREPARE
message. Then it waits for2F + 1
ofPREPARE
orCOMMIT
messages.PREPARED
: A validator has received2F + 1
ofPREPARE
messages and broadcastsCOMMIT
messages. Then it waits for2F + 1
ofCOMMIT
messages.COMMITTED
: A validator has received2F + 1
ofCOMMIT
messages and is able to insert the proposed block into the blockchain.FINAL COMMITTED
: A new block is successfully inserted into the blockchain and the validator is ready for the next round.ROUND CHANGE
: A validator is waiting for2F + 1
ofROUND CHANGE
messages on the same proposed round number.State transitions:
NEW ROUND
->PRE-PREPARED
:PRE-PREPARED
state.PRE-PREPARED
upon receiving thePRE-PREPARE
message with the following conditions:PREPARE
message to other validators.PRE-PREPARED
->PREPARED
:2F + 1
of validPREPARE
messages to enterPREPARED
state. Valid messages conform to the following conditions:COMMIT
message upon enteringPREPARED
state.PREPARED
->COMMITTED
:2F + 1
of validCOMMIT
messages to enterCOMMITTED
state. Valid messages conform to the following conditions:COMMITTED
->FINAL COMMITTED
:2F + 1
commitment signatures toextraData
and tries to insert the block into the blockchain.FINAL COMMITTED
state when insertion succeeds.FINAL COMMITTED
->NEW ROUND
:Round change flow
ROUND CHANGE
:PREPREPARE
message.ROUND CHANGE
message along with the proposed round number and waits forROUND CHANGE
messages from other validators. The proposed round number is selected based on following condition:ROUND CHANGE
messages from its peers, it picks the largest round number which hasF + 1
ofROUND CHANGE
messages.1 + current round number
as the proposed round number.F + 1
ofROUND CHANGE
messages on the same proposed round number, it compares the received one with its own. If the received is larger, the validator broadcastsROUND CHANGE
message again with the received number.2F + 1
ofROUND CHANGE
messages on the same proposed round number, the validator exits the round change loop, calculates the new proposer, and then entersNEW ROUND
state.Proposer selection
Currently we support two policies: round robin and sticky proposer.
Validator list voting
We use a similar validator voting mechanism as Clique and copy most of the content from Clique EIP. Every epoch transaction resets the validator voting, meaning if an authorization or de-authorization vote is still in progress, that voting process will be terminated.
For all transactions blocks:
VALIDATOR_LIMIT
come into effect immediately.Future message and backlog
In an asynchronous network environment, one may receive future messages which cannot be processed in the current state. For example, a validator can receive
COMMIT
messages onNEW ROUND
. We call this kind of message a "future message." When a validator receives a future message, it will put the message into its backlog and try to process later whenever possible.Optimization
To speed up the consensus process, a validator that received
2F + 1
ofCOMMIT
messages prior to receiving2F + 1
ofPREPARE
message will jump to theCOMMITTED
state so that it is not necessary to wait for furtherPREPARE
messages.Constants
We define the following constants:
EPOCH_LENGTH
: Number of blocks after which to checkpoint and reset the pending votes.30000
for the testnet to remain analogous to the main netethash
epoch.REQUEST_TIMEOUT
: Timeout for each consensus round before firing a round change in millisecond.BLOCK_PERIOD
: Minimum timestamp difference in seconds between two consecutive blocks.PROPOSER_POLICY
: Proposer selection policy, defaults to round robin.ISTANBUL_DIGEST
: Fixed magic number0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365
ofmixDigest
in block header for Istanbul block identification.DEFAULT_DIFFICULTY
: Default block difficulty, which is set to0x0000000000000001
.EXTRA_VANITY
: Fixed number of extra-data prefix bytes reserved for proposer vanity.32 bytes
to retain the current extra-data allowance and/or use.NONCE_AUTH
: Magic nonce number0xffffffffffffffff
to vote on adding a validator.NONCE_DROP
: Magic nonce number0x0000000000000000
to vote on removing a validator.UNCLE_HASH
: AlwaysKeccak256(RLP([]))
as uncles are meaningless outside of PoW.PREPREPARE_MSG_CODE
: Fixed number0
. Message code forPREPREPARE
message.COMMIT_MSG_CODE
: Fixed number1
. Message code forCOMMIT
message.ROUND_CHANGE_MSG_CODE
: Fixed number2
. Message code forROUND CHANGE
message.We also define the following per-block constants:
BLOCK_NUMBER
: Block height in the chain, where the height of the genesis block is 0.N
: Number of authorized validators.F
: Number of allowed faulty validators.VALIDATOR_INDEX
: Index of the block validator in the sorted list of current authorized validators.VALIDATOR_LIMIT
: Number of validators to pass an authorization or de-authorization proposal.floor(N / 2) + 1
to enforce majority consensus on a chain.Block header
We didn't invent a new block header for Istanbul BFT. Instead, we follow Clique in repurposing the
ethash
header fields as follows:beneficiary
: Address to propose modifying the list of validator with.nonce
: Proposer proposal regarding the account defined by the beneficiary field.NONCE_DROP
to propose deauthorizing beneficiary as a existing validator.NONCE_AUTH
to propose authorizing beneficiary as a new validator.NONCE_DROP
orNONCE_AUTH
mixHash
: Fixed magic number0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365
for Istanbul block identification.ommersHash
: Must beUNCLE_HASH
as uncles are meaningless outside of PoW.timestamp
: Must be at least the parent timestamp +BLOCK_PERIOD
difficulty
: Must be filled with0x0000000000000001
.extraData
: Combined field for signer vanity and RLP encoded Istanbul extra data, where Istanbul extra data contains validator list, proposer seal, and commit seals. Istanbul extra data is defined as follows:Thus the
extraData
would be in the form ofEXTRA_VANITY | ISTANBUL_EXTRA
where|
represents a fixed index to separate vanity and Istanbul extra data (not an actual character for separator).EXTRA_VANITY
bytes (fixed) may contain arbitrary proposer vanity data.ISTANBUL_EXTRA
bytes are the RLP encoded Istanbul extra data calculated fromRLP(IstanbulExtra)
, whereRLP()
is RLP encoding function, andIstanbulExtra
is the Istanbul extra data.Validators
: The list of validators, which must be sorted in ascending order.Seal
: The proposer's signature sealing of the header.CommittedSeal
: The list of commitment signature seals as consensus proof.Block hash, proposer seal, and committed seals
The Istanbul block hash calculation is different from the
ethash
block hash calculation due to the following reasons:extraData
to prove the block is signed by the chosen proposer.2F + 1
of committed seals as consensus proof inextraData
to prove the block has gone through consensus.The calculation is still similar to the
ethash
block hash calculation, with the exception that we need to deal withextraData
. We calculate the fields as follows:Proposer seal calculation
By the time of proposer seal calculation, the committed seals are still unknown, so we calculate the seal with those unknowns empty. The calculation is as follows:
Proposer seal
:SignECDSA(Keccak256(RLP(Header)), PrivateKey)
PrivateKey
: Proposer's private key.Header
: Same asethash
header only with a differentextraData
.extraData
:vanity | RLP(IstanbulExtra)
, where in theIstanbulExtra
,CommittedSeal
andSeal
are empty arrays.Block hash calculation
While calculating block hash, we need to exclude committed seals since that data is dynamic between different validators. Therefore, we make
CommittedSeal
an empty array while calculating the hash. The calculation is:Header
: Same as ethash header only with a differentextraData
.extraData
:vanity | RLP(IstanbulExtra)
, where in theIstanbulExtra
,CommittedSeal
is an empty array.Consensus proof
Before inserting a block into the blockchain, each validator needs to collect
2F + 1
of committed seals from other validators to compose a consensus proof. Once it receives enough committed seals, it will fill theCommittedSeal
inIstanbulExtra
, recalculate theextraData
, and then insert the block into the blockchain. Note that since committed seals can differ by different sources, we exclude that part while calculating the block hash as in the previous section.Committed seal calculation:
Committed seal is calculated by each of the validator signing the hash along with
COMMIT_MSG_CODE
message code of its private key. The calculation is as follows:Committed seal
:SignECDSA(Keccak256(CONCAT(Hash, COMMIT_MSG_CODE)), PrivateKey)
.CONCAT(Hash, COMMIT_MSG_CODE)
: Concatenate block hash andCOMMIT_MSG_CODE
bytes.PrivateKey
: Signing validator's private key.Block locking mechanism
Locking mechanism is introduced to resolve safety issues. In general, when a proposer is locked at certain height
H
with a blockB
, it can only proposeB
for heightH
. On the other hand, when a validator is locked, it can only vote onB
for heightH
.Lock
A lock
Lock(B, H)
contains a block and its height, which means its belonging validator is currently locked at certain blockB
and heightH
. In the following, we also use+
to denote more than and-
to denote less than. For example+2/3
validators denotes more than two-thirds of validators, while-1/3
validators denotes less than one-third of validators.Lock and unlock
2F + 1
PREPARE
messages on a blockB
at heightH
.H
and blockB
when it fails to insert blockB
to blockchain.Protocol (
+2/3
validators are locked withLock(B,H)
)PRE-PREPARE
:PRE-PREPARE
onB
, and entersPREPARED
state.PRE-PREPARE
on blockB'
.PRE-PREPARE
on existing block: Ignore.PRE-PREPARE
onB
: BroadcastsPREPARE
onB
.PRE-PREPARE
onB'
: BroadcastsROUND CHANGE
.PRE-PREPARE
onB
: BroadcastsPREPARE
onB
.PRE-PREPARE
onB'
: BroadcastsPREPARE
onB'
.+2/3
are locked atB
and which would lead to round change.PREPARE
:PREPARE
onB
: BroadcastsCOMMIT
onB
, and entersPREPARED
state.PREPARED
inPRE-PREPARE
stage.PREPARE
onB'
: Ignore.+1/3
PREPARE
onB'
since+2/3
are locked atB
. Thus the consensus round onB'
will cause round change. Validator cannot broadcastROUND CHANGE
directly here since thisPREPARE
message can possibly from a faulty node.PREPARE
onB
: Waits for2F + 1
PREPARE
messages onB
.2F + 1
COMMIT
messages prior to receiving2F + 1
PREPARE
messages since there are+2/3
validators being locked atB
. In this case, it will jump toCOMMITTED
state directly.PREPARE
onB'
: Waits for2F + 1
PREPARE
message onB'
.+2/3
validators are locked onB
and which would lead to round change.COMMIT
:COMMIT
onB
: Waits for2F + 1
COMMIT
messages.COMMIT
onB'
: Shouldn't happen.Locking cases
Round change:
+2/3
are locked:B
.B'
, but which will lead to another round change.B
will be committed by honest validators.+1/3 ~ 2/3
are locked:B
.B'
. However, since+1/3
are locked atB
, no validators can ever receive2F + 1
PREPARE
onB'
, meaning no validators can be locked atB'
. Also those+1/3
locked validators will not response toB'
and eventually lead to round change.B
will be committed by honest validators.-1/3
are locked:B
.B'
. If+2/3
reach consensus onB'
, those locked-1/3
will getB'
through synchronization and move to next height. Otherwise, there will be another round change.B
or other blockB'
be finally committed.Round change caused by insertion failure:
+2/3
validators will unlock blockB
atH
and try to propose a new blockB'
.-1/3
validators insert the block successfully, but others successfully trigger round change, meaning+1/3
are still locked atLock(B,H)
B
: Proposer will proposeB'
atH'
, but+1/3
are locked atB
, soB'
won't pass the consensus, which will eventually lead to round change. Other validators will either perform consensus onB
or getB
through synchronization.B
:B
.B'
atH
. The rest is the same as above case 1.+1/3
validators insert the block successfully,-2/3
are trying to trigger round change atH
.B
: Proposer will proposeB'
atH'
, but won't pass the consensus until+1/3
getB
through synchronization.B
:B
.B'
atH
. The rest is the same as above case 1.+2/3
validators insert the block successfully,-1/3
are trying to trigger round change atH
.B
: proposer will proposeB'
atH'
, which may lead to a successful consensus. Then those-1/3
need to getB
through synchronization.B
:B
.B'
atH
. Since+2/3
haveB
atH
already, this round would cause round change.Gossip network
Traditionally, validators need to be strongly connected in order to reach stable consensus results, which means all validators need to be connected directly to each other; however, in practical network environment, stable and constant p2p connections are hard to achieve. To resolve this issue, Istanbul BFT implements gossip network to overcome this constrain. In a gossip network environment, all validators only need to be weakly connected, which means any two validators are seen connected when either they are directly connected or they are connected with one or more validators in between. Consensus messages will be relayed between validators.
How to run
Running Istanbul BFT validators and nodes is similar to running the official node in a private chain. First of all, you need to initialize the data folder as:
Then,
for validators:
for regular nodes:
Note on
syncmode
:--syncmode "full"
is required for the first set of validators to initialize a new network. Since we are using fetcher to insert blocks, if we don't set it to full mode, the fetcher cannot insert the first block. Please refer the following code ineth/handler.go
.The sync mode affects only if there are some existing blocks, so there is no impact for initializing a new network.
For the later joined validators, we don't need to use full mode as they can get blocks by downloader. After the first sync from peers, they will automatically switch to full mode.
Command line options
Nodekey and validator
To be a validator, a node needs to meet the following conditions:
extraData
's validators section.genesis.json
To run the Istanbul BFT chain, the
config
field is required, and thepbft
subfield must present. Example as the following:extraData
toolsWe've create a set of
extraData
coding tools in istanbul-tools repository to help developers to manually generategenesis.json
.Encoding:
Before encoding you need to define a toml file with
vanity
andvalidators
fields to define proposer vanity and validator set. Please refer to example.toml for the example. The output would be a hex string which can be put intoextraData
field directly.Command:
Decoding:
Use
--extradata
option to give theextraData
hex string. The output would show the following if presents: vanity, validator set, seal, and committed seal.Command:
Ottoman testnet
We have setup a testnet for public testing. There are initially 4 validators and no designated faulty nodes. In the future, we want to extend it to 22 validators and setup few faulty nodes amongst them.
Run testnet node
Faulty node
We have implemented a simple faulty node that can make a validator run faulty behaviors during consensus. There are five behaviors included in this implementation:
NotBroadcast
: The validator doesn't broadcast any message.SendWrongMsg
: The validator sends out messages with wrong message codes.ModifySig
: The validator modifies the message signatures.AlwaysPropose
: The validator always sends out proposals.AlwaysRoundChange
: The validator always sendsROUND CHANGE
while receiving messages.BadBlock
: The validator proposes a block with bad bodyRun following command to enable faulty node:
Where the
<MODE>
can be the following number:0
: Disable faulty behaviors.1
: Randomly run any faulty behaviors.2
:NotBroadcast
.3
:SendWrongMsg
.4
:ModifySig
.5
:AlwaysPropose
.6
:AlwaysRoundChange
.7
:BadBlock
.Background
The idea of implementing a byzantine fault tolerance (BFT) consensus came from the challenges we faced while building blockchain solutions for banks. We chose ethereum as the baseline protocol mostly because of its smart contract capability. However, the built-in consensus, proof of work or ethash, is not the ideal choice when settlement finality and minimum latency is required.
Banking systems tend to form a private chain or consortium chain to run their applications. PBFT is ideal for these settings. These environments require a higher degree of manageability and higher throughput. In terms of scalability, validator scalability is not required. Many of the decentralization benefits of PoW in public chains become drawbacks in a private/consortium chain. On the other hand, designated validators in a PBFT environment maps well to private/consortium chains.
Remaining Tasks
extraData
field, but should be fairly straightforward.worker.go
code.Notes and discussions
Does it still make sense to use gas?
Yes. We still need gas to prevent infinite loops and any kind of EVM exhaustion.
Does it make sense to charge gas in a consortium chain?
The network would be vulnerable if every account has unlimited gas or unlimited transaction sending power. However, to enable so, one can run all validators with gas price flag
--gasprice 0
to accept gas price at zero.Put consensus proof in the next block?
Currently our block header can be varied in
extraData
depending on its source validator because of the need to put consensus proof in the block header (by each validator). One way to resolve this is to put the proof in the next block. Therefore, in the proposing stage, the proposer can select2F + 1
of commitment signatures of the previous block and put them in the current proposed block header. However, it would require each block to have one confirmation to reach finality (not instant finality).Proof of lock
Inspired by Tendermint. We are still considering whether to add it to this EIP. Further efficiency benefits can be realized by reusing a current proposed block in a round change situation.
Contribution
The work was initiated and open sourced by the Amis team. We're looking for developers around the world to contribute. Please feel free to contact us:
Forked repository (and original implementation branch)
https://github.com/getamis/go-ethereum/tree/feature/pbft
Clarifications and feedback
TBD
The text was updated successfully, but these errors were encountered: