Skip to content

Conversation

@danwt
Copy link
Contributor

@danwt danwt commented Jul 4, 2025

Closes #700

Comment on lines 240 to 243
pub fn payload(mut self, payload: Vec<u8>) -> Self {
self.inner_pskt.global.payload = Some(payload);
self
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be wise to keep the underlying signature (Option<Vec<u8>>), some might want to reset payload by setting a None value to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will update

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@danwt danwt requested a review from IzioDev July 14, 2025 11:22
@biryukovmaxim
Copy link
Collaborator

Hello, @danwt great work.
There are some things that should also be done:

  1. version bump. New field makes incompatible at signing and finalization steps. Old clients will make transaction without payload, but new clients will include it.
    So we need to ensure that every combining has the same versions, as well as payload can only be added if version is 2. The same rule for unsigned tx method
  2. Add method should be reflected
    If one of left/right global struct has some payload it should have payload in the output, both none -> None. If they have non equal payloads -> return error.

If overwriting is required - it can be solved via another pr/issue or it should require separate field with vector of payloads so the finalized can combine them properly, or some other deterministic approach. The invariant is left+right==right+left

/// Unknown key-value pairs for this output.
#[serde(flatten)]
pub unknowns: BTreeMap<String, serde_value::Value>,
pub payload: Option<Vec<u8>>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add attribute #[serde(with = "kaspa_utils::serde_bytes_optional")] to serialize it as hex in case of human readable serializer, as well as it has consistency with redeem script serialization

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much for review I'll address soon

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @biryukovmaxim I have updated the pr

- Add Version::One variant to PSKT Version enum for explicit payload support
- Add serde attribute for hex serialization of payload field
- Implement payload combination rules in Global::Add:
  - Both None -> None
  - One has payload -> use that payload
  - Same payload -> use that payload
  - Different payloads -> return PayloadMismatch error
- Add PayloadMismatch error variant to CombineError enum
- Auto-upgrade PSKT version to One when setting payload
- Maintain backward compatibility with Version::Zero (no payload)

These changes address all feedback from the PR review while maintaining
compatibility and proper error handling.
danwt added 3 commits August 14, 2025 17:22
- Changed payload() method to return Result<Self, Error> instead of Self
- Payload can only be set when PSKT version is One or higher (no auto-upgrade)
- Returns PayloadRequiresVersion1 error if attempting to set payload on Version::Zero
- unsigned_tx() now only includes payload when version >= One
- Version combining already fails if versions don't match (no changes needed)

This ensures strict compatibility: old clients (Version::Zero) cannot have payloads,
and combining PSKTs with different versions will fail as expected.
Address reviewer feedback for PSKT payload support
@danwt danwt requested a review from biryukovmaxim August 14, 2025 16:31
// - One has payload -> use that payload
// - Both have same payload -> use that payload
// - Different payloads -> error
self.payload = match (self.payload.clone(), rhs.payload.clone()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use .take instead of clone here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also should return error in case of version<1
Could you also add a set_version method to pskt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR looks legit. What else is pending here @biryukovmaxim @danwt?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on it

@biryukovmaxim
Copy link
Collaborator

LGTM,
cc. @coderofstuff

@coderofstuff coderofstuff removed the request for review from IzioDev September 2, 2025 15:55
@coderofstuff
Copy link
Collaborator

Looks good. @danwt Please merge or rebase with latest master

@coderofstuff coderofstuff merged commit a5fe224 into kaspanet:master Sep 4, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add tx.payload support for PSKT constructions

4 participants