Skip to content

Commit 441dfc2

Browse files
feat: [Indexer] Wiring (#170)
* feat: indexer fetcher * feat: indexer refactored * improved impl * store modified * removed doc * feat: indexer http service * feat: only applied private http * lint fixed * removed unused middleware * feat: pg implementation for indexer store * ordering fix * lint fix and improvements * wired indexer * http private * lint fixed * Update cmd/indexer/migrate/main.go Co-authored-by: Arun Dhyani <dhyaniarun7@gmail.com> --------- Co-authored-by: Arun Dhyani <dhyaniarun7@gmail.com>
1 parent 2a2bddc commit 441dfc2

19 files changed

Lines changed: 563 additions & 44 deletions

Dockerfile.local

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ COPY . .
1818
# CGO_ENABLED=0 creates static binaries compatible with alpine
1919
RUN CGO_ENABLED=0 go build -o /app/bin/relayer ./cmd/relayer && \
2020
CGO_ENABLED=0 go build -o /app/bin/api-server ./cmd/api-server && \
21+
CGO_ENABLED=0 go build -o /app/bin/indexer ./cmd/indexer && \
2122
CGO_ENABLED=0 go build -o /app/bin/api-server-migrate ./cmd/api-server/migrate && \
2223
CGO_ENABLED=0 go build -o /app/bin/relayer-migrate ./cmd/relayer/migrate && \
24+
CGO_ENABLED=0 go build -o /app/bin/indexer-migrate ./cmd/indexer/migrate && \
2325
CGO_ENABLED=0 go build -o /app/bin/bootstrap-bridge ./scripts/setup/bootstrap-bridge.go && \
2426
CGO_ENABLED=0 go build -o /app/bin/register-user ./scripts/testing/register-user.go && \
2527
CGO_ENABLED=0 go build -o /app/bin/mock-oauth2-server ./scripts/utils/mock-oauth2-server.go
@@ -69,6 +71,24 @@ ENV ENV=docker
6971

7072
ENTRYPOINT ["/app/docker-bootstrap.sh"]
7173

74+
# Runtime stage for indexer
75+
FROM alpine:latest AS indexer
76+
77+
WORKDIR /app
78+
RUN apk add --no-cache ca-certificates wget
79+
COPY --from=builder /app/bin/indexer /app/indexer
80+
COPY --from=builder /app/bin/indexer-migrate /app/indexer-migrate
81+
COPY --from=builder /app/pkg/config/defaults /app/config/defaults
82+
COPY scripts/setup/entrypoint.sh /app/entrypoint.sh
83+
RUN chmod +x /app/entrypoint.sh
84+
85+
ENV DEFAULT_BINARY=/app/indexer
86+
ENV ENV=docker
87+
88+
EXPOSE 8082
89+
90+
ENTRYPOINT ["/app/entrypoint.sh"]
91+
7292
# Runtime stage for api-server
7393
FROM alpine:latest AS api-server
7494

cmd/indexer/Dockerfile

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Build stage
2+
# Using full golang image (not alpine) for toolchain auto-download support
3+
FROM golang:1.24 AS builder
4+
5+
WORKDIR /app
6+
7+
# Allow Go toolchain to auto-upgrade for dependencies requiring newer versions
8+
ENV GOTOOLCHAIN=auto
9+
10+
# Copy go mod files first
11+
COPY go.mod go.sum ./
12+
13+
# Download deps and build in one layer to preserve toolchain
14+
RUN GOTOOLCHAIN=auto go mod download && \
15+
GOTOOLCHAIN=auto CGO_ENABLED=0 go build -ldflags="-w -s" -o /app/bin/indexer ./cmd/indexer && \
16+
GOTOOLCHAIN=auto CGO_ENABLED=0 go build -ldflags="-w -s" -o /app/bin/indexer-migrate ./cmd/indexer/migrate
17+
18+
# Copy all source
19+
COPY . .
20+
21+
# Runtime stage
22+
FROM alpine:latest
23+
24+
WORKDIR /app
25+
26+
RUN apk add --no-cache ca-certificates
27+
28+
COPY --from=builder /app/bin/indexer /app/indexer
29+
COPY --from=builder /app/bin/indexer-migrate /app/indexer-migrate
30+
31+
EXPOSE 8082
32+
33+
ENTRYPOINT ["/app/indexer"]
34+
CMD ["-config", "/app/config.yaml"]

cmd/indexer/main.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"log"
6+
7+
appindexer "github.com/chainsafe/canton-middleware/pkg/app/indexer"
8+
"github.com/chainsafe/canton-middleware/pkg/config"
9+
)
10+
11+
func main() {
12+
configPath := flag.String("config", "config.yaml", "Path to configuration file")
13+
flag.Parse()
14+
15+
cfg, err := config.LoadIndexerServer(*configPath)
16+
if err != nil {
17+
log.Fatalf("load config: %v", err)
18+
}
19+
20+
if err = appindexer.NewServer(cfg).Run(); err != nil {
21+
log.Fatalf("indexer server exited with error: %v", err)
22+
}
23+
}

cmd/indexer/migrate/main.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"log"
6+
7+
"github.com/uptrace/bun/migrate"
8+
9+
"github.com/chainsafe/canton-middleware/pkg/config"
10+
"github.com/chainsafe/canton-middleware/pkg/migrations/indexerdb"
11+
"github.com/chainsafe/canton-middleware/pkg/pgutil"
12+
mghelper "github.com/chainsafe/canton-middleware/pkg/pgutil/migrations"
13+
)
14+
15+
func main() {
16+
cfgPath := flag.String("config", "config.yaml", "Path to configuration file")
17+
flag.Usage = mghelper.Usage
18+
flag.Parse()
19+
20+
cfg, err := config.LoadIndexerServer(*cfgPath)
21+
if err != nil {
22+
log.Fatalf("load config: %v", err)
23+
}
24+
25+
db, err := pgutil.ConnectDB(cfg.Database)
26+
if err != nil {
27+
log.Fatalf("connect database: %v", err)
28+
}
29+
defer db.Close()
30+
31+
log.Printf("Running migrations for indexer database")
32+
33+
if err = mghelper.RunMigrations(migrate.NewMigrator(db, indexerdb.Migrations), flag.Args()...); err != nil {
34+
mghelper.Exitf(err.Error())
35+
}
36+
}

config.e2e-local.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ database:
2929

3030
# Canton config
3131
canton:
32-
domain_id: "local::1220491bf04408d7cf1a8c9d6147f46a4e300901b5fd2f13dd60c4e871fc5df130d2"
32+
domain_id: "local::122012347c9534aef60e0c941f8baa14d4bd977d18b593011f714078064ce154ed7e"
3333
issuer_party: "BridgeIssuer::1220192c25966fe2d53554dfe3a7e2c1c786268318f9870a26902935f3c912ac51ac"
3434

3535
ledger:

docker-compose.devnet.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,21 @@ services:
5959
CANTON_AUTH_CLIENT_SECRET: "${CANTON_AUTH_CLIENT_SECRET}"
6060
CANTON_MASTER_KEY: "${CANTON_MASTER_KEY}"
6161

62-
# Postgres stays enabled for relayer and API server state
62+
# Indexer connecting to 5North DevNet
63+
indexer:
64+
depends_on: !override
65+
postgres:
66+
condition: service_healthy
67+
volumes: []
68+
command: []
69+
environment:
70+
ENV: devnet
71+
INDEXER_DATABASE_URL: "${INDEXER_DATABASE_URL:-postgres://postgres:p%40ssw0rd@postgres:5432/canton_indexer}"
72+
CANTON_AUTH_CLIENT_ID: "${CANTON_AUTH_CLIENT_ID}"
73+
CANTON_AUTH_CLIENT_SECRET: "${CANTON_AUTH_CLIENT_SECRET}"
74+
CANTON_ISSUER_PARTY: "${CANTON_ISSUER_PARTY}"
75+
76+
# Postgres stays enabled for relayer, API server, and indexer state
6377

6478
volumes:
6579
postgres_data:

docker-compose.local-test.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ services:
2222
LOG_LEVEL: debug
2323
E2E_TEST_MODE: "true"
2424

25+
# Override indexer environment
26+
indexer:
27+
environment:
28+
LOG_LEVEL: debug
29+
E2E_TEST_MODE: "true"
30+
2531
# Override postgres to skip persistent volume for clean test state
2632
postgres:
2733
# No persistent volume - fresh DB each run

docker-compose.mainnet.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ services:
2727
api-server:
2828
profiles: ["disabled"]
2929

30+
indexer:
31+
profiles: ["disabled"]
32+
3033
relayer:
3134
depends_on: !override
3235
postgres:

docker-compose.yaml

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ services:
109109
POSTGRES_USER: postgres
110110
POSTGRES_PASSWORD: p@ssw0rd
111111
POSTGRES_DB: postgres
112-
POSTGRES_MULTIPLE_DATABASES: relayer,erc20_api
112+
POSTGRES_MULTIPLE_DATABASES: relayer,erc20_api,canton_indexer
113113
ports:
114114
- "5432:5432"
115115
volumes:
@@ -154,6 +154,7 @@ services:
154154
ENV: docker
155155
CONFIG_FILE: /app/state/config.yaml
156156
API_SERVER_CONFIG_FILE: /app/state/api-server-config.yaml
157+
INDEXER_CONFIG_FILE: /app/state/indexer-config.yaml
157158
CANTON_HTTP: http://canton:5013
158159
BROADCAST_DIR: /app/broadcast
159160
RELAYER_DATABASE_URL: "${RELAYER_DATABASE_URL:-postgres://postgres:p%40ssw0rd@postgres:5432/relayer}"
@@ -258,6 +259,45 @@ services:
258259
networks:
259260
- bridge-network
260261

262+
# ===========================================================================
263+
# Canton Indexer
264+
# ===========================================================================
265+
indexer:
266+
build:
267+
context: .
268+
dockerfile: Dockerfile.local
269+
target: indexer
270+
container_name: canton-indexer
271+
ports:
272+
- "8082:8082"
273+
volumes:
274+
- config_state:/app/state:ro
275+
command: ["-config", "/app/state/indexer-config.yaml"]
276+
environment:
277+
LOG_LEVEL: debug
278+
ENV: docker
279+
INDEXER_DATABASE_URL: "${INDEXER_DATABASE_URL:-postgres://postgres:p%40ssw0rd@postgres:5432/canton_indexer}"
280+
CANTON_AUTH_CLIENT_ID: "${CANTON_AUTH_CLIENT_ID:-local-test-client}"
281+
CANTON_AUTH_CLIENT_SECRET: "${CANTON_AUTH_CLIENT_SECRET:-local-test-secret}"
282+
depends_on:
283+
bootstrap:
284+
condition: service_completed_successfully
285+
postgres:
286+
condition: service_healthy
287+
canton:
288+
condition: service_healthy
289+
mock-oauth2:
290+
condition: service_healthy
291+
restart: unless-stopped
292+
healthcheck:
293+
test: ["CMD", "wget", "-qO-", "http://localhost:8082/health"]
294+
interval: 10s
295+
timeout: 5s
296+
retries: 5
297+
start_period: 30s
298+
networks:
299+
- bridge-network
300+
261301
networks:
262302
bridge-network:
263303
driver: bridge

0 commit comments

Comments
 (0)