From 4725efa8d560fe9fca31a21c45404851c2bb6539 Mon Sep 17 00:00:00 2001
From: 0o-de-lally <1364012+0o-de-lally@users.noreply.github.com>
Date: Thu, 5 Dec 2024 10:40:13 -0500
Subject: [PATCH] add community wallet flag to snapshot state

---
 src/extract_snapshot.rs     | 10 ++++++++-
 src/schema_account_state.rs |  8 +++++--
 tests/test_load_state.rs    | 43 +++++++++++++++++++++++++++++++++++--
 3 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/src/extract_snapshot.rs b/src/extract_snapshot.rs
index 4f7a812..e492c24 100644
--- a/src/extract_snapshot.rs
+++ b/src/extract_snapshot.rs
@@ -10,7 +10,10 @@ use libra_backwards_compatibility::version_five::{
 use libra_storage::read_snapshot::{accounts_from_snapshot_backup, load_snapshot_manifest};
 use libra_types::{
     exports::AccountAddress,
-    move_resource::{libra_coin::LibraCoinStoreResource, wallet::SlowWalletResource},
+    move_resource::{
+        cumulative_deposits::CumulativeDepositResource, libra_coin::LibraCoinStoreResource,
+        wallet::SlowWalletResource,
+    },
 };
 use log::{error, info, warn};
 
@@ -112,6 +115,11 @@ pub async fn extract_current_snapshot(archive_path: &Path) -> Result<Vec<Warehou
                 s.slow_wallet_transferred = sw.transferred;
             }
 
+            // Infer if it is a donor voice account
+            if let Some(_sw) = el.get_resource::<CumulativeDepositResource>()? {
+                s.donor_voice_acc = true;
+            }
+
             warehouse_state.push(s);
         }
     }
diff --git a/src/schema_account_state.rs b/src/schema_account_state.rs
index ad9f858..a44fc3d 100644
--- a/src/schema_account_state.rs
+++ b/src/schema_account_state.rs
@@ -19,6 +19,7 @@ pub struct WarehouseAccState {
     pub balance: u64,
     pub slow_wallet_locked: u64,
     pub slow_wallet_transferred: u64,
+    pub donor_voice_acc: bool,
 }
 
 impl Default for WarehouseAccState {
@@ -30,6 +31,7 @@ impl Default for WarehouseAccState {
             balance: Default::default(),
             slow_wallet_locked: Default::default(),
             slow_wallet_transferred: Default::default(),
+            donor_voice_acc: false,
         }
     }
 }
@@ -43,6 +45,7 @@ impl WarehouseAccState {
             balance: 0,
             slow_wallet_locked: 0,
             slow_wallet_transferred: 0,
+            donor_voice_acc: false,
         }
     }
     pub fn set_time(&mut self, timestamp: u64, version: u64, epoch: u64) {
@@ -57,7 +60,7 @@ impl WarehouseAccState {
     /// Note original data was in an RFC rfc3339 with Z for UTC, Cypher seems to prefer with offsets +00000
     pub fn to_cypher_object_template(&self) -> String {
         format!(
-            r#"{{address: "{}", balance: {}, version: {}, sequence_num: {}, slow_locked: {}, slow_transfer: {}, framework_version: "{}" }}"#,
+            r#"{{address: "{}", balance: {}, version: {}, sequence_num: {}, slow_locked: {}, slow_transfer: {}, framework_version: "{}", donor_voice: {} }}"#,
             self.address.to_hex_literal(),
             self.balance,
             self.time.version,
@@ -65,6 +68,7 @@ impl WarehouseAccState {
             self.slow_wallet_locked,
             self.slow_wallet_transferred,
             self.time.framework_version,
+            self.donor_voice_acc,
         )
     }
 
@@ -87,7 +91,7 @@ impl WarehouseAccState {
   UNWIND tx_data AS tx
 
   MERGE (addr:Account {{address: tx.address}})
-  MERGE (snap:Snapshot {{address: tx.address, balance: tx.balance, framework_version: tx.framework_version, version: tx.version, sequence_num: tx.sequence_num, slow_locked: tx.slow_locked, slow_transfer: tx.slow_transfer }})
+  MERGE (snap:Snapshot {{address: tx.address, balance: tx.balance, framework_version: tx.framework_version, version: tx.version, sequence_num: tx.sequence_num, slow_locked: tx.slow_locked, slow_transfer: tx.slow_transfer, donor_voice: tx.donor_voice }})
   MERGE (addr)-[rel:State {{version: tx.version}} ]->(snap)
 
   RETURN
diff --git a/tests/test_load_state.rs b/tests/test_load_state.rs
index cb93665..cabea63 100644
--- a/tests/test_load_state.rs
+++ b/tests/test_load_state.rs
@@ -1,13 +1,14 @@
 mod support;
 
 use libra_forensic_db::{
-    extract_snapshot::extract_v5_snapshot,
+    extract_snapshot::{extract_current_snapshot, extract_v5_snapshot},
     load_account_state::{impl_batch_snapshot_insert, snapshot_batch},
     neo4j_init::{get_neo4j_localhost_pool, maybe_create_indexes},
     schema_account_state::WarehouseAccState,
 };
 use support::{
-    fixtures::v5_state_manifest_fixtures_path, neo4j_testcontainer::start_neo4j_container,
+    fixtures::{v5_state_manifest_fixtures_path, v7_state_manifest_fixtures_path},
+    neo4j_testcontainer::start_neo4j_container,
 };
 
 #[tokio::test]
@@ -36,6 +37,44 @@ async fn test_snapshot_unit() -> anyhow::Result<()> {
 
 #[tokio::test]
 async fn test_snapshot_batch() -> anyhow::Result<()> {
+    libra_forensic_db::log_setup();
+    let manifest_file = v7_state_manifest_fixtures_path().join("state.manifest");
+    assert!(manifest_file.exists());
+    let vec_snap = extract_current_snapshot(&manifest_file).await?;
+
+    let c = start_neo4j_container();
+    let port = c.get_host_port_ipv4(7687);
+    let graph = get_neo4j_localhost_pool(port)
+        .await
+        .expect("could not get neo4j connection pool");
+    maybe_create_indexes(&graph)
+        .await
+        .expect("could start index");
+
+    let merged_snapshots = impl_batch_snapshot_insert(&graph, &vec_snap[..100]).await?;
+    dbg!(&merged_snapshots.created_tx);
+    // assert!(merged_snapshots.created_tx == 100);
+
+    // check DB to see what is persisted
+    let cypher_query = neo4rs::query(
+        "MATCH ()-[r:State]->()
+         RETURN count(r) AS count_state_edges",
+    );
+
+    // Execute the query
+    let mut result = graph.execute(cypher_query).await?;
+
+    // Fetch the first row only
+    let row = result.next().await?.unwrap();
+    let count: i64 = row.get("count_state_edges").unwrap();
+    dbg!(&count);
+    // assert!(count == 100i64);
+
+    Ok(())
+}
+
+#[tokio::test]
+async fn test_v5_snapshot_batch() -> anyhow::Result<()> {
     libra_forensic_db::log_setup();
     let manifest_file = v5_state_manifest_fixtures_path().join("state.manifest");
     assert!(manifest_file.exists());