Skip to content

Add support for V1 transactions#531

Closed
grod220 wants to merge 9 commits into
masterfrom
v1-tx
Closed

Add support for V1 transactions#531
grod220 wants to merge 9 commits into
masterfrom
v1-tx

Conversation

@grod220
Copy link
Copy Markdown
Contributor

@grod220 grod220 commented Jan 15, 2026

Reference: SIMD-0296 & SIMD-0385

Add V1 transaction format

V1 transactions increase the maximum transaction size from 1232 bytes to 4096 bytes and embed compute budget configuration directly in the message header, eliminating the need for separate ComputeBudget program instructions.

Changes

New module (message/src/versions/v1/):

  • message.rs: core Message struct
  • config.rs: ComputeBudgetConfig and ComputeBudgetConfigMask for inline compute budget
  • serialization.rs: custom binary serialization/deserialization
  • runtime.rs: LoadedMessage wrapper with precomputed writability for runtime
  • builder.rs: builder API for constructing messages
  • constants.rs: format limits and sizes
  • error.rs: deserialization error types

New module (transaction/src/v1.rs):

  • Transaction: transaction wrapper combining Message with signatures
  • Custom wire format: [message bytes][signatures] (no signature length prefix)

@grod220 grod220 requested a review from a team as a code owner January 15, 2026 00:16
@grod220 grod220 requested a review from tao-stones January 15, 2026 00:17
Comment thread packet/src/lib.rs
Comment thread message/src/versions/v1/config.rs Outdated
Comment thread transaction/src/v1.rs Outdated
Comment thread transaction/src/v1.rs Outdated
/// Create a V1 transaction from a message and existing signatures.
///
/// Returns an error if the signature count doesn't match `num_required_signatures`.
pub fn from_signatures(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

try to think if there are use cases for this, is it for tests only?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thinking offline signing/multisig workflows, but realizing the current struct has public fields. So this method is sort of optional right now. However, constructing manually gets around the validation check. Leaning toward making these fields private and forcing method construction. What do you think?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It makes sense to keep fields private and do "raw" construction via this api.

My train-of-thoughts is: V1::Transaction type is temporarily; it will, or can, be merged into Transaction - after all, they have same structure; but managing APIs might be bit messy. That's why I feel don't need to introduce from_signature(), but keep fields public as legacy/v0 Transactions currently are.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@febo subbing you in if that's ok! 🙏

Totally open for whatever API design changes ya'll find are best.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@tao-stones Made the fields public and removed from_signatures.

Comment thread transaction/src/v1.rs Outdated
Comment thread transaction/src/v1.rs Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think the actual VersionedTransaction needs to be modified. As is, the signatures would still be at the front of the serialized bytes, right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

in current impl, v1::Transaction::serialize() puts sigs after message. But if we don't introduces V1::Transaction as new type, then (de)ser for v1 can happen elsewhere.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

right but for it to actually work in validator we need VersionedTransaction; or we've got to change over to some new type wrapping the different message types - which imo doesn't make much sense

Comment thread transaction/src/v1.rs
/// - Signatures are appended directly with NO length prefix
/// - Signature count is determined by `num_required_signatures` from the message header
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Transaction {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what do you think about not having V1::Transaction? So from user perspective, using bench-tps as example, it only knows one transaction type that is solana-transaction::Transaction, which can be constructed from V1::Message, then goes through same Transaction -> VersionTransaction -> SanitizedVersionTransaction lifespan. In another words, we only introduce new Message v1, and Transaction (somewhat) automatically supports that. @febo

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Makes sense to me. We would need to make Transaction generic over Message right? Seems like VersinedTransaction and SanitizedVersionedTransaction would be fine since they use enum representations for the message.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Transaction is the wrong type I think. It only supports Legacy iirc.

VersionedTransaction, SanitizedVersionedTransaction, SanitizedTransaction are what we need to work if we want a drop in replacement in the validator (ignoring users for my perspective only).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Those ones should support V1 with the changes on this PR. But Transaction is being duplicated at the moment. Perhaps we don't need the duplication after all?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yea, remove (or "merge") duplicated "Transaction" is what I was thinking.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Those ones should support V1 with the changes on this PR.

I think the Message types are correctly handled, but VersionedTransaction doesn't have a new variant afaict, so don't see how that could be working given the format difference in signature placement (leading vs trailing)

Copy link
Copy Markdown
Contributor

@febo febo Jan 22, 2026

Choose a reason for hiding this comment

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

VersionedTransaction uses VersionedMessage, which has a variant for V1. So you can create a new one VersionedTransaction::try_new passing a VersionedMessage::V1.

I see what you mean now. That has to change indeed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@tao-stones I am reworking the implementation to avoid so much duplication and address Andrew's comment. I will put a separate PR with it and then we can decide which approach works best.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thanks @febo

@febo
Copy link
Copy Markdown
Contributor

febo commented Feb 5, 2026

Closed in favour of #538

@febo febo closed this Feb 5, 2026
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.

4 participants