/ docs / fork-resistance.md
fork-resistance.md
  1  # Fork resistance in Aeternity nodes
  2  
  3  The Aeternity consensus and sync protocols resolve forks according to the specification
  4  in [the aeternity Bitcoin-ng protocol](https://github.com/aeternity/protocol/blob/master/consensus/bitcoin-ng.md). This means that 51% attacks are still possible, just as with other Proof-of-Work chains.
  5  
  6  The Aeternity node implementation offers a few ways to withstand 51% attacks.
  7  
  8  ## Fork resistance via gossip
  9  
 10  The configuration variable
 11  
 12  ```yaml
 13  sync:
 14      gossip_allowed_height_from_top : <height>
 15  ```
 16  limits the height difference allowed for incoming blocks via gossip. This variable has a
 17  hard-coded default of `5`, but can be changed via the `aeternity_config.[yaml|json]`
 18  file (see [the configuration instructions](configuration.md)).
 19  Any keyblock received via gossip will be rejected if its height is more than this
 20  value below the current top.
 21  
 22  ## Fork resistance via sync
 23  
 24  The normal way to introduce a long competing fork would be via the sync protocol. That is,
 25  a node goes off-line and mines a long chain, then reconnects to the network and syncs
 26  against other nodes: if the competing fork has a higher difficulty, it will supersede the
 27  chain on the network.
 28  
 29  The following configuration variable,
 30  
 31  ```yaml
 32  sync:
 33      sync_allowed_height_from_top: <height>
 34  ```
 35  will instruct the node to reject blocks received via sync whose height is more than `<height>`
 36  blocks below the current top. The default value is `100`. A value of `0` disables the
 37  protection. In practice, this should mean that once a transaction has at least `<height>`
 38  keyblocks on top of it, the nodes will resist any competing fork trying to evict it.
 39  
 40  The fork resistance is activated once the node has synced with at least one other node.
 41  It is possible to enable fork resistance immediately, using the following setting:
 42  
 43  ```yaml
 44  sync:
 45      resist_forks_from_start: true`
 46  ```
 47  
 48  Note that configuration variables can be set both via the config file and via OS
 49  environment variables. This means that it's possible to instruct the node to resist
 50  forks at a given node start in the following way:
 51  
 52  ```
 53  AE__SYNC__RESIST_FORKS_FROM_START=true bin/aeternity start
 54  ```
 55  (see [the configuration documentation](configuration.md#configuration-from-the-command-line-or-scripts))
 56  
 57  ### Finalized depth
 58  
 59  When sync fork resistance (`sync: sync_allowed_height_from_top`) is active, the node
 60  will persist the height just below the fork resistance depth as `finalized_height`.
 61  If the node should restart and starts syncing with other nodes (recall that the dynamic
 62  fork resistance is not activated until the node has successfully synced with one peer),
 63  it will reject any chain that presents a key block hash at the finalized height which 
 64  differs from what the node already has on record.
 65  
 66  This shores up the dynamic protection offered by `sync_allowed_height_from_top` to also defend
 67  against malicious nodes during node restarts. The function is automatic, once fork resistance
 68  has been configured. If fork resistance is later turned off, finalized height will not be
 69  enforced.
 70  
 71  ### Discussion
 72  
 73  When choosing a suitable fork resistance depth, it is important to consider some tradeoffs.
 74  Blockchains naturally rely on 'optimistic concurrency', that is, it is entirely possible
 75  that different nodes manage to produce keyblock candidates at roughly the same time.
 76  This means that keyblock forking can occur occasionally. The likelihood that it will happen
 77  repeatedly is extremely low, so such forks should resolve quickly, usually with the following
 78  keyblock.
 79  
 80  Note that even with very long competing forks, the chain will converge. Absent malice and unless
 81  the `TTL` has been set very low for some transactions, transactions evicted for being on a
 82  "losing fork" will be returned to the mempool and find their way back onto the main chain.
 83  The problem is when this behavior is exploited to evict specific high-value transactions
 84  (so-called "rollback", or "double-spend" attacks).
 85  
 86  Even if all transactions get returned to the chain, miners who have mined several blocks
 87  on a losing fork may have reason to feel cheated, as they lose their mining rewards.
 88  
 89  Network latency and network failures may increase the frequency and length of naturally
 90  competing forks, and setting the fork resistance too low might increase the risk of
 91  chain splits, where different nodes end up on different forks and cannot resolve the
 92  situation without manual intervention.
 93  
 94  From a user experience perspective, fork resistance sets an upper bound on the confirmation
 95  time needed to secure high-value transactions, since there is no need to wait longer than
 96  the configured fork resistance depth. Once the generation that contains a transaction is
 97  at or below the finalized depth, the transaction _cannot_ be evicted, either accidentally
 98  or through a malicious attack. Using the default setting of `100`, this would mean that
 99  a block confirmation time of 100 key blocks (5 hours) will be sufficient to protect any transaction
100  amount.