owned this note
owned this note
Published
Linked with GitHub
# Polkadot corrupted ledgers recovery
We outline the i) [current state](#Current-state) of the corrupted ledgers; 2) [steps to recover](#Recovery-steps) all corrupted and double bonded ledgers; 3) the [state after the recovery](#State-after-recovery) (i.e. executing the recovery referendum).
**TL;DR**: The solution to restore the corrupted ledgers and bonds in Polkadot consists of caling the following extrinsics:
1. `Staking.restore_ledger(138fZsNu67JFtiiWc1eWK2Ev5jCYT6ZirZM288tf99CUHk8K, None, None, None)`
2. `Staking.restore_ledger(14kwUJW6rtjTVW3RusMecvTfDqjEMAt8W159jAGBJqPrwwvC, None, None, None)`
3. `Staking.restore_ledger(13SvkXXNbFJ74pHDrkEnUw6AE8TVkLRRkUm2CMXsQtd4ibwq, None, None, None)`
4. `Staking.restore_ledger(12YcbjN5cvqM63oK7WMhNtpTQhtCrrUr4ntzqqrJ4EijvDE8, None, None, None)`
## Current state
Instructions to re-run the report in [github/polkadot-js-report](https://github.com/gpestana/polkadot-js-report).
```
> Starting report of corrupted ledgers
- Polkadot
- block 0x6889cf24f2d27f1193904076d28528ab5762f4521616a33afb90404361ab0bfe
- at Tue Jul 16 2024 11:49:36 GMT+0200 (Central European Summer Time)
🔬 #ledgers: 62571, #bonded: 62574, #payee: 62574
🙈 🙉 🙊 Duplicate controller found: 12gmcL9eej9jRBFT26vZLF4b7aAe4P9aEYHGHFzJdmf5arPi | stash 1: 13SvkXXNbFJ74pHDrkEnUw6AE8TVkLRRkUm2CMXsQtd4ibwq | stash 2: 12gmcL9eej9jRBFT26vZLF4b7aAe4P9aEYHGHFzJdmf5arPi
⚙️ ⚙️ ⚙️ is_validator controller: false | stash1 false | stash 2: false
🎯 🎯 🎯 status for recovery for [controller: 12gmcL9eej9jRBFT26vZLF4b7aAe4P9aEYHGHFzJdmf5arPi, stash: 139t3ziRzn1HBDK2oGscUaZaXeXDsrrT5Z9hGYYQFowUyJYb]: ledger.stash: 12gmcL9eej9jRBFT26vZLF4b7aAe4P9aEYHGHFzJdmf5arPi, ledger.total: 213432704809853, lock: 0
🎯 🎯 🎯 status for recovery for [controller: 12gmcL9eej9jRBFT26vZLF4b7aAe4P9aEYHGHFzJdmf5arPi, stash: 12gmcL9eej9jRBFT26vZLF4b7aAe4P9aEYHGHFzJdmf5arPi]: ledger.stash: 12gmcL9eej9jRBFT26vZLF4b7aAe4P9aEYHGHFzJdmf5arPi, ledger.total: 213432704809853, lock: 213432704809853
‼️ stash.lock != ledger total for [controller: 12gmcL9eej9jRBFT26vZLF4b7aAe4P9aEYHGHFzJdmf5arPi, stash: 139t3ziRzn1HBDK2oGscUaZaXeXDsrrT5Z9hGYYQFowUyJYb]: ledger.stash: 12gmcL9eej9jRBFT26vZLF4b7aAe4P9aEYHGHFzJdmf5arPi, ledger.total: 213432704809853, lock: 0
⚫ None ledgers, i.e. 'Ledger(bonded_controller) = None'
none ledger with pair (controller: 15bt67qghz8hJxCUPgAXmzVxUBHLpPN41RVm2nwMFyLWByVE, stash: 14kwUJW6rtjTVW3RusMecvTfDqjEMAt8W159jAGBJqPrwwvC)
none ledger with pair (controller: 138fZsNu67JFtiiWc1eWK2Ev5jCYT6ZirZM288tf99CUHk8K, stash: 138fZsNu67JFtiiWc1eWK2Ev5jCYT6ZirZM288tf99CUHk8K)
```
### Explanation
There are 2 bonded ledgers that have been wiped out due to double bonding (associated with stashes `14k` and `138`). In addition, there is a double-bonding corruption (associated with stashes `12Y` and `13S`) that affected the stashes locks.
**In sum, the stashes/ledgers needing to recover in Polkadot are**:
1. None stash `138fZsNu67JFtiiWc1eWK2Ev5jCYT6ZirZM288tf99CUHk8K`
- [detailed explanation, recovery steps, state after recovery](#1-None-ledger-138)
2. None stash `14kwUJW6rtjTVW3RusMecvTfDqjEMAt8W159jAGBJqPrwwvC`
- [detailed explanation, recovery steps, state after recovery](#2-None-ledger-14k)
3. Double bounded stash `13SvkXXNbFJ74pHDrkEnUw6AE8TVkLRRkUm2CMXsQtd4ibwq`
- [detailed explanation, recovery steps, state after recovery](#3-Corrupted-ledger-13S)
For the different corruption cases and how to recover them, check the [Ledger recovery walkthrough](https://hackmd.io/DLb5jEYWSmmvqXC9ae4yRg?both#/) doc.
### 1. None ledger `138`
**Current state**:
- `Bonded(138) = 138fZsNu67JFtiiWc1eWK2Ev5jCYT6ZirZM288tf99CUHk8K` (itself)
- `Ledger(138) = None`
- `Balances.locks.staking(138) = 85,560,353,029,324`
The stash `138` is bonded but its ledger was wiped out due to double bonding (see X) and the staking locks previous to the wiep out were left behind. We can recover the ledger by calling the extrinsic `Staking.restore_ledger`:
**Solution**:
```
Staking.restore_ledger(138fZsNu67JFtiiWc1eWK2Ev5jCYT6ZirZM288tf99CUHk8K, None, None, None)
```
✅ **State after recovering**
- `Bonded(138) = 138fZsNu67JFtiiWc1eWK2Ev5jCYT6ZirZM288tf99CUHk8K` (itself)
- `Ledger(138) = Ledger {stash: 138.., total: 85,560,353,029,324}`
- `Balances.locks.staking(138) = 85,560,353,029,324`
The ledger has been recovered as expected, with the new `ledger.total` being the equivalent of the staking locks.
### 2. None ledger `14k`
**Current state**:
- `Bonded(14k) = 15bt67qghz8hJxCUPgAXmzVxUBHLpPN41RVm2nwMFyLWByVE`
- `Ledger(14k) = None`
- `Balances.locks.staking(14k) = 42,606,076,773,049`
Note that although `14k` is bonded to `15bt`, the stash, bond and locks of `15bt` are all None. The solution is to recover the ledger associated with `14k`:
**Solution**:
```
Staking.restore_ledger(14kwUJW6rtjTVW3RusMecvTfDqjEMAt8W159jAGBJqPrwwvC, None, None, None)
```
✅ **State after recovery**:
- `Bonded(14k) = 14kwUJW6rtjTVW3RusMecvTfDqjEMAt8W159jAGBJqPrwwvC`
- `Ledger(14k) = Ledger {stash: 14k.., total: 42,606,076,773,049}`
- `Balances.locks.staking(14k) = 42,606,076,773,049`
The ledger has been recovered as expected, with the new ledger.total being the equivalent of the staking locks.
### 3. Corrupted ledger `13S`
**Current state**:
- `Bonded(13S) = 12gmcL9eej9jRBFT26vZLF4b7aAe4P9aEYHGHFzJdmf5arPi`
- `Ledger(13S) = None`
- `Balances.locks.staking(14k) = 201,151,395,706,325`
**Solution**:
```
Staking.restore_ledger(13SvkXXNbFJ74pHDrkEnUw6AE8TVkLRRkUm2CMXsQtd4ibwq, None, None, None)
```
✅ **State after recovery**:
- `Bonded(13S) = 13SvkXXNbFJ74pHDrkEnUw6AE8TVkLRRkUm2CMXsQtd4ibwq`
- `Ledger(13S) = Ledger {stash: 13S.., total: 201,151,395,706,325}`
- `Balances.locks.staking(13S) = 201,151,395,706,325`
### 3. Corrupted ledger `12YcbjN5cvqM63oK7WMhNtpTQhtCrrUr4ntzqqrJ4EijvDE8`
**Current state**
- `Bounded(12Y) = 12YcbjN5cvqM63oK7WMhNtpTQhtCrrUr4ntzqqrJ4EijvDE8`
- `Ledger(12Y) = Ledger {stash: 138.., total: 85,560,353,029,324}`
- `Balances.locks.staking(12Y) = 84,985,052,242,831`
**Solution**:
```
Staking.restore_ledger(12YcbjN5cvqM63oK7WMhNtpTQhtCrrUr4ntzqqrJ4EijvDE8, None, None, None)
```
✅ **State after recovery**:
- `Bonded(12Y) = 12YcbjN5cvqM63oK7WMhNtpTQhtCrrUr4ntzqqrJ4EijvDE8`
- `Ledger(12Y) = Ledger {stash: 12Y , total: 84,985,052,242,831}`
- `Balances.locks.staking(12Y) = 84,985,052,242,831`
## Overall state after recovery
Instructions to re-run the report in [github/polkadot-js-report](https://github.com/gpestana/polkadot-js-report).
Note: the overall number of bonded/ledgers/payee items may differ at the time of running the report script, but the important factor is that they are all in sync after the ledger recovery.
```
> Starting report of corrupted ledgers
- Polkadot
🔬 #ledgers: 62574, #bonded: 62574, #payee: 62574
⚫ None ledgers, i.e. 'Ledger(bonded_controller) = None'
# of none ledgers: 0
```