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

Fix idb account contains asset, fix wasm gas prices #1603

Closed
wants to merge 6 commits into from

Conversation

turbocrime
Copy link
Contributor

@turbocrime turbocrime commented Jul 31, 2024

fixes #1601
fixes #1602

this PR corrects idb method used to identify tokens present in an account by correctly comparing address index and asset id. the method will assert the validity of incoming arguments.

this PR corrects wasm planner to use default-zero gas fees if none are present in idb query.

some minifront ui may still be submitting plans with asset id that are not valid.

it should be decided if:

  1. incoming rpc with asset id that do not contain a proper inner binary field should be accepted
  2. incoming rpc with asset id that do not contain a proper inner binary field should be rejected

tested on deimos (zero chain gas fees) successfully with ibc-osmo gda to um and ibc-osmo out.

tested on phobos (chain gas fees) successfully with ibc-osmo gda to um and ibc-osmo out.

ci is failing because tests are using incorrect data.

Copy link

changeset-bot bot commented Jul 31, 2024

🦋 Changeset detected

Latest commit: af28b4d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@penumbra-zone/getters Minor
@penumbra-zone/storage Major
@penumbra-zone/types Major
@penumbra-zone/wasm Major
minifront Patch
@penumbra-zone/perspective Major
@penumbra-zone/query Major
@penumbra-zone/services Major
@repo/ui Patch
node-status Patch
@penumbra-zone/crypto-web Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@turbocrime turbocrime changed the title Fix idb Fix idb account contains asset, fix wasm gas prices Jul 31, 2024
@turbocrime turbocrime requested review from TalDerei, grod220 and a team July 31, 2024 06:24
Comment on lines 120 to 129
if (assetId) {
const balance = await indexedDb.hasTokenBalance(request.source, assetId);
const balance = await indexedDb.accountHasSpendableAsset(request.source, assetId);
// This check ensures that the alternative fee token is a valid fee token, for example, TestUSD is not.
const isInGasTable = altGasPrices.find(gp => gp.assetId?.equals(assetId));
const isInGasTable = altGasPrices.find(
// TODO: assert this more thoroughly
gp => bech32mAssetId(gp.assetId!) === bech32mAssetId(assetId),
);
if (balance && isInGasTable) {
return assetId;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this part could be improved but i'm going to bed

Copy link
Contributor

@TalDerei TalDerei Jul 31, 2024

Choose a reason for hiding this comment

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

this checks if the assetId passed in exists in the GasPrices table. since we're comparing assetId objects directly, why isn't the equality method sufficient here?


const spendableNotes = assetNotes.filter(({ note, addressIndex, heightSpent }) => {
const noteAddressIndex = toPlainMessage(addressIndex ?? new AddressIndex());
const accountMatch = noteAddressIndex.account === account;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

is it correct to ignore account randomizer for this comparison?

Copy link
Contributor

@TalDerei TalDerei Jul 31, 2024

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

someone should fix these tests

Copy link
Contributor

Choose a reason for hiding this comment

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

@TalDerei
Copy link
Contributor

TalDerei commented Jul 31, 2024

There are a few points to note about #1602.

For context, GasPrices not Available essentially means that "the fee we're trying to use for the transaction hasn't been defined on-chain and therefore isn't in the GasPrices table, making it unusable for the transaction". That sounds reasonable to me.


1. This situation isn't representative of mainnet conditions because the mainnet chain does have gas prices.

2. If alternative fees in the GasPrices table are undefined, it seems they already default to 0. For example:

Screenshot 2024-07-31 at 1 44 32 AM
Screen.Recording.2024-07-31.at.1.49.27.AM.mov

3. The consequence of the refactor is that it wouldn't even reach that point because it will fail early and be caught by minfront if the user doesn't have a balance for any of the alternative fees defined in the GasPrices table. In the example below, notice that the account doesn't have any UM, GM, or GN, which are the only assets defined in the GasPrices table. Not able to pay fee for transaction is the error we should expect to see.

Screen.Recording.2024-07-31.at.2.14.32.AM.mov

packages/services/src/view-service/fees.ts Show resolved Hide resolved
Comment on lines +19 to +22
const noNativeTokenAvailable = !(await indexedDb.accountHasSpendableAsset(
toPlainMessage(req.source ?? new AddressIndex()),
indexedDb.stakingTokenAssetId,
));
Copy link
Contributor

Choose a reason for hiding this comment

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

actually shouldn't AddressIndex never be undefined, since it will fail the transaction source check. In that case, why can't we use the non-null assertion operator on source?

const gasFeeToken = needsAltFeeToken
? await extractAltFee(req, indexedDb)
: indexedDb.stakingTokenAssetId;
console.log('alt fee reasons', noNativeTokenAvailable, planningSwapClaim);
Copy link
Contributor

Choose a reason for hiding this comment

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

remove log

console.log('alt fee reasons', noNativeTokenAvailable, planningSwapClaim);

const gasFeeToken =
noNativeTokenAvailable || planningSwapClaim
Copy link
Contributor

Choose a reason for hiding this comment

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

I actually prefer keeping needsAltFeeToken, so we can tack on more invariants later.

@@ -205,7 +205,7 @@ pub async fn plan_transaction_inner<Db: Database>(
let gas_prices = storage
.get_gas_prices_by_asset_id(&fee_asset_id)
.await?
.ok_or_else(|| anyhow!("GasPrices not available"))?;
.unwrap_or_default();
Copy link
Contributor

Choose a reason for hiding this comment

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

see comment below addressing #1602

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's a mistake, we shouldn't use default gas prices
And use only those gas prices that have been published in compact blocks

Copy link
Contributor

@TalDerei TalDerei Jul 31, 2024

Choose a reason for hiding this comment

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

I agree with this sentiment. For example, this could theoretically allow paying fees with unsupported gas tokens, like TestUSD. However, I don't think it would ever error in the planner because we have checks in the frontend at in getAssetFromGasPriceTable, which would then trigger this error.


const spendableNotes = assetNotes.filter(({ note, addressIndex, heightSpent }) => {
const noteAddressIndex = toPlainMessage(addressIndex ?? new AddressIndex());
const accountMatch = noteAddressIndex.account === account;
Copy link
Contributor

@TalDerei TalDerei Jul 31, 2024

Choose a reason for hiding this comment

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

@@ -205,7 +205,7 @@ pub async fn plan_transaction_inner<Db: Database>(
let gas_prices = storage
.get_gas_prices_by_asset_id(&fee_asset_id)
.await?
.ok_or_else(|| anyhow!("GasPrices not available"))?;
.unwrap_or_default();
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's a mistake, we shouldn't use default gas prices
And use only those gas prices that have been published in compact blocks

@grod220
Copy link
Collaborator

grod220 commented Jul 31, 2024

Taking this over to expedite bug fixes

@TalDerei
Copy link
Contributor

prioritizing #1605, this pr can be useful follow-up work.

@turbocrime
Copy link
Contributor Author

update: address-index comparison is corrected by #1605 but remaining issues persist

@TalDerei
Copy link
Contributor

TalDerei commented Aug 14, 2024

closing this per the comments #1603 (comment) and #1603 (comment). This changeset is outdated and introduces unnecessary changes to what appear to be non-issues.

The only remaining open question concerns the representation of the asset Id. I believe that any incoming rpc with an asset Id that lacks a proper inner binary field — which might come from the frontend but it won’t ever come in a compact block — should be rejected. However, if we decide otherwise, we can address this in a separate PR and reduce the scope of the changes.

@TalDerei TalDerei closed this Aug 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Wasm planner throws on undefined gas fees hasTokenBalance does not correctly detect token balances
4 participants