Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@samkim-crypto
Copy link
Contributor

@samkim-crypto samkim-crypto commented Aug 27, 2025

Problem

There are a number of proposed changes to the bn128 syscall (SIMD-0284, 0334, and also issues discussed in #267). Making these breaking changes are difficult because these changes have to be feature-gated in agave. Instead of making changes to the original function, we have to define a new function with the updated changes in order to properly feature gate the change (example).

Whenever there are new changes, we have to come up with alternate names for the new functions, which makes the functions in this crate inconsistent. This can also be confusing to developers who have to decipher which functions they have to use.

For the most part, a syscall implementation should rarely be updated. But since there are a number of changes lined up for the bn128 syscall, it would be nice to have a more modular way of defining the functions so that upgrading is easy.

Summary of Changes

I took a stab at modularizing the addition, multiplication, and pairing syscalls. For the addition, multiplication, and pairing functions, I created a enums Versioned{Addition, Multiplication, Pairing} enums and versioned_{addition, multiplication, pairing} functions.

These enums and functions are re-exported out as part of the validator module. Whenever a breaking change is to be made to the syscalls, one should define a new version variant for the enum and then scope the change with this variant in the versioned_{addition, multiplication, pairing} functions.

Then, in the validator implementation, we can feature gate the change with the versioning:

if feature_gate_active {
    versioned_addition(VersionedAddition::V1, ...)
} else {
    versioned_addition(VersionedAddition::V0, ...)
}

I just made the changes to the addition, multiplication, and pairing submodules for now. I don't think there are any immediate breaking changes pending for the compression and decompression syscalls, so we might not need such refactoring for the compression module, but I'll consider it again after this PR.

@samkim-crypto samkim-crypto marked this pull request as ready for review August 27, 2025 04:42
_version: VersionedMultiplication,
input: &[u8],
endianness: Endianness,
expected_length: usize,
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it be better to "move" expected_length to a version? If versioned_multiplication is public, this parameter can create confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point! I absorbed the length into the version as you suggested.

///
/// Developers should be extremely careful when modifying this function, as a breaking change
/// can result in a fork in the Solana cluster. Any such change requires an
/// approved Solana SIMD. Subsequently, a new `VersionedAddition` variant must be added,
Copy link
Contributor

Choose a reason for hiding this comment

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

VersionedAddition -> VersionedMultiplication

///
/// Developers should be extremely careful when modifying this function, as a breaking change
/// can result in a fork in the Solana cluster. Any such change requires an
/// approved Solana SIMD. Subsequently, a new `VersionedAddition` variant must be added,
Copy link
Contributor

Choose a reason for hiding this comment

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

VersionedAddition -> VersionedPairing

#[inline(always)]
pub fn alt_bn128_multiplication_128(input: &[u8]) -> Result<Vec<u8>, AltBn128Error> {
versioned_multiplication(VersionedMultiplication::V0, input, Endianness::BE)
// hard-code length; we will remove this function in the future
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this comment below the code?

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 ended up removing this comment actually since we don't hardcode the length as a function parameter any more.

@samkim-crypto samkim-crypto force-pushed the bn254-refactor-validator branch from fa33617 to 0283595 Compare August 27, 2025 14:54
@LStan
Copy link
Contributor

LStan commented Aug 29, 2025

Couple of thoughts:

  1. When SIMD-0334 is implemented, how alt_bn128_pairing will be changed? target_os = "solana" part can be easily changed, but not(solana) can't be changed because it is used in the validator. Or when updating the dependency in the validator, new versioned_* functions will be used? Maybe it is better to deprecate old functions for not(solana) and recommend to use `versioned_* ones for everyone?
  2. Naming. All functions have alt_bn128 prefix. Maybe this prefix should also be added to the versioned_* functions? Also there is SIMD-0302 that suggests adding g2 addition and multiplication. Maybe add g1 to the current versioned_* functions? So the names will be alt_bn128_versioned_g1_addition, alt_bn128_versioned_g1_multiplication, alt_bn128_versioned_pairing

Copy link
Collaborator

@joncinque joncinque left a comment

Choose a reason for hiding this comment

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

Looks great! Just the one nit

bn254/src/lib.rs Outdated
/// This module contains the versioned syscall implementations and is intended for use
/// primarily by validator code.
#[cfg(not(target_os = "solana"))]
pub mod validator {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: how about just calling this versioned? That seems clearer than validator

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, okay. Updated!

Comment on lines 25 to 27
pub enum VersionedAddition {
V0,
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I was reading through the SIMDs, but just so I'm sure I understand -- is the plan to add a V1 for the BE length check?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the plan is to add V1 and then require that the input length is strictly 128 bytes (ALT_BN128_ADDITION_INPUT_LEN) for BE addition.

@samkim-crypto
Copy link
Contributor Author

  1. When SIMD-0334 is implemented, how alt_bn128_pairing will be changed? target_os = "solana" part can be easily changed, but not(solana) can't be changed because it is used in the validator. Or when updating the dependency in the validator, new versioned_* functions will be used? Maybe it is better to deprecate old functions for not(solana) and recommend to use `versioned_* ones for everyone?

Yes, as you described, my plan was to update agave code so that the new versioned_* functions are used for the syscall. Then we can easily feature gate upcoming changes by using the Versioned* enum.

I kept the not(solana) function so that downstream projects that wishes to invoke the same function as the validator syscall but off-chain, maybe on the client side.

  1. Naming. All functions have alt_bn128 prefix. Maybe this prefix should also be added to the versioned_* functions? Also there is SIMD-0302 that suggests adding g2 addition and multiplication. Maybe add g1 to the current versioned_* functions? So the names will be alt_bn128_versioned_g1_addition, alt_bn128_versioned_g1_multiplication, alt_bn128_versioned_pairing

These are good ideas. When I was refactoring, I was hoping that the submodule would already scope the functions appropriately, but I ended up re-exporting all the functions as is. I'll add the prefix and also specify the group in the function names.

@LStan
Copy link
Contributor

LStan commented Sep 3, 2025

Yes, as you described, my plan was to update agave code so that the new versioned_* functions are used for the syscall. Then we can easily feature gate upcoming changes by using the Versioned* enum.

I kept the not(solana) function so that downstream projects that wishes to invoke the same function as the validator syscall but off-chain, maybe on the client side.

But will alt_bn128_pairing for not(solana) be changed to use VersionedPairing::V1 when implementing SIMD-0334? Because if yes, then if somebody updates version to 3.1 in the validator without changing to versioned_ functions, it will break. So this probably should happen in version 4. Or maybe I'm just overcomplicating.

@samkim-crypto
Copy link
Contributor Author

Yes, as you described, my plan was to update agave code so that the new versioned_* functions are used for the syscall. Then we can easily feature gate upcoming changes by using the Versioned* enum.
I kept the not(solana) function so that downstream projects that wishes to invoke the same function as the validator syscall but off-chain, maybe on the client side.

But will alt_bn128_pairing for not(solana) be changed to use VersionedPairing::V1 when implementing SIMD-0334? Because if yes, then if somebody updates version to 3.1 in the validator without changing to versioned_ functions, it will break. So this probably should happen in version 4. Or maybe I'm just overcomplicating.

Yeah I think this is fine. As soon as the changes are in v3.1, I can create a PR on the agave side to update the syscall to use the versioned functions.

@samkim-crypto samkim-crypto merged commit 519c7d5 into anza-xyz:master Sep 12, 2025
25 checks passed
febo pushed a commit to febo/solana-sdk that referenced this pull request Sep 21, 2025
… `validator` and `prelude` modules (anza-xyz#297)

* refactor addition, multiplication, and pairing functions into validator and prelude modules

* remove `expected_length` parameter in `versioned_multiplication`

* fix typos

* remove comment on hard-coded length

* rename `validator` to `versioned`

* add `alt_bn128_` prefix to functions and identify group in function names
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.

3 participants