Skip to content

SIMD-0258: Signatures sysvar for signature introspection #262

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

ultd
Copy link

@ultd ultd commented Mar 14, 2025


simd: 0258
title: Signatures sysvar for signatures introspection
authors: Ahmad Abbasi (Syndica)
category: Standard
type: Core
status: Review
created: 2025-03-14


Summary

Allow the ability to introspect a transaction's signatures within an instruction via a Signatures sysvar.

Motivation

As we develop the Sig validator, we've experimented with novel ways an on-chain protocol can be designed. Many of those designs require some source of sequencing. Along with the need for a sequencing mechanism, the ability to query previous sequence "entries" is also important. Today, the only viable way to accomplish retrieving previous sequence entries is to use getSignaturesForAddress RPC and then parse through transactions individually to find the ones which create the next/previous "entry." If you have access to a transaction's signature within an instruction, you're able to save that into an account which can be used down the line to retrieve past entries.

New Terminology

  • Signatures sysvar: A Solana runtime sysvar which provides the ability to read a transaction's signatures within an instruction.

Detailed Design

In order to introspect transaction signatures within an instruction, a transaction MUST include the Signatures sysvar (SysvarSignatures111111111111111111111111111) in the accounts list. The runtime will recognize this special sysvar, pass the raw transaction signatures to the instruction so that the bpf program can extract them and use as needed.

A helper function to extract the signatures can be used:

fn load_signatures(signatures_sysvar_account_info: &AccountInfo) -> Result<&[Signature]>;

Alternatives Considered

Currently, no alternative exists to introspect a transaction's signature from within an instruction.

Impact

The impact of this will allow for unique and bespoke protocols to emerge on Solana enabling a new subset of sequence-based and hybrid (on/off-chain) applications to exist.

Security Considerations

Because Sysvar(s) are inherently read-only, no major security concerns would arise from this feature. We already allow instruction data introspection via Sysvar1nstructions1111111111111111111111111 sysvar.

@ultd ultd changed the title SIMD-0258: Signatures sysvar for signatures introspection SIMD-0258: Signatures sysvar for signature introspection Mar 14, 2025
@deanmlittle
Copy link
Contributor

Hi there. I actually already wrote this two years ago: deanmlittle/solana@fe6f4ba

I also discussed it in the Solana discord. A lot of people didn't understand it or think there was a use case for it, but also didn't think it would be harmful. I hope the sentiment has changed now! There are actually many interesting use cases for it, such as using tx signatures as the indexing mechanism for generalised state compression, or induction proofs enabling you to prove something happened in a previous transaction, essentially making the Solana ledger itself turing complete.

The main thing that I would say in my conversations with others about it is that you probably also want to have the blockhash used in the transaction accessible, so maybe it's best to not just do "SignatureSyvar" but to choose a name that would be inclusive of the blockhash, as without it, you are still missing one crucial piece to recreate transactions onchain (instruction sysvar doesn't include it), and it seems too wasteful to split into a second sysvar account.

Would be super happy to help in any way to get this to pass!

@t-nelson
Copy link
Contributor

i'd rather see this as a more generic "transaction introspection" sysvar than a one-off for signatures. people have been asking for access to other transaction properties like fee-payer and total fee

@deanmlittle
Copy link
Contributor

deanmlittle commented Mar 21, 2025

i'd rather see this as a more generic "transaction introspection" sysvar than a one-off for signatures. people have been asking for access to other transaction properties like fee-payer and total fee

Is the TX fee part necessary? Total fee can be found from number of signatures + fee request ix in InstructionsSysvar. Is there anything else that would be required? The only part of a TX that isn't currently able to be introspected is signatures and blockhash.

@zfedoran
Copy link

I echo others in the thread, I would be happy to have access to nothing more than the full serialized Transaction struct bytes, without any extra introspection bells or whistles.

With this, devs would have the ability to create conditional transactions— transactions that depend on the success of a previous transaction. Conditional payments could be done with a cleaner interface. Merkle compressed state could have signatures added. We could build linked lists of transactions with the current tail signature written to an account. We could create virtualized transaction processing steps, etc...

Over the last few years, I've tossed out half a dozen novel ideas that would have been made easier or feasible if only I could access the signature.

I've even gone down the rabbit hole of creating in-flight signature signing with the edwards curves syscalls and sending ephemeral private keys to sign a pseudo transaction in the actual transaction to sort of mimic this...

Please consider this improvement. It feels like a fundamental oversight that this is still missing.

@topointon-jump
Copy link

Could this be a syscall instead? If the main use-case is accessing the information inside the VM. Sysvars are slightly more complicated to design and have more performance implications, as they are included in the bank hash.

Would a syscall that just exposed this information inside the VM suffice, or are there use-cases that would require a sysvar?

@deanmlittle
Copy link
Contributor

Could this be a syscall instead? If the main use-case is accessing the information inside the VM. Sysvars are slightly more complicated to design and have more performance implications, as they are included in the bank hash.

Would a syscall that just exposed this information inside the VM suffice, or are there use-cases that would require a sysvar?

In most cases, you just want the first signature, but in some cases, you want all of them. If you go the syscall route, you end up making multiple syscalls which is an anti-pattern. If you're always exposing the first signature, you may as well expose the rest of the information that isn't available at execution. If you do that all in a single syscall, you're forcing the user to copy and store a bunch of data, potentially blowing up their stack. If you just use a single sysvar, you can more or less copy verbatim what was done for InstructionsSysvar and allow the user to pick and choose what they want. I think a Sysvar makes a lot more sense. If there were a good argument to the contrary, I'd argue we should then throw in a SIMD to make instructions work the same way.

@t-nelson
Copy link
Contributor

Is the TX fee part necessary? Total fee can be found from number of signatures + fee request ix in InstructionsSysvar.

for the sake of forward thinking to a day where we have compute budget info encoded directly in the tx header and are freed from the compute budget program and its overhead, it may makes sense for compatibility

we'd deprecate the ix sysvar

Is there anything else that would be required? The only part of a TX that isn't currently able to be introspected is signatures and blockhash.

can't see the fee-payer, though technically this can be resolved via creative instruction construction. same of "other" accounts not specified by the instruction. position in the header, too.

does ix sysvar not only give you previous + current ix? i can never remember. that would preclude determining fee of a tx that appends it's cbp ixes.

Could this be a syscall instead? If the main use-case is accessing the information inside the VM. Sysvars are slightly more complicated to design and have more performance implications, as they are included in the bank hash.

Would a syscall that just exposed this information inside the VM suffice, or are there use-cases that would require a sysvar?

i don't think it would really make sense to persist this "sysvar." it would be ephemeral like the instructions sysvar

@topointon-jump
Copy link

i don't think it would really make sense to persist this "sysvar." it would be ephemeral like the instructions sysvar

agreed 💯

@austbot
Copy link

austbot commented Mar 21, 2025

@deanmlittle the tx fee is needed because it would be amazing to know what the priority fee for the transaction was, or rather the total fee, signatures + prio.

Useful in cases where I want to refund the feepayer or take action on my protocol in certain fee scenarios

@ultd
Copy link
Author

ultd commented Mar 21, 2025

I echo others in the thread, I would be happy to have access to nothing more than the full serialized Transaction struct bytes, without any extra introspection bells or whistles.

In response to above, I agree with @deanmlittle's statement:

If you do that all in a single syscall, you're forcing the user to copy and store a bunch of data, potentially blowing up their stack. If you just use a single sysvar, you can more or less copy verbatim what was done for InstructionsSysvar and allow the user to pick and choose what they want.

In response to @t-nelson:

can't see the fee-payer, though technically this can be resolved via creative instruction construction. same of "other" accounts not specified by the instruction. position in the header, too.

does ix sysvar not only give you previous + current ix? i can never remember. that would preclude determining fee of a tx that appends it's cbp ixes.

You can get the current ix index and are able to get any other instruction by index to my understanding. Yes you can technically calculate it but wouldn't be ideal.

I think it makes sense exposing individual sysvars that allow users to pick and choose what data they want, at least when it comes to instruction and signatures data. I suppose the "Signatures" sysvar could be the "Meta" sysvar which can include meta data about the transaction such as blockhash, signatures and message header?

@t-nelson
Copy link
Contributor

I think it makes sense exposing individual sysvars

this is not zero cost. we want as few sysvars/syscalls as possible. the runtime complexity is not worth it

@ultd
Copy link
Author

ultd commented Mar 22, 2025

this is not zero cost. we want as few sysvars/syscalls as possible. the runtime complexity is not worth it

Agreed, then we stick to two? Instruction and signatures/meta sysvar. I think forcing a TX to copy all ixs data if you're only needing the signature(s) is a bigger hit on the runtime perf than just having two individual sysvars

@topointon-jump
Copy link

Yep, we want to make this sysvar as small as possible whilst including all the information the user needs.

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.

6 participants