From eb5252d4579a2f085184ac05e436f80dd1dea7c7 Mon Sep 17 00:00:00 2001 From: Hank Stoever Date: Thu, 7 Mar 2024 18:04:36 -0800 Subject: [PATCH] feat: show new transactions in monitor --- stacking/common.ts | 5 +++-- stacking/monitor.ts | 42 +++++++++++++++++++++++++++--------------- stacking/package.json | 3 ++- stacking/stacking.ts | 15 +-------------- 4 files changed, 33 insertions(+), 32 deletions(-) diff --git a/stacking/common.ts b/stacking/common.ts index 9dcb728..5c7eacd 100644 --- a/stacking/common.ts +++ b/stacking/common.ts @@ -8,7 +8,7 @@ import { import { getPublicKeyFromPrivate, publicKeyToBtcAddress } from '@stacks/encryption'; import { StacksNodeApi } from '@stacks/api'; import crypto from 'crypto'; -import { InfoApi, Configuration, BlocksApi } from '@stacks/blockchain-api-client'; +import { InfoApi, Configuration, BlocksApi, TransactionsApi } from '@stacks/blockchain-api-client'; export const nodeUrl = `http://${process.env.STACKS_CORE_RPC_HOST}:${process.env.STACKS_CORE_RPC_PORT}`; export const network = new StacksTestnet({ url: nodeUrl }); @@ -17,6 +17,7 @@ const apiConfig = new Configuration({ }); export const infoApi = new InfoApi(apiConfig); export const blocksApi = new BlocksApi(apiConfig); +export const txApi = new TransactionsApi(apiConfig); export const EPOCH_30_START = parseEnvInt('STACKS_30_HEIGHT', true); export const EPOCH_25_START = parseEnvInt('STACKS_25_HEIGHT', true); @@ -49,7 +50,7 @@ export async function waitForSetup() { } catch (error) { if (/(ECONNREFUSED|ENOTFOUND)/.test(error.cause?.message)) { console.log(`Stacks node not ready, waiting...`); - await new Promise(resolve => setTimeout(resolve, 1000)); + await new Promise(resolve => setTimeout(resolve, 3000)); return waitForSetup(); } throw error; diff --git a/stacking/monitor.ts b/stacking/monitor.ts index 8eb9aab..607f8f8 100644 --- a/stacking/monitor.ts +++ b/stacking/monitor.ts @@ -8,7 +8,9 @@ import { didCrossPreparePhase, blocksApi, parseEnvInt, + txApi, } from './common'; +import { Transaction, ContractCallTransaction } from '@stacks/stacks-blockchain-api-types'; let lastBurnHeight = 0; let lastStxHeight = 0; @@ -23,27 +25,31 @@ const monitorInterval = parseEnvInt('MONITOR_INTERVAL') ?? 2; console.log('Exit from monitor:', EXIT_FROM_MONITOR); +async function getTransactions(): Promise { + let res = await txApi.getTransactionsByBlock({ + heightOrHash: 'latest', + }); + let txs = res.results as Transaction[]; + return txs.filter(tx => { + return tx.tx_type === 'contract_call'; + }) as ContractCallTransaction[]; +} + async function getInfo() { let { client } = accounts[0]; - const [poxInfo, coreInfo, blockInfo] = await Promise.all([ + const [poxInfo, blockInfo, txs] = await Promise.all([ client.getPoxInfo(), - infoApi.getCoreApiInfo(), blocksApi.getBlock({ heightOrHash: 'latest', }), + getTransactions(), ]); const { reward_cycle_id } = poxInfo; - const [currentSigners, nextSigners] = await Promise.all([ - getSignerSet(reward_cycle_id), - getSignerSet(reward_cycle_id + 1), - ]); return { poxInfo, - coreInfo, blockInfo, - currentSigners, - nextSigners, nextCycleId: reward_cycle_id + 1, + txs, }; } @@ -71,9 +77,8 @@ async function getSignerSet(cycle: number) { async function loop() { try { - const { poxInfo, coreInfo, blockInfo, ...info } = await getInfo(); + const { poxInfo, blockInfo, ...info } = await getInfo(); let { reward_cycle_id, current_burnchain_block_height } = poxInfo; - // let { stacks_tip_height } = coreInfo; let { height } = blockInfo; let showBurnMsg = false; let showPrepareMsg = false; @@ -111,9 +116,10 @@ async function loop() { } if (showPrepareMsg) { console.log(`Prepare phase started. Next cycle is ${reward_cycle_id + 1}`); - if (info.nextSigners) { + const nextSigners = await getSignerSet(reward_cycle_id + 1); + if (nextSigners) { console.log( - `Next cycle (${info.nextCycleId}) has ${info.nextSigners.stacker_set.signers.length} signers` + `Next cycle (${info.nextCycleId}) has ${nextSigners.stacker_set.signers.length} signers` ); } } @@ -125,13 +131,19 @@ async function loop() { )} seconds)` ); } + if (showStxBlockMsg && info.txs.length > 0) { + info.txs.forEach(({ contract_call, sender_address, tx_status }) => { + console.log(`${sender_address}:\t${contract_call.function_name}\t${tx_status}`); + }); + } if (showCycleMsg) { - const signerCount = info.currentSigners?.stacker_set.signers.length ?? 0; + const currentSigners = await getSignerSet(reward_cycle_id); + const signerCount = currentSigners?.stacker_set.signers.length ?? 0; console.log(`New cycle started (${reward_cycle_id}) with ${signerCount} signers`); } - if (reward_cycle_id >= EPOCH_30_START && !info.currentSigners?.stacker_set.signers.length) { + if (reward_cycle_id >= EPOCH_30_START && !poxInfo.reward_slots) { console.error('FATAL: no signers while going in to Epoch 3.0'); exit(); } diff --git a/stacking/package.json b/stacking/package.json index 8423fc9..49c0693 100644 --- a/stacking/package.json +++ b/stacking/package.json @@ -14,7 +14,8 @@ "@stacks/stacking": "6.11.4-pr.36558cf.0", "@stacks/transactions": "6.11.4-pr.36558cf.0", "@stacks/common": "6.11.4-pr.36558cf.0", - "@stacks/blockchain-api-client": "7.8.2" + "@stacks/blockchain-api-client": "7.8.2", + "@stacks/stacks-blockchain-api-types": "7.8.2" }, "devDependencies": { "@stacks/prettier-config": "^0.0.10", diff --git a/stacking/stacking.ts b/stacking/stacking.ts index 779d6b5..56e5136 100644 --- a/stacking/stacking.ts +++ b/stacking/stacking.ts @@ -7,26 +7,13 @@ import { } from '@stacks/transactions'; import { getPublicKeyFromPrivate, publicKeyToBtcAddress } from '@stacks/encryption'; import crypto from 'crypto'; -import { Account, accounts, network, maxAmount, parseEnvInt } from './common'; +import { Account, accounts, network, maxAmount, parseEnvInt, waitForSetup } from './common'; const randInt = () => crypto.randomInt(0, 0xffffffffffff); const stackingInterval = parseEnvInt('STACKING_INTERVAL') ?? 2; const postTxWait = parseEnvInt('POST_TX_WAIT') ?? 10; const stackingCycles = parseEnvInt('STACKING_CYCLES') ?? 1; -async function waitForSetup() { - try { - await accounts[0].client.getPoxInfo(); - } catch (error) { - if (/(ECONNREFUSED|ENOTFOUND)/.test(error.cause?.message)) { - console.log(`Stacks node not ready, waiting...`); - await new Promise(resolve => setTimeout(resolve, 1000)); - return waitForSetup(); - } - throw error; - } -} - async function run() { await waitForSetup(); const poxInfo = await accounts[0].client.getPoxInfo();