diff --git a/sips/sip-039/sip-039-clarity5.md b/sips/sip-039/sip-039-clarity5.md new file mode 100644 index 00000000..700040b2 --- /dev/null +++ b/sips/sip-039/sip-039-clarity5.md @@ -0,0 +1,201 @@ +# Preamble + +SIP Number: 039 + +Title: Clarity 5: Fixing known issues in Clarity + +Author(s): + +- Brice Dobry + +Status: Activation-In-Progress + +Consideration: Governance, Technical + +Type: Consensus + +Layer: Consensus (hard fork) + +Created: 2025-01-16 + +License: BSD-2-Clause + +Sign-off: + +Discussions-To: + +- https://forum.stacks.org/t/clarity-5-and-epoch-3-4/18659 + +# Abstract + +This version of Clarity is being proposed solely to address and resolve +documented issues with existing functionality, specifically those that require a +hard-fork to change. The implementation for this SIP should only resolve +problems in the current Clarity implementation or make beneficial changes to +under-specified aspects of the Clarity language and virtual machine (VM). + +# Copyright + +This SIP is made available under the terms of the BSD-2-Clause license, +available at https://opensource.org/licenses/BSD-2-Clause. This SIP’s copyright +is held by the Stacks Open Internet Foundation. + +# Introduction + +This SIP intends to solve the known issues in the implementation of the Clarity +VM, without making any changes to the intended behavior of the Clarity language. + +# Specification + +## Resolve the discrepancy in `secp256r1-verify` described in SIP-035 + +In Clarity 5 and above, `secp256r1-verify` will no longer double-hash its input. +See [SIP-035](./sips/sip-035/sip-secp256r1-verify.md) for details. + +## Runtime error when passing an empty buffer to `from-consensus-buff?` + +Beginning in Clarity 5, computing the cost of passing an empty buffer to +`from-consensus-buff?` will no longer trigger a runtime error. Instead, the cost +will be charged appropriately, and the expression will return `none`, as +originally intended. See issue +[#6683](https://github.com/stacks-network/stacks-core/issues/6683). + +## Bug inside `at-block` expressions + +From issue [#6123](https://github.com/stacks-network/stacks-core/issues/6123): + +> Epoch 3 introduced a bug which causes `burn-block-height` to always return the +> current burn block height, even if inside of an `at-block` expression. This +> should be fixed to behave as expected in the next hard-fork. + +In addition to `burn-block-height`, it was also determined that this same error +effects `stx-account` and `stx-get-balance`. These two functions can return an +incorrect value inside of an `at-block` since the incorrect burn block height is +used to determine the locked status of the STX. + +In Clarity 5 and above, `burn-block-height` will return the correct value when +used inside of an `at-block` expression. + +## Increased stack depth + +Currently, the Clarity VM limits the call stack of a transaction execution to a +depth of 64 and several user applications have been hitting this limit recently. +This value was not specified in any previous SIPs, but was chosen to constrain +memory usage by the VM. Upon further testing, it has been determined that this +value can safely be increased to 128 without imposing unreasonable requirements +on Stacks node runners. Effective in epoch 3.4, the stack depth will be set +to 128. + +## Rejectable transactions + +Several kinds of errors have been avoided in the Clarity VM via a soft-fork +mechanism, causing transactions that trigger these problematic situations to be +rejected, not allowed to be included in a block. This strategy is useful for +quickly patching issues without requiring a hard-fork. However, once the +soft-fork is in place, the next time a hard-fork is executed, these errors can +all be transitioned to errors that can be included in a block. This is much +better for the network, since not including a transaction in a block has several +downsides: + +- Miners cannot charge a fee for processing the transaction +- Users may be confused as to why their transaction is not being included, + causing that transaction and all later transactions (with higher nonces) to + stall +- These unmineable transactions remain in the mempool, unprocessed, until they + age out + +With the upgrade to epoch 3.4, all known reachable "rejectable" errors will +become includable errors. + +## Allow trait use in same contract + +Currently, a trait defined in a contract cannot be used at the top-level of that +contract. For example, the code below will result in a `NoSuchContract` error. + +```clarity +(define-trait trait-1 ( + (foo + () + (response int int) + ) +)) +(define-private (bar (F )) + (unwrap-panic (contract-call? F foo)) +) +(bar .c-foo) +``` + +This behavior is a bit surprising. Beginning in Clarity 5, this usage will be +supported. See issue +[6831](https://github.com/stacks-network/stacks-core/issues/6831). + +## Allow `contract-call?` to constant + +Effective in Clarity 2, the type-checker does not complain about using a +constant as the target of a `contract-call?`, for example: + +```clarity +(define-constant MY_CONTRACT .contract-a) +(define-public (call-foo) + (contract-call? MY_CONTRACT foo) +) +``` + +Despite passing type-checking, this contract would fail during runtime, with an +error, `RuntimeCheckErrorKind::ContractCallExpectName`. This again is surprising +behavior. Beginning in epoch 3.4, this usage will be supported. + +# Related Work + +This SIP is focused on fixing consensus issues discovered in previous +implementations of Clarity, or improving behavior which is unspecified in prior +SIPs. The existing SIPs defining Clarity are: + +- [SIP-002 (Clarity)](../sip-002/sip-002-smart-contract-language.md) +- [SIP-015 (Clarity 2)](../sip-015/sip-015-network-upgrade.md) +- [SIP-021 (Clarity 3)](../sip-021/sip-021-nakamoto.md) +- [SIP-033 (Clarity 4)](../sip-033/sip-033-clarity4.md) + +# Backwards Compatibility + +Clarity 5 will be implemented with these changes while maintaining backwards +compatibility for previous versions of Clarity. Existing contracts will continue +to execute with the existing behavior, but new contracts will default to +Clarity 5. + +# Activation + +In order for this SIP to activate, the following criteria must be met: + +- At least 80 million stacked STX must vote, with at least 80% of all stacked + STX committed by voting must be in favor of the proposal (vote "yes"). +- At least 80% of all liquid STX committed by voting must be in favor of the + proposal (vote "yes"). + +All STX holders vote by sending Stacks dust to the corresponding Stacks address +from the account where their Stacks are held (stacked or liquid). To simplify +things, users can create their votes by visiting the +[ballot.gg](https://ballot.gg/67a34537-0375-4046-a4b7-432e8dfd4eb3/1MP9LjMBZRKXWq3tRio6nGwFyUoboozEQx) +platform. Voting power is determined by a snapshot of the amount of STX (stacked +and unstacked) at the block height at which the voting started (preventing the +same STX from being transferred between accounts and used to effectively double +vote). The voting addresses are also shared below. + +Solo stackers only can also vote by sending a bitcoin dust transaction (6000 +sats) to the corresponding bitcoin address. + +| Vote | Bitcoin | Stacks | ASCII Encoding | Msg | +| ---- | ------------------------------ | ----------------------------------- | ---------------------------------------- | ---------- | +| yes | 11111111111mdWK2VXcrA1eceSntcp | SP00000000001WPAWSDEDMQ0B9K76XTZ79N | 000000000000000000007965732d7369702d3339 | yes-sip-39 | +| no | 111111111111ACW5wa4RwyepZ84byy | SP000000000006WVSDEDMQ0B9K76JZVAKY | 00000000000000000000006e6f2d7369702d3339 | no-sip-39 | + +If the SIP is approved, epoch 3.4 will activate at Bitcoin block height 943000, +targeting March 30, 2026. + +# Reference Implementation + +At the time of this writing, the following public implementations are available +so far: + +- [`secp256r1-verify?` change](https://github.com/stacks-network/stacks-core/pull/6763) +- [`from-consensus-buff?` change](https://github.com/stacks-network/stacks-core/pull/6820)