-
Notifications
You must be signed in to change notification settings - Fork 305
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
TransactionView: summary of transaction effects #4943
Conversation
crates/core/asset/src/balance.rs
Outdated
|
||
impl From<Balance> for pb::Balance { | ||
fn from(_v: Balance) -> Self { | ||
todo!() // todo: implement fallible conversion |
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.
comment: need to implement infallible conversion (domain type to proto)
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.
filled in the implementation. Sanity check the Amount
was computed properly, references from https://github.com/penumbra-zone/penumbra/blob/main/crates/core/asset/src/balance.rs#L296-L301
crates/core/asset/src/balance.rs
Outdated
let amount = NonZeroU128::new(value.amount.into()) | ||
.ok_or_else(|| anyhow::anyhow!("amount must be non-zero"))?; | ||
|
||
let imbalance = Imbalance::Provided(amount); // todo: fix this placeholder |
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.
comment: Values
cannot be negative, and a negative Balance
is formed by negating a balance derived from a value. How do we determine the Imbalance and differentiate between provided and required balances?
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.
I think the modeling suggested by henry here: https://github.com/penumbra-zone/penumbra/pull/4943/files#r1855950445 takes care of that
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.
the negated flag for each individual SignedValue
pair now determines the imbalance
message Balance { | ||
// Indicates if the balance is negated. | ||
bool negated = 1; | ||
// Represents the vector of 'Values' in the balance. | ||
repeated Value balance = 2; | ||
} |
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.
xref https://github.com/penumbra-zone/penumbra/pull/4943/files#r1855748563
Since Value
s can't be negative, I think we'll want to have a list of pairs, each with a negation flag, something like
message Balance {
message SignedValue {
Value value = 1;
bool negated = 2;
}
repeated SignedValue values = 1;
}
The top-level bool in the Rust Balance
struct is an optimization that makes sign changes less expensive (unclear this was really necessary perf-wise, but, we have it now), IMO it should be excluded from serialization by having the serialized form always be "normalized" with individual sign bools.
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.
makes sense, refactored to capture the sign information directly in the SignedValue
pairs and normalize the top-level Balance
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.
how should we handle cases where multiple entries share the same asset ID with different negation flags, for instance:
let proto_balance = pb::Balance {
values: vec![
pb::balance::SignedValue {
value: Some(pb::Value { asset_id: Some((*STAKING_TOKEN_ASSET_ID).into()), amount: Some(Amount::from(100u128).into()) }),
negated: false
},
pb::balance::SignedValue {
value: Some(pb::Value {
asset_id: Some((*STAKING_TOKEN_ASSET_ID).into()),
amount: Some(Amount::from(200u128).into()),
}),
negated: true,
},
],
};
let balance = Balance::try_from(proto_balance).expect("fallible conversion");
The BTreeMap
can't hold multiple imbalances for the same asset ID. Instead, should it be doing something more sophisticated and explicitly accumulating values during conversion? Consequently, the serialized output should be
balance: Balance { required: [Value { amount: 100, asset_id: passet1984fctenw8m2fpl8a9wzguzp7j34d7vravryuhft808nyt9fdggqxmanqm }], provided: [] }
update: implemented an ordering-agnostic accumulation scheme that combines imbalances for the same asset ID.
crates/core/keys/src/address/view.rs
Outdated
@@ -11,7 +11,7 @@ use super::Address; | |||
/// | |||
/// This type allows working with addresses and address indexes without knowing | |||
/// the corresponding FVK. | |||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] | |||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)] |
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.
IMO, we should explicitly write down the PartialOrd instance, so that someone refactoring the order of the enums or something doesn't accidentally change it.
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.
Good idea, is it even necessary here? if so, then I think a comment like this one:
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)] | |
// Warning: This enum derives `PartialOrd` which means that re-arranging | |
// field-less variants is semver breaking. | |
#derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)] |
would be helpful. Can put a pin on doing a lookup on the rest of the codebase.
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.
It's necessary to satisfy other trait bounds in accumulate_effects
. I added the proposed comment
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.
Yeah, also we want a canonical serialization for balances.
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.
added PartialOrd
and Ord
impls for AddressView
This makes the newly added proptests pass
This matches the derived implementation, but doesn't change under refactoring.
Signed-off-by: Erwan Or <[email protected]>
change base to release/v0.81.x? |
References #4939 - [x] I have added guiding text to explain how a reviewer should test these changes. - [x] If this code contains consensus-breaking changes, I have added the "consensus-breaking" label. Otherwise, I declare my belief that there are not consensus-breaking changes, for the following reason: --------- Signed-off-by: Erwan Or <[email protected]> Co-authored-by: Lucas Meier <[email protected]> Co-authored-by: Erwan Or <[email protected]> Co-authored-by: Erwan Or <[email protected]>
Describe your changes
References #4939
Issue ticket number and link
Checklist before requesting a review
I have added guiding text to explain how a reviewer should test these changes.
If this code contains consensus-breaking changes, I have added the "consensus-breaking" label. Otherwise, I declare my belief that there are not consensus-breaking changes, for the following reason: