Replies: 7 comments 2 replies
-
Thanks for taking the time to break this into issues @kantai! Just reiterating something we talked about, we have a choice in whether or not to cause contract-calls into |
Beta Was this translation helpful? Give feedback.
-
Maybe you could avoid the double negation on |
Beta Was this translation helpful? Give feedback.
-
Thanks for the update, @kantai! I also favor of the But that said, I still favor the |
Beta Was this translation helpful? Give feedback.
-
We're considering at a "period 2" length of 2 reward cycles, or about 4 weeks. This will give Stackers and pool operators time to migrate to the new |
Beta Was this translation helpful? Give feedback.
-
A question for the stakeholders: how should the migration to
The first option keeps old |
Beta Was this translation helpful? Give feedback.
-
I've gotten no feedback since the above comment, but we're coming up to the point where we have to make a decision. Right now, there are three non-trivial contracts that call into Just looking at the code for these three contracts, I think contract-call interposition is still on the table. It doesn't look like anything would break if we did contract-call interposition today. None of the calls to stack (or delegate-stack) do any additional block height checks to prevent callers from stacking too early, so they should just work with continuous stacking. I don't think we anticipate changing the return types of any of the existing read-only methods (which are used quite often), so that's probably not an issue. However, if we just keep the interfaces the same, it would be just as easy to re-deploy these (and future) contracts to just call into |
Beta Was this translation helpful? Give feedback.
-
For Boom, we set block-height limits on our Boombox implementations so we will not have pox-related contracts that span the migration period. It's easy enough for us to route around any changes. |
Beta Was this translation helpful? Give feedback.
-
The goal of this topic is to outline a plan and link together the related issues for implementing an upgrade to PoX at the network upgrade of Stacks 2.1. This is also a place for discussion of the impacts of this plan, receiving feedback on the plan, suggestions for additional changes.
High-level Approach
At the launch of Stacks 2.1, a new
pox-2
contract will be published. Thestacks-node
consensus algorithm will use the newpox-2
contract for determining PoX reward sets and governing PoX locks. Existing calls to the originalpox
contract will be re-routed topox-2
.The new PoX contract operates exclusively with PoX state that was created by itself. To do so, a particular reward cycle N is chosen as the “Last PoX 2.0” reward cycle, and then the first PoX 2.1 reward cycle is the subsequent cycle (N+1).
This defines three “periods” of PoX operation:
pox-2.lock-extend
, which allows an account to re-lock for some subsequent number of reward cycles while still being locked.delegate-lock-extend
stack-stx
,delegate-stack-stx
,stack-aggregation-commit
, andreject-pox
.Consequences of this approach
stack-stx
11 cycles before they would have otherwise needed to.allow-contract-caller
would need to re-initialize those relationships.Semantics
Behavior during "Period 2"
Original PoX Contract
stack-stx
lock-period
that extends into Period 3, this function will yield a runtime error, and not impart any state changesstack-aggregation-commit
reward-cycle >= N+1
, this function will yield a runtime error, and not impart any state changesdelegate-stack-stx
lock-period
that extends into Period 3, this function will yield a runtime error, and not impart any state changesstacker
that already has performed a locking operation via the PoX 2.1 contract, this function will yield a runtime error, and not impart any state changesreject-pox
>= N+1
, this function will yield a runtime error and not impart any state changesset-burnchain-parameters
This method will behave exactly as it did before. There will be no contract-call interposition to prevent it from being called
disallow-contract-caller
This method will behave exactly as it did before. There will be no contract-call interposition to prevent it from being called
allow-contract-caller
This method will behave exactly as it did before. There will be no contract-call interposition to prevent it from being called
revoke-delegate-stx
This method will behave exactly as it did before. There will be no contract-call interposition to prevent it from being called
delegate-stx
This method will behave exactly as it did before. There will be no contract-call interposition to prevent it from being called
PoX 2 Contract
stack-stx
lock-period
that includes any cycles in Period 2, this function will yield a runtime error and not impart any state changesstack-aggregation-commit
reward-cycle < N + 1
, this function will yield a runtime error and not impart any state changesdelegate-stack-stx
lock-period
that includes any cycles in Period 2, this function will yield a runtime error and not impart any state changesreject-pox
< N+1
, this function will yield a runtime error and not impart any state changesset-burnchain-parameters
This method will always behave the same
disallow-contract-caller
This method will always behave the same
allow-contract-caller
This method will always behave the same
revoke-delegate-stx
This method will always behave the same
delegate-stx
This method will always behave the same
lock-extend
>= N + 1
, then this function operates “normally”. It is able to insert state for the extended-into reward cycles in the 2.1 contract< N + 1
, the the function yields a runtime errordelegate-lock-extend
stack-increase
< N + 1
, then this function yields a runtime error.delegate-stack-increase
< N + 1
, then this function yields a runtime error.Behavior During "Period 3"
Original PoX Contract
All contract-calls to the PoX contract are interposed on and re-routed to the PoX 2.1 contract.
This is done to reduce the tooling upgrades that would otherwise be required by the whole network and to allow contracts that already depended on PoX functionality to continue to operate without themselves needing to produce new contracts.
PoX 2.1 Contract
All behaviors for the PoX 2.1 contract in this period should now be the "normal" contract behavior.
Implementing "Mass Unlock" at Cycle N
The VM should implement the "mass unlock" at Cycle N lazily. Basically, if the account locking state was set by the original PoX contract, then perform the "account unlock" lazy update (it is already implemented lazily) as if the unlock height were the end of Cycle N. To do this check, the VM needs to be able to differentiate between account states set by the original PoX contract and the new PoX contract.
To do this, we should update the
STXBalance
struct from:to
Where serialization of
Unlocked
andLockedPoxOne
use the current 40-byte serialization:and serialization of
LockedPoxTwo
uses a 41-byte serializationWhen deserializing, if
amount_locked = 0
, it deserializes toUnlocked
.New Features and Behavior Updates
PoX Contract Functions
stack-unlock
#2534stack-extend
anddelegate-stack-extend
#2532stack-increase
#2533New Native Functions
All of these are captured in #2538
Behavior Updates
Plumbing for the 2.1 Changes
pox
->pox-v2
: PoX Updates: Implement 2.1 data port frompox
->pox-v2
#2536Anchor block selection
Discussion
pox-2
vspox-extension
approach trade-offsThere are two good options for how to upgrade the existing PoX contract:
pox-2
contract - this would be a new contract, with existing PoX functions updated and new functions added. Function calls and transactions against the originalpox
contract would be re-routed by the Clarity VM to the new contract.pox-extension
contract - this would be a new contract with exclusively new functionality. The contract would be implemented not in Clarity, but as a "simulated" contract, where the function calls are re-routed to a native implementation capable of operating on the originalpox
contract's data.Outright replacing the existing PoX contract should be avoided -- one of the fundamental assumptions made by the Clarity VM is that a particular contract can only be published "once".
One way to think about the trade-offs with these approaches is looking at the potential benefits to each:
pox
contract remains usableIn both approaches, some kind of function interception is required: (a) the extension approach requires intercepting calls to
pox-extension
and replacing them with native implementations and (b) thepox-2
approach requires intercepting calls topox
and rerouting them to calls topox-2
. The main benefit to the extension approach is that the originalpox
contract remains directly callable. However, thepox-2
approach allows the new contract to behave more similarly to a normal Clarity contract and it allows existing behaviors to either be updated or fixed. Because of this, I think thepox-2
approach is the better strategy, however, suggestions and discussion are still appreciated here.Beta Was this translation helpful? Give feedback.
All reactions