Skip to content

Commit

Permalink
Monitoring: Migrate to latest SDK (#819)
Browse files Browse the repository at this point in the history
Depends on: #818 
Depends on: #820 

Here we migrate the monitoring package to the latest version of tBTC
SDK. We are using the latest `development` version of the SDK for now as
it contains some unreleased features and fixes that are useful for the
monitoring tool. Migration of the monitoring to the new tBTC SDK pays
off some tech debt but also reduces the number of requests sent to the
Ethereum node due to some optimizations introduced in the recent
versions of the SDK.
  • Loading branch information
tomaszslabon authored Jul 5, 2024
2 parents 977aed9 + 173a536 commit f364b70
Show file tree
Hide file tree
Showing 15 changed files with 495 additions and 642 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/monitoring.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:

- uses: actions/setup-node@v3
with:
node-version: "14.x"
node-version: "18.x"
cache: "yarn"
cache-dependency-path: monitoring/yarn.lock

Expand Down Expand Up @@ -133,7 +133,7 @@ jobs:

- uses: actions/setup-node@v3
with:
node-version: "14.x"
node-version: "18.x"
cache: "yarn"
cache-dependency-path: monitoring/yarn.lock

Expand Down
6 changes: 2 additions & 4 deletions monitoring/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:14-alpine as builder
FROM node:18-alpine as builder

# Add packages necessary to perform the build process.
RUN apk add --update --no-cache \
Expand All @@ -25,20 +25,18 @@ COPY tsconfig.json ./
COPY src ./src

RUN yarn install --frozen-lockfile --ignore-scripts
RUN yarn run postinstall

RUN yarn build

# Prune development dependencies.
RUN rm -rf ./node_modules
RUN rm -rf ./external
RUN yarn install --production --frozen-lockfile --ignore-scripts
RUN yarn run postinstall

# Prune other unnecessary files from dependencies using node-prune.
RUN node-prune

FROM node:14-alpine as runner
FROM node:18-alpine as runner

WORKDIR /monitoring

Expand Down
9 changes: 3 additions & 6 deletions monitoring/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@
"format": "yarn run lint && prettier --check .",
"format:fix": "yarn run lint:fix && prettier --write .",
"lint": "eslint . --ext .js,.ts",
"lint:fix": "eslint . --ext .js,.ts --fix",
"postinstall": "npm rebuild bcrypto"
"lint:fix": "eslint . --ext .js,.ts --fix"
},
"dependencies": {
"@keep-network/tbtc-v2-mainnet": "npm:@keep-network/tbtc-v2@mainnet",
"@keep-network/tbtc-v2-testnet": "npm:@keep-network/tbtc-v2@sepolia",
"@keep-network/tbtc-v2.ts": "1.4.0-dev.1",
"@keep-network/tbtc-v2.ts": "v2.5.0-dev.5",
"@sentry/node": "^7.33.0",
"axios": "^1.3.2",
"ethers": "^5.5.2",
Expand All @@ -29,6 +26,6 @@
"typescript": "^4.9.5"
},
"engines": {
"node": ">=14 <15"
"node": ">=16"
}
}
4 changes: 2 additions & 2 deletions monitoring/src/block-explorer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { context, Environment } from "./context"

import type { BitcoinTransactionHash, Hex } from "@keep-network/tbtc-v2.ts"
import type { BitcoinTxHash, Hex } from "@keep-network/tbtc-v2.ts"

const ethTxUrlPrefixMapping = {
[Environment.Mainnet]: "https://etherscan.io/tx",
Expand All @@ -18,6 +18,6 @@ const btcTxUrlPrefixMapping = {
[Environment.Testnet]: "https://mempool.space/testnet/tx",
}

export function createBtcTxUrl(txHash: BitcoinTransactionHash) {
export function createBtcTxUrl(txHash: BitcoinTxHash) {
return `${btcTxUrlPrefixMapping[context.environment]}/${txHash.toString()}`
}
21 changes: 21 additions & 0 deletions monitoring/src/blocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { providers } from "ethers"

import { context } from "./context"

const resolve = () => {
const provider = new providers.JsonRpcProvider(context.ethereumUrl)

const latestBlock = async () => {
const block = await provider.getBlock("latest")
return block.number
}

const blockTimestamp = async (blockNumber: number): Promise<number> => {
const block = await provider.getBlock(blockNumber)
return block.timestamp
}

return { latestBlock, blockTimestamp }
}

export const blocks = resolve()
14 changes: 14 additions & 0 deletions monitoring/src/context.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { BitcoinNetwork, Chains } from "@keep-network/tbtc-v2.ts"

// List of environment variables used by the monitoring package.
const {
ENVIRONMENT,
Expand All @@ -15,6 +17,16 @@ export enum Environment {
Testnet = "testnet",
}

const ethereumEnvironmentMapping = {
[Environment.Mainnet]: Chains.Ethereum.Mainnet,
[Environment.Testnet]: Chains.Ethereum.Sepolia,
}

const bitcoinEnvironmentMapping = {
[Environment.Mainnet]: BitcoinNetwork.Mainnet,
[Environment.Testnet]: BitcoinNetwork.Testnet,
}

const resolveEnvironment = () => {
switch (ENVIRONMENT) {
case Environment.Mainnet: {
Expand Down Expand Up @@ -57,4 +69,6 @@ export const context = {
dataDirPath: DATA_DIR_PATH ?? "./data",
sentryDsn: SENTRY_DSN,
discordWebhookUrl: DISCORD_WEBHOOK_URL,
ethereumEnvironmentMapping,
bitcoinEnvironmentMapping,
}
74 changes: 0 additions & 74 deletions monitoring/src/contracts.ts

This file was deleted.

6 changes: 4 additions & 2 deletions monitoring/src/deposit-monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import { context } from "./context"
import { createBtcTxUrl, createEthTxUrl } from "./block-explorer"

import type { SystemEvent, Monitor as SystemEventMonitor } from "./system-event"
import type { DepositRevealedEvent as DepositRevealedChainEvent } from "@keep-network/tbtc-v2.ts/dist/src/deposit"
import type { Bridge } from "@keep-network/tbtc-v2.ts/dist/src/chain"
import type {
Bridge,
DepositRevealedEvent as DepositRevealedChainEvent,
} from "@keep-network/tbtc-v2.ts"

export const satsToRoundedBTC = (sats: BigNumber): string =>
(sats.div(BigNumber.from(1e6)).toNumber() / 100).toFixed(2)
Expand Down
115 changes: 78 additions & 37 deletions monitoring/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { ElectrumClient } from "@keep-network/tbtc-v2.ts"
import {
ElectrumClient,
loadEthereumCoreContracts,
TBTC,
} from "@keep-network/tbtc-v2.ts"
import { providers } from "ethers"

import { Manager as SystemEventManager } from "./system-event"
import { DepositMonitor } from "./deposit-monitor"
import { contracts } from "./contracts"
import { DiscordReceiver } from "./discord-receiver"
import { SentryReceiver } from "./sentry-receiver"
import {
Expand All @@ -15,53 +19,90 @@ import { WalletMonitor } from "./wallet-monitor"
import { SupplyMonitor } from "./supply-monitor"
import { RedemptionMonitor } from "./redemption-monitor"

import type { Client as BitcoinClient } from "@keep-network/tbtc-v2.ts/dist/src/bitcoin"
import type {
Monitor as SystemEventMonitor,
Receiver as SystemEventReceiver,
} from "./system-event"

const btcClient: BitcoinClient = ElectrumClient.fromUrl(context.electrumUrl)
async function setupSDK(): Promise<TBTC> {
const provider = new providers.JsonRpcProvider(context.ethereumUrl)
const chainId = context.ethereumEnvironmentMapping[context.environment]
const tbtcContracts = await loadEthereumCoreContracts(provider, chainId)

const monitors: SystemEventMonitor[] = [
new DepositMonitor(contracts.bridge),
new MintingMonitor(contracts.bridge, contracts.tbtcVault, btcClient),
new SupplyMonitor(contracts.tbtcToken, new SupplyMonitorFilePersistence()),
new WalletMonitor(contracts.bridge),
new RedemptionMonitor(contracts.bridge),
]
const bitcoinNetwork = context.bitcoinEnvironmentMapping[context.environment]
const btcClient = ElectrumClient.fromUrl(context.electrumUrl)
if ((await btcClient.getNetwork()) !== bitcoinNetwork) {
throw new Error("Bitcoin network mismatch")
}

const receivers: SystemEventReceiver[] = ((): SystemEventReceiver[] => {
const registered: SystemEventReceiver[] = []
return TBTC.initializeCustom(tbtcContracts, btcClient)
}

if (context.discordWebhookUrl) {
console.log("registered Discord receiver")
registered.push(new DiscordReceiver(context.discordWebhookUrl))
}
async function setupMonitoring(sdk: TBTC): Promise<SystemEventManager> {
const { tbtcContracts, bitcoinClient } = sdk

if (context.sentryDsn) {
console.log("registered Sentry receiver")
registered.push(new SentryReceiver(context.sentryDsn))
}
const monitors: SystemEventMonitor[] = [
new DepositMonitor(tbtcContracts.bridge),
new MintingMonitor(
tbtcContracts.bridge,
tbtcContracts.tbtcVault,
bitcoinClient
),
new SupplyMonitor(
tbtcContracts.tbtcToken,
new SupplyMonitorFilePersistence()
),
new WalletMonitor(tbtcContracts.bridge),
new RedemptionMonitor(tbtcContracts.bridge),
]

return registered
})()
const receivers: SystemEventReceiver[] = ((): SystemEventReceiver[] => {
const registered: SystemEventReceiver[] = []

const manager = new SystemEventManager(
monitors,
receivers,
new SystemEventFilePersistence()
)
if (context.discordWebhookUrl) {
// eslint-disable-next-line no-console
console.log("registered Discord receiver")
registered.push(new DiscordReceiver(context.discordWebhookUrl))
}

manager.trigger().then((report) => {
switch (report.status) {
case "success": {
console.log(report)
break
if (context.sentryDsn) {
// eslint-disable-next-line no-console
console.log("registered Sentry receiver")
registered.push(new SentryReceiver(context.sentryDsn))
}
case "failure": {
console.error(report)
break

return registered
})()

return new SystemEventManager(
monitors,
receivers,
new SystemEventFilePersistence()
)
}

async function setup(): Promise<SystemEventManager> {
const sdk = await setupSDK()
return setupMonitoring(sdk)
}

setup().then((manager) => {
// eslint-disable-next-line no-console
console.log("setup completed; triggering monitoring manager")

manager.trigger().then((report) => {
// eslint-disable-next-line default-case
switch (report.status) {
case "success": {
// eslint-disable-next-line no-console
console.log(report)
break
}
case "failure": {
// eslint-disable-next-line no-console
console.error(report)
break
}
}
}
})
})
Loading

0 comments on commit f364b70

Please sign in to comment.