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.