Generalized storage proofs

Last week as we discussed the recovery of parachains I came up with this crazy idea of supporting to call into wasm blobs of other parachains while validating a parachain block. The idea there was to provide a common interface for verifying proofs that are opaque to the caller, but should be interpret-able by the callee aka the wasm blob of the parachain from where we have extracted the proof. Relay chain validators already have all or most of the parachain wasm blobs pre-compiled, so that calling them should be fairly cheap. However, this probably brings a lot of other problems with it that we don’t want to start with. Simple issues like, how much memory would this sub instance get or what are we doing if the validator hasn’t yet pre-compiled the wasm? There is probably an endless stream of issues with this. On the parachain side we would then also need to support importing these blocks without needing to have the blob of the other parachain available anymore. While building we would require these blobs and it should be fairly simple to get them, but at import it gets more complicated.

So, we should forget this idea. However, the general idea of having standardized interface for checking these proofs sounds like something we could think more about. In general this goes into the direction of SPREE I would say. Instead of using the actual parachain wasm blob to verify a certain proof, we could introduce wasm blobs which are only providing certain functionality. We could experiment with using wasmi inside the runtime to execute these blobs, similar to what pallet_contracts is doing. However, we could trust these blobs “more”. One of the questions would be on where these extra blobs are stored. Are they stored in the chain that wants to verify a proof? Then we would need to put these extra blobs into the PoV when sending it to the relay chain. Could we maybe put this into the relay chain and make them accessible by the parachain validation? I mean we would only need to provide the blob and the execution would happen inside the validation blob using wasmi. A lot of that boils down to the question on how big these blobs are and how fast the execution with wasmi is.

Another question would also be on what kind of interfaces we would need to support? Maybe for certain things we could get away with some generic verify_proof(key: Vec<u8>, known_head: Vec<u8>, proof: Vec<u8>) -> Option<Vec<u8>>. Where you pass the key and the proof and then it returns the value it found for this key in the proof. In the chain that wants to have a proof of a different chain verified, the call that is doing this verification would take the proof and the expected_value that should be found in the proof. While writing this I realized that we would also need to know the key and we can not trust the caller of our call to give us the correct key. So, this interface wouldn’t really work and we would need much more specialized interfaces like extract_balance_from_proof(user: Vec<u8>, known_head: Vec<u8>, proof: Vec<u8>) -> u128. Not sure on how many of these interfaces we would need.

See this post as some kind of brain dump. It doesn’t really give any great solution, just some ideas to think about. I hope that this may inspires someone else to come up with a great idea :slight_smile: Or we can just iterate on these ideas, try them and see where they bring us. I think in general with runtime upgrades etc where are really good suited to play around with ideas to come up with solutions :slight_smile:

3 Likes