Skip to main content

neo_devpack_solidity/runtime/storage/storage_impl/manager/
query.rs

1use super::*;
2
3impl StorageManager {
4    /// Query storage with filters
5    pub fn query(&mut self, query: StorageQuery) -> Result<StorageEntries, RuntimeError> {
6        let mut results = Vec::new();
7
8        if let Some(account_storage) = self.storage.get(&query.account) {
9            // Collect from committed storage
10            for (key, value) in &account_storage.storage {
11                if let Some(ref prefix) = query.key_prefix {
12                    if !key.starts_with(prefix) {
13                        continue;
14                    }
15                }
16                results.push((key.clone(), value.clone()));
17            }
18
19            // Include pending changes if requested
20            if query.include_pending {
21                for (key, change) in &account_storage.pending_changes {
22                    if let Some(ref prefix) = query.key_prefix {
23                        if !key.starts_with(prefix) {
24                            continue;
25                        }
26                    }
27
28                    match &change.change_type {
29                        StorageChangeType::Delete => {
30                            results.retain(|(k, _)| k != key);
31                        }
32                        _ => {
33                            if let Some(ref new_value) = change.new_value {
34                                // Remove old entry if exists and add new one
35                                results.retain(|(k, _)| k != key);
36                                results.push((key.clone(), new_value.clone()));
37                            }
38                        }
39                    }
40                }
41            }
42        }
43
44        // Apply limit
45        if let Some(limit) = query.limit {
46            results.truncate(limit);
47        }
48
49        // Sort by key for consistent results
50        results.sort_by(|a, b| a.0.cmp(&b.0));
51
52        Ok(results)
53    }
54
55    /// Get storage root hash for account (Neo compatibility)
56    pub fn get_storage_root(&self, account: &str) -> Result<String, RuntimeError> {
57        if let Some(account_storage) = self.storage.get(account) {
58            // Calculate Merkle root of storage items
59            let mut items: Vec<_> = account_storage.storage.iter().collect();
60            items.sort_by_key(|(k, _)| *k);
61
62            let root_hash = self.calculate_merkle_root(&items);
63            Ok(hex::encode(root_hash))
64        } else {
65            Ok(hex::encode(self.empty_root_hash()))
66        }
67    }
68}