ChainSafe / ChainSafe/canton-middleware

feat(submitter): make pending-entry drain safe and efficient across multiple instances

Open
#282 0 comments 0 reactions 0 assignees View on GitHub
Type: Enhancement
Dominant language
Go
Stars
1
Forks
1
Avg merge
40m
Merged PRs (30d)
1

Description

**Problem**

`pkg/ethrpc/submitter/submitter.go` polls mempool rows in pending status and pushes each one through `erc20.TransferFrom` on Canton, then transitions the row to completed / failed. The drain query is a plain `SELECT … WHERE status = 'pending'` with no row-level locking, no claim/lease, and no leader election around `Submitter.Start`.

When the API server runs as more than one instance (the expected deployment shape once we scale horizontally), every instance:
- Selects the same batch of pending rows on each tick.
- Issues a Canton TransferFrom gRPC call for every one of them in parallel with the other instances.
- Races to write the outcome back to Postgres.

**Current safety net (why nothing is corrupted today)**
- `CompleteMempoolEntry` and `FailMempoolEntry` both guard with WHERE status = 'pending', so the second writer is a silent no-op. So the row can't be flipped from completed to failed or vice versa.
- Canton command-id idempotency on the tx hash means duplicate submissions resolve to one Canton commit

**Why it still matters**
- Wasted Canton RPCs. N instances ⇒ ~N× the gRPC traffic and ~N× the load on Canton for the same backlog.

**Goal**
Each pending row should be processed by exactly one submitter instance per attempt. Transient failures must remain retryable (idempotent under command-id).

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.