Skip to content

Commit b28c744

Browse files
authored
chore: split up pox-2-rosetta tests (#1461)
* chore: split up pox-2-rosetta tests * chore: split up pox-2-rosetta test suites into smaller units
1 parent 26033a6 commit b28c744

File tree

5 files changed

+161
-164
lines changed

5 files changed

+161
-164
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,9 @@ jobs:
411411
pox-2-delegate-aggregation,
412412
pox-2-delegate-stacking,
413413
pox-2-stack-extend-increase,
414-
pox-2-rosetta
414+
pox-2-rosetta-btc-addr-types,
415+
pox-2-rosetta-cycle-phases,
416+
pox-2-rosetta-segwit,
415417
]
416418
runs-on: ubuntu-latest
417419
steps:
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { getBitcoinAddressFromKey } from '../ec-helpers';
2+
import { testnetKeys } from '../api/routes/debug';
3+
import {
4+
fetchGet,
5+
stackStxWithRosetta,
6+
standByUntilBurnBlock,
7+
testEnv,
8+
} from '../test-utils/test-helpers';
9+
import { CoreRpcPoxInfo } from '../core-rpc/client';
10+
import { DbTxStatus } from '../datastore/common';
11+
import { BurnchainRewardSlotHolderListResponse } from '@stacks/stacks-blockchain-api-types';
12+
13+
const BTC_ADDRESS_CASES = [
14+
{ addressFormat: 'p2pkh' },
15+
{ addressFormat: 'p2sh' },
16+
{ addressFormat: 'p2sh-p2wpkh' },
17+
{ addressFormat: 'p2sh-p2wsh' },
18+
{ addressFormat: 'p2wpkh' },
19+
{ addressFormat: 'p2wsh' },
20+
{ addressFormat: 'p2tr' },
21+
] as const;
22+
23+
describe.each(BTC_ADDRESS_CASES)(
24+
'PoX-2 - Rosetta - Stack with BTC address format $addressFormat',
25+
({ addressFormat }) => {
26+
let poxInfo: CoreRpcPoxInfo;
27+
const account = testnetKeys[1];
28+
let bitcoinAddress: string;
29+
30+
beforeAll(() => {
31+
bitcoinAddress = getBitcoinAddressFromKey({
32+
privateKey: account.secretKey,
33+
network: 'testnet',
34+
addressFormat,
35+
});
36+
});
37+
38+
test('Standby for next cycle', async () => {
39+
poxInfo = await testEnv.client.getPox();
40+
await standByUntilBurnBlock(poxInfo.next_cycle.reward_phase_start_block_height); // a good time to stack
41+
// await standByForPoxCycle(); DON'T USE THIS!!! <cycle>.id is lying to you!
42+
});
43+
44+
test('Perform stack-stx using Rosetta', async () => {
45+
poxInfo = await testEnv.client.getPox();
46+
expect(poxInfo.next_cycle.blocks_until_reward_phase).toBe(poxInfo.reward_cycle_length); // cycle just started
47+
48+
const ustxAmount = BigInt(Math.round(Number(poxInfo.min_amount_ustx) * 1.1).toString());
49+
const cycleCount = 1;
50+
51+
const rosettaStackStx = await stackStxWithRosetta({
52+
btcAddr: bitcoinAddress,
53+
stacksAddress: account.stacksAddress,
54+
pubKey: account.pubKey,
55+
privateKey: account.secretKey,
56+
cycleCount,
57+
ustxAmount,
58+
});
59+
expect(rosettaStackStx.tx.status).toBe(DbTxStatus.Success);
60+
expect(rosettaStackStx.constructionMetadata.metadata.contract_name).toBe('pox-2');
61+
});
62+
63+
test('Validate reward set received', async () => {
64+
// todo: is it correct that the reward set is only available after/in the 2nd block of a reward phase?
65+
await standByUntilBurnBlock(poxInfo.next_cycle.reward_phase_start_block_height + 1); // time to check reward sets
66+
67+
poxInfo = await testEnv.client.getPox();
68+
const rewardSlotHolders = await fetchGet<BurnchainRewardSlotHolderListResponse>(
69+
`/extended/v1/burnchain/reward_slot_holders/${bitcoinAddress}`
70+
);
71+
expect(rewardSlotHolders.total).toBe(1);
72+
expect(rewardSlotHolders.results[0].address).toBe(bitcoinAddress);
73+
expect(rewardSlotHolders.results[0].burn_block_height).toBe(
74+
poxInfo.current_burnchain_block_height
75+
);
76+
expect(poxInfo.next_cycle.blocks_until_reward_phase).toBe(
77+
poxInfo.reward_cycle_length - (2 - 1) // aka 2nd / nth block of reward phase (zero-indexed)
78+
);
79+
});
80+
}
81+
);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { testnetKeys } from '../api/routes/debug';
2+
import { stackStxWithRosetta, standByUntilBurnBlock, testEnv } from '../test-utils/test-helpers';
3+
4+
const REWARD_CYCLE_LENGTH = 5; // assuming regtest
5+
const BLOCK_SHIFT_COUNT: { shift: number }[] = [];
6+
for (let shift = 0; shift < REWARD_CYCLE_LENGTH; shift++) {
7+
BLOCK_SHIFT_COUNT.push({ shift });
8+
}
9+
10+
const account = testnetKeys[1];
11+
const btcAddr = '2N74VLxyT79VGHiBK2zEg3a9HJG7rEc5F3o';
12+
13+
describe.each(BLOCK_SHIFT_COUNT)(
14+
'PoX-2 - Rosetta - Stack on any phase of cycle $shift',
15+
({ shift }) => {
16+
test('Standby for cycle phase', async () => {
17+
const poxInfo = await testEnv.client.getPox();
18+
19+
const blocksUntilNextCycle =
20+
poxInfo.next_cycle.blocks_until_reward_phase % poxInfo.reward_cycle_length;
21+
const startHeight =
22+
(poxInfo.current_burnchain_block_height as number) + blocksUntilNextCycle + shift;
23+
24+
if (startHeight !== poxInfo.current_burnchain_block_height) {
25+
// only stand-by if we're not there yet
26+
await standByUntilBurnBlock(startHeight);
27+
}
28+
});
29+
30+
test('Rosetta - stack-stx tx', async () => {
31+
const poxInfo = await testEnv.client.getPox();
32+
const ustxAmount = BigInt(poxInfo.current_cycle.min_threshold_ustx * 1.2);
33+
expect((poxInfo.current_burnchain_block_height as number) % poxInfo.reward_cycle_length).toBe(
34+
shift
35+
);
36+
37+
await stackStxWithRosetta({
38+
stacksAddress: account.stacksAddress,
39+
privateKey: account.secretKey,
40+
pubKey: account.pubKey,
41+
cycleCount: 1,
42+
ustxAmount,
43+
btcAddr,
44+
});
45+
});
46+
47+
test('Wait for unlock', async () => {
48+
const coreBalance = await testEnv.client.getAccount(account.stacksAddress);
49+
expect(coreBalance.unlock_height).toBeGreaterThan(0);
50+
51+
await standByUntilBurnBlock(coreBalance.unlock_height + 1);
52+
});
53+
}
54+
);

0 commit comments

Comments
 (0)