-
Notifications
You must be signed in to change notification settings - Fork 679
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add delegate-stack-extend command #4610
Merged
moodmosaic
merged 1 commit into
feat/pox-4-stateful-property-testing
from
feat/pox-4-delegate-stack-extend
Apr 2, 2024
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
160 changes: 160 additions & 0 deletions
160
contrib/core-contract-tests/tests/pox-4/pox_DelegateStackExtendCommand.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
import { | ||
logCommand, | ||
PoxCommand, | ||
Real, | ||
Stub, | ||
Wallet, | ||
} from "./pox_CommandModel.ts"; | ||
import { poxAddressToTuple } from "@stacks/stacking"; | ||
import { assert, expect } from "vitest"; | ||
import { | ||
Cl, | ||
ClarityType, | ||
isClarityType, | ||
} from "@stacks/transactions"; | ||
import { | ||
FIRST_BURNCHAIN_BLOCK_HEIGHT, | ||
REWARD_CYCLE_LENGTH, | ||
} from "./pox_Commands.ts"; | ||
|
||
/** | ||
* The `DelegateStackExtendCommand` allows a pool operator to | ||
* extend an active stacking lock, issuing a "partial commitment" | ||
* for the extended-to cycles. | ||
* | ||
* This method extends stacker's current lockup for an additional | ||
* extend-count and partially commits those new cycles to `pox-addr`. | ||
* | ||
* Constraints for running this command include: | ||
* - Stacker must have locked uSTX. | ||
* - The Operator has to currently be delegated by the Stacker. | ||
* - The new lock period must be less than or equal to 12. | ||
*/ | ||
export class DelegateStackExtendCommand implements PoxCommand { | ||
readonly operator: Wallet; | ||
readonly stacker: Wallet; | ||
readonly extendCount: number; | ||
readonly currentCycle: number; | ||
|
||
/** | ||
* Constructs a `DelegateStackExtendCommand` to extend the unlock | ||
* height as a Pool Operator on behalf of a Stacker. | ||
* | ||
* @param operator - Represents the Pool Operator's wallet. | ||
* @param stacker - Represents the STacker's wallet. | ||
* @param extendCount - Represents the cycles to be expended. | ||
* @param currentCycle - Represents the current PoX reward cycle. | ||
*/ | ||
constructor( | ||
operator: Wallet, | ||
stacker: Wallet, | ||
extendCount: number, | ||
currentCycle: number, | ||
) { | ||
this.operator = operator; | ||
this.stacker = stacker; | ||
this.extendCount = extendCount; | ||
this.currentCycle = currentCycle; | ||
} | ||
|
||
check(model: Readonly<Stub>): boolean { | ||
// Constraints for running this command include: | ||
// - Stacker must have locked uSTX. | ||
// - The Stacker's uSTX must have been locked by the Operator. | ||
// - The Operator has to currently be delegated by the Stacker. | ||
// - The new lock period must be less than or equal to 12. | ||
|
||
const operatorWallet = model.wallets.get(this.operator.stxAddress)!; | ||
const stackerWallet = model.wallets.get(this.stacker.stxAddress)!; | ||
|
||
const firstRewardCycle = | ||
this.currentCycle > this.stacker.firstLockedRewardCycle | ||
? this.currentCycle | ||
: this.stacker.firstLockedRewardCycle; | ||
const firstExtendCycle = Math.floor( | ||
(this.stacker.unlockHeight - FIRST_BURNCHAIN_BLOCK_HEIGHT) / | ||
REWARD_CYCLE_LENGTH, | ||
); | ||
const lastExtendCycle = firstExtendCycle + this.extendCount - 1; | ||
const totalPeriod = lastExtendCycle - firstRewardCycle + 1; | ||
|
||
return ( | ||
stackerWallet.amountLocked > 0 && | ||
stackerWallet.hasDelegated === true && | ||
stackerWallet.isStacking === true && | ||
operatorWallet.poolMembers.includes(stackerWallet.stxAddress) && | ||
operatorWallet.lockedAddresses.includes(stackerWallet.stxAddress) && | ||
totalPeriod <= 12 | ||
); | ||
} | ||
|
||
run(model: Stub, real: Real): void { | ||
model.trackCommandRun(this.constructor.name); | ||
|
||
// Act | ||
const delegateStackExtend = real.network.callPublicFn( | ||
"ST000000000000000000002AMW42H.pox-4", | ||
"delegate-stack-extend", | ||
[ | ||
// (stacker principal) | ||
Cl.principal(this.stacker.stxAddress), | ||
// (pox-addr { version: (buff 1), hashbytes: (buff 32) }) | ||
poxAddressToTuple(this.stacker.delegatedPoxAddress), | ||
// (extend-count uint) | ||
Cl.uint(this.extendCount), | ||
], | ||
this.operator.stxAddress, | ||
); | ||
|
||
const { result: firstExtendCycle } = real.network.callReadOnlyFn( | ||
"ST000000000000000000002AMW42H.pox-4", | ||
"burn-height-to-reward-cycle", | ||
[Cl.uint(this.stacker.unlockHeight)], | ||
this.operator.stxAddress, | ||
); | ||
assert(isClarityType(firstExtendCycle, ClarityType.UInt)); | ||
|
||
const lastExtendCycle = Number(firstExtendCycle.value) + this.extendCount - | ||
1; | ||
|
||
const { result: extendedUnlockHeight } = real.network.callReadOnlyFn( | ||
"ST000000000000000000002AMW42H.pox-4", | ||
"reward-cycle-to-burn-height", | ||
[Cl.uint(lastExtendCycle + 1)], | ||
this.operator.stxAddress, | ||
); | ||
assert(isClarityType(extendedUnlockHeight, ClarityType.UInt)); | ||
const newUnlockHeight = extendedUnlockHeight.value; | ||
|
||
// Assert | ||
expect(delegateStackExtend.result).toBeOk( | ||
Cl.tuple({ | ||
stacker: Cl.principal(this.stacker.stxAddress), | ||
"unlock-burn-height": Cl.uint(newUnlockHeight), | ||
}), | ||
); | ||
|
||
// Get the Stacker's wallet from the model and update it with the new state. | ||
const stackerWallet = model.wallets.get(this.stacker.stxAddress)!; | ||
// Update model so that we know this wallet's unlock height was extended. | ||
stackerWallet.unlockHeight = Number(newUnlockHeight); | ||
|
||
// Log to console for debugging purposes. This is not necessary for the | ||
// test to pass but it is useful for debugging and eyeballing the test. | ||
logCommand( | ||
`✓ ${this.operator.label} Ӿ ${this.stacker.label}`, | ||
"delegate-stack-extend", | ||
"extend count", | ||
this.extendCount.toString(), | ||
"new unlock height", | ||
this.stacker.unlockHeight.toString(), | ||
); | ||
} | ||
|
||
toString() { | ||
// fast-check will call toString() in case of errors, e.g. property failed. | ||
// It will then make a minimal counterexample, a process called 'shrinking' | ||
// https://github.com/dubzzz/fast-check/issues/2864#issuecomment-1098002642 | ||
return `${this.operator.label} delegate-stack-extend extend count ${this.extendCount} previous unlock height ${this.stacker.unlockHeight}`; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need this value? You are substracting one and adding one afterwards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@friedger I am doing this to simulate how the lock period is calculated inside PoX-4 contract