hirosystems / stacks-blockchain-api

API for the Stacks blockchain
https://stacks-blockchain-api.vercel.app
GNU General Public License v3.0
170 stars 108 forks source link

[Stacks 2.1] Support PoX-2 in Rosetta stacking operations #1278

Closed zone117x closed 1 year ago

zone117x commented 2 years ago

Progress:


See related issue https://github.com/hirosystems/stacks-blockchain-api/issues/1277 which goes over similar details and questions around PoX-2.

The Rosetta implementation currently contains rosetta-operations for initiating a Stacking transaction. It also returns a synthetic "stx-unlocked" operation when querying for a block operations, where the block corresponds to an unlock height provided in the Stacks node stx_lock_event event.

This was initially implemented in PR https://github.com/hirosystems/stacks-blockchain-api/pull/689

At a high level, here are the changes required to ensure Rosetta Stacking functionality works with Pox-2:

PoX address format changes

PoX-2 functions will support segwit/taproot/bech32 addresses. See https://github.com/stacks-network/stacks-blockchain/issues/2586. This means the function signatures that used to use { (hashbytes (buff 20)) (version (buff 1)) } will be switched to { (hashbytes (buff 32)) (version (buff 1)) } (32 hashbytes instead of 20). The allowed version bytes will also be expanded to include new address formats. Various areas of code that assumed a 1-to-1 conversion between a STX and BTC address (C32 and B58) need to be refactored -- as the new BTC address formats cannot be represented as STX addresses.

Constructing Stacking Operations

Rosetta has built-in support for performing various "Stacking" operations, which under the hood perform PoX-1 contract calls. These need to be changed to PoX-2 contract calls. IIRC, only the stack-stx operation is currently fully supported, and the code for the delegate-stx and revoke-delegate-stx isn't fully supported or tested. See code around RosettaOperationType.DelegateStx: https://github.com/hirosystems/stacks-blockchain-api/blob/aceb7afdc1b27d36603cb0acb167d2262c3d5360/src/api/routes/rosetta/construction.ts#L207-L248

Parsing Stacking Operations

When Rosetta is queried for a given block or transaction, it parses existing txs to display the various "Stacking" operations. This is done by scanning for hardcoded PoX-1 contract principals and contract function names. This need to support parsing PoX-2 contract calls as well. See code around here: https://github.com/hirosystems/stacks-blockchain-api/blob/aceb7afdc1b27d36603cb0acb167d2262c3d5360/src/rosetta-helpers.ts#L578-L586

New PoX-2 Stacking Operations

The following new PoX-2 operations need supported (for both parsing and construction the associated Rosetta operations):

zone117x commented 2 years ago

Note: blocked by https://github.com/hirosystems/stacks-blockchain-api/issues/1277 (and on the associated questions around stx_lock_event behavior for the new PoX-2 operations).

zone117x commented 2 years ago

@kantai, follow-up to https://github.com/hirosystems/stacks-blockchain-api/issues/1277#issuecomment-1218346400, after evaluating the current Rosetta implementation, I think we do need explicit events (print or otherwise) for the outcomes of the various stacking operations.

(Note it would also still be helpful to have that higher level StxBalanceUpdate event you proposed so the API doesn't have to evaluate event deltas to derive the current locked state).

The current Rosetta code for parsing Stacking operations is brittle. It scans for hardcoded PoX contract principals and contract function names, then parses the input args in order to generate a Stacking operation. IIUC, this means that if Stacking is initiated by another contract calling into PoX, then the Rosetta layer will be missing those operations.

I'm also somewhat wary of continuing the "contract-call-arg parsing" approach for the new Stacking operations. Seems like reading a PoX event is a lot less brittle and more future-proof. Thoughts?

zone117x commented 1 year ago

Update: MVP for PoX-2 support in Rosetta can just be parity with current PoX-1 support. That narrows the scope down to only supporting the stack-stx operation in PoX-2, and potentially only supporting legacy B58 bitcoin addresses (depends on how much more work and testing is required to get new bitcoin address formats supported).

This MVP still requires new logic in the tx construction where /v2/pox must be queried to determine which PoX contract ID should be used.

Additionally, there's a period of time where stack-stx operations can fail during the PoX-2 phase transitions. We can either A) let the Rosetta layer generate stacks-stx txs that will fail later on when it gets mined, or B) detect if the tx will fail and return an error to the client immediately.

zone117x commented 1 year ago

The MVP approach described in the previous comment was implemented in https://github.com/hirosystems/stacks-blockchain-api/pull/1339

The following critical issues still need addressed:

zone117x commented 1 year ago

Update: all but one of the remaining tasks for this issue are now complete.

@janniks is working on the last issue in PR https://github.com/hirosystems/stacks-blockchain-api/pull/1454

zone117x commented 1 year ago

Last task resolved in https://github.com/hirosystems/stacks-blockchain-api/pull/1454