From 4052238e109eb5d21b7d4d316b847e2e0b2d4fcb Mon Sep 17 00:00:00 2001 From: Joe C Date: Tue, 26 Mar 2024 16:11:17 -0500 Subject: [PATCH 1/9] syscall: get epoch stake --- proposals/0133-syscall-get-epoch-stake.md | 106 ++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 proposals/0133-syscall-get-epoch-stake.md diff --git a/proposals/0133-syscall-get-epoch-stake.md b/proposals/0133-syscall-get-epoch-stake.md new file mode 100644 index 00000000..36bb1322 --- /dev/null +++ b/proposals/0133-syscall-get-epoch-stake.md @@ -0,0 +1,106 @@ +--- +simd: '0133' +title: Syscall Get-Epoch-Stake +authors: + - Joe Caulfield (Anza) +category: Standard +type: Core +status: Draft +created: 2024-03-25 +feature: (fill in with feature tracking issues once accepted) +--- + +## Summary + +A syscall to retrieve a vote account's delegated stake for the current epoch. + +## Motivation + +Currently, on-chain programs have no knowledge of the current epoch's stake and +how much active stake is delegated to a certain vote account. + +If this data was available for querying by on-chain programs, it would unblock +many use cases, such as validator governance and secondary consensus mechanisms, +that were previously not possible on Solana. + +Additionally, this would enable the Feature Gate program defined in +[SIMD 0089](./0089-programify-feature-gate.md) to tally vote account stake in +support for a pending feature gate. + +## Alternatives Considered + +An alternative design has been proposed in the past for using an on-chain sysvar +account to store all of the current epoch's stake. It was proposed in +[SIMD 0056](https://github.com/solana-foundation/solana-improvement-documents/pull/56). + +Using a sysvar account to store even just the current epoch's stake introduces a +size limitation on the number of entries that can be stored, which the number of +validators on Solana could surpass in the future. + +By offering access to this information through only a syscall, we can avoid this +account maximum size constraint. However, the syscall approach also makes the +data more cumbersome to retrieve off-chain than the sysvar approach. + +While retrieving this data off-chain may not be straightforward, it remains +entirely feasible. Conversely, on-chain programs currently do not have this +capability at all. + +## New Terminology + +N/A. + +## Detailed Design + +The specification for the proposed syscall is as follows: + +```c +/** + * Retrieves the total active stake delegated to a vote account for the current + * epoch. + * + * @param var_addr VM memory address to copy the retrieved data to. + * @param vote_address The vote account whose stake to query. + * @return A 64-bit unsigned integer error code: + * - 0 if the operation is successful. + * - Non-zero error code. + * + * If the operation is not successful, data will not be written to the + * provided VM memory address. + */ +uint64_t sol_get_epoch_stake( + /* r1 */ uint8_t * var_addr, + /* r2 */ void const * vote_address, +); +``` + +`var_addr` must be the starting address of at least 8 bytes of writable VM +memory to store the `u64` response. If not, the syscall will return an error. + +If the provided vote address corresponds to an account that is not a vote +account or does not exist, the syscall will write `0` for active stake. + +The `InvokeContext` must be modified to store a pointer to the epoch's current +stake, which will be used to obtain the query response for the syscall. The +epoch's current stake should be a collection of fixed-size elements of the +following structure: + +- 32 bytes for the vote address. +- 8 bytes for the delegated stake. + + +## Impact + +This new syscall directly unlocks highly relevant network data for a wide range +of protocols. Developers seeking to access vote account stake will be positively +impacted. + +## Security Considerations + +This new syscall introduces the same security considerations as the rest of the +syscalls in the existing interface, which manipulate raw pointers to VM memory +and must be implemented with care. + +A potential pitfall in the implementation could come when comparing the act of +writing a `0` to the VM memory for active stake versus returning a `0` for +success. The two should not be conflated. + From f5b9bc4f271b16a49bd5f2322ffcff73e5b1703f Mon Sep 17 00:00:00 2001 From: Joe C Date: Tue, 26 Mar 2024 16:12:11 -0500 Subject: [PATCH 2/9] specify access violation --- proposals/0133-syscall-get-epoch-stake.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/0133-syscall-get-epoch-stake.md b/proposals/0133-syscall-get-epoch-stake.md index 36bb1322..33e40b00 100644 --- a/proposals/0133-syscall-get-epoch-stake.md +++ b/proposals/0133-syscall-get-epoch-stake.md @@ -74,7 +74,8 @@ uint64_t sol_get_epoch_stake( ``` `var_addr` must be the starting address of at least 8 bytes of writable VM -memory to store the `u64` response. If not, the syscall will return an error. +memory to store the `u64` response. If not, the syscall will abort the VM with +an access violation. If the provided vote address corresponds to an account that is not a vote account or does not exist, the syscall will write `0` for active stake. From 305babca9ce15c5aa535000b0b3d9fdb274b5a45 Mon Sep 17 00:00:00 2001 From: Joe C Date: Tue, 26 Mar 2024 16:12:40 -0500 Subject: [PATCH 3/9] remove invoke context implementation details --- proposals/0133-syscall-get-epoch-stake.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/proposals/0133-syscall-get-epoch-stake.md b/proposals/0133-syscall-get-epoch-stake.md index 33e40b00..2a984135 100644 --- a/proposals/0133-syscall-get-epoch-stake.md +++ b/proposals/0133-syscall-get-epoch-stake.md @@ -80,15 +80,6 @@ an access violation. If the provided vote address corresponds to an account that is not a vote account or does not exist, the syscall will write `0` for active stake. -The `InvokeContext` must be modified to store a pointer to the epoch's current -stake, which will be used to obtain the query response for the syscall. The -epoch's current stake should be a collection of fixed-size elements of the -following structure: - -- 32 bytes for the vote address. -- 8 bytes for the delegated stake. - - ## Impact This new syscall directly unlocks highly relevant network data for a wide range From 83fc06b102b8568ee80c28f2dd86996764e0e263 Mon Sep 17 00:00:00 2001 From: Joe C Date: Tue, 26 Mar 2024 19:18:25 -0500 Subject: [PATCH 4/9] clarifying changes --- proposals/0133-syscall-get-epoch-stake.md | 42 +++++++++++------------ 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/proposals/0133-syscall-get-epoch-stake.md b/proposals/0133-syscall-get-epoch-stake.md index 2a984135..afeba6b4 100644 --- a/proposals/0133-syscall-get-epoch-stake.md +++ b/proposals/0133-syscall-get-epoch-stake.md @@ -17,9 +17,9 @@ A syscall to retrieve a vote account's delegated stake for the current epoch. ## Motivation Currently, on-chain programs have no knowledge of the current epoch's stake and -how much active stake is delegated to a certain vote account. +how much active stake is delegated to any vote account. -If this data was available for querying by on-chain programs, it would unblock +If this data were available for querying by on-chain programs, it would unblock many use cases, such as validator governance and secondary consensus mechanisms, that were previously not possible on Solana. @@ -29,21 +29,20 @@ support for a pending feature gate. ## Alternatives Considered -An alternative design has been proposed in the past for using an on-chain sysvar -account to store all of the current epoch's stake. It was proposed in -[SIMD 0056](https://github.com/solana-foundation/solana-improvement-documents/pull/56). +[SIMD 0056](https://github.com/solana-foundation/solana-improvement-documents/pull/56) +proposes using an on-chain sysvar account to store all of the current epoch's +stake. -Using a sysvar account to store even just the current epoch's stake introduces a -size limitation on the number of entries that can be stored, which the number of -validators on Solana could surpass in the future. +Because account data is finite, using a sysvar account to store even just the +current epoch's stake limits the number of entries that can be stored. The +amount of validators in one Solana cluster could surpass this number in the +future. -By offering access to this information through only a syscall, we can avoid this -account maximum size constraint. However, the syscall approach also makes the -data more cumbersome to retrieve off-chain than the sysvar approach. - -While retrieving this data off-chain may not be straightforward, it remains -entirely feasible. Conversely, on-chain programs currently do not have this -capability at all. +Exposing epoch-stake information through a syscall avoids this account maximum +size constraint. While the syscall approach does not offer the easy off-chain +retrieval of a sysvar, there are existing ways to get epoch-stake data off +chain. The priority of a new design should be making the data available to +on-chain programs. ## New Terminology @@ -59,7 +58,7 @@ The specification for the proposed syscall is as follows: * epoch. * * @param var_addr VM memory address to copy the retrieved data to. - * @param vote_address The vote account whose stake to query. + * @param vote_address A pointer to 32 bytes representing the vote address. * @return A 64-bit unsigned integer error code: * - 0 if the operation is successful. * - Non-zero error code. @@ -73,18 +72,17 @@ uint64_t sol_get_epoch_stake( ); ``` -`var_addr` must be the starting address of at least 8 bytes of writable VM -memory to store the `u64` response. If not, the syscall will abort the VM with -an access violation. +`var_addr` must be the starting address of 8 bytes of writable VM memory to +store the `u64` response. If not, the syscall will abort the VM with an access +violation. If the provided vote address corresponds to an account that is not a vote account or does not exist, the syscall will write `0` for active stake. ## Impact -This new syscall directly unlocks highly relevant network data for a wide range -of protocols. Developers seeking to access vote account stake will be positively -impacted. +Dapp developers will be able to query vote account stake for the current epoch +from within on-chain programs. ## Security Considerations From e6a7c9a30493092c115a4308450cc05fa8e228e1 Mon Sep 17 00:00:00 2001 From: Joe C Date: Sun, 31 Mar 2024 11:20:42 -0500 Subject: [PATCH 5/9] add cu --- proposals/0133-syscall-get-epoch-stake.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/proposals/0133-syscall-get-epoch-stake.md b/proposals/0133-syscall-get-epoch-stake.md index afeba6b4..ed1bc3b2 100644 --- a/proposals/0133-syscall-get-epoch-stake.md +++ b/proposals/0133-syscall-get-epoch-stake.md @@ -79,6 +79,18 @@ violation. If the provided vote address corresponds to an account that is not a vote account or does not exist, the syscall will write `0` for active stake. +### Compute Unit Usage + +The syscall will always attempt to consume the same amount of CUs regardless of +control flow. + +``` +(32 / cpi_per_u) + (8 / cpi_per_u) +``` + +- `syscall_base`: Base cost of a sysvall. +- `cpi_per_u`: Number of account data bytes per CU charged during CPI. + ## Impact Dapp developers will be able to query vote account stake for the current epoch From c082f295364e17570deabacf177834bd398cddf3 Mon Sep 17 00:00:00 2001 From: Joe C Date: Mon, 1 Apr 2024 09:17:14 -0500 Subject: [PATCH 6/9] change to return the `u64` rather than write it --- proposals/0133-syscall-get-epoch-stake.md | 38 ++++++++++------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/proposals/0133-syscall-get-epoch-stake.md b/proposals/0133-syscall-get-epoch-stake.md index ed1bc3b2..29e57d70 100644 --- a/proposals/0133-syscall-get-epoch-stake.md +++ b/proposals/0133-syscall-get-epoch-stake.md @@ -57,35 +57,35 @@ The specification for the proposed syscall is as follows: * Retrieves the total active stake delegated to a vote account for the current * epoch. * - * @param var_addr VM memory address to copy the retrieved data to. - * @param vote_address A pointer to 32 bytes representing the vote address. - * @return A 64-bit unsigned integer error code: - * - 0 if the operation is successful. - * - Non-zero error code. - * - * If the operation is not successful, data will not be written to the - * provided VM memory address. + * @param vote_addr A pointer to 32 bytes representing the vote address. + * @return A 64-bit unsigned integer representing the total + * active stake delegated to the vote account at the + * provided address. */ -uint64_t sol_get_epoch_stake( - /* r1 */ uint8_t * var_addr, - /* r2 */ void const * vote_address, -); +uint64_t sol_get_epoch_stake(/* r1 */ void const * vote_addr); ``` -`var_addr` must be the starting address of 8 bytes of writable VM memory to -store the `u64` response. If not, the syscall will abort the VM with an access -violation. - If the provided vote address corresponds to an account that is not a vote account or does not exist, the syscall will write `0` for active stake. +### Control Flow + +The syscall aborts the virtual machine if not all bytes in VM memory range +`[vote_addr, vote_addr + 32)` are readable. + +Otherwise, the syscall returns a `u64` integer representing the total active +stake delegated to the vote account at the provided address. + +If the provided vote address corresponds to an account that is not a vote +account or does not exist, the syscall will return `0` for active stake. + ### Compute Unit Usage The syscall will always attempt to consume the same amount of CUs regardless of control flow. ``` -(32 / cpi_per_u) + (8 / cpi_per_u) +syscall_base + (32/cpi_per_u) + mem_op_base ``` - `syscall_base`: Base cost of a sysvall. @@ -102,7 +102,3 @@ This new syscall introduces the same security considerations as the rest of the syscalls in the existing interface, which manipulate raw pointers to VM memory and must be implemented with care. -A potential pitfall in the implementation could come when comparing the act of -writing a `0` to the VM memory for active stake versus returning a `0` for -success. The two should not be conflated. - From cf6ae8712d453fb3b3ca1272071cd6f6b8989c6e Mon Sep 17 00:00:00 2001 From: Joe Caulfield Date: Mon, 1 Apr 2024 11:31:29 -0500 Subject: [PATCH 7/9] dedupe --- proposals/0133-syscall-get-epoch-stake.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/proposals/0133-syscall-get-epoch-stake.md b/proposals/0133-syscall-get-epoch-stake.md index 29e57d70..714d8798 100644 --- a/proposals/0133-syscall-get-epoch-stake.md +++ b/proposals/0133-syscall-get-epoch-stake.md @@ -65,9 +65,6 @@ The specification for the proposed syscall is as follows: uint64_t sol_get_epoch_stake(/* r1 */ void const * vote_addr); ``` -If the provided vote address corresponds to an account that is not a vote -account or does not exist, the syscall will write `0` for active stake. - ### Control Flow The syscall aborts the virtual machine if not all bytes in VM memory range From 2f28ba9f1e9d03e0cc5afd4f410f1fece7dc8cfe Mon Sep 17 00:00:00 2001 From: Joe C Date: Wed, 3 Apr 2024 14:13:00 -0500 Subject: [PATCH 8/9] Update proposals/0133-syscall-get-epoch-stake.md Co-authored-by: lheeger-jump <126003637+lheeger-jump@users.noreply.github.com> --- proposals/0133-syscall-get-epoch-stake.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0133-syscall-get-epoch-stake.md b/proposals/0133-syscall-get-epoch-stake.md index 714d8798..ec6158e4 100644 --- a/proposals/0133-syscall-get-epoch-stake.md +++ b/proposals/0133-syscall-get-epoch-stake.md @@ -82,7 +82,7 @@ The syscall will always attempt to consume the same amount of CUs regardless of control flow. ``` -syscall_base + (32/cpi_per_u) + mem_op_base +syscall_base + floor(32/cpi_bytes_per_unit) + mem_op_base ``` - `syscall_base`: Base cost of a sysvall. From 91f3c5651f8b42378d2d5f416d62c9bc7cf1118c Mon Sep 17 00:00:00 2001 From: Joe C Date: Wed, 3 Apr 2024 14:13:11 -0500 Subject: [PATCH 9/9] Update proposals/0133-syscall-get-epoch-stake.md Co-authored-by: lheeger-jump <126003637+lheeger-jump@users.noreply.github.com> --- proposals/0133-syscall-get-epoch-stake.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/0133-syscall-get-epoch-stake.md b/proposals/0133-syscall-get-epoch-stake.md index ec6158e4..aa03f77b 100644 --- a/proposals/0133-syscall-get-epoch-stake.md +++ b/proposals/0133-syscall-get-epoch-stake.md @@ -86,7 +86,8 @@ syscall_base + floor(32/cpi_bytes_per_unit) + mem_op_base ``` - `syscall_base`: Base cost of a sysvall. -- `cpi_per_u`: Number of account data bytes per CU charged during CPI. +- `cpi_bytes_per_units`: Number of account data bytes per CU charged during CPI. +- `mem_op_base`: Base cost of a memory operation syscall. ## Impact