Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delegator voting tests #1480

Merged
merged 6 commits into from
Jul 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/seven-gifts-play.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@penumbra-zone/wasm': patch
---

Bug fix with get_all_notes not respecting None asset id + delegator voting tests
1 change: 1 addition & 0 deletions packages/wasm/crate/src/database/mock.rs
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@ pub fn get_mock_tables() -> Tables {

type DbTable = Rc<RefCell<HashMap<String, JsValue>>>;

#[derive(Clone, Debug)]
pub struct MockDb {
tables: RefCell<HashMap<String, DbTable>>,
}
45 changes: 26 additions & 19 deletions packages/wasm/crate/src/planner.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@ use std::mem;
use anyhow::anyhow;
use ark_ff::UniformRand;
use decaf377::{Fq, Fr};
use indexed_db_futures::IdbDatabase;
use penumbra_asset::asset::{Id, Metadata};
use penumbra_asset::Value;
use penumbra_auction::auction::dutch::actions::ActionDutchAuctionWithdrawPlan;
@@ -34,17 +33,18 @@ use penumbra_stake::rate::RateData;
use penumbra_stake::{IdentityKey, Penalty, Undelegate, UndelegateClaimPlan};
use penumbra_transaction::gas::swap_claim_gas_cost;
use penumbra_transaction::memo::MemoPlaintext;
use penumbra_transaction::ActionList;
use penumbra_transaction::{plan::MemoPlan, ActionPlan, TransactionParameters};
use penumbra_transaction::{ActionList, TransactionPlan};
use prost::Message;
use rand_core::{OsRng, RngCore};
use wasm_bindgen::prelude::wasm_bindgen;
use wasm_bindgen::JsValue;

use crate::database::interface::Database;
use crate::error::WasmError;
use crate::metadata::customize_symbol_inner;
use crate::note_record::SpendableNoteRecord;
use crate::storage::{init_idb_storage, OutstandingReserves, Storage};
use crate::storage::{init_idb_storage, DbConstants, OutstandingReserves, Storage};
use crate::utils;
use crate::{error::WasmResult, swap_record::SwapRecord};

@@ -97,9 +97,9 @@ fn prioritize_and_filter_spendable_notes(
/// token metadata for a given validator and a given height doesn't exist yet,
/// we'll generate it here and save it to the database, so that the undelegate
/// action renders correctly in the transaction approval dialog.
async fn save_unbonding_token_metadata_if_needed(
async fn save_unbonding_token_metadata_if_needed<Db: Database>(
undelegate: &Undelegate,
storage: &Storage<IdbDatabase>,
storage: &Storage<Db>,
) -> WasmResult<()> {
let metadata = undelegate.unbonding_token().denom();

@@ -113,9 +113,9 @@ async fn save_unbonding_token_metadata_if_needed(
/// dervived from the auction description parameters, which include a nonce). So
/// we'll generate the metadata here and save it to the database, so that the
/// action renders correctly in the transaction approval dialog.
async fn save_auction_nft_metadata_if_needed(
async fn save_auction_nft_metadata_if_needed<Db: Database>(
id: AuctionId,
storage: &Storage<IdbDatabase>,
storage: &Storage<Db>,
seq: u64,
) -> WasmResult<()> {
let nft = AuctionNft::new(id, seq);
@@ -124,9 +124,9 @@ async fn save_auction_nft_metadata_if_needed(
save_metadata_if_needed(metadata, storage).await
}

async fn save_metadata_if_needed(
async fn save_metadata_if_needed<Db: Database>(
metadata: Metadata,
storage: &Storage<IdbDatabase>,
storage: &Storage<Db>,
) -> WasmResult<()> {
if storage.get_asset(&metadata.id()).await?.is_none() {
let metadata_proto = metadata.to_proto();
@@ -148,8 +148,23 @@ pub async fn plan_transaction(
) -> WasmResult<JsValue> {
utils::set_panic_hook();

let request = TransactionPlannerRequest::decode(request)?;
let tx_planner_req = TransactionPlannerRequest::decode(request)?;
let fvk: FullViewingKey = FullViewingKey::decode(full_viewing_key)?;
let fee_asset_id = Id::decode(gas_fee_token)?;
let constants: DbConstants = serde_wasm_bindgen::from_value(idb_constants)?;
let storage = init_idb_storage(constants).await?;

let plan = plan_transaction_inner(storage, tx_planner_req, fvk, fee_asset_id).await?;

Ok(serde_wasm_bindgen::to_value(&plan)?)
}
Comment on lines +151 to +160
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created plan_transaction_inner() in order to separate the serde serialization from the core logic of the function (that gets tested in the test suite).


pub async fn plan_transaction_inner<Db: Database>(
storage: Storage<Db>,
request: TransactionPlannerRequest,
fvk: FullViewingKey,
fee_asset_id: Id,
) -> WasmResult<TransactionPlan> {
let expiry_height: u64 = request.expiry_height;

let mut source_address_index: AddressIndex = request
@@ -164,16 +179,11 @@ pub async fn plan_transaction(
// 2. Using one-time addresses for change addresses is undesirable.
source_address_index.randomizer = [0u8; 12];

let fvk: FullViewingKey = FullViewingKey::decode(full_viewing_key)?;

// Compute the change address for this transaction.
let (mut change_address, _) = fvk
.incoming()
.payment_address(source_address_index.account.into());

let constants = serde_wasm_bindgen::from_value(idb_constants)?;
let storage = init_idb_storage(constants).await?;

let fmd_params: fmd::Parameters = storage
.get_fmd_params()
.await?
@@ -191,9 +201,6 @@ pub async fn plan_transaction(

let chain_id: String = app_parameters.chain_id;

// Decode the gas fee token into an `Id` type
let fee_asset_id: Id = Id::decode(gas_fee_token)?;

// Request information about current gas prices
let gas_prices = storage
.get_gas_prices_by_asset_id(&fee_asset_id)
@@ -634,5 +641,5 @@ pub async fn plan_transaction(
let plan =
mem::take(&mut actions_list).into_plan(OsRng, &fmd_params, transaction_parameters, memo)?;

Ok(serde_wasm_bindgen::to_value(&plan)?)
Ok(plan)
}
16 changes: 9 additions & 7 deletions packages/wasm/crate/src/storage.rs
Original file line number Diff line number Diff line change
@@ -54,17 +54,17 @@ pub async fn init_idb_storage(constants: DbConstants) -> WasmResult<Storage<IdbD
Storage::new(db, constants.tables)
}

pub struct Storage<T: Database> {
db: T,
pub struct Storage<Db: Database> {
db: Db,
tables: Tables,
}

impl<T: Database> Storage<T> {
pub fn new(db: T, tables: Tables) -> WasmResult<Self> {
impl<Db: Database> Storage<Db> {
pub fn new(db: Db, tables: Tables) -> WasmResult<Self> {
Ok(Storage { db, tables })
}

pub fn get_database(&self) -> *const T {
pub fn get_database(&self) -> *const Db {
&self.db
}

@@ -94,8 +94,10 @@ impl<T: Database> Storage<T> {
continue;
}

if Some(record.note.asset_id()) != asset_id {
continue;
if let Some(id) = asset_id {
if record.note.asset_id() != id {
continue;
}
Comment on lines +97 to +100
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug fix 🐞 : The query should respect passing a None. Currently breaks delegator vote planning.

}

// Planner should omit the address index randomizer and compare only the account index
Loading
Loading