From 306a3225275c69be24416000681c6d7a809011ff Mon Sep 17 00:00:00 2001 From: Matthew Little Date: Wed, 20 Mar 2024 10:38:06 +0100 Subject: [PATCH 1/2] feat: ingest signer_bitvec --- ...710856121027_stacks_block_signer-bitvec.js | 12 ++++++ src/datastore/common.ts | 3 ++ src/datastore/helpers.ts | 2 + src/datastore/pg-write-store.ts | 2 + src/event-stream/core-node-message.ts | 1 + src/event-stream/event-server.ts | 14 ++++++- src/helpers.ts | 42 +++++++++++++++++++ src/test-utils/test-builders.ts | 1 + src/tests/address-tests.ts | 3 ++ src/tests/block-tests.ts | 2 + src/tests/cache-control-tests.ts | 1 + src/tests/datastore-tests.ts | 41 ++++++++++++++++++ src/tests/mempool-tests.ts | 8 ++++ src/tests/microblock-tests.ts | 1 + src/tests/other-tests.ts | 1 + src/tests/search-tests.ts | 4 ++ src/tests/smart-contract-tests.ts | 4 ++ src/tests/tx-tests.ts | 16 +++++++ src/tests/v2-proxy-tests.ts | 1 + 19 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 migrations/1710856121027_stacks_block_signer-bitvec.js diff --git a/migrations/1710856121027_stacks_block_signer-bitvec.js b/migrations/1710856121027_stacks_block_signer-bitvec.js new file mode 100644 index 0000000000..0337aeb7d4 --- /dev/null +++ b/migrations/1710856121027_stacks_block_signer-bitvec.js @@ -0,0 +1,12 @@ +/* eslint-disable camelcase */ + +/** @param { import("node-pg-migrate").MigrationBuilder } pgm */ +exports.up = pgm => { + + pgm.addColumn('blocks', { + signer_bitvec: { + type: 'bit varying', + } + }); + +}; diff --git a/src/datastore/common.ts b/src/datastore/common.ts index 0133f58fac..eb79b90e4c 100644 --- a/src/datastore/common.ts +++ b/src/datastore/common.ts @@ -25,6 +25,7 @@ export interface DbBlock { execution_cost_write_length: number; tx_count: number; block_time: number; + signer_bitvec: string | null; } /** An interface representing the microblock data that can be constructed _only_ from the /new_microblocks payload */ @@ -844,6 +845,7 @@ export interface BlockQueryResult { execution_cost_write_count: string; execution_cost_write_length: string; tx_count: number; + signer_bitvec: string | null; } export interface MicroblockQueryResult { @@ -1227,6 +1229,7 @@ export interface BlockInsertValues { execution_cost_write_count: number; execution_cost_write_length: number; tx_count: number; + signer_bitvec: string | null; } export interface MicroblockInsertValues { diff --git a/src/datastore/helpers.ts b/src/datastore/helpers.ts index 7e15566886..e5a6ca9f39 100644 --- a/src/datastore/helpers.ts +++ b/src/datastore/helpers.ts @@ -183,6 +183,7 @@ export const BLOCK_COLUMNS = [ 'execution_cost_write_count', 'execution_cost_write_length', 'tx_count', + 'signer_bitvec', ]; export const MICROBLOCK_COLUMNS = [ @@ -473,6 +474,7 @@ export function parseBlockQueryResult(row: BlockQueryResult): DbBlock { execution_cost_write_count: Number.parseInt(row.execution_cost_write_count), execution_cost_write_length: Number.parseInt(row.execution_cost_write_length), tx_count: row.tx_count, + signer_bitvec: row.signer_bitvec, }; return block; } diff --git a/src/datastore/pg-write-store.ts b/src/datastore/pg-write-store.ts index 1d5621bbbf..ce543761b5 100644 --- a/src/datastore/pg-write-store.ts +++ b/src/datastore/pg-write-store.ts @@ -465,6 +465,7 @@ export class PgWriteStore extends PgStore { execution_cost_write_count: block.execution_cost_write_count, execution_cost_write_length: block.execution_cost_write_length, tx_count: block.tx_count, + signer_bitvec: block.signer_bitvec, }; const result = await sql` INSERT INTO blocks ${sql(values)} @@ -3059,6 +3060,7 @@ export class PgWriteStore extends PgStore { execution_cost_write_count: block.execution_cost_write_count, execution_cost_write_length: block.execution_cost_write_length, tx_count: block.tx_count, + signer_bitvec: block.signer_bitvec, })); await sql` INSERT INTO blocks ${sql(values)} diff --git a/src/event-stream/core-node-message.ts b/src/event-stream/core-node-message.ts index 93d711c496..87f48bfb34 100644 --- a/src/event-stream/core-node-message.ts +++ b/src/event-stream/core-node-message.ts @@ -271,6 +271,7 @@ export interface CoreNodeBlockMessage { }; }; block_time: number; + signer_bitvec?: string | null; } export interface CoreNodeParsedTxMessage { diff --git a/src/event-stream/event-server.ts b/src/event-stream/event-server.ts index 8e4c240eb5..01f3e7d386 100644 --- a/src/event-stream/event-server.ts +++ b/src/event-stream/event-server.ts @@ -6,7 +6,13 @@ import * as bodyParser from 'body-parser'; import { asyncHandler } from '../api/async-handler'; import PQueue from 'p-queue'; import * as prom from 'prom-client'; -import { ChainID, assertNotNullish, getChainIDNetwork, getIbdBlockHeight } from '../helpers'; +import { + BitVec, + ChainID, + assertNotNullish, + getChainIDNetwork, + getIbdBlockHeight, +} from '../helpers'; import { CoreNodeBlockMessage, CoreNodeEventType, @@ -291,6 +297,10 @@ async function handleBlockMessage( counts.events[event.type] += 1; } + const signerBitvec = msg.signer_bitvec + ? BitVec.consensusDeserializeToString(msg.signer_bitvec) + : null; + const dbBlock: DbBlock = { canonical: true, block_hash: msg.block_hash, @@ -311,6 +321,7 @@ async function handleBlockMessage( execution_cost_write_length: 0, tx_count: msg.transactions.length, block_time: msg.block_time, + signer_bitvec: signerBitvec, }; logger.debug(`Received block ${msg.block_hash} (${msg.block_height}) from node`, dbBlock); @@ -1148,6 +1159,7 @@ export function parseNewBlockMessage(chainId: ChainID, msg: CoreNodeBlockMessage execution_cost_write_count: totalCost.execution_cost_write_count, execution_cost_write_length: totalCost.execution_cost_write_length, tx_count: msg.transactions.length, + signer_bitvec: msg.signer_bitvec ?? null, }; const dbMinerRewards: DbMinerReward[] = []; diff --git a/src/helpers.ts b/src/helpers.ts index 2adc885dd7..834ad1077e 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -783,3 +783,45 @@ export function getUintEnvOrDefault(envName: string, defaultValue = 0) { } return Number(v); } + +export class BitVec { + bits: boolean[]; + constructor(bits: boolean[]) { + this.bits = bits; + } + + /** + * Deserialize a bit vector from a bytes in the consensus format: + * - 2 bytes (u16): bit length (how many bits to read from the byte data) + * - 4 bytes (u32): data length (how many remaining bytes to read) + */ + static consensusDeserialize(serializedData: Uint8Array) { + const dataView = new DataView(serializedData.buffer, serializedData.byteOffset); + const bitLen = dataView.getUint16(0); + const dataLen = dataView.getUint32(2); + const bitVecBytes = serializedData.subarray(6, 6 + dataLen); + const bits = Array.from( + { length: bitLen }, + (_, i) => !!(bitVecBytes[i >>> 3] & (128 >> i % 8)) + ); + return new BitVec(bits); + } + + /** Return a base-2 string */ + toString() { + return this.bits.map(b => (b ? '1' : '0')).join(''); + } + + /** + * Deserialize a bit vector from a bytes in the consensus format, and return as a base-2 string + */ + static consensusDeserializeToString(serializedData: Uint8Array | string): string { + const data = + typeof serializedData === 'string' + ? Buffer.from(serializedData.replace(/^0x/, ''), 'hex') + : serializedData; + const bitVec = BitVec.consensusDeserialize(data); + const bitVecStr = bitVec.toString(); + return bitVecStr; + } +} diff --git a/src/test-utils/test-builders.ts b/src/test-utils/test-builders.ts index da9cc898fc..df2780de5d 100644 --- a/src/test-utils/test-builders.ts +++ b/src/test-utils/test-builders.ts @@ -125,6 +125,7 @@ function testBlock(args?: TestBlockArgs): DbBlock { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; } diff --git a/src/tests/address-tests.ts b/src/tests/address-tests.ts index 255774b130..546c5cd64a 100644 --- a/src/tests/address-tests.ts +++ b/src/tests/address-tests.ts @@ -91,6 +91,7 @@ describe('address tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; let indexIdIndex = 0; const createStxTx = ( @@ -884,6 +885,7 @@ describe('address tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; let indexIdIndex = 0; @@ -2078,6 +2080,7 @@ describe('address tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const txBuilder = await makeContractCall({ contractAddress: 'ST11NJTTKGVT6D1HY4NJRVQWMQM7TVAR091EJ8P2Y', diff --git a/src/tests/block-tests.ts b/src/tests/block-tests.ts index 3977fb2673..423e323ac7 100644 --- a/src/tests/block-tests.ts +++ b/src/tests/block-tests.ts @@ -85,6 +85,7 @@ describe('block tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.updateBlock(client, block); const tx: DbTxRaw = { @@ -532,6 +533,7 @@ describe('block tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const dbTx1: DbTxRaw = { ...dbBlock, diff --git a/src/tests/cache-control-tests.ts b/src/tests/cache-control-tests.ts index 14e51ea6cb..c75886c65e 100644 --- a/src/tests/cache-control-tests.ts +++ b/src/tests/cache-control-tests.ts @@ -97,6 +97,7 @@ describe('cache-control tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx: DbTxRaw = { tx_id: '0x1234', diff --git a/src/tests/datastore-tests.ts b/src/tests/datastore-tests.ts index 40220dfb52..889287b6ec 100644 --- a/src/tests/datastore-tests.ts +++ b/src/tests/datastore-tests.ts @@ -278,6 +278,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx: DbTxRaw = { tx_id: '0x1234', @@ -444,6 +445,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx: DbTxRaw = { tx_id: '0x1234', @@ -616,6 +618,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.updateBlock(client, block); const blockQuery = await db.getBlock({ hash: block.block_hash }); @@ -684,6 +687,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; let indexIdIndex = 0; @@ -946,6 +950,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const txs1 = [ createStxTx('addrA', 'addrB', 100, dbBlock1), @@ -1020,6 +1025,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx1: DbTxRaw = { tx_id: '0x1234', @@ -1990,6 +1996,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx: DbTx = { tx_id: '0x1234', @@ -2072,6 +2079,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx: DbTx = { tx_id: '0x421234', @@ -2159,6 +2167,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx: DbTx = { tx_id: '0x421234', @@ -2254,6 +2263,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx: DbTxRaw = { tx_id: '0x421234', @@ -2392,6 +2402,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx: DbTx = { tx_id: '0x421234', @@ -2479,6 +2490,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx: DbTx = { tx_id: '0x421234', @@ -2565,6 +2577,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx: DbTx = { tx_id: '0x421234', @@ -2650,6 +2663,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.updateBlock(client, dbBlock); @@ -2722,6 +2736,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx1: DbTx = { tx_id: '0x421234', @@ -3094,6 +3109,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const block2: DbBlock = { block_hash: '0x22', @@ -3115,6 +3131,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const block3: DbBlock = { block_hash: '0x33', @@ -3136,6 +3153,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const block3B: DbBlock = { ...block3, @@ -3163,6 +3181,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const block4: DbBlock = { block_hash: '0x44', @@ -3184,6 +3203,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const block5: DbBlock = { block_hash: '0x55', @@ -3205,6 +3225,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const block6: DbBlock = { block_hash: '0x66', @@ -3226,6 +3247,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx1Mempool: DbMempoolTxRaw = { @@ -3416,6 +3438,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const block2: DbBlock = { block_hash: '0x22', @@ -3437,6 +3460,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const block3: DbBlock = { block_hash: '0x33', @@ -3458,6 +3482,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const block3B: DbBlock = { ...block3, @@ -3485,6 +3510,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const minerReward1: DbMinerReward = { @@ -3617,6 +3643,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const reorgResult = await db.handleReorg(client, block5, 0); @@ -3697,6 +3724,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const block2: DbBlock = { block_hash: '0x22', @@ -3718,6 +3746,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const minerReward1: DbMinerReward = { @@ -3995,6 +4024,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.update({ block: block3, microblocks: [], minerRewards: [], txs: [] }); @@ -4018,6 +4048,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx3: DbTxRaw = { tx_id: '0x03', @@ -4227,6 +4258,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.update({ block: block3b, microblocks: [], minerRewards: [], txs: [] }); const blockQuery2 = await db.getBlock({ hash: block3b.block_hash }); @@ -4267,6 +4299,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.update({ block: block4b, microblocks: [], minerRewards: [], txs: [] }); @@ -4366,6 +4399,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx1: DbTxRaw = { tx_id: '0x421234', @@ -4451,6 +4485,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx1: DbTxRaw = { tx_id: '0x421234', @@ -4535,6 +4570,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx1: DbTxRaw = { tx_id: '0x421234', @@ -4690,6 +4726,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.update({ block: dbBlock, @@ -4751,6 +4788,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.update({ block: dbBlock, @@ -4813,6 +4851,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.update({ block: dbBlock, @@ -4875,6 +4914,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.updateBlock(client, block); const blockQuery = await db.getBlock({ hash: block.block_hash }); @@ -4982,6 +5022,7 @@ describe('postgres datastore', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.updateBlock(client, block); const blockQuery = await db.getBlock({ hash: block.block_hash }); diff --git a/src/tests/mempool-tests.ts b/src/tests/mempool-tests.ts index c70ab19b8d..62a7e86826 100644 --- a/src/tests/mempool-tests.ts +++ b/src/tests/mempool-tests.ts @@ -536,6 +536,7 @@ describe('mempool tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const dbTx1: DbTxRaw = { ...mempoolTx1, @@ -1315,6 +1316,7 @@ describe('mempool tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.updateBlock(client, dbBlock); const senderAddress = 'SP25YGP221F01S9SSCGN114MKDAK9VRK8P3KXGEMB'; @@ -1389,6 +1391,7 @@ describe('mempool tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.updateBlock(client, dbBlock); const senderAddress = 'SP25YGP221F01S9SSCGN114MKDAK9VRK8P3KXGEMB'; @@ -1609,6 +1612,7 @@ describe('mempool tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const dbBlock2: DbBlock = { block_hash: '0x2123', @@ -1630,6 +1634,7 @@ describe('mempool tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const mempoolTx: DbMempoolTxRaw = { tx_id: txId, @@ -1754,6 +1759,7 @@ describe('mempool tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const dbBlock1b: DbBlock = { block_hash: '0x0123bb', @@ -1775,6 +1781,7 @@ describe('mempool tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const dbBlock2b: DbBlock = { block_hash: '0x2123', @@ -1796,6 +1803,7 @@ describe('mempool tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const mempoolTx: DbMempoolTxRaw = { tx_id: txId, diff --git a/src/tests/microblock-tests.ts b/src/tests/microblock-tests.ts index fc7b0fc72e..3ba978d196 100644 --- a/src/tests/microblock-tests.ts +++ b/src/tests/microblock-tests.ts @@ -284,6 +284,7 @@ describe('microblock tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx1: DbTxRaw = { diff --git a/src/tests/other-tests.ts b/src/tests/other-tests.ts index 753161f5a7..d086a8b9e3 100644 --- a/src/tests/other-tests.ts +++ b/src/tests/other-tests.ts @@ -62,6 +62,7 @@ describe('other tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx: DbTxRaw = { tx_id: '0x1234', diff --git a/src/tests/search-tests.ts b/src/tests/search-tests.ts index 64807825ec..e37fb4ce45 100644 --- a/src/tests/search-tests.ts +++ b/src/tests/search-tests.ts @@ -62,6 +62,7 @@ describe('search tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.updateBlock(client, block); const tx: DbTxRaw = { @@ -272,6 +273,7 @@ describe('search tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx: DbTxRaw = { @@ -609,6 +611,7 @@ describe('search tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.updateBlock(client, block); @@ -1050,6 +1053,7 @@ describe('search tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const stxTx1: DbTxRaw = { diff --git a/src/tests/smart-contract-tests.ts b/src/tests/smart-contract-tests.ts index 8c9aa142f7..df07b4340f 100644 --- a/src/tests/smart-contract-tests.ts +++ b/src/tests/smart-contract-tests.ts @@ -63,6 +63,7 @@ describe('smart contract tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx1: DbTxRaw = { tx_id: '0x421234', @@ -214,6 +215,7 @@ describe('smart contract tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const txId1 = '0x421234'; const smartContract1: DbSmartContract = { @@ -324,6 +326,7 @@ describe('smart contract tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const txId1 = '0x421234'; const smartContract1: DbSmartContract = { @@ -432,6 +435,7 @@ describe('smart contract tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; const tx1: DbTxRaw = { tx_id: '0x421235', diff --git a/src/tests/tx-tests.ts b/src/tests/tx-tests.ts index 49a8fe8f20..f2013672ff 100644 --- a/src/tests/tx-tests.ts +++ b/src/tests/tx-tests.ts @@ -155,6 +155,7 @@ describe('tx tests', () => { execution_cost_runtime: 2480886000, execution_cost_write_count: 138, execution_cost_write_length: 91116, + signer_bitvec: null, }; const dbTx2: DbTxRaw = { tx_id: '0x8915000000000000000000000000000000000000000000000000000000000000', @@ -349,6 +350,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; // stacks.js does not have a versioned-smart-contract tx builder as of writing, so use a known good serialized tx @@ -509,6 +511,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; // stacks.js does not support `coinbase-pay-to-alt-recipient` tx support as of writing, so use a known good serialized tx @@ -652,6 +655,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; // stacks.js does not support `coinbase-pay-to-alt-recipient` tx support as of writing, so use a known good serialized tx @@ -795,6 +799,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; const txBuilder = await makeContractCall({ contractAddress: 'ST11NJTTKGVT6D1HY4NJRVQWMQM7TVAR091EJ8P2Y', @@ -984,6 +989,7 @@ describe('tx tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; await db.update({ block: dbBlock, @@ -1179,6 +1185,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; const dbTx: DbTxRaw = { tx_id: '0x421234', @@ -1380,6 +1387,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; const pc1 = createNonFungiblePostCondition( @@ -1630,6 +1638,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; const txBuilder = await makeContractDeploy({ contractName: 'hello-world', @@ -1780,6 +1789,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; const txBuilder = await makeContractDeploy({ contractName: 'hello-world', @@ -1930,6 +1940,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; const tx: DbTxRaw = { tx_id: '0x421234', @@ -2048,6 +2059,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; await db.updateBlock(client, block); const tx: DbTxRaw = { @@ -2702,6 +2714,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; const tx: DbTxRaw = { tx_id: '0x1234', @@ -2954,6 +2967,7 @@ describe('tx tests', () => { execution_cost_runtime: 2480886000, execution_cost_write_count: 138, execution_cost_write_length: 91116, + signer_bitvec: null, }; const expected = { tx_id: '0x8407751d1a8d11ee986aca32a6459d9cd798283a12e048ebafcd4cc7dadb29af', @@ -3289,6 +3303,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; const tx: DbTxRaw = { tx_id: '0x1234', @@ -3490,6 +3505,7 @@ describe('tx tests', () => { execution_cost_runtime: 0, execution_cost_write_count: 0, execution_cost_write_length: 0, + signer_bitvec: null, }; await db.updateBlock(client, block); const tx: DbTxRaw = { diff --git a/src/tests/v2-proxy-tests.ts b/src/tests/v2-proxy-tests.ts index 38e0113b07..8c74e28375 100644 --- a/src/tests/v2-proxy-tests.ts +++ b/src/tests/v2-proxy-tests.ts @@ -76,6 +76,7 @@ describe('v2-proxy tests', () => { execution_cost_write_count: 0, execution_cost_write_length: 0, tx_count: 1, + signer_bitvec: null, }; // Ensure db has a block so that current block height queries return a found result From 94a30f49e683fd41f2c966885e36296e57d8b395 Mon Sep 17 00:00:00 2001 From: Matthew Little Date: Wed, 20 Mar 2024 11:08:22 +0100 Subject: [PATCH 2/2] test: add bitvec tests --- src/tests/helpers-tests.ts | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/tests/helpers-tests.ts b/src/tests/helpers-tests.ts index 9e1994b8c0..87c8c22d79 100644 --- a/src/tests/helpers-tests.ts +++ b/src/tests/helpers-tests.ts @@ -3,7 +3,7 @@ import * as c32check from 'c32check'; import { bitcoinToStacksAddress, stacksToBitcoinAddress } from 'stacks-encoding-native-js'; import * as c32AddrCache from '../c32-addr-cache'; import { ADDR_CACHE_ENV_VAR } from '../c32-addr-cache'; -import { isValidBitcoinAddress, getUintEnvOrDefault } from '../helpers'; +import { isValidBitcoinAddress, getUintEnvOrDefault, BitVec } from '../helpers'; import { ECPair, getBitcoinAddressFromKey } from '../ec-helpers'; import { decodeBtcAddress, poxAddressToBtcAddress } from '@stacks/stacking'; import { has0xPrefix } from '@hirosystems/api-toolkit'; @@ -547,3 +547,29 @@ test('getUintEnvOrDefault tests', () => { process.env[key] = 'ABC'; expect(() => getUintEnvOrDefault(key)).toThrowError(); }); + +test('signer bitvec decoding', () => { + const signerBitvecString1 = '00010000000100'; + const signerBitvecPayload1 = Buffer.from(signerBitvecString1, 'hex'); + const bitVec1 = BitVec.consensusDeserialize(signerBitvecPayload1); + expect(bitVec1.bits).toHaveLength(1); + expect(bitVec1.bits).toStrictEqual([false]); + expect(bitVec1.toString()).toBe('0'); + expect(BitVec.consensusDeserializeToString(signerBitvecString1)).toBe('0'); + + const signerBitvecString2 = '000100000001ff'; + const signerBitvecPayload2 = Buffer.from(signerBitvecString2, 'hex'); + const bitVec2 = BitVec.consensusDeserialize(signerBitvecPayload2); + expect(bitVec2.bits).toHaveLength(1); + expect(bitVec2.bits).toStrictEqual([true]); + expect(bitVec2.toString()).toBe('1'); + expect(BitVec.consensusDeserializeToString(signerBitvecString2)).toBe('1'); + + const signerBitvecString3 = '000300000001c0'; + const signerBitvecPayload3 = Buffer.from(signerBitvecString3, 'hex'); + const bitVec3 = BitVec.consensusDeserialize(signerBitvecPayload3); + expect(bitVec3.bits).toHaveLength(3); + expect(bitVec3.bits).toStrictEqual([true, true, false]); + expect(bitVec3.toString()).toBe('110'); + expect(BitVec.consensusDeserializeToString(signerBitvecString3)).toBe('110'); +});