|
1 | 1 | use light_client::{
|
2 | 2 | indexer::{
|
3 |
| - AddressWithTree, GetCompressedTokenAccountsByOwnerOrDelegateOptions, Hash, Indexer, |
4 |
| - IndexerRpcConfig, PaginatedOptions, RetryConfig, |
| 3 | + AccountProofInputs, AddressProofInputs, AddressWithTree, |
| 4 | + GetCompressedTokenAccountsByOwnerOrDelegateOptions, Hash, Indexer, IndexerRpcConfig, |
| 5 | + MerkleProof, PaginatedOptions, RetryConfig, RootIndex, TreeInfo, ValidityProofWithContext, |
5 | 6 | },
|
6 | 7 | local_test_validator::{spawn_validator, LightValidatorConfig},
|
7 | 8 | rpc::{LightClient, LightClientConfig},
|
8 | 9 | };
|
9 |
| -use light_compressed_account::hash_to_bn254_field_size_be; |
| 10 | +use light_compressed_account::{hash_to_bn254_field_size_be, TreeType}; |
10 | 11 | use light_compressed_token::mint_sdk::{
|
11 | 12 | create_create_token_pool_instruction, create_mint_to_instruction,
|
12 | 13 | };
|
| 14 | +use light_hasher::Poseidon; |
| 15 | +use light_merkle_tree_reference::{indexed::IndexedMerkleTree, MerkleTree}; |
13 | 16 | use light_program_test::accounts::test_accounts::TestAccounts;
|
14 | 17 | use light_prover_client::prover::ProverConfig;
|
15 | 18 | use light_sdk::{
|
@@ -66,6 +69,7 @@ async fn test_all_endpoints() {
|
66 | 69 | .await
|
67 | 70 | .unwrap();
|
68 | 71 | let mt = test_accounts.v1_state_trees[0].merkle_tree;
|
| 72 | + let _address_mt = test_accounts.v1_address_trees[0].merkle_tree; |
69 | 73 |
|
70 | 74 | let lamports = LAMPORTS_PER_SOL / 2;
|
71 | 75 | let lamports_1 = LAMPORTS_PER_SOL / 2 + 1;
|
@@ -109,12 +113,21 @@ async fn test_all_endpoints() {
|
109 | 113 | };
|
110 | 114 |
|
111 | 115 | let account_hashes: Vec<Hash> = initial_accounts.items.iter().map(|a| a.hash).collect();
|
| 116 | + let mut reference_tree = MerkleTree::<Poseidon>::new(26, 10); |
| 117 | + for hash in &account_hashes { |
| 118 | + reference_tree.append(hash).unwrap(); |
| 119 | + } |
112 | 120 | let account_addresses: Vec<Hash> = initial_accounts
|
113 | 121 | .items
|
114 | 122 | .iter()
|
115 | 123 | .map(|a| a.address.unwrap())
|
116 | 124 | .collect();
|
117 | 125 |
|
| 126 | + // Create reference address tree and add the addresses |
| 127 | + let _reference_address_tree = IndexedMerkleTree::<Poseidon, usize>::new(26, 10).unwrap(); |
| 128 | + |
| 129 | + // Don't add the test address to the reference tree since we want non-inclusion proof |
| 130 | + |
118 | 131 | // 2. get_multiple_compressed_accounts
|
119 | 132 | let accounts = rpc
|
120 | 133 | .get_multiple_compressed_accounts(None, Some(account_hashes.clone()), None)
|
@@ -158,6 +171,53 @@ async fn test_all_endpoints() {
|
158 | 171 | .value;
|
159 | 172 | assert_eq!(result.accounts.len(), account_hashes.len());
|
160 | 173 | assert_eq!(result.addresses.len(), new_addresses.len());
|
| 174 | + |
| 175 | + println!("account_proof {:?}", result); |
| 176 | + |
| 177 | + // Build expected ValidityProofWithContext using reference tree |
| 178 | + let expected_result = ValidityProofWithContext { |
| 179 | + proof: result.proof, // Keep the actual proof as-is |
| 180 | + accounts: account_hashes |
| 181 | + .iter() |
| 182 | + .enumerate() |
| 183 | + .map(|(i, &hash)| AccountProofInputs { |
| 184 | + hash, |
| 185 | + root: reference_tree.root(), |
| 186 | + root_index: RootIndex::new_some(2), |
| 187 | + leaf_index: i as u64, |
| 188 | + tree_info: TreeInfo { |
| 189 | + cpi_context: None, |
| 190 | + next_tree_info: None, |
| 191 | + queue: test_accounts.v1_state_trees[0].nullifier_queue, |
| 192 | + tree: mt, |
| 193 | + tree_type: TreeType::StateV1, |
| 194 | + }, |
| 195 | + }) |
| 196 | + .collect(), |
| 197 | + addresses: new_addresses |
| 198 | + .iter() |
| 199 | + .enumerate() |
| 200 | + .map(|(i, addr_with_tree)| { |
| 201 | + // TODO: enable once photon bug is fixed |
| 202 | + // let address_bigint = BigUint::from_bytes_be(&addr_with_tree.address); |
| 203 | + // let non_inclusion_proof = reference_address_tree.get_non_inclusion_proof(&address_bigint).unwrap(); |
| 204 | + AddressProofInputs { |
| 205 | + address: addr_with_tree.address, |
| 206 | + root: result.addresses[i].root, |
| 207 | + root_index: 3, |
| 208 | + tree_info: TreeInfo { |
| 209 | + cpi_context: None, |
| 210 | + next_tree_info: None, |
| 211 | + queue: test_accounts.v1_address_trees[0].queue, |
| 212 | + tree: addr_with_tree.tree, |
| 213 | + tree_type: TreeType::AddressV1, |
| 214 | + }, |
| 215 | + } |
| 216 | + }) |
| 217 | + .collect(), |
| 218 | + }; |
| 219 | + |
| 220 | + assert_eq!(result, expected_result); |
161 | 221 | }
|
162 | 222 | // 4. get_compressed_account
|
163 | 223 | let first_account = rpc
|
@@ -252,21 +312,62 @@ async fn test_all_endpoints() {
|
252 | 312 | assert!(!proofs.items.is_empty());
|
253 | 313 | assert_eq!(proofs.items[0].hash, account_hashes[0]);
|
254 | 314 |
|
| 315 | + // Build expected Vec<MerkleProof> using reference tree |
| 316 | + let expected_proofs: Vec<MerkleProof> = account_hashes |
| 317 | + .iter() |
| 318 | + .enumerate() |
| 319 | + .map(|(i, &hash)| { |
| 320 | + let expected_proof = reference_tree.get_proof_of_leaf(i, false).unwrap(); |
| 321 | + MerkleProof { |
| 322 | + hash, |
| 323 | + leaf_index: i as u64, |
| 324 | + merkle_tree: mt, |
| 325 | + proof: expected_proof, |
| 326 | + root_seq: 2, |
| 327 | + root: reference_tree.root(), |
| 328 | + } |
| 329 | + }) |
| 330 | + .collect(); |
| 331 | + |
| 332 | + assert_eq!(proofs.items, expected_proofs); |
| 333 | + |
255 | 334 | // 12. get_multiple_new_address_proofs
|
256 | 335 | let addresses = vec![address];
|
257 | 336 | let new_address_proofs = rpc
|
258 | 337 | .get_multiple_new_address_proofs(
|
259 | 338 | test_accounts.v1_address_trees[0].merkle_tree.to_bytes(),
|
260 |
| - addresses, |
| 339 | + addresses.clone(), |
261 | 340 | None,
|
262 | 341 | )
|
263 | 342 | .await
|
264 | 343 | .unwrap();
|
265 | 344 | assert!(!new_address_proofs.value.items.is_empty());
|
266 |
| - assert_eq!( |
267 |
| - new_address_proofs.value.items[0].merkle_tree.to_bytes(), |
268 |
| - test_accounts.v1_address_trees[0].merkle_tree.to_bytes() |
269 |
| - ); |
| 345 | + // TODO: update once photon is ready |
| 346 | + // Build expected Vec<NewAddressProofWithContext> using reference address tree |
| 347 | + // let expected_address_proofs: Vec<NewAddressProofWithContext> = addresses |
| 348 | + // .iter() |
| 349 | + // .map(|&addr| { |
| 350 | + // let address_bigint = BigUint::from_bytes_be(&addr); |
| 351 | + // let non_inclusion_proof = reference_address_tree |
| 352 | + // .get_non_inclusion_proof(&address_bigint) |
| 353 | + // .unwrap(); |
| 354 | + |
| 355 | + // NewAddressProofWithContext { |
| 356 | + // merkle_tree: address_mt, |
| 357 | + // root: non_inclusion_proof.root, |
| 358 | + // root_seq: 3, |
| 359 | + // low_address_index: non_inclusion_proof.leaf_index as u64, |
| 360 | + // low_address_value: non_inclusion_proof.leaf_lower_range_value, |
| 361 | + // low_address_next_index: non_inclusion_proof.next_index as u64, |
| 362 | + // low_address_next_value: non_inclusion_proof.leaf_higher_range_value, |
| 363 | + // low_address_proof: non_inclusion_proof.merkle_proof, |
| 364 | + // new_low_element: None, |
| 365 | + // new_element: None, |
| 366 | + // new_element_next_value: None, |
| 367 | + // } |
| 368 | + // }) |
| 369 | + // .collect(); |
| 370 | + assert_eq!(new_address_proofs.value.items.len(), 1); |
270 | 371 | }
|
271 | 372 |
|
272 | 373 | test_token_api(&rpc, &test_accounts).await;
|
|
0 commit comments