Skip to content

Commit bdd0141

Browse files
Update SnapshotQuery to use new batch statepaths fetching method + upgrade to SnarkVM v4.2.0
With SnarkOS version 4.1.0 a new batch statepaths endpoint was added, this PR adds the SnapShot query to fetch directly from this endpoint due to the SnarkVM query's insufficient design. Further the upgrade to SnarkVM v4.2.0 requires addition of consensus versions as a method argument to verification routines and deployment cost calculations. To account for this, this PR adds automatic detection of ConsensusVersion and InclusionVersion based on block height detected from the Query.
1 parent 17fbbb9 commit bdd0141

File tree

15 files changed

+508
-341
lines changed

15 files changed

+508
-341
lines changed

wasm/Cargo.lock

Lines changed: 110 additions & 116 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wasm/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ features = ["async", "wasm"]
6666
[dependencies.snarkvm-wasm]
6767
git = "https://github.com/ProvableHQ/snarkVM"
6868
rev = "fb8349c4fdbab3862915f6f44517319e5b43d981"
69-
features = ["console", "fields", "utilities"]
69+
features = ["fields", "utilities"]
7070
[dependencies.anyhow]
7171
version = "1.0"
7272

wasm/src/lib.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,14 @@ mod thread_pool;
178178
mod utilities;
179179
#[cfg(test)]
180180
pub use utilities::test;
181-
pub use utilities::{EncryptionToolkit, get, get_network, latest_block_height};
181+
pub use utilities::{
182+
EncryptionToolkit,
183+
get,
184+
get_network,
185+
get_statepaths_for_commitments,
186+
latest_block_height,
187+
latest_stateroot,
188+
};
182189

183190
#[cfg(test)]
184191
mod thread_pool {

wasm/src/programs/macros.rs

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ macro_rules! execute_program {
178178

179179
#[macro_export]
180180
macro_rules! execute_fee {
181-
($process:expr, $private_key:expr, $fee_record:expr, $priority_fee_microcredits:expr, $submission_url:expr, $fee_proving_key:expr, $fee_verifying_key:expr, $deployment_or_execution_id:expr, $rng:expr, $offline_query:expr, $minimum_execution_cost:expr) => {{
181+
($process:expr, $private_key:expr, $fee_record:expr, $priority_fee_microcredits:expr, $node_url:expr, $fee_proving_key:expr, $fee_verifying_key:expr, $deployment_or_execution_id:expr, $rng:expr, $offline_query:expr, $minimum_execution_cost:expr) => {{
182+
use ::snarkvm_ledger_query::QueryTrait;
182183
if (($fee_proving_key.is_some() && $fee_verifying_key.is_none())
183184
|| ($fee_proving_key.is_none() && $fee_verifying_key.is_some()))
184185
{
@@ -188,29 +189,31 @@ macro_rules! execute_fee {
188189
);
189190
}
190191

192+
let function_name = if $fee_record.is_some() {
193+
IdentifierNative::from_str("fee_private").unwrap()
194+
} else {
195+
IdentifierNative::from_str("fee_public").unwrap()
196+
};
197+
191198
if let Some(fee_proving_key) = $fee_proving_key {
192199
let credits = ProgramIDNative::from_str("credits.aleo").unwrap();
193-
let fee = if $fee_record.is_some() {
194-
IdentifierNative::from_str("fee_private").unwrap()
195-
} else {
196-
IdentifierNative::from_str("fee_public").unwrap()
197-
};
198-
if Self::contains_key($process, &credits, &fee) {
200+
201+
if Self::contains_key($process, &credits, &function_name) {
199202
log("Fee proving & verifying keys were specified but a key already exists in the cache. Using cached keys");
200203
} else {
201204
log("Inserting externally provided fee proving and verifying keys");
202205
$process
203-
.insert_proving_key(&credits, &fee, ProvingKeyNative::from(fee_proving_key)).map_err(|e| e.to_string())?;
206+
.insert_proving_key(&credits, &function_name, ProvingKeyNative::from(fee_proving_key)).map_err(|e| e.to_string())?;
204207
if let Some(fee_verifying_key) = $fee_verifying_key {
205208
$process
206-
.insert_verifying_key(&credits, &fee, VerifyingKeyNative::from(fee_verifying_key))
209+
.insert_verifying_key(&credits, &function_name, VerifyingKeyNative::from(fee_verifying_key))
207210
.map_err(|e| e.to_string())?;
208211
}
209212
}
210213
};
211214

212215
log("Authorizing Fee");
213-
let fee_authorization = match $fee_record {
216+
let fee_authorization = match $fee_record.clone() {
214217
Some(fee_record) => {
215218
let fee_record_native = RecordPlaintextNative::from_str(&fee_record.to_string()).unwrap();
216219
$process.authorize_fee_private::<CurrentAleo, _>(
@@ -239,16 +242,52 @@ macro_rules! execute_fee {
239242
.map_err(|e| e.to_string())?;
240243

241244
log("Preparing inclusion proofs for fee execution");
242-
if let Some(offline_query) = $offline_query.as_ref() {
245+
let latest_height = if let Some(offline_query) = $offline_query.as_ref() {
243246
trace.prepare_async(offline_query).await.map_err(|err| err.to_string())?;
247+
offline_query.current_block_height().map_err(|e| e.to_string())?
244248
} else {
245-
let query = QueryNative::from($submission_url);
249+
let credits = ProgramNative::credits().unwrap();
250+
let function_name = IdentifierNative::from_str("split").unwrap();
251+
let view_key = ViewKeyNative::try_from(PrivateKeyNative::from($private_key)).map_err(|err| err.to_string())?;
252+
let inputs = if let Some(fee_record) = $fee_record {
253+
vec![
254+
::wasm_bindgen::JsValue::from_str(&fee_record.to_string()),
255+
::wasm_bindgen::JsValue::from_str(&format!("{}u64", $minimum_execution_cost)),
256+
::wasm_bindgen::JsValue::from_str(&format!("{}u64", $minimum_execution_cost)),
257+
::wasm_bindgen::JsValue::from_str(&format!("{}", $deployment_or_execution_id))
258+
]
259+
} else {
260+
vec![
261+
::wasm_bindgen::JsValue::from_str(&format!("{}u64", $minimum_execution_cost)),
262+
::wasm_bindgen::JsValue::from_str(&format!("{}u64", $minimum_execution_cost)),
263+
::wasm_bindgen::JsValue::from_str(&format!("{}", $deployment_or_execution_id))
264+
]
265+
};
266+
let query = SnapshotQuery::try_from_inputs(
267+
$node_url,
268+
&credits,
269+
&function_name,
270+
&view_key,
271+
&inputs,
272+
)
273+
.await
274+
.map_err(|err| err.to_string())?;
246275
trace.prepare_async(&query).await.map_err(|err| err.to_string())?;
276+
query.current_block_height().map_err(|e| e.to_string())?
247277
};
278+
let consensus_version = <CurrentNetwork as Network>::CONSENSUS_VERSION(latest_height).map_err(|err| err.to_string())?;
279+
let inclusion_upgrade_height = <CurrentNetwork as Network>::INCLUSION_UPGRADE_HEIGHT().map_err(|err| err.to_string())?;
280+
let inclusion_version = if latest_height >= inclusion_upgrade_height {
281+
::snarkvm_synthesizer::prelude::InclusionVersion::V1
282+
} else {
283+
::snarkvm_synthesizer::prelude::InclusionVersion::V0
284+
};
285+
286+
log("Proving fee execution");
248287
let fee = trace.prove_fee::<CurrentAleo, _>(::snarkvm_algorithms::snark::varuna::VarunaVersion::V2, &mut StdRng::from_entropy()).map_err(|e|e.to_string())?;
249288

250289
log("Verifying fee execution");
251-
$process.verify_fee(::snarkvm_console::prelude::ConsensusVersion::V8, ::snarkvm_algorithms::snark::varuna::VarunaVersion::V2, ::snarkvm_synthesizer::prelude::InclusionVersion::V1, &fee, $deployment_or_execution_id).map_err(|e| e.to_string())?;
290+
$process.verify_fee(consensus_version, ::snarkvm_algorithms::snark::varuna::VarunaVersion::V2, inclusion_version, &fee, $deployment_or_execution_id).map_err(|e| e.to_string())?;
252291

253292
fee
254293
}}
@@ -261,8 +300,7 @@ macro_rules! calculate_minimum_fee {
261300
let block_height = offline_query.current_block_height().map_err(|e| e.to_string())?;
262301
block_height
263302
} else {
264-
let query = QueryNative::from($node_url);
265-
let block_height = query.current_block_height_async().await.map_err(|e| e.to_string())?;
303+
let block_height = latest_block_height($node_url).await.map_err(|e| e.to_string())?;
266304
block_height
267305
};
268306
let (minimum_execution_cost, (_, _)) =

wasm/src/programs/manager/deploy.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::{
2020
OfflineQuery,
2121
PrivateKey,
2222
RecordPlaintext,
23+
SnapshotQuery,
2324
Transaction,
2425
execute_fee,
2526
latest_block_height,
@@ -30,11 +31,11 @@ use crate::{
3031
CurrentNetwork,
3132
PrivateKeyNative,
3233
ProcessNative,
33-
ProgramIDNative,
3434
ProgramNative,
3535
ProgramOwnerNative,
3636
RecordPlaintextNative,
3737
TransactionNative,
38+
ViewKeyNative,
3839
},
3940
};
4041
use snarkvm_console::prelude::{ConsensusVersion, Network};
@@ -94,7 +95,7 @@ impl ProgramManager {
9495
}
9596

9697
log("Setting program checksum and owner");
97-
let latest_height = latest_block_height(node_url).await?;
98+
let latest_height = latest_block_height(node_url).await.map_err(|err| err.to_string())?;
9899
let consensus_version = CurrentNetwork::CONSENSUS_VERSION(latest_height).map_err(|err| err.to_string())?;
99100
let private_key_native = PrivateKeyNative::from(private_key);
100101
if consensus_version < ConsensusVersion::V9 {
@@ -107,8 +108,12 @@ impl ProgramManager {
107108
}
108109

109110
log("Ensuring the fee is sufficient to pay for the deployment");
111+
let block_height = latest_block_height(node_url).await.map_err(|err| err.to_string())?;
112+
let consensus_version =
113+
<CurrentNetwork as Network>::CONSENSUS_VERSION(block_height).map_err(|err| err.to_string())?;
110114
let (minimum_deployment_cost, (_, _, _, _)) =
111-
deployment_cost::<CurrentNetwork>(process, &deployment).map_err(|err| err.to_string())?;
115+
deployment_cost::<CurrentNetwork>(process, &deployment, consensus_version)
116+
.map_err(|err| err.to_string())?;
112117

113118
// Check to see if the fee record has enough microcredits to pay for the deployment.
114119
let priority_fee_microcredits = (priority_fee_credits * 1_000_000.0) as u64;
@@ -169,9 +174,15 @@ impl ProgramManager {
169174
return Err("Attempted to create an empty transaction deployment".to_string());
170175
}
171176

177+
log("Get the latest block height and determine the consensus version");
178+
let latest_height = latest_block_height(DEFAULT_URL).await.map_err(|err| err.to_string())?;
179+
let consensus_version =
180+
<CurrentNetwork as Network>::CONSENSUS_VERSION(latest_height).map_err(|err| err.to_string())?;
181+
172182
log("Estimate the deployment fee");
173183
let (minimum_deployment_cost, (_, _, _, _)) =
174-
deployment_cost::<CurrentNetwork>(process, &deployment).map_err(|err| err.to_string())?;
184+
deployment_cost::<CurrentNetwork>(process, &deployment, consensus_version)
185+
.map_err(|err| err.to_string())?;
175186

176187
Ok(minimum_deployment_cost)
177188
}

wasm/src/programs/manager/execute.rs

Lines changed: 45 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ use crate::{
2121
OfflineQuery,
2222
PrivateKey,
2323
RecordPlaintext,
24+
SnapshotQuery,
2425
Transaction,
2526
calculate_minimum_fee,
2627
execute_fee,
2728
execute_program,
29+
latest_block_height,
2830
log,
2931
process_inputs,
3032
types::native::{
@@ -42,6 +44,7 @@ use snarkvm_console::network::{ConsensusVersion, Network};
4244
use snarkvm_ledger_query::QueryTrait;
4345
use snarkvm_synthesizer::prelude::{InclusionVersion, cost_in_microcredits_v1, execution_cost_v1, execution_cost_v2};
4446

47+
use crate::types::native::{PrivateKeyNative, ViewKeyNative};
4548
use core::ops::Add;
4649
use js_sys::{Array, Object};
4750
use rand::{SeedableRng, rngs::StdRng};
@@ -113,10 +116,20 @@ impl ProgramManager {
113116
if let Some(offline_query) = offline_query {
114117
trace.prepare_async(&offline_query).await.map_err(|err| err.to_string())?;
115118
} else {
116-
let query = QueryNative::from(node_url);
117-
// todo change this to new query struct and to try_from rather than from
119+
let function_name = IdentifierNative::from_str(function).map_err(|err| err.to_string())?;
120+
let view_key =
121+
ViewKeyNative::try_from(PrivateKeyNative::from(private_key)).map_err(|err| err.to_string())?;
122+
let query = SnapshotQuery::try_from_inputs(
123+
node_url,
124+
&program_native,
125+
&function_name,
126+
&view_key,
127+
&inputs.to_vec(),
128+
)
129+
.await
130+
.map_err(|err| err.to_string())?;
118131
trace.prepare_async(&query).await.map_err(|err| err.to_string())?;
119-
}
132+
};
120133

121134
log("Proving execution");
122135
let locator = program_native.id().to_string().add("/").add(function);
@@ -200,12 +213,20 @@ impl ProgramManager {
200213
);
201214

202215
log("Preparing inclusion proofs for execution");
203-
if let Some(offline_query) = offline_query.as_ref() {
216+
let latest_height = if let Some(offline_query) = offline_query.as_ref() {
204217
trace.prepare_async(offline_query).await.map_err(|err| err.to_string())?;
218+
offline_query.current_block_height().map_err(|e| e.to_string())?
205219
} else {
206-
let query = QueryNative::from(node_url);
220+
let function_name = IdentifierNative::from_str(function).map_err(|err| err.to_string())?;
221+
let view_key =
222+
ViewKeyNative::try_from(PrivateKeyNative::from(private_key)).map_err(|err| err.to_string())?;
223+
let query =
224+
SnapshotQuery::try_from_inputs(node_url, &program_native, &function_name, &view_key, &inputs.to_vec())
225+
.await
226+
.map_err(|err| err.to_string())?;
207227
trace.prepare_async(&query).await.map_err(|err| err.to_string())?;
208-
}
228+
query.current_block_height().map_err(|e| e.to_string())?
229+
};
209230

210231
log("Proving execution");
211232
let locator = program_native.id().to_string().add("/").add(function);
@@ -249,8 +270,14 @@ impl ProgramManager {
249270
};
250271

251272
// Verify the execution
273+
let consensus_version =
274+
<CurrentNetwork as Network>::CONSENSUS_VERSION(latest_height).map_err(|err| err.to_string())?;
275+
let inclusion_upgrade_height =
276+
<CurrentNetwork as Network>::INCLUSION_UPGRADE_HEIGHT().map_err(|err| err.to_string())?;
277+
let inclusion_version =
278+
if latest_height >= inclusion_upgrade_height { InclusionVersion::V1 } else { InclusionVersion::V0 };
252279
process
253-
.verify_execution(ConsensusVersion::V8, VarunaVersion::V2, InclusionVersion::V1, &execution)
280+
.verify_execution(consensus_version, VarunaVersion::V2, inclusion_version, &execution)
254281
.map_err(|err| err.to_string())?;
255282

256283
log("Creating execution transaction");
@@ -321,15 +348,19 @@ impl ProgramManager {
321348
let program = ProgramNative::from_str(program).map_err(|err| err.to_string())?;
322349
let locator = program.id().to_string().add("/").add(function);
323350

324-
let block_height = if let Some(offline_query) = offline_query {
325-
let block_height = offline_query.current_block_height().map_err(|e| e.to_string())?;
326-
trace.prepare_async(&offline_query).await.map_err(|err| err.to_string())?;
327-
block_height
351+
let block_height = if let Some(offline_query) = offline_query.as_ref() {
352+
trace.prepare_async(offline_query).await.map_err(|err| err.to_string())?;
353+
offline_query.current_block_height().map_err(|e| e.to_string())?
328354
} else {
329-
let query = QueryNative::from(node_url);
330-
let block_height = query.current_block_height_async().await.map_err(|e| e.to_string())?;
355+
let function_name = IdentifierNative::from_str(function).map_err(|err| err.to_string())?;
356+
let view_key =
357+
ViewKeyNative::try_from(PrivateKeyNative::from(private_key)).map_err(|err| err.to_string())?;
358+
let query =
359+
SnapshotQuery::try_from_inputs(node_url, &program_native, &function_name, &view_key, &inputs.to_vec())
360+
.await
361+
.map_err(|err| err.to_string())?;
331362
trace.prepare_async(&query).await.map_err(|err| err.to_string())?;
332-
block_height
363+
query.current_block_height().map_err(|e| e.to_string())?
333364
};
334365
let execution =
335366
trace.prove_execution::<CurrentAleo, _>(&locator, VarunaVersion::V2, rng).map_err(|e| e.to_string())?;
@@ -388,46 +419,3 @@ impl ProgramManager {
388419
cost_in_microcredits_v2(&stack, &function_id).map_err(|e| e.to_string())
389420
}
390421
}
391-
392-
#[cfg(test)]
393-
mod tests {
394-
use super::*;
395-
use crate::{
396-
Metadata,
397-
array,
398-
utilities::test::{HELLO_PROGRAM, PROVABLE_API},
399-
};
400-
401-
async fn test_execute_added_program() {
402-
// Generate the private key.
403-
let private_key = PrivateKey::new();
404-
405-
// Download the fee prover.
406-
let fee_prover_uri = Metadata::fee_public().prover;
407-
let fee_proving_key_bytes = reqwest::get(fee_prover_uri).await.unwrap().bytes().await.unwrap().to_vec();
408-
let fee_prover = ProvingKey::from_bytes(&fee_proving_key_bytes).unwrap();
409-
let fee_verifier = VerifyingKey::fee_public_verifier();
410-
411-
// Create the execution.
412-
let transaction = ProgramManager::execute(
413-
&private_key,
414-
HELLO_PROGRAM,
415-
"main",
416-
array!["5u32", "5u32"],
417-
0.0,
418-
None,
419-
Some(PROVABLE_API.to_string()),
420-
None,
421-
None,
422-
None,
423-
Some(fee_prover),
424-
Some(fee_verifier),
425-
None,
426-
None,
427-
)
428-
.await
429-
.unwrap();
430-
431-
assert!(transaction.is_execute());
432-
}
433-
}

0 commit comments

Comments
 (0)