-
Notifications
You must be signed in to change notification settings - Fork 1
Update AssetSuply and SupplyInfo (new) #133
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
Changes from 15 commits
2bee134
01eb3e3
60e1854
6c540dd
c9f8ba3
c30e108
9d1fcfa
19ee69f
4f43896
a60428e
d7973db
2cce7db
5b852f0
2bd20ab
062dfca
c07e872
1c7ef6c
b3ed468
967cf84
124dddf
495c5d4
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 |
|---|---|---|
|
|
@@ -4,21 +4,21 @@ use group::Group; | |
| use k256::schnorr; | ||
| use nonempty::NonEmpty; | ||
| use rand::RngCore; | ||
| use std::collections::{HashMap, HashSet}; | ||
| use std::collections::HashSet; | ||
| use std::fmt; | ||
|
|
||
| use crate::bundle::commitments::{hash_issue_bundle_auth_data, hash_issue_bundle_txid_data}; | ||
| use crate::constants::reference_keys::ReferenceKeys; | ||
| use crate::issuance::Error::{ | ||
| AssetBaseCannotBeIdentityPoint, IssueActionNotFound, IssueActionPreviouslyFinalizedAssetBase, | ||
| IssueActionWithoutNoteNotFinalized, IssueBundleIkMismatchAssetBase, | ||
| IssueBundleInvalidSignature, ValueSumOverflow, WrongAssetDescSize, | ||
| IssueBundleInvalidSignature, ValueOverflow, WrongAssetDescSize, | ||
| }; | ||
| use crate::keys::{IssuanceAuthorizingKey, IssuanceValidatingKey}; | ||
| use crate::note::asset_base::is_asset_desc_of_valid_size; | ||
| use crate::note::{AssetBase, Nullifier, Rho}; | ||
|
|
||
| use crate::value::{NoteValue, ValueSum}; | ||
| use crate::value::NoteValue; | ||
| use crate::{Address, Note}; | ||
|
|
||
| use crate::supply_info::{AssetSupply, SupplyInfo}; | ||
|
|
@@ -114,7 +114,7 @@ impl IssueAction { | |
| /// | ||
| /// This function may return an error in any of the following cases: | ||
| /// | ||
| /// * `ValueSumOverflow`: If the total amount value of all notes in the `IssueAction` overflows. | ||
| /// * `ValueOverflow`: If the total amount value of all notes in the `IssueAction` overflows. | ||
| /// | ||
| /// * `IssueBundleIkMismatchAssetBase`: If the provided `ik` is not used to derive the | ||
| /// `AssetBase` for **all** internal notes. | ||
|
|
@@ -132,7 +132,7 @@ impl IssueAction { | |
| let value_sum = self | ||
| .notes | ||
| .iter() | ||
| .try_fold(ValueSum::zero(), |value_sum, ¬e| { | ||
| .try_fold(NoteValue::zero(), |value_sum, ¬e| { | ||
| //The asset base should not be the identity point of the Pallas curve. | ||
| if bool::from(note.asset().cv_base().is_identity()) { | ||
| return Err(AssetBaseCannotBeIdentityPoint); | ||
|
|
@@ -145,12 +145,16 @@ impl IssueAction { | |
| .ok_or(IssueBundleIkMismatchAssetBase)?; | ||
|
|
||
| // The total amount should not overflow | ||
| (value_sum + note.value()).ok_or(ValueSumOverflow) | ||
| (value_sum + note.value()).ok_or(ValueOverflow) | ||
| })?; | ||
|
|
||
| Ok(( | ||
| issue_asset, | ||
| AssetSupply::new(value_sum, self.is_finalized()), | ||
| AssetSupply::new( | ||
| value_sum, | ||
| self.is_finalized(), | ||
| self.get_reference_note().cloned(), | ||
| ), | ||
| )) | ||
| } | ||
|
|
||
|
|
@@ -163,6 +167,13 @@ impl IssueAction { | |
| 0b0000_0000 | ||
| } | ||
| } | ||
|
|
||
| /// Returns the reference note. | ||
| pub fn get_reference_note(&self) -> Option<&Note> { | ||
| self.notes.iter().find(|note| { | ||
| (note.recipient() == ReferenceKeys::recipient()) && (note.value() == NoteValue::zero()) | ||
| }) | ||
| } | ||
|
Comment on lines
+172
to
+187
Collaborator
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. So according to the finalized spec, the reference note must be the first note.
with
Collaborator
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. use the existing
Author
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. So, if the first note doesn't match the reference note condition, it should return None even if, for example, there's the second note that does match the condition? Now I changed it this way: /// Returns the reference note.
pub fn get_reference_note(&self) -> Option<&Note> {
self.notes.first().filter(|note| {
(note.recipient() == ReferenceKeys::recipient()) && (note.value() == NoteValue::zero())
})
}It considers the first note only, and
Collaborator
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.
Also update doc for this function.
Author
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. Now I added new function: fn is_reference_note(note: &Note) -> bool {
note.value() == NoteValue::zero() && note.recipient() == ReferenceKeys::recipient()
}and used it in |
||
| } | ||
|
|
||
| /// Defines the authorization type of an Issue bundle. | ||
|
|
@@ -468,23 +479,6 @@ impl IssueBundle<Unauthorized> { | |
| } | ||
| } | ||
|
|
||
| impl<T: IssueAuth> IssueBundle<T> { | ||
| /// Returns the reference notes for the `IssueBundle`. | ||
| pub fn get_reference_notes(self) -> HashMap<AssetBase, Note> { | ||
| let mut reference_notes = HashMap::new(); | ||
| self.actions.iter().for_each(|action| { | ||
| action.notes.iter().for_each(|note| { | ||
| if (note.recipient() == ReferenceKeys::recipient()) | ||
| && (note.value() == NoteValue::zero()) | ||
| { | ||
| reference_notes.insert(note.asset(), *note); | ||
| } | ||
| }) | ||
| }); | ||
| reference_notes | ||
| } | ||
| } | ||
|
|
||
| fn create_reference_note(asset: AssetBase, mut rng: impl RngCore) -> Note { | ||
| Note::new( | ||
| ReferenceKeys::recipient(), | ||
|
|
@@ -561,12 +555,13 @@ impl IssueBundle<Signed> { | |
| /// * For each `Note` inside an `IssueAction`: | ||
| /// * All notes have the same, correct `AssetBase`. | ||
| /// | ||
| // # Returns | ||
| /// # Returns | ||
| /// | ||
| /// A Result containing a SupplyInfo struct, which stores supply information in a HashMap. | ||
| /// The HashMap uses AssetBase as the key, and an AssetSupply struct as the value. The | ||
| /// AssetSupply contains a ValueSum (representing the total value of all notes for the asset) | ||
| /// and a bool indicating whether the asset is finalized. | ||
| /// The HashMap `assets` uses AssetBase as the key, and an AssetSupply struct as the | ||
| /// value. The AssetSupply contains a NoteValue (representing the total value of all notes for | ||
| /// the asset), a bool indicating whether the asset is finalized and a Note (the reference note | ||
| /// for this asset). | ||
| /// | ||
| /// # Errors | ||
| /// | ||
|
|
@@ -576,7 +571,7 @@ impl IssueBundle<Signed> { | |
| /// asset in the bundle is incorrect. | ||
| /// * `IssueActionPreviouslyFinalizedAssetBase`: This error occurs if the asset has already been | ||
| /// finalized (inserted into the `finalized` collection). | ||
| /// * `ValueSumOverflow`: This error occurs if an overflow happens during the calculation of | ||
| /// * `ValueOverflow`: This error occurs if an overflow happens during the calculation of | ||
| /// the value sum for the notes in the asset. | ||
| /// * `IssueBundleIkMismatchAssetBase`: This error is raised if the `AssetBase` derived from | ||
| /// the `ik` (Issuance Validating Key) and the `asset_desc` (Asset Description) does not match | ||
|
|
@@ -636,7 +631,7 @@ pub enum Error { | |
| IssueActionPreviouslyFinalizedAssetBase(AssetBase), | ||
|
|
||
| /// Overflow error occurred while calculating the value of the asset | ||
| ValueSumOverflow, | ||
| ValueOverflow, | ||
| } | ||
|
|
||
| impl fmt::Display for Error { | ||
|
|
@@ -672,7 +667,7 @@ impl fmt::Display for Error { | |
| IssueActionPreviouslyFinalizedAssetBase(_) => { | ||
| write!(f, "the provided `AssetBase` has been previously finalized") | ||
| } | ||
| ValueSumOverflow => { | ||
| ValueOverflow => { | ||
| write!( | ||
| f, | ||
| "overflow error occurred while calculating the value of the asset" | ||
|
|
@@ -696,7 +691,7 @@ mod tests { | |
| FullViewingKey, IssuanceAuthorizingKey, IssuanceValidatingKey, Scope, SpendingKey, | ||
| }; | ||
| use crate::note::{AssetBase, Nullifier, Rho}; | ||
| use crate::value::{NoteValue, ValueSum}; | ||
| use crate::value::NoteValue; | ||
| use crate::{Address, Note}; | ||
| use group::{Group, GroupEncoding}; | ||
| use nonempty::NonEmpty; | ||
|
|
@@ -829,7 +824,7 @@ mod tests { | |
| let (asset, supply) = result.unwrap(); | ||
|
|
||
| assert_eq!(asset, test_asset); | ||
| assert_eq!(supply.amount, ValueSum::from_raw(30)); | ||
| assert_eq!(supply.amount, NoteValue::from_raw(30)); | ||
| assert!(!supply.is_finalized); | ||
| } | ||
|
|
||
|
|
@@ -854,7 +849,7 @@ mod tests { | |
| let (asset, supply) = result.unwrap(); | ||
|
|
||
| assert_eq!(asset, test_asset); | ||
| assert_eq!(supply.amount, ValueSum::from_raw(30)); | ||
| assert_eq!(supply.amount, NoteValue::from_raw(30)); | ||
| assert!(supply.is_finalized); | ||
| } | ||
|
|
||
|
|
@@ -975,10 +970,8 @@ mod tests { | |
| assert_eq!(first_note.value().inner(), 15); | ||
| assert_eq!(first_note.asset(), third_asset); | ||
|
|
||
| let reference_notes = bundle.get_reference_notes(); | ||
| assert_eq!(reference_notes.len(), 2); | ||
| verify_reference_note(reference_notes.get(&asset).unwrap(), asset); | ||
| verify_reference_note(reference_notes.get(&third_asset).unwrap(), third_asset); | ||
| verify_reference_note(action.get_reference_note().unwrap(), asset); | ||
| verify_reference_note(action2.get_reference_note().unwrap(), third_asset); | ||
| } | ||
|
|
||
| #[test] | ||
|
|
@@ -1227,17 +1220,33 @@ mod tests { | |
|
|
||
| assert_eq!(supply_info.assets.len(), 3); | ||
|
|
||
| let reference_note1 = signed.actions()[0].notes()[0]; | ||
| let reference_note2 = signed.actions()[1].notes()[0]; | ||
| let reference_note3 = signed.actions()[2].notes()[0]; | ||
|
|
||
| assert_eq!( | ||
| supply_info.assets.get(&asset1_base), | ||
| Some(&AssetSupply::new(ValueSum::from_raw(15), true)) | ||
| Some(&AssetSupply::new( | ||
| NoteValue::from_raw(15), | ||
| true, | ||
| Some(reference_note1) | ||
| )) | ||
| ); | ||
| assert_eq!( | ||
| supply_info.assets.get(&asset2_base), | ||
| Some(&AssetSupply::new(ValueSum::from_raw(10), true)) | ||
| Some(&AssetSupply::new( | ||
| NoteValue::from_raw(10), | ||
| true, | ||
| Some(reference_note2) | ||
| )) | ||
| ); | ||
| assert_eq!( | ||
| supply_info.assets.get(&asset3_base), | ||
| Some(&AssetSupply::new(ValueSum::from_raw(5), false)) | ||
| Some(&AssetSupply::new( | ||
| NoteValue::from_raw(5), | ||
| false, | ||
| Some(reference_note3) | ||
| )) | ||
| ); | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.