Skip to content
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

Upgradable fraud proof verification and ER derivation #2712

Open
NingLin-P opened this issue Apr 24, 2024 · 3 comments
Open

Upgradable fraud proof verification and ER derivation #2712

NingLin-P opened this issue Apr 24, 2024 · 3 comments

Comments

@NingLin-P
Copy link
Member

NingLin-P commented Apr 24, 2024

The fraud proof is essentially proof of the ER derivation process and it is proving something happened in the past. Both fraud proof verification and ER derivation MUST keep consistency otherwise the attacker can possibly submit FP to target valid ER (produced by the honest operator) or submit bad ER that can't targeted by FP.

Since the FP is proving something happened in the past we must use both the data and logic from the past, while we already use storage proof of the historical domain state and domain runtime code and working on storage proof of the consensus state, there is one important missing piece which is the consensus runtime.

The logic of the FP verification and ER derivation that involved consensus runtime can fall into the following categories:

  1. The logic exists in both the consensus runtime and the operator client, the code is different but will return the same result (e.g. inherent extrinsic order)
    • Can easily cause inconsistency if we update the logic in one place but forget another (like the extrinsic order we found in 3h)
  2. The logic exists in a shared crate that is used by both the consensus runtime and the operator client (e.g. extrinsic deduplicate and shuffle)
    • Better than 1 but can still cause inconsistency in practice, since runtime upgrade is done automatically while client upgrade is not, can cause honest operators who didn't upgrade get slash.
  3. The logic only exists in the consensus runtime and the operator needs to call the consensus runtime API (e.g. tx-range, consensus transaction byte fee)
    • Better than 2 but still have issues, because the FP is verified against the best block which means the latest consensus runtime is used, while FP is proving something happened in the past so the historical consensus runtime should be used, otherwise, after the consensus runtime logic is upgraded the attacker can submit FP to target ER that produced previously with old runtime by the honest operator.

3 is the best we have so far and we should convert 1 & 2 into 3, to fix the remaining issue of 3 we can:

  • First, make these logics stateless and not access any state
    • If it does require some state, FP verification can get the state from storage proof and pass in as an argument and ER derivation can just use runtime API call since it is in the client
  • Then use the correct consensus runtime and call the stateless runtime call
    • FP verification can get the runtime from a storage proof and ER derivation can just use runtime API call since it is in the client

Another better approach is to introduce a dedicated lightweight runtime, which only contains the necessary logic for FP verification and ER derivation, it can be stored in the consensus chain and can be upgraded just like the domain runtime. Also, storage proof of the runtime code can be replaced by storage proof of the runtime hash in most cases, since runtime upgrade is rare we can get the runtime code from the latest state just need to ensure it has the same hash.

cc @vedhavyas @nazar-pc

@dariolina
Copy link
Member

dariolina commented May 8, 2024

This feels a duplicate of #2082 however the discussion there may not be relevant anymore since we have MMR now.
UPD: this not duplicate but separate issues

@nazar-pc
Copy link
Member

nazar-pc commented May 9, 2024

I think I agree with general conclusion, but the question still remains where to get the correct consensus runtime. Since it is technically just state as well, we could have MMR proof that something was a valid consensus runtime in the past, but attaching it as part of the proof both constrains the size of consensus runtime and the size of domain storage proof that domain can use, both of which are not ideal.

@NingLin-P
Copy link
Member Author

There are 2 things we can do to reduce the size:

  1. Use the compressed consensus runtime code
864K    ../../target/release/wbuild/subspace-runtime/subspace_runtime.compact.compressed.wasm
4.1M    ../../target/release/wbuild/subspace-runtime/subspace_runtime.compact.wasm
3.6M    ../../target/release/wbuild/subspace-runtime/subspace_runtime.wasm
  1. Extract the necessary logic related to FP verification and ER derivation to a dedicated lightweight runtime

This runtime can be stored and upgraded just like the domain runtime but can't be instantiated like them, this runtime only used in 2 places:

  • FP verification in the consensus runtime, similar to the domain runtime code, this runtime is fetch from the consensus runtime state or storage proof, and used in the host function when verifying a FP
  • ER derivation in the domain client, a runtime instance will be created at node start and used for ER derivation until this runtime is upgraded by then a new runtime instance will be created from the new runtime code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants