test_execute.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the deltavm library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use crate::{CallStack, InclusionVersion, Process, Trace, execution_cost, execution_cost_for_authorization}; 17 use deltavm_algorithms::snark::varuna::VarunaVersion; 18 use deltavm_ledger_block::{Fee, Output, Transaction, Transition}; 19 use deltavm_ledger_query::Query; 20 use deltavm_ledger_store::{ 21 BlockStorage, 22 BlockStore, 23 FinalizeStorage, 24 FinalizeStore, 25 helpers::memory::{BlockMemory, FinalizeMemory}, 26 }; 27 use deltavm_synthesizer_program::{FinalizeGlobalState, FinalizeStoreTrait, Program, StackTrait}; 28 use deltavm_synthesizer_snark::UniversalSRS; 29 use circuit::{Alpha, network::AlphaV0}; 30 use console::{ 31 account::{Address, PrivateKey, ViewKey}, 32 network::{MainnetV0, prelude::*}, 33 program::{Identifier, Literal, Plaintext, ProgramID, Record, Value}, 34 types::{Field, U64}, 35 }; 36 37 use alphastd::StorageMode; 38 #[cfg(feature = "locktick")] 39 use locktick::parking_lot::RwLock; 40 #[cfg(not(feature = "locktick"))] 41 use parking_lot::RwLock; 42 use std::sync::Arc; 43 44 type CurrentNetwork = MainnetV0; 45 type CurrentAlpha = AlphaV0; 46 47 /// Samples a new finalize state. 48 pub fn sample_finalize_state(block_height: u32) -> FinalizeGlobalState { 49 FinalizeGlobalState::from(block_height as u64, block_height, None, [0u8; 32]) 50 } 51 52 /// Samples a valid fee for the given process, block store, and finalize store. 53 pub fn sample_fee<N: Network, A: Alpha<Network = N>, B: BlockStorage<N>, P: FinalizeStorage<N>>( 54 process: &Process<N>, 55 block_store: &BlockStore<N, B>, 56 finalize_store: &FinalizeStore<N, P>, 57 rng: &mut TestRng, 58 ) -> Fee<N> { 59 let program_id = ProgramID::from_str("credits.delta").unwrap(); 60 let account_mapping = Identifier::from_str("account").unwrap(); 61 62 // Initialize the account mapping, even if it already has been (we silence the result for testing). 63 let _ = finalize_store.initialize_mapping(program_id, account_mapping); 64 65 // Sample a random private key. 66 let private_key = PrivateKey::<N>::new(rng).unwrap(); 67 let address = Address::try_from(private_key).unwrap(); 68 69 // Construct the key. 70 let key = Plaintext::from(Literal::Address(address)); 71 // Construct the public balance. 72 let value = Value::from(Literal::U64(U64::new(100))); 73 // Update the public balance in finalize storage. 74 finalize_store.update_key_value(program_id, account_mapping, key, value).unwrap(); 75 76 // Sample a base fee in microcredits. 77 let base_fee_in_microcredits = 100; 78 // Sample a priority fee in microcredits. 79 let priority_fee_in_microcredits = 0; 80 // Sample a dummy ID. 81 let id = Field::rand(rng); 82 83 // Authorize the fee. 84 let authorization = process 85 .authorize_fee_public::<A, _>(&private_key, base_fee_in_microcredits, priority_fee_in_microcredits, id, rng) 86 .unwrap(); 87 // Execute the fee. 88 let (_, mut trace) = process.execute::<A, _>(authorization, rng).unwrap(); 89 // Prepare the assignments. 90 trace.prepare(&Query::from(block_store)).unwrap(); 91 // Compute the proof and construct the fee. 92 trace.prove_fee::<A, _>(VarunaVersion::V2, rng).unwrap() 93 } 94 95 #[test] 96 fn test_program_evaluate_function() { 97 let program = Program::<CurrentNetwork>::from_str( 98 r" 99 program example.delta; 100 101 function foo: 102 input r0 as field.public; 103 input r1 as field.private; 104 add r0 r1 into r2; 105 output r2 as field.private; 106 ", 107 ) 108 .unwrap(); 109 110 // Declare the function name. 111 let function_name = Identifier::from_str("foo").unwrap(); 112 // Declare the function inputs. 113 let inputs = [ 114 Value::<CurrentNetwork>::Plaintext(Plaintext::from_str("2field").unwrap()), 115 Value::Plaintext(Plaintext::from_str("3field").unwrap()), 116 ]; 117 118 // Construct the process. 119 let process = crate::test_helpers::sample_process(&program); 120 121 // Initialize an RNG. 122 let rng = &mut TestRng::default(); 123 124 // Compute the authorization. 125 let authorization = { 126 // Initialize caller private key. 127 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 128 129 // Authorize the function call. 130 let authorization = process 131 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, inputs.iter(), rng) 132 .unwrap(); 133 assert_eq!(authorization.len(), 1); 134 authorization 135 }; 136 137 // Retrieve the stack. 138 let stack = process.get_stack(program.id()).unwrap(); 139 140 // Declare the expected output. 141 let expected = Value::Plaintext(Plaintext::<CurrentNetwork>::from_str("5field").unwrap()); 142 143 // Run the function. 144 let response = stack 145 .evaluate_function::<CurrentAlpha, _>(CallStack::evaluate(authorization.replicate()).unwrap(), None, None, rng) 146 .unwrap(); 147 let candidate = response.outputs(); 148 assert_eq!(1, candidate.len()); 149 assert_eq!(expected, candidate[0]); 150 151 // Re-run to ensure state continues to work. 152 let response = stack 153 .evaluate_function::<CurrentAlpha, _>(CallStack::evaluate(authorization).unwrap(), None, None, rng) 154 .unwrap(); 155 let candidate = response.outputs(); 156 assert_eq!(1, candidate.len()); 157 assert_eq!(expected, candidate[0]); 158 } 159 160 #[test] 161 fn test_program_evaluate_struct_and_function() { 162 // Initialize a new program. 163 let (string, program) = Program::<CurrentNetwork>::parse( 164 r" 165 program example.delta; 166 167 struct message: 168 first as field; 169 second as field; 170 171 function compute: 172 input r0 as message.private; 173 add r0.first r0.second into r1; 174 output r1 as field.private;", 175 ) 176 .unwrap(); 177 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 178 179 // Declare the function name. 180 let function_name = Identifier::from_str("compute").unwrap(); 181 // Declare the input value. 182 let input = Value::<CurrentNetwork>::Plaintext(Plaintext::from_str("{ first: 2field, second: 3field }").unwrap()); 183 // Declare the expected output value. 184 let expected = Value::Plaintext(Plaintext::from_str("5field").unwrap()); 185 186 // Construct the process. 187 let process = crate::test_helpers::sample_process(&program); 188 189 // Initialize an RNG. 190 let rng = &mut TestRng::default(); 191 192 // Compute the authorization. 193 let authorization = { 194 // Initialize caller private key. 195 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 196 197 // Authorize the function call. 198 let authorization = process 199 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, [input].iter(), rng) 200 .unwrap(); 201 assert_eq!(authorization.len(), 1); 202 authorization 203 }; 204 205 // Retrieve the stack. 206 let stack = process.get_stack(program.id()).unwrap(); 207 208 // Compute the output value. 209 let response = stack 210 .evaluate_function::<CurrentAlpha, _>(CallStack::evaluate(authorization.replicate()).unwrap(), None, None, rng) 211 .unwrap(); 212 let candidate = response.outputs(); 213 assert_eq!(1, candidate.len()); 214 assert_eq!(expected, candidate[0]); 215 216 // Re-run to ensure state continues to work. 217 let response = stack 218 .evaluate_function::<CurrentAlpha, _>(CallStack::evaluate(authorization).unwrap(), None, None, rng) 219 .unwrap(); 220 let candidate = response.outputs(); 221 assert_eq!(1, candidate.len()); 222 assert_eq!(expected, candidate[0]); 223 } 224 225 #[test] 226 fn test_program_evaluate_record_and_function() { 227 // Initialize a new program. 228 let (string, program) = Program::<CurrentNetwork>::parse( 229 r" 230 program token.delta; 231 232 record token: 233 owner as address.private; 234 token_amount as u64.private; 235 236 function compute: 237 input r0 as token.record; 238 add r0.token_amount r0.token_amount into r1; 239 output r1 as u64.private;", 240 ) 241 .unwrap(); 242 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 243 244 // Declare the function name. 245 let function_name = Identifier::from_str("compute").unwrap(); 246 247 // Initialize an RNG. 248 let rng = &mut TestRng::default(); 249 250 // Initialize caller private key. 251 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 252 let caller = Address::try_from(&caller_private_key).unwrap(); 253 254 // Declare the input value. 255 let input_record = Record::from_str(&format!( 256 "{{ owner: {caller}.private, token_amount: 100u64.private, _nonce: 0group.public }}" 257 )) 258 .unwrap(); 259 let input = Value::<CurrentNetwork>::Record(input_record); 260 261 // Declare the expected output value. 262 let expected = Value::Plaintext(Plaintext::from_str("200u64").unwrap()); 263 264 // Construct the process. 265 let process = crate::test_helpers::sample_process(&program); 266 267 // Authorize the function call. 268 let authorization = process 269 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, [input].iter(), rng) 270 .unwrap(); 271 assert_eq!(authorization.len(), 1); 272 273 // Retrieve the stack. 274 let stack = process.get_stack(program.id()).unwrap(); 275 276 // Compute the output value. 277 let response = stack 278 .evaluate_function::<CurrentAlpha, _>(CallStack::evaluate(authorization.replicate()).unwrap(), None, None, rng) 279 .unwrap(); 280 let candidate = response.outputs(); 281 assert_eq!(1, candidate.len()); 282 assert_eq!(expected, candidate[0]); 283 284 // Re-run to ensure state continues to work. 285 let response = stack 286 .evaluate_function::<CurrentAlpha, _>(CallStack::evaluate(authorization).unwrap(), None, None, rng) 287 .unwrap(); 288 let candidate = response.outputs(); 289 assert_eq!(1, candidate.len()); 290 assert_eq!(expected, candidate[0]); 291 } 292 293 #[test] 294 fn test_program_evaluate_call() { 295 // Initialize a new program. 296 let (string, program) = Program::<CurrentNetwork>::parse( 297 r" 298 program example_call.delta; 299 300 // (a + (a + b)) + (a + b) == (3a + 2b) 301 closure execute: 302 input r0 as field; 303 input r1 as field; 304 add r0 r1 into r2; 305 add r0 r2 into r3; 306 add r2 r3 into r4; 307 output r4 as field; 308 output r3 as field; 309 output r2 as field; 310 311 function compute: 312 input r0 as field.private; 313 input r1 as field.public; 314 call execute r0 r1 into r2 r3 r4; 315 output r2 as field.private; 316 output r3 as field.private; 317 output r4 as field.private;", 318 ) 319 .unwrap(); 320 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 321 322 // Declare the function name. 323 let function_name = Identifier::from_str("compute").unwrap(); 324 325 // Declare the input value. 326 let r0 = Value::<CurrentNetwork>::Plaintext(Plaintext::from_str("3field").unwrap()); 327 let r1 = Value::<CurrentNetwork>::Plaintext(Plaintext::from_str("5field").unwrap()); 328 329 // Declare the expected output value. 330 let r2 = Value::Plaintext(Plaintext::from_str("19field").unwrap()); 331 let r3 = Value::Plaintext(Plaintext::from_str("11field").unwrap()); 332 let r4 = Value::Plaintext(Plaintext::from_str("8field").unwrap()); 333 334 { 335 // Construct the process. 336 let process = crate::test_helpers::sample_process(&program); 337 // Check that the circuit key can be synthesized. 338 process.synthesize_key::<CurrentAlpha, _>(program.id(), &function_name, &mut TestRng::default()).unwrap(); 339 } 340 341 // Construct the process. 342 let process = crate::test_helpers::sample_process(&program); 343 344 // Initialize an RNG. 345 let rng = &mut TestRng::default(); 346 347 // Compute the authorization. 348 let authorization = { 349 // Initialize caller private key. 350 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 351 352 // Authorize the function call. 353 let authorization = process 354 .authorize::<CurrentAlpha, _>( 355 &caller_private_key, 356 program.id(), 357 function_name, 358 [r0.clone(), r1.clone()].iter(), 359 rng, 360 ) 361 .unwrap(); 362 assert_eq!(authorization.len(), 1); 363 authorization 364 }; 365 366 // Retrieve the stack. 367 let stack = process.get_stack(program.id()).unwrap(); 368 369 // Compute the output value. 370 let response = stack 371 .evaluate_function::<CurrentAlpha, _>(CallStack::evaluate(authorization.replicate()).unwrap(), None, None, rng) 372 .unwrap(); 373 let candidate = response.outputs(); 374 assert_eq!(3, candidate.len()); 375 assert_eq!(r2, candidate[0]); 376 assert_eq!(r3, candidate[1]); 377 assert_eq!(r4, candidate[2]); 378 379 // Re-run to ensure state continues to work. 380 let response = stack 381 .evaluate_function::<CurrentAlpha, _>(CallStack::evaluate(authorization).unwrap(), None, None, rng) 382 .unwrap(); 383 let candidate = response.outputs(); 384 assert_eq!(3, candidate.len()); 385 assert_eq!(r2, candidate[0]); 386 assert_eq!(r3, candidate[1]); 387 assert_eq!(r4, candidate[2]); 388 389 use circuit::Environment; 390 391 // Ensure the environment is clean. 392 assert_eq!(0, CurrentAlpha::num_constants()); 393 assert_eq!(1, CurrentAlpha::num_public()); 394 assert_eq!(0, CurrentAlpha::num_private()); 395 assert_eq!(0, CurrentAlpha::num_constraints()); 396 397 // Initialize an RNG. 398 let rng = &mut TestRng::default(); 399 // Initialize a burner private key. 400 let burner_private_key = PrivateKey::new(rng).unwrap(); 401 // Authorize the function call, with a burner private key. 402 let authorization = process 403 .authorize::<CurrentAlpha, _>(&burner_private_key, program.id(), function_name, [r0, r1].iter(), rng) 404 .unwrap(); 405 assert_eq!(authorization.len(), 1); 406 407 // Re-run to ensure state continues to work. 408 let trace = Arc::new(RwLock::new(Trace::new())); 409 let call_stack = CallStack::execute(authorization, trace).unwrap(); 410 let response = stack.execute_function::<CurrentAlpha, _>(call_stack, None, None, rng).unwrap(); 411 let candidate = response.outputs(); 412 assert_eq!(3, candidate.len()); 413 assert_eq!(r2, candidate[0]); 414 assert_eq!(r3, candidate[1]); 415 assert_eq!(r4, candidate[2]); 416 } 417 418 #[test] 419 fn test_program_evaluate_cast() { 420 // Initialize a new program. 421 let (string, program) = Program::<CurrentNetwork>::parse( 422 r" 423 program token_with_cast.delta; 424 425 record token: 426 owner as address.private; 427 token_amount as u64.private; 428 429 function compute: 430 input r0 as token.record; 431 cast r0.owner r0.token_amount into r1 as token.record; 432 output r1 as token.record;", 433 ) 434 .unwrap(); 435 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 436 437 // Declare the function name. 438 let function_name = Identifier::from_str("compute").unwrap(); 439 440 // Initialize an RNG. 441 let rng = &mut TestRng::default(); 442 443 // Initialize caller private key. 444 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 445 let caller = Address::try_from(&caller_private_key).unwrap(); 446 447 // Declare the input value. 448 let input_record = Record::from_str(&format!( 449 "{{ owner: {caller}.private, token_amount: 100u64.private, _nonce: 0group.public }}" 450 )) 451 .unwrap(); 452 let input = Value::<CurrentNetwork>::Record(input_record); 453 454 // Construct the process. 455 let process = crate::test_helpers::sample_process(&program); 456 457 // Authorize the function call. 458 let authorization = process 459 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, [input].iter(), rng) 460 .unwrap(); 461 assert_eq!(authorization.len(), 1); 462 let request = authorization.peek_next().unwrap(); 463 464 // Compute the encryption randomizer as `HashToScalar(tvk || index)`. 465 let randomizer = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(1)]).unwrap(); 466 let nonce = CurrentNetwork::g_scalar_multiply(&randomizer); 467 468 // Declare the expected output value. 469 let expected = Value::from_str(&format!( 470 "{{ owner: {caller}.private, token_amount: 100u64.private, _nonce: {nonce}.public, _version: 1u8.public }}" 471 )) 472 .unwrap(); 473 474 // Retrieve the stack. 475 let stack = process.get_stack(program.id()).unwrap(); 476 477 // Compute the output value. 478 let response = stack 479 .evaluate_function::<CurrentAlpha, _>(CallStack::evaluate(authorization.replicate()).unwrap(), None, None, rng) 480 .unwrap(); 481 let candidate = response.outputs(); 482 assert_eq!(1, candidate.len()); 483 assert_eq!(expected, candidate[0]); 484 485 // Re-run to ensure state continues to work. 486 let response = stack 487 .evaluate_function::<CurrentAlpha, _>(CallStack::evaluate(authorization).unwrap(), None, None, rng) 488 .unwrap(); 489 let candidate = response.outputs(); 490 assert_eq!(1, candidate.len()); 491 assert_eq!(expected, candidate[0]); 492 } 493 494 #[test] 495 fn test_process_execute_transfer_public_to_private() { 496 // Initialize a new program. 497 let program = Program::<CurrentNetwork>::credits().unwrap(); 498 499 // Initialize the RNG. 500 let rng = &mut TestRng::default(); 501 // Initialize a new caller account. 502 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 503 let caller_view_key = ViewKey::try_from(&caller_private_key).unwrap(); 504 let caller = Address::try_from(&caller_private_key).unwrap(); 505 // Initialize a new recipient address. 506 let recipient_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 507 let recipient_view_key = ViewKey::try_from(&recipient_private_key).unwrap(); 508 let recipient = Address::try_from(&recipient_private_key).unwrap(); 509 // Declare the input value. 510 let r0 = Value::<CurrentNetwork>::from_str(&format!("{recipient}")).unwrap(); 511 let r1 = Value::<CurrentNetwork>::from_str("99_000_000_000_000_u64").unwrap(); 512 513 // Construct the process. 514 let process = Process::load().unwrap(); 515 516 // Authorize the function call. 517 let authorization = process 518 .authorize::<CurrentAlpha, _>( 519 &caller_private_key, 520 program.id(), 521 Identifier::from_str("transfer_public_to_private").unwrap(), 522 [r0, r1].iter(), 523 rng, 524 ) 525 .unwrap(); 526 assert_eq!(authorization.len(), 1); 527 let request = authorization.peek_next().unwrap(); 528 529 // Compute the encryption randomizer as `HashToScalar(tvk || index)`. 530 let randomizer = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(2)]).unwrap(); 531 let nonce = CurrentNetwork::g_scalar_multiply(&randomizer); 532 533 // Declare the expected output value. 534 let r2 = Value::from_str(&format!( 535 "{{ owner: {recipient}.private, microcredits: 99_000_000_000_000_u64.private, _nonce: {nonce}.public, _version: 1u8.public }}" 536 )) 537 .unwrap(); 538 539 // Check again to make sure we didn't modify the authorization before calling `evaluate`. 540 assert_eq!(authorization.len(), 1); 541 542 // Compute the output value. 543 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 544 let candidate = response.outputs(); 545 assert_eq!(2, candidate.len()); 546 assert_eq!(r2, candidate[0]); 547 548 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 549 assert_eq!(authorization.len(), 1); 550 551 let expected_execution_cost = 552 execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap(); 553 554 // Execute the request. 555 let (response, mut trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 556 let candidate = response.outputs(); 557 assert_eq!(2, candidate.len()); 558 assert_eq!(r2, candidate[0]); 559 560 // Check that the sender ciphertext is well-formed. 561 { 562 // Construct a new process. 563 let process = Process::load().unwrap(); 564 // Initialize a new block store. 565 let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 566 // Prepare the trace. 567 trace.prepare(&Query::from(block_store)).unwrap(); 568 // Prove the execution. 569 let execution = trace.prove_execution::<CurrentAlpha, _>("credits.delta", VarunaVersion::V2, rng).unwrap(); 570 // Verify the execution. 571 process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap(); 572 573 // Check the execution cost 574 assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost); 575 576 // Ensure there is only one transition. 577 assert_eq!(1, execution.transitions().len()); 578 // Retrieve the transition. 579 let transition: Transition<_> = execution.into_transitions().next().unwrap(); 580 // Ensure the transition program ID and function name are correct. 581 assert_eq!(transition.program_id(), program.id()); 582 assert_eq!(transition.function_name(), &Identifier::from_str("transfer_public_to_private").unwrap()); 583 // Ensure the transition has 2 inputs and 2 outputs. 584 assert_eq!(2, transition.inputs().len()); 585 assert_eq!(2, transition.outputs().len()); 586 // Ensure the first output is a record. 587 assert!(matches!(transition.outputs()[0], Output::Record(..))); 588 589 // Retrieve the first output. 590 let output = transition.outputs()[0].clone(); 591 // Decrypt the sender ciphertext. 592 let expected_caller = output.decrypt_sender_ciphertext(&recipient_view_key).unwrap(); 593 // Ensure the caller address matches the expected caller. 594 assert_eq!(Some(caller), expected_caller); 595 596 // Ensure decryption fails with the caller view key. 597 assert!(output.decrypt_sender_ciphertext(&caller_view_key).is_err()); 598 599 // Ensure decryption fails with a different view key. 600 let different_view_key = ViewKey::try_from(&PrivateKey::<CurrentNetwork>::new(rng).unwrap()).unwrap(); 601 assert!(output.decrypt_sender_ciphertext(&different_view_key).is_err()); 602 } 603 604 // use circuit::Environment; 605 // 606 // assert_eq!(22152, CurrentAlpha::num_constants()); 607 // assert_eq!(9, CurrentAlpha::num_public()); 608 // assert_eq!(20561, CurrentAlpha::num_private()); 609 // assert_eq!(20579, CurrentAlpha::num_constraints()); 610 // assert_eq!(79386, CurrentAlpha::num_gates()); 611 } 612 613 #[test] 614 fn test_process_circuit_key() { 615 // Initialize a new program. 616 let program = Program::<CurrentNetwork>::from_str( 617 r#"program testing.delta; 618 619 function hello_world: 620 input r0 as u32.public; 621 input r1 as u32.private; 622 add r0 r1 into r2; 623 output r2 as u32.private; 624 "#, 625 ) 626 .unwrap(); 627 628 // Declare the function name. 629 let function_name = Identifier::from_str("hello_world").unwrap(); 630 631 // Construct the process. 632 let process = crate::test_helpers::sample_process(&program); 633 // Check that the circuit key can be synthesized. 634 process.synthesize_key::<CurrentAlpha, _>(program.id(), &function_name, &mut TestRng::default()).unwrap(); 635 } 636 637 #[test] 638 fn test_process_multirecords() { 639 // Initialize a new program. 640 let program = Program::<CurrentNetwork>::from_str( 641 r"program multirecord.delta; 642 643 record record_a: 644 owner as address.private; 645 item as u64.private; 646 647 record record_b: 648 owner as address.private; 649 item as u64.private; 650 651 record record_c: 652 owner as address.private; 653 item as u64.private; 654 655 function initialize: 656 input r0 as record_a.record; 657 input r1 as record_b.record; 658 input r2 as record_c.record; 659 cast r0.owner r0.item into r3 as record_a.record; 660 cast r1.owner r1.item into r4 as record_b.record; 661 cast r2.owner r2.item into r5 as record_c.record; 662 output r3 as record_a.record; 663 output r4 as record_b.record; 664 output r5 as record_c.record;", 665 ) 666 .unwrap(); 667 668 // Declare the function name. 669 let function_name = Identifier::from_str("initialize").unwrap(); 670 671 // Initialize the RNG. 672 let rng = &mut TestRng::default(); 673 674 // Construct the process. 675 let process = crate::test_helpers::sample_process(&program); 676 677 // Initialize a new caller account. 678 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 679 let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap(); 680 let caller = Address::try_from(&caller_private_key).unwrap(); 681 682 // Declare the input value. 683 let input_a = 684 Value::from_str(&format!("{{ owner: {caller}.private, item: 1234u64.private, _nonce: 0group.public }}")) 685 .unwrap(); 686 let input_b = 687 Value::from_str(&format!("{{ owner: {caller}.private, item: 4321u64.private, _nonce: 0group.public }}")) 688 .unwrap(); 689 let input_c = 690 Value::from_str(&format!("{{ owner: {caller}.private, item: 5678u64.private, _nonce: 0group.public }}")) 691 .unwrap(); 692 693 // Authorize the function call. 694 let authorization = process 695 .authorize::<CurrentAlpha, _>( 696 &caller_private_key, 697 program.id(), 698 function_name, 699 [input_a, input_b, input_c].iter(), 700 rng, 701 ) 702 .unwrap(); 703 assert_eq!(authorization.len(), 1); 704 let request = authorization.peek_next().unwrap(); 705 706 // Compute the encryption randomizer for the first output as `HashToScalar(tvk || index)`. 707 let randomizer_a = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(3)]).unwrap(); 708 let nonce_a = CurrentNetwork::g_scalar_multiply(&randomizer_a); 709 710 // Compute the encryption randomizer for the second output as `HashToScalar(tvk || index)`. 711 let randomizer_b = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(4)]).unwrap(); 712 let nonce_b = CurrentNetwork::g_scalar_multiply(&randomizer_b); 713 714 // Compute the encryption randomizer for the third output as `HashToScalar(tvk || index)`. 715 let randomizer_c = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(5)]).unwrap(); 716 let nonce_c = CurrentNetwork::g_scalar_multiply(&randomizer_c); 717 718 // Declare the output value. 719 let output_a = Value::from_str(&format!( 720 "{{ owner: {caller}.private, item: 1234u64.private, _nonce: {nonce_a}.public, _version: 1u8.public }}" 721 )) 722 .unwrap(); 723 let output_b = Value::from_str(&format!( 724 "{{ owner: {caller}.private, item: 4321u64.private, _nonce: {nonce_b}.public, _version: 1u8.public }}" 725 )) 726 .unwrap(); 727 let output_c = Value::from_str(&format!( 728 "{{ owner: {caller}.private, item: 5678u64.private, _nonce: {nonce_c}.public, _version: 1u8.public }}" 729 )) 730 .unwrap(); 731 732 // Check again to make sure we didn't modify the authorization before calling `evaluate`. 733 assert_eq!(authorization.len(), 1); 734 735 // Compute the output value. 736 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 737 let candidate = response.outputs(); 738 assert_eq!(3, candidate.len()); 739 assert_eq!(output_a, candidate[0]); 740 assert_eq!(output_b, candidate[1]); 741 assert_eq!(output_c, candidate[2]); 742 743 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 744 assert_eq!(authorization.len(), 1); 745 746 // Execute the request. 747 let (response, _trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 748 let candidate = response.outputs(); 749 assert_eq!(3, candidate.len()); 750 assert_eq!(output_a, candidate[0]); 751 assert_eq!(output_b, candidate[1]); 752 assert_eq!(output_c, candidate[2]); 753 754 // use circuit::Environment; 755 // 756 // assert_eq!(20060, CurrentAlpha::num_constants()); 757 // assert_eq!(12, CurrentAlpha::num_public()); 758 // assert_eq!(57602, CurrentAlpha::num_private()); 759 // assert_eq!(57684, CurrentAlpha::num_constraints()); 760 // assert_eq!(178189, CurrentAlpha::num_gates()); 761 } 762 763 #[test] 764 fn test_process_self_caller() { 765 // Initialize a new program. 766 let program = Program::<CurrentNetwork>::from_str( 767 r"program caller.delta; 768 769 record data: 770 owner as address.private; 771 item as u64.private; 772 773 function initialize: 774 input r0 as data.record; 775 cast self.caller r0.item into r1 as data.record; 776 output r1 as data.record;", 777 ) 778 .unwrap(); 779 780 // Declare the function name. 781 let function_name = Identifier::from_str("initialize").unwrap(); 782 783 // Initialize the RNG. 784 let rng = &mut TestRng::default(); 785 786 // Construct the process. 787 let process = crate::test_helpers::sample_process(&program); 788 789 // Initialize a new caller account. 790 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 791 let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap(); 792 let caller = Address::try_from(&caller_private_key).unwrap(); 793 794 // Declare the input value. 795 let input = 796 Value::from_str(&format!("{{ owner: {caller}.private, item: 1234u64.private, _nonce: 0group.public }}")) 797 .unwrap(); 798 799 // Authorize the function call. 800 let authorization = process 801 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, [input].iter(), rng) 802 .unwrap(); 803 assert_eq!(authorization.len(), 1); 804 let request = authorization.peek_next().unwrap(); 805 806 // Compute the encryption randomizer as `HashToScalar(tvk || index)`. 807 let randomizer = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(1)]).unwrap(); 808 let nonce = CurrentNetwork::g_scalar_multiply(&randomizer); 809 810 // Declare the output value. 811 let output = Value::from_str(&format!( 812 "{{ owner: {caller}.private, item: 1234u64.private, _nonce: {nonce}.public, _version: 1u8.public }}" 813 )) 814 .unwrap(); 815 816 // Check again to make sure we didn't modify the authorization before calling `evaluate`. 817 assert_eq!(authorization.len(), 1); 818 819 // Compute the output value. 820 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 821 let candidate = response.outputs(); 822 assert_eq!(1, candidate.len()); 823 assert_eq!(output, candidate[0]); 824 825 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 826 assert_eq!(authorization.len(), 1); 827 828 // Execute the request. 829 let (response, _trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 830 let candidate = response.outputs(); 831 assert_eq!(1, candidate.len()); 832 assert_eq!(output, candidate[0]); 833 } 834 835 #[test] 836 fn test_process_program_id() { 837 // Initialize a new program. 838 let program = Program::<CurrentNetwork>::from_str( 839 r"program id.delta; 840 841 struct data: 842 user as address; 843 844 function initialize: 845 cast id.delta into r0 as data; 846 output r0 as data.private;", 847 ) 848 .unwrap(); 849 850 // Declare the program ID. 851 let program_id = ProgramID::from_str("id.delta").unwrap(); 852 assert_eq!(*program.id(), program_id); 853 854 // Declare the function name. 855 let function_name = Identifier::from_str("initialize").unwrap(); 856 857 // Initialize the RNG. 858 let rng = &mut TestRng::default(); 859 860 // Construct the process. 861 let process = crate::test_helpers::sample_process(&program); 862 863 // Initialize a new caller account. 864 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 865 866 // Authorize the function call. 867 let inputs: &[Value<CurrentNetwork>] = &[]; 868 let authorization = process 869 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, inputs.iter(), rng) 870 .unwrap(); 871 assert_eq!(authorization.len(), 1); 872 873 // Declare the output value. 874 let output = Value::from_str(&format!("{{ user: {} }}", program_id.to_address().unwrap())).unwrap(); 875 876 // Check again to make sure we didn't modify the authorization before calling `evaluate`. 877 assert_eq!(authorization.len(), 1); 878 879 // Compute the output value. 880 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 881 let candidate = response.outputs(); 882 assert_eq!(1, candidate.len()); 883 assert_eq!(output, candidate[0]); 884 885 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 886 assert_eq!(authorization.len(), 1); 887 888 // Execute the request. 889 let (response, _trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 890 let candidate = response.outputs(); 891 assert_eq!(1, candidate.len()); 892 assert_eq!(output, candidate[0]); 893 } 894 895 #[test] 896 fn test_process_output_operand() { 897 // Helper function to test authorization, execution, and verification for the program below. 898 fn authorize_execute_and_verify( 899 program: &Program<CurrentNetwork>, 900 function_name: Identifier<CurrentNetwork>, 901 output: Value<CurrentNetwork>, 902 caller_private_key: &PrivateKey<CurrentNetwork>, 903 rng: &mut TestRng, 904 ) { 905 // Construct the process. 906 let process = crate::test_helpers::sample_process(program); 907 908 // Authorize the function call. 909 let inputs: &[Value<CurrentNetwork>] = &[]; 910 let authorization = process 911 .authorize::<CurrentAlpha, _>(caller_private_key, program.id(), function_name, inputs.iter(), rng) 912 .unwrap(); 913 assert_eq!(authorization.len(), 1); 914 915 // Check again to make sure we didn't modify the authorization before calling `evaluate`. 916 assert_eq!(authorization.len(), 1); 917 918 // Compute the output value. 919 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 920 let candidate = response.outputs(); 921 assert_eq!(1, candidate.len()); 922 assert_eq!(output, candidate[0]); 923 924 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 925 assert_eq!(authorization.len(), 1); 926 927 // Execute the request. 928 let (response, _trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 929 let candidate = response.outputs(); 930 assert_eq!(1, candidate.len()); 931 assert_eq!(output, candidate[0]); 932 933 // process.verify_execution::<true>(&execution).unwrap(); 934 } 935 936 // Initialize a new program. 937 let program = Program::<CurrentNetwork>::from_str( 938 r"program operand.delta; 939 940 function program_id: 941 output operand.delta as address.private; 942 943 function literal: 944 output 1234u64 as u64.private; 945 946 function caller: 947 output self.caller as address.private;", 948 ) 949 .unwrap(); 950 951 // Initialize the RNG. 952 let rng = &mut TestRng::default(); 953 954 // Initialize a new caller account. 955 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 956 let caller = Address::try_from(&caller_private_key).unwrap(); 957 958 // Test the `program_id` function. 959 authorize_execute_and_verify( 960 &program, 961 Identifier::from_str("program_id").unwrap(), 962 Value::from_str(&program.id().to_address().unwrap().to_string()).unwrap(), 963 &caller_private_key, 964 rng, 965 ); 966 967 // Test the `literal` function. 968 authorize_execute_and_verify( 969 &program, 970 Identifier::from_str("literal").unwrap(), 971 Value::from_str("1234u64").unwrap(), 972 &caller_private_key, 973 rng, 974 ); 975 976 // Test the `caller` function. 977 authorize_execute_and_verify( 978 &program, 979 Identifier::from_str("caller").unwrap(), 980 Value::from_str(&format!("{caller}")).unwrap(), 981 &caller_private_key, 982 rng, 983 ); 984 } 985 986 #[test] 987 fn test_process_execute_call_closure() { 988 // Initialize a new program. 989 let (string, program) = Program::<CurrentNetwork>::parse( 990 r" 991 program token.delta; 992 993 record token: 994 owner as address.private; 995 token_amount as u64.private; 996 997 // (a + (a + b)) + (a + b) == (3a + 2b) 998 closure execute: 999 input r0 as field; 1000 input r1 as field; 1001 add r0 r1 into r2; 1002 add r0 r2 into r3; 1003 add r2 r3 into r4; 1004 output r4 as field; 1005 output r3 as field; 1006 output r2 as field; 1007 1008 closure check_not_equal: 1009 input r0 as field; 1010 input r1 as field; 1011 assert.neq r0 r1; 1012 1013 function compute: 1014 input r0 as field.private; 1015 input r1 as field.public; 1016 input r2 as token.record; 1017 cast r2.owner r2.token_amount into r3 as token.record; 1018 call check_not_equal r0 r1; 1019 call execute r0 r1 into r4 r5 r6; 1020 output r3 as token.record; 1021 output r4 as field.private; 1022 output r5 as field.private; 1023 output r6 as field.private;", 1024 ) 1025 .unwrap(); 1026 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 1027 1028 // Declare the function name. 1029 let function_name = Identifier::from_str("compute").unwrap(); 1030 1031 // Initialize the RNG. 1032 let rng = &mut TestRng::default(); 1033 1034 // Construct the process. 1035 let process = crate::test_helpers::sample_process(&program); 1036 // Check that the circuit key can be synthesized. 1037 process.synthesize_key::<CurrentAlpha, _>(program.id(), &function_name, rng).unwrap(); 1038 1039 // Reset the process. 1040 let process = crate::test_helpers::sample_process(&program); 1041 1042 // Initialize a new caller account. 1043 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 1044 let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap(); 1045 let caller = Address::try_from(&caller_private_key).unwrap(); 1046 1047 // Prepare a record belonging to the address. 1048 let record_string = format!("{{ owner: {caller}.private, token_amount: 100u64.private, _nonce: 0group.public }}"); 1049 1050 // Declare the input value. 1051 let r0 = Value::<CurrentNetwork>::from_str("3field").unwrap(); 1052 let r1 = Value::<CurrentNetwork>::from_str("5field").unwrap(); 1053 let r2 = Value::<CurrentNetwork>::from_str(&record_string).unwrap(); 1054 1055 // Authorize the function call. 1056 let authorization = process 1057 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, [r0, r1, r2].iter(), rng) 1058 .unwrap(); 1059 assert_eq!(authorization.len(), 1); 1060 let request = authorization.peek_next().unwrap(); 1061 1062 // Compute the encryption randomizer as `HashToScalar(tvk || index)`. 1063 let randomizer = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(3)]).unwrap(); 1064 let nonce = CurrentNetwork::g_scalar_multiply(&randomizer); 1065 1066 // Declare the expected output value. 1067 let r3 = Value::<CurrentNetwork>::from_str(&format!( 1068 "{{ owner: {caller}.private, token_amount: 100u64.private, _nonce: {nonce}.public, _version: 1u8.public }}" 1069 )) 1070 .unwrap(); 1071 let r4 = Value::from_str("19field").unwrap(); 1072 let r5 = Value::from_str("11field").unwrap(); 1073 let r6 = Value::from_str("8field").unwrap(); 1074 1075 // Check again to make sure we didn't modify the authorization before calling `evaluate`. 1076 assert_eq!(authorization.len(), 1); 1077 1078 // Compute the output value. 1079 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 1080 let candidate = response.outputs(); 1081 assert_eq!(4, candidate.len()); 1082 assert_eq!(r3, candidate[0]); 1083 assert_eq!(r4, candidate[1]); 1084 assert_eq!(r5, candidate[2]); 1085 assert_eq!(r6, candidate[3]); 1086 1087 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 1088 assert_eq!(authorization.len(), 1); 1089 1090 // Execute the request. 1091 let (response, _trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 1092 let candidate = response.outputs(); 1093 assert_eq!(4, candidate.len()); 1094 assert_eq!(r3, candidate[0]); 1095 assert_eq!(r4, candidate[1]); 1096 assert_eq!(r5, candidate[2]); 1097 assert_eq!(r6, candidate[3]); 1098 1099 // use circuit::Environment; 1100 // 1101 // assert_eq!(37080, CurrentAlpha::num_constants()); 1102 // assert_eq!(12, CurrentAlpha::num_public()); 1103 // assert_eq!(41630, CurrentAlpha::num_private()); 1104 // assert_eq!(41685, CurrentAlpha::num_constraints()); 1105 // assert_eq!(159387, CurrentAlpha::num_gates()); 1106 } 1107 1108 #[test] 1109 fn test_process_execute_call_external_function() { 1110 // Initialize a new program. 1111 let (string, program0) = Program::<CurrentNetwork>::parse( 1112 r" 1113 program token.delta; 1114 1115 record token: 1116 owner as address.private; 1117 amount as u64.private; 1118 1119 function mint: 1120 input r0 as address.private; 1121 input r1 as u64.private; 1122 cast r0 r1 into r2 as token.record; 1123 output r2 as token.record; 1124 1125 function produce_magic_number: 1126 add 1234u64 0u64 into r0; 1127 output r0 as u64.private; 1128 1129 function check_magic_number: 1130 input r0 as u64.private; 1131 assert.eq r0 1234u64; 1132 1133 function noop: 1134 1135 function transfer: 1136 input r0 as token.record; 1137 input r1 as address.private; 1138 input r2 as u64.private; 1139 sub r0.amount r2 into r3; 1140 cast r1 r2 into r4 as token.record; 1141 cast r0.owner r3 into r5 as token.record; 1142 output r4 as token.record; 1143 output r5 as token.record;", 1144 ) 1145 .unwrap(); 1146 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 1147 1148 // Construct the process. 1149 let mut process = crate::test_helpers::sample_process(&program0); 1150 // Initialize another program. 1151 let (string, program1) = Program::<CurrentNetwork>::parse( 1152 r" 1153 import token.delta; 1154 1155 program wallet.delta; 1156 1157 function transfer: 1158 input r0 as token.delta/token.record; 1159 input r1 as address.private; 1160 input r2 as u64.private; 1161 call token.delta/noop; 1162 call token.delta/produce_magic_number into r3; 1163 call token.delta/check_magic_number r3; 1164 call token.delta/transfer r0 r1 r2 into r4 r5; 1165 output r4 as token.delta/token.record; 1166 output r5 as token.delta/token.record;", 1167 ) 1168 .unwrap(); 1169 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 1170 1171 // Add the program to the process. 1172 process.add_program(&program1).unwrap(); 1173 1174 // Initialize the RNG. 1175 let rng = &mut TestRng::default(); 1176 1177 // Initialize caller 0. 1178 let caller0_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 1179 let caller0 = Address::try_from(&caller0_private_key).unwrap(); 1180 1181 // Initialize caller 1. 1182 let caller1_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 1183 let caller1 = Address::try_from(&caller1_private_key).unwrap(); 1184 1185 // Declare the function name. 1186 let function_name = Identifier::from_str("transfer").unwrap(); 1187 1188 // Declare the input value. 1189 let r0 = Value::<CurrentNetwork>::from_str(&format!( 1190 "{{ owner: {caller0}.private, amount: 100u64.private, _nonce: 0group.public }}" 1191 )) 1192 .unwrap(); 1193 let r1 = Value::<CurrentNetwork>::from_str(&caller1.to_string()).unwrap(); 1194 let r2 = Value::<CurrentNetwork>::from_str("99u64").unwrap(); 1195 1196 // Authorize the function call. 1197 let authorization = process 1198 .authorize::<CurrentAlpha, _>(&caller0_private_key, program1.id(), function_name, [r0, r1, r2].iter(), rng) 1199 .unwrap(); 1200 assert_eq!(authorization.len(), 5); 1201 println!("\nAuthorize\n{:#?}\n\n", authorization.to_vec_deque()); 1202 1203 let (output_a, output_b) = { 1204 // Fetch the first request. 1205 let request = authorization.to_vec_deque().pop_back().unwrap(); 1206 1207 // Compute the encryption randomizer as `HashToScalar(tvk || index)`. 1208 let randomizer_a = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(4)]).unwrap(); 1209 let nonce_a = CurrentNetwork::g_scalar_multiply(&randomizer_a); 1210 1211 // Compute the encryption randomizer as `HashToScalar(tvk || index)`. 1212 let randomizer_b = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(5)]).unwrap(); 1213 let nonce_b = CurrentNetwork::g_scalar_multiply(&randomizer_b); 1214 1215 // Declare the expected output value. 1216 let output_a = Value::from_str(&format!( 1217 "{{ owner: {caller1}.private, amount: 99u64.private, _nonce: {nonce_a}.public, _version: 1u8.public }}" 1218 )) 1219 .unwrap(); 1220 let output_b = Value::from_str(&format!( 1221 "{{ owner: {caller0}.private, amount: 1u64.private, _nonce: {nonce_b}.public, _version: 1u8.public }}" 1222 )) 1223 .unwrap(); 1224 1225 (output_a, output_b) 1226 }; 1227 1228 // Check again to make sure we didn't modify the authorization before calling `evaluate`. 1229 assert_eq!(authorization.len(), 5); 1230 1231 // Compute the output value. 1232 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 1233 let candidate = response.outputs(); 1234 assert_eq!(2, candidate.len()); 1235 assert_eq!(output_a, candidate[0]); 1236 assert_eq!(output_b, candidate[1]); 1237 1238 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 1239 assert_eq!(authorization.len(), 5); 1240 1241 // Execute the request. 1242 let (response, _trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 1243 let candidate = response.outputs(); 1244 assert_eq!(2, candidate.len()); 1245 assert_eq!(output_a, candidate[0]); 1246 assert_eq!(output_b, candidate[1]); 1247 1248 // use circuit::Environment; 1249 // 1250 // assert_eq!(6427, CurrentAlpha::num_constants()); 1251 // assert_eq!(8, CurrentAlpha::num_public()); 1252 // assert_eq!(21264, CurrentAlpha::num_private()); 1253 // assert_eq!(21279, CurrentAlpha::num_constraints()); 1254 // assert_eq!(81872, CurrentAlpha::num_gates()); 1255 // 1256 // assert_eq!(18504, CurrentAlpha::num_constants()); 1257 // assert_eq!(17, CurrentAlpha::num_public()); 1258 // assert_eq!(58791, CurrentAlpha::num_private()); 1259 // assert_eq!(58855, CurrentAlpha::num_constraints()); 1260 // assert_eq!(215810, CurrentAlpha::num_gates()); 1261 } 1262 1263 #[test] 1264 fn test_process_execute_and_finalize_get_add_set() { 1265 // Initialize a new program. 1266 let (string, program) = Program::<CurrentNetwork>::parse( 1267 r" 1268 program testing.delta; 1269 1270 mapping account: 1271 key as address.public; 1272 value as u64.public; 1273 1274 function compute: 1275 input r0 as address.public; 1276 input r1 as u64.public; 1277 input r2 as u64.public; 1278 add r1 r2 into r3; 1279 async compute r0 r3 into r4; 1280 output r4 as testing.delta/compute.future; 1281 1282 finalize compute: 1283 input r0 as address.public; 1284 input r1 as u64.public; 1285 get.or_use account[r0] 0u64 into r2; 1286 add r2 r1 into r3; 1287 set r3 into account[r0]; 1288 ", 1289 ) 1290 .unwrap(); 1291 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 1292 1293 // Declare the program ID. 1294 let program_id = program.id(); 1295 // Declare the mapping. 1296 let mapping_name = Identifier::from_str("account").unwrap(); 1297 // Declare the function name. 1298 let function_name = Identifier::from_str("compute").unwrap(); 1299 1300 // Initialize the RNG. 1301 let rng = &mut TestRng::default(); 1302 1303 // Construct the process. 1304 let process = crate::test_helpers::sample_process(&program); 1305 // Check that the circuit key can be synthesized. 1306 process.synthesize_key::<CurrentAlpha, _>(program.id(), &function_name, rng).unwrap(); 1307 1308 // Reset the process. 1309 let mut process = Process::load().unwrap(); 1310 1311 // Initialize a new block store. 1312 let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 1313 // Initialize a new finalize store. 1314 let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 1315 1316 // Add the program to the process. 1317 let deployment = process.deploy::<CurrentAlpha, _>(&program, rng).unwrap(); 1318 // Check that the deployment verifies. 1319 process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V10, &deployment, rng).unwrap(); 1320 // Compute the fee. 1321 let fee = sample_fee::<_, CurrentAlpha, _, _>(&process, &block_store, &finalize_store, rng); 1322 // Finalize the deployment. 1323 let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap(); 1324 // Add the stack *manually* to the process. 1325 process.add_stack(stack); 1326 1327 // Initialize a new caller account. 1328 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 1329 let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap(); 1330 let caller = Address::try_from(&caller_private_key).unwrap(); 1331 1332 // Declare the input value. 1333 let r0 = Value::<CurrentNetwork>::from_str(&caller.to_string()).unwrap(); 1334 let r1 = Value::<CurrentNetwork>::from_str("3u64").unwrap(); 1335 let r2 = Value::<CurrentNetwork>::from_str("5u64").unwrap(); 1336 1337 // Authorize the function call. 1338 let authorization = process 1339 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, [r0, r1, r2].iter(), rng) 1340 .unwrap(); 1341 assert_eq!(authorization.len(), 1); 1342 1343 let expected_execution_cost = 1344 execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap(); 1345 1346 // Compute the output value. 1347 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 1348 let candidate = response.outputs(); 1349 assert_eq!(1, candidate.len()); 1350 1351 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 1352 assert_eq!(authorization.len(), 1); 1353 1354 // Execute the request. 1355 let (response, mut trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 1356 let candidate = response.outputs(); 1357 assert_eq!(1, candidate.len()); 1358 1359 // Prepare the trace. 1360 trace.prepare(&Query::from(block_store)).unwrap(); 1361 // Prove the execution. 1362 let execution = trace.prove_execution::<CurrentAlpha, _>("testing", VarunaVersion::V2, rng).unwrap(); 1363 // Verify the execution. 1364 process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap(); 1365 1366 // Check the execution cost 1367 assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost); 1368 1369 // Now, finalize the execution. 1370 process.finalize_execution(sample_finalize_state(1), &finalize_store, &execution, None).unwrap(); 1371 1372 // Check that the account balance is now 8. 1373 let candidate = finalize_store 1374 .get_value_speculative(*program_id, mapping_name, &Plaintext::from(Literal::Address(caller))) 1375 .unwrap() 1376 .unwrap(); 1377 assert_eq!(candidate, Value::from_str("8u64").unwrap()); 1378 } 1379 1380 #[test] 1381 fn test_process_execute_and_finalize_increment_decrement_via_get_set() { 1382 // Initialize a new program. 1383 let (string, program) = Program::<CurrentNetwork>::parse( 1384 r" 1385 program testing.delta; 1386 1387 mapping account: 1388 key as address.public; 1389 value as u64.public; 1390 1391 function compute: 1392 input r0 as address.public; 1393 input r1 as u64.public; 1394 input r2 as u64.public; 1395 add r1 r2 into r3; 1396 async compute r0 r3 into r4; 1397 output r4 as testing.delta/compute.future; 1398 1399 finalize compute: 1400 input r0 as address.public; 1401 input r1 as u64.public; 1402 get.or_use account[r0] 0u64 into r2; 1403 add r2 r1 into r3; 1404 sub r3 r1 into r4; 1405 set r4 into account[r0]; 1406 ", 1407 ) 1408 .unwrap(); 1409 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 1410 1411 // Declare the program ID. 1412 let program_id = program.id(); 1413 // Declare the mapping. 1414 let mapping_name = Identifier::from_str("account").unwrap(); 1415 // Declare the function name. 1416 let function_name = Identifier::from_str("compute").unwrap(); 1417 1418 // Initialize the RNG. 1419 let rng = &mut TestRng::default(); 1420 1421 // Construct the process. 1422 let process = crate::test_helpers::sample_process(&program); 1423 // Check that the circuit key can be synthesized. 1424 process.synthesize_key::<CurrentAlpha, _>(program.id(), &function_name, rng).unwrap(); 1425 1426 // Reset the process. 1427 let mut process = Process::load().unwrap(); 1428 1429 // Initialize a new block store. 1430 let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 1431 // Initialize a new finalize store. 1432 let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 1433 1434 // Add the program to the process. 1435 let deployment = process.deploy::<CurrentAlpha, _>(&program, rng).unwrap(); 1436 // Check that the deployment verifies. 1437 process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V10, &deployment, rng).unwrap(); 1438 // Compute the fee. 1439 let fee = sample_fee::<_, CurrentAlpha, _, _>(&process, &block_store, &finalize_store, rng); 1440 // Finalize the deployment. 1441 let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap(); 1442 // Add the stack *manually* to the process. 1443 process.add_stack(stack); 1444 1445 // Initialize a new caller account. 1446 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 1447 let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap(); 1448 let caller = Address::try_from(&caller_private_key).unwrap(); 1449 1450 // Declare the input value. 1451 let r0 = Value::<CurrentNetwork>::from_str(&caller.to_string()).unwrap(); 1452 let r1 = Value::<CurrentNetwork>::from_str("3u64").unwrap(); 1453 let r2 = Value::<CurrentNetwork>::from_str("5u64").unwrap(); 1454 1455 // Authorize the function call. 1456 let authorization = process 1457 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, [r0, r1, r2].iter(), rng) 1458 .unwrap(); 1459 assert_eq!(authorization.len(), 1); 1460 1461 let expected_execution_cost = 1462 execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap(); 1463 1464 // Compute the output value. 1465 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 1466 let candidate = response.outputs(); 1467 assert_eq!(1, candidate.len()); 1468 1469 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 1470 assert_eq!(authorization.len(), 1); 1471 1472 // Execute the request. 1473 let (response, mut trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 1474 let candidate = response.outputs(); 1475 assert_eq!(1, candidate.len()); 1476 1477 // Prepare the trace. 1478 trace.prepare(&Query::from(block_store)).unwrap(); 1479 // Prove the execution. 1480 let execution = trace.prove_execution::<CurrentAlpha, _>("testing", VarunaVersion::V2, rng).unwrap(); 1481 1482 // Verify the execution. 1483 process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap(); 1484 1485 // Check the execution cost 1486 assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost); 1487 1488 // Now, finalize the execution. 1489 process.finalize_execution(sample_finalize_state(1), &finalize_store, &execution, None).unwrap(); 1490 1491 // Check that the account balance is now 0. 1492 let candidate = finalize_store 1493 .get_value_speculative(*program_id, mapping_name, &Plaintext::from(Literal::Address(caller))) 1494 .unwrap() 1495 .unwrap(); 1496 assert_eq!(candidate, Value::from_str("0u64").unwrap()); 1497 } 1498 1499 #[test] 1500 fn test_process_execute_mint_public() { 1501 // Initialize a new program. 1502 let (string, program) = Program::<CurrentNetwork>::parse( 1503 r" 1504 program token.delta; 1505 1506 // On-chain storage of an `account` map, with `owner` as the key, 1507 // and `amount` as the value. 1508 mapping account: 1509 // The token owner. 1510 key as address.public; 1511 // The token amount. 1512 value as u64.public; 1513 1514 // The function `mint_public` issues the specified token amount 1515 // for the token receiver publicly on the network. 1516 function mint_public: 1517 // Input the token receiver. 1518 input r0 as address.public; 1519 // Input the token amount. 1520 input r1 as u64.public; 1521 // Mint the tokens publicly. 1522 async mint_public r0 r1 into r2; 1523 output r2 as token.delta/mint_public.future; 1524 1525 // The finalize scope of `mint_public` increments the 1526 // `account` of the token receiver by the specified amount. 1527 finalize mint_public: 1528 // Input the token receiver. 1529 input r0 as address.public; 1530 // Input the token amount. 1531 input r1 as u64.public; 1532 1533 // Get `account[r0]` into `r2`, defaulting to 0u64 if the entry does not exist. 1534 get.or_use account[r0] 0u64 into r2; 1535 // Add `r1` to `r2`. If the operation overflows, `mint_public` is reverted. 1536 add r2 r1 into r3; 1537 // Set `r3` into `account[r0]`. 1538 set r3 into account[r0]; 1539 ", 1540 ) 1541 .unwrap(); 1542 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 1543 1544 // Declare the program ID. 1545 let program_id = program.id(); 1546 // Declare the mapping. 1547 let mapping_name = Identifier::from_str("account").unwrap(); 1548 // Declare the function name. 1549 let function_name = Identifier::from_str("mint_public").unwrap(); 1550 1551 // Initialize the RNG. 1552 let rng = &mut TestRng::default(); 1553 1554 // Construct the process. 1555 let process = crate::test_helpers::sample_process(&program); 1556 // Check that the circuit key can be synthesized. 1557 process.synthesize_key::<CurrentAlpha, _>(program.id(), &function_name, rng).unwrap(); 1558 1559 // Reset the process. 1560 let mut process = Process::load().unwrap(); 1561 1562 // Initialize a new block store. 1563 let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 1564 // Initialize a new finalize store. 1565 let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 1566 1567 // Add the program to the process. 1568 let deployment = process.deploy::<CurrentAlpha, _>(&program, rng).unwrap(); 1569 // Check that the deployment verifies. 1570 process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V10, &deployment, rng).unwrap(); 1571 // Compute the fee. 1572 let fee = sample_fee::<_, CurrentAlpha, _, _>(&process, &block_store, &finalize_store, rng); 1573 // Finalize the deployment. 1574 let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap(); 1575 // Add the stack *manually* to the process. 1576 process.add_stack(stack); 1577 1578 // TODO (howardwu): Remove this. I call this to synthesize the proving key independent of the assignment from 'execute'. 1579 // In general, we should update all tests to utilize a presynthesized proving key, before execution, to test 1580 // the correctness of the synthesizer. 1581 process.synthesize_key::<CurrentAlpha, _>(program.id(), &function_name, rng).unwrap(); 1582 1583 // Initialize a new caller account. 1584 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 1585 let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap(); 1586 let caller = Address::try_from(&caller_private_key).unwrap(); 1587 1588 // Declare the input value. 1589 let r0 = Value::<CurrentNetwork>::from_str(&caller.to_string()).unwrap(); 1590 let r1 = Value::<CurrentNetwork>::from_str("3u64").unwrap(); 1591 1592 // Authorize the function call. 1593 let authorization = process 1594 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, [r0, r1].iter(), rng) 1595 .unwrap(); 1596 assert_eq!(authorization.len(), 1); 1597 1598 // Compute the output value. 1599 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 1600 let candidate = response.outputs(); 1601 assert_eq!(1, candidate.len()); 1602 1603 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 1604 assert_eq!(authorization.len(), 1); 1605 1606 let expected_execution_cost = 1607 execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap(); 1608 1609 // Execute the request. 1610 let (response, mut trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 1611 let candidate = response.outputs(); 1612 assert_eq!(1, candidate.len()); 1613 1614 // Prepare the trace. 1615 trace.prepare(&Query::from(block_store)).unwrap(); 1616 // Prove the execution. 1617 let execution = trace.prove_execution::<CurrentAlpha, _>("token", VarunaVersion::V2, rng).unwrap(); 1618 1619 // Verify the execution. 1620 process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap(); 1621 1622 // Check the execution cost 1623 assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost); 1624 1625 // Now, finalize the execution. 1626 process.finalize_execution(sample_finalize_state(1), &finalize_store, &execution, None).unwrap(); 1627 1628 // Check the account balance. 1629 let candidate = finalize_store 1630 .get_value_speculative(*program_id, mapping_name, &Plaintext::from(Literal::Address(caller))) 1631 .unwrap() 1632 .unwrap(); 1633 assert_eq!(candidate, Value::from_str("3u64").unwrap()); 1634 } 1635 1636 #[test] 1637 fn test_process_execute_call_mint_public() { 1638 // Initialize a new program. 1639 let (string, program0) = Program::<CurrentNetwork>::parse( 1640 r" 1641 program token.delta; 1642 1643 // On-chain storage of an `account` map, with `owner` as the key, 1644 // and `amount` as the value. 1645 mapping account: 1646 // The token owner. 1647 key as address.public; 1648 // The token amount. 1649 value as u64.public; 1650 1651 // The function `mint_public` issues the specified token amount 1652 // for the token receiver publicly on the network. 1653 function mint_public: 1654 // Input the token receiver. 1655 input r0 as address.public; 1656 // Input the token amount. 1657 input r1 as u64.public; 1658 // Mint the tokens publicly. 1659 async mint_public r0 r1 into r2; 1660 output r2 as token.delta/mint_public.future; 1661 1662 // The finalize scope of `mint_public` increments the 1663 // `account` of the token receiver by the specified amount. 1664 finalize mint_public: 1665 // Input the token receiver. 1666 input r0 as address.public; 1667 // Input the token amount. 1668 input r1 as u64.public; 1669 1670 // Get `account[r0]` into `r2`, defaulting to 0u64 if the entry does not exist. 1671 get.or_use account[r0] 0u64 into r2; 1672 // Add `r1` to `r2`. If the operation overflows, `mint_public` is reverted. 1673 add r2 r1 into r3; 1674 // Set `r3` into `account[r0]`. 1675 set r3 into account[r0]; 1676 ", 1677 ) 1678 .unwrap(); 1679 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 1680 1681 // Declare the mapping. 1682 let mapping_name = Identifier::from_str("account").unwrap(); 1683 // Declare the function name. 1684 let function_name = Identifier::from_str("mint_public").unwrap(); 1685 1686 // Initialize the RNG. 1687 let rng = &mut TestRng::default(); 1688 1689 // Construct the process. 1690 let process = crate::test_helpers::sample_process(&program0); 1691 // Check that the circuit key can be synthesized. 1692 process.synthesize_key::<CurrentAlpha, _>(program0.id(), &function_name, rng).unwrap(); 1693 1694 // Reset the process. 1695 let mut process = Process::load().unwrap(); 1696 1697 // Initialize a new block store. 1698 let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 1699 // Initialize a new finalize store. 1700 let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 1701 1702 // Add the program to the process. 1703 let deployment = process.deploy::<CurrentAlpha, _>(&program0, rng).unwrap(); 1704 // Check that the deployment verifies. 1705 process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V10, &deployment, rng).unwrap(); 1706 // Compute the fee. 1707 let fee = sample_fee::<_, CurrentAlpha, _, _>(&process, &block_store, &finalize_store, rng); 1708 // Finalize the deployment. 1709 let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap(); 1710 // Add the stack *manually* to the process. 1711 process.add_stack(stack); 1712 1713 // TODO (howardwu): Remove this. I call this to synthesize the proving key independent of the assignment from 'execute'. 1714 // In general, we should update all tests to utilize a presynthesized proving key, before execution, to test 1715 // the correctness of the synthesizer. 1716 process.synthesize_key::<CurrentAlpha, _>(program0.id(), &function_name, rng).unwrap(); 1717 1718 // Initialize another program. 1719 let (string, program1) = Program::<CurrentNetwork>::parse( 1720 r" 1721 import token.delta; 1722 1723 program public_wallet.delta; 1724 1725 function init: 1726 input r0 as address.public; 1727 input r1 as u64.public; 1728 call token.delta/mint_public r0 r1 into r2; 1729 async init r2 into r3; 1730 output r3 as public_wallet.delta/init.future; 1731 finalize init: 1732 input r0 as token.delta/mint_public.future; 1733 await r0; 1734 ", 1735 ) 1736 .unwrap(); 1737 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 1738 1739 // Declare the function name. 1740 let function_name = Identifier::from_str("init").unwrap(); 1741 1742 // Add the program to the process. 1743 let deployment = process.deploy::<CurrentAlpha, _>(&program1, rng).unwrap(); 1744 // Check that the deployment verifies. 1745 process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V10, &deployment, rng).unwrap(); 1746 // Compute the fee. 1747 let fee = sample_fee::<_, CurrentAlpha, _, _>(&process, &block_store, &finalize_store, rng); 1748 // Finalize the deployment. 1749 let (stack, _) = process.finalize_deployment(sample_finalize_state(2), &finalize_store, &deployment, &fee).unwrap(); 1750 // Add the stack *manually* to the process. 1751 process.add_stack(stack); 1752 1753 // TODO (howardwu): Remove this. I call this to synthesize the proving key independent of the assignment from 'execute'. 1754 // In general, we should update all tests to utilize a presynthesized proving key, before execution, to test 1755 // the correctness of the synthesizer. 1756 process.synthesize_key::<CurrentAlpha, _>(program1.id(), &function_name, rng).unwrap(); 1757 1758 // Initialize caller. 1759 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 1760 let caller = Address::try_from(&caller_private_key).unwrap(); 1761 1762 // Declare the input value. 1763 let r0 = Value::<CurrentNetwork>::from_str(&caller.to_string()).unwrap(); 1764 let r1 = Value::<CurrentNetwork>::from_str("100u64").unwrap(); 1765 1766 // Authorize the function call. 1767 let authorization = process 1768 .authorize::<CurrentAlpha, _>(&caller_private_key, program1.id(), function_name, [r0, r1].iter(), rng) 1769 .unwrap(); 1770 assert_eq!(authorization.len(), 2); 1771 1772 let expected_execution_cost = 1773 execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap(); 1774 1775 // Compute the output value. 1776 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 1777 let candidate = response.outputs(); 1778 assert_eq!(1, candidate.len()); 1779 1780 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 1781 assert_eq!(authorization.len(), 2); 1782 1783 // Execute the request. 1784 let (response, mut trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 1785 let candidate = response.outputs(); 1786 assert_eq!(1, candidate.len()); 1787 1788 // Prepare the trace. 1789 trace.prepare(&Query::from(block_store)).unwrap(); 1790 // Prove the execution. 1791 let execution = trace.prove_execution::<CurrentAlpha, _>("public_wallet", VarunaVersion::V2, rng).unwrap(); 1792 1793 // Verify the execution. 1794 process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap(); 1795 1796 // Check the execution cost 1797 assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost); 1798 1799 // Now, finalize the execution. 1800 process.finalize_execution(sample_finalize_state(1), &finalize_store, &execution, None).unwrap(); 1801 1802 // Check the account balance. 1803 let candidate = finalize_store 1804 .get_value_speculative(*program0.id(), mapping_name, &Plaintext::from(Literal::Address(caller))) 1805 .unwrap() 1806 .unwrap(); 1807 assert_eq!(candidate, Value::from_str("100u64").unwrap()); 1808 } 1809 1810 #[test] 1811 fn test_process_execute_and_finalize_get_set() { 1812 // Initialize a new program. 1813 let (string, program) = Program::<CurrentNetwork>::parse( 1814 r" 1815 program testing.delta; 1816 1817 mapping account: 1818 key as address.public; 1819 value as u64.public; 1820 1821 function compute: 1822 input r0 as address.public; 1823 input r1 as u64.public; 1824 input r2 as u64.public; 1825 add r1 r2 into r3; 1826 async compute r0 r3 into r4; 1827 output r4 as testing.delta/compute.future; 1828 1829 finalize compute: 1830 input r0 as address.public; 1831 input r1 as u64.public; 1832 get.or_use account[r0] 0u64 into r2; 1833 add r1 r2 into r3; 1834 set r3 into account[r0]; 1835 get account[r0] into r4; 1836 add r1 r4 into r5; 1837 set r5 into account[r0]; 1838 ", 1839 ) 1840 .unwrap(); 1841 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 1842 1843 // Declare the program ID. 1844 let program_id = program.id(); 1845 // Declare the mapping. 1846 let mapping_name = Identifier::from_str("account").unwrap(); 1847 // Declare the function name. 1848 let function_name = Identifier::from_str("compute").unwrap(); 1849 1850 // Initialize the RNG. 1851 let rng = &mut TestRng::default(); 1852 1853 // Construct the process. 1854 let process = crate::test_helpers::sample_process(&program); 1855 // Check that the circuit key can be synthesized. 1856 process.synthesize_key::<CurrentAlpha, _>(program.id(), &function_name, rng).unwrap(); 1857 1858 // Reset the process. 1859 let mut process = Process::load().unwrap(); 1860 1861 // Initialize a new block store. 1862 let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 1863 // Initialize a new finalize store. 1864 let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 1865 1866 // Add the program to the process. 1867 let deployment = process.deploy::<CurrentAlpha, _>(&program, rng).unwrap(); 1868 // Check that the deployment verifies. 1869 process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V10, &deployment, rng).unwrap(); 1870 // Compute the fee. 1871 let fee = sample_fee::<_, CurrentAlpha, _, _>(&process, &block_store, &finalize_store, rng); 1872 // Finalize the deployment. 1873 let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap(); 1874 // Add the stack *manually* to the process. 1875 process.add_stack(stack); 1876 1877 // Initialize a new caller account. 1878 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 1879 let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap(); 1880 let caller = Address::try_from(&caller_private_key).unwrap(); 1881 1882 // Declare the input value. 1883 let r0 = Value::<CurrentNetwork>::from_str(&caller.to_string()).unwrap(); 1884 let r1 = Value::<CurrentNetwork>::from_str("3u64").unwrap(); 1885 let r2 = Value::<CurrentNetwork>::from_str("5u64").unwrap(); 1886 1887 // Authorize the function call. 1888 let authorization = process 1889 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, [r0, r1, r2].iter(), rng) 1890 .unwrap(); 1891 assert_eq!(authorization.len(), 1); 1892 1893 // Compute the output value. 1894 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 1895 let candidate = response.outputs(); 1896 assert_eq!(1, candidate.len()); 1897 1898 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 1899 assert_eq!(authorization.len(), 1); 1900 1901 let expected_execution_cost = 1902 execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap(); 1903 1904 // Execute the request. 1905 let (response, mut trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 1906 let candidate = response.outputs(); 1907 assert_eq!(1, candidate.len()); 1908 1909 // Prepare the trace. 1910 trace.prepare(&Query::from(block_store)).unwrap(); 1911 // Prove the execution. 1912 let execution = trace.prove_execution::<CurrentAlpha, _>("testing", VarunaVersion::V2, rng).unwrap(); 1913 1914 // Verify the execution. 1915 process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap(); 1916 1917 // Check the execution cost 1918 assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost); 1919 1920 // Now, finalize the execution. 1921 process.finalize_execution(sample_finalize_state(1), &finalize_store, &execution, None).unwrap(); 1922 1923 // Check that the account balance is now 8. 1924 let candidate = finalize_store 1925 .get_value_speculative(*program_id, mapping_name, &Plaintext::from(Literal::Address(caller))) 1926 .unwrap() 1927 .unwrap(); 1928 assert_eq!(candidate, Value::from_str("16u64").unwrap()); 1929 } 1930 1931 #[test] 1932 fn test_execution_order() { 1933 // Initialize a new program. 1934 let (string, program0) = Program::<CurrentNetwork>::parse( 1935 r" 1936 program zero.delta; 1937 1938 function c: 1939 input r0 as u8.private; 1940 input r1 as u8.private; 1941 add r0 r1 into r2; 1942 output r2 as u8.private;", 1943 ) 1944 .unwrap(); 1945 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 1946 1947 // Construct the process. 1948 let mut process = crate::test_helpers::sample_process(&program0); 1949 1950 // Initialize another program. 1951 let (string, program1) = Program::<CurrentNetwork>::parse( 1952 r" 1953 import zero.delta; 1954 1955 program one.delta; 1956 1957 function b: 1958 input r0 as u8.private; 1959 input r1 as u8.private; 1960 call zero.delta/c r0 r1 into r2; 1961 output r2 as u8.private;", 1962 ) 1963 .unwrap(); 1964 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 1965 1966 // Add the program to the process. 1967 process.add_program(&program1).unwrap(); 1968 1969 // Initialize another program. 1970 let (string, program2) = Program::<CurrentNetwork>::parse( 1971 r" 1972 import one.delta; 1973 1974 program two.delta; 1975 1976 function a: 1977 input r0 as u8.private; 1978 input r1 as u8.private; 1979 call one.delta/b r0 r1 into r2; 1980 output r2 as u8.private;", 1981 ) 1982 .unwrap(); 1983 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 1984 1985 // Add the program to the process. 1986 process.add_program(&program2).unwrap(); 1987 1988 // Initialize the RNG. 1989 let rng = &mut TestRng::default(); 1990 1991 // Initialize the caller. 1992 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 1993 1994 // Declare the function name. 1995 let function_name = Identifier::from_str("a").unwrap(); 1996 1997 // Declare the input value. 1998 let r0 = Value::<CurrentNetwork>::from_str("1u8").unwrap(); 1999 let r1 = Value::<CurrentNetwork>::from_str("2u8").unwrap(); 2000 2001 // Authorize the function call. 2002 let authorization = process 2003 .authorize::<CurrentAlpha, _>(&caller_private_key, program2.id(), function_name, [r0, r1].iter(), rng) 2004 .unwrap(); 2005 assert_eq!(authorization.len(), 3); 2006 println!("\nAuthorize\n{:#?}\n\n", authorization.to_vec_deque()); 2007 2008 let output = Value::<CurrentNetwork>::from_str("3u8").unwrap(); 2009 2010 // Compute the output value. 2011 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 2012 let candidate = response.outputs(); 2013 assert_eq!(1, candidate.len()); 2014 assert_eq!(output, candidate[0]); 2015 2016 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 2017 assert_eq!(authorization.len(), 3); 2018 2019 let expected_execution_cost = 2020 execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap(); 2021 2022 // Execute the request. 2023 let (response, mut trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 2024 let candidate = response.outputs(); 2025 assert_eq!(1, candidate.len()); 2026 assert_eq!(output, candidate[0]); 2027 2028 // Construct the expected transition order. 2029 let expected_order = [ 2030 (program0.id(), Identifier::<MainnetV0>::from_str("c").unwrap()), 2031 (program1.id(), Identifier::from_str("b").unwrap()), 2032 (program2.id(), Identifier::from_str("a").unwrap()), 2033 ]; 2034 2035 // Check the expected transition order. 2036 for (transition, (expected_program_id, expected_function_name)) in 2037 trace.transitions().iter().zip_eq(expected_order.iter()) 2038 { 2039 assert_eq!(transition.program_id(), *expected_program_id); 2040 assert_eq!(transition.function_name(), expected_function_name); 2041 } 2042 2043 // Initialize a new block store. 2044 let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 2045 // Prepare the trace. 2046 trace.prepare(&Query::from(block_store)).unwrap(); 2047 // Prove the execution. 2048 let execution = trace.prove_execution::<CurrentAlpha, _>("two", VarunaVersion::V2, rng).unwrap(); 2049 2050 // Verify the execution. 2051 process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap(); 2052 2053 // Check the execution cost 2054 assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost); 2055 } 2056 2057 #[test] 2058 fn test_complex_execution_order() { 2059 // This test checks that the execution order is correct. 2060 // The functions are invoked in the following order: 2061 // "four::a" 2062 // --> "two::b" 2063 // --> "zero::c" 2064 // --> "one::d" 2065 // --> "three::e" 2066 // --> "two::b" 2067 // --> "zero::c" 2068 // --> "one::d" 2069 // --> "one::d" 2070 // --> "zero::c" 2071 // The linearized order is: 2072 // - [a, b, c, d, e, b, c, d, d, c] 2073 // The transitions must be included in the `Execution` in the order they finish. 2074 // The execution order is: 2075 // - [c, d, b, c, d, b, d, c, e, a] 2076 2077 // Initialize a new program. 2078 let (string, program0) = Program::<CurrentNetwork>::parse( 2079 r" 2080 program zero.delta; 2081 2082 function c: 2083 input r0 as u8.private; 2084 input r1 as u8.private; 2085 add r0 r1 into r2; 2086 output r2 as u8.private;", 2087 ) 2088 .unwrap(); 2089 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 2090 2091 // Construct the process. 2092 let mut process = crate::test_helpers::sample_process(&program0); 2093 2094 // Initialize another program. 2095 let (string, program1) = Program::<CurrentNetwork>::parse( 2096 r" 2097 program one.delta; 2098 2099 function d: 2100 input r0 as u8.private; 2101 input r1 as u8.private; 2102 add r0 r1 into r2; 2103 output r2 as u8.private;", 2104 ) 2105 .unwrap(); 2106 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 2107 2108 // Add the program to the process. 2109 process.add_program(&program1).unwrap(); 2110 2111 // Initialize another program. 2112 let (string, program2) = Program::<CurrentNetwork>::parse( 2113 r" 2114 import zero.delta; 2115 import one.delta; 2116 2117 program two.delta; 2118 2119 function b: 2120 input r0 as u8.private; 2121 input r1 as u8.private; 2122 call zero.delta/c r0 r1 into r2; 2123 call one.delta/d r1 r2 into r3; 2124 output r3 as u8.private;", 2125 ) 2126 .unwrap(); 2127 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 2128 2129 // Add the program to the process. 2130 process.add_program(&program2).unwrap(); 2131 2132 // Initialize another program. 2133 let (string, program3) = Program::<CurrentNetwork>::parse( 2134 r" 2135 import zero.delta; 2136 import one.delta; 2137 import two.delta; 2138 2139 program three.delta; 2140 2141 function e: 2142 input r0 as u8.private; 2143 input r1 as u8.private; 2144 call two.delta/b r0 r1 into r2; 2145 call one.delta/d r1 r2 into r3; 2146 call zero.delta/c r1 r2 into r4; 2147 output r4 as u8.private;", 2148 ) 2149 .unwrap(); 2150 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 2151 2152 // Add the program to the process. 2153 process.add_program(&program3).unwrap(); 2154 2155 // Initialize another program. 2156 let (string, program4) = Program::<CurrentNetwork>::parse( 2157 r" 2158 import two.delta; 2159 import three.delta; 2160 2161 program four.delta; 2162 2163 function a: 2164 input r0 as u8.private; 2165 input r1 as u8.private; 2166 call two.delta/b r0 r1 into r2; 2167 call three.delta/e r1 r2 into r3; 2168 output r3 as u8.private;", 2169 ) 2170 .unwrap(); 2171 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 2172 2173 // Add the program to the process. 2174 process.add_program(&program4).unwrap(); 2175 2176 // Initialize the RNG. 2177 let rng = &mut TestRng::default(); 2178 2179 // Initialize caller. 2180 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 2181 2182 // Declare the function name. 2183 let function_name = Identifier::from_str("a").unwrap(); 2184 2185 // Declare the input value. 2186 let r0 = Value::<CurrentNetwork>::from_str("1u8").unwrap(); 2187 let r1 = Value::<CurrentNetwork>::from_str("2u8").unwrap(); 2188 2189 // Authorize the function call. 2190 let authorization = process 2191 .authorize::<CurrentAlpha, _>(&caller_private_key, program4.id(), function_name, [r0, r1].iter(), rng) 2192 .unwrap(); 2193 assert_eq!(authorization.len(), 10); 2194 println!("\nAuthorize\n{:#?}\n\n", authorization.to_vec_deque()); 2195 2196 let expected_execution_cost = 2197 execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap(); 2198 2199 let output = Value::<CurrentNetwork>::from_str("17u8").unwrap(); 2200 2201 // Compute the output value. 2202 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 2203 let candidate = response.outputs(); 2204 assert_eq!(1, candidate.len()); 2205 assert_eq!(output, candidate[0]); 2206 2207 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 2208 assert_eq!(authorization.len(), 10); 2209 2210 // Execute the request. 2211 let (response, mut trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 2212 let candidate = response.outputs(); 2213 assert_eq!(1, candidate.len()); 2214 assert_eq!(output, candidate[0]); 2215 2216 // Construct the expected execution order. 2217 let expected_order = [ 2218 (program0.id(), Identifier::<MainnetV0>::from_str("c").unwrap()), 2219 (program1.id(), Identifier::<MainnetV0>::from_str("d").unwrap()), 2220 (program2.id(), Identifier::<MainnetV0>::from_str("b").unwrap()), 2221 (program0.id(), Identifier::<MainnetV0>::from_str("c").unwrap()), 2222 (program1.id(), Identifier::<MainnetV0>::from_str("d").unwrap()), 2223 (program2.id(), Identifier::<MainnetV0>::from_str("b").unwrap()), 2224 (program1.id(), Identifier::<MainnetV0>::from_str("d").unwrap()), 2225 (program0.id(), Identifier::<MainnetV0>::from_str("c").unwrap()), 2226 (program3.id(), Identifier::<MainnetV0>::from_str("e").unwrap()), 2227 (program4.id(), Identifier::<MainnetV0>::from_str("a").unwrap()), 2228 ]; 2229 for (transition, (expected_program_id, expected_function_name)) in 2230 trace.transitions().iter().zip_eq(expected_order.iter()) 2231 { 2232 assert_eq!(transition.program_id(), *expected_program_id); 2233 assert_eq!(transition.function_name(), expected_function_name); 2234 } 2235 2236 // Initialize a new block store. 2237 let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 2238 // Prepare the trace. 2239 trace.prepare(&Query::from(block_store)).unwrap(); 2240 // Prove the execution. 2241 let execution = trace.prove_execution::<CurrentAlpha, _>("four", VarunaVersion::V2, rng).unwrap(); 2242 2243 // Verify the execution. 2244 process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap(); 2245 2246 // Check the execution cost 2247 assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost); 2248 } 2249 2250 #[test] 2251 fn test_process_execute_and_finalize_get_set_with_struct() { 2252 // Initialize a new program. 2253 let (string, program) = Program::<CurrentNetwork>::parse( 2254 r" 2255 program testing.delta; 2256 2257 struct entry: 2258 count as u8; 2259 data as u8; 2260 2261 mapping entries: 2262 key as address.public; 2263 value as entry.public; 2264 2265 function compute: 2266 input r0 as u8.public; 2267 input r1 as u8.public; 2268 cast r0 r1 into r2 as entry; 2269 async compute self.caller r2 into r3; 2270 output r3 as testing.delta/compute.future; 2271 2272 finalize compute: 2273 input r0 as address.public; 2274 input r1 as entry.public; 2275 get.or_use entries[r0] r1 into r2; 2276 add r1.count r2.count into r3; 2277 add r1.data r2.data into r4; 2278 cast r3 r4 into r5 as entry; 2279 set r5 into entries[r0]; 2280 get entries[r0] into r6; 2281 add r6.count r1.count into r7; 2282 add r6.data r1.data into r8; 2283 cast r7 r8 into r9 as entry; 2284 set r9 into entries[r0]; 2285 ", 2286 ) 2287 .unwrap(); 2288 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 2289 2290 // Declare the program ID. 2291 let program_id = program.id(); 2292 // Declare the mapping. 2293 let mapping_name = Identifier::from_str("entries").unwrap(); 2294 // Declare the function name. 2295 let function_name = Identifier::from_str("compute").unwrap(); 2296 2297 // Initialize the RNG. 2298 let rng = &mut TestRng::default(); 2299 2300 // Construct the process. 2301 let process = crate::test_helpers::sample_process(&program); 2302 // Check that the circuit key can be synthesized. 2303 process.synthesize_key::<CurrentAlpha, _>(program.id(), &function_name, rng).unwrap(); 2304 2305 // Reset the process. 2306 let mut process = Process::load().unwrap(); 2307 2308 // Initialize a new block store. 2309 let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 2310 // Initialize a new finalize store. 2311 let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 2312 2313 // Add the program to the process. 2314 let deployment = process.deploy::<CurrentAlpha, _>(&program, rng).unwrap(); 2315 // Check that the deployment verifies. 2316 process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V10, &deployment, rng).unwrap(); 2317 // Compute the fee. 2318 let fee = sample_fee::<_, CurrentAlpha, _, _>(&process, &block_store, &finalize_store, rng); 2319 // Finalize the deployment. 2320 let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap(); 2321 // Add the stack *manually* to the process. 2322 process.add_stack(stack); 2323 2324 // Initialize a new caller account. 2325 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 2326 let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap(); 2327 let caller = Address::try_from(&caller_private_key).unwrap(); 2328 2329 // Declare the input value. 2330 let r0 = Value::<CurrentNetwork>::from_str("1u8").unwrap(); 2331 let r1 = Value::<CurrentNetwork>::from_str("2u8").unwrap(); 2332 2333 // Authorize the function call. 2334 let authorization = process 2335 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, [r0, r1].iter(), rng) 2336 .unwrap(); 2337 assert_eq!(authorization.len(), 1); 2338 2339 // Compute the output value. 2340 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 2341 let candidate = response.outputs(); 2342 assert_eq!(1, candidate.len()); 2343 2344 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 2345 assert_eq!(authorization.len(), 1); 2346 2347 let expected_execution_cost = 2348 execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap(); 2349 2350 // Execute the request. 2351 let (response, mut trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 2352 let candidate = response.outputs(); 2353 assert_eq!(1, candidate.len()); 2354 2355 // Prepare the trace. 2356 trace.prepare(&Query::from(block_store)).unwrap(); 2357 // Prove the execution. 2358 let execution = trace.prove_execution::<CurrentAlpha, _>("testing", VarunaVersion::V2, rng).unwrap(); 2359 2360 // Verify the execution. 2361 process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap(); 2362 2363 // Check the execution cost 2364 assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost); 2365 2366 // Now, finalize the execution. 2367 process.finalize_execution(sample_finalize_state(1), &finalize_store, &execution, None).unwrap(); 2368 2369 // Check that the struct is stored as expected. 2370 let candidate = finalize_store 2371 .get_value_speculative(*program_id, mapping_name, &Plaintext::from(Literal::Address(caller))) 2372 .unwrap() 2373 .unwrap(); 2374 assert_eq!(candidate, Value::from_str("{ count: 3u8, data: 6u8 }").unwrap()); 2375 } 2376 2377 #[test] 2378 fn test_process_execute_and_verify_call_to_closure() { 2379 // Initialize a new program. 2380 let (string, program) = Program::<CurrentNetwork>::parse( 2381 r" 2382 program testing.delta; 2383 2384 // (a + (a + b)) + (a + b) == (3a + 2b) 2385 closure execute: 2386 input r0 as field; 2387 input r1 as field; 2388 add r0 r1 into r2; 2389 add r0 r2 into r3; 2390 add r2 r3 into r4; 2391 output r4 as field; 2392 output r3 as field; 2393 output r2 as field; 2394 2395 closure check_not_equal: 2396 input r0 as field; 2397 input r1 as field; 2398 assert.neq r0 r1; 2399 2400 function compute: 2401 input r0 as field.private; 2402 input r1 as field.public; 2403 call check_not_equal r0 r1; 2404 call execute r0 r1 into r2 r3 r4; 2405 output r2 as field.private; 2406 output r3 as field.private; 2407 output r4 as field.private;", 2408 ) 2409 .unwrap(); 2410 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); 2411 2412 // Declare the function name. 2413 let function_name = Identifier::from_str("compute").unwrap(); 2414 2415 // Initialize the RNG. 2416 let rng = &mut TestRng::default(); 2417 2418 // Construct the process. 2419 let process = crate::test_helpers::sample_process(&program); 2420 // Check that the circuit key can be synthesized. 2421 process.synthesize_key::<CurrentAlpha, _>(program.id(), &function_name, rng).unwrap(); 2422 2423 // Reset the process. 2424 let process = crate::test_helpers::sample_process(&program); 2425 2426 // Initialize a new caller account. 2427 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 2428 2429 // Declare the input value. 2430 let r0 = Value::<CurrentNetwork>::from_str("3field").unwrap(); 2431 let r1 = Value::<CurrentNetwork>::from_str("5field").unwrap(); 2432 2433 // Authorize the function call. 2434 let authorization = process 2435 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), function_name, [r0, r1].iter(), rng) 2436 .unwrap(); 2437 assert_eq!(authorization.len(), 1); 2438 2439 let r2 = Value::from_str("19field").unwrap(); 2440 let r3 = Value::from_str("11field").unwrap(); 2441 let r4 = Value::from_str("8field").unwrap(); 2442 2443 // Check again to make sure we didn't modify the authorization before calling `evaluate`. 2444 assert_eq!(authorization.len(), 1); 2445 2446 // Compute the output value. 2447 let response = process.evaluate::<CurrentAlpha>(authorization.replicate()).unwrap(); 2448 let candidate = response.outputs(); 2449 assert_eq!(3, candidate.len()); 2450 assert_eq!(r2, candidate[0]); 2451 assert_eq!(r3, candidate[1]); 2452 assert_eq!(r4, candidate[2]); 2453 2454 // Check again to make sure we didn't modify the authorization after calling `evaluate`. 2455 assert_eq!(authorization.len(), 1); 2456 2457 let expected_execution_cost = 2458 execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap(); 2459 2460 // Execute the request. 2461 let (response, mut trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 2462 let candidate = response.outputs(); 2463 assert_eq!(3, candidate.len()); 2464 assert_eq!(r2, candidate[0]); 2465 assert_eq!(r3, candidate[1]); 2466 assert_eq!(r4, candidate[2]); 2467 2468 // Initialize a new block store. 2469 let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 2470 // Prepare the trace. 2471 trace.prepare(&Query::from(block_store)).unwrap(); 2472 // Prove the execution. 2473 let execution = trace.prove_execution::<CurrentAlpha, _>("testing", VarunaVersion::V2, rng).unwrap(); 2474 2475 // Verify the execution. 2476 process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap(); 2477 2478 // Check the execution cost 2479 assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost); 2480 } 2481 2482 #[test] 2483 fn test_process_deploy_credits_program() { 2484 let rng = &mut TestRng::default(); 2485 2486 // Initialize an empty process without the `credits` program. 2487 let empty_process = Process { 2488 universal_srs: UniversalSRS::<CurrentNetwork>::load().unwrap(), 2489 stacks: Default::default(), 2490 old_stacks: Default::default(), 2491 }; 2492 2493 // Construct the process. 2494 let process = Process::load().unwrap(); 2495 2496 // Fetch the credits program 2497 let program = Program::credits().unwrap(); 2498 2499 // Create a deployment for the credits.delta program. 2500 let deployment = empty_process.deploy::<CurrentAlpha, _>(&program, rng).unwrap(); 2501 2502 // Ensure the deployment is valid on the empty process. 2503 empty_process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V10, &deployment, rng).unwrap(); 2504 // Ensure the deployment is not valid on the standard process. 2505 assert!(process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V10, &deployment, rng).is_err()); 2506 2507 // Create a new `credits.delta` program. 2508 let program = Program::from_str( 2509 r" 2510 program credits.delta; 2511 2512 record token: 2513 owner as address.private; 2514 amount as u64.private; 2515 2516 function compute: 2517 input r0 as u32.private; 2518 add r0 r0 into r1; 2519 output r1 as u32.public;", 2520 ) 2521 .unwrap(); 2522 2523 // Create a deployment for the credits.delta program. 2524 let deployment = empty_process.deploy::<CurrentAlpha, _>(&program, rng).unwrap(); 2525 2526 // Ensure the deployment is valid on the empty process. 2527 empty_process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V10, &deployment, rng).unwrap(); 2528 // Ensure the deployment is not valid on the standard process. 2529 assert!(process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V10, &deployment, rng).is_err()); 2530 } 2531 2532 #[test] 2533 fn test_process_zero_input_zero_output_executions() { 2534 // Initialize the RNG. 2535 let rng = &mut TestRng::default(); 2536 2537 // Create a new program with a function that has no inputs or outputs. 2538 let function_name = Identifier::from_str("zero_inputs_zero_outputs").unwrap(); 2539 let program = Program::from_str(&format!( 2540 r" 2541 program testing.delta; 2542 function {function_name}: 2543 add 0u8 1u8 into r0;", 2544 )) 2545 .unwrap(); 2546 2547 // Reset the process. 2548 let mut process = Process::load().unwrap(); 2549 2550 // Initialize a new block store. 2551 let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 2552 // Initialize a new finalize store. 2553 let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap(); 2554 2555 // Add the program to the process. 2556 let deployment = process.deploy::<CurrentAlpha, _>(&program, rng).unwrap(); 2557 // Check that the deployment verifies. 2558 process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V10, &deployment, rng).unwrap(); 2559 // Compute the fee. 2560 let fee = sample_fee::<_, CurrentAlpha, _, _>(&process, &block_store, &finalize_store, rng); 2561 // Finalize the deployment. 2562 let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap(); 2563 // Add the stack *manually* to the process. 2564 process.add_stack(stack); 2565 2566 // Initialize a new caller account. 2567 let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap(); 2568 2569 // Create an execution for the `zero_inputs_zero_outputs` function. 2570 let execution_1 = { 2571 // Authorize the function call. 2572 let inputs = Vec::<Value<CurrentNetwork>>::new(); 2573 let authorization = process 2574 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), &function_name, inputs.iter(), rng) 2575 .unwrap(); 2576 2577 // Execute the request. 2578 let (response, mut trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 2579 assert_eq!(response.outputs().len(), 0); 2580 2581 // Prepare the trace. 2582 trace.prepare(&Query::from(block_store.clone())).unwrap(); 2583 // Prove the execution. 2584 trace.prove_execution::<CurrentAlpha, _>("testing", VarunaVersion::V2, rng).unwrap() 2585 }; 2586 assert_eq!(execution_1.len(), 1); 2587 2588 // Create a subsequent execution for the `zero_inputs_zero_outputs` function. 2589 let execution_2 = { 2590 // Authorize the function call. 2591 let inputs = Vec::<Value<CurrentNetwork>>::new(); 2592 let authorization = process 2593 .authorize::<CurrentAlpha, _>(&caller_private_key, program.id(), &function_name, inputs.iter(), rng) 2594 .unwrap(); 2595 2596 // Execute the request. 2597 let (response, mut trace) = process.execute::<CurrentAlpha, _>(authorization, rng).unwrap(); 2598 assert_eq!(response.outputs().len(), 0); 2599 2600 // Prepare the trace. 2601 trace.prepare(&Query::from(block_store)).unwrap(); 2602 // Prove the execution. 2603 trace.prove_execution::<CurrentAlpha, _>("testing", VarunaVersion::V2, rng).unwrap() 2604 }; 2605 assert_eq!(execution_2.len(), 1); 2606 2607 // Ensure that the transitions are unique. 2608 assert_ne!(execution_1.peek().unwrap().id(), execution_2.peek().unwrap().id()); 2609 assert_ne!(execution_1.to_execution_id().unwrap(), execution_2.to_execution_id().unwrap()); 2610 } 2611 2612 #[test] 2613 fn test_long_import_chain() { 2614 const MAX_PROGRAM_DEPTH: usize = 64; 2615 // Initialize a new program. 2616 let program = Program::<CurrentNetwork>::from_str( 2617 r" 2618 program test0.delta; 2619 function c:", 2620 ) 2621 .unwrap(); 2622 2623 // Construct the process. 2624 let mut process = crate::test_helpers::sample_process(&program); 2625 2626 // Add `MAX_PROGRAM_DEPTH` programs to the process. 2627 for i in 1..=MAX_PROGRAM_DEPTH { 2628 println!("Adding program {i}"); 2629 // Initialize a new program. 2630 let program = Program::from_str(&format!( 2631 " 2632 import test{}.delta; 2633 program test{}.delta; 2634 function c:", 2635 i - 1, 2636 i 2637 )) 2638 .unwrap(); 2639 // Add the program to the process. 2640 process.add_program(&program).unwrap(); 2641 } 2642 2643 // Add the `MAX_PROGRAM_DEPTH + 1` program to the process, which should fail. 2644 let program = Program::from_str(&format!( 2645 " 2646 import test{}.delta; 2647 program test{}.delta; 2648 function c:", 2649 MAX_PROGRAM_DEPTH, 2650 MAX_PROGRAM_DEPTH + 1 2651 )) 2652 .unwrap(); 2653 let result = process.add_program(&program); 2654 // Programs may create long import chains as long as number of calls does not exceed the maximum number of transitions. 2655 assert!(result.is_ok()); 2656 } 2657 2658 #[test] 2659 fn test_long_import_chain_with_calls() { 2660 // Initialize a new program. 2661 let program = Program::<CurrentNetwork>::from_str( 2662 r" 2663 program test0.delta; 2664 function c:", 2665 ) 2666 .unwrap(); 2667 2668 // Construct the process. 2669 let mut process = crate::test_helpers::sample_process(&program); 2670 2671 // Check that the number of calls, up to `Transaction::MAX_TRANSITIONS - 1`, is correct. 2672 for i in 1..(Transaction::<CurrentNetwork>::MAX_TRANSITIONS - 1) { 2673 println!("Adding program {i}"); 2674 // Initialize a new program. 2675 let program = Program::from_str(&format!( 2676 " 2677 import test{}.delta; 2678 program test{}.delta; 2679 function c: 2680 call test{}.delta/c;", 2681 i - 1, 2682 i, 2683 i - 1 2684 )) 2685 .unwrap(); 2686 // Add the program to the process. 2687 process.add_program(&program).unwrap(); 2688 // Check that the number of calls is correct. 2689 let stack = process.get_stack(program.id()).unwrap(); 2690 let number_of_calls = stack.get_number_of_calls(program.functions().into_iter().next().unwrap().0).unwrap(); 2691 assert_eq!(number_of_calls, i + 1); 2692 } 2693 2694 // Check that `Transaction::MAX_TRANSITIONS - 1`-th call fails. 2695 let program = Program::from_str(&format!( 2696 " 2697 import test{}.delta; 2698 program test{}.delta; 2699 function c: 2700 call test{}.delta/c;", 2701 Transaction::<CurrentNetwork>::MAX_TRANSITIONS - 2, 2702 Transaction::<CurrentNetwork>::MAX_TRANSITIONS - 1, 2703 Transaction::<CurrentNetwork>::MAX_TRANSITIONS - 2 2704 )) 2705 .unwrap(); 2706 let result = process.add_program(&program); 2707 assert!(result.is_err()) 2708 } 2709 2710 #[test] 2711 fn test_max_imports() { 2712 // Construct the process. 2713 let mut process = Process::<CurrentNetwork>::load().unwrap(); 2714 2715 // Add `MAX_IMPORTS` programs to the process. 2716 for i in 0..CurrentNetwork::MAX_IMPORTS { 2717 println!("Adding program {i}"); 2718 // Initialize a new program. 2719 let program = Program::from_str(&format!("program test{i}.delta; function c:")).unwrap(); 2720 // Add the program to the process. 2721 process.add_program(&program).unwrap(); 2722 } 2723 2724 // Add a program importing all `MAX_IMPORTS` programs, which should pass. 2725 let import_string = 2726 (0..CurrentNetwork::MAX_IMPORTS).map(|i| format!("import test{i}.delta;")).collect::<Vec<_>>().join(" "); 2727 let program = 2728 Program::from_str(&format!("{import_string}program test{}.delta; function c:", CurrentNetwork::MAX_IMPORTS)) 2729 .unwrap(); 2730 process.add_program(&program).unwrap(); 2731 2732 // Attempt to construct a program importing `MAX_IMPORTS + 1` programs, which should fail. 2733 let import_string = 2734 (0..CurrentNetwork::MAX_IMPORTS + 1).map(|i| format!("import test{i}.delta;")).collect::<Vec<_>>().join(" "); 2735 let result = Program::<CurrentNetwork>::from_str(&format!( 2736 "{import_string}program test{}.delta; function c:", 2737 CurrentNetwork::MAX_IMPORTS + 1 2738 )); 2739 assert!(result.is_err()); 2740 } 2741 2742 #[test] 2743 fn test_program_exceeding_transaction_spend_limit() { 2744 // Construct a finalize body whose finalize cost is excessively large. 2745 let mut finalize_body = r" 2746 cast 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 into r0 as [u8; 16u32]; 2747 cast r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 into r1 as [[u8; 16u32]; 16u32]; 2748 cast r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 into r2 as [[[u8; 16u32]; 16u32]; 16u32];" 2749 .to_string(); 2750 (3..500).for_each(|i| { 2751 finalize_body.push_str(&format!("hash.bhp256 r2 into r{i} as field;\n")); 2752 }); 2753 // Construct the program. 2754 let program = Program::from_str(&format!( 2755 r"program test_max_spend_limit.delta; 2756 function foo: 2757 async foo into r0; 2758 output r0 as test_max_spend_limit.delta/foo.future; 2759 2760 finalize foo:{finalize_body}", 2761 )) 2762 .unwrap(); 2763 2764 // Initialize a `Process`. 2765 let process = Process::<CurrentNetwork>::load().unwrap(); 2766 2767 // Attempt to deploy the program, which should succeed. 2768 let rng = &mut TestRng::default(); 2769 let deployment = process.deploy::<CurrentAlpha, _>(&program, rng).unwrap(); 2770 // Attempt to verify the deployment, which should fail. 2771 assert!(process.verify_deployment::<CurrentAlpha, _>(ConsensusVersion::V8, &deployment, rng).is_ok()); 2772 }