github.com/badrootd/nibiru-cometbft@v0.37.5-0.20240307173500-2a75559eee9b/docs/rfc/rfc-009-consensus-parameter-upgrades.md (about)

     1  # RFC 009 : Consensus Parameter Upgrade Considerations
     2  
     3  ## Changelog
     4  
     5  - 06-Jan-2011: Initial draft (@williambanfield).
     6  
     7  ## Abstract
     8  
     9  This document discusses the challenges of adding additional consensus parameters
    10  to Tendermint and proposes a few solutions that can enable addition of consensus
    11  parameters in a backwards-compatible way.
    12  
    13  ## Background
    14  
    15  This section provides an overview of the issues of adding consensus parameters
    16  to Tendermint.
    17  
    18  ### Hash Compatibility
    19  
    20  Tendermint produces a hash of a subset of the consensus parameters. The values
    21  that are hashed currently are the `BlockMaxGas` and the `BlockMaxSize`. These
    22  are currently in the [HashedParams struct][hashed-params]. This hash is included
    23  in the block and validators use it to validate that their local view of the consensus
    24  parameters matches what the rest of the network is configured with.
    25  
    26  Any new consensus parameters added to Tendermint should be included in this
    27  hash. This presents a challenge for verification of historical blocks when consensus
    28  parameters are added. If a network produced blocks with a version of Tendermint that
    29  did not yet have the new consensus parameters, the parameter hash it produced will
    30  not reference the new parameters. Any nodes joining the network with the newer
    31  version of Tendermint will have the new consensus parameters. Tendermint will need
    32  to handle this case so that new versions of Tendermint with new consensus parameters
    33  can still validate old blocks correctly without having to do anything overly complex
    34  or hacky.
    35  
    36  ### Allowing Developer-Defined Values and the `EndBlock` Problem
    37  
    38  When new consensus parameters are added, application developers may wish to set
    39  values for them so that the developer-defined values may be used as soon as the
    40  software upgrades. We do not currently have a clean mechanism for handling this.
    41  
    42  Consensus parameter updates are communicated from the application to Tendermint
    43  within `EndBlock` of some height `H` and take effect at the next height, `H+1`.
    44  This means that for updates that add a consensus parameter, there is a single
    45  height where the new parameters cannot take effect. The parameters did not exist
    46  in the version of the software that emitted the `EndBlock` response for height `H-1`,
    47  so they cannot take effect at height `H`. The first height that the updated params
    48  can take effect is height `H+1`. As of now, height `H` must run with the defaults.
    49  
    50  ## Discussion
    51  
    52  ### Hash Compatibility
    53  
    54  This section discusses possible solutions to the problem of maintaining backwards-compatibility
    55  of hashed parameters while adding new parameters.
    56  
    57  #### Never Hash Defaults
    58  
    59  One solution to the problem of backwards-compatibility is to never include parameters
    60  in the hash if the are using the default value. This means that blocks produced
    61  before the parameters existed will have implicitly been created with the defaults.
    62  This works because any software with newer versions of Tendermint must be using the
    63  defaults for new parameters when validating old blocks since the defaults can not
    64  have been updated until a height at which the parameters existed.
    65  
    66  #### Only Update HashedParams on Hash-Breaking Releases
    67  
    68  An alternate solution to never hashing defaults is to not update the hashed
    69  parameters on non-hash-breaking releases. This means that when new consensus 
    70  parameters are added to Tendermint, there may be a release that makes use of the
    71  parameters but does not verify that they are the same across all validators by
    72  referencing them in the hash. This seems reasonably safe given the fact that
    73  only a very far subset of the consensus parameters are currently verified at all.
    74  
    75  #### Version The Consensus Parameter Hash Scheme
    76  
    77  The upcoming work on [soft upgrades](https://github.com/tendermint/spec/pull/222)
    78  proposes applying different hashing rules depending on the active block version.
    79  The consensus parameter hash could be versioned in the same way. When different
    80  block versions are used, a different set of consensus parameters will be included
    81  in the hash.
    82  
    83  ### Developer Defined Values
    84  
    85  This section discusses possible solutions to the problem of allowing application
    86  developers to define values for the new parameters during the upgrade that adds
    87  the parameters.
    88  
    89  #### Using `InitChain` for New Values
    90  
    91  One solution to the problem of allowing application developers to define values
    92  for new consensus parameters is to call the `InitChain` ABCI method on application
    93  startup and fetch the value for any new consensus parameters. The [response object][init-chain-response]
    94  contains a field for `ConsensusParameter` updates so this may serve as a natural place
    95  to put this logic.
    96  
    97  This poses a few difficulties. Nodes replaying old blocks while running new
    98  software do not ever call `InitChain` after the initial time. They will therefore
    99  not have a way to determine that the parameters changed at some height by using a
   100  call to `InitChain`. The `EndBlock` response is how parameter changes at a height
   101  are currently communicated to Tendermint and conflating these cases seems risky.
   102  
   103  #### Force Defaults For Single Height
   104  
   105  An alternate option is to not use `InitChain` and instead require chains to use the
   106  default values of the new parameters for a single height.
   107  
   108  As documented in the upcoming [ADR-74][adr-74], popular chains often simply use the default
   109  values. Additionally, great care is being taken to ensure that logic governed by upcoming
   110  consensus parameters is not liveness-breaking. This means that, at worst-case, 
   111  chains will experience a single slow height while waiting for the new values to
   112  by applied.
   113  
   114  #### Add a new `UpgradeChain` method
   115  
   116  An additional method for allowing chains to update the consensus parameters that
   117  do not yet exist is to add a new `UpgradeChain` method to `ABCI`. The upgrade chain
   118  method would be called when the chain detects that the version of block that it
   119  is about to produce does not match the previous block. This method would be called
   120  after `EndBlock` and would return the set of consensus parameters to use at the
   121  next height. It would therefore give an application the chance to set the new
   122  consensus parameters before running a height with these new parameter.
   123  
   124  ### References
   125  
   126  [hashed-params]: https://github.com/tendermint/tendermint/blob/0ae974e63911804d4a2007bd8a9b3ad81d6d2a90/types/params.go#L49
   127  [init-chain-response]: https://github.com/tendermint/tendermint/blob/0ae974e63911804d4a2007bd8a9b3ad81d6d2a90/abci/types/types.pb.go#L1616
   128  [adr-74]: https://github.com/tendermint/tendermint/pull/7503