Skip to content
This repository was archived by the owner on Feb 8, 2026. It is now read-only.

tx_indexer#89

Merged
webpiratt merged 1 commit into
mainfrom
87-tx-indexer
Jun 12, 2025
Merged

tx_indexer#89
webpiratt merged 1 commit into
mainfrom
87-tx-indexer

Conversation

@webpiratt

@webpiratt webpiratt commented Jun 11, 2025

Copy link
Copy Markdown
Contributor

Scope of this PR, closes: #87:

  • tx_indexer on-chain worker instance for plugin db;
  • tx_indexer as a package imported from verifier, and proposed/verified/signed off-chain change states called with tx_indexer.Service wrapper into plugin db;
  • tx_indexer table migration added for plugin db;

To be implemented in next PR:

Summary by CodeRabbit

  • New Features
    • Introduced transaction tracking and indexing for plugin messages, enabling enhanced monitoring of transaction status.
    • Added a transaction indexer service with PostgreSQL support, including new configuration options and operational parameters.
    • Launched a dedicated transaction indexer worker with its own configuration and main program.
  • Configuration
    • Added new database connection settings and a separate configuration file for the transaction indexer service.
  • Database
    • Created a new tx_indexer table to store transaction metadata and status, supporting improved transaction management and visibility.
  • Dependency Updates
    • Updated and added several dependencies to support new transaction indexing features.

@coderabbitai

coderabbitai Bot commented Jun 11, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

This update introduces a transaction indexer service across multiple server and worker components, adds configuration and migration files for transaction indexing, and integrates transaction tracking into plugin message signing flows. New configuration options and a dedicated transaction indexer worker are included, along with a database migration for the transaction indexing schema.

Changes

File(s) Change Summary
api/plugin.go Integrated transaction tracking into SignPluginMessages using a txIndexerService; removed direct DB status updates.
api/server.go Added txIndexerService field to Server struct and updated NewServer constructor to accept it.
cmd/dca/server/main.go
cmd/payroll/server/main.go
Updated server initialization to create and pass a transaction indexer service to api.NewServer.
cmd/dca/worker/main.go
cmd/payroll/worker/main.go
Integrated transaction indexer service into vault management service initialization.
cmd/dca/worker/config.go Added a Database struct with a DSN field to DCAWorkerConfig.
cmd/tx_indexer/config.go New file: Implements configuration loading for the transaction indexer using Viper.
cmd/tx_indexer/main.go New file: Implements a transaction indexer worker main program.
config-server.yaml Added database.dsn setting; minor whitespace cleanup.
config-tx-indexer.yaml New configuration file for the transaction indexer service, including DB and RPC settings.
go.mod Updated dependencies, added new indirect dependencies, removed/updated indirects.
storage/postgres/migrations/plugin/20250603181247_tx_indexer.sql New migration: Adds tx_indexer table and related ENUM types for transaction tracking.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API_Server
    participant TxIndexerService
    participant Database

    Client->>API_Server: SignPluginMessages(request)
    API_Server->>TxIndexerService: CreateTx (for each message)
    TxIndexerService->>Database: Insert tx_indexer record
    TxIndexerService-->>API_Server: Return TxIndexerID
    API_Server-->>Client: Response with TxIndexerID(s)
Loading
sequenceDiagram
    participant Main
    participant ConfigLoader
    participant TxIndexerStore
    participant TxIndexerService
    participant Server

    Main->>ConfigLoader: Load configuration
    ConfigLoader-->>Main: Config struct
    Main->>TxIndexerStore: NewPostgresTxIndexStore(DSN)
    TxIndexerStore-->>Main: Store instance
    Main->>TxIndexerService: NewService(logger, store, chains)
    TxIndexerService-->>Main: Service instance
    Main->>Server: NewServer(..., txIndexerService)
Loading

Suggested reviewers

  • RaghavSood
  • johnnyluo

Poem

A hop and a skip, a new table we bring,
For tracking transactions and every bling-bling.
Configs and workers, all now aligned,
Indexing each message, robustly designed.
With code and with carrots, we leap ever higher—
A rabbit’s delight: the indexer’s entire! 🥕

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (1.64.8)

level=warning msg="[runner] Can't run linter goanalysis_metalinter: buildir: failed to load package session: could not load export data: no export data for "github.com/vultisig/go-wrappers/go-dkls/sessions""
level=error msg="Running error: can't run linter goanalysis_metalinter\nbuildir: failed to load package session: could not load export data: no export data for "github.com/vultisig/go-wrappers/go-dkls/sessions""

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

♻️ Duplicate comments (2)
config-tx-indexer.yaml (1)

1-3: Secrets in plain text — same concern as server config

Replicate the fix suggested for config-server.yaml; eliminate hard-coded credentials before this file lands in the main branch.

🧰 Tools
🪛 Checkov (3.2.334)

[MEDIUM] 2-3: Basic Auth Credentials

(CKV_SECRET_4)

cmd/dca/server/main.go (1)

58-68: Repeat of store-closing issue

Apply the same defer txIndexerStore.Close() pattern here.

🧹 Nitpick comments (10)
config-tx-indexer.yaml (1)

4-7: Place-holders: leave explicit TODO or remove

Empty url: keys will unmarshal as empty strings and may cause runtime failures. Add clear comments/TODOs or supply sensible defaults.

cmd/payroll/worker/main.go (2)

4-11: Alias collision: use distinct import name for tx-indexer storage

import … "github.com/vultisig/verifier/tx_indexer/pkg/storage" as storage can easily be confused with other storage packages used elsewhere (plugin/storage, etc.). Alias it for clarity:

-import (
-
-    "github.com/vultisig/verifier/tx_indexer/pkg/storage"
+import (
+
+    txstorage "github.com/vultisig/verifier/tx_indexer/pkg/storage"

21-22: Context created but never cancelled

ctx := context.Background() is fine for short-lived functions, but this worker runs indefinitely. Prefer ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) and defer cancel() to allow graceful shutdowns.

cmd/dca/worker/main.go (1)

3-12: Prefer an explicit alias for the tx-indexer store import

Using a bare storage alias next to the already imported vaultStorage variable (and other storage packages in the repo) makes it extremely hard to tell which package is referred to at call-sites.
Rename the import to something unambiguous, e.g. txindexerstorage, for immediate readability.

-	"github.com/vultisig/verifier/tx_indexer/pkg/storage"
+	txindexerstorage "github.com/vultisig/verifier/tx_indexer/pkg/storage"
go.mod (1)

43-47: Vintage btcsuite packages pulled in – verify necessity & CVEs

github.com/btcsuite/btclog, go-socks, and a 2015 snapshot of websocket are ~9 years old. Unless the new verifier version truly depends on them, consider pruning or vendoring newer forks to avoid latent security issues and heavy dependency trees.

Run go mod why / go mod graph | grep btcsuite and decide if they must stay.

cmd/payroll/server/main.go (1)

3-18: Import alias inconsistency across commands

Here you correctly alias the store package as tx_indexer_storage, while cmd/dca/worker/main.go keeps the default storage. Harmonise the alias in all entrypoints to avoid mental context switching.

cmd/tx_indexer/main.go (1)

42-45: Bubble up run error instead of panicking

worker.Run() is presumably long-running; panic on normal shutdown feels harsh and complicates supervisory tooling. Return the error code or log and exit cleanly.

-if err != nil {
-	panic(fmt.Errorf("failed to start worker: %w", err))
-}
+if err != nil && !errors.Is(err, context.Canceled) {
+	logger.Fatalf("worker terminated: %v", err)
+}
cmd/tx_indexer/config.go (2)

22-22: Consider adding more config search paths.

The current implementation only searches for the config file in the current directory. Consider adding additional paths like the executable's directory or a dedicated config directory for better flexibility in deployment scenarios.

 viper.SetConfigName(configName)
 viper.AddConfigPath(".")
+viper.AddConfigPath("/etc/tx_indexer/")
+viper.AddConfigPath("$HOME/.tx_indexer")

23-23: Consider setting environment variable prefix for better organization.

While AutomaticEnv() is called, consider using SetEnvPrefix() to namespace your environment variables and avoid conflicts with other applications.

 viper.AddConfigPath(".")
+viper.SetEnvPrefix("TX_INDEXER")
 viper.AutomaticEnv()
api/plugin.go (1)

126-130: Important: Address transaction replay protection.

The TODO comment correctly identifies the need for transaction replay protection. This is a critical security feature that should be implemented before production deployment. Consider implementing a transaction nonce or timestamp-based validation mechanism.

Would you like me to create a GitHub issue to track the implementation of transaction replay protection based on the strategy-specific periods mentioned in the comment?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e73a526 and 1867dbb.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (13)
  • api/plugin.go (2 hunks)
  • api/server.go (4 hunks)
  • cmd/dca/server/main.go (4 hunks)
  • cmd/dca/worker/config.go (1 hunks)
  • cmd/dca/worker/main.go (2 hunks)
  • cmd/payroll/server/main.go (4 hunks)
  • cmd/payroll/worker/main.go (3 hunks)
  • cmd/tx_indexer/config.go (1 hunks)
  • cmd/tx_indexer/main.go (1 hunks)
  • config-server.yaml (2 hunks)
  • config-tx-indexer.yaml (1 hunks)
  • go.mod (4 hunks)
  • storage/postgres/migrations/plugin/20250603181247_tx_indexer.sql (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
cmd/tx_indexer/main.go (1)
cmd/tx_indexer/config.go (1)
  • GetConfigure (11-18)
🪛 Checkov (3.2.334)
config-server.yaml

[MEDIUM] 7-8: Basic Auth Credentials

(CKV_SECRET_4)

config-tx-indexer.yaml

[MEDIUM] 2-3: Basic Auth Credentials

(CKV_SECRET_4)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build
  • GitHub Check: migration-test
🔇 Additional comments (8)
config-server.yaml (1)

18-18: Nit: stray whitespace cleanup is fine

Just noting that the trailing blanks on bucket were removed – no issues.

cmd/payroll/worker/main.go (2)

63-67: Service instantiated but never started

If tx_indexer.NewService requires an explicit Start() (common pattern), remember to call it in a goroutine and stop it on shutdown.


58-67:

Details

❓ Verification inconclusive

Postgres store not closed; potential connection leak

NewPostgresTxIndexStore likely opens a connection pool. Defer its Close() (or Stop()) method if available.

 txIndexerStore, err := txstorage.NewPostgresTxIndexStore(ctx, cfg.Database.DSN)
 if err != nil {
     panic(fmt.Errorf("storage.NewPostgresTxIndexStore: %w", err))
 }
+defer txIndexerStore.Close() // ensure resources are released

#!/usr/bin/env bash
set -e

# Locate files defining the constructor
files=$(rg -l "NewPostgresTxIndexStore" .)
if [ -z "$files" ]; then
  echo "No files found containing NewPostgresTxIndexStore"
  exit 0
fi

# For each matching file, inspect signature, type, and resource cleanup methods
for file in $files; do
  echo "=== File: $file ==="
  rg -n "func NewPostgresTxIndexStore" "$file"
  rg -n "type .*Store" "$file"
  rg -n "Close(" "$file"
  rg -n "Stop(" "$file"
done

🏁 Script executed:

#!/usr/bin/env bash
set -e

echo "=== Finding NewPostgresTxIndexStore constructor ==="
rg -n "func NewPostgresTxIndexStore" -A2 -B2 .

echo "=== Checking for Close methods on any type ==="
rg -n "func \(.*\*.*\) Close" -A1 -B0 .

echo "=== Checking for Stop methods on any type ==="
rg -n "func \(.*\*.*\) Stop" -A1 -B0 .

Length of output: 170


Verify resource cleanup for PostgresTxIndexStore

The txIndexerStore returned by NewPostgresTxIndexStore likely opens a database connection pool that must be explicitly closed. Please confirm whether the store type provides a Close() (or Stop()) method and, if so, add a deferred call immediately after initialization:

Locations to review:

  • cmd/payroll/worker/main.go: lines 58–67

Suggested diff:

 txIndexerStore, err := txstorage.NewPostgresTxIndexStore(ctx, cfg.Database.DSN)
 if err != nil {
     panic(fmt.Errorf("storage.NewPostgresTxIndexStore: %w", err))
 }
+defer txIndexerStore.Close() // ensure DB connections are released

If the cleanup is handled elsewhere or there is no explicit teardown method, please document how resources are released.

api/server.go (2)

34-46: Field added, but access not shown here

txIndexerService is wired in, good. Double-check all handlers use the injected service, and nil checks guard against missing initialisation in older call-sites.


60-61: Constructor signature changed – ensure all callers updated

Compile will fail if any NewServer(...) invocations weren’t amended with the new parameter; run go vet ./... to verify.

cmd/dca/worker/main.go (1)

54-58: Potential resource leak – TxIndexStore is never closed

storage.NewPostgresTxIndexStore returns an object that implements io.Closer.
If the worker exits (e.g. srv.Run returns an error) the underlying pgx pool will remain open.

 txIndexerStore, err := storage.NewPostgresTxIndexStore(ctx, cfg.Database.DSN)
 if err != nil {
     panic(fmt.Errorf("storage.NewPostgresTxIndexStore: %w", err))
 }
+defer txIndexerStore.Close()
api/plugin.go (1)

102-120: Transaction tracking implementation looks good!

The conditional check for txIndexerService and proper error handling ensure graceful degradation when the service is unavailable. The transaction creation logic correctly captures all necessary metadata.

storage/postgres/migrations/plugin/20250603181247_tx_indexer.sql (1)

1-33: Well-designed schema for transaction tracking!

The migration properly defines status ENUMs, includes comprehensive fields for tracking transaction lifecycle, and has thoughtful comments explaining the lost flag mechanism. The index on (status_onchain, lost) will efficiently support queries for active transactions.

Comment thread config-server.yaml
Comment thread cmd/dca/worker/config.go
Comment thread cmd/payroll/server/main.go
Comment thread cmd/tx_indexer/main.go
Comment thread cmd/tx_indexer/main.go
Comment thread storage/postgres/migrations/plugin/20250603181247_tx_indexer.sql
@webpiratt
webpiratt enabled auto-merge June 11, 2025 19:00

@johnnyluo johnnyluo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@webpiratt
webpiratt merged commit 675c1c6 into main Jun 12, 2025
3 checks passed
@webpiratt
webpiratt deleted the 87-tx-indexer branch June 12, 2025 03:26
@coderabbitai coderabbitai Bot mentioned this pull request Jun 17, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Run copy of tx_indexer for both plugin and verifier databases

2 participants