Skip to main content

Original source: 0055-stop-transaction-processing.md

Stop processing transactions / stop the network after a certain slot

This PR describes the feature to stop processing transactions and to stop the network after a certain slot, to be used in the Berkeley hard fork.

Summary

Transactions come from a client or the gossip network and are processed by BPs and SNARK workers to be included in blocks. These blocks are propagated through the network and validated by other participants.

In this RFC, the procedure to stop processing any new transactions and to stop the network after a certain slot is described. This is, we define two slots: the first one is the slot after which any blocks produced will include no transaction at all and no fee payments, and the second one is the slot after which no blocks are produced and blocks received are rejected.

Motivation

In a hard fork scenario, we want to halt the preceding network and produce a new genesis ledger for the succeeding network. This new genesis ledger should be produced from a stabilised staged ledger from the preceding network. This is, we define a point in time (slot) where the network continues to operate but with no "activity". In detail, after this slot, the network continues to produce blocks but without including any transactions, sets coinbase fees to zero, and ensures there are no fees for snark work, by including no snark work in the block. This will run for a certain number of slots, after which the network will stop producing blocks. This will allow the network to stabilise and produce a new genesis ledger from the last ledger produced by the network.

This feature enables part of this procedure, by adding the definition of the slots and the mechanisms to stop the node from processing transactions and to stop the networks after those slots.

Detailed design

The procedure to stop processing transactions and producing/validating empty blocks after a certain slot will be as follows:

  • There will be a configuration parameter set at compile-time that will define the slot at which the node will stop processing transactions.
  • The previous configuration cannot be overridable at runtime, by design, as this compromises the safety of the daemon software.
  • The node (daemon) will stop accepting new transactions from clients after the configured slot.
  • After the configured slot, the block producer will stop including transactions in blocks, as well as any snark work and coinbase fee will be set to zero.
  • The block validator will reject blocks produced after the stop slot that contain any transaction, snark work or a non-zero coinbase fee.
  • The node should start notifying the user every 60 slots (3 hours) when transaction processing halts in less than 480 slots (24 hours).

To stop the network after a certain slot, the procedure will be as described next:

  • There will be a configuration parameter set at compile-time that will define the slot at which the node will stop the network.
  • After the configured slot, the block producer will stop producing any blocks.
  • The block validator will reject any blocks received after the stop network
  • slot.
  • The node should start notifying the user every 60 slots (3 hours) when block production/validation halts in less than 480 slots (24 hours).

Each of these procedures will be described in detail in the following sections.

Compile-time configuration

The configuration parameters slot_tx_end and slot_chain_end will be set at compile-time and will define the slot at which the node will stop processing transactions and the slot at which the network stops, respectively. These configuration parameters will be optional and will default to None. If slot_tx_end is set to None, the node will not stop processing transactions. If slot_chain_end is set to None, the node will not stop producing or validating blocks.

Client submits transaction

When a client sends a transaction to the node daemon, the node will check if the stop transaction slot configuration is set. If so, and the current global slot is less than the configured stop slot, the transaction will be accepted by the node and processed as usual. If the current global slot is equal or greater than the configured stop slot, the transaction will be rejected. The client will be notified of the rejection and the reason why the transaction was rejected. This improves user UX by rejecting transactions that will not be included in the ledger in the preceding network.

This can be done by adding these checks and subsequent rejection messages to the GraphQL functions that receive and submit user commands.

Block producer

When the block producer is producing a block, it will check if the stop network slot configuration is set. If so, and the current global slot is equal or greater than the configured stop slot the block producer will not produce a block. If the configured stop slot is not set or it's greater than the current global slot, the block producer will then check if the stop transaction slot configuration is set. If so, and the current global slot is equal or greater than the configured stop slot the block producer will produce a block without any transactions nor snark work and with a coinbase fee of zero. If the configured stop slot is not set or is greater than the current global slot, the block producer will produce blocks as usual.

This can be done by adding these checks to block production logic. First, decide whether or not blocks should be produced. If the stop network slot is set and the current global slot is equal or greater than it doesn't produce blocks. If the previous is false, return an empty staged ledger diff instead of the generated one whenever the stop transaction slot is defined and the current global slot is equal or greater than it, ultimately resulting in a block produced with no transactions, no internal commands, no completed snark work, and a coinbase fee of zero. When doing these checks, the node will also check for the conditions to emit the info log messages at the timings and conditions expressed earlier.

Block validator

When the block validator is validating a block, it will check if the stop network slot configuration is set. If so, and the current global slot is equal or greater than the configured stop slot, the block validator will reject the block. If the stop network slot is not set or is greater than the current global slot, the block validator will then check if the stop transaction slot configuration is set. If so, and the global slot at which the block was produced is less than the configured stop slot, the block validator will validate the block as usual. If the stop transaction slot configuration is not set or is greater than the global slot of the block, the block validator will reject blocks that define a staged ledger diff different than the empty one.

This can be done by adding these checks to the transition handler logic. First, reject any blocks if the stop network slot value is set and the current global slot is greater than it. Second, and if the previous is not true, check the staged ledger diff of the transition against the empty staged ledger diff instead doing the usual verification process when the configured stop transaction slot is defined and the global slot for which the block was produced is equal or greater than it. When doing these checks, the node will also check for the conditions to emit the info log messages at the timings and conditions expressed earlier.

Test plan and functional requirements

Integration tests will be added to test the behavior of the block producer and the block validator. The following requirements should be tested:

  • Block producer
    • When the stop network slot configuration is set to None, the block producer should produce blocks.
    • When the stop network slot configuration is set to <slot> and the current global slot is less than <slot>, the block producer should produce blocks.
    • When the stop network slot configuration is set to <slot> and the current global slot is greater or equal to <slot>, the block producer should not produce blocks.
    • When the stop transaction slot configuration is set to None, the block producer processes transactions, snark work and coinbase fee as usual.
    • When the stop transaction slot configuration is set to <slot> and the current global slot is less than <slot>, the block producer processes transactions, snark work and coinbase fee as usual.
    • When the stop transaction slot configuration is set to <slot> and the current global slot is greater or equal to <slot>, the block producer produces empty blocks (blocks with an empty staged ledger diff).
  • Block validator
    • When the stop network slot configuration is set to None, the block validator validates blocks as usual.
    • When the stop network slot configuration is set to <slot> and the current global slot is less than <slot>, the block validator validates blocks as usual.
    • When the stop network slot configuration is set to <slot> and the current global slot is greater or equal to <slot>, the block validator rejects all blocks.
    • When the stop transaction slot configuration is set to None, the block validator validates blocks as usual.
    • When the stop transaction slot configuration is set to <slot> and the global slot of the block is less than <slot>, the block validator validates blocks as usual.
    • When the stop transaction slot configuration is set to <slot> and the global slot of the block is greater or equal to <slot>, the block validator rejects blocks that define a staged ledger diff differently than the empty one.
  • Node/client
    • When the stop transaction slot configuration is set to None, the node processes transactions from clients as usual.
    • When the stop transaction slot configuration is set to <slot> and the current global slot is less than <slot>, the node processes transactions from clients as usual.
    • When the stop transaction slot configuration is set to <slot> and the current global slot is greater or equal to <slot>, the node rejects transactions from clients.

Drawbacks

Non-patched nodes or nodes with the configuration overridden will still be able to send transactions to the network. These transactions will be included in the transaction pool but will not be processed by the patched block producers, alongside other transactions that may have arrived at the transaction pool before the configured stop slot but haven't been included in a block as of that slot. This will result in a transaction pool that will not be emptied until the network stops and those transactions will not be included in the succeeding network unless there's a mechanism to port them over to the new network to be processed and included there. This might result in a bad UX, especially for users who send transactions to the network before the configured stop slot and don't see them included in the ledger and disappear from the transaction pool when the network restarts. Moreover, non-patched nodes will produce and process transactions as usual after the transaction stop slot, resulting in these nodes constantly attempting to fork.

Rationale and alternatives

Prior art

Unresolved questions