-
Notifications
You must be signed in to change notification settings - Fork 17
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
1310 modify gasprices storage to support multi asset fees #1412
Changes from all commits
70b6ae7
aaf5eea
c896050
6b1cc4a
e71b644
1adb710
37205da
4e57947
0918c81
e201ad2
9cbcd5f
557677b
30d7049
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--- | ||
'@penumbra-zone/storage': major | ||
'@penumbra-zone/services': minor | ||
'@penumbra-zone/query': minor | ||
'@penumbra-zone/types': minor | ||
'@penumbra-zone/wasm': minor | ||
--- | ||
|
||
Modify GasPrices storage to support multi-asset fees |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -119,7 +119,7 @@ export class IndexedDb implements IndexedDbInterface { | |
db.createObjectStore('SWAPS', { | ||
keyPath: 'swapCommitment.inner', | ||
}).createIndex('nullifier', 'nullifier.inner'); | ||
db.createObjectStore('GAS_PRICES'); | ||
db.createObjectStore('GAS_PRICES', { keyPath: 'assetId.inner' }); | ||
db.createObjectStore('POSITIONS', { keyPath: 'id.inner' }); | ||
db.createObjectStore('EPOCHS', { autoIncrement: true }); | ||
db.createObjectStore('VALIDATOR_INFOS'); | ||
|
@@ -385,21 +385,26 @@ export class IndexedDb implements IndexedDbInterface { | |
return SwapRecord.fromJson(json); | ||
} | ||
|
||
// TODO #1310 'getGasPrices()' should be renamed to 'getNativeGasPrice()' | ||
async getGasPrices(): Promise<GasPrices | undefined> { | ||
// TODO #1310 use this.stakingTokenAssetId as the key for the query | ||
const jsonGasPrices = await this.db.get('GAS_PRICES', 'gas_prices'); | ||
async getNativeGasPrices(): Promise<GasPrices | undefined> { | ||
const jsonGasPrices = await this.db.get( | ||
'GAS_PRICES', | ||
uint8ArrayToBase64(this.stakingTokenAssetId.inner), | ||
); | ||
if (!jsonGasPrices) return undefined; | ||
return GasPrices.fromJson(jsonGasPrices); | ||
} | ||
|
||
// TODO #1310 implement getAltGasPrices() | ||
async getAltGasPrices(): Promise<GasPrices[]> { | ||
const allGasPrices = await this.db.getAll('GAS_PRICES'); | ||
return allGasPrices | ||
.map(gp => GasPrices.fromJson(gp)) | ||
.filter(gp => !gp.assetId?.equals(this.stakingTokenAssetId)); | ||
} | ||
|
||
async saveGasPrices(value: PartialMessage<GasPrices>): Promise<void> { | ||
await this.u.update({ | ||
table: 'GAS_PRICES', | ||
value: new GasPrices(value).toJson() as Jsonified<GasPrices>, | ||
key: 'gas_prices', | ||
}); | ||
} | ||
|
||
|
@@ -815,7 +820,7 @@ export class IndexedDb implements IndexedDbInterface { | |
}; | ||
} | ||
|
||
async hasStakingAssetBalance(): Promise<boolean> { | ||
async hasStakingAssetBalance(addressIndex: AddressIndex | undefined): Promise<boolean> { | ||
const spendableUMNotes = await this.db.getAllFromIndex( | ||
'SPENDABLE_NOTES', | ||
'assetId', | ||
|
@@ -824,7 +829,11 @@ export class IndexedDb implements IndexedDbInterface { | |
|
||
return spendableUMNotes.some(note => { | ||
const umNote = SpendableNoteRecord.fromJson(note); | ||
return umNote.heightSpent === 0n && !isZero(getAmountFromRecord(umNote)); | ||
return ( | ||
umNote.heightSpent === 0n && | ||
!isZero(getAmountFromRecord(umNote)) && | ||
umNote.addressIndex?.equals(addressIndex) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice filtering for address index here |
||
); | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,11 @@ | ||
use crate::metadata::customize_symbol_inner; | ||
use crate::note_record::SpendableNoteRecord; | ||
use crate::storage::{IndexedDBStorage, OutstandingReserves}; | ||
use crate::utils; | ||
use crate::{error::WasmResult, swap_record::SwapRecord}; | ||
use std::collections::BTreeMap; | ||
use std::mem; | ||
|
||
use anyhow::anyhow; | ||
use ark_ff::UniformRand; | ||
use decaf377::{Fq, Fr}; | ||
use penumbra_asset::asset::{Id, Metadata}; | ||
use penumbra_asset::{Value, STAKING_TOKEN_ASSET_ID}; | ||
use penumbra_asset::Value; | ||
use penumbra_auction::auction::dutch::actions::ActionDutchAuctionWithdrawPlan; | ||
use penumbra_auction::auction::dutch::{ | ||
ActionDutchAuctionEnd, ActionDutchAuctionSchedule, DutchAuctionDescription, | ||
|
@@ -38,11 +36,15 @@ use penumbra_transaction::ActionList; | |
use penumbra_transaction::{plan::MemoPlan, ActionPlan, TransactionParameters}; | ||
use prost::Message; | ||
use rand_core::{OsRng, RngCore}; | ||
use std::collections::BTreeMap; | ||
use std::mem; | ||
use wasm_bindgen::prelude::wasm_bindgen; | ||
use wasm_bindgen::JsValue; | ||
|
||
use crate::metadata::customize_symbol_inner; | ||
use crate::note_record::SpendableNoteRecord; | ||
use crate::storage::{IndexedDBStorage, OutstandingReserves}; | ||
use crate::utils; | ||
use crate::{error::WasmResult, swap_record::SwapRecord}; | ||
|
||
/// Prioritize notes to spend to release value of a specific transaction. | ||
/// | ||
/// Various logic is possible for note selection. Currently, this method | ||
|
@@ -181,13 +183,15 @@ 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 | ||
// TODO #1310 GasPrices record may not exist for alternative fee assets | ||
let mut gas_prices: GasPrices = { | ||
let gas_prices: GasPrices = { | ||
let gas_prices: penumbra_proto::core::component::fee::v1::GasPrices = | ||
serde_wasm_bindgen::from_value( | ||
storage | ||
.get_gas_prices() | ||
.get_gas_prices_by_asset_id(fee_asset_id) | ||
.await? | ||
.ok_or_else(|| anyhow!("GasPrices not available"))?, | ||
)?; | ||
|
@@ -202,28 +206,12 @@ pub async fn plan_transaction( | |
} | ||
}; | ||
|
||
// Decode the gas fee token into an `Id` type | ||
let alt_gas: Id = Id::decode(gas_fee_token)?; | ||
|
||
// Check if the decoded gas fee token is different from the staking token asset ID. | ||
// If the gas fee token is different, use the alternative gas fee token with a 10x | ||
// multiplier. | ||
if alt_gas != *STAKING_TOKEN_ASSET_ID { | ||
gas_prices = GasPrices { | ||
asset_id: alt_gas, | ||
block_space_price: gas_prices.block_space_price * 10, | ||
compact_block_space_price: gas_prices.compact_block_space_price * 10, | ||
verification_price: gas_prices.verification_price * 10, | ||
execution_price: gas_prices.execution_price * 10, | ||
}; | ||
Comment on lines
-213
to
-217
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. gas fee token price multiplier will instead be determined by governance proposals, rather than arbitrarily setting a 10x multiplier. |
||
}; | ||
|
||
let mut transaction_parameters = TransactionParameters { | ||
chain_id, | ||
expiry_height, | ||
..Default::default() | ||
}; | ||
transaction_parameters.fee.0.asset_id = alt_gas; | ||
transaction_parameters.fee.0.asset_id = fee_asset_id; | ||
|
||
let mut actions_list = ActionList::default(); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this suggests that the RPC node is returning information in compact blocks about two alternative gas fees, but with zero gas prices. Manual testing confirmed that all other token denominations result in a "GasPrices not available" error.