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

TransactionView: summary of transaction effects #4943

Merged
merged 30 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9935b89
proto(balance): define Balance message
TalDerei Nov 24, 2024
30138f8
regenerate protos for Balance message
TalDerei Nov 24, 2024
7174118
proto(TransactionSummary): define TransactionSummary message
TalDerei Nov 24, 2024
06bf641
regenerate protos for TransactionSummary message
TalDerei Nov 24, 2024
9add44d
add corresponding domain types to Balance
TalDerei Nov 24, 2024
abd9a29
modify message and regenerate protos for Balance
TalDerei Nov 25, 2024
8c12d8e
stub fallible conversion (proto message to domain type)
TalDerei Nov 25, 2024
8382e6a
add corresponding domain types to TransactionSummary and Effects
TalDerei Nov 25, 2024
ff86c9a
stub summary method in TransactionView
TalDerei Nov 25, 2024
425e549
proto(TransactionSummary): combine into a sub-message
TalDerei Nov 30, 2024
95aacc0
domain type (TransactionSummary): combine into a sub-message
TalDerei Nov 30, 2024
78741f8
proto(Balance): encapsulate list of value pairs
TalDerei Nov 30, 2024
36e9e5e
domain type (Balance): refactor conversions
TalDerei Nov 30, 2024
e434fa4
fix infinite recursion
TalDerei Nov 30, 2024
7b5670c
fill other action views
TalDerei Nov 30, 2024
f812330
proto(Balance): modify serialization and add unit testing
TalDerei Dec 8, 2024
f2142d8
proto(Balance): fix negation flag
TalDerei Dec 9, 2024
746d981
TransactionSummary: add unit testing
TalDerei Dec 9, 2024
86ede41
cargo clippy
TalDerei Dec 9, 2024
0ef739a
change visibility to private
TalDerei Dec 9, 2024
ef70e9c
simplify accumulate_summary method
TalDerei Dec 11, 2024
6b59390
swap unit test and dummy data
TalDerei Dec 11, 2024
2544232
remove log statements
TalDerei Dec 11, 2024
ee48a48
simplify accumulate effects helper
TalDerei Dec 13, 2024
d59033e
proto(Balance): handle zero cases in fallible conversion
TalDerei Dec 13, 2024
02b18d0
serialization: explicitely define ordering
TalDerei Dec 13, 2024
a37c046
testing: add proptest and filter zero amounts in fallible conversion
TalDerei Dec 13, 2024
f34601f
Simplify balance conversion
cronokirby Dec 13, 2024
74aa056
Simplify manual PartialOrd for AdressView
cronokirby Dec 13, 2024
28c8e70
core(balance): fix typo
erwanor Dec 13, 2024
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
Binary file modified crates/cnidarium/src/gen/proto_descriptor.bin.no_lfs
Binary file not shown.
383 changes: 376 additions & 7 deletions crates/core/asset/src/balance.rs

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions crates/core/keys/src/address/view.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::cmp::Ordering;

use serde::{Deserialize, Serialize};

use penumbra_proto::{penumbra::core::keys::v1 as pb, DomainType};
Expand Down Expand Up @@ -99,6 +101,76 @@ impl TryFrom<pb::AddressView> for AddressView {
}
}

// Canonical ordering for serialization
impl PartialOrd for AddressView {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
use AddressView::*;
// Opaque < Decoded
match (self, other) {
(Opaque { .. }, Decoded { .. }) => Some(Ordering::Less),
(Decoded { .. }, Opaque { .. }) => Some(Ordering::Greater),
(Opaque { address: a1 }, Opaque { address: a2 }) => a1.partial_cmp(a2),
(
Decoded {
address: a1,
index: i1,
wallet_id: w1,
},
Decoded {
address: a2,
index: i2,
wallet_id: w2,
},
) => (a1, i1, w1).partial_cmp(&(a2, i2, w2)),
}
}
}

impl Ord for AddressView {
fn cmp(&self, other: &Self) -> Ordering {
// Opaque < Decoded
match (self, other) {
(AddressView::Opaque { address: a1 }, AddressView::Opaque { address: a2 }) => {
a1.cmp(a2)
}
(
AddressView::Decoded {
address: a1,
index: i1,
wallet_id: w1,
},
AddressView::Decoded {
address: a2,
index: i2,
wallet_id: w2,
},
) => match a1.cmp(a2) {
Ordering::Equal => match i1.cmp(i2) {
Ordering::Equal => w1.cmp(w2),
ord => ord,
},
ord => ord,
},
(
AddressView::Opaque { address: _ },
AddressView::Decoded {
address: _,
index: _,
wallet_id: _,
},
) => Ordering::Less,
(
AddressView::Decoded {
address: _,
index: _,
wallet_id: _,
},
AddressView::Opaque { address: _ },
) => Ordering::Greater,
}
}
}

#[cfg(test)]
mod tests {
use rand_core::OsRng;
Expand Down
68 changes: 66 additions & 2 deletions crates/core/transaction/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ use anyhow::{Context, Error};
use ark_ff::Zero;
use decaf377::Fr;
use decaf377_rdsa::{Binding, Signature, VerificationKey, VerificationKeyBytes};
use penumbra_asset::Balance;
use penumbra_community_pool::{CommunityPoolDeposit, CommunityPoolOutput, CommunityPoolSpend};
use penumbra_dex::{
lp::action::{PositionClose, PositionOpen},
swap::Swap,
};
erwanor marked this conversation as resolved.
Show resolved Hide resolved
use penumbra_governance::{DelegatorVote, ProposalSubmit, ProposalWithdraw, ValidatorVote};
use penumbra_ibc::IbcRelay;
use penumbra_keys::{FullViewingKey, PayloadKey};
use penumbra_keys::{AddressView, FullViewingKey, PayloadKey};
use penumbra_proto::{
core::transaction::v1::{self as pbt},
DomainType, Message,
Expand Down Expand Up @@ -44,6 +45,20 @@ pub struct TransactionBody {
pub memo: Option<MemoCiphertext>,
}

/// Represents a transaction summary containing multiple effects.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(try_from = "pbt::TransactionSummary", into = "pbt::TransactionSummary")]
pub struct TransactionSummary {
pub effects: Vec<TransactionEffect>,
}

/// Represents an individual effect of a transaction.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TransactionEffect {
pub address: AddressView,
pub balance: Balance,
}

impl EffectingData for TransactionBody {
fn effect_hash(&self) -> EffectHash {
let mut state = blake2b_simd::Params::new()
Expand Down Expand Up @@ -591,6 +606,50 @@ impl Transaction {
}
}

impl DomainType for TransactionSummary {
type Proto = pbt::TransactionSummary;
}

impl From<TransactionSummary> for pbt::TransactionSummary {
fn from(summary: TransactionSummary) -> Self {
pbt::TransactionSummary {
effects: summary
.effects
.into_iter()
.map(|effect| pbt::transaction_summary::Effects {
address: Some(effect.address.into()),
balance: Some(effect.balance.into()),
})
.collect(),
}
}
}

impl TryFrom<pbt::TransactionSummary> for TransactionSummary {
type Error = anyhow::Error;

fn try_from(pbt: pbt::TransactionSummary) -> Result<Self, Self::Error> {
let effects = pbt
.effects
.into_iter()
.map(|effect| {
Ok(TransactionEffect {
address: effect
.address
.ok_or_else(|| anyhow::anyhow!("missing address field"))?
.try_into()?,
balance: effect
.balance
.ok_or_else(|| anyhow::anyhow!("missing balance field"))?
.try_into()?,
})
})
.collect::<Result<Vec<TransactionEffect>, anyhow::Error>>()?;

Ok(Self { effects })
}
}

impl DomainType for TransactionBody {
type Proto = pbt::TransactionBody;
}
Expand Down Expand Up @@ -662,7 +721,12 @@ impl From<Transaction> for pbt::Transaction {

impl From<&Transaction> for pbt::Transaction {
fn from(msg: &Transaction) -> Self {
msg.into()
Transaction {
transaction_body: msg.transaction_body.clone(),
anchor: msg.anchor.clone(),
binding_sig: msg.binding_sig.clone(),
}
.into()
}
}

Expand Down
Loading
Loading