Conversation
| /// - Note can be partially or fully filled by consumers | ||
| /// - Unfilled portions create remainder notes | ||
| /// - Creator receives requested assets via P2ID notes | ||
| pub struct PswapNote; |
There was a problem hiding this comment.
Since we're adding this as a completely new note, it would be great if we could immediately set it up with the structure we want to end up with, i.e. the one described in #2283.
So roughly:
pub struct PswapNoteStorage {
requested_key: Word,
requested_value: Word,
swapp_tag: NoteTag,
p2id_tag: NoteTag,
swap_count: u64,
creator_account_id: AccountId,
}
impl PswapNoteStorage {
pub fn into_recipient(self, serial_num: Word) -> NoteRecipient {
todo!()
}
}
impl From<PswapNoteStorage> for NoteStorage {
fn from(pswap_storage: PswapNoteStorage) -> Self {
todo!()
}
}
#[derive(Debug, Clone, bon::Builder)]
#[builder(finish_fn(vis = "", name = build_internal))]
pub struct PswapNote {
sender: AccountId,
storage: PswapNoteStorage,
serial_number: Word,
#[builder(default = NoteType::Private)]
note_type: NoteType,
#[builder(default)]
assets: NoteAssets,
#[builder(default)]
attachment: NoteAttachment,
}
impl PswapNote {
pub fn execute(
&self,
consumer_account_id: AccountId,
input_amount: u64,
inflight_amount: u64,
) -> Result<(Note, Option<PswapNote>), NoteError> {
todo!("what create_output_notes does now")
}
}This would result in a more natural API, i.e. execute takes &self instead of create_output_notes taking an arbitrary &Note.
What do you think?
There was a problem hiding this comment.
Yes, agree to this.
I have made the change.
c04d47c to
0f1b15b
Compare
0f1b15b to
b664dd4
Compare
PhilippGackstatter
left a comment
There was a problem hiding this comment.
Looks good, thank you! I primarily looked at the Rust code for now and left a few comments, but on a high level:
- I think we should use the builder-style way of creating
PswapNoteandPswapNoteStorage, since both have quite a few fields. - Some lints are failing (see CI or run
make lintlocally). - If this PR is ready for review, can we put it ouf of draft mode?
- Nits: Would be nice to use attachment instead of aux, storage instead of inputs, sender instead of creator, etc.
| /// Builds a P2ID payback note that delivers the filled assets to the swap creator. | ||
| /// | ||
| /// The note inherits its type (public/private) from this PSWAP note and derives a | ||
| /// deterministic serial number via `hmerge(swap_count + 1, serial_num)`. | ||
| pub fn build_p2id_payback_note( |
There was a problem hiding this comment.
Nit: I'd change build_ to create_ for consistency with P2idNote::create, PswapNote::create, etc. Applies to build_remainder_pswap_note and build_tag as well. (Not for this PR, but we should eventually rename SwapNote::build_tag as well).
| pub fn create<R: FeltRng>( | ||
| creator_account_id: AccountId, | ||
| offered_asset: Asset, | ||
| requested_asset: Asset, | ||
| note_type: NoteType, | ||
| note_attachment: NoteAttachment, | ||
| rng: &mut R, | ||
| ) -> Result<Note, NoteError> { |
There was a problem hiding this comment.
As motivated in #2283, I think we should get rid of this method and steer users towards using the builder methods to create notes.
This requires adding a public build method which we could do like this:
// Use a custom build method for custom validation.
impl<S: IsComplete> PswapNoteBuilder<S> {
pub fn build(self) -> Result<PswapNote, NoteError> {
let note = self.build_internal();
// TODO: Validate note if needed.
// We should probably validate the number of assets here, for instance.
Ok(note)
}
}…MS, remove create_ wrappers, add builder finish_fn - Rename swapp_tag -> pswap_tag and SWAPp -> PSWAP throughout - Rename NUM_ITEMS -> NUM_STORAGE_ITEMS for clarity - Remove create_p2id_payback_note and create_remainder_note wrappers, make build_ functions public instead - Compute p2id_tag inside build_p2id_payback_note from self.storage - Add #[builder(finish_fn(vis = "", name = build_internal))] to PswapNote
…ctly Replace all test helper wrappers with direct calls to library functions: - create_pswap_note -> PswapNote::create() - create_expected_pswap_p2id_note + create_expected_pswap_remainder_note -> pswap.execute() - build_pswap_storage -> PswapNoteStorage::from_parts() - Remove make_pswap_tag, make_note_assets, make_note_args, compute_p2id_tag_* - Inline calculate_output_amount as PswapNote::calculate_output_amount()
- Replace storage layout list with markdown table - Remove trivial "Returns the X" docs on simple getters - Add # Errors sections where relevant - Rewrite method docs to describe intent, not implementation - Add one-line docs on From/TryFrom conversion impls - Tighten PswapNote struct doc
- Rename RpoRandomCoin to RandomCoin (miden-crypto 0.23 rename) - Store full ASSET_KEY instead of prefix/suffix to preserve callback metadata in faucet_id_suffix_and_metadata - Replace create_fungible_asset calls with direct ASSET_KEY + manual ASSET_VALUE construction, avoiding the new enable_callbacks parameter - Update hardcoded P2ID script root to match current P2idNote::script_root()
- Replace hardcoded P2ID script root with procref.p2id::main for compile-time resolution - Default to full fill when both input and inflight amounts are zero - Replace magic address 4000 with named P2ID_RECIPIENT_STORAGE constant - Remove step numbering from comments, fix memory layout docs
- Rename P2ID_RECIPIENT_STORAGE to P2ID_RECIPIENT_SUFFIX/PREFIX - Add METADATA_HEADER word layout docs with source reference - Document attachment_scheme parameter in set_word_attachment call - Add stack views after condition checks
…lper, simplify build_p2id_payback_note Rename requested_key/requested_value/requested_amount to requested_asset_key/requested_asset_value/requested_asset_amount for clarity. Extract offered_asset_amount() helper on PswapNote to deduplicate offered asset extraction. Simplify build_p2id_payback_note to take fill_amount: u64 instead of aux_word: Word, constructing the aux word internally.
- Use NoteTag::default() instead of NoteTag::new(0) - Change swap_count from u64 to u16 with safe try_into conversion - Rename p2id_tag to payback_note_tag, p2id_payback_note to payback_note - Rename build_ prefix to create_ for consistency - Rename aux_word to attachment_word - Replace Felt::new with Felt::from where possible - Rename inputs to note_storage in TryFrom impl - Make create_payback_note and create_remainder_pswap_note private - Add offered_faucet_id helper to replace unreachable!()
- Remove PswapNote::create, add public build() with validation on builder - Add bon::Builder to PswapNoteStorage, remove new() and from_parts() - Remove payback_note_tag field, compute from creator_account_id on the fly - Fix clippy warnings (useless conversions, needless borrows) - Update all unit and integration tests to use builder pattern
- Compare full faucet_id instead of just prefix in build validation - Rename swap_note to pswap_note in integration tests for consistency - Extract PswapNoteStorage builder into separate let bindings - Replace manual current_swap_count counter with enumerate index - Fix clippy useless_conversion and needless_borrow warnings
5eb3cc0 to
1780388
Compare
Add PSWAP (partially-fillable swap) note to miden-standards — a new note script that enables partial
fills, creator reclaim, and inflight cross-swaps for decentralized asset exchange
1e5 precision factor, and an early-return optimization for full fills to avoid integer truncation
remainder), storage parsing, and calculate_offered_for_requested convenience method
reclaim, invalid input rejection, multiple fill amounts, non-exact ratios, fuzz cases, and chained
partial fills
Test plan
calculation, storage parsing)
reclaim, fuzz, chained fills)