Skip to content

fix(tron): route deployment MongoDB logging through the working update-deployment-logs.ts path#2018

Open
0xDEnYO wants to merge 3 commits into
mainfrom
fix/tron-deployment-log-mongodb-write-v2
Open

fix(tron): route deployment MongoDB logging through the working update-deployment-logs.ts path#2018
0xDEnYO wants to merge 3 commits into
mainfrom
fix/tron-deployment-log-mongodb-write-v2

Conversation

@0xDEnYO

@0xDEnYO 0xDEnYO commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Which Linear task belongs to this PR?

Fixes EXSC-589 — EXSC-589 was originally filed as a follow-up for the hardcoded optimizer-runs=200 value (see below), now also fixed in this same PR.

Why did I implement it this way?

While investigating why the Tron deploy runbook has a manual "update deployments/tron.json/tron.diamond.json" step, I found that step is actually stale — those files are already written automatically by saveContractAddress() / updateDiamondJsonBatch() during every Tron deploy.

But that investigation surfaced a real, separate bug: logDeployment() in script/utils/utils.ts (used by every Tron deploy script) has been shelling out to script/helperFunctions.sh logDeployment ... to write the MongoDB deployment-log record — except helperFunctions.sh has never had a logDeployment function (only logContractDeploymentInfo) and has no argument dispatcher at the bottom of the file. So the shell-out has silently exited 0 and done nothing since it was introduced (c93177d10). Every Tron deploy since then has been missing from the MongoDB deployment log that query-deployment-logs.ts reads.

This is Tron-specific — EVM deploys never go through this function; deploySingleContract.sh calls the working logContractDeploymentInfo bash function directly, which in turn invokes bunx tsx script/deploy/update-deployment-logs.ts add ....

The fix: point logDeployment() at that same, already-working update-deployment-logs.ts add CLI instead of the nonexistent bash function, with the same field mapping logContractDeploymentInfo uses (contract/network/version/address/optimizer-runs/timestamp/constructor-args/verified/solc-version/evm-version). No behavior change for EVM; Tron deploys now actually land in MongoDB.

I also left a comment on the Notion runbook explaining both findings and suggesting step 6 be simplified to point at the "end-to-end deploy flow" section instead of restating it.

Update: the hardcoded --optimizer-runs 200 finding below was originally deferred to EXSC-589 as a separate follow-up, but ended up landing on this same branch instead of a new PR — see the second /pr-ready entry.

/pr-ready (local CodeRabbit) — 2 findings, both resolved

  • script/utils/utils.ts:304--optimizer-runs was hardcoded to '200', but foundry.toml's [profile.default].optimizer_runs is actually 1000000, so the MongoDB deployment-log record stored an inaccurate value. Pre-existing (not introduced by this PR — the old broken command hardcoded the same "200"). Fixed by adding getFoundryDefaultOptimizerRuns() (mirroring getFoundryDefaultSolcVersion()/getFoundryDefaultEvmVersion()), tracked as EXSC-589.
  • script/utils/utils.ts:102 — the follow-up commit's regex fallback for optimizer_runs only captured leading digits (1_0001) and didn't validate the result as a real integer. Fixed: regex now accepts underscore-separated digits, and the final value is validated with Number.isSafeInteger.

Checklist before requesting a review

  • I have performed a self-review of my code
  • This pull request is as small as possible and only tackles one problem
  • I have run /pr-ready (local CodeRabbit) on this branch and resolved (or explicitly documented) all findings — see .agents/commands/pr-ready.md
  • I have added tests that cover the functionality / test the bug
  • For new facets: I have checked all points from this list: https://www.notion.so/lifi/New-Facet-Contract-Checklist-157f0ff14ac78095a2b8f999d655622e
  • I have updated any required documentation

Checklist for reviewer (DO NOT DEPLOY and contracts BEFORE CHECKING THIS!!!)

  • I have checked that any arbitrary calls to external contracts are validated and or restricted
  • I have checked that any privileged calls (i.e. storage modifications) are validated and or restricted
  • I have ensured that any new contracts have had AT A MINIMUM 1 preliminary audit conducted on by <company/auditor>

…e-deployment-logs.ts path

logDeployment() in script/utils/utils.ts shelled out to a `logDeployment`
function in helperFunctions.sh that never existed, so every Tron deploy has
silently no-op'd its MongoDB deployment-log write since the function was
introduced. deployments/tron.json and tron.diamond.json were unaffected
(written separately by saveContractAddress/updateDiamondJsonBatch); only the
MongoDB record used by query-deployment-logs.ts was missing. Now calls the
same `bunx tsx script/deploy/update-deployment-logs.ts add` command that
EVM's logContractDeploymentInfo already uses.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@lifi-action-bot lifi-action-bot marked this pull request as draft July 3, 2026 04:01
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds an optional optimizer_runs field to IFoundryTomlConfig, extends foundry.toml parsing to extract it, introduces a new getFoundryDefaultOptimizerRuns() helper with validation, and reworks logDeployment to invoke update-deployment-logs.ts add with --optimizer-runs instead of the previous helperFunctions.sh JSON logging flow.

Changes

Optimizer runs config and deployment logging

Layer / File(s) Summary
Config type and foundry.toml parsing for optimizer_runs
script/common/types.ts, script/utils/utils.ts, script/utils/utils.test.ts
Adds optional optimizer_runs?: number to IFoundryTomlConfig, extends regex-based fallback parsing to extract and validate optimizer_runs, adds exported getFoundryDefaultOptimizerRuns() with safe-integer/non-negative validation and error handling, and adds a test asserting the value 1000000.
logDeployment routed through MongoDB update script
script/utils/utils.ts
Updates logDeployment docstring and shell command construction to call bunx tsx script/deploy/update-deployment-logs.ts add with --optimizer-runs and other args, replacing the prior script/helperFunctions.sh logDeployment invocation.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

  • lifinance/contracts#1229: Original introduction of the MongoDB update-deployment-logs.ts script including optimizerRuns field, which this PR now wires logDeployment to call.
  • lifinance/contracts#1304: Modifies update-deployment-logs.ts connection/indexing behavior, overlapping with the same Mongo logging flow this PR routes logDeployment through.
  • lifinance/contracts#1472: Restructures OPTIMIZER_RUNS deployment log output, directly affected by this PR's addition of --optimizer-runs to the logging command.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main change: fixing Tron deployment MongoDB logging via the working update-deployment-logs.ts path.
Description check ✅ Passed The description includes the Linear task, rationale, testing/docs notes, and a mostly completed checklist, so it satisfies the template overall.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/tron-deployment-log-mongodb-write-v2

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

Comment @coderabbitai help to get the list of available commands.

@0xDEnYO 0xDEnYO marked this pull request as ready for review July 3, 2026 04:03
@0xDEnYO 0xDEnYO enabled auto-merge (squash) July 3, 2026 04:03
0xDEnYO and others added 2 commits July 3, 2026 11:47
…g 200

logDeployment() passed a hardcoded '200' as --optimizer-runs to
update-deployment-logs.ts, but foundry.toml's [profile.default] is
1000000 — every Tron deployment's MongoDB log record stored an
inaccurate value. Adds getFoundryDefaultOptimizerRuns(), mirroring the
existing solc/evm-version helpers, with the same TOML-parse-then-regex
fallback (extended to match unquoted numeric values).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ipt/utils/utils.ts:102)

CR says: the regex fallback captured only leading digits (`1_000` -> `1`)
and the parsed/TOML value was never validated as a real integer.

Extends the fallback regex to accept underscore-separated digits and
normalizes them, then validates the final value with Number.isSafeInteger
in both the fallback and the TOML happy-path getter.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@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.

🧹 Nitpick comments (1)
script/utils/utils.test.ts (1)

1-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test reads the real foundry.toml instead of mocking it, and doesn't cover validation branches.

This test calls getFoundryDefaultOptimizerRuns() directly against the actual repo foundry.toml, asserting a hardcoded value (1000000). It will break whenever optimizer_runs legitimately changes and doesn't test the function's own validation logic (missing/non-integer/negative optimizer_runs), which is the core new logic added in this PR.

As per coding guidelines, **/*.{test,spec}.{js,ts,jsx,tsx,py,java,go,rb} should "Use mocking and stubbing libraries appropriate to your language/framework to isolate units under test," and **/*.{test,spec}.{ts,tsx} tests should "Ensure tests are deterministic and do not depend on execution order or external state."

♻️ Example using bun:test's mock.module to isolate and cover error paths
 import {
   describe,
   expect,
   it,
+  mock,
   // eslint-disable-next-line import/no-unresolved
 } from 'bun:test'

-import { getFoundryDefaultOptimizerRuns } from './utils'
+describe('getFoundryDefaultOptimizerRuns', () => {
+  it('returns optimizer_runs when present and valid', () => {
+    mock.module('node:fs', () => ({
+      readFileSync: () => '[profile.default]\noptimizer_runs = 1_000_000\n',
+    }))
+    const { getFoundryDefaultOptimizerRuns } = require('./utils')
+    expect(getFoundryDefaultOptimizerRuns()).toBe(1000000)
+  })

-describe('getFoundryDefaultOptimizerRuns', () => {
-  it('returns the optimizer_runs value from [profile.default] in foundry.toml', () => {
-    expect(getFoundryDefaultOptimizerRuns()).toBe(1000000)
-  })
+  it('throws when optimizer_runs is missing', () => {
+    mock.module('node:fs', () => ({
+      readFileSync: () => '[profile.default]\nsolc_version = "0.8.20"\n',
+    }))
+    const { getFoundryDefaultOptimizerRuns } = require('./utils')
+    expect(() => getFoundryDefaultOptimizerRuns()).toThrow()
+  })
 })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@script/utils/utils.test.ts` around lines 1 - 17, The
`getFoundryDefaultOptimizerRuns` test is coupled to the real `foundry.toml` and
only checks one happy path, so it should be made deterministic by mocking the
file-reading/parsing dependency used inside `script/utils/utils.ts` and
validating the new branches too. Update the `getFoundryDefaultOptimizerRuns`
spec to stub the TOML input for `foundry.toml`, then add separate cases for a
valid `profile.default.optimizer_runs`, missing `optimizer_runs`, non-integer
values, and negative values so the function’s validation logic is exercised
without relying on repo state.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@script/utils/utils.test.ts`:
- Around line 1-17: The `getFoundryDefaultOptimizerRuns` test is coupled to the
real `foundry.toml` and only checks one happy path, so it should be made
deterministic by mocking the file-reading/parsing dependency used inside
`script/utils/utils.ts` and validating the new branches too. Update the
`getFoundryDefaultOptimizerRuns` spec to stub the TOML input for `foundry.toml`,
then add separate cases for a valid `profile.default.optimizer_runs`, missing
`optimizer_runs`, non-integer values, and negative values so the function’s
validation logic is exercised without relying on repo state.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: dac73b29-48a1-46f4-8a56-226cbb7f81aa

📥 Commits

Reviewing files that changed from the base of the PR and between a5bd281 and 02c1ebd.

📒 Files selected for processing (3)
  • script/common/types.ts
  • script/utils/utils.test.ts
  • script/utils/utils.ts

@lifi-qa-agent

lifi-qa-agent Bot commented Jul 3, 2026

Copy link
Copy Markdown

🔍 QA Review — EXSC-589

🔗 Linear Ticket · Pull Request #2018

🧠 What this ticket does

Every Tron deployment since the function was introduced has been recording an inaccurate optimizer_runs value of 200 in the MongoDB deployment log, because logDeployment() in script/utils/utils.ts hardcoded --optimizer-runs 200 when shelling out. The actual foundry.toml value is 1000000. This PR fixes that by adding a getFoundryDefaultOptimizerRuns() helper that reads the real value from foundry.toml at runtime — mirroring the existing getFoundryDefaultSolcVersion() and getFoundryDefaultEvmVersion() pattern — and wiring it into the logDeployment() call. The PR also fixes a second, larger bug (the shell-out was targeting a non-existent bash function and silently doing nothing), but that is the broader PR scope; EXSC-589 specifically tracks the hardcoded 200 portion.

Verdict: Needs Work — the new getFoundryDefaultOptimizerRuns() function's error-path validation logic is completely untested, and the single existing test is brittle and non-isolated.


📋 Ticket Summary

Fix hardcoded optimizer-runs=200 in Tron MongoDB deployment log

The ticket identifies the root cause (hardcoded escapeShellArg('200')), prescribes the exact fix pattern (getFoundryDefaultOptimizerRuns() mirroring sibling helpers), calls out the need for a numeric-value regex variant, and requires a unit test. All of this is implemented in the PR.

Acceptance Criteria (inferred from ticket description — no explicit checklist):

  1. getFoundryDefaultOptimizerRuns() helper added, reading from foundry.toml [profile.default].optimizer_runs — ✅ Met
    • Evidence: script/utils/utils.ts lines 163–192
  2. IFoundryProfileDefaultConfig type gets optimizer_runs?: number field — ✅ Met
    • Evidence: script/common/types.tsoptimizer_runs?: number added to IFoundryTomlConfig.profile.default. IFoundryProfileDefaultConfig is derived as NonNullable<NonNullable<IFoundryTomlConfig['profile']>['default']>, so the field propagates automatically. No separate change required.
  3. Numeric regex fallback handles unquoted integer value — ✅ Met
    • Evidence: extractNumeric() in utils.ts ~line 102; regex (\d(?:_?\d)*) correctly captures both 1000000 and underscore-separated forms like 1_000_000. The replace(/_/g, '') normalises before conversion.
  4. Hardcoded '200' replaced with dynamic value — ✅ Met
    • Evidence: utils.ts logDeployment() now calls getFoundryDefaultOptimizerRuns() and passes result via escapeShellArg(String(optimizerRuns)).
  5. Unit test added — ⚠️ Partial
    • Evidence: script/utils/utils.test.ts exists and runs one happy-path case, but the test reads the real foundry.toml rather than mocking it, and the three error branches (missing field, non-integer, negative value) have no test coverage. See Issues below.

🏷️ PR Naming — ✅ Pass

fix(tron): route deployment MongoDB logging through the working update-deployment-logs.ts path

Follows conventional-commit style (fix(scope): summary). The title accurately describes the primary fix in the PR; EXSC-589 is the embedded secondary fix, clearly documented in the PR body. Scope tron is appropriate.

🔎 Ticket Discoverability — ✅ Pass

EXSC-589 found in: PR description body (linked explicitly twice with full URL).

Note: EXSC-589 does not appear in the PR title or branch name (fix/tron-deployment-log-mongodb-write-v2). This is acceptable given the PR covers two issues; the ticket link in the body is the authoritative reference per the PR template.

🛡️ Version & Audit State

Contract Version Bumped in PR Audit log entry PR labels
N/A — TypeScript-only changes n/a n/a n/a AuditNotRequired ✅

No Solidity contracts under src/ were modified. AuditNotRequired label is correct. No version bump or audit log entry needed.


✅ Ticket Coverage — High

The EXSC-589 fix is fully implemented. The helper follows the established pattern exactly, the type extension is minimal and correct, the regex correctly handles the unquoted integer format, and the shell command argument is now dynamic. The only gap is test completeness (see below).


⚠️ Issues Found (2)

# Severity Type Issue
1 🟠 Medium Test gap getFoundryDefaultOptimizerRuns error branches have no test coverage
2 🟡 Low Test quality Single test is coupled to live foundry.toml — brittle and non-isolated

🟠 [Medium] getFoundryDefaultOptimizerRuns error branches have no test coverage

getFoundryDefaultOptimizerRuns() in script/utils/utils.ts contains explicit validation logic with three error-path branches:

  1. typeof optimizerRuns !== 'number' — fires when optimizer_runs is absent from [profile.default]
  2. !Number.isSafeInteger(optimizerRuns) — fires when the parsed value is a float or overflows safe integer range
  3. optimizerRuns < 0 — fires when the value is negative

None of these branches are exercised by script/utils/utils.test.ts. The ticket description explicitly says "Cover with a unit test" and the PR author checked "I have added tests that cover the functionality / test the bug" — that coverage is incomplete. Bugs in the validation logic (e.g. a future refactor that accidentally removes the < 0 check) would go undetected.

Also uncovered in extractNumeric() (the regex fallback path): the case where the key is present but the parsed value fails Number.isSafeInteger validation (e.g. an astronomically large integer that overflows) — extractNumeric returns undefined in this case, triggering the outer throw, but this path has no test.

Suggested fix: add at minimum three further test cases using mock.module('node:fs', ...) to control the TOML content:

  • optimizer_runs absent from [profile.default] → expects throw
  • optimizer_runs = -1 → expects throw
  • optimizer_runs = 1_000_000 (underscore-separated) → expects toBe(1000000) (also validates the regex underscore-stripping path)

CodeRabbit flagged the same isolation issue as a nitpick with a concrete mock.module example.


🟢 [Low] Single test is coupled to live foundry.toml — brittle and non-isolated

script/utils/utils.test.ts line 14: expect(getFoundryDefaultOptimizerRuns()).toBe(1000000) calls the function directly against the real foundry.toml. This creates two problems:

  1. Fragility: if optimizer_runs is legitimately changed in foundry.toml (e.g. tuned for a new compiler version), this test will fail on an unrelated PR with a confusing error message.
  2. Non-isolation: the test is an integration test disguised as a unit test. It depends on file system state and the current directory when the test runner executes — making it environment-sensitive.

The ticket description says "Cover with a unit test" — a proper unit test should mock the file-reading dependency so it exercises only the helper's own logic, not the current value in foundry.toml.

Suggested fix: use mock.module('node:fs', () => ({ readFileSync: () => '[profile.default]\noptimizer_runs = 1000000\n' })) (or the Bun equivalent) to decouple from the real file. This is the same approach CodeRabbit recommended.

This is Low rather than Medium because the happy-path value of 1000000 is unlikely to change in the near term and the test still provides some regression protection, but it should be fixed before it causes false-positive CI failures on an unrelated change.


🧪 Test Coverage

Layer Score Files reviewed
TypeScript unit tests Partial script/utils/utils.test.ts (new)
Deploy scripts N/A No deploy script changes in this PR

Gaps — all are requested changes, every item must be addressed or explicitly accepted:

TypeScript unit test gaps:

  • [Medium] getFoundryDefaultOptimizerRuns — missing: throw branch when optimizer_runs is absent from [profile.default]
  • [Medium] getFoundryDefaultOptimizerRuns — missing: throw branch when optimizer_runs < 0
  • [Medium] getFoundryDefaultOptimizerRuns — missing: validation of underscore-separated integer input (e.g. 1_000_000) via the regex fallback path
  • [Low] utils.test.ts — test reads real foundry.toml instead of mocking the file dependency; makes the test brittle and non-deterministic across environments

🔗 Downstream Impact

Blocks: None listed in ticket relations.

Operational: TypeScript-only changes — no redeploy, no diamond cut, no EVM network impact. The fix corrects MongoDB deployment log data for future Tron deployments only. Historical records written with 200 are not back-filled; if historical accuracy matters, a one-time migration script would be needed (out of scope for this PR — not flagged as a required change, noting for completeness). No indexer or backend coordination required since deployment-log records are internal tooling data only.


QA Agent — 2026-07-03

@lifi-qa-agent lifi-qa-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Requesting changes on 2 items — each requires either a code fix or an explicit acceptance comment with justification before this review is considered complete.

# Severity Type Issue / File
1 🟠 Medium Test gap script/utils/utils.test.tsgetFoundryDefaultOptimizerRuns error branches untested
2 🟢 Low Test quality script/utils/utils.test.ts — test coupled to live foundry.toml (brittle, non-isolated)

1. [Medium] Test gap — script/utils/utils.test.ts

  • Missing: throw case when optimizer_runs is absent from [profile.default]
  • Missing: throw case when optimizer_runs is negative (e.g. -1)
  • Missing: valid underscore-separated integer (e.g. 1_000_000) via the regex fallback path — validates the replace(/_/g, '') normalisation
  • The three error branches in getFoundryDefaultOptimizerRuns() are the core new logic added by this PR; none are exercised

2. [Low] Test quality — script/utils/utils.test.ts (also flagged by CodeRabbit)
The single test (expect(getFoundryDefaultOptimizerRuns()).toBe(1000000)) reads the real foundry.toml directly. If optimizer_runs is legitimately changed in foundry.toml on a future PR, this test will fail with a confusing, misleading failure. Decouple the test from the repo file system by mocking node:fs readFileSync (e.g. via mock.module from bun:test) to supply controlled TOML content.

💡 Once you've addressed the items above, re-apply the "Agent Review Request" label to trigger an automated re-review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants