Skip to content

Commit 3ee2de8

Browse files
committed
test: add the integration testing of a verification of a sent coin proof
1 parent 1c78133 commit 3ee2de8

2 files changed

Lines changed: 115 additions & 14 deletions

File tree

neptune-core/src/util_types/proof_of_transfer/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ pub fn claim_inputs(
4646
}
4747
/// add the outputs to the claim
4848
///
49-
/// `aocl_digest` part of `Claim` is not mandatory for proving per se, but a comfort facility so that if the prover have not communicated which AOCL instance (i.e. the block) had he used to make the argument, then a verifier
49+
/// `aocl_digest` part of `Claim` is not needed for proving per se, but a comfort facility
50+
/// so that if the prover have not communicated which AOCL instance (i.e. the block) had he
51+
/// used to make the argument, then a verifier
5052
/// could search the block by this `Digest` instead of trying all canonical blocks
5153
pub fn claim_outputs(
5254
c: Claim,
@@ -357,8 +359,8 @@ pub async fn helper(
357359
.ok_or(anyhow!("no canonical block with the given digest"))?;
358360

359361
let block_aocl = block
360-
.body()
361-
.mutator_set_accumulator_without_guesser_fees()
362+
.mutator_set_accumulator_after()
363+
.expect("only a mined block")
362364
.aocl;
363365
let block_aocl_numleafs = block_aocl.num_leafs();
364366

neptune-core/tests/send_and_receive_basic.rs

Lines changed: 110 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(clippy::unit_arg)]
2+
13
mod common;
24

35
use common::genesis_node::GenesisNode;
@@ -10,8 +12,12 @@ use neptune_cash::api::export::Timestamp;
1012
use neptune_cash::api::export::TransparentTransactionInfo;
1113
use neptune_cash::api::export::TxProvingCapability;
1214
use neptune_cash::api::tx_initiation::error::SendError;
15+
use neptune_cash::util_types::proof_of_transfer;
1316
use num_traits::ops::checked::CheckedSub;
1417
use num_traits::Zero;
18+
use tasm_lib::triton_vm::prelude::BFieldElement;
19+
use tasm_lib::twenty_first::prelude::Mmr;
20+
use tracing::debug;
1521

1622
/// test: alice sends funds to herself onchain
1723
///
@@ -75,40 +81,130 @@ pub async fn alice_sends_to_self() -> anyhow::Result<()> {
7581
/// see description of alice_sends_to_bob() for details
7682
#[tokio::test(flavor = "multi_thread")]
7783
pub async fn alice_sends_to_bob_with_primitive_witness_capability() -> anyhow::Result<()> {
78-
alice_sends_to_bob(
84+
let _ = alice_sends_to_bob(
7985
&GenesisNode::cluster_id(),
8086
TxProvingCapability::PrimitiveWitness,
8187
)
82-
.await
88+
.await?;
89+
90+
Ok(())
8391
}
8492

8593
/// test: alice sends funds to bob onchain with proof collection capability
8694
///
8795
/// see description of alice_sends_to_bob() for details
8896
#[tokio::test(flavor = "multi_thread")]
8997
pub async fn alice_sends_to_bob_with_proof_collection_capability() -> anyhow::Result<()> {
90-
alice_sends_to_bob(
98+
let _ = alice_sends_to_bob(
9199
&GenesisNode::cluster_id(),
92100
TxProvingCapability::PrimitiveWitness,
93101
)
94-
.await
102+
.await?;
103+
Ok(())
95104
}
96105

97106
/// test: alice sends funds to bob onchain with single proof capability
98107
///
99108
/// see description of alice_sends_to_bob() for details
100109
#[tokio::test(flavor = "multi_thread")]
101110
pub async fn alice_sends_to_bob_with_single_proof_capability() -> anyhow::Result<()> {
102-
alice_sends_to_bob(
111+
let _ = alice_sends_to_bob(
103112
&GenesisNode::cluster_id(),
104113
TxProvingCapability::PrimitiveWitness,
105114
)
106-
.await
115+
.await?;
116+
117+
Ok(())
107118
}
108119

109-
/// test: alice sends funds to bob onchain
120+
/// test: Bob verifies a proof Alice made for him over the transfer (proving is a part of this one)
121+
///
122+
/// (single proof capability)
110123
///
111-
/// this is a basic test of:
124+
/// see description of `alice_sends_to_bob()` for details
125+
#[tokio::test(flavor = "multi_thread")]
126+
pub async fn alice_sends_to_bob_tritonverify() -> anyhow::Result<()> {
127+
let ([alice, bob], bob_address) = alice_sends_to_bob(
128+
&GenesisNode::cluster_id(),
129+
TxProvingCapability::PrimitiveWitness,
130+
)
131+
.await?;
132+
133+
tracing::trace!["Alice proves the transfer"];
134+
let tip_the = alice.gsl.lock(|gs| gs.chain.tip().hash()).await;
135+
let (claim, proof) = proof_of_transfer::helper(alice.gsl.clone(), 0, 0, tip_the)
136+
.await
137+
.unwrap();
138+
139+
tracing::trace!["Bob verifies the claim"];
140+
141+
let bob_address = neptune_cash::state::wallet::address::generation_address::GenerationReceivingAddress::try_from(bob_address).unwrap();
142+
143+
assert_eq!(
144+
&claim.input[0..5],
145+
bob_address
146+
.receiver_postimage()
147+
.values()
148+
.into_iter()
149+
.rev()
150+
.collect::<Vec<BFieldElement>>()
151+
.as_slice(),
152+
"Bob checks it's sent to his address"
153+
);
154+
155+
tracing::debug!["{:?}| `&claim.input`", &claim.input];
156+
assert_eq!(
157+
&claim.output[0..5],
158+
bob_address.lock_script().hash().values(),
159+
"Bob checks he commands the sent coin"
160+
);
161+
162+
// it's expected that a good prover pass the block digest along the argument & claim: let's imagine here that piece of data was lost and we have only required minimum
163+
let aocl_digest = tasm_lib::prelude::Digest::try_from(&claim.output[10..15]).unwrap();
164+
match bob
165+
.gsl
166+
.lock_async(|gs| {
167+
futures::FutureExt::boxed(async move {
168+
let mut t = gs.chain.tip().clone();
169+
debug!(
170+
"{:?}| The height of the tip Bob starts traversing the chain from.",
171+
t.header().height
172+
);
173+
174+
while !t.header().height.is_genesis() {
175+
if aocl_digest == t.mutator_set_accumulator_after().unwrap().aocl.bag_peaks() {
176+
return Some(t.hash());
177+
}
178+
179+
t = gs
180+
.chain
181+
.archival_state()
182+
.get_block(t.header().prev_block_digest)
183+
.await
184+
.unwrap()
185+
.unwrap();
186+
}
187+
188+
None
189+
})
190+
})
191+
.await
192+
{
193+
Some(b) => {
194+
tracing::trace!("{b}| Bob has the block of this digest which have the claimed AOCL")
195+
}
196+
None => panic!["Bob has no canonical `Block` of the claimed AOCL"],
197+
}
198+
199+
Ok(assert!(
200+
tasm_lib::triton_vm::verify(Default::default(), &claim, &proof,),
201+
"Triton verification failed: the argument does not prove the claim"
202+
))
203+
}
204+
205+
/// helper: Alice sends funds to Bob onchain
206+
///
207+
/// this is a basic test of the following
112208
/// * peer connectivity
113209
/// * block generation
114210
/// * block propagation between nodes
@@ -126,7 +222,10 @@ pub async fn alice_sends_to_bob_with_single_proof_capability() -> anyhow::Result
126222
pub async fn alice_sends_to_bob(
127223
cluster_id: &str,
128224
proving_capability: TxProvingCapability,
129-
) -> anyhow::Result<()> {
225+
) -> anyhow::Result<(
226+
[GenesisNode; 2],
227+
neptune_cash::api::export::ReceivingAddress,
228+
)> {
130229
logging::tracing_logger();
131230
let timeout_secs = 5;
132231

@@ -183,7 +282,7 @@ pub async fn alice_sends_to_bob(
183282
.api_mut()
184283
.tx_sender_mut()
185284
.send(
186-
vec![(bob_address, payment_amount)],
285+
vec![(bob_address.clone(), payment_amount)],
187286
Default::default(),
188287
fee_amount,
189288
Timestamp::now(),
@@ -252,7 +351,7 @@ pub async fn alice_sends_to_bob(
252351
assert_eq!(bob_balances.confirmed_available, payment_amount);
253352
assert_eq!(bob_balances.unconfirmed_available, payment_amount);
254353

255-
Ok(())
354+
Ok(([alice, bob], bob_address))
256355
}
257356

258357
/// test: alice sends funds to random key.

0 commit comments

Comments
 (0)