|
5 | 5 | #![no_std] |
6 | 6 |
|
7 | 7 | use soroban_sdk::{ |
8 | | - contract, contractimpl, contracttype, Address, BytesN, Env, IntoVal, String, Symbol, TryFromVal, |
9 | | - Val, Vec, |
| 8 | + contract, contractimpl, contracttype, Address, Bytes, BytesN, Env, IntoVal, String, Symbol, |
| 9 | + TryFromVal, Val, Vec, |
10 | 10 | }; |
| 11 | +use utils::merkle::{self, MerkleProof}; |
11 | 12 |
|
12 | 13 | // ════════════════════════════════════════════════════════════════ |
13 | 14 | // DATA STRUCTURES |
@@ -523,6 +524,43 @@ impl SubTrackrBatch { |
523 | 524 | } |
524 | 525 | } |
525 | 526 |
|
| 527 | + // ── Batch Storage Operations (Merkle Tree) ── |
| 528 | + |
| 529 | + /// Batch read multiple storage keys using Merkle accumulator |
| 530 | + pub fn batch_get_storage( |
| 531 | + env: Env, |
| 532 | + key_prefix: Bytes, |
| 533 | + keys: Vec<Bytes>, |
| 534 | + ) -> (Vec<(Bytes, Option<Bytes>)>, MerkleProof) { |
| 535 | + merkle::batch_get(&env, &key_prefix, &keys) |
| 536 | + } |
| 537 | + |
| 538 | + /// Batch insert multiple key-value pairs with Merkle root update |
| 539 | + pub fn batch_insert_storage( |
| 540 | + env: Env, |
| 541 | + key_prefix: Bytes, |
| 542 | + values: Vec<(Bytes, Bytes)>, |
| 543 | + ) { |
| 544 | + merkle::batch_insert(&env, &key_prefix, &values); |
| 545 | + } |
| 546 | + |
| 547 | + /// Verify a batch of key-value pairs against stored Merkle root |
| 548 | + pub fn verify_batch_storage( |
| 549 | + env: Env, |
| 550 | + key_prefix: Bytes, |
| 551 | + keys: Vec<Bytes>, |
| 552 | + values: Vec<Option<Bytes>>, |
| 553 | + proof: MerkleProof, |
| 554 | + ) -> bool { |
| 555 | + merkle::verify_batch(&env, &key_prefix, &keys, &values, &proof) |
| 556 | + } |
| 557 | + |
| 558 | + /// Get the Merkle root for a given key prefix |
| 559 | + pub fn get_merkle_root(env: Env, key_prefix: Bytes) -> Option<BytesN<32>> { |
| 560 | + let root_key = make_root_key(&env, &key_prefix); |
| 561 | + env.storage().instance().get(&root_key) |
| 562 | + } |
| 563 | + |
526 | 564 | fn vec_contains_address(vec: &Vec<Address>, address: &Address) -> bool { |
527 | 565 | for item in vec.iter() { |
528 | 566 | if &item == address { |
@@ -822,6 +860,13 @@ pub fn validate_batch_operations(batch: &Vec<BatchOperation>) -> bool { |
822 | 860 | true |
823 | 861 | } |
824 | 862 |
|
| 863 | +fn make_root_key(env: &Env, prefix: &Bytes) -> Bytes { |
| 864 | + let mut root_key = Bytes::new(env); |
| 865 | + root_key.append(prefix); |
| 866 | + root_key.append(&Bytes::from_slice(env, b"_merkle_root")); |
| 867 | + root_key |
| 868 | +} |
| 869 | + |
825 | 870 | #[cfg(test)] |
826 | 871 | mod tests { |
827 | 872 | use super::*; |
|
0 commit comments