diff --git a/examples/demo-stf/src/genesis_config.rs b/examples/demo-stf/src/genesis_config.rs index 9b0a64f8d..1b8da3e12 100644 --- a/examples/demo-stf/src/genesis_config.rs +++ b/examples/demo-stf/src/genesis_config.rs @@ -1,7 +1,12 @@ +use std::convert::AsRef; +use std::path::Path; + use anyhow::Context as AnyhowContext; #[cfg(feature = "experimental")] use reth_primitives::Bytes; +use serde::de::DeserializeOwned; use sov_accounts::AccountConfig; +use sov_bank::BankConfig; use sov_chain_state::ChainStateConfig; use sov_cli::wallet_state::PrivateKeyAndAddress; #[cfg(feature = "experimental")] @@ -32,12 +37,9 @@ pub fn get_genesis_config( sequencer_da_address: Da::Address, #[cfg(feature = "experimental")] evm_genesis_addresses: Vec, ) -> GenesisConfig { - // This will be read from a file: #872 - let initial_sequencer_balance = 100000000; let token_deployer: PrivateKeyAndAddress = read_private_key(); create_genesis_config( - initial_sequencer_balance, token_deployer.address.clone(), sequencer_da_address, #[cfg(feature = "experimental")] @@ -47,24 +49,13 @@ pub fn get_genesis_config( } fn create_genesis_config( - initial_sequencer_balance: u64, sequencer_address: C::Address, sequencer_da_address: Da::Address, #[cfg(feature = "experimental")] evm_genesis_addresses: Vec, ) -> anyhow::Result> { - // This will be read from a file: #872 - let token_config: sov_bank::TokenConfig = sov_bank::TokenConfig { - token_name: DEMO_TOKEN_NAME.to_owned(), - address_and_balances: vec![(sequencer_address.clone(), initial_sequencer_balance)], - authorized_minters: vec![sequencer_address.clone()], - salt: 0, - }; - - // This will be read from a file: #872 - let bank_config = sov_bank::BankConfig { - tokens: vec![token_config], - }; - + // This path will be injected as a parameter: #872 + let bank_genesis_path = "../test-data/genesis/bank.json"; + let bank_config: BankConfig = read_json_file(bank_genesis_path)?; // This will be read from a file: #872 let token_address = sov_bank::get_genesis_token_address::( &bank_config.tokens[0].token_name, @@ -84,17 +75,10 @@ fn create_genesis_config( // This path will be injected as a parameter: #872 let value_setter_genesis_path = "../test-data/genesis/value_setter.json"; - let value_setter_data = std::fs::read_to_string(value_setter_genesis_path) - .with_context(|| format!("Failed to read genesis from {}", value_setter_genesis_path))?; - let value_setter_config: ValueSetterConfig = serde_json::from_str(&value_setter_data) - .with_context(|| format!("Failed to parse genesis from {}", value_setter_genesis_path))?; + let value_setter_config: ValueSetterConfig = read_json_file(value_setter_genesis_path)?; let accounts_genesis_path = "../test-data/genesis/accounts.json"; - let accounts_data = std::fs::read_to_string(accounts_genesis_path) - .with_context(|| format!("Failed to read genesis from {}", accounts_genesis_path))?; - - let accounts_config: AccountConfig = serde_json::from_str(&accounts_data) - .with_context(|| format!("Failed to parse genesis from {}", accounts_genesis_path))?; + let accounts_config: AccountConfig = read_json_file(accounts_genesis_path)?; let nft_config = sov_nft_module::NonFungibleTokenConfig {}; // This will be read from a file: #872 @@ -117,6 +101,17 @@ fn create_genesis_config( )) } +fn read_json_file>(path: P) -> anyhow::Result { + let path_str = path.as_ref().display(); + + let data = std::fs::read_to_string(&path) + .with_context(|| format!("Failed to read genesis from {}", path_str))?; + let config: T = serde_json::from_str(&data) + .with_context(|| format!("Failed to parse genesis from {}", path_str))?; + + Ok(config) +} + // TODO: #840 #[cfg(feature = "experimental")] fn get_evm_config(genesis_addresses: Vec) -> EvmConfig { diff --git a/examples/test-data/genesis/bank.json b/examples/test-data/genesis/bank.json new file mode 100644 index 000000000..35b065659 --- /dev/null +++ b/examples/test-data/genesis/bank.json @@ -0,0 +1,10 @@ +{ + "tokens":[ + { + "token_name":"sov-demo-token", + "address_and_balances":[["sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94",100000000]], + "authorized_minters":["sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94"] + ,"salt":0 + } + ] +} \ No newline at end of file diff --git a/module-system/module-implementations/sov-bank/src/lib.rs b/module-system/module-implementations/sov-bank/src/lib.rs index 7f3cece42..99d194bd8 100644 --- a/module-system/module-implementations/sov-bank/src/lib.rs +++ b/module-system/module-implementations/sov-bank/src/lib.rs @@ -6,12 +6,14 @@ mod genesis; mod query; #[cfg(feature = "native")] pub use query::*; +#[cfg(test)] +mod tests; mod token; /// Util functions for bank pub mod utils; - /// Specifies the call methods using in that module. pub use call::CallMessage; +use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use sov_modules_api::{CallResponse, Error, GasUnit, ModuleInfo, WorkingSet}; use token::Token; @@ -22,7 +24,8 @@ pub use utils::{get_genesis_token_address, get_token_address}; /// [`TokenConfig`] specifies a configuration used when generating a token for the bank /// module. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] +#[serde(bound = "C::Address: Serialize + DeserializeOwned")] pub struct TokenConfig { /// The name of the token. pub token_name: String, @@ -35,7 +38,8 @@ pub struct TokenConfig { } /// Initial configuration for sov-bank module. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] +#[serde(bound = "C::Address: Serialize + DeserializeOwned")] pub struct BankConfig { /// A list of configurations for the initial tokens. pub tokens: Vec>, diff --git a/module-system/module-implementations/sov-bank/src/tests.rs b/module-system/module-implementations/sov-bank/src/tests.rs new file mode 100644 index 000000000..0e5661a10 --- /dev/null +++ b/module-system/module-implementations/sov-bank/src/tests.rs @@ -0,0 +1,39 @@ +use std::str::FromStr; + +use sov_modules_api::default_context::DefaultContext; +use sov_modules_api::{AddressBech32, Spec}; + +use crate::{BankConfig, TokenConfig}; + +#[test] +fn test_config_serialization() { + let address: ::Address = + AddressBech32::from_str("sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94") + .unwrap() + .into(); + + let config = BankConfig:: { + tokens: vec![TokenConfig { + token_name: "sov-demo-token".to_owned(), + address_and_balances: vec![(address, 100000000)], + authorized_minters: vec![address], + salt: 0, + }], + }; + + let data = r#" + { + "tokens":[ + { + "token_name":"sov-demo-token", + "address_and_balances":[["sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94",100000000]], + "authorized_minters":["sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94"] + ,"salt":0 + } + ] + }"#; + + let parsed_config: BankConfig = serde_json::from_str(data).unwrap(); + + assert_eq!(config, parsed_config) +}