paritytech / polkadot-sdk

The Parity Polkadot Blockchain SDK
https://polkadot.network/
1.81k stars 658 forks source link

Make Recovery Work Network-Wide #2479

Open joepetrowski opened 10 months ago

joepetrowski commented 10 months ago

In order to get the Recovery pallet into Polkadot, we need to ensure that recovery in one place (let's assume the People Chain) allows recovery on the Relay Chain and all parachains that opt in to recognize account recovery from the People Chain. When an account is recovered in the Recovery pallet, it sets the recoverer as an Any proxy to the recovered account.

I see two options:

  1. Allow Any proxies on the People Chain to send messages and Transact on remote chains using the proxied AccountId's origin. In this option, all recovery would be done from the People Chain.
  2. Write a standard XCM program that will SetAgent on remote chains as a proxy with Any privilege. In this option, the recoverer would only use the People Chain to set proxies on all the remote chains and then transact on those directly.

We can't limit recovery to balance transfer because the recovered account may have locked funds from staking/governance and need to make calls to unlock them.

These approaches also imply some changes to the concept of a proxy, which for now is limited to a specific chain. These changes mean that an Any proxy on the People Chain would really mean, "anything on any chain that recognizes the People Chain". We could also introduce a new UniveralAny proxy type to distinguish "anything local" from "anything in the network".

joepetrowski commented 10 months ago

Tagging @franciscoaguirre and @seadanda now, but I don't know if either has time to work on it immediately, so someone else can pick this up if they are inclined.

bkchr commented 10 months ago

it sets the recoverer as an Any proxy to the recovered account.

Just as an info, the proxy is handled inside the recovery pallet and is not related to pallet-proxy.

joepetrowski commented 10 months ago

The setting of the proxy happens locally in the Recovery pallet, but then any calls to the recovered account have to be done via pallet-proxy. And it will not set this on remote chains.

franciscoaguirre commented 10 months ago

I think there are two scenarios for this, based on the difference between a main account and sovereign accounts.

Lets say a user has an account in the people chain and is dealing with other chains using its sovereign account on each of them.

The other scenario would be one where a user doesn't have their main account in the people chain, but rather on asset hub for example, more likely maybe? They only ever used the people chain via a sovereign account of their main asset hub account. In this case, they can only recover their account by using a pallet on another chain.

I think the first scenario would work right now, but sadly because of the asymmetry between the main account and all sovereign accounts, the second scenario is more complicated. We'd still have a way around it, which mainly entails moving these proxy constructs from FRAME to XCM by way of moving AccountId -> Location and Proxy -> AliasOrigin. I'm a fan of using more Locations everywhere, making the substrate pallet generic enough to be able to configure it for our use-case, so that cross-chain interactions are much easier.

Further details on both scenarios below:

In the first scenario. They lose their keys, and create a rescuer account, aka proxy, via the recovery pallet. This new account can call as_recovered and use that to send XCMs to the other chains as the old account. This results in the same sovereign account on all other chains, which means they can unlock all funds and move them to this new account in due time. After that, they can just seed new sovereign accounts and cancel the recovery.

In the second scenario. They can set up recovery by sending an XCM to the people chain with a Transact calling the necessary extrinsic on the pallet, create_recovery. This would be stored in the recovery pallet. Tuning the recovery pallet to work with XCM Locations instead of local accounts might be a possibility here to make things easier. Then, when a new rescuer account is created, this could be communicated to all other chains so they update a map from Location to Location, so they know who is a proxy of who. Then every message that wants to act like the old account has to be prepended with an AliasOrigin instruction that transforms the new proxy account to the old one. This can be cleared up once everything relevant has been moved. This would require all chains to have a special pallet to take note of this and a special XCM configuration to allow for this origin manipulation.

xlc commented 10 months ago

I don't think we don't need to do special proxy work. The recovery system needs to be able to dispatch arbitrary calls on the dest chain and that call could be adding a proxy. But from the people chain, that just XCM transact. While I think every parachain have proxy pallet currently, that shouldn't be a requirement. For example, an EVM may not have it.