changed a year ago
Linked with GitHub

Polkadot corrupted ledgers recovery

We outline the i) current state of the corrupted ledgers; 2) steps to recover all corrupted and double bonded ledgers; 3) the state after the 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.

> 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
  2. None stash 14kwUJW6rtjTVW3RusMecvTfDqjEMAt8W159jAGBJqPrwwvC
  3. Double bounded stash 13SvkXXNbFJ74pHDrkEnUw6AE8TVkLRRkUm2CMXsQtd4ibwq

For the different corruption cases and how to recover them, check the Ledger recovery walkthrough 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.

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
Select a repo