Legacy documentation: You are viewing version CURRENT; the latest available is LATEST.
Go to latest →Federated Consensus Protocol
Introduction
The present version of the protocol uses federated consensus mechanism based on a single block generator (elected out of band) and a group of block signers.
Generator state
The block generator maintains, in addition to its node state:
- A pending transaction pool, or simply a transaction pool, that is a set of transactions used to construct each block it generates. Transactions can be added to and removed from the transaction pool.
- The last generated block, to avoid proposing more than one block at the same height.
- The generator’s signing key. All signers recognize the corresponding verification key and verify generated blocks using this key before validating and co-signing the block themselves. This key can be replaced by an operator after an out-of-band agreement with other nodes.
- The maximum issuance window (in milliseconds), configurable parameter that limits the maximum time field of a transaction containing issuances. This relieves nodes of having to store transactions in the nonce set indefinitely.
Note that the generator can also be a signer, and if so, it also has signer state.
Signer state
Each block signer stores, in addition to its node state:
- The last signed block. This last signed block can be replaced with a new block in an algorithm below.
- The generator’s verification key used to authenticate the block produced by the generator before validating and signing it.
- The signing key required by the consensus program in the last signed block. The signing key can be replaced by an operator after an out-of-band agreement with other nodes (by updating the consensus program in one of the future blocks).
Algorithms
The algorithms below describe the rules for updating a node’s state. Some of the algorithms are used only by other algorithms defined here. Others are entry points — they are triggered by network activity or user input.
Entry Point | When used |
---|---|
Initialize generator | A new network is being set up. |
Join new network | A new network is being set up. |
Accept transaction | Generator receives a transaction. |
Generate block | Generator produces blocks of transactions at regular intervals. |
Sign block | Block signers co-sign a block produced by a block generator. |
Initialize generator
Input: current time.
Outputs: none.
Affects:
- current blockchain state,
- transaction pool.
Algorithm:
- Create a consensus program. The contents of this program are a matter of local policy.
- Make an initial block with the current time and the created consensus program.
- Allocate an empty unspent output set.
- The initial block and these empty sets together constitute the initial state.
- Assign the initial state to the current blockchain state.
- Create an empty transaction pool.
Join new network
A new node starts here when joining a new network (with height = 1).
Input: block.
Output: true or false.
Affects: current blockchain state.
Algorithm:
- Make an initial block with the input block’s timestamp and consensus program.
- The created block must equal the input block; if not, halt and return false.
- Allocate an empty unspent output set.
- The initial block and these empty sets together constitute the initial state.
- Assign the initial state to the current blockchain state.
- Return true.
Accept transaction
The block generator collects transactions to include in each block it generates. When another node or client has prepared a transaction, it sends the transaction to the generator, which follows this algorithm.
Inputs:
- transaction,
- current time,
- current blockchain state.
Output: true or false.
Affects: transaction pool.
Algorithm:
- Validate the transaction with respect to the current blockchain state, but using system timestamp instead of the latest block timestamp; if invalid, halt and return false.
- For every visited Nonce entry in the transaction:
- Test that nonce mintime plus the maximum issuance window is greater or equal to the nonce maxtime; if not, halt and return false.
- Add the transaction to the transaction pool.
- Return true.
Generate block
The generator runs this periodically or when the transaction pool reaches a certain size, according to its local policy. It must broadcast the resulting fully-signed block to all other nodes.
Inputs:
- current blockchain state,
- transaction pool,
- current time,
- last generated block.
Output: block.
Affects:
- transaction pool,
- last generated block.
Algorithm:
- If the last generated block exists with height greater than the current blockchain state, halt and return it.
- Make Block with the current blockchain state, the transaction pool, and the current time.
- For each block signer:
- Send the block and the generator’s signature to the signer asking the signer to sign the block
- Receive a signature from the signer.
- Add the signature to the block witness program arguments.
- Replace the last generated block with the new block.
- Apply the block to the current blockchain state, yielding a new state.
- Let T be an empty list of transactions.
- For each transaction in the transaction pool:
- Validate the transaction with respect to the new state; if invalid, discard it and continue to the next.
- Add the transaction to T.
- Replace the transaction pool with T.
- Return the block.
Note: steps 6-8 are necessary because the transaction pool is not necessarily fully consumed by the new block. See also the note in the Make Block algorithm.
Sign block
Inputs:
- block,
- generator’s signature,
- current blockchain state,
- last signed block,
- signing key,
- system time
Output: signature or nothing.
Affects: last signed block.
Algorithm:
- Test that the height of the input block is strictly greater than the height of the last signed block; if not, halt and return nothing.
- Verify the generator’s signature using the generator’s verification key in the current blockchain state. If the signature is invalid, halt and return nothing.
- Validate the block with respect to the current blockchain state; if invalid, halt and return nothing.
- Check that the block’s consensus program equals the consensus program in the last signed block; if not, halt and return nothing.
- Ensure that reserved values and versions are unused. If any of the following conditions are not satisfied, halt and return nothing:
- The block version must equal 1.
- For every transaction in the block transaction version must equal 1.
- Check that the block’s timestamp is less than 2 minutes after the system time. If it is not, halt and return nothing.
- Compute the block ID for the block.
- Sign the hash with the signing key, yielding a signature.
- Replace the last signed block with the input block.
- Return the signature.
Make initial block
Inputs:
- consensus program,
- time.
Output: a block.
Algorithm:
- Return a block with the following values:
- Version: 1.
- Height: 1.
- Previous block ID: 32 zero bytes.
- Timestamp: the input time.
- Transactions merkle root: merkle binary tree hash of the empty list.
- Assets merkle root: merkle patricia tree hash of the empty list.
- Consensus program: the input consensus program.
- Arguments: an empty list.
- Transaction count: 0.
- Transactions: none.
Make block
Inputs:
- blockchain state,
- set of transactions,
- time.
Output: block.
Algorithm:
- Let S be the blockchain state.
- Let T be an empty list of transactions.
- For each transaction in the set:
- Validate the transaction against S; if it fails, discard the transaction and continue to the next one.
- If local policy prohibits the transaction, discard it and continue to the next one.
- Add the transaction to T.
- Apply the transaction to S, yielding S′.
- Replace S with S′.
- Return a block with the following values:
- Version: 1.
- Height: 1 + the height of the blockchain state.
- Previous block ID: the hash of the blockchain state’s block.
- Timestamp: the input time, or the timestamp of the blockchain state increased by 1 millisecond, whichever is greater:
time[n] = max(input_time, time[n-1]+1)
. - Transactions merkle root: merkle binary tree hash of transaction IDs in T.
- Assets merkle root: merkle patricia tree hash of S.
- Consensus program: the input consensus program.
- Arguments: an empty list.
- Transaction count: the number of transactions in T.
- Transactions: T.
Note: “local policy” in this section gives the generator the ability to exclude a transaction for any reason. For example, it might apply a fixed size limit to every block, and stop adding transactions once it reaches that size.