From 2406ddbe251dc43b6b5ca3b1a5bc84d70b62ace8 Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Mon, 26 Aug 2024 18:51:16 -0500 Subject: [PATCH 01/15] draft --- ...170-builtin-instruction-cost-and-budget.md | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 proposals/simd-0170-builtin-instruction-cost-and-budget.md diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md new file mode 100644 index 000000000..8add3e5fb --- /dev/null +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -0,0 +1,127 @@ +--- +simd: '0170' +title: Allocate percise builtin instructions budget +authors: + - Tao Zhu (Anza) +category: Standard +type: Core +status: Draft +created: 2024-08-26 +feature: https://github.com/anza-xyz/agave/issues/2562 +supersedes: +superseded-by: +extends: +--- + +## Summary + +Builtin instructions always consume a statically defined amount of compute +units (CUs). Therefore, they should allocate the exact same amount of compute +budget and count the same amount toward the block limit during the banking +stage. + +## Motivation + +Builtin instructions in the SVM consume their static DEFAULT_COMPUTE_UNITS from +the compute budget during execution. These DEFAULT_COMPUTE_UNITS are also +counted against block limits during the banking stage. However, historically, +builtin instructions have been allocated DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT +units of compute budget. This discrepancy between the allowed consumption and +the actual usage tracked for block limits has led to several issues that need +to be addressed. + +Allocating DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT instead of the actual +DEFAULT_COMPUTE_UNITS for builtin instructions distorts the tracking of +transaction compute budgets. This can result in more expensive instructions +being executed when they should fail due to exceeding the budget. Consequently, +the cost tracker may need to account for additional compute units toward block +limits after transaction execution, potentially producing blocks that exceed +those limits. + +Furthermore, maintaining consistency in transaction costs between the banking +stage and SVM would simplify the code logic and make reasoning more +straightforward. + +## Alternatives Considered + +- One possible alternative approach would be to maintain the current allocation +of compute budget for builtin instructions but add logic to the cost tracker +to account for the discrepancy during tracking. However, this would add +complexity and could introduce additional corner cases, potentially leading to +more issues. + +- Another alternative would be to treat builtin instructions the same as other +instructions by allocating DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT units for them +as well. However, this approach has concerns. DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT +is a very conservative estimate, currently set at 200,000 CUs per instruction. +Estimating all builtin instructions, including votes and transfers, would cause +the banking stage to significantly over-reserve block space during block +production, potentially leading to under-packed blocks. Additionally, if it's +known that builtin instructions will consume a fixed amount of CUs, it doesn't +make sense to estimate them with a generic DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT. + +## New Terminology + +None + +## Detailed Design + +To ensure consistency, the following three changes are proposed: + +1. Allocate Static Compute Budget for Builtin Instructions: + When the compute-unit-limit is not explicitly requested, the compute budget +should always allocate the statically defined DEFAULT_COMPUTE_UNITS for builtin +instructions, including compute-budget instructions. + + Currently, when set_compute_unit_limit is not used, all instructions are +allocated DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT, capped by the transaction's +MAX_COMPUTE_UNIT_LIMIT. However, compute-budget instructions historically +haven't had any units allocated. This can lead to over-packed blocks in +certain scenarios. + + [Example 1](https://github.com/anza-xyz/agave/pull/2746/files#diff-c6c8658338536afbf59d65e9f66b71460e7403119ca76e51dc9125e1719f4f52R13403-R13429): + A transaction consists of a Transfer and an expensive non-builtin instruction. +If the non-builtin instruction requires more than DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT +CUs, the over-budgeting for Transfer allows the expensive instruction to +execute to completion, forcing an upward adjustment. + + [Example 2](https://github.com/anza-xyz/agave/pull/2746/files#diff-c6c8658338536afbf59d65e9f66b71460e7403119ca76e51dc9125e1719f4f52R13431-R13455): + A builtin instruction that might call other instructions (CPI) would fail +without explicitly requesting more CUs. However, this isn't currently happening. + +2. Respect Explicit Compute Unit Requests During Block Production: + When a compute-unit-limit is explicitly requested, always use it to reserve +block space during block production, even if there are no user-space instructions. + + [Example 3](https://github.com/anza-xyz/agave/pull/2746/files#diff-c6c8658338536afbf59d65e9f66b71460e7403119ca76e51dc9125e1719f4f52R13457-R13484) + The cost model ignores explicitly requested CUs for transactions has all +buitin instructions, resulting in an upward adjustment instead of the usual +downward adjustment. + +3. Fail Transactions with Invalid Compute Unit Limits Early: + If set_compute_unit_limit sets an invalid value, the transaction should fail +before being sent for execution. + "invalid value" is defined as `> MAX_COMPUTE_UNIT_LIMIT || < Sum(builtin_instructions)` + + [Example 4](https://github.com/anza-xyz/agave/pull/2746/files#diff-c6c8658338536afbf59d65e9f66b71460e7403119ca76e51dc9125e1719f4f52R13344-R13373): + If the explicitly requested CU limit is invalid, the transaction should +fail during sanitization, saving it from being sent to the SVM for execution. + + +*Note*: Users are encouraged to explicitly request a reasonable amount of +compute-unit-limits. Requesting more than needed not only increases the +prioritization fee the user pays but also lowers the transaction's priority. + +## Impact + +Users who previously relied on including builtin instructions, instead of +explicitly setting compute-unit limits, to allocate budget for their +transactions may experience an increase in transaction failures. To avoid this, +users are encouraged to use set_compute_unit_limits to explicitly request the +necessary budget for their transactions. + +## Security Considerations + +Both Agave and FD clients should implement this proposal to avoid breaking +consensus. + From 6adc82b8901d7202d976ab757b65036e50849cd2 Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Wed, 28 Aug 2024 14:32:54 -0500 Subject: [PATCH 02/15] updated proposal to have a static and low builtin allocation CU limit as a compromised solution --- ...170-builtin-instruction-cost-and-budget.md | 157 ++++++++---------- 1 file changed, 68 insertions(+), 89 deletions(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index 8add3e5fb..b2d4fe3ef 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -1,6 +1,6 @@ --- simd: '0170' -title: Allocate percise builtin instructions budget +title: Specifying CU Definitions for Built-ins authors: - Tao Zhu (Anza) category: Standard @@ -15,109 +15,88 @@ extends: ## Summary -Builtin instructions always consume a statically defined amount of compute -units (CUs). Therefore, they should allocate the exact same amount of compute -budget and count the same amount toward the block limit during the banking -stage. +1. Built-in programs should consume a predefined number of CUs for each + instruction. +2. Since built-ins can invoke other programs (CPI), they should allocate enough + but granular CUs to ensure successful execution without over-allocation. ## Motivation -Builtin instructions in the SVM consume their static DEFAULT_COMPUTE_UNITS from -the compute budget during execution. These DEFAULT_COMPUTE_UNITS are also -counted against block limits during the banking stage. However, historically, -builtin instructions have been allocated DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT -units of compute budget. This discrepancy between the allowed consumption and -the actual usage tracked for block limits has led to several issues that need -to be addressed. - -Allocating DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT instead of the actual -DEFAULT_COMPUTE_UNITS for builtin instructions distorts the tracking of -transaction compute budgets. This can result in more expensive instructions -being executed when they should fail due to exceeding the budget. Consequently, -the cost tracker may need to account for additional compute units toward block -limits after transaction execution, potentially producing blocks that exceed -those limits. - -Furthermore, maintaining consistency in transaction costs between the banking -stage and SVM would simplify the code logic and make reasoning more -straightforward. +This proposal addresses two key issues related to CU allocation and consumption +for built-in programs while aiming to avoid adding unnecessary complexity. + +1. **Accurate CU tracking without post-execution adjust-up**: Currently, + built-in instructions deduct a fixed amount of CUs (DEFAULT_COMPUTE_UNITS) +from both the CU meter and block limits after execution. However, the CU meter +allocates a much larger value (DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT) to each +built-in instruction. This discrepancy creates imprecise CU tracking and may +require block producers to account for additional CUs after a transaction's +execution, potentially causing block limits to be exceeded. + + Furthermore, built-ins can conditionally CPI into other programs, introducing +variability in CU consumption. This unpredictability makes it difficult to +allocate CUs upfront solely based on CUs builtin consumes during execution, also +adds complexity to the tracking process. + +2. **Preventing over-allocation of CUs**: Over-allocating CUs for built-ins + reduces block density, lowers network throughput, and can degrade block +producer performance by causing repeated transaction retries. Avoiding excessive +CU allocation is critical for maximizing block efficiency and minimizing network +delays. + +To resolve these issues, we propose statically defining the CU cost of built-in +instructions based on worst-case scenarios, including potential CPI calls. A +unified MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT will standardize CU allocation +for both block producers and the CU meter. ## Alternatives Considered -- One possible alternative approach would be to maintain the current allocation -of compute budget for builtin instructions but add logic to the cost tracker -to account for the discrepancy during tracking. However, this would add -complexity and could introduce additional corner cases, potentially leading to -more issues. - -- Another alternative would be to treat builtin instructions the same as other -instructions by allocating DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT units for them -as well. However, this approach has concerns. DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT -is a very conservative estimate, currently set at 200,000 CUs per instruction. -Estimating all builtin instructions, including votes and transfers, would cause -the banking stage to significantly over-reserve block space during block -production, potentially leading to under-packed blocks. Additionally, if it's -known that builtin instructions will consume a fixed amount of CUs, it doesn't -make sense to estimate them with a generic DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT. - -## New Terminology - -None +1. **Maintain current CU allocation with additional tracking logic**: One option + is to keep the current DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT for built-ins +and add/modify tracking logic to the cost tracker. This would address the +discrepancy between CU allocation and consumption but increase system +complexity. The added logic could introduce corner cases and potential bugs, +raising the risk of issues in the transaction pipeline. + +2. **Treat built-ins like regular instructions**: Another approach would be to + allocate DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT for built-ins as for other +instructions. However, this fails to address over-allocation. Unlike regular +instructions, the execution of built-ins is more predictable and usually +requires significantly fewer CUs than BPF instructions. This approach would +allocate more CUs than necessary, undermining the goal of efficient CU usage. + +3. **Declare both max and default CU values for built-ins**: A more precise + approach would be to require built-ins to declare both a maximum CU +allocation (MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT) and a default CU value +for each instruction (DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS). This would +allow fine-tuned CU allocation based on each instruction’s potential execution +path. However, this introduces new constraints for existing and future +built-ins, requiring updates to comply with these rules, which could +overcomplicate the design. ## Detailed Design -To ensure consistency, the following three changes are proposed: - -1. Allocate Static Compute Budget for Builtin Instructions: - When the compute-unit-limit is not explicitly requested, the compute budget -should always allocate the statically defined DEFAULT_COMPUTE_UNITS for builtin -instructions, including compute-budget instructions. - - Currently, when set_compute_unit_limit is not used, all instructions are -allocated DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT, capped by the transaction's -MAX_COMPUTE_UNIT_LIMIT. However, compute-budget instructions historically -haven't had any units allocated. This can lead to over-packed blocks in -certain scenarios. - - [Example 1](https://github.com/anza-xyz/agave/pull/2746/files#diff-c6c8658338536afbf59d65e9f66b71460e7403119ca76e51dc9125e1719f4f52R13403-R13429): - A transaction consists of a Transfer and an expensive non-builtin instruction. -If the non-builtin instruction requires more than DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT -CUs, the over-budgeting for Transfer allows the expensive instruction to -execute to completion, forcing an upward adjustment. - - [Example 2](https://github.com/anza-xyz/agave/pull/2746/files#diff-c6c8658338536afbf59d65e9f66b71460e7403119ca76e51dc9125e1719f4f52R13431-R13455): - A builtin instruction that might call other instructions (CPI) would fail -without explicitly requesting more CUs. However, this isn't currently happening. - -2. Respect Explicit Compute Unit Requests During Block Production: - When a compute-unit-limit is explicitly requested, always use it to reserve -block space during block production, even if there are no user-space instructions. - - [Example 3](https://github.com/anza-xyz/agave/pull/2746/files#diff-c6c8658338536afbf59d65e9f66b71460e7403119ca76e51dc9125e1719f4f52R13457-R13484) - The cost model ignores explicitly requested CUs for transactions has all -buitin instructions, resulting in an upward adjustment instead of the usual -downward adjustment. - -3. Fail Transactions with Invalid Compute Unit Limits Early: - If set_compute_unit_limit sets an invalid value, the transaction should fail -before being sent for execution. - "invalid value" is defined as `> MAX_COMPUTE_UNIT_LIMIT || < Sum(builtin_instructions)` - - [Example 4](https://github.com/anza-xyz/agave/pull/2746/files#diff-c6c8658338536afbf59d65e9f66b71460e7403119ca76e51dc9125e1719f4f52R13344-R13373): - If the explicitly requested CU limit is invalid, the transaction should -fail during sanitization, saving it from being sent to the SVM for execution. - - -*Note*: Users are encouraged to explicitly request a reasonable amount of -compute-unit-limits. Requesting more than needed not only increases the -prioritization fee the user pays but also lowers the transaction's priority. +1. **Statically define CUs per instruction**: Assign a fixed CU consumption + (DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS) to each built-in instruction +rather than per built-in program. +2. **Set a static maximum CU allocation**: Propose a global limit of 5,000 CUs + (MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT) to cover worst-case scenarios, +including CPI operations. +3. **Handling invalid CU requests**: Transactions will fail if they request: + - More than MAX_COMPUTE_UNIT_LIMIT + - Less than the sum of all included built-in instructions' + MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT + +If a transaction consists only of built-ins, no explicit CU request should be +required. If a CU request is made, the requested limit will override the max +allocation in #2. ## Impact Users who previously relied on including builtin instructions, instead of explicitly setting compute-unit limits, to allocate budget for their transactions may experience an increase in transaction failures. To avoid this, -users are encouraged to use set_compute_unit_limits to explicitly request the +users are encouraged to use set_compute_unit_limit to explicitly request the necessary budget for their transactions. ## Security Considerations From dad1298ebaceab6fb237aec29e71ed8d296736a6 Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Thu, 24 Oct 2024 10:31:36 -0500 Subject: [PATCH 03/15] rename --- ...170-builtin-instruction-cost-and-budget.md | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index b2d4fe3ef..8181d872c 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -1,6 +1,6 @@ --- simd: '0170' -title: Specifying CU Definitions for Built-ins +title: Specifying CU Definitions for Builtins authors: - Tao Zhu (Anza) category: Standard @@ -15,36 +15,36 @@ extends: ## Summary -1. Built-in programs should consume a predefined number of CUs for each +1. Builtin programs should consume a predefined number of CUs for each instruction. -2. Since built-ins can invoke other programs (CPI), they should allocate enough +2. Since builtins can invoke other programs (CPI), they should allocate enough but granular CUs to ensure successful execution without over-allocation. ## Motivation This proposal addresses two key issues related to CU allocation and consumption -for built-in programs while aiming to avoid adding unnecessary complexity. +for builtin programs while aiming to avoid adding unnecessary complexity. 1. **Accurate CU tracking without post-execution adjust-up**: Currently, - built-in instructions deduct a fixed amount of CUs (DEFAULT_COMPUTE_UNITS) + builtin instructions deduct a fixed amount of CUs (DEFAULT_COMPUTE_UNITS) from both the CU meter and block limits after execution. However, the CU meter allocates a much larger value (DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT) to each -built-in instruction. This discrepancy creates imprecise CU tracking and may +builtin instruction. This discrepancy creates imprecise CU tracking and may require block producers to account for additional CUs after a transaction's execution, potentially causing block limits to be exceeded. - Furthermore, built-ins can conditionally CPI into other programs, introducing + Furthermore, builtins can conditionally CPI into other programs, introducing variability in CU consumption. This unpredictability makes it difficult to allocate CUs upfront solely based on CUs builtin consumes during execution, also adds complexity to the tracking process. -2. **Preventing over-allocation of CUs**: Over-allocating CUs for built-ins +2. **Preventing over-allocation of CUs**: Over-allocating CUs for builtins reduces block density, lowers network throughput, and can degrade block producer performance by causing repeated transaction retries. Avoiding excessive CU allocation is critical for maximizing block efficiency and minimizing network delays. -To resolve these issues, we propose statically defining the CU cost of built-in +To resolve these issues, we propose statically defining the CU cost of builtin instructions based on worst-case scenarios, including potential CPI calls. A unified MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT will standardize CU allocation for both block producers and the CU meter. @@ -52,42 +52,42 @@ for both block producers and the CU meter. ## Alternatives Considered 1. **Maintain current CU allocation with additional tracking logic**: One option - is to keep the current DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT for built-ins + is to keep the current DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT for builtins and add/modify tracking logic to the cost tracker. This would address the discrepancy between CU allocation and consumption but increase system complexity. The added logic could introduce corner cases and potential bugs, raising the risk of issues in the transaction pipeline. -2. **Treat built-ins like regular instructions**: Another approach would be to - allocate DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT for built-ins as for other +2. **Treat builtins like regular instructions**: Another approach would be to + allocate DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT for builtins as for other instructions. However, this fails to address over-allocation. Unlike regular -instructions, the execution of built-ins is more predictable and usually +instructions, the execution of builtins is more predictable and usually requires significantly fewer CUs than BPF instructions. This approach would allocate more CUs than necessary, undermining the goal of efficient CU usage. -3. **Declare both max and default CU values for built-ins**: A more precise - approach would be to require built-ins to declare both a maximum CU +3. **Declare both max and default CU values for builtins**: A more precise + approach would be to require builtins to declare both a maximum CU allocation (MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT) and a default CU value for each instruction (DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS). This would allow fine-tuned CU allocation based on each instruction’s potential execution path. However, this introduces new constraints for existing and future -built-ins, requiring updates to comply with these rules, which could +builtins, requiring updates to comply with these rules, which could overcomplicate the design. ## Detailed Design 1. **Statically define CUs per instruction**: Assign a fixed CU consumption - (DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS) to each built-in instruction -rather than per built-in program. + (DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS) to each builtin instruction +rather than per builtin program. 2. **Set a static maximum CU allocation**: Propose a global limit of 5,000 CUs (MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT) to cover worst-case scenarios, including CPI operations. 3. **Handling invalid CU requests**: Transactions will fail if they request: - More than MAX_COMPUTE_UNIT_LIMIT - - Less than the sum of all included built-in instructions' + - Less than the sum of all included builtin instructions' MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT -If a transaction consists only of built-ins, no explicit CU request should be +If a transaction consists only of builtins, no explicit CU request should be required. If a CU request is made, the requested limit will override the max allocation in #2. From 350d34c815a89f07ef686fbdffc1543c84963dc9 Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Thu, 24 Oct 2024 10:34:50 -0500 Subject: [PATCH 04/15] format --- ...170-builtin-instruction-cost-and-budget.md | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index 8181d872c..20f48e69c 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -25,7 +25,7 @@ extends: This proposal addresses two key issues related to CU allocation and consumption for builtin programs while aiming to avoid adding unnecessary complexity. -1. **Accurate CU tracking without post-execution adjust-up**: Currently, +1. Accurate CU tracking without post-execution adjust-up: Currently, builtin instructions deduct a fixed amount of CUs (DEFAULT_COMPUTE_UNITS) from both the CU meter and block limits after execution. However, the CU meter allocates a much larger value (DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT) to each @@ -38,7 +38,7 @@ variability in CU consumption. This unpredictability makes it difficult to allocate CUs upfront solely based on CUs builtin consumes during execution, also adds complexity to the tracking process. -2. **Preventing over-allocation of CUs**: Over-allocating CUs for builtins +2. Preventing over-allocation of CUs: Over-allocating CUs for builtins reduces block density, lowers network throughput, and can degrade block producer performance by causing repeated transaction retries. Avoiding excessive CU allocation is critical for maximizing block efficiency and minimizing network @@ -49,23 +49,44 @@ instructions based on worst-case scenarios, including potential CPI calls. A unified MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT will standardize CU allocation for both block producers and the CU meter. +## New Terminology + +None + +## Detailed Design + +1. Statically define CUs per instruction: Assign a fixed CU consumption + (DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS) to each builtin instruction +rather than per builtin program. +2. Set a static maximum CU allocation: Propose a global limit of 5,000 CUs + (MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT) to cover worst-case scenarios, +including CPI operations. +3. Handling invalid CU requests: Transactions will fail if they request: + - More than MAX_COMPUTE_UNIT_LIMIT + - Less than the sum of all included builtin instructions' + MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT + +If a transaction consists only of builtins, no explicit CU request should be +required. If a CU request is made, the requested limit will override the max +allocation in #2. + ## Alternatives Considered -1. **Maintain current CU allocation with additional tracking logic**: One option +1. Maintain current CU allocation with additional tracking logic: One option is to keep the current DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT for builtins and add/modify tracking logic to the cost tracker. This would address the discrepancy between CU allocation and consumption but increase system complexity. The added logic could introduce corner cases and potential bugs, raising the risk of issues in the transaction pipeline. -2. **Treat builtins like regular instructions**: Another approach would be to +2. Treat builtins like regular instructions: Another approach would be to allocate DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT for builtins as for other instructions. However, this fails to address over-allocation. Unlike regular instructions, the execution of builtins is more predictable and usually requires significantly fewer CUs than BPF instructions. This approach would allocate more CUs than necessary, undermining the goal of efficient CU usage. -3. **Declare both max and default CU values for builtins**: A more precise +3. Declare both max and default CU values for builtins: A more precise approach would be to require builtins to declare both a maximum CU allocation (MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT) and a default CU value for each instruction (DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS). This would @@ -74,23 +95,6 @@ path. However, this introduces new constraints for existing and future builtins, requiring updates to comply with these rules, which could overcomplicate the design. -## Detailed Design - -1. **Statically define CUs per instruction**: Assign a fixed CU consumption - (DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS) to each builtin instruction -rather than per builtin program. -2. **Set a static maximum CU allocation**: Propose a global limit of 5,000 CUs - (MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT) to cover worst-case scenarios, -including CPI operations. -3. **Handling invalid CU requests**: Transactions will fail if they request: - - More than MAX_COMPUTE_UNIT_LIMIT - - Less than the sum of all included builtin instructions' - MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT - -If a transaction consists only of builtins, no explicit CU request should be -required. If a CU request is made, the requested limit will override the max -allocation in #2. - ## Impact Users who previously relied on including builtin instructions, instead of From 30fd5295ffae9989ed5fa0458d97b54aa3e77a1c Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Thu, 24 Oct 2024 10:43:25 -0500 Subject: [PATCH 05/15] lint --- proposals/simd-0170-builtin-instruction-cost-and-budget.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index 20f48e69c..36b1bb06b 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -5,7 +5,7 @@ authors: - Tao Zhu (Anza) category: Standard type: Core -status: Draft +status: Review created: 2024-08-26 feature: https://github.com/anza-xyz/agave/issues/2562 supersedes: From aa70ccf9d061eabb282c3846a5d60a12a506325c Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Fri, 25 Oct 2024 11:26:14 -0500 Subject: [PATCH 06/15] some details in Design section --- ...170-builtin-instruction-cost-and-budget.md | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index 36b1bb06b..6de2e2d4f 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -55,12 +55,30 @@ None ## Detailed Design -1. Statically define CUs per instruction: Assign a fixed CU consumption - (DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS) to each builtin instruction -rather than per builtin program. -2. Set a static maximum CU allocation: Propose a global limit of 5,000 CUs - (MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT) to cover worst-case scenarios, -including CPI operations. +1. Define Compute Units (CUs) on a per-instruction basis: Each builtin + instruction is assigned a predetermined, static CU consumption value, denoted +as DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS, rather than a program-wide +allocation. When the virtual machine (VM) invokes a builtin instruction, the +specified DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS is consistently deducted +from the CU Meter. + +2. Establish a static maximum CU allocation: Define a global compute unit limit + of 5,000 CUs, denoted as MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT, to +accommodate worst-case execution scenarios, including potential Cross-Program +Invocations (CPIs). This uniform limit is applied to each builtin program +instruction and is used to configure both CU meter allocations and block +producer CU limits reservation for all builtin instructions. + +The 5,000 CU threshold is derived from analysis of existing builtin programs. +For instance, the `AddressLookupTable`’s `CreateLookupTable` makes the highest +number of CPI calls (up to three invocations of the `System` program), resulting +in a maximum CU demand of 1,200 CUs (750 + 3 × 150). Similarly, +`UpgradeableLoader`’s `ExtendProgram`, which may invoke the `System` program +once, requires a peak CU of 2,520 (2,370 + 150), representing the most +resource-intensive operation among current builtins. The proposed 5,000 CU +ceiling nearly doubles this requirement, providing ample margin for future +builtins that may have increased complexity. + 3. Handling invalid CU requests: Transactions will fail if they request: - More than MAX_COMPUTE_UNIT_LIMIT - Less than the sum of all included builtin instructions' From f56285dcb6540b8b400555d25e1266e02564013f Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Mon, 28 Oct 2024 10:25:28 -0500 Subject: [PATCH 07/15] tighen limit from 5000 to 3000 CU --- ...170-builtin-instruction-cost-and-budget.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index 6de2e2d4f..6fc316dfc 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -63,21 +63,21 @@ specified DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS is consistently deducted from the CU Meter. 2. Establish a static maximum CU allocation: Define a global compute unit limit - of 5,000 CUs, denoted as MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT, to + of 3,000 CUs, denoted as MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT, to accommodate worst-case execution scenarios, including potential Cross-Program Invocations (CPIs). This uniform limit is applied to each builtin program instruction and is used to configure both CU meter allocations and block producer CU limits reservation for all builtin instructions. -The 5,000 CU threshold is derived from analysis of existing builtin programs. -For instance, the `AddressLookupTable`’s `CreateLookupTable` makes the highest -number of CPI calls (up to three invocations of the `System` program), resulting -in a maximum CU demand of 1,200 CUs (750 + 3 × 150). Similarly, -`UpgradeableLoader`’s `ExtendProgram`, which may invoke the `System` program -once, requires a peak CU of 2,520 (2,370 + 150), representing the most -resource-intensive operation among current builtins. The proposed 5,000 CU -ceiling nearly doubles this requirement, providing ample margin for future -builtins that may have increased complexity. +The 3,000 CU threshold is based on analysis of current built-in programs and +reflects the unlikely need for additional complexity. For instance, the +`AddressLookupTable`’s `CreateLookupTable` performs the highest number of CPI +calls (up to three invocations of the System program), resulting in a maximum +CU demand of 1,200 CUs (750 + 3 × 150). Similarly, `UpgradeableLoader`’s +`ExtendProgram`, which may invoke the System program once, requires up to +2,520 CUs (2,370 + 150), representing the most resource-intensive operation +among current built-ins. The proposed 3,000 CU limit slightly exceeds this +requirement, allowing for controlled flexibility without an excessive margin. 3. Handling invalid CU requests: Transactions will fail if they request: - More than MAX_COMPUTE_UNIT_LIMIT From 926519fea9632b5f12e99ab4a02f79d54424d608 Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Tue, 19 Nov 2024 15:27:25 -0600 Subject: [PATCH 08/15] updated proposed design #1 item to retain current builtin default CUs --- .../simd-0170-builtin-instruction-cost-and-budget.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index 6fc316dfc..37a898b29 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -55,12 +55,10 @@ None ## Detailed Design -1. Define Compute Units (CUs) on a per-instruction basis: Each builtin - instruction is assigned a predetermined, static CU consumption value, denoted -as DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS, rather than a program-wide -allocation. When the virtual machine (VM) invokes a builtin instruction, the -specified DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS is consistently deducted -from the CU Meter. +1. Retain the existing DEFAULT_COMPUTE_UNITS for builtin programs. + When the virtual machine (VM) invokes a builtin instruction, the +statically defined DEFAULT_COMPUTE_UNITS is consistently deducted from the CU +Meter. 2. Establish a static maximum CU allocation: Define a global compute unit limit of 3,000 CUs, denoted as MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT, to @@ -80,7 +78,7 @@ among current built-ins. The proposed 3,000 CU limit slightly exceeds this requirement, allowing for controlled flexibility without an excessive margin. 3. Handling invalid CU requests: Transactions will fail if they request: - - More than MAX_COMPUTE_UNIT_LIMIT + - More than MAX_COMPUTE_UNIT_LIMIT per transaction, or - Less than the sum of all included builtin instructions' MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT From e8ed406540118a54f97f1a9f3c96eb78ae1e5c05 Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Wed, 20 Nov 2024 13:38:31 -0600 Subject: [PATCH 09/15] simplify proposal --- ...170-builtin-instruction-cost-and-budget.md | 38 ++++++------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index 37a898b29..98ac67b41 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -1,6 +1,6 @@ --- simd: '0170' -title: Specifying CU Definitions for Builtins +title: Reserve sufficient CUs for builtin instructions authors: - Tao Zhu (Anza) category: Standard @@ -15,10 +15,8 @@ extends: ## Summary -1. Builtin programs should consume a predefined number of CUs for each - instruction. -2. Since builtins can invoke other programs (CPI), they should allocate enough - but granular CUs to ensure successful execution without over-allocation. +If a transaction doesn't request a compute budget limit, then for each builtin +program instruction allocate 3,000 compute units rather than 200,000. ## Motivation @@ -55,13 +53,8 @@ None ## Detailed Design -1. Retain the existing DEFAULT_COMPUTE_UNITS for builtin programs. - When the virtual machine (VM) invokes a builtin instruction, the -statically defined DEFAULT_COMPUTE_UNITS is consistently deducted from the CU -Meter. - -2. Establish a static maximum CU allocation: Define a global compute unit limit - of 3,000 CUs, denoted as MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT, to +Establish a static maximum CU allocation: Define a global compute unit limit +of 3,000 CUs, denoted as MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT, to accommodate worst-case execution scenarios, including potential Cross-Program Invocations (CPIs). This uniform limit is applied to each builtin program instruction and is used to configure both CU meter allocations and block @@ -77,32 +70,20 @@ CU demand of 1,200 CUs (750 + 3 × 150). Similarly, `UpgradeableLoader`’s among current built-ins. The proposed 3,000 CU limit slightly exceeds this requirement, allowing for controlled flexibility without an excessive margin. -3. Handling invalid CU requests: Transactions will fail if they request: - - More than MAX_COMPUTE_UNIT_LIMIT per transaction, or - - Less than the sum of all included builtin instructions' - MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT - If a transaction consists only of builtins, no explicit CU request should be required. If a CU request is made, the requested limit will override the max allocation in #2. ## Alternatives Considered -1. Maintain current CU allocation with additional tracking logic: One option - is to keep the current DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT for builtins -and add/modify tracking logic to the cost tracker. This would address the -discrepancy between CU allocation and consumption but increase system -complexity. The added logic could introduce corner cases and potential bugs, -raising the risk of issues in the transaction pipeline. - -2. Treat builtins like regular instructions: Another approach would be to +1. Treat builtins like regular instructions: Another approach would be to allocate DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT for builtins as for other instructions. However, this fails to address over-allocation. Unlike regular instructions, the execution of builtins is more predictable and usually requires significantly fewer CUs than BPF instructions. This approach would allocate more CUs than necessary, undermining the goal of efficient CU usage. -3. Declare both max and default CU values for builtins: A more precise +2. Declare both max and default CU values for builtins: A more precise approach would be to require builtins to declare both a maximum CU allocation (MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT) and a default CU value for each instruction (DEFAULT_BUILTIN_INSTRUCTION_COMPUTE_UNITS). This would @@ -119,6 +100,11 @@ transactions may experience an increase in transaction failures. To avoid this, users are encouraged to use set_compute_unit_limit to explicitly request the necessary budget for their transactions. +If those impacted users have issues fitting in the set compute unit limit +instruction into their transactions due to tx data size limits, they can also +migrate to using address lookup tables to fit in the compute budget instruction +call. + ## Security Considerations Both Agave and FD clients should implement this proposal to avoid breaking From c88fdbaa8052803fd242974904dee2a2fd43432a Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Wed, 20 Nov 2024 13:41:54 -0600 Subject: [PATCH 10/15] lint - title length --- proposals/simd-0170-builtin-instruction-cost-and-budget.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index 98ac67b41..b9f051f61 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -1,6 +1,6 @@ --- simd: '0170' -title: Reserve sufficient CUs for builtin instructions +title: Reserve minimal CUs for builtins authors: - Tao Zhu (Anza) category: Standard From 0d6e75f7be745bfb19b0a34dd75d3328f25e91cd Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Wed, 20 Nov 2024 13:48:35 -0600 Subject: [PATCH 11/15] update motivation section --- ...170-builtin-instruction-cost-and-budget.md | 25 +++++-------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index b9f051f61..0ab7af119 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -20,32 +20,19 @@ program instruction allocate 3,000 compute units rather than 200,000. ## Motivation -This proposal addresses two key issues related to CU allocation and consumption +This proposal addresses an issue related to CU allocation and consumption for builtin programs while aiming to avoid adding unnecessary complexity. -1. Accurate CU tracking without post-execution adjust-up: Currently, - builtin instructions deduct a fixed amount of CUs (DEFAULT_COMPUTE_UNITS) -from both the CU meter and block limits after execution. However, the CU meter -allocates a much larger value (DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT) to each -builtin instruction. This discrepancy creates imprecise CU tracking and may -require block producers to account for additional CUs after a transaction's -execution, potentially causing block limits to be exceeded. - - Furthermore, builtins can conditionally CPI into other programs, introducing -variability in CU consumption. This unpredictability makes it difficult to -allocate CUs upfront solely based on CUs builtin consumes during execution, also -adds complexity to the tracking process. - -2. Preventing over-allocation of CUs: Over-allocating CUs for builtins +- Preventing over-allocation of CUs: Over-allocating CUs for builtins reduces block density, lowers network throughput, and can degrade block producer performance by causing repeated transaction retries. Avoiding excessive CU allocation is critical for maximizing block efficiency and minimizing network delays. -To resolve these issues, we propose statically defining the CU cost of builtin -instructions based on worst-case scenarios, including potential CPI calls. A -unified MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT will standardize CU allocation -for both block producers and the CU meter. +To resolve this issue, we propose statically defining the CU reservation of +builtin instructions based on worst-case scenarios, including potential CPI +calls. A unified MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT will standardize CU +allocation for both block producers and the CU meter. ## New Terminology From dd075615d850ac6a010dfd1176c80a48c9d8d129 Mon Sep 17 00:00:00 2001 From: Tao Zhu <82401714+tao-stones@users.noreply.github.com> Date: Wed, 20 Nov 2024 15:08:58 -0600 Subject: [PATCH 12/15] Update proposals/simd-0170-builtin-instruction-cost-and-budget.md Co-authored-by: Justin Starry --- .../simd-0170-builtin-instruction-cost-and-budget.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index 0ab7af119..a39e676cb 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -40,10 +40,10 @@ None ## Detailed Design -Establish a static maximum CU allocation: Define a global compute unit limit -of 3,000 CUs, denoted as MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT, to -accommodate worst-case execution scenarios, including potential Cross-Program -Invocations (CPIs). This uniform limit is applied to each builtin program +Establish a static maximum allocation of 3,000 CU's for builtin programs denoted as +`MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT`, which is larger than all actual +compute unit costs of builtin programs as well as the potential Cross-Program +Invocations (CPIs) they do. This uniform limit is applied to each builtin program instruction and is used to configure both CU meter allocations and block producer CU limits reservation for all builtin instructions. From 355c2afee6ad5e5d57ecd926747bb9338cc3eb94 Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Wed, 20 Nov 2024 15:24:40 -0600 Subject: [PATCH 13/15] updates with jstarry comments --- ...170-builtin-instruction-cost-and-budget.md | 65 ++++++++++++------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index a39e676cb..82a11219d 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -15,24 +15,27 @@ extends: ## Summary -If a transaction doesn't request a compute budget limit, then for each builtin -program instruction allocate 3,000 compute units rather than 200,000. +When transactions do not request a specific compute unit limit, the Solana +runtime conservatively allocates 200,000 compute units for each tx-level +instruction (excluding compute budget instructions) in the transaction's +compute budget. Since builtin program instructions consume far less than 200k +compute units, the runtime will be modified to only allocate 3,000 compute units +in the transaction compute budget for each of these instructions. ## Motivation -This proposal addresses an issue related to CU allocation and consumption -for builtin programs while aiming to avoid adding unnecessary complexity. +When allocating the transaction compute budget for transactions which don't +specify a specific compute unit limit, the Solana runtime over-allocates the +number of compute units needed for executing builtin programs which have a +small (mostly) static execution compute unit cost. The runtime will only release +the over-allocated compute units from the block cost tracker when transaction +execution finishes and the actual consume compute units is known. -- Preventing over-allocation of CUs: Over-allocating CUs for builtins - reduces block density, lowers network throughput, and can degrade block -producer performance by causing repeated transaction retries. Avoiding excessive -CU allocation is critical for maximizing block efficiency and minimizing network -delays. - -To resolve this issue, we propose statically defining the CU reservation of -builtin instructions based on worst-case scenarios, including potential CPI -calls. A unified MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT will standardize CU -allocation for both block producers and the CU meter. +Over-allocating CUs for builtin program instructions reduces block density, +lowers network throughput, and can degrade block producer performance by causing +repeated transaction retries (due to repeatedly over allocating cu's and then +releasing them after execution). Avoiding excessive CU allocation is critical +for maximizing block efficiency and minimizing network delays. ## New Terminology @@ -40,13 +43,32 @@ None ## Detailed Design -Establish a static maximum allocation of 3,000 CU's for builtin programs denoted as -`MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT`, which is larger than all actual +Establish a static maximum allocation of 3,000 CU's for builtin programs denoted +as `MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT`, which is larger than all actual compute unit costs of builtin programs as well as the potential Cross-Program -Invocations (CPIs) they do. This uniform limit is applied to each builtin program -instruction and is used to configure both CU meter allocations and block +Invocations (CPIs) they do. This uniform limit is applied to each builtin +program instruction and is used to configure both CU meter allocations and block producer CU limits reservation for all builtin instructions. +The static list of builtin program id's that will have 3000 compute units +allocated are: + +- Stake11111111111111111111111111111111111111 +- Config1111111111111111111111111111111111111 +- Vote111111111111111111111111111111111111111 +- 11111111111111111111111111111111 +- ComputeBudget111111111111111111111111111111 +- AddressLookupTab1e1111111111111111111111111 +- BPFLoaderUpgradeab1e11111111111111111111111 +- BPFLoader1111111111111111111111111111111111 +- BPFLoader2111111111111111111111111111111111 +- LoaderV411111111111111111111111111111111111 +- KeccakSecp256k11111111111111111111111111111 +- Ed25519SigVerify111111111111111111111111111 + +Note that there are a few builtin programs not in the list including the +upcoming zk programs as well as the feature program. + The 3,000 CU threshold is based on analysis of current built-in programs and reflects the unlikely need for additional complexity. For instance, the `AddressLookupTable`’s `CreateLookupTable` performs the highest number of CPI @@ -63,10 +85,9 @@ allocation in #2. ## Alternatives Considered -1. Treat builtins like regular instructions: Another approach would be to - allocate DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT for builtins as for other -instructions. However, this fails to address over-allocation. Unlike regular -instructions, the execution of builtins is more predictable and usually +1. Do nothing and continue allocating 200k compute unit's for all non-compute +budget instructions. However, this fails to address over-allocation. Unlike +regular instructions, the execution of builtins is more predictable and usually requires significantly fewer CUs than BPF instructions. This approach would allocate more CUs than necessary, undermining the goal of efficient CU usage. From 0e6e0caa2d35a915ae2455dadf66a4ad8c1e8ae6 Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Wed, 20 Nov 2024 16:10:20 -0600 Subject: [PATCH 14/15] specify builtins need to be owned by native loader --- proposals/simd-0170-builtin-instruction-cost-and-budget.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index 82a11219d..39ca6399b 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -50,8 +50,9 @@ Invocations (CPIs) they do. This uniform limit is applied to each builtin program instruction and is used to configure both CU meter allocations and block producer CU limits reservation for all builtin instructions. -The static list of builtin program id's that will have 3000 compute units -allocated are: +The static list of builtin program id's that will have 3,000 compute units +allocated are listed below, note that the builtins must be owned by the native +loader. - Stake11111111111111111111111111111111111111 - Config1111111111111111111111111111111111111 From b523d2e8ee96e0189c31b85d06e117c8be198f77 Mon Sep 17 00:00:00 2001 From: Tao Zhu <82401714+tao-stones@users.noreply.github.com> Date: Wed, 20 Nov 2024 16:18:00 -0600 Subject: [PATCH 15/15] Update proposals/simd-0170-builtin-instruction-cost-and-budget.md Co-authored-by: Justin Starry --- proposals/simd-0170-builtin-instruction-cost-and-budget.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/simd-0170-builtin-instruction-cost-and-budget.md b/proposals/simd-0170-builtin-instruction-cost-and-budget.md index 39ca6399b..5ec73f1a2 100644 --- a/proposals/simd-0170-builtin-instruction-cost-and-budget.md +++ b/proposals/simd-0170-builtin-instruction-cost-and-budget.md @@ -51,8 +51,9 @@ program instruction and is used to configure both CU meter allocations and block producer CU limits reservation for all builtin instructions. The static list of builtin program id's that will have 3,000 compute units -allocated are listed below, note that the builtins must be owned by the native -loader. +allocated are listed below, note that when builtins are migrated to sBPF +programs, they MUST be removed from this list and have the default 200k +compute units allocated instead. - Stake11111111111111111111111111111111111111 - Config1111111111111111111111111111111111111