Skip to content

Commit ab14ad5

Browse files
authored
fix: use correct pox-addr arg while parsing stack-stx bitcoin-op #415 (#1533)
1 parent ea01587 commit ab14ad5

File tree

2 files changed

+48
-18
lines changed

2 files changed

+48
-18
lines changed

src/event-stream/reader.ts

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ import {
2929
TxSpendingConditionSingleSigHashMode,
3030
decodeClarityValueList,
3131
} from 'stacks-encoding-native-js';
32-
import { DbMicroblockPartial, DbPox2DelegateStxEvent, DbPox2EventData } from '../datastore/common';
32+
import {
33+
DbMicroblockPartial,
34+
DbPox2DelegateStxEvent,
35+
DbPox2StackStxEvent,
36+
} from '../datastore/common';
3337
import { NotImplementedError } from '../errors';
3438
import {
3539
getEnumDescription,
@@ -79,7 +83,8 @@ function createTransactionFromCoreBtcStxLockEvent(
7983
event: StxLockEvent,
8084
burnBlockHeight: number,
8185
txResult: string,
82-
txId: string
86+
txId: string,
87+
stxStacksPox2Event: DbPox2StackStxEvent | undefined
8388
): DecodedTxResult {
8489
const resultCv = decodeClarityValue<
8590
ClarityValueResponse<
@@ -108,9 +113,14 @@ function createTransactionFromCoreBtcStxLockEvent(
108113

109114
const contractName = event.stx_lock_event.contract_identifier?.split('.')?.[1] ?? 'pox';
110115

116+
// If a pox-2 event is available then use its pox_addr, otherwise fallback to the stacker address
117+
const poxAddrArg = stxStacksPox2Event?.pox_addr
118+
? poxAddressToTuple(stxStacksPox2Event.pox_addr)
119+
: poxAddressToTuple(c32ToB58(stacker.address));
120+
111121
const legacyClarityVals = [
112122
uintCV(lockAmount.value), // amount-ustx
113-
poxAddressToTuple(c32ToB58(stacker.address)), // pox-addr
123+
poxAddrArg, // pox-addr
114124
uintCV(burnBlockHeight), // start-burn-height
115125
uintCV(lockPeriod), // lock-period
116126
];
@@ -363,13 +373,15 @@ export function parseMessageTransaction(
363373
(e): e is StxLockEvent => e.type === CoreNodeEventType.StxLockEvent
364374
);
365375

366-
const pox2Event = events.map(e => {
367-
if (
368-
e.type === CoreNodeEventType.ContractEvent &&
369-
e.contract_event.topic === 'print' &&
370-
(e.contract_event.contract_identifier === Pox2ContractIdentifer.mainnet ||
371-
e.contract_event.contract_identifier === Pox2ContractIdentifer.testnet)
372-
) {
376+
const pox2Event = events
377+
.filter(
378+
(e): e is SmartContractEvent =>
379+
e.type === CoreNodeEventType.ContractEvent &&
380+
e.contract_event.topic === 'print' &&
381+
(e.contract_event.contract_identifier === Pox2ContractIdentifer.mainnet ||
382+
e.contract_event.contract_identifier === Pox2ContractIdentifer.testnet)
383+
)
384+
.map(e => {
373385
const network = chainId === ChainID.Mainnet ? 'mainnet' : 'testnet';
374386
const decodedEvent = decodePox2PrintEvent(e.contract_event.raw_value, network);
375387
if (decodedEvent) {
@@ -378,20 +390,24 @@ export function parseMessageTransaction(
378390
decodedEvent,
379391
};
380392
}
381-
}
382-
return null;
383-
})[0];
393+
})
394+
.find(e => !!e);
384395

385396
if (stxTransferEvent) {
386397
rawTx = createTransactionFromCoreBtcTxEvent(chainId, stxTransferEvent, coreTx.txid);
387398
txSender = stxTransferEvent.stx_transfer_event.sender;
388399
} else if (stxLockEvent) {
400+
const stxStacksPox2Event =
401+
pox2Event?.decodedEvent.name === Pox2EventName.StackStx
402+
? pox2Event.decodedEvent
403+
: undefined;
389404
rawTx = createTransactionFromCoreBtcStxLockEvent(
390405
chainId,
391406
stxLockEvent,
392407
blockData.burn_block_height,
393408
coreTx.raw_result,
394-
coreTx.txid
409+
coreTx.txid,
410+
stxStacksPox2Event
395411
);
396412
txSender = stxLockEvent.stx_lock_event.locked_address;
397413
} else if (pox2Event && pox2Event.decodedEvent.name === Pox2EventName.DelegateStx) {

src/tests-2.1/pox-2-burnchain-stack-stx.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { RPCClient } from 'rpc-bitcoin';
3131
import * as supertest from 'supertest';
3232
import { Pox2ContractIdentifer } from '../pox-helpers';
3333
import { ClarityValueUInt, decodeClarityValue } from 'stacks-encoding-native-js';
34+
import { decodeBtcAddress } from '@stacks/stacking';
3435

3536
// Perform Stack-STX operation on Bitcoin.
3637
// See https://github.com/stacksgov/sips/blob/0da29c6911c49c45e4125dbeaed58069854591eb/sips/sip-007/sip-007-stacking-consensus.md#stx-operations-on-bitcoin
@@ -39,6 +40,7 @@ async function createPox2StackStx(args: {
3940
cycleCount: number;
4041
stackerAddress: string;
4142
bitcoinWif: string;
43+
poxAddrPayout: string;
4244
}) {
4345
const btcAccount = ECPair.fromWIF(args.bitcoinWif, btc.networks.regtest);
4446
const feeAmount = 0.0001;
@@ -116,7 +118,7 @@ async function createPox2StackStx(args: {
116118
})
117119
// The second Bitcoin output will be used as the reward address for any stacking rewards.
118120
.addOutput({
119-
address: c32ToB58(args.stackerAddress),
121+
address: args.poxAddrPayout,
120122
value: Math.round(outAmount1 - feeAmount * sats),
121123
})
122124
.signInput(0, btcAccount)
@@ -145,6 +147,11 @@ describe('PoX-2 - Stack using Bitcoin-chain ops', () => {
145147
const accountKey = '72e8e3725324514c38c2931ed337ab9ab8d8abaae83ed2275456790194b1fd3101';
146148
let account: Account;
147149

150+
// testnet btc addr: tb1pf4x64urhdsdmadxxhv2wwjv6e3evy59auu2xaauu3vz3adxtskfschm453
151+
// regtest btc addr: bcrt1pf4x64urhdsdmadxxhv2wwjv6e3evy59auu2xaauu3vz3adxtskfs4w3npt
152+
const poxAddrPayoutKey = 'c71700b07d520a8c9731e4d0f095aa6efb91e16e25fb27ce2b72e7b698f8127a01';
153+
let poxAddrPayoutAccount: Account;
154+
148155
let testAccountBalance: bigint;
149156
const testAccountBtcBalance = 5;
150157
let testStackAmount: bigint;
@@ -159,6 +166,7 @@ describe('PoX-2 - Stack using Bitcoin-chain ops', () => {
159166
({ db, api, client, stacksNetwork, bitcoinRpcClient } = testEnv);
160167

161168
account = accountFromKey(accountKey);
169+
poxAddrPayoutAccount = accountFromKey(poxAddrPayoutKey, 'p2tr');
162170

163171
const poxInfo = await client.getPox();
164172
const [contractAddress, contractName] = poxInfo.contract_id.split('.');
@@ -246,6 +254,7 @@ describe('PoX-2 - Stack using Bitcoin-chain ops', () => {
246254
stxOpBtcTxs = await createPox2StackStx({
247255
bitcoinWif: account.wif,
248256
stackerAddress: account.stxAddr,
257+
poxAddrPayout: poxAddrPayoutAccount.btcAddr,
249258
stxAmount: testStackAmount,
250259
cycleCount: 6,
251260
});
@@ -298,11 +307,16 @@ describe('PoX-2 - Stack using Bitcoin-chain ops', () => {
298307
expect(callArg1.name).toBe('amount-ustx');
299308
expect(BigInt(decodeClarityValue<ClarityValueUInt>(callArg1.hex).value)).toBe(testStackAmount);
300309

310+
const expectedPoxPayoutAddr = decodeBtcAddress(poxAddrPayoutAccount.btcTestnetAddr);
311+
const expectedPoxPayoutAddrRepr = `(tuple (hashbytes 0x${Buffer.from(
312+
expectedPoxPayoutAddr.data
313+
).toString('hex')}) (version 0x${Buffer.from([expectedPoxPayoutAddr.version]).toString(
314+
'hex'
315+
)}))`;
301316
const callArg2 = txObj.contract_call.function_args![1];
302317
expect(callArg2.name).toBe('pox-addr');
303-
const callArg2Addr = decodePoxAddrArg(callArg2.hex);
304-
expect(callArg2Addr.stxAddr).toBe(account.stxAddr);
305-
expect(callArg2Addr.btcAddr).toBe(account.btcAddr);
318+
expect(callArg2.type).toBe('(tuple (hashbytes (buff 32)) (version (buff 1)))');
319+
expect(callArg2.repr).toBe(expectedPoxPayoutAddrRepr);
306320
});
307321

308322
// TODO: this is very flaky

0 commit comments

Comments
 (0)