-
Notifications
You must be signed in to change notification settings - Fork 95
Read general account files at genesis #1624
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
base: next
Are you sure you want to change the base?
Changes from all commits
ecab159
3e27b14
94c6916
2a62f1e
04a4606
a89b4c9
6e86241
fa7df9f
bae7946
9a5ee1f
0b42607
3a72972
debc11a
784c5fa
c96f01f
d113e6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are generating them if the accounts are checked-in? As a general rule
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of scope: We should revisit how we deal protobuf generated code too. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,106 @@ | ||
| // This build.rs is required to trigger the `diesel_migrations::embed_migrations!` proc-macro in | ||
| // `store/src/db/migrations.rs` to include the latest version of the migrations into the binary, see <https://docs.rs/diesel_migrations/latest/diesel_migrations/macro.embed_migrations.html#automatic-rebuilds>. | ||
|
|
||
| use std::path::PathBuf; | ||
| use std::sync::Arc; | ||
|
|
||
| use miden_agglayer::{create_existing_agglayer_faucet, create_existing_bridge_account}; | ||
| use miden_protocol::account::{Account, AccountCode, AccountFile}; | ||
| use miden_protocol::{Felt, Word}; | ||
|
|
||
| fn main() { | ||
| println!("cargo:rerun-if-changed=./src/db/migrations"); | ||
| // If we do one re-write, the default rules are disabled, | ||
| // hence we need to trigger explicitly on `Cargo.toml`. | ||
| // <https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed> | ||
| println!("cargo:rerun-if-changed=Cargo.toml"); | ||
|
|
||
| // Generate sample agglayer account files for genesis config samples. | ||
| generate_agglayer_sample_accounts(); | ||
| miden_node_rocksdb_cxx_linkage_fix::configure(); | ||
| } | ||
|
|
||
| /// Generates sample agglayer account files for the `02-with-account-files` genesis config sample. | ||
| /// | ||
| /// Creates: | ||
| /// - `bridge.mac` - agglayer bridge account | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did we document the |
||
| /// - `agglayer_faucet_eth.mac` - agglayer faucet for wrapped ETH | ||
| /// - `agglayer_faucet_usdc.mac` - agglayer faucet for wrapped USDC | ||
| fn generate_agglayer_sample_accounts() { | ||
| // Use CARGO_MANIFEST_DIR to get the absolute path to the crate root | ||
| let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"); | ||
| let samples_dir: PathBuf = | ||
| [&manifest_dir, "src", "genesis", "config", "samples", "02-with-account-files"] | ||
| .iter() | ||
| .collect(); | ||
|
|
||
| // Create the directory if it doesn't exist | ||
| fs_err::create_dir_all(&samples_dir).expect("Failed to create samples directory"); | ||
|
|
||
| // Use deterministic seeds for reproducible builds | ||
| // WARNING: DO NOT USE THIS IN PRODUCTION | ||
| let bridge_seed: Word = Word::new([Felt::new(1u64); 4]); | ||
| let eth_faucet_seed: Word = Word::new([Felt::new(2u64); 4]); | ||
| let usdc_faucet_seed: Word = Word::new([Felt::new(3u64); 4]); | ||
|
|
||
| // Create the bridge account first (faucets need to reference it) | ||
| // Use "existing" variant so accounts have nonce > 0 (required for genesis) | ||
| let bridge_account = create_existing_bridge_account(bridge_seed); | ||
| let bridge_account_id = bridge_account.id(); | ||
|
|
||
| // Create AggLayer faucets using "existing" variant | ||
| // ETH: 18 decimals, max supply of 1 billion tokens | ||
| let eth_faucet = create_existing_agglayer_faucet( | ||
| eth_faucet_seed, | ||
| "ETH", | ||
| 18, | ||
| Felt::new(1_000_000_000), | ||
| bridge_account_id, | ||
| ); | ||
|
|
||
| // USDC: 6 decimals, max supply of 10 billion tokens | ||
| let usdc_faucet = create_existing_agglayer_faucet( | ||
| usdc_faucet_seed, | ||
| "USDC", | ||
| 6, | ||
| Felt::new(10_000_000_000), | ||
| bridge_account_id, | ||
| ); | ||
|
|
||
| // Strip source location decorators from account code to ensure deterministic output. | ||
| let bridge_account = strip_code_decorators(bridge_account); | ||
| let eth_faucet = strip_code_decorators(eth_faucet); | ||
| let usdc_faucet = strip_code_decorators(usdc_faucet); | ||
|
|
||
| // Save account files (without secret keys since these use NoAuth) | ||
| let bridge_file = AccountFile::new(bridge_account, vec![]); | ||
| let eth_faucet_file = AccountFile::new(eth_faucet, vec![]); | ||
| let usdc_faucet_file = AccountFile::new(usdc_faucet, vec![]); | ||
|
|
||
| // Write files | ||
| bridge_file | ||
| .write(samples_dir.join("bridge.mac")) | ||
| .expect("Failed to write bridge.mac"); | ||
| eth_faucet_file | ||
| .write(samples_dir.join("agglayer_faucet_eth.mac")) | ||
| .expect("Failed to write agglayer_faucet_eth.mac"); | ||
| usdc_faucet_file | ||
| .write(samples_dir.join("agglayer_faucet_usdc.mac")) | ||
| .expect("Failed to write agglayer_faucet_usdc.mac"); | ||
| } | ||
|
|
||
| /// Strips source location decorators from an account's code MAST forest. | ||
| /// | ||
| /// This is necessary because the MAST forest embeds absolute file paths from the Cargo build | ||
| /// directory, which include a hash that differs between `cargo check` and `cargo build`. Stripping | ||
| /// decorators ensures the serialized `.mac` files are identical regardless of which cargo command | ||
| /// is used (CI or local builds or tests). | ||
| fn strip_code_decorators(account: Account) -> Account { | ||
| let (id, vault, storage, code, nonce, seed) = account.into_parts(); | ||
|
|
||
| let mut mast = code.mast(); | ||
| Arc::make_mut(&mut mast).strip_decorators(); | ||
| let code = AccountCode::from_parts(mast, code.procedures().to_vec()); | ||
|
|
||
| Account::new_unchecked(id, vault, storage, code, nonce, seed) | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,3 +1,5 @@ | ||||||
| use std::path::PathBuf; | ||||||
|
|
||||||
| use miden_protocol::account::AccountId; | ||||||
| use miden_protocol::errors::{ | ||||||
| AccountDeltaError, | ||||||
|
|
@@ -17,13 +19,21 @@ use crate::genesis::config::TokenSymbolStr; | |||||
| pub enum GenesisConfigError { | ||||||
| #[error(transparent)] | ||||||
| Toml(#[from] toml::de::Error), | ||||||
| #[error("failed to read config file at {path}: {reason}")] | ||||||
| ConfigFileRead { path: PathBuf, reason: String }, | ||||||
| #[error("failed to read account file at {path}: {reason}")] | ||||||
| AccountFileRead { path: PathBuf, reason: String }, | ||||||
| #[error("native faucet from file {path} is not a fungible faucet")] | ||||||
| NativeFaucetNotFungible { path: PathBuf }, | ||||||
| #[error("account translation from config to state failed")] | ||||||
| Account(#[from] AccountError), | ||||||
| #[error("asset translation from config to state failed")] | ||||||
| Asset(#[from] AssetError), | ||||||
| #[error("adding assets to account failed")] | ||||||
| AccountDelta(#[from] AccountDeltaError), | ||||||
| #[error("the defined asset {symbol:?} has no corresponding faucet")] | ||||||
| #[error( | ||||||
| "the defined asset {symbol:?} has no corresponding faucet, or the faucet was provided as an account file" | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should
Suggested change
|
||||||
| )] | ||||||
|
Comment on lines
+34
to
+36
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand how the faucet being specified as an account file is an error, but I'll return to this once I've read the rest. |
||||||
| MissingFaucetDefinition { symbol: TokenSymbolStr }, | ||||||
| #[error("account with id {account_id} was referenced but is not part of given genesis state")] | ||||||
| MissingGenesisAccount { account_id: AccountId }, | ||||||
|
|
||||||
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.
This swallows some errors, i.e. missing, access rights