Versioning of public types
We need to make all public complex types like Blocks, Transactions, Inputs, Outputs, and Consensus to support versioning. It is not related to the primitive types.
Using Rust enums for versioning types in the context of blockchains
Enums can be used to version types in the context of blockchains. This is particularly useful for representing changes to the blockchain protocol over time without breaking compatibility with existing nodes.
Example:
enum ConsensusAlgorithmVersion {
V1(ConsensusAlgorithmV1),
V2(ConsensusAlgorithmV2),
}
struct ConsensusAlgorithmV1 {
voting_mechanism: VotingMechanism,
}
struct ConsensusAlgorithmV2 {
voting_mechanism: VotingMechanism,
}
impl From<ConsensusAlgorithmV1> for ConsensusAlgorithmV2 {
fn from(algorithm: ConsensusAlgorithmV1) -> ConsensusAlgorithmV2 {
ConsensusAlgorithmV2 {
voting_mechanism: algorithm.voting_mechanism,
}
}
}
Existing code that interacts with the blockchain can use the ConsensusAlgorithmVersion enum to determine the specific version of the consensus algorithm that is used for the current block. This allows you to introduce new versions of the consensus algorithm without breaking existing code that handles consensus messages.
Benefits of using enums for versioning types
- Flexibility: You can easily add new versions of the type without modifying existing code.
- Backward compatibility: Existing code that handles the older version of the type will continue to work seamlessly with the new version.
- Maintainability: It is easier to track and manage changes to the type over time.
Most of them already are enums. But some of them(like Block) - not. In the scope of this task, we need to revise all existing types and decide which ones should be enums and which should not. It may also require fuel-specs modifications.
Notes:
Add #[non_exhaustive] flag.
Should we use #[non_exhaustive] for the version enum? This way users of the type must handle the cases where they're not aware of the new values yet.
This story should also include the ability to configure the block height at which these versions take effect
We need to make sure we are covering all types that get included in the DB. There are also subtypes, like BlockHeader that definitely needs to be versioned.
How can we feel confident that we have caught all relevant types?