Skip to content
Closed
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
26 changes: 26 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.git
.github
.codex
.agents
.DS_Store
.idea
.vscode
.history

build
bin
site
target
tests/*.txt

.env
.env.example
.config.example
config.json
config.example*.json
keys
*.key
*.block
gethdata1
gethdata2
centrifuge-chain
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
MONITOR_DATA_DIR=/opt/bridge-monitor
MONITOR_IMAGE=bridge-monitor:local
MONITOR_CONTAINER_NAME=bridge-monitor
MONITOR_VERSION=local
TZ=Asia/Shanghai
compass=Mainnet-monitor
hooks=
107 changes: 107 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: CD

on:
push:
branches:
- main
- master
tags:
- "v*"
pull_request:
workflow_dispatch:

permissions:
contents: read
packages: write

concurrency:
group: cd-${{ github.ref }}
cancel-in-progress: true

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
GOPRIVATE: github.com/lbtsm/*
GONOSUMDB: github.com/lbtsm/*

jobs:
test:
name: Go test and build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true

- name: Configure private Go module access
env:
LBTSM_REPO_TOKEN: ${{ secrets.LBTSM_REPO_TOKEN }}
run: |
if [ -z "$LBTSM_REPO_TOKEN" ]; then
echo "::warning::LBTSM_REPO_TOKEN is not set; private github.com/lbtsm modules must be public or Go module download will fail."
exit 0
fi
printf "machine github.com\nlogin x-access-token\npassword %s\n" "$LBTSM_REPO_TOKEN" > ~/.netrc
chmod 0600 ~/.netrc

- name: Run unit tests
run: go test ./internal/... ./chains/tron ./pkg/monitor

- name: Build binary
run: go build -trimpath -ldflags="-s -w -X main.Version=${GITHUB_REF_NAME}" -o build/bridge-monitor ./cmd

docker:
name: Docker build
runs-on: ubuntu-latest
needs: test
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Validate Compose file
run: docker compose config

- name: Normalize image name
run: echo "IMAGE_NAME=${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV"

- name: Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=ref,event=branch
type=ref,event=tag
type=sha,prefix=sha-

- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and publish Docker image
uses: docker/build-push-action@v6
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=${{ github.ref_name }}
GOPRIVATE=${{ env.GOPRIVATE }}
secrets: |
github_token=${{ secrets.LBTSM_REPO_TOKEN }}
cache-from: type=gha
cache-to: type=gha,mode=max
45 changes: 45 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# syntax=docker/dockerfile:1

ARG GO_VERSION=1.25

FROM golang:${GO_VERSION}-bookworm AS builder

WORKDIR /src

ARG GOPRIVATE=github.com/lbtsm/*
ENV GOPRIVATE=${GOPRIVATE}
ENV GONOSUMDB=${GOPRIVATE}

COPY go.mod go.sum ./
RUN --mount=type=secret,id=github_token \
set -eu; \
cleanup() { rm -f /root/.netrc; }; \
trap cleanup EXIT; \
if [ -s /run/secrets/github_token ]; then \
token="$(cat /run/secrets/github_token)"; \
printf "machine github.com\nlogin x-access-token\npassword %s\n" "$token" > /root/.netrc; \
chmod 0600 /root/.netrc; \
fi; \
go mod download

COPY . .

ARG VERSION=dev
RUN go build -trimpath -ldflags="-s -w -X main.Version=${VERSION}" -o /out/bridge-monitor ./cmd

FROM debian:bookworm-slim AS runtime

RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates tzdata \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /app/runtime

RUN mkdir -p /app/runtime/keys

COPY --from=builder /out/bridge-monitor /usr/local/bin/bridge-monitor

ENV TZ=Asia/Shanghai

ENTRYPOINT ["bridge-monitor"]
CMD ["monitor", "--config", "/app/runtime/config.json"]
71 changes: 67 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ whether the transaction is cross-chain, and the user balance

# Configuration

See `config.example` for an example configuration.
Use a valid `config.json` for runtime configuration. Keep production config
files and keystores out of git.

## Options

Expand All @@ -16,11 +17,73 @@ See `config.example` for an example configuration.
"waterLine": "5000000000000000000", // If the user balance is lower than, an alarm will be triggered, unit : wei
"changeInterval": "3000", // How long does the lightnode height remain unchanged, triggering the alarm, use for near unit : seconds
"checkHeightCount": "20", // How long does the lightnode height not change remain unchanged, triggering the alarm, default 15
"syncHeightAlarm": "false", // Optional: disable other-chain-to-map sync height alarm, default true
}
```

## TRON Energy Expiry Monitoring

Add `protectedThreshold` to a tron chain's `energy` entry to enable
Stake 2.0 delegation-expiry alerting (protected energy = inbound delegations
whose lock expires strictly after now+lookahead):

```shell
"energy": [{
"address": "TT6GDYkpHPVk24w9he9pavbagtzqBRS3XP",
"waterline": 100000, // existing: current remaining-energy alarm
"protectedThreshold": 10000000, // alert when protected energy drops below
"recoveryThreshold": 10500000, // optional, default = protected × 1.05
"lookaheadHours": 72, // optional, default 72
"checkIntervalMinutes": 60, // optional, default 60
"repeatIntervalHours": 12 // optional, default 12
}]
```

State files are written to `<keystorePath>/energy_state_<address>.json`.
Scan failures alarm separately as "监控异常" and never count as zero energy.

## Env

```shell
export hooks="https://hooks.slack.com/services/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" // Slack alarm hook, Apply See This https://api.slack.com/messaging/webhooks
```
```shell
export hooks="https://hooks.slack.com/services/xxx/yyy/zzz"
```

# Docker Deployment

The container uses `/app/runtime` as its runtime directory. Map one host
directory to it and keep `config.json`, `keys/`, and generated state files in
that host directory.

```shell
sudo mkdir -p /opt/bridge-monitor/keys
sudo cp /path/to/your/config.json /opt/bridge-monitor/config.json

cp .env.example .env
vim .env

docker compose up -d --build
docker compose logs -f bridge-monitor
```

If the `github.com/lbtsm/*` Go modules are private, set a GitHub token with
read access before building locally:

```shell
export LBTSM_REPO_TOKEN="github_pat_xxx"
docker compose up -d --build
```

After pulling updates on the server:

```shell
git pull
docker compose up -d --build
```

GitHub Actions builds and tests the project on pull requests, and builds the
Docker image on pushes to `main`, `master`, or version tags. Non-PR builds are
published to GitHub Container Registry as `ghcr.io/<owner>/<repo>:<branch-or-tag>`.
The default branch also publishes `ghcr.io/<owner>/<repo>:latest`.

For private `github.com/lbtsm/*` dependencies, add a repository secret named
`LBTSM_REPO_TOKEN` with read access to the private dependency repositories.
Loading
Loading