Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Monitoring: Migrate to latest SDK #819

Merged
merged 8 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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) {
tomaszslabon marked this conversation as resolved.
Show resolved Hide resolved
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
Loading