-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pure Proxy Replication #111
base: main
Are you sure you want to change the base?
Pure Proxy Replication #111
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is another drawback which is unlikely but nevertheless needs to be considered.
Say we have 3 parachains, A, B, and C
3 accounts, Alice, Bob, Charlie
Alice created a pure proxy on chain A: Alice#1@A
Alice created a pure proxy on chain B with the exact same parameters: Alice#1@B
The preimage data (and therefore the hash) for Alice#1@A and Alice#1@B are exactly the same
The ownership of Alice#1@A is transferred to Bob (e.g. the account had some staked asset and Alice sold them to Bob by transferring the pure proxy ownership)
The ownership of Alice#1@B is transferred to Charlie
Now some assets are airdropped to Alice#1@C
Both Bob and Charlie want to replicate the proxy on chain C to gain control of the airdropped asset.
What now?
This issue exists because there is no chain specific data in the pure proxy preimage (e.g. chain genesis). The proper fix is to introduce such data to the preimage but it wouldn't fix the legacy issue.
I don't know what will be the solution and I don't even sure if it is possible to have a solution, unfortunately.
That's one of the reason why ss58 prefix is important because it distinguishes the accounts between chains. Similar issue exists on other EVM chains. There were multiple attacks caused by people are able to take control of gnosis safe ownership by replicate the contract deployment using a same nonce and the original owner were expecting they control such contract on other EVM networks, which is not always true.
- The receiving chain has to trust the sending chain's claim that the account controlling the pure account has commanded the replication. | ||
- Clients must obtain witness data. | ||
|
||
We could eliminate the first disadvantage by allowing only the spawner of the pure proxy to recreate the pure proxies, if they sign the transaction on a remote chain and supply the witness/preimage. Since the preimage of a pure account includes the account ID of the spawner, we can verify that the account signing the transaction is indeed the spawner of the given pure account. However, this approach would grant exclusive rights to the spawner over the pure account, which is not a property of pure proxies at present. This is why it's not an option for us. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah we shouldn't do this. it is for example the spawner private key is forgotten because people wasn't expecting they need it anymore
@xlc good point, thank you. what if we a receiving chain will require no proxy records for a replicated pure account? |
It is not going to help (if not make the problem worse). Both Bob and Charlie can still try to claim Alice#1@C and it will just be whomever is the fastest. And without the witness data, root origin on chain A or B can even try to claim non pure proxy account. I guess it could just let it be a known issue without solution and we just accept it and life continues. Not every bug requires fix but at least we are making a considered decision. |
@xlc makes sense. we should allow multiple replications of the same pure account with different proxy accounts. I think we can allow clients of the pallets to add an additional custom seed into the pure account preimage. |
Yes that will improve the security. |
@xlc I have included your note. thank you |
|
||
### Ergonomics | ||
|
||
The proposed solution does not alter any existing interfaces. It does require clients to obtain the witness data which should not be an issue with support of an indexer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clients would need to get this witness data and perform the replication before any action on another chain. When would they know to do the replication?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when they want to use the proxy account on dest chain. i.e. requires user to manually initiate the replication
Is it correct that it's no longer keyless then? I'm curious about how ownership of a pure account is defined and how it can be transferred. As far as I know, the deposit for the pure account remains with its creator indefinitely. I assume that the creator of pure accounts could simply be an operational account used for initialization. For example, if it creates three pure accounts to form a multisig, it could then connect those pure accounts to other users and remove its own link. In that scenario, the new owner's identity is clear. However, it’s also possible for one pure account to be connected to different types of proxies. In that case, who would be considered the owner? It's obvious but important to note that there is a security risk if the creator were to restore its link to the pure account on another chain, after having removed it from the original one. |
The seed is not private key seed, but hash preimage payload (it shouldn't be called seed).
The deposit issue is unrelated but nevertheless a bug should be fixed (paritytech/polkadot-sdk#237, paritytech/substrate#8550)
There is no concept of owner.
This is never this RFC about and obviously should never happen unless the proxy account explicitly wants it. |
Sorry for misleading it was mostly a joke :-)
You wrote
That's my question about. |
The onchain pallet doesn't have concept of owner. A pure proxy can be controlled by no one (which shouldn't happen but the last owner can remove itself) or multiple. And then we have proxy type so some accounts could have limited control, for example, A have TransferOnly and B have EverythingButTransfer. So yeah we should avoid owner in RFC. What is actually happening is some accounts have the authorization to request the pure proxy to do kind of action (the kind is determined by the proxy type). That's it. @AndreiEres what is your question again? |
I think I'm good, thank you. I had some edge cases in my head but the goal of the RFC is more broad and there are more important security questions. |
Is there anything to address here or can we get it to a vote? @muharem |
While I'm very late to the party, sorry. I would have a different proposal, but do with it whatever you want ;) Instead of replicating the proxies everywhere, I would propose we put them on one or two chains only. From there we can do proofs that the pure proxy exists on the destination chain. I would assume that proxies only exists on the people or maybe only on AH. When you want to call something on parachain X using your proxy, you would forward a proof of the data inside the state of AH/People chain to parachain X. Each parachain tracks the relay chain storage root and based on this we can get the individual heads of each parachain and with this we can check the storage proof from the proxy holding chain. This way we don't need to have the proxy everywhere and also all parachains probably trust the system chains. |
Yeah we don't really need a native replicate function. What we need is authenticate that allow the source chain to dispatch some transact on dest chain for some proxy account. The transact can be So for one time usage, people can just use transact to do whatever they want. But if they want to do something on the dest chain repetitively, they can replicate the proxy to avoid the XCM overhead. |
What I proposed doesn't use XCM at all and just uses proofs to prove the existence of the proxy. |
One key difference will be how much of internal details that we would like to be spec'ed and fixed? |
On-chain messaging should've base costs like 30 x more than off-chain messaging, but congestion should hopefully make them cost much more. Any off-chain message requires a state proof, so on-chain messaging should not remain more flexible/forward compatible, but this requires nice storage abstraction traits (not even planned for JAM yet). I think proofs have very different semantics from replication, with replication closely resembling airdrops, so definitely a popular usecase, but not universal. Internally though, we'll need proofs to split polkadot functionality into multiple parachains: A governance vote needs the current locks state, not airdrops of past state, as well as proofs into the vote for early unlocking. An on-chain messaging protocol cannot handle this many messages btw. App parachains who outgrow elastic scaling might employ off-chain messages with guaranteed delievery for account migration between their parachain shards, but their governance might resemble this polkadot model. As an aside, validator ellections could be done by a temporary "fork" of whatever chain holds the nominators accounts, aka one huge off-chain message, so neither a proof nor an airdrop/replication. |
Please correct me if I am wrong, the solution with the off-chain proof submission would look like: The client/wallet on a user request pulls the proxy ownership proof (1) (the whole sub trie) from the chain that sources the proxies, block height (2) at which the poof was pulled and constructs keyless/pure account witness (3) (as in the present RFC, currently proxy pallet does not differentiate a keyless/pure accounts and general accounts or we open it for all proxies). With these arguments now the client constructs the target call for a user. The user must submit this call from the account that has an ownership of the proxy. This composite call contains the arguments (1), (2) and (3). Concerns:
The client submits the extrinsic to a target chain. The target chain's runtime has to know the part of the source chain's storage layout (the part concerning the proof) and be able to obtain the source chain's state root at a give height (2). The target chain verifies that the height is not too old, verifies the proof (1) and the witness (3) data. If all valid the target chain proxies the call. Where am I wrong or missing something? @bkchr @xlc
@burdges |
Depends on the trie depth ;) If you would replicate the proxies on the destination chain, loading the proxy from the destination state versus delivering the proof alongside the call should not make such a big difference.
This is a good point. In the end it depends on how long we want to store the storage roots of the proxy providing chain. However, we could come up with a solution that uses the dispatch local context to store the proof, then the final multisig tx could provide this information. |
IIUC:
The implementation+deployment complexities of the two options are comparable, but 2nd option would have higher maintenance cost because of its dependency on storage layouts, and IMO poorer UX. So unless I am missing something, I am supporting the onchain XCM path. |
It's completely irrelevant in the worst case.. Polkadot only validates stateless blocks, so a collators expands the block by every Merkle proof required for the state proofs, so in the worst case all transactions have size If a user submits proof into chan A in transaction on chain B, then the user's proof has size In fact, we do not work in the worse case because collators merge those Merkle proofs, which saves considerable space. Interestingly, we achieve this merger by running a generic compression algorithm, which while less efficent than simply merging them manually, does ensure that if you many transactions have Merkle proofs into a specific chain, then those merge too. All told, I'd expect Merkle proofs into other parachains const little in practice, not because they do not take space, but because you'd pay that space anyways, assuming all users behave somewhat similarly. You can save space by minimizing state accesses though.
An on-chain multi-sig was never a great idea. We only do them because we're a blockchain company and so we first think about doing things on-chain. A cryptographic multi-sig would be coordinated off-chain of course, but one could coordinate off-chain even without a cryptographic multi-sig, and place all the signatures into one transaction. All the above are "difficult" in the sense that everything happens closer to the user, which requires the UX be more advanced, and maybe the UX people have more exciting lives. |
@burdges yes, I only left the extrinsic length concern in my comment, as something to consider. Since the proof passed as an extrinsic argument will take a space from the max block length. I agree with @acatangiu and lean toward the XCM solution, but I want to hear @bkchr’s verdict. |
As I said directly at the beginning, do whatever you want. I will not block it. Probably also the proof based solution will be more complicated to implement.
The "poorer UX" argument is not really an argument. When you require to replicate the proxy, you first will need to check if the proxy exists on the destination chain and if not, do the replication. The UX of the replication process will probably be more complicated than providing a proof alongside the transaction.
This is a valid argument, but also the XCM solution depends on the storage layout slightly. For sure it is much more flexible etc when it comes to the storage layout, but you will still require the same data to be present. If you would then want to do this change to include the genesis hash or similar to make it more secure, it would also require some not so trivial migrations and whatever. All in all, I will not block the current RFC. |
from ## Summary
This RFC proposes a solution to replicate an existing pure proxy from one chain to others. The aim is to address the current limitations where pure proxy accounts, which are keyless, cannot have their proxy relationships recreated on different chains. This leads to issues where funds or permissions transferred to the same keyless account address on chains other than its origin chain become inaccessible.