mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-11-15 11:53:54 +01:00
share proof amount and drop serde defaults
This commit is contained in:
@@ -529,7 +529,7 @@ where
|
||||
tx_id,
|
||||
tx_slate_id,
|
||||
)?;
|
||||
let proof = match tx.payment_proof {
|
||||
let proof = match tx.payment_proof.as_ref() {
|
||||
Some(p) => p,
|
||||
None => {
|
||||
return Err(Error::PaymentProofRetrieval(
|
||||
@@ -537,15 +537,7 @@ where
|
||||
));
|
||||
}
|
||||
};
|
||||
let amount = if tx.amount_credited >= tx.amount_debited {
|
||||
tx.amount_credited - tx.amount_debited
|
||||
} else {
|
||||
let fee = match tx.fee {
|
||||
Some(f) => f.fee(), // apply fee mask past HF4
|
||||
None => 0,
|
||||
};
|
||||
tx.amount_debited - tx.amount_credited - fee
|
||||
};
|
||||
let amount = tx.payment_proof_amount();
|
||||
let excess = match tx.kernel_excess {
|
||||
Some(e) => e,
|
||||
None => {
|
||||
@@ -620,16 +612,11 @@ where
|
||||
tx_id,
|
||||
tx_slate_id,
|
||||
)?;
|
||||
// Contract tx logs store the agreed net change separately from the fee.
|
||||
let amount = tx.amount_credited.abs_diff(tx.amount_debited);
|
||||
let sender_public_nonce = tx
|
||||
.payment_proof
|
||||
.as_ref()
|
||||
.and_then(|proof| proof.sender_public_nonce);
|
||||
|
||||
let p = tx.payment_proof.ok_or_else(|| {
|
||||
let p = tx.payment_proof.as_ref().ok_or_else(|| {
|
||||
Error::PaymentProofRetrieval("Transaction does not contain a payment proof".to_owned())
|
||||
})?;
|
||||
let amount = tx.payment_proof_amount();
|
||||
let sender_public_nonce = p.sender_public_nonce;
|
||||
let receiver_public_nonce = p.receiver_public_nonce.ok_or_else(|| {
|
||||
Error::PaymentProofRetrieval(
|
||||
"Early payment proof requires stored receiver public nonce".into(),
|
||||
@@ -657,7 +644,7 @@ where
|
||||
receiver_public_excess,
|
||||
sender_address: p.sender_address,
|
||||
timestamp: timestamp.timestamp(),
|
||||
memo: p.memo,
|
||||
memo: p.memo.clone(),
|
||||
promise_signature: p.receiver_signature,
|
||||
witness_data: None,
|
||||
};
|
||||
|
||||
@@ -59,16 +59,12 @@ pub struct ParticipantData {
|
||||
#[serde(with = "secp_ser::pubkey_serde")]
|
||||
pub nonce: PublicKey,
|
||||
/// Public partial signature
|
||||
#[serde(default = "default_part_sig_none")]
|
||||
#[serde(default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde(with = "secp_ser::option_sig_serde")]
|
||||
pub part: Option<Signature>,
|
||||
}
|
||||
|
||||
fn default_part_sig_none() -> Option<Signature> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Input commitment or output with its range proof
|
||||
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
|
||||
pub struct Commits {
|
||||
@@ -85,7 +81,7 @@ pub struct Commits {
|
||||
/// A proof that the commitment is in the right range
|
||||
/// Only applies for transaction outputs
|
||||
#[serde(with = "ser::option_rangeproof_hex")]
|
||||
#[serde(default = "default_range_proof")]
|
||||
#[serde(default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub p: Option<RangeProof>,
|
||||
}
|
||||
@@ -133,10 +129,6 @@ pub fn sig_is_blank(s: &secp::Signature) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_range_proof() -> Option<RangeProof> {
|
||||
None
|
||||
}
|
||||
|
||||
/// A mining node requests new coinbase via the foreign api every time a new candidate block is built.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Coinbase {
|
||||
|
||||
@@ -95,7 +95,7 @@ pub struct SlateV4 {
|
||||
/// base amount (excluding fee)
|
||||
#[serde(with = "secp_ser::string_or_u64")]
|
||||
#[serde(skip_serializing_if = "u64_is_blank")]
|
||||
#[serde(default = "default_u64_0")]
|
||||
#[serde(default)]
|
||||
pub amt: u64,
|
||||
/// fee
|
||||
#[serde(skip_serializing_if = "fee_is_zero")]
|
||||
@@ -103,13 +103,13 @@ pub struct SlateV4 {
|
||||
pub fee: FeeFields,
|
||||
/// kernel features, if any
|
||||
#[serde(skip_serializing_if = "u8_is_blank")]
|
||||
#[serde(default = "default_u8_0")]
|
||||
#[serde(default)]
|
||||
pub feat: u8,
|
||||
/// TTL, the block height at which wallets
|
||||
/// should refuse to process the transaction and unlock all
|
||||
#[serde(with = "secp_ser::string_or_u64")]
|
||||
#[serde(skip_serializing_if = "u64_is_blank")]
|
||||
#[serde(default = "default_u64_0")]
|
||||
#[serde(default)]
|
||||
pub ttl: u64,
|
||||
// Structs always required
|
||||
/// Participant data, each participant in the transaction will
|
||||
@@ -118,24 +118,20 @@ pub struct SlateV4 {
|
||||
pub sigs: Vec<ParticipantDataV4>,
|
||||
// Situational, but required at some point in the tx
|
||||
/// Inputs/Output commits added to slate
|
||||
#[serde(default = "default_coms_none")]
|
||||
#[serde(default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub coms: Option<Vec<CommitsV4>>,
|
||||
// Optional Structs
|
||||
/// Payment Proof
|
||||
#[serde(default = "default_payment_none")]
|
||||
#[serde(default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub proof: Option<PaymentInfoV4>,
|
||||
/// Kernel features arguments
|
||||
#[serde(default = "default_kernel_features_none")]
|
||||
#[serde(default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub feat_args: Option<KernelFeaturesArgsV4>,
|
||||
}
|
||||
|
||||
fn default_payment_none() -> Option<PaymentInfoV4> {
|
||||
None
|
||||
}
|
||||
|
||||
fn default_offset_zero() -> BlindingFactor {
|
||||
BlindingFactor::zero()
|
||||
}
|
||||
@@ -144,14 +140,6 @@ fn offset_is_zero(o: &BlindingFactor) -> bool {
|
||||
*o == BlindingFactor::zero()
|
||||
}
|
||||
|
||||
fn default_coms_none() -> Option<Vec<CommitsV4>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn default_u64_0() -> u64 {
|
||||
0
|
||||
}
|
||||
|
||||
fn num_parts_is_2(n: &u8) -> bool {
|
||||
*n == 2
|
||||
}
|
||||
@@ -160,10 +148,6 @@ fn default_num_participants_2() -> u8 {
|
||||
2
|
||||
}
|
||||
|
||||
fn default_kernel_features_none() -> Option<KernelFeaturesArgsV4> {
|
||||
None
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct VersionCompatInfoV4 {
|
||||
/// The current version of the slate format
|
||||
@@ -178,24 +162,16 @@ pub struct PaymentInfoV4 {
|
||||
pub saddr: DalekPublicKey,
|
||||
#[serde(with = "ser::dalek_pubkey_serde")]
|
||||
pub raddr: DalekPublicKey,
|
||||
#[serde(default = "default_receiver_signature_none")]
|
||||
#[serde(default)]
|
||||
#[serde(with = "ser::option_dalek_sig_serde")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub rsig: Option<DalekSignature>,
|
||||
}
|
||||
|
||||
fn default_receiver_signature_none() -> Option<DalekSignature> {
|
||||
None
|
||||
}
|
||||
|
||||
fn u64_is_blank(u: &u64) -> bool {
|
||||
*u == 0
|
||||
}
|
||||
|
||||
fn default_u8_0() -> u8 {
|
||||
0
|
||||
}
|
||||
|
||||
fn u8_is_blank(u: &u8) -> bool {
|
||||
*u == 0
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ pub struct SlateV5 {
|
||||
/// base amount (excluding fee)
|
||||
#[serde(with = "secp_ser::string_or_u64")]
|
||||
#[serde(skip_serializing_if = "u64_is_blank")]
|
||||
#[serde(default = "default_u64_0")]
|
||||
#[serde(default)]
|
||||
pub amt: u64,
|
||||
/// fee
|
||||
#[serde(skip_serializing_if = "fee_is_zero")]
|
||||
@@ -81,13 +81,13 @@ pub struct SlateV5 {
|
||||
pub fee: FeeFields,
|
||||
/// kernel features, if any
|
||||
#[serde(skip_serializing_if = "u8_is_blank")]
|
||||
#[serde(default = "default_u8_0")]
|
||||
#[serde(default)]
|
||||
pub feat: u8,
|
||||
/// TTL, the block height at which wallets
|
||||
/// should refuse to process the transaction and unlock all
|
||||
#[serde(with = "secp_ser::string_or_u64")]
|
||||
#[serde(skip_serializing_if = "u64_is_blank")]
|
||||
#[serde(default = "default_u64_0")]
|
||||
#[serde(default)]
|
||||
pub ttl: u64,
|
||||
// Structs always required
|
||||
/// Participant data, each participant in the transaction will
|
||||
@@ -96,24 +96,20 @@ pub struct SlateV5 {
|
||||
pub sigs: Vec<ParticipantDataV5>,
|
||||
// Situational, but required at some point in the tx
|
||||
/// Inputs/Output commits added to slate
|
||||
#[serde(default = "default_coms_none")]
|
||||
#[serde(default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub coms: Option<Vec<CommitsV5>>,
|
||||
// Optional Structs
|
||||
/// Payment Proof
|
||||
#[serde(default = "default_payment_none")]
|
||||
#[serde(default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub proof: Option<PaymentInfoV5>,
|
||||
/// Kernel features arguments
|
||||
#[serde(default = "default_kernel_features_none")]
|
||||
#[serde(default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub feat_args: Option<KernelFeaturesArgsV5>,
|
||||
}
|
||||
|
||||
fn default_payment_none() -> Option<PaymentInfoV5> {
|
||||
None
|
||||
}
|
||||
|
||||
fn default_offset_zero() -> BlindingFactor {
|
||||
BlindingFactor::zero()
|
||||
}
|
||||
@@ -122,14 +118,6 @@ fn offset_is_zero(o: &BlindingFactor) -> bool {
|
||||
*o == BlindingFactor::zero()
|
||||
}
|
||||
|
||||
fn default_coms_none() -> Option<Vec<CommitsV5>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn default_u64_0() -> u64 {
|
||||
0
|
||||
}
|
||||
|
||||
fn num_parts_is_2(n: &u8) -> bool {
|
||||
*n == 2
|
||||
}
|
||||
@@ -138,10 +126,6 @@ fn default_num_participants_2() -> u8 {
|
||||
2
|
||||
}
|
||||
|
||||
fn default_kernel_features_none() -> Option<KernelFeaturesArgsV5> {
|
||||
None
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct VersionCompatInfoV5 {
|
||||
/// The current version of the slate format
|
||||
@@ -163,7 +147,7 @@ pub struct PaymentInfoV5 {
|
||||
#[serde_as(as = "Option<TimestampSeconds<i64>>")]
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub ts: Option<DateTime<Utc>>,
|
||||
#[serde(default = "default_promise_signature_none")]
|
||||
#[serde(default)]
|
||||
#[serde(with = "ser::option_dalek_sig_serde")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub psig: Option<DalekSignature>,
|
||||
@@ -171,18 +155,10 @@ pub struct PaymentInfoV5 {
|
||||
pub memo: Option<PaymentMemo>,
|
||||
}
|
||||
|
||||
fn default_promise_signature_none() -> Option<DalekSignature> {
|
||||
None
|
||||
}
|
||||
|
||||
fn u64_is_blank(u: &u64) -> bool {
|
||||
*u == 0
|
||||
}
|
||||
|
||||
fn default_u8_0() -> u8 {
|
||||
0
|
||||
}
|
||||
|
||||
fn u8_is_blank(u: &u8) -> bool {
|
||||
*u == 0
|
||||
}
|
||||
|
||||
@@ -769,6 +769,20 @@ impl TxLogEntry {
|
||||
pub fn update_confirmation_ts(&mut self) {
|
||||
self.confirmation_ts = Some(Utc::now());
|
||||
}
|
||||
|
||||
/// Amount covered by the stored payment proof; early (contract) proofs don't subtract the fee
|
||||
pub fn payment_proof_amount(&self) -> u64 {
|
||||
let early = self
|
||||
.payment_proof
|
||||
.as_ref()
|
||||
.is_some_and(|p| p.proof_type.is_some());
|
||||
if early || self.amount_credited >= self.amount_debited {
|
||||
self.amount_credited.abs_diff(self.amount_debited)
|
||||
} else {
|
||||
let fee = self.fee.map(|f| f.fee()).unwrap_or(0); // apply fee mask past HF4
|
||||
self.amount_debited - self.amount_credited - fee
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Payment proof information. Differs from what is sent via
|
||||
@@ -1073,6 +1087,23 @@ mod tests {
|
||||
dur: Option<Duration>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn payment_proof_amount() {
|
||||
let key = DalekSecretKey::from_bytes(&[1u8; 32]).verifying_key();
|
||||
let mut tx = TxLogEntry::new(Identifier::zero(), TxLogEntryType::TxSent, 0);
|
||||
tx.fee = Some(FeeFields::new(0, 23_000_000).unwrap());
|
||||
tx.payment_proof = Some(StoredProofInfo::new(key, None, key, 0, None));
|
||||
// legacy send
|
||||
tx.amount_debited = 1_500_000_000;
|
||||
tx.amount_credited = 477_000_000;
|
||||
assert_eq!(tx.payment_proof_amount(), 1_000_000_000);
|
||||
// contract send
|
||||
tx.amount_debited = 200_000_000;
|
||||
tx.amount_credited = 0;
|
||||
tx.payment_proof.as_mut().unwrap().proof_type = Some(1);
|
||||
assert_eq!(tx.payment_proof_amount(), 200_000_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn duration_serde() {
|
||||
let some = TestSer {
|
||||
|
||||
Reference in New Issue
Block a user