diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ef61e682e..19a6db61a6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -921,7 +921,7 @@ jobs: type=ref,event=pr type=semver,pattern={{version}},value=${{ steps.semantic.outputs.new_release_version }},enable=${{ steps.semantic.outputs.new_release_version != '' }} type=semver,pattern={{major}}.{{minor}},value=${{ steps.semantic.outputs.new_release_version }},enable=${{ steps.semantic.outputs.new_release_version != '' }} - type=raw,value=latest,enable={{is_default_branch}} + type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'master') }} - name: Login to DockerHub uses: docker/login-action@v3 diff --git a/README.md b/README.md index eb496481b2..9be736f79b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![CI](https://github.com/hirosystems/stacks-blockchain-api/actions/workflows/ci.yml/badge.svg)](https://github.com/hirosystems/stacks-blockchain-api/actions/workflows/ci.yml) [![GitHub Releases](https://img.shields.io/github/v/release/hirosystems/stacks-blockchain-api?display_name=release)](https://github.com/hirosystems/stacks-blockchain-api/releases/latest) -[![Docker Pulls](https://img.shields.io/docker/pulls/blockstack/stacks-blockchain-api-standalone)](https://hub.docker.com/r/hirosystems/stacks-blockchain-api-standalone/) +[![Docker Pulls](https://img.shields.io/docker/pulls/blockstack/stacks-blockchain-api)](https://hub.docker.com/r/hirosystems/stacks-blockchain-api/) [![NPM client package](https://img.shields.io/badge/npm-%40stacks%2Fblockchain--api--client-blue)](https://www.npmjs.org/package/@stacks/blockchain-api-client) ## Quick start diff --git a/client/README.md b/client/README.md index 4087009b7c..899c5ef2cd 100644 --- a/client/README.md +++ b/client/README.md @@ -45,14 +45,12 @@ await sub.unsubscribe(); ### Socket.io ```js -import { io } from "socket.io-client"; -import * as stacks from '@stacks/blockchain-api-client'; +import { StacksApiSocketClient } from '@stacks/blockchain-api-client'; -// for testnet, replace with https://api.testnet.hiro.so/ -const socketUrl = "https://api.mainnet.hiro.so/"; +// for testnet, replace with https://api.testnet.hiro.so +const socketUrl = "https://api.mainnet.hiro.so"; -const socket = io(socketUrl); -const sc = new stacks.StacksApiSocketClient(socket); +const sc = new StacksApiSocketClient({ url: socketUrl }); sc.subscribeAddressTransactions('ST3GQB6WGCWKDNFNPSQRV8DY93JN06XPZ2ZE9EVMA', (address, tx) => { console.log('address:', address); diff --git a/client/src/socket-io/index.ts b/client/src/socket-io/index.ts index 913bb490ce..f8dedb695c 100644 --- a/client/src/socket-io/index.ts +++ b/client/src/socket-io/index.ts @@ -46,6 +46,9 @@ function createStacksApiSocket(opts?: StacksApiSocketConnectionOptions) { subscriptions: Array.from(new Set(opts?.subscriptions)).join(','), }, }; + if (!socketOpts.transports) { + socketOpts.transports = ['websocket']; + } const socket: StacksApiSocket = io(getWsUrl(opts?.url ?? BASE_PATH).href, socketOpts); return socket; } diff --git a/docker/docker-compose.dev.stacks-blockchain.yml b/docker/docker-compose.dev.stacks-blockchain.yml index c226fafb59..2a353119ea 100644 --- a/docker/docker-compose.dev.stacks-blockchain.yml +++ b/docker/docker-compose.dev.stacks-blockchain.yml @@ -1,7 +1,7 @@ version: '3.7' services: stacks-blockchain: - image: 'hirosystems/stacks-api-e2e:stacks3.0-4d11d85' + image: 'hirosystems/stacks-api-e2e:stacks3.0-0a2c0e2' restart: on-failure environment: STACKS_EVENT_OBSERVER: host.docker.internal:3700 diff --git a/docker/docker-compose.dev.stacks-krypton.yml b/docker/docker-compose.dev.stacks-krypton.yml index acf25aefea..6e3ebb6908 100644 --- a/docker/docker-compose.dev.stacks-krypton.yml +++ b/docker/docker-compose.dev.stacks-krypton.yml @@ -1,7 +1,7 @@ version: '3.7' services: stacks-blockchain: - image: 'hirosystems/stacks-api-e2e:stacks3.0-4d11d85' + image: 'hirosystems/stacks-api-e2e:stacks3.0-0a2c0e2' ports: - '18443:18443' # bitcoin regtest JSON-RPC interface - '18444:18444' # bitcoin regtest p2p diff --git a/docs/api/rosetta/rosetta-network-status-response.schema.json b/docs/api/rosetta/rosetta-network-status-response.schema.json index da898e8af9..a272d40482 100644 --- a/docs/api/rosetta/rosetta-network-status-response.schema.json +++ b/docs/api/rosetta/rosetta-network-status-response.schema.json @@ -6,7 +6,8 @@ "current_block_identifier", "current_block_timestamp", "genesis_block_identifier", - "peers" + "peers", + "current_burn_block_height" ], "properties": { "current_block_identifier": { @@ -31,6 +32,10 @@ "items": { "$ref": "./../../entities/rosetta/rosetta-network-peers.schema.json" } + }, + "current_burn_block_height": { + "type": "integer", + "description": "The latest burn block height" } }, "additionalProperties": false diff --git a/docs/api/stacking/get-pox-cycle-signers.example.json b/docs/api/stacking/get-pox-cycle-signers.example.json index fa7499dd80..60dd71a15d 100644 --- a/docs/api/stacking/get-pox-cycle-signers.example.json +++ b/docs/api/stacking/get-pox-cycle-signers.example.json @@ -5,6 +5,7 @@ "results": [ { "signing_key": "0x038e3c4529395611be9abf6fa3b6987e81d402385e3d605a073f42f407565a4a3d", + "signer_address": "STRYYQQ9M8KAF4NS7WNZQYY59X93XEKR31JP64CP", "stacked_amount": "686251350000000000", "stacked_amount_percent": 50, "weight": 5, @@ -12,6 +13,7 @@ }, { "signing_key": "0x029874497a7952483aa23890e9d0898696f33864d3df90939930a1f45421fe3b09", + "signer_address": "STF9B75ADQAVXQHNEQ6KGHXTG7JP305J2GRWF3A2", "stacked_amount": "457500900000000000", "stacked_amount_percent": 33.333333333333336, "weight": 3, @@ -19,6 +21,7 @@ }, { "signing_key": "0x02dcde79b38787b72d8e5e0af81cffa802f0a3c8452d6b46e08859165f49a72736", + "signer_address": "ST18MDW2PDTBSCR1ACXYRJP2JX70FWNM6YY2VX4SS", "stacked_amount": "228750450000000000", "stacked_amount_percent": 16.666666666666668, "weight": 1, diff --git a/docs/entities/rosetta/rosetta-block.schema.json b/docs/entities/rosetta/rosetta-block.schema.json index 9f9f92bd49..8c99d829ae 100644 --- a/docs/entities/rosetta/rosetta-block.schema.json +++ b/docs/entities/rosetta/rosetta-block.schema.json @@ -2,7 +2,7 @@ "type": "object", "title": "RosettaBlock", "description": "Blocks contain an array of Transactions that occurred at a particular BlockIdentifier. A hard requirement for blocks returned by Rosetta implementations is that they MUST be inalterable: once a client has requested and received a block identified by a specific BlockIndentifier, all future calls for that same BlockIdentifier must return the same block contents.", - "required": ["block_identifier", "parent_block_identifier", "timestamp", "transactions"], + "required": ["block_identifier", "parent_block_identifier", "timestamp", "transactions", "metadata"], "additionalProperties": false, "properties": { "block_identifier": { @@ -25,14 +25,10 @@ "metadata": { "type": "object", "description": "meta data", - "required": ["transactions_root", "difficulty"], + "required": ["burn_block_height"], "properties": { - "transactions_root": { - "type": "string", - "description": "" - }, - "difficulty": { - "type": "string", + "burn_block_height": { + "type": "number", "description": "" } } diff --git a/docs/entities/stacking/signer.example.json b/docs/entities/stacking/signer.example.json index e7b0dcd7cf..b4e17c4146 100644 --- a/docs/entities/stacking/signer.example.json +++ b/docs/entities/stacking/signer.example.json @@ -1,5 +1,6 @@ { "signing_key": "0x038e3c4529395611be9abf6fa3b6987e81d402385e3d605a073f42f407565a4a3d", + "signer_address": "STRYYQQ9M8KAF4NS7WNZQYY59X93XEKR31JP64CP", "stacked_amount": "686251350000000000", "stacked_amount_percent": 50, "weight": 5, diff --git a/docs/entities/stacking/signer.schema.json b/docs/entities/stacking/signer.schema.json index 8b1c62a38f..46d0e9b460 100644 --- a/docs/entities/stacking/signer.schema.json +++ b/docs/entities/stacking/signer.schema.json @@ -4,6 +4,7 @@ "additionalProperties": false, "required": [ "signing_key", + "signer_address", "weight", "stacked_amount", "weight_percent", @@ -13,6 +14,10 @@ "signing_key": { "type": "string" }, + "signer_address": { + "type": "string", + "description": "The Stacks address derived from the signing_key." + }, "weight": { "type": "integer" }, diff --git a/docs/generated.d.ts b/docs/generated.d.ts index 7674fe99bb..93896c066b 100644 --- a/docs/generated.d.ts +++ b/docs/generated.d.ts @@ -440,6 +440,9 @@ export type AbstractTransaction = BaseTransaction & { * An ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ) indicating when this block was mined. */ block_time_iso: string; + /** + * Height of the anchor burn block. + */ burn_block_height: number; /** * Unix timestamp (in seconds) indicating when this block was mined @@ -2361,9 +2364,8 @@ export interface RosettaBlock { /** * meta data */ - metadata?: { - transactions_root: string; - difficulty: string; + metadata: { + burn_block_height: number; [k: string]: unknown | undefined; }; } @@ -3029,6 +3031,10 @@ export interface RosettaNetworkStatusResponse { * Peers information */ peers: RosettaPeers[]; + /** + * The latest burn block height + */ + current_burn_block_height: number; } /** * The block_identifier uniquely identifies a block in a particular network. @@ -3387,6 +3393,10 @@ export interface PoxCycleSignersListResponse { } export interface PoxSigner { signing_key: string; + /** + * The Stacks address derived from the signing_key. + */ + signer_address: string; weight: number; stacked_amount: string; weight_percent: number; diff --git a/src/api/controllers/db-controller.ts b/src/api/controllers/db-controller.ts index 6d4da4a6c8..82198a4170 100644 --- a/src/api/controllers/db-controller.ts +++ b/src/api/controllers/db-controller.ts @@ -518,6 +518,9 @@ export async function getRosettaBlockFromDataStore( parent_block_identifier, timestamp: dbBlock.burn_block_time * 1000, transactions: blockTxs.found ? blockTxs.result : [], + metadata: { + burn_block_height: dbBlock.burn_block_height, + }, }; return { found: true, result: apiBlock }; }); diff --git a/src/api/init.ts b/src/api/init.ts index 1453658976..b4ebd2b786 100644 --- a/src/api/init.ts +++ b/src/api/init.ts @@ -242,7 +242,7 @@ export async function startApiServer(opts: { v2.use('/smart-contracts', createV2SmartContractsRouter(datastore)); v2.use('/mempool', createMempoolRouter(datastore)); v2.use('/addresses', createV2AddressesRouter(datastore)); - v2.use('/pox', createPoxRouter(datastore)); + v2.use('/pox', createPoxRouter(datastore, chainId)); return v2; })() ); diff --git a/src/api/routes/rosetta/network.ts b/src/api/routes/rosetta/network.ts index 8e5960b414..a314e0ac9b 100644 --- a/src/api/routes/rosetta/network.ts +++ b/src/api/routes/rosetta/network.ts @@ -98,6 +98,7 @@ export function createRosettaNetworkRouter(db: PgStore, chainId: ChainID): expre hash: genesis.block_identifier.hash, }, peers, + current_burn_block_height: block.metadata?.burn_block_height ?? 0, }; const nodeInfo = await stacksCoreRpcClient.getInfo(); const referenceNodeTipHeight = nodeInfo.stacks_tip_height; diff --git a/src/api/routes/v2/helpers.ts b/src/api/routes/v2/helpers.ts index 1955cc6092..0a312a1077 100644 --- a/src/api/routes/v2/helpers.ts +++ b/src/api/routes/v2/helpers.ts @@ -27,6 +27,7 @@ import { parseDbTx, } from '../../../api/controllers/db-controller'; import { decodeClarityValueToRepr } from 'stacks-encoding-native-js'; +import { TransactionVersion, getAddressFromPublicKey } from '@stacks/transactions'; export function parseDbNakamotoBlock(block: DbBlock): NakamotoBlock { const apiBlock: NakamotoBlock = { @@ -175,9 +176,14 @@ export function parseDbPoxCycle(cycle: DbPoxCycle): PoxCycle { return result; } -export function parseDbPoxSigner(signer: DbPoxCycleSigner): PoxSigner { +export function parseDbPoxSigner(signer: DbPoxCycleSigner, isMainnet: boolean): PoxSigner { + const signerAddress = getAddressFromPublicKey( + Buffer.from(signer.signing_key.slice(2), 'hex'), + isMainnet ? TransactionVersion.Mainnet : TransactionVersion.Testnet + ); const result: PoxSigner = { signing_key: signer.signing_key, + signer_address: signerAddress, weight: signer.weight, stacked_amount: signer.stacked_amount, weight_percent: signer.weight_percent, @@ -192,5 +198,12 @@ export function parseDbPoxSignerStacker(stacker: DbPoxCycleSignerStacker): PoxSt stacked_amount: stacker.locked, pox_address: stacker.pox_addr, }; + // Special handling for pool operator stackers + if ( + stacker.name === 'stack-aggregation-commit-indexed' || + stacker.name === 'stack-aggregation-commit' + ) { + result.stacked_amount = stacker.amount_ustx; + } return result; } diff --git a/src/api/routes/v2/pox.ts b/src/api/routes/v2/pox.ts index b7de76637a..2647339b8a 100644 --- a/src/api/routes/v2/pox.ts +++ b/src/api/routes/v2/pox.ts @@ -18,13 +18,16 @@ import { PoxCycleListResponse, PoxCycleSignerStackersListResponse, PoxCycleSignersListResponse, -} from 'docs/generated'; + PoxSigner, +} from '@stacks/stacks-blockchain-api-types'; import { parseDbPoxCycle, parseDbPoxSigner, parseDbPoxSignerStacker } from './helpers'; import { InvalidRequestError } from '../../../errors'; +import { ChainID, getChainIDNetwork } from '../../../helpers'; -export function createPoxRouter(db: PgStore): express.Router { +export function createPoxRouter(db: PgStore, chainId: ChainID): express.Router { const router = express.Router(); const cacheHandler = getETagCacheHandler(db); + const isMainnet = getChainIDNetwork(chainId) === 'mainnet'; router.get( '/cycles', @@ -83,7 +86,7 @@ export function createPoxRouter(db: PgStore): express.Router { limit, offset, total, - results: results.map(r => parseDbPoxSigner(r)), + results: results.map(r => parseDbPoxSigner(r, isMainnet)), }; setETagCacheHeaders(res); res.json(response); @@ -110,8 +113,9 @@ export function createPoxRouter(db: PgStore): express.Router { res.status(404).json({ error: `Not found` }); return; } + const response: PoxSigner = parseDbPoxSigner(signer, isMainnet); setETagCacheHeaders(res); - res.json(parseDbPoxSigner(signer)); + res.json(response); } catch (error) { if (error instanceof InvalidRequestError) { res.status(404).json({ errors: error.message }); diff --git a/src/datastore/common.ts b/src/datastore/common.ts index de5cf276a5..9c26263a88 100644 --- a/src/datastore/common.ts +++ b/src/datastore/common.ts @@ -1094,6 +1094,8 @@ export interface DbPoxCycleSignerStacker { stacker: string; locked: string; pox_addr: string; + name: string; + amount_ustx: string; } interface ReOrgEntities { diff --git a/src/datastore/pg-store-v2.ts b/src/datastore/pg-store-v2.ts index 8c23c68c2a..01c2fe8795 100644 --- a/src/datastore/pg-store-v2.ts +++ b/src/datastore/pg-store-v2.ts @@ -688,7 +688,7 @@ export class PgStoreV2 extends BasePgStoreModule { ); const results = await sql<(DbPoxCycleSignerStacker & { total: number })[]>` WITH stackers AS ( - SELECT DISTINCT ON (stacker) stacker, locked, pox_addr + SELECT DISTINCT ON (stacker) stacker, locked, pox_addr, amount_ustx, name FROM pox4_events WHERE canonical = true AND microblock_canonical = true diff --git a/src/datastore/pg-store.ts b/src/datastore/pg-store.ts index e4c8f0cc60..e335c7c038 100644 --- a/src/datastore/pg-store.ts +++ b/src/datastore/pg-store.ts @@ -1938,8 +1938,10 @@ export class PgStore extends BasePgStore { if (!dbTx.found) { return { found: false }; } + const cols = + poxTable === 'pox4_events' ? POX4_SYNTHETIC_EVENT_COLUMNS : POX_SYNTHETIC_EVENT_COLUMNS; const queryResults = await sql` - SELECT ${sql(POX_SYNTHETIC_EVENT_COLUMNS)} + SELECT ${sql(cols)} FROM ${sql(poxTable)} WHERE canonical = true AND microblock_canonical = true AND tx_id = ${txId} ORDER BY block_height DESC, microblock_sequence DESC, tx_index DESC, event_index DESC @@ -1957,8 +1959,10 @@ export class PgStore extends BasePgStore { poxTable: PoxSyntheticEventTable; }): Promise> { return await this.sqlTransaction(async sql => { + const cols = + poxTable === 'pox4_events' ? POX4_SYNTHETIC_EVENT_COLUMNS : POX_SYNTHETIC_EVENT_COLUMNS; const queryResults = await sql` - SELECT ${sql(POX_SYNTHETIC_EVENT_COLUMNS)} + SELECT ${sql(cols)} FROM ${sql(poxTable)} WHERE canonical = true AND microblock_canonical = true AND stacker = ${principal} ORDER BY block_height DESC, microblock_sequence DESC, tx_index DESC, event_index DESC @@ -2349,7 +2353,7 @@ export class PgStore extends BasePgStore { // Special case for `handle-unlock` which should be returned if it is the last received event. const pox4EventQuery = await sql` - SELECT ${sql(POX_SYNTHETIC_EVENT_COLUMNS)} + SELECT ${sql(POX4_SYNTHETIC_EVENT_COLUMNS)} FROM pox4_events WHERE canonical = true AND microblock_canonical = true AND stacker = ${stxAddress} AND block_height <= ${blockHeight} @@ -4243,7 +4247,7 @@ export class PgStore extends BasePgStore { let poxV4Unlocks: StxLockEventResult[] = []; const pox4EventQuery = await sql` - SELECT DISTINCT ON (stacker) stacker, ${sql(POX_SYNTHETIC_EVENT_COLUMNS)} + SELECT DISTINCT ON (stacker) stacker, ${sql(POX4_SYNTHETIC_EVENT_COLUMNS)} FROM pox4_events WHERE canonical = true AND microblock_canonical = true AND block_height <= ${block.block_height} diff --git a/src/tests-2.5/pox-4-delegate-aggregation.ts b/src/tests-2.5/pox-4-delegate-aggregation.ts index b5c032aa12..cd8e27ec00 100644 --- a/src/tests-2.5/pox-4-delegate-aggregation.ts +++ b/src/tests-2.5/pox-4-delegate-aggregation.ts @@ -319,6 +319,26 @@ describe('PoX-4 - Delegate aggregation increase operations', () => { name: 'stack-aggregation-commit-indexed', pox_addr: delegateeAccount.btcTestnetAddr, stacker: delegatorAccount.stxAddr, + data: expect.objectContaining({ + signer_key: `0x${signerPubKey}`, + end_cycle_id: expect.stringMatching(/\d+/), + start_cycle_id: expect.stringMatching(/\d+/), + }), + }) + ); + + const stackerRes: any = await fetchGet(`/extended/v1/pox4/stacker/${delegatorAccount.stxAddr}`); + expect(stackerRes).toBeDefined(); + expect(stackerRes.results[0]).toEqual( + expect.objectContaining({ + name: 'stack-aggregation-commit-indexed', + pox_addr: delegateeAccount.btcTestnetAddr, + stacker: delegatorAccount.stxAddr, + data: expect.objectContaining({ + signer_key: `0x${signerPubKey}`, + end_cycle_id: expect.stringMatching(/\d+/), + start_cycle_id: expect.stringMatching(/\d+/), + }), }) ); }); diff --git a/src/tests-rosetta/api.ts b/src/tests-rosetta/api.ts index 327582f33c..8c537a9c6c 100644 --- a/src/tests-rosetta/api.ts +++ b/src/tests-rosetta/api.ts @@ -11,10 +11,12 @@ import { RosettaAccountBalanceRequest, RosettaAccountBalanceResponse, RosettaAmount, + RosettaBlockResponse, RosettaMempoolRequest, RosettaMempoolResponse, RosettaMempoolTransactionRequest, RosettaMempoolTransactionResponse, + RosettaNetworkStatusResponse, RosettaOperation, RosettaTransaction, } from '@stacks/stacks-blockchain-api-types'; @@ -133,7 +135,8 @@ describe('Rosetta API', () => { parent_block_hash: genesisData.block.block_hash, parent_index_block_hash: genesisData.block.index_block_hash, block_height: 2, - index_block_hash: '0x12345678' + index_block_hash: '0x12345678', + burn_block_height: 13334, } const blockData = new TestBlockBuilder(blockBuilderData).build(); @@ -172,7 +175,7 @@ describe('Rosetta API', () => { expect(query1.status).toBe(200); expect(query1.type).toBe('application/json'); - const expectResponse = { + const expectResponse: RosettaNetworkStatusResponse = { current_block_identifier: { index: block.block_height, hash: block.block_hash, @@ -183,18 +186,14 @@ describe('Rosetta API', () => { hash: genesisBlock.block_hash, }, peers: [], + current_burn_block_height: blockBuilderData.burn_block_height, + sync_status: { + current_index: 2, + synced: true, + target_index: 2, + } }; - - expect(JSON.parse(query1.text)).toHaveProperty('sync_status'); - expect(JSON.parse(query1.text).current_block_identifier).toEqual( - expectResponse.current_block_identifier - ); - expect(JSON.parse(query1.text).current_block_timestamp).toEqual( - expectResponse.current_block_timestamp - ); - expect(JSON.parse(query1.text).genesis_block_identifier).toEqual( - expectResponse.genesis_block_identifier - ); + expect(query1.body).toEqual(expectResponse); }); test('block - by index', async () => { @@ -224,7 +223,7 @@ describe('Rosetta API', () => { }); expect(query1.status).toBe(200); expect(query1.type).toBe('application/json'); - expect(JSON.parse(query1.text)).toEqual({ + const expected: RosettaBlockResponse = { block: { block_identifier: { index: blockHeight, @@ -250,8 +249,12 @@ describe('Rosetta API', () => { ], }, ], + metadata: { + burn_block_height: data.block.burn_block_height, + } }, - }); + }; + expect(JSON.parse(query1.text)).toEqual(expected); }); test('block - by hash', async () => { @@ -281,7 +284,7 @@ describe('Rosetta API', () => { }); expect(query1.status).toBe(200); expect(query1.type).toBe('application/json'); - expect(JSON.parse(query1.text)).toEqual({ + const expected: RosettaBlockResponse = { block: { block_identifier: { index: blockHeight, @@ -307,8 +310,12 @@ describe('Rosetta API', () => { ], }, ], + metadata: { + burn_block_height: data.block.burn_block_height, + } }, - }); + }; + expect(JSON.parse(query1.text)).toEqual(expected); }); test('block - get latest', async () => { @@ -327,6 +334,7 @@ describe('Rosetta API', () => { block_height: 2, burn_block_time: 94869286, burn_block_hash: '0xfe15c0d3ebe314fad720a08b839a004c2e6386f5aecc19ec74807d1920cb6aeb', + burn_block_height: 1222, } await db.update(new TestBlockBuilder(block1).addTx().build()); @@ -341,7 +349,7 @@ describe('Rosetta API', () => { expect(query1.status).toBe(200); expect(query1.type).toBe('application/json'); - expect(JSON.parse(query1.text)).toEqual({ + const expected: RosettaBlockResponse = { block: { block_identifier: { index: block2.block_height, @@ -353,8 +361,12 @@ describe('Rosetta API', () => { }, timestamp: block2.burn_block_time * 1000, transactions: expect.objectContaining({}), + metadata: { + burn_block_height: block2.burn_block_height, + } }, - }); + }; + expect(JSON.parse(query1.text)).toEqual(expected); }); test('block/transaction', async () => { diff --git a/src/tests/pox-tests.ts b/src/tests/pox-tests.ts index b12ffeede4..140477fe8f 100644 --- a/src/tests/pox-tests.ts +++ b/src/tests/pox-tests.ts @@ -106,6 +106,7 @@ describe('PoX tests', () => { results: [ { signing_key: '0x038e3c4529395611be9abf6fa3b6987e81d402385e3d605a073f42f407565a4a3d', + signer_address: 'STRYYQQ9M8KAF4NS7WNZQYY59X93XEKR31JP64CP', stacked_amount: '686251350000000000', stacked_amount_percent: 50, weight: 5, @@ -113,6 +114,7 @@ describe('PoX tests', () => { }, { signing_key: '0x029874497a7952483aa23890e9d0898696f33864d3df90939930a1f45421fe3b09', + signer_address: 'STF9B75ADQAVXQHNEQ6KGHXTG7JP305J2GRWF3A2', stacked_amount: '457500900000000000', stacked_amount_percent: 33.333333333333336, weight: 3, @@ -120,6 +122,7 @@ describe('PoX tests', () => { }, { signing_key: '0x02dcde79b38787b72d8e5e0af81cffa802f0a3c8452d6b46e08859165f49a72736', + signer_address: 'ST18MDW2PDTBSCR1ACXYRJP2JX70FWNM6YY2VX4SS', stacked_amount: '228750450000000000', stacked_amount_percent: 16.666666666666668, weight: 1, @@ -135,6 +138,7 @@ describe('PoX tests', () => { expect(signer.type).toBe('application/json'); expect(JSON.parse(signer.text)).toStrictEqual({ signing_key: '0x038e3c4529395611be9abf6fa3b6987e81d402385e3d605a073f42f407565a4a3d', + signer_address: 'STRYYQQ9M8KAF4NS7WNZQYY59X93XEKR31JP64CP', stacked_amount: '686251350000000000', stacked_amount_percent: 50, weight: 5, @@ -253,6 +257,7 @@ describe('PoX tests', () => { results: [ { signing_key: '0x028efa20fa5706567008ebaf48f7ae891342eeb944d96392f719c505c89f84ed8d', + signer_address: 'ST3AM1A56AK2C1XAFJ4115ZSV26EB49BVQ10MGCS0', stacked_amount: '7500510000000000', stacked_amount_percent: 42.857142857142854, weight: 9, @@ -260,6 +265,7 @@ describe('PoX tests', () => { }, { signing_key: '0x023f19d77c842b675bd8c858e9ac8b0ca2efa566f17accf8ef9ceb5a992dc67836', + signer_address: 'ST3PF13W7Z0RRM42A8VZRVFQ75SV1K26RXEP8YGKJ', stacked_amount: '5000340000000000', stacked_amount_percent: 28.571428571428573, weight: 6, @@ -268,6 +274,7 @@ describe('PoX tests', () => { { // steph doubled the weight of this signer signing_key: '0x029fb154a570a1645af3dd43c3c668a979b59d21a46dd717fd799b13be3b2a0dc7', + signer_address: 'ST3NBRSFKX28FQ2ZJ1MAKX58HKHSDGNV5N7R21XCP', stacked_amount: '5000340000000000', stacked_amount_percent: 28.571428571428573, weight: 6, @@ -284,6 +291,7 @@ describe('PoX tests', () => { expect(signer.type).toBe('application/json'); expect(JSON.parse(signer.text)).toStrictEqual({ signing_key: '0x029fb154a570a1645af3dd43c3c668a979b59d21a46dd717fd799b13be3b2a0dc7', + signer_address: 'ST3NBRSFKX28FQ2ZJ1MAKX58HKHSDGNV5N7R21XCP', stacked_amount: '5000340000000000', stacked_amount_percent: 28.571428571428573, weight: 6, diff --git a/stacks-blockchain/docker/Dockerfile b/stacks-blockchain/docker/Dockerfile index 691ad8905b..d283f14e8d 100644 --- a/stacks-blockchain/docker/Dockerfile +++ b/stacks-blockchain/docker/Dockerfile @@ -1,5 +1,5 @@ # Pointed to stacks-blockchain `2.1.0.0.0` git tag -FROM --platform=linux/amd64 hirosystems/stacks-api-e2e:stacks3.0-4d11d85 as build +FROM --platform=linux/amd64 hirosystems/stacks-api-e2e:stacks3.0-0a2c0e2 as build FROM --platform=linux/amd64 debian:bookworm