From c4ea63f661cc301233d44d85daaca1e6feefae1e Mon Sep 17 00:00:00 2001 From: Chris Czub Date: Wed, 14 Aug 2024 21:59:26 -0400 Subject: [PATCH] Add `new_with_penumbra_prefixes` to the `TempStorageExt` --- .../app_can_define_and_delegate_to_a_validator.rs | 3 ++- .../app/tests/app_can_deposit_into_community_pool.rs | 3 ++- .../tests/app_can_disable_community_pool_spends.rs | 3 ++- .../tests/app_can_propose_community_pool_spends.rs | 3 ++- .../tests/app_can_spend_notes_and_detect_outputs.rs | 3 ++- .../app_can_sweep_a_collection_of_small_notes.rs | 3 ++- .../app/tests/app_can_undelegate_from_a_validator.rs | 3 ++- crates/core/app/tests/app_check_dex_vcb.rs | 5 ++++- ...s_validator_definitions_with_invalid_auth_sigs.rs | 3 ++- .../app/tests/app_reproduce_testnet_75_vcb_close.rs | 5 +++-- ...ks_uptime_for_genesis_validator_missing_blocks.rs | 5 +++-- ...ks_uptime_for_genesis_validator_signing_blocks.rs | 3 ++- ..._tracks_uptime_for_validators_only_once_active.rs | 3 ++- crates/core/app/tests/common/temp_storage_ext.rs | 7 ++++++- .../mock_consensus_can_define_a_genesis_validator.rs | 3 ++- ..._consensus_can_send_a_sequence_of_empty_blocks.rs | 3 ++- crates/core/app/tests/spend.rs | 11 +++++++---- crates/core/app/tests/swap_and_swap_claim.rs | 12 +++++++++--- .../tests/view_server_can_be_served_on_localhost.rs | 3 ++- 19 files changed, 58 insertions(+), 26 deletions(-) diff --git a/crates/core/app/tests/app_can_define_and_delegate_to_a_validator.rs b/crates/core/app/tests/app_can_define_and_delegate_to_a_validator.rs index fe1cf55adc..0027ee1408 100644 --- a/crates/core/app/tests/app_can_define_and_delegate_to_a_validator.rs +++ b/crates/core/app/tests/app_can_define_and_delegate_to_a_validator.rs @@ -2,6 +2,7 @@ use { self::common::{BuilderExt, TestNodeExt, ValidatorDataReadExt}, anyhow::anyhow, cnidarium::TempStorage, + common::TempStorageExt as _, decaf377_rdsa::{SigningKey, SpendAuth, VerificationKey}, penumbra_app::{ genesis::{self, AppState}, @@ -32,7 +33,7 @@ const EPOCH_DURATION: u64 = 8; async fn app_can_define_and_delegate_to_a_validator() -> anyhow::Result<()> { // Install a test logger, acquire some temporary storage, and start the test node. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; // Configure an AppState with slightly shorter epochs than usual. let app_state = AppState::Content( diff --git a/crates/core/app/tests/app_can_deposit_into_community_pool.rs b/crates/core/app/tests/app_can_deposit_into_community_pool.rs index c2b69a7d04..895e61014e 100644 --- a/crates/core/app/tests/app_can_deposit_into_community_pool.rs +++ b/crates/core/app/tests/app_can_deposit_into_community_pool.rs @@ -2,6 +2,7 @@ use { self::common::BuilderExt, anyhow::anyhow, cnidarium::TempStorage, + common::TempStorageExt as _, penumbra_app::{ genesis::{self, AppState}, server::consensus::Consensus, @@ -28,7 +29,7 @@ mod common; async fn app_can_deposit_into_community_pool() -> anyhow::Result<()> { // Install a test logger, and acquire some temporary storage. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; // Define our application state, and start the test node. let mut test_node = { diff --git a/crates/core/app/tests/app_can_disable_community_pool_spends.rs b/crates/core/app/tests/app_can_disable_community_pool_spends.rs index 4cfb3c6b3a..0854e3633f 100644 --- a/crates/core/app/tests/app_can_disable_community_pool_spends.rs +++ b/crates/core/app/tests/app_can_disable_community_pool_spends.rs @@ -2,6 +2,7 @@ use { self::common::ValidatorDataReadExt, anyhow::anyhow, cnidarium::TempStorage, + common::TempStorageExt as _, decaf377_rdsa::VerificationKey, penumbra_app::{ genesis::{AppState, Content}, @@ -49,7 +50,7 @@ const PROPOSAL_VOTING_BLOCKS: u64 = 3; async fn app_can_disable_community_pool_spends() -> anyhow::Result<()> { // Install a test logger, and acquire some temporary storage. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; // Define a helper to get the current community pool balance. let pool_balance = || async { storage.latest_snapshot().community_pool_balance().await }; diff --git a/crates/core/app/tests/app_can_propose_community_pool_spends.rs b/crates/core/app/tests/app_can_propose_community_pool_spends.rs index 2b7d31be0f..d8af8d1b07 100644 --- a/crates/core/app/tests/app_can_propose_community_pool_spends.rs +++ b/crates/core/app/tests/app_can_propose_community_pool_spends.rs @@ -2,6 +2,7 @@ use { self::common::ValidatorDataReadExt, anyhow::anyhow, cnidarium::TempStorage, + common::TempStorageExt as _, decaf377_rdsa::VerificationKey, penumbra_app::{ genesis::{AppState, Content}, @@ -49,7 +50,7 @@ const PROPOSAL_VOTING_BLOCKS: u64 = 3; async fn app_can_propose_community_pool_spends() -> anyhow::Result<()> { // Install a test logger, and acquire some temporary storage. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; // Define a helper to get the current community pool balance. let pool_balance = || async { storage.latest_snapshot().community_pool_balance().await }; diff --git a/crates/core/app/tests/app_can_spend_notes_and_detect_outputs.rs b/crates/core/app/tests/app_can_spend_notes_and_detect_outputs.rs index 21b40406ba..49d7b93018 100644 --- a/crates/core/app/tests/app_can_spend_notes_and_detect_outputs.rs +++ b/crates/core/app/tests/app_can_spend_notes_and_detect_outputs.rs @@ -2,6 +2,7 @@ use { self::common::BuilderExt, anyhow::anyhow, cnidarium::TempStorage, + common::TempStorageExt as _, penumbra_app::{ genesis::{self, AppState}, server::consensus::Consensus, @@ -27,7 +28,7 @@ mod common; async fn app_can_spend_notes_and_detect_outputs() -> anyhow::Result<()> { // Install a test logger, acquire some temporary storage, and start the test node. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; let mut test_node = { let app_state = AppState::Content( genesis::Content::default().with_chain_id(TestNode::<()>::CHAIN_ID.to_string()), diff --git a/crates/core/app/tests/app_can_sweep_a_collection_of_small_notes.rs b/crates/core/app/tests/app_can_sweep_a_collection_of_small_notes.rs index c182a4cca5..dfe096bdde 100644 --- a/crates/core/app/tests/app_can_sweep_a_collection_of_small_notes.rs +++ b/crates/core/app/tests/app_can_sweep_a_collection_of_small_notes.rs @@ -1,6 +1,7 @@ use { anyhow::Context, cnidarium::TempStorage, + common::TempStorageExt as _, penumbra_app::{ genesis::{AppState, Content}, server::consensus::Consensus, @@ -37,7 +38,7 @@ const COUNT: usize = SWEEP_COUNT + 1; async fn app_can_sweep_a_collection_of_small_notes() -> anyhow::Result<()> { // Install a test logger, and acquire some temporary storage. let guard = common::set_tracing_subscriber_with_env_filter("info".into()); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; // Instantiate a mock tendermint proxy, which we will connect to the test node. let proxy = penumbra_mock_tendermint_proxy::TestNodeProxy::new::(); diff --git a/crates/core/app/tests/app_can_undelegate_from_a_validator.rs b/crates/core/app/tests/app_can_undelegate_from_a_validator.rs index d927fd823f..82ec8b14b6 100644 --- a/crates/core/app/tests/app_can_undelegate_from_a_validator.rs +++ b/crates/core/app/tests/app_can_undelegate_from_a_validator.rs @@ -2,6 +2,7 @@ use { self::common::{BuilderExt, TestNodeExt, ValidatorDataReadExt}, anyhow::anyhow, cnidarium::TempStorage, + common::TempStorageExt as _, decaf377_fmd::Precision, penumbra_app::{ genesis::{self, AppState}, @@ -37,7 +38,7 @@ const UNBONDING_DELAY: u64 = 4; async fn app_can_undelegate_from_a_validator() -> anyhow::Result<()> { // Install a test logger, acquire some temporary storage, and start the test node. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; // Helper function to get the latest block height. let get_latest_height = || async { diff --git a/crates/core/app/tests/app_check_dex_vcb.rs b/crates/core/app/tests/app_check_dex_vcb.rs index 266e15f4a7..85d6a87f5a 100644 --- a/crates/core/app/tests/app_check_dex_vcb.rs +++ b/crates/core/app/tests/app_check_dex_vcb.rs @@ -25,7 +25,10 @@ use std::{ops::Deref, sync::Arc}; /// This bug was fixed in #4643. async fn dex_vcb_tracks_multiswap() -> anyhow::Result<()> { let mut rng = rand_chacha::ChaChaRng::seed_from_u64(1776); - let storage = TempStorage::new().await?.apply_default_genesis().await?; + let storage = TempStorage::new_with_penumbra_prefixes() + .await? + .apply_default_genesis() + .await?; let mut state = Arc::new(StateDelta::new(storage.latest_snapshot())); // Create the first swap: diff --git a/crates/core/app/tests/app_rejects_validator_definitions_with_invalid_auth_sigs.rs b/crates/core/app/tests/app_rejects_validator_definitions_with_invalid_auth_sigs.rs index 8242d817fa..5bc71e50ed 100644 --- a/crates/core/app/tests/app_rejects_validator_definitions_with_invalid_auth_sigs.rs +++ b/crates/core/app/tests/app_rejects_validator_definitions_with_invalid_auth_sigs.rs @@ -1,6 +1,7 @@ use { self::common::{BuilderExt, ValidatorDataReadExt}, cnidarium::TempStorage, + common::TempStorageExt as _, decaf377_rdsa::{SigningKey, SpendAuth, VerificationKey}, penumbra_app::{ genesis::{self, AppState}, @@ -23,7 +24,7 @@ mod common; async fn app_rejects_validator_definitions_with_invalid_auth_sigs() -> anyhow::Result<()> { // Install a test logger, and acquire some temporary storage. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; // Start the test node. let mut node = { diff --git a/crates/core/app/tests/app_reproduce_testnet_75_vcb_close.rs b/crates/core/app/tests/app_reproduce_testnet_75_vcb_close.rs index 17c3316a74..fcf7a4e21e 100644 --- a/crates/core/app/tests/app_reproduce_testnet_75_vcb_close.rs +++ b/crates/core/app/tests/app_reproduce_testnet_75_vcb_close.rs @@ -2,18 +2,19 @@ use { self::common::BuilderExt, anyhow::anyhow, cnidarium::TempStorage, + common::TempStorageExt as _, penumbra_app::{ genesis::{self, AppState}, server::consensus::Consensus, }, penumbra_asset::{Value, STAKING_TOKEN_ASSET_ID}, - penumbra_auction::StateReadExt as _, penumbra_auction::{ auction::{ dutch::{ActionDutchAuctionEnd, ActionDutchAuctionSchedule, DutchAuctionDescription}, AuctionNft, }, component::AuctionStoreRead, + StateReadExt as _, }, penumbra_keys::test_keys, penumbra_mock_client::MockClient, @@ -65,7 +66,7 @@ async fn app_can_reproduce_tesnet_75_vcb_close() -> anyhow::Result<()> { common::set_tracing_subscriber_with_env_filter(filter) }; - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; let app_state = AppState::Content( genesis::Content::default().with_chain_id(TestNode::<()>::CHAIN_ID.to_string()), ); diff --git a/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_missing_blocks.rs b/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_missing_blocks.rs index 6d55488163..b242c9c8eb 100644 --- a/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_missing_blocks.rs +++ b/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_missing_blocks.rs @@ -2,6 +2,7 @@ use { self::common::{BuilderExt, ValidatorDataReadExt}, anyhow::Context, cnidarium::TempStorage, + common::TempStorageExt as _, penumbra_app::{ genesis::{self, AppState}, server::consensus::Consensus, @@ -18,7 +19,7 @@ mod common; async fn app_tracks_uptime_for_genesis_validator_missing_blocks() -> anyhow::Result<()> { // Install a test logger, acquire some temporary storage, and start the test node. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; // Start the test node. let mut node = { @@ -60,7 +61,7 @@ async fn app_tracks_uptime_for_genesis_validator_missing_blocks() -> anyhow::Res let height = 4; for i in 1..=height { node.block() - .with_signatures(Default::default()) + .with_signatures(vec![]) .execute() .tap(|_| trace!(%i, "executing block with no signatures")) .instrument(error_span!("executing block with no signatures", %i)) diff --git a/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_signing_blocks.rs b/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_signing_blocks.rs index 9685a37395..309afa4256 100644 --- a/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_signing_blocks.rs +++ b/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_signing_blocks.rs @@ -2,6 +2,7 @@ use { self::common::{BuilderExt, ValidatorDataReadExt}, anyhow::Context, cnidarium::TempStorage, + common::TempStorageExt as _, penumbra_app::{ genesis::{self, AppState}, server::consensus::Consensus, @@ -18,7 +19,7 @@ mod common; async fn app_tracks_uptime_for_genesis_validator_missing_blocks() -> anyhow::Result<()> { // Install a test logger, acquire some temporary storage, and start the test node. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; // Start the test node. let mut node = { diff --git a/crates/core/app/tests/app_tracks_uptime_for_validators_only_once_active.rs b/crates/core/app/tests/app_tracks_uptime_for_validators_only_once_active.rs index 19674ae33e..de687b1356 100644 --- a/crates/core/app/tests/app_tracks_uptime_for_validators_only_once_active.rs +++ b/crates/core/app/tests/app_tracks_uptime_for_validators_only_once_active.rs @@ -1,6 +1,7 @@ use { self::common::{BuilderExt, TestNodeExt, ValidatorDataReadExt}, cnidarium::TempStorage, + common::TempStorageExt as _, decaf377_rdsa::{SigningKey, SpendAuth, VerificationKey}, penumbra_app::{ genesis::{self, AppState}, @@ -32,7 +33,7 @@ async fn app_tracks_uptime_for_validators_only_once_active() -> anyhow::Result<( // Install a test logger, acquire some temporary storage, and start the test node. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; // Configure an AppState with slightly shorter epochs than usual. let app_state = AppState::Content( diff --git a/crates/core/app/tests/common/temp_storage_ext.rs b/crates/core/app/tests/common/temp_storage_ext.rs index 8ef1233b9d..efff367ca8 100644 --- a/crates/core/app/tests/common/temp_storage_ext.rs +++ b/crates/core/app/tests/common/temp_storage_ext.rs @@ -1,7 +1,7 @@ use { async_trait::async_trait, cnidarium::TempStorage, - penumbra_app::{app::App, genesis::AppState}, + penumbra_app::{app::App, genesis::AppState, SUBSTORE_PREFIXES}, std::ops::Deref, }; @@ -9,10 +9,15 @@ use { pub trait TempStorageExt: Sized { async fn apply_genesis(self, genesis: AppState) -> anyhow::Result; async fn apply_default_genesis(self) -> anyhow::Result; + async fn new_with_penumbra_prefixes() -> anyhow::Result; } #[async_trait] impl TempStorageExt for TempStorage { + async fn new_with_penumbra_prefixes() -> anyhow::Result { + TempStorage::new_with_prefixes(SUBSTORE_PREFIXES.to_vec()).await + } + async fn apply_genesis(self, genesis: AppState) -> anyhow::Result { // Check that we haven't already applied a genesis state: if self.latest_version() != u64::MAX { diff --git a/crates/core/app/tests/mock_consensus_can_define_a_genesis_validator.rs b/crates/core/app/tests/mock_consensus_can_define_a_genesis_validator.rs index da66bd8575..a0077ae8f8 100644 --- a/crates/core/app/tests/mock_consensus_can_define_a_genesis_validator.rs +++ b/crates/core/app/tests/mock_consensus_can_define_a_genesis_validator.rs @@ -2,6 +2,7 @@ use { self::common::{BuilderExt, ValidatorDataReadExt}, anyhow::anyhow, cnidarium::TempStorage, + common::TempStorageExt as _, penumbra_app::{ genesis::{self, AppState}, server::consensus::Consensus, @@ -19,7 +20,7 @@ mod common; async fn mock_consensus_can_define_a_genesis_validator() -> anyhow::Result<()> { // Install a test logger, acquire some temporary storage, and start the test node. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; let test_node = { let app_state = AppState::Content( genesis::Content::default().with_chain_id(TestNode::<()>::CHAIN_ID.to_string()), diff --git a/crates/core/app/tests/mock_consensus_can_send_a_sequence_of_empty_blocks.rs b/crates/core/app/tests/mock_consensus_can_send_a_sequence_of_empty_blocks.rs index cf66c15fdc..b0461b3d69 100644 --- a/crates/core/app/tests/mock_consensus_can_send_a_sequence_of_empty_blocks.rs +++ b/crates/core/app/tests/mock_consensus_can_send_a_sequence_of_empty_blocks.rs @@ -1,6 +1,7 @@ use { self::common::BuilderExt, cnidarium::TempStorage, + common::TempStorageExt as _, penumbra_app::{ genesis::{self, AppState}, server::consensus::Consensus, @@ -18,7 +19,7 @@ mod common; async fn mock_consensus_can_send_a_sequence_of_empty_blocks() -> anyhow::Result<()> { // Install a test logger, acquire some temporary storage, and start the test node. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; let mut test_node = { let app_state = AppState::Content( genesis::Content::default().with_chain_id(TestNode::<()>::CHAIN_ID.to_string()), diff --git a/crates/core/app/tests/spend.rs b/crates/core/app/tests/spend.rs index 703c41097c..94c9f63caf 100644 --- a/crates/core/app/tests/spend.rs +++ b/crates/core/app/tests/spend.rs @@ -26,7 +26,10 @@ use tendermint::abci; async fn spend_happy_path() -> anyhow::Result<()> { let mut rng = rand_chacha::ChaChaRng::seed_from_u64(1312); - let storage = TempStorage::new().await?.apply_default_genesis().await?; + let storage = TempStorage::new_with_penumbra_prefixes() + .await? + .apply_default_genesis() + .await?; let mut state = Arc::new(StateDelta::new(storage.latest_snapshot())); let height = 1; @@ -102,7 +105,7 @@ async fn spend_happy_path() -> anyhow::Result<()> { async fn invalid_dummy_spend() { let mut rng = rand_chacha::ChaChaRng::seed_from_u64(1312); - let storage = TempStorage::new() + let storage = TempStorage::new_with_penumbra_prefixes() .await .unwrap() .apply_default_genesis() @@ -203,7 +206,7 @@ async fn invalid_dummy_spend() { async fn spend_duplicate_nullifier_previous_transaction() { let mut rng = rand_chacha::ChaChaRng::seed_from_u64(1312); - let storage = TempStorage::new() + let storage = TempStorage::new_with_penumbra_prefixes() .await .expect("can start new temp storage") .apply_default_genesis() @@ -294,7 +297,7 @@ async fn spend_duplicate_nullifier_previous_transaction() { async fn spend_duplicate_nullifier_same_transaction() { let mut rng = rand_chacha::ChaChaRng::seed_from_u64(1312); - let storage = TempStorage::new() + let storage = TempStorage::new_with_penumbra_prefixes() .await .expect("can start new temp storage") .apply_default_genesis() diff --git a/crates/core/app/tests/swap_and_swap_claim.rs b/crates/core/app/tests/swap_and_swap_claim.rs index 717f51bc4e..6cf1d8de45 100644 --- a/crates/core/app/tests/swap_and_swap_claim.rs +++ b/crates/core/app/tests/swap_and_swap_claim.rs @@ -30,7 +30,10 @@ use tendermint::abci; async fn swap_and_swap_claim() -> anyhow::Result<()> { let mut rng = rand_chacha::ChaChaRng::seed_from_u64(1312); - let storage = TempStorage::new().await?.apply_default_genesis().await?; + let storage = TempStorage::new_with_penumbra_prefixes() + .await? + .apply_default_genesis() + .await?; let mut state = Arc::new(StateDelta::new(storage.latest_snapshot())); let height = 1; @@ -141,7 +144,7 @@ async fn swap_and_swap_claim() -> anyhow::Result<()> { async fn swap_claim_duplicate_nullifier_previous_transaction() { let mut rng = rand_chacha::ChaChaRng::seed_from_u64(1312); - let storage = TempStorage::new() + let storage = TempStorage::new_with_penumbra_prefixes() .await .unwrap() .apply_default_genesis() @@ -267,7 +270,10 @@ async fn swap_claim_duplicate_nullifier_previous_transaction() { async fn swap_with_nonzero_fee() -> anyhow::Result<()> { let mut rng = rand_chacha::ChaChaRng::seed_from_u64(1312); - let storage = TempStorage::new().await?.apply_default_genesis().await?; + let storage = TempStorage::new_with_penumbra_prefixes() + .await? + .apply_default_genesis() + .await?; let mut state = Arc::new(StateDelta::new(storage.latest_snapshot())); let height = 1; diff --git a/crates/core/app/tests/view_server_can_be_served_on_localhost.rs b/crates/core/app/tests/view_server_can_be_served_on_localhost.rs index 1ba83aabc7..6ef2571ac3 100644 --- a/crates/core/app/tests/view_server_can_be_served_on_localhost.rs +++ b/crates/core/app/tests/view_server_can_be_served_on_localhost.rs @@ -2,6 +2,7 @@ use { self::common::BuilderExt, anyhow::Context, cnidarium::TempStorage, + common::TempStorageExt as _, penumbra_app::{ genesis::{self, AppState}, server::consensus::Consensus, @@ -30,7 +31,7 @@ mod common; async fn view_server_can_be_served_on_localhost() -> anyhow::Result<()> { // Install a test logger, acquire some temporary storage, and start the test node. let guard = common::set_tracing_subscriber(); - let storage = TempStorage::new().await?; + let storage = TempStorage::new_with_penumbra_prefixes().await?; // Instantiate a mock tendermint proxy, which we will connect to the test node. let proxy = penumbra_mock_tendermint_proxy::TestNodeProxy::new::();