Просмотр исходного кода

script/research/state_usage_analyser: txs simulation to measure ram usage

aggstam 4 лет назад
Родитель
Сommit
99107d4d87

+ 2 - 0
script/research/state_usage_analyser/.gitignore

@@ -0,0 +1,2 @@
+/target
+Cargo.lock

+ 18 - 0
script/research/state_usage_analyser/Cargo.toml

@@ -0,0 +1,18 @@
+[package]
+name = "state_usage_analyser"
+version = "0.3.0"
+edition = "2021"
+
+[dependencies]
+async-std = {version = "1.12.0", features = ["attributes"]}
+bincode = "1.3.3"
+darkfi = {path = "../../../", features = ["blockchain"]}
+incrementalmerkletree = "0.3.0"
+lazy-init = "0.5.1"
+log = "0.4.17"
+pasta_curves = "0.4.0"
+rand = "0.8.5"
+serde = {version = "1.0.142", features = ["derive"]}
+sled = "0.34.7"
+
+[workspace]

+ 136 - 0
script/research/state_usage_analyser/src/main.rs

@@ -0,0 +1,136 @@
+use async_std::sync::{Arc, Mutex};
+use incrementalmerkletree::bridgetree::BridgeTree;
+use lazy_init::Lazy;
+use pasta_curves::{group::ff::Field, pallas::Base};
+use rand::rngs::OsRng;
+use serde::ser::{Serialize, SerializeStruct, Serializer};
+
+use darkfi::{
+    blockchain::Blockchain,
+    consensus::{TESTNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_TIMESTAMP},
+    crypto::{
+        constants::MERKLE_DEPTH,
+        keypair::{PublicKey, SecretKey},
+        merkle_node::MerkleNode,
+    },
+    node::{
+        state::{state_transition, ProgramState},
+        Client, MemoryState, State,
+    },
+    util::{cli::progress_bar, expand_path},
+    wallet::walletdb::init_wallet,
+};
+
+// Auxiliary struct to Serialize BridgeTree
+struct BridgeTreeWrapper {
+    tree: BridgeTree<MerkleNode, MERKLE_DEPTH>,
+}
+
+impl Serialize for BridgeTreeWrapper {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        let mut state = serializer.serialize_struct("BridgeTreeWrapper", 1)?;
+        state.serialize_field("tree", &self.tree)?;
+        state.end()
+    }
+}
+
+pub fn bridge_tree_usage(prefix: &str, tree: BridgeTree<MerkleNode, MERKLE_DEPTH>) {
+    let wrapper = BridgeTreeWrapper { tree };
+    let encoded: Vec<u8> = bincode::serialize(&wrapper).unwrap();
+    let size = ::std::mem::size_of_val(&*encoded);
+    println!("  {} size: {:?} Bytes", prefix, size);
+}
+
+#[async_std::main]
+async fn main() -> darkfi::Result<()> {
+    // Config
+    let folder = "~/.config/darkfi/merkle_testing";
+    let genesis_ts = *TESTNET_GENESIS_TIMESTAMP;
+    let genesis_data = *TESTNET_GENESIS_HASH_BYTES;
+    let pass = "changeme";
+
+    // Initialize
+    let pb = progress_bar("Initializing wallet...");
+    let path = folder.to_owned() + "/wallet.db";
+    let wallet = init_wallet(&path, &pass).await?;
+    let client = Arc::new(Client::new(wallet.clone()).await?);
+    let address = wallet.get_default_address().await?;
+    let pubkey = PublicKey::try_from(address)?;
+    pb.finish();
+
+    let pb = progress_bar("Initializing sled database...");
+    let path = folder.to_owned() + "/blockchain/testnet";
+    let db_path = expand_path(&path).unwrap();
+    let sled_db = sled::open(&db_path)?;
+    pb.finish();
+
+    let pb = progress_bar("Generating state machine...");
+    let blockchain = Blockchain::new(&sled_db, genesis_ts, genesis_data)?;
+    let state_machine = State {
+        tree: client.get_tree().await?,
+        merkle_roots: blockchain.merkle_roots.clone(),
+        nullifiers: blockchain.nullifiers.clone(),
+        cashier_pubkeys: vec![],
+        faucet_pubkeys: vec![pubkey.clone()],
+        mint_vk: Lazy::new(),
+        burn_vk: Lazy::new(),
+    };
+    pb.finish();
+
+    let pb = progress_bar("Creating zk proof verification keys...");
+    let _ = state_machine.mint_vk();
+    let _ = state_machine.burn_vk();
+    pb.finish();
+
+    let pb = progress_bar("Generating memory state and secret keys...");
+    let canon_state_clone = state_machine.clone();
+    let mut state = state_machine;
+    let mut mem_state = MemoryState::new(canon_state_clone);
+    let state_arc = Arc::new(Mutex::new(state.clone()));
+
+    let secret_keys: Vec<SecretKey> =
+        client.get_keypairs().await?.iter().map(|x| x.secret).collect();
+    pb.finish();
+
+    // Initial size
+    bridge_tree_usage("Original state", state.tree.clone());
+
+    // Create txs token
+    let token_id = Base::random(&mut OsRng);
+    let amount = 1;
+
+    // Generating and applying transactions
+    let txs = 5;
+    println!("  Applying {} transactions...", txs);
+    for i in 0..txs {
+        println!("    tx {}", i);
+        let tx =
+            match client.build_transaction(pubkey, amount, token_id, true, state_arc.clone()).await
+            {
+                Ok(v) => v,
+                Err(e) => {
+                    println!("Failed building transaction: {}", e);
+                    return Err(e.into())
+                }
+            };
+
+        let update = match state_transition(&mem_state, tx.clone()) {
+            Ok(v) => v,
+            Err(e) => {
+                println!("validate_state_transition(): Failed for tx {}: {}", i, e);
+                return Err(e.into())
+            }
+        };
+
+        mem_state.apply(update.clone());
+        state.apply(update, secret_keys.clone(), None, client.wallet.clone()).await?;
+    }
+
+    // Final size
+    bridge_tree_usage("Final state", state.tree);
+
+    Ok(())
+}