diff --git a/docker/docker-compose.dev.stacks-blockchain.yml b/docker/docker-compose.dev.stacks-blockchain.yml index 23c338e983..2e5eebfc16 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-800259e" + image: "hirosystems/stacks-api-e2e:stacks3.0-8f95e53" 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 58858240bf..2ce2863138 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-800259e" + image: "hirosystems/stacks-api-e2e:stacks3.0-8f95e53" ports: - "18443:18443" # bitcoin regtest JSON-RPC interface - "18444:18444" # bitcoin regtest p2p diff --git a/docs/entities/transactions/transaction-7-tenure-change-metadata.schema.json b/docs/entities/transactions/transaction-7-tenure-change-metadata.schema.json index 68f6728abb..7087a7915e 100644 --- a/docs/entities/transactions/transaction-7-tenure-change-metadata.schema.json +++ b/docs/entities/transactions/transaction-7-tenure-change-metadata.schema.json @@ -12,8 +12,20 @@ "tenure_change_payload": { "type": "object", "additionalProperties": false, - "required": ["previous_tenure_end", "previous_tenure_blocks", "cause", "pubkey_hash", "signature", "signers"], + "required": ["tenure_consensus_hash", "prev_tenure_consensus_hash", "burn_view_consensus_hash", "previous_tenure_end", "previous_tenure_blocks", "cause", "pubkey_hash", "signature", "signers"], "properties": { + "tenure_consensus_hash": { + "type": "string", + "description": "Consensus hash of this tenure. Corresponds to the sortition in which the miner of this block was chosen." + }, + "prev_tenure_consensus_hash": { + "type": "string", + "description": "Consensus hash of the previous tenure. Corresponds to the sortition of the previous winning block-commit." + }, + "burn_view_consensus_hash": { + "type": "string", + "description": "Current consensus hash on the underlying burnchain. Corresponds to the last-seen sortition." + }, "previous_tenure_end": { "type": "string", "description": "(Hex string) Stacks Block hash" @@ -24,7 +36,7 @@ }, "cause": { "type": "string", - "enum": ["block_found", "no_block_found", "null_miner"], + "enum": ["block_found", "extended"], "description": "Cause of change in mining tenure. Depending on cause, tenure can be ended or extended." }, "pubkey_hash": { diff --git a/docs/generated.d.ts b/docs/generated.d.ts index 4e39356ad9..bf8253d278 100644 --- a/docs/generated.d.ts +++ b/docs/generated.d.ts @@ -1132,6 +1132,18 @@ export interface CoinbaseTransactionMetadata { export interface TenureChangeTransactionMetadata { tx_type: "tenure_change"; tenure_change_payload?: { + /** + * Consensus hash of this tenure. Corresponds to the sortition in which the miner of this block was chosen. + */ + tenure_consensus_hash: string; + /** + * Consensus hash of the previous tenure. Corresponds to the sortition of the previous winning block-commit. + */ + prev_tenure_consensus_hash: string; + /** + * Current consensus hash on the underlying burnchain. Corresponds to the last-seen sortition. + */ + burn_view_consensus_hash: string; /** * (Hex string) Stacks Block hash */ @@ -1143,7 +1155,7 @@ export interface TenureChangeTransactionMetadata { /** * Cause of change in mining tenure. Depending on cause, tenure can be ended or extended. */ - cause: "block_found" | "no_block_found" | "null_miner"; + cause: "block_found" | "extended"; /** * (Hex string) The ECDSA public key hash of the current tenure. */ diff --git a/migrations/1701368149776_nakamoto-txs.js b/migrations/1701368149776_nakamoto-txs.js index 27ec61ddbd..0e7d46b267 100644 --- a/migrations/1701368149776_nakamoto-txs.js +++ b/migrations/1701368149776_nakamoto-txs.js @@ -13,6 +13,9 @@ exports.up = pgm => { coinbase_vrf_proof: 'bytea', // `tenure-change` tx types + tenure_change_tenure_consensus_hash: 'bytea', + tenure_change_prev_tenure_consensus_hash: 'bytea', + tenure_change_burn_view_consensus_hash: 'bytea', tenure_change_previous_tenure_end: 'bytea', tenure_change_previous_tenure_blocks: 'integer', tenure_change_cause: 'smallint', @@ -26,6 +29,9 @@ exports.up = pgm => { coinbase_vrf_proof: 'bytea', // `tenure-change` tx types + tenure_change_tenure_consensus_hash: 'bytea', + tenure_change_prev_tenure_consensus_hash: 'bytea', + tenure_change_burn_view_consensus_hash: 'bytea', tenure_change_previous_tenure_end: 'bytea', tenure_change_previous_tenure_blocks: 'integer', tenure_change_cause: 'smallint', @@ -35,7 +41,7 @@ exports.up = pgm => { }); pgm.addConstraint('txs', 'valid_tenure-change', `CHECK (type_id != 7 OR ( - NOT (tenure_change_previous_tenure_end, tenure_change_previous_tenure_blocks, tenure_change_cause, tenure_change_pubkey_hash, tenure_change_signature, tenure_change_signers) IS NULL + NOT (tenure_change_tenure_consensus_hash, tenure_change_prev_tenure_consensus_hash, tenure_change_burn_view_consensus_hash, tenure_change_previous_tenure_end, tenure_change_previous_tenure_blocks, tenure_change_cause, tenure_change_pubkey_hash, tenure_change_signature, tenure_change_signers) IS NULL ))`); pgm.addConstraint('txs', 'valid_nakamoto-coinbase', `CHECK (type_id != 8 OR ( @@ -43,7 +49,7 @@ exports.up = pgm => { ))`); pgm.addConstraint('mempool_txs', 'valid_tenure-change', `CHECK (type_id != 7 OR ( - NOT (tenure_change_previous_tenure_end, tenure_change_previous_tenure_blocks, tenure_change_cause, tenure_change_pubkey_hash, tenure_change_signature, tenure_change_signers) IS NULL + NOT (tenure_change_tenure_consensus_hash, tenure_change_prev_tenure_consensus_hash, tenure_change_burn_view_consensus_hash, tenure_change_previous_tenure_end, tenure_change_previous_tenure_blocks, tenure_change_cause, tenure_change_pubkey_hash, tenure_change_signature, tenure_change_signers) IS NULL ))`); pgm.addConstraint('mempool_txs', 'valid_nakamoto-coinbase', `CHECK (type_id != 8 OR ( diff --git a/package-lock.json b/package-lock.json index 6daeefe001..37c1ddd58c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -62,7 +62,7 @@ "socket.io": "4.6.1", "source-map-support": "0.5.21", "split2": "3.2.2", - "stacks-encoding-native-js": "1.1.0-beta.3", + "stacks-encoding-native-js": "1.1.0-beta.4", "strict-event-emitter-types": "2.0.0", "tiny-secp256k1": "2.2.1", "ts-unused-exports": "7.0.3", @@ -12825,9 +12825,9 @@ "dev": true }, "node_modules/stacks-encoding-native-js": { - "version": "1.1.0-beta.3", - "resolved": "https://registry.npmjs.org/stacks-encoding-native-js/-/stacks-encoding-native-js-1.1.0-beta.3.tgz", - "integrity": "sha512-A9Fh/hAs0CK8XTv/F5fyLAcoH2ONTPuHoQO19qfwgvpgJcbsdVKrrdaf/N5604YWilA1SK80bXFV7va5+aBiFw==", + "version": "1.1.0-beta.4", + "resolved": "https://registry.npmjs.org/stacks-encoding-native-js/-/stacks-encoding-native-js-1.1.0-beta.4.tgz", + "integrity": "sha512-YpkLNhamcjn2TzPJ6OQAxqAK2XDFKXGGIBEBOAs5F0zfTDvY6ruL3zb6YjLAqtgtNMuaQZvIErGBXZTh0zgaOA==", "dependencies": { "@types/node": "^16.11.26", "detect-libc": "^2.0.1" diff --git a/package.json b/package.json index da1ae344c2..e88a17fe12 100644 --- a/package.json +++ b/package.json @@ -137,7 +137,7 @@ "socket.io": "4.6.1", "source-map-support": "0.5.21", "split2": "3.2.2", - "stacks-encoding-native-js": "1.1.0-beta.3", + "stacks-encoding-native-js": "1.1.0-beta.4", "strict-event-emitter-types": "2.0.0", "tiny-secp256k1": "2.2.1", "ts-unused-exports": "7.0.3", diff --git a/src/api/controllers/db-controller.ts b/src/api/controllers/db-controller.ts index 52fea4b546..8f00ff39f0 100644 --- a/src/api/controllers/db-controller.ts +++ b/src/api/controllers/db-controller.ts @@ -121,9 +121,7 @@ function getTxTenureChangeCauseString(cause: number) { case 0: return 'block_found'; case 1: - return 'no_block_found'; - case 2: - return 'null_miner'; + return 'extended'; default: throw new Error(`Unexpected tenure change cause value ${cause}`); } @@ -968,6 +966,18 @@ function parseDbTxTypeMetadata(dbTx: DbTx | DbMempoolTx): TransactionMetadata { const metadata: TenureChangeTransactionMetadata = { tx_type: 'tenure_change', tenure_change_payload: { + tenure_consensus_hash: unwrapOptional( + dbTx.tenure_change_tenure_consensus_hash, + () => 'Unexpected nullish tenure_change_tenure_consensus_hash' + ), + prev_tenure_consensus_hash: unwrapOptional( + dbTx.tenure_change_prev_tenure_consensus_hash, + () => 'Unexpected nullish tenure_change_prev_tenure_consensus_hash' + ), + burn_view_consensus_hash: unwrapOptional( + dbTx.tenure_change_burn_view_consensus_hash, + () => 'Unexpected nullish tenure_change_burn_view_consensus_hash' + ), previous_tenure_end: unwrapOptional( dbTx.tenure_change_previous_tenure_end, () => 'Unexpected nullish tenure_change_previous_tenure_end' diff --git a/src/datastore/common.ts b/src/datastore/common.ts index e037569330..64328a89b9 100644 --- a/src/datastore/common.ts +++ b/src/datastore/common.ts @@ -150,6 +150,9 @@ export interface BaseTx { abi?: string; /** Only valid for `tenure-change` tx types. */ + tenure_change_tenure_consensus_hash?: string; + tenure_change_prev_tenure_consensus_hash?: string; + tenure_change_burn_view_consensus_hash?: string; tenure_change_previous_tenure_end?: string; tenure_change_previous_tenure_blocks?: number; tenure_change_cause?: number; @@ -868,6 +871,9 @@ export interface MempoolTxQueryResult { coinbase_vrf_proof?: string; // `tenure-change` tx types + tenure_change_tenure_consensus_hash?: string; + tenure_change_prev_tenure_consensus_hash?: string; + tenure_change_burn_view_consensus_hash?: string; tenure_change_previous_tenure_end?: string; tenure_change_previous_tenure_blocks?: number; tenure_change_cause?: number; @@ -939,6 +945,9 @@ export interface TxQueryResult { coinbase_vrf_proof?: string; // `tenure-change` tx types + tenure_change_tenure_consensus_hash?: string; + tenure_change_prev_tenure_consensus_hash?: string; + tenure_change_burn_view_consensus_hash?: string; tenure_change_previous_tenure_end?: string; tenure_change_previous_tenure_blocks?: number; tenure_change_cause?: number; @@ -1071,6 +1080,9 @@ export interface TxInsertValues { coinbase_payload: PgBytea | null; coinbase_alt_recipient: string | null; coinbase_vrf_proof: string | null; + tenure_change_tenure_consensus_hash: string | null; + tenure_change_prev_tenure_consensus_hash: string | null; + tenure_change_burn_view_consensus_hash: string | null; tenure_change_previous_tenure_end: string | null; tenure_change_previous_tenure_blocks: number | null; tenure_change_cause: number | null; @@ -1117,6 +1129,9 @@ export interface MempoolTxInsertValues { coinbase_payload: PgBytea | null; coinbase_alt_recipient: string | null; coinbase_vrf_proof: string | null; + tenure_change_tenure_consensus_hash: string | null; + tenure_change_prev_tenure_consensus_hash: string | null; + tenure_change_burn_view_consensus_hash: string | null; tenure_change_previous_tenure_end: string | null; tenure_change_previous_tenure_blocks: number | null; tenure_change_cause: number | null; diff --git a/src/datastore/helpers.ts b/src/datastore/helpers.ts index bfc351de19..ca8331407f 100644 --- a/src/datastore/helpers.ts +++ b/src/datastore/helpers.ts @@ -104,6 +104,9 @@ export const TX_COLUMNS = [ 'coinbase_payload', 'coinbase_alt_recipient', 'coinbase_vrf_proof', + 'tenure_change_tenure_consensus_hash', + 'tenure_change_prev_tenure_consensus_hash', + 'tenure_change_burn_view_consensus_hash', 'tenure_change_previous_tenure_end', 'tenure_change_previous_tenure_blocks', 'tenure_change_cause', @@ -149,6 +152,9 @@ export const MEMPOOL_TX_COLUMNS = [ 'coinbase_payload', 'coinbase_alt_recipient', 'coinbase_vrf_proof', + 'tenure_change_tenure_consensus_hash', + 'tenure_change_prev_tenure_consensus_hash', + 'tenure_change_burn_view_consensus_hash', 'tenure_change_previous_tenure_end', 'tenure_change_previous_tenure_blocks', 'tenure_change_cause', @@ -391,6 +397,10 @@ function parseTxTypeSpecificQueryResult( } target.coinbase_vrf_proof = result.coinbase_vrf_proof; } else if (target.type_id === DbTxTypeId.TenureChange) { + target.tenure_change_tenure_consensus_hash = result.tenure_change_tenure_consensus_hash; + target.tenure_change_prev_tenure_consensus_hash = + result.tenure_change_prev_tenure_consensus_hash; + target.tenure_change_burn_view_consensus_hash = result.tenure_change_burn_view_consensus_hash; target.tenure_change_previous_tenure_end = result.tenure_change_previous_tenure_end; target.tenure_change_previous_tenure_blocks = result.tenure_change_previous_tenure_blocks; target.tenure_change_cause = result.tenure_change_cause; @@ -1047,6 +1057,9 @@ function extractTransactionPayload(txData: DecodedTxResult, dbTx: DbTx | DbMempo break; } case TxPayloadTypeID.TenureChange: { + dbTx.tenure_change_tenure_consensus_hash = txData.payload.tenure_consensus_hash; + dbTx.tenure_change_prev_tenure_consensus_hash = txData.payload.prev_tenure_consensus_hash; + dbTx.tenure_change_burn_view_consensus_hash = txData.payload.burn_view_consensus_hash; dbTx.tenure_change_previous_tenure_end = txData.payload.previous_tenure_end; dbTx.tenure_change_previous_tenure_blocks = txData.payload.previous_tenure_blocks; dbTx.tenure_change_cause = txData.payload.cause; diff --git a/src/datastore/pg-write-store.ts b/src/datastore/pg-write-store.ts index bd9d6c476b..2380da21a1 100644 --- a/src/datastore/pg-write-store.ts +++ b/src/datastore/pg-write-store.ts @@ -1617,6 +1617,9 @@ export class PgWriteStore extends PgStore { coinbase_payload: tx.coinbase_payload ?? null, coinbase_alt_recipient: tx.coinbase_alt_recipient ?? null, coinbase_vrf_proof: tx.coinbase_vrf_proof ?? null, + tenure_change_tenure_consensus_hash: tx.tenure_change_tenure_consensus_hash ?? null, + tenure_change_prev_tenure_consensus_hash: tx.tenure_change_prev_tenure_consensus_hash ?? null, + tenure_change_burn_view_consensus_hash: tx.tenure_change_burn_view_consensus_hash ?? null, tenure_change_previous_tenure_end: tx.tenure_change_previous_tenure_end ?? null, tenure_change_previous_tenure_blocks: tx.tenure_change_previous_tenure_blocks ?? null, tenure_change_cause: tx.tenure_change_cause ?? null, @@ -1674,6 +1677,9 @@ export class PgWriteStore extends PgStore { coinbase_payload: tx.coinbase_payload ?? null, coinbase_alt_recipient: tx.coinbase_alt_recipient ?? null, coinbase_vrf_proof: tx.coinbase_vrf_proof ?? null, + tenure_change_tenure_consensus_hash: tx.tenure_change_tenure_consensus_hash ?? null, + tenure_change_prev_tenure_consensus_hash: tx.tenure_change_prev_tenure_consensus_hash ?? null, + tenure_change_burn_view_consensus_hash: tx.tenure_change_burn_view_consensus_hash ?? null, tenure_change_previous_tenure_end: tx.tenure_change_previous_tenure_end ?? null, tenure_change_previous_tenure_blocks: tx.tenure_change_previous_tenure_blocks ?? null, tenure_change_cause: tx.tenure_change_cause ?? null, @@ -3009,6 +3015,9 @@ export class PgWriteStore extends PgStore { coinbase_payload: tx.coinbase_payload ?? null, coinbase_alt_recipient: tx.coinbase_alt_recipient ?? null, coinbase_vrf_proof: tx.coinbase_vrf_proof ?? null, + tenure_change_tenure_consensus_hash: tx.tenure_change_tenure_consensus_hash ?? null, + tenure_change_prev_tenure_consensus_hash: tx.tenure_change_prev_tenure_consensus_hash ?? null, + tenure_change_burn_view_consensus_hash: tx.tenure_change_burn_view_consensus_hash ?? null, tenure_change_previous_tenure_end: tx.tenure_change_previous_tenure_end ?? null, tenure_change_previous_tenure_blocks: tx.tenure_change_previous_tenure_blocks ?? null, tenure_change_cause: tx.tenure_change_cause ?? null, diff --git a/stacks-blockchain/docker/Dockerfile b/stacks-blockchain/docker/Dockerfile index d962f5eb95..5345c2ac4a 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-800259e as build +FROM --platform=linux/amd64 hirosystems/stacks-api-e2e:stacks3.0-8f95e53 as build FROM --platform=linux/amd64 debian:bookworm