chore: add accounts creation for network monitor#1276
chore: add accounts creation for network monitor#1276SantiagoPittella merged 33 commits intonextfrom
Conversation
1cb7884 to
d11a4ea
Compare
igamigo
left a comment
There was a problem hiding this comment.
Leaving some comments after the offline discussion
| use.external_contract::counter_contract | ||
|
|
||
| begin | ||
| call.counter_contract::increment |
There was a problem hiding this comment.
If this is used as a transaction script on #1280 (should it be moved to that PR?), it will fail every time because the get_sender call only applies at the moment of note processing (and in general, any getter under active_note)
There was a problem hiding this comment.
I removed the sender validations temporarily, since it was complicating things i wanted to first have a simpler version working and then add it after.
Since this change made the deployment to be easier, I merge #1280 here and now we have the complete workflow. I will now work on sending the increment counter requests and display it in the frontend.
There was a problem hiding this comment.
I would maybe put the authentication logic into counter_contract::increment since we want the counter contract to decide which notes to accept (rather than for notes to decide which accounts can consume them). To do this, we'd need to store the "owner" account ID in the storage slot together with the counter as well, and then before we increment, check that owner_id == note.sender.
There was a problem hiding this comment.
I added it here, but fixed some small things in #1295 where it is actually tested.
| push.0 | ||
| # => [0] | ||
|
|
||
| exec.account::get_item | ||
| # => [count] |
There was a problem hiding this comment.
nit: Some of these could be grouped for better readability:
| push.0 | |
| # => [0] | |
| exec.account::get_item | |
| # => [count] | |
| push.0 exec.account::get_item | |
| # => [count] |
e1f2703 to
0040d14
Compare
* chore: add accounts creation command * wip: deploy accounts * chore: deploy counter account
| let prover_url_clone = prover_url.clone(); | ||
| let name_clone = name.clone(); | ||
| // SAFETY: we matched Some above | ||
| let proof_type = proof_type.unwrap(); |
There was a problem hiding this comment.
nit: would do .expect("proof type is not none") instead of safety comment
bobbinth
left a comment
There was a problem hiding this comment.
Looks good! Thank you. I left some comments inline.
Yes. I did exactly that in the first implementation that I did of the procedures, but ATM I'm using the increment to deploy the network account too, so it was incompatible due to the account ID check failing (the sender was the network account itself and not the wallet) |
|
I replaced the deployment, adding authentication and a call to get_count instead of the counter increase, so the nonce is increased but we dont need to go through the account ID match verification for deployment. |
| let account_code = AccountComponent::compile( | ||
| script, | ||
| TransactionKernel::assembler(), | ||
| vec![StorageSlot::empty_value(), StorageSlot::Value(owner_word)], | ||
| )? | ||
| .with_supports_all_types(); | ||
|
|
||
| const INCR_NONCE_AUTH_CODE: &str = r" | ||
| use.miden::account | ||
| use.std::sys | ||
|
|
||
| export.auth__basic | ||
| exec.account::incr_nonce | ||
| drop | ||
| end | ||
| "; | ||
|
|
||
| let incr_nonce_auth = | ||
| AccountComponent::compile(INCR_NONCE_AUTH_CODE, TransactionKernel::assembler(), vec![]) | ||
| .context("failed to compile increment nonce auth component")? | ||
| .with_supports_all_types(); |
There was a problem hiding this comment.
I wonder if IncrNonce component from the mock tools from miden-testing can be used here instead (I think they are pretty much equivalent).
There was a problem hiding this comment.
Yes! It is equivalent. I;m replacing it since we already use miden testing.
| use.miden::account | ||
| use.std::sys | ||
|
|
||
| export.auth__basic |
There was a problem hiding this comment.
nit: I'm not 100% sure, but I believe having two underscores is not required anymore (ie, auth_basic would work)
There was a problem hiding this comment.
It was removed in the replacement with miden testing
|
|
||
| // Compile the account code | ||
| let owner_felts: [Felt; 2] = owner_account_id.into(); | ||
| let owner_word = Word::from([owner_felts[0], owner_felts[1], Felt::new(0), Felt::new(0)]); |
There was a problem hiding this comment.
Based on how these will be used, would it be better to arrange them differently?
| let owner_word = Word::from([owner_felts[0], owner_felts[1], Felt::new(0), Felt::new(0)]); | |
| let owner_word = Word::from([Felt::ZERO, Felt::ZERO, owner_felts[1], owner_felts[0]]); |
There was a problem hiding this comment.
Should it like this? It the prefix first and then the suffix
| let owner_word = Word::from([owner_felts[0], owner_felts[1], Felt::new(0), Felt::new(0)]); | |
| let owner_word = Word::from([Felt::new(0), Felt::new(0), owner_felts[0], owner_felts[1]]); |
There was a problem hiding this comment.
Oh no, you're right, i see why.
| .with_auth_component(incr_nonce_auth) | ||
| .build()?; | ||
|
|
||
| Ok(counter_program) |
There was a problem hiding this comment.
nit: "program" is a bit misleading, I've seen people name this "counter contract" or "counter account"
| # Ensure the note sender matches the authorized wallet stored in slot 1. | ||
| push.0 exec.input_note::get_sender | ||
| # => [sender_prefix, sender_suffix] | ||
| push.1 exec.account::get_item | ||
| # => [sender_prefix, sender_suffix, owner_prefix, owner_suffix, 0, 0] | ||
| movup.3 drop | ||
| movup.2 drop | ||
| # => [sender_prefix, sender_suffix, owner_prefix, owner_suffix] | ||
| exec.account_id::is_equal | ||
| assert |
There was a problem hiding this comment.
I think the ordering on the stack comments may not be correct here. Now that I see how the account is set up, I also think what I commented offline was not fully correct either. If the ordering of the owner word is as in this other comment, I believe you should be able to do something like:
push.1 exec.account::get_item
# => [owner_prefix, owner_suffix, 0, 0]
exec.active_note::get_sender
# => [sender_prefix, sender_suffix, owner_prefix, owner_suffix, 0, 0]
exec.account_id::is_equal
# => [are_equal, 0, 0]
assert drop drop
(but maybe this is not fully correct either, I have not run it)
| if wallet_exists && counter_exists { | ||
| tracing::info!("Account files already exist, skipping account creation"); | ||
| return Ok(()); | ||
| } |
There was a problem hiding this comment.
I think this shouldn't matter too much outside of testing (where one may want to reset the state of at least one of the accounts), but if somehow only one of these were false, both accounts would be created again. Maybe this was intended but mentioning it just in case.
There was a problem hiding this comment.
If only the wallet does not exists, the counter needs to be created again (since it is coupled to a wallet). The other way (wallet exists but not the counter) might be possible and should work
There was a problem hiding this comment.
Despite that it should work to deploy a new counter with an existing account, we probably want to use a new wallet to keep some consistency between accounts, wdyt? I can comment it in the check
There was a problem hiding this comment.
Ah yes, thanks for the explanation. Makes sense! I think always re-creating both should be fine.
bin/network-monitor/README.md
Outdated
| 1. Checks for existing account files on startup | ||
| 2. Creates new accounts if files don't exist | ||
| 3. Deploys accounts to the network via RPC | ||
| 4. Uses the specified file paths (default: `wallet_account.bin` and `counter_program.bin`) |
There was a problem hiding this comment.
nit: When using AccountFile, we've used the .mac suffix for files. Also, I'd mention that the files are saved in the paths:
| 4. Uses the specified file paths (default: `wallet_account.bin` and `counter_program.bin`) | |
| 4. Saves the wallet and counter contract account in the specified file paths (default: `wallet_account.mac` and `counter_program.mac`) |
There was a problem hiding this comment.
I was trying to test this locally and saw that the default port does not match with the node's default (altohugh in the env file it seems to be correct). Should it be changed here as well?
| const DEFAULT_RPC_URL: &str = "http://localhost:57291"; |
bobbinth
left a comment
There was a problem hiding this comment.
Looks good! Thank you! I left a few more small comments inline, and I think there are some comments from @igamigo that still need to be addressed.
Also, we should rebase this from the latest next now that it is updated to v0.12.0 miden-base.
igamigo
left a comment
There was a problem hiding this comment.
LGTM! Left a few comments. Let me know if they are not clear. Overall though, they are mostly optional and so this should be good to merge.
One more thing: it would be great to test this somehow to make sure we catch functional drifts without having to manually run the monitor (similar to the stress test). This would include either mocking the node or running an integration test, so it could be left for a different issue.
| .map_err(|e| anyhow::anyhow!("Failed to assemble library: {e}")) | ||
| } | ||
|
|
||
| // MONITOR DATA STORE |
There was a problem hiding this comment.
nit: I'd probably move this to its own mod
There was a problem hiding this comment.
Since it is not too large and only used in this same file, I think that leaving it here is fine. Maybe we can consider to move it if we start to use it somewhere else, wdyt?
There was a problem hiding this comment.
Yeah, sounds good. Not a strong opinion bjut it felt like the executor side of things could be refactored into its own submodule, but I agree it's probably premature
| /// Deploy accounts to the network. | ||
| /// | ||
| /// This function creates both a wallet account and a counter program account, | ||
| /// then saves them to the specified files. | ||
| #[instrument(target = COMPONENT, name = "deploy-accounts", skip_all, ret(level = "debug"))] | ||
| pub async fn deploy_accounts( | ||
| wallet_account: &Account, | ||
| counter_account: &Account, | ||
| rpc_url: &Url, | ||
| ) -> Result<()> { |
There was a problem hiding this comment.
I think part of the doc comment is outdated. Also, really only the counter account gets deployed to the network, right? So maybe it could be named deploy_counter_contract
There was a problem hiding this comment.
It was already changed with deploy_counter_account in the follow up PR https://github.com/0xMiden/miden-node/pull/1295/files already
| # Transaction script used during deployment to bump the counter contract nonce | ||
| # without changing the counter value. |
There was a problem hiding this comment.
I think transaction scripts are not needed anymore for this. I'd try removing it and executing without a script.
There was a problem hiding this comment.
Awesome, tested it and works. I remvoed the deploy tx script.
| let account = self.wallet_account.lock().await; | ||
|
|
||
| let account = if account_id == account.id() { | ||
| account.to_owned() | ||
| } else { | ||
| self.counter_account.lock().await.to_owned() | ||
| }; | ||
|
|
||
| let mut map_witness = None; | ||
| for slot in account.storage().slots() { | ||
| if let StorageSlot::Map(map) = slot { | ||
| if map.root() == map_root { | ||
| map_witness = Some(map.open(&map_key)); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if let Some(map_witness) = map_witness { | ||
| Ok(map_witness) | ||
| } else { | ||
| Err(DataStoreError::Other { | ||
| error_msg: "account storage does not contain the expected root".into(), | ||
| source: None, | ||
| }) | ||
| } |
There was a problem hiding this comment.
In get_transaction_inputs you are instantiating the partial accounts with PartialAccount::from. If you include all the account data (I think you'd need to use PartialAccount::new), I think you should be able to remove the implementations of these methods. I would test removing them. We can also keep them, but it's more maintenance overhead + more code to test.
There was a problem hiding this comment.
Removing the get_storage_map_witness worked when removing while using PartialAccount::new, that was not the case for get_vault_asset_witness.
There was a problem hiding this comment.
Interesting, I wonder why that was? I don't think assets are involved in these flows.
There was a problem hiding this comment.
I'll do further investigation after merging this PR 👍🏼
part of #1190
Added the account creations and deployment in this first version.
I'm working on another PR in the periodic value increments, and i'm leaving authentication as the last part.