Compute claimed global index chain hash#2516
Compute claimed global index chain hash#2516Fumuran wants to merge 7 commits intoajl-reorient-claim-note-flowfrom
Conversation
| # save the leaf value to the local memory to reuse it during the computation of the CGI chain | ||
| # hash |
There was a problem hiding this comment.
Nit:
| # save the leaf value to the local memory to reuse it during the computation of the CGI chain | |
| # hash | |
| # save the leaf value to the local memory to reuse it during the computation | |
| # of the CGI hash chain |
| # TODO: once the CLAIM note will be consumed against the bridge contract (and not FPIed against | ||
| # it), store the computed value. Notice that this value is used during the computation of the | ||
| # next CGI chain hash, so the `compute_cgi_hash_chain` procedure should be updated. | ||
| dropw dropw |
There was a problem hiding this comment.
This functionality is available here: #2528
Probably best to add the functionality which stores the CGI hash chain in a separate PR.
There was a problem hiding this comment.
I'll need to update this procedure to test it anyway, so it won't be a big deal to store the CGI hash chain into the memory. But I'm not sure where actually to store it.
It should be stored somewhere in the Bridge account storage, right? But I can't see a storage slot for that. Or is it not created yet, and I need to add it to the From<AggLayerBridge> for AccountComponent implementation?
There was a problem hiding this comment.
a new slot needs to be created to hold it
There was a problem hiding this comment.
Looks great!
I just think we should reuse the pure function test helpers: test_utils::execute_program_with_default_host. I think using execute_program_with_default_host will clean up the test, and also make it possible to not have to have a "copy" of the compute_cgi_hash_chain procedure in the test.
Also lets update references to "chain hash" to "hash chain". Otherwise everything looks great!
| proc compute_cgi_hash_chain_copy | ||
| # load the global index onto the stack | ||
| push.GLOBAL_INDEX_PTR exec.utils::mem_load_double_word | ||
| # => [GLOBAL_INDEX[8], LEAF_VALUE[8]] | ||
|
|
||
| exec.keccak256::merge | ||
| # => [Keccak256(GLOBAL_INDEX, LEAF_VALUE), pad(8)] | ||
|
|
||
| # load the old CGI chain hash | ||
| push.OLD_CGI_CHAIN_HASH_PTR exec.utils::mem_load_double_word | ||
| # => [OLD_CGI_CHAIN_HASH[8], Keccak256(GLOBAL_INDEX, LEAF_VALUE), pad(8)] | ||
|
|
||
| # compute the new CGI chain hash | ||
| exec.keccak256::merge | ||
| # => [NEW_CGI_CHAIN_HASH[8], pad(8)] | ||
| end |
There was a problem hiding this comment.
I'd actually call the real procedure, not a copy of it. I think the asset conversion tests are a good example which show how to do this so that you don't have to run a full transaction.
| "# | ||
| ); | ||
|
|
||
| let tx_script = CodeBuilder::new() |
There was a problem hiding this comment.
I think it would be cleaner if we had the assert_eq! in Rust as opposed to running the test logic in masm. I think it reads easier if you call the masm procedure, get the returned values off the stack in Rust, then check the two Rust variable values are equal. As noted above, we have this testing functions available in the agglayer crate, check out the asset_conversion.rs file to see how they are used
There was a problem hiding this comment.
I recall that we had a discussion about whether we should use asserts in the Rust code vs MASM code, but IIRC we agreed to follow @PhilippGackstatter 's proposal to use asserts in the MASM code, but honestly I don't remember why. Probably to make the code self-contained and, which is more important, to check the error messages correctness in case the testing code uses some of the internal kernel/protocol procedures.
There was a problem hiding this comment.
I think we discussed it at some point, but don't recall the outcome. I think there are pros and cons. Multiple asserts in MASM read relatively nicely and can be done sequentially, as done in this test.
On the other hand, asserts in Rust generally result in a better error when they fail. The downside is if you need to assert the correctness of multiple values, you sometimes need to write extra MASM to arrange the output stack appropriately and then also extract multiple stack values in the right order from the ExecutionOutput, which is messy and incurs unnecessary mental load to review its correctness.
So, I'd use whichever approach results in a more readable and easily maintainble test and one that provides good errors when it fails.
50ab9b1 to
558257d
Compare
| # TODO: once the CLAIM note will be consumed against the bridge contract (and not FPIed against | ||
| # it), store the computed value. Notice that this value is used during the computation of the | ||
| # next CGI chain hash, so the `compute_cgi_hash_chain` procedure should be updated. | ||
| dropw dropw |
There was a problem hiding this comment.
a new slot needs to be created to hold it
mmagician
left a comment
There was a problem hiding this comment.
LGTM, thanks, with small nits only.
Once #2528 is ready and merged into agglayer, we can merge this one too.
Currently, the test here is a unit test, but I would still like to see an integration test (insofar as we can call them integration tests in protocol repo) that checks the expected state of the CGI storage slots after a CLAIM note has been processed. But this could be done either as a follow-up if you want to get unblocked, or as part of this PR - whichever is easier (but it should be done before we release another alpha version)
| # load the old CGI chain hash | ||
| push.CGI_CHAIN_HASH_HI_SLOT_NAME[0..2] | ||
| exec.active_account::get_item | ||
| # => [OLD_CGI_CHAIN_HASH_HI, pad(16)] | ||
|
|
||
| push.CGI_CHAIN_HASH_LO_SLOT_NAME[0..2] | ||
| exec.active_account::get_item | ||
| # => [OLD_CGI_CHAIN_HASH[8], pad(16)] | ||
|
|
||
| # load the pointer to the leaf value onto the stack | ||
| locaddr.0 | ||
| # => [leaf_value_ptr, OLD_CGI_CHAIN_HASH[8], pad(16)] | ||
|
|
||
| # compute the claimed global index chain hash | ||
| exec.compute_cgi_hash_chain | ||
| # => [NEW_CGI_CHAIN_HASH[8], pad(8)] | ||
| # => [NEW_CGI_CHAIN_HASH[8], pad(16)] | ||
|
|
||
| # store the computed CGI chain hash | ||
| # | ||
| # TODO: once the CLAIM note will be consumed against the bridge contract (and not FPIed against | ||
| # it), store the computed value. Notice that this value is used during the computation of the | ||
| # next CGI chain hash, so the `compute_cgi_hash_chain` procedure should be updated. | ||
| dropw dropw | ||
| exec.store_cgi_hash_chain |
There was a problem hiding this comment.
this works, but it would be neater to encapsulate this logic into:
proc update_cgi_hash_chain
# load
# compute new
# store the updated chain hash
end
| # push the expected hash onto the stack | ||
| push.{expected_cgi_hash_hi} exec.word::reverse | ||
| push.{expected_cgi_hash_lo} exec.word::reverse | ||
| # => [EXPECTED_CGI_HASH[8]] |
There was a problem hiding this comment.
nit: I would only push the expected values onto the stack after we've computed the computed values.
| [submodule "crates/miden-agglayer/solidity-compat/lib/openzeppelin-contracts"] | ||
| path = crates/miden-agglayer/solidity-compat/lib/openzeppelin-contracts | ||
| url = https://github.com/OpenZeppelin/openzeppelin-contracts.git | ||
| branch = release-v5.0 | ||
| [submodule "crates/miden-agglayer/solidity-compat/lib/openzeppelin-contracts-upgradeable5"] | ||
| path = crates/miden-agglayer/solidity-compat/lib/openzeppelin-contracts-upgradeable5 | ||
| url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable.git | ||
| branch = release-v5.0 |
There was a problem hiding this comment.
nit: it seems we have a v4 and v5 of the same submodule, is it possible to just have the latest version?
This PR:
bridge_in.masmfile to add the CGI chain hash computation in theverify_leaf_bridgeprocedure. For now it is more like in a "template" state, since for now it is impossible to compute this value: to do so we need to read the previous CGI hash value, but currently it is not store anywhere (yet).verify_leaf_bridgeprocedure (or, to be precise, the value, computed using the same algorithm: I can't reuse thecompute_cgi_hash_chainprocedure itself since it is private and it uses some memory values which are not available during the test) is correct.We still need to store the computed value in memory, but this approach is blocked until we change the way SWAP note it consumed. Storing the CGI hash will be done in a separate PR.
Part of #2386