Skip to content

feat(db): support solidity conditional shutdown#70

Open
317787106 wants to merge 7 commits intodevelopfrom
feature/solidity_shutdown
Open

feat(db): support solidity conditional shutdown#70
317787106 wants to merge 7 commits intodevelopfrom
feature/solidity_shutdown

Conversation

@317787106
Copy link
Copy Markdown
Owner

@317787106 317787106 commented Apr 16, 2026

Summary

Closes tronprotocol#6610.

Refactors SolidityNode into a Spring-managed component with proper lifecycle support, enabling it to respond to conditional shutdown signals (block height, block time, block count) already implemented in TronNetDelegate.processBlock. The previous static start() approach bypassed Spring entirely, so the shutdown conditions could never be reached during solidity sync.

Problem

SolidityNode previously initialized its own TronApplicationContext, created a SolidityNode instance manually, and called appT.blockUntilShutdown() in a separate JVM entry path. This architecture had two consequences:

  1. Shutdown conditions were unreachable. The conditional-shutdown logic lives in TronNetDelegate.processBlock (checking latestSolidityNumShutDown), but SolidityNode called Manager.pushVerifiedBlock -> Manager.pushBlock -- a path that never passes through TronNetDelegate. The shutdown signal was therefore silently ignored.
  2. No graceful resource cleanup. Thread pools and gRPC connections were abandoned on JVM exit rather than being released through Spring's @PreDestroy lifecycle.

Changes

SolidityNode (framework)

  • Converted from a static utility class to a Spring @Component with @Conditional(SolidityCondition.class) -- only registered when --solidity flag is set.
  • @PostConstruct init(): initialises named ExecutorService thread pools via ExecutorServiceManager and the gRPC client.
  • @PreDestroy shutdown(): sets flag = false, shuts down both executors, and closes the gRPC client cleanly.
  • getBlockByNum() and getLastSolidityBlockNum() loops now check flag; they throw RuntimeException instead of looping forever when the node is shutting down.
  • loopProcessBlock() now calls tronNetDelegate.pushVerifiedBlock() instead of dbManager.pushVerifiedBlock(), routing blocks through the shutdown-condition check in processBlock.

TronNetDelegate (framework)

  • Added pushVerifiedBlock(BlockCapsule): sets generatedByMyself = true and delegates to processBlock(block, true), which already contains the conditional-shutdown logic. Includes timing log consistent with the removed Manager method.

Manager (framework)

  • Removed pushVerifiedBlock(). Block push for solidity sync now goes through TronNetDelegate.

FullNode (framework)

  • In solidity mode, trustNodeAddr validation and p2pDisable = true are now enforced before the Spring context is created.
  • After appT.startup(), retrieves the SolidityNode bean from the context and calls run() -- reusing the same application lifecycle rather than spawning a second context.

Test

  • SolidityNodeTest#testSolidityGrpcCall -- verifies gRPC connectivity through the running RpcApiService.
  • SolidityNodeTest#testSolidityNodeHttpApiService -- verifies HTTP service start/stop idempotency.
  • ManagerTest#transactionTest (partial) -- the pushVerifiedBlock assertion is commented out as the method no longer exists on Manager; the rest of the test is unaffected.

Summary by CodeRabbit

  • Refactor

    • Refactored Solidity node initialization to use Spring-managed components with improved lifecycle management.
    • Migrated block verification handling to centralized processing path.
    • Enhanced network configuration for Solidity node operation by disabling P2P during initialization.
    • Added validation to ensure required node address configuration is present when running in Solidity mode.
  • Tests

    • Updated test suite to align with Solidity node architecture changes.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 16, 2026

Warning

Rate limit exceeded

@317787106 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 35 minutes and 39 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 35 minutes and 39 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 058622fd-9bc5-4691-ab36-7fff597d0a85

📥 Commits

Reviewing files that changed from the base of the PR and between 50c76de and 1e9c558.

📒 Files selected for processing (1)
  • framework/src/main/java/org/tron/program/SolidityNode.java
📝 Walkthrough

Walkthrough

This change relocates the pushVerifiedBlock public API from Manager to TronNetDelegate, and refactors SolidityNode from a manually bootstrapped class to a Spring-managed component with lifecycle hooks, enabling proper shutdown handling and integration with the application context startup flow.

Changes

Cohort / File(s) Summary
Block Verification API Migration
framework/src/main/java/org/tron/core/db/Manager.java, framework/src/main/java/org/tron/core/net/TronNetDelegate.java
Removed pushVerifiedBlock(BlockCapsule) from Manager; added equivalent method to TronNetDelegate with generatedByMyself flag forcing, processBlock delegation, and info-level duration/block content logging.
SolidityNode Spring Integration
framework/src/main/java/org/tron/program/SolidityNode.java
Refactored from static-bootstrapped class to Spring @Component with @Conditional guard. Constructor removed; added @PostConstruct for initialization, run() method for executor task submission, and @PreDestroy for graceful shutdown. Block verification now routes through tronNetDelegate.pushVerifiedBlock(...) instead of dbManager.pushVerifiedBlock(...).
FullNode Startup Control Flow
framework/src/main/java/org/tron/program/FullNode.java
Removed early exit for Solidity mode; added trustNodeAddr validation with TronError on missing value; set parameter.setP2pDisable(true) for Solidity nodes; deferred SolidityNode startup to post-application-context initialization via Spring bean retrieval and node.run() invocation.
Test Updates
framework/src/test/java/org/tron/core/db/ManagerTest.java, framework/src/test/java/org/tron/program/SolidityNodeTest.java
Removed pushVerifiedBlock/fork-hash validation sequence from transactionTest; deleted testSolidityArgs() method that validated trustNodeAddr initialization and SolidityNode::start exception handling.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 A node once stood alone and static, now springs to life dramatic!
With lifecycle hooks and conditional grace, SolidityNode finds its place.
Block verification takes a new route, through delegates it shall compute.
From manual threads to beans so clean, the cleanest startup ever seen! 🌱

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(db): support solidity conditional shutdown' accurately describes the main feature being implemented: adding conditional shutdown support to the SolidityNode component through Spring bean refactoring.
Linked Issues check ✅ Passed The PR fully implements the requirements from issue #6610: SolidityNode converted to Spring component with conditional shutdown support, p2pdisable forced in solidity mode, and shutdown conditions properly integrated through TronNetDelegate.pushVerifiedBlock routing.
Out of Scope Changes check ✅ Passed All changes align with the stated objective of enabling SolidityNode conditional shutdown; the Manager.pushVerifiedBlock removal and TronNetDelegate addition are necessary supporting refactorings scoped to the solidity node feature.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/solidity_shutdown

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 and usage tips.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 6 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="framework/src/main/java/org/tron/program/SolidityNode.java">

<violation number="1" location="framework/src/main/java/org/tron/program/SolidityNode.java:69">
P1: Shutdown can hang because stop flag is not honored inside the inner retry loops (`getBlockByNum` / `getLastSolidityBlockNum`).</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread framework/src/main/java/org/tron/program/SolidityNode.java Outdated
@317787106 317787106 force-pushed the feature/solidity_shutdown branch from 3fc0053 to 0e5a48f Compare April 23, 2026 10:04
@317787106 317787106 changed the base branch from release_v4.8.1 to develop April 23, 2026 10:05
@317787106 317787106 changed the title feat(db): support solidity shutdown feat(db): support solidity conditional shutdown Apr 23, 2026
resolveCompatibilityIssueIfUsingFullNodeDatabase();
ID.set(chainBaseManager.getDynamicPropertiesStore().getLatestSolidifiedBlockNum());
databaseGrpcClient = new DatabaseGrpcClient(CommonParameter.getInstance().getTrustNodeAddr());
remoteBlockNum.set(getLastSolidityBlockNum());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[MUST] Move blocking remote RPC out of @PostConstruct

init() is executed synchronously during ApplicationContext.refresh(). It calls new DatabaseGrpcClient(trustNodeAddr) followed by remoteBlockNum.set(getLastSolidityBlockNum()), and getLastSolidityBlockNum() now runs a while (flag) retry loop that can only exit when flag becomes false (i.e. via @PreDestroy). If the trust node is unreachable at startup, the loop never returns, context.refresh() never completes, and context.registerShutdownHook() in FullNode.main is never registered — the process becomes unresponsive to SIGTERM. This is a regression vs. the old SolidityNode.start() which invoked this call after appT.startup(), when the shutdown hook was already wired.

Suggestion: Move databaseGrpcClient creation and remoteBlockNum initialization out of @PostConstruct into run() (or first iteration of getBlock). Keep @PostConstruct limited to local field initialization.

public void pushVerifiedBlock(BlockCapsule block) throws P2pException {
block.generatedByMyself = true;
long start = System.currentTimeMillis();
processBlock(block, true);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[MUST] hitDown path leaves callers writing a fake success

When latestSolidityNumShutDown is hit, processBlock flips hitDown=true, unparks the hit-thread, and returns normally. The caller SolidityNode.loopProcessBlock treats that as success, then executes saveLatestSolidifiedBlockNum(blockNum) and logs "Success to process block", while the block was never actually pushed into BlockStore. Depending on the race between the hit-thread's System.exit(0) and the current thread's save, LATEST_SOLIDIFIED_BLOCK_NUM may be advanced to a block number that does not exist in the store — producing an inconsistent DB state and misleading logs.

Suggestion: Throw a dedicated sentinel (e.g. P2pException with a new TypeEnum, or a HitDownException) from processBlock when entering the hitDown branch, and let loopProcessBlock break out without calling saveLatestSolidifiedBlockNum. Alternatively, let the caller check tronNetDelegate.isHitDown() before writing state.

new Thread(this::getBlock).start();
new Thread(this::processBlock).start();
getBlockExecutor.submit(this::getBlock);
processBlockExecutor.submit(this::processBlock);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[SHOULD] Use ExecutorServiceManager.submit for TronError propagation

getBlockExecutor.submit(this::getBlock) and processBlockExecutor.submit(this::processBlock) use the raw ExecutorService.submit. Any uncaught Throwable (OOM, AssertionError, unexpected RuntimeException) is captured inside the FutureTask and swallowed — the solidity sync threads die silently, with no log and no JVM exit. The project-wide convention is ExecutorServiceManager.submit(es, task) (see DposTask.java:78, TransactionsMsgHandler.java:90/120, Manager.java:562/567/573), which wraps the task in a try/catch that routes TronError through ExitManager::logAndExit.

Suggestion: Replace both submits with ExecutorServiceManager.submit(getBlockExecutor, this::getBlock) and the equivalent for processBlockExecutor.

sleep(exceptionSleepTime);
}
}
throw new RuntimeException("SolitityNode is closing.");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[SHOULD] Fix typo and avoid raw RuntimeException for shutdown path

Two issues on the shutdown exit of getBlockByNum (line 157) and getLastSolidityBlockNum (line 174):

  1. The string "SolitityNode is closing." has a typo — Solidity is misspelled as Solitity. This text surfaces in logger.error(e.getMessage()) downstream and will hamper future log grepping.
  2. Using a bare RuntimeException to signal graceful shutdown makes it indistinguishable from a real error in callers that catch Exception — the normal shutdown ends up being logged at ERROR level.

Suggestion: Correct the spelling, and either define a private sentinel exception (e.g. ShuttingDownException extends RuntimeException) or change the method to return null / return -1 and have callers check + break explicitly.

sleep(exceptionSleepTime);
}
}
throw new RuntimeException("SolitityNode is closing.");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[SHOULD] Re-interrupt after catching InterruptedException in sleep()

(Anchored here because sleep() at line 177-183 is outside the diff hunk.)

sleep(long) catches Exception and only logs e.getMessage(), dropping the interrupt flag when InterruptedException is the cause. During @PreDestroy, ExecutorServiceManager.shutdownAndAwaitTermination relies on shutdownNow() interrupting worker threads to end them quickly; by swallowing the interrupt bit, the worker may continue iterating while (flag) for an extra cycle and slow shutdown.

Suggestion: Catch InterruptedException specifically and call Thread.currentThread().interrupt(); before/after the log, and keep a separate catch (Exception e) for other cases if needed.

Args.getInstance().setTrustNodeAddr(trustNodeAddr);
}

@Test
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[SHOULD] Restore coverage lost with testSolidityArgs and add tests for new surfaces

This PR deletes testSolidityArgs (which asserted TronError(SOLID_NODE_INIT) when trustNodeAddr is missing), deletes a pushVerifiedBlock assertion in ManagerTest.transactionTest, and introduces new surfaces without any test:

  • TronNetDelegate.pushVerifiedBlock(BlockCapsule) (new method, zero tests)
  • SolidityNode lifecycle (@PostConstruct / @PreDestroy / run()) (zero integration tests)
  • The hitDown shutdown path end-to-end

The PR main behavioral promise — "shutdown signal is now reachable from solidity mode" — has no automated coverage; any future change to processBlock hitDown branch or the solidity lifecycle will regress without CI catching it.

Suggestion: Add at minimum (1) a happy-path and a hitDown test for TronNetDelegate.pushVerifiedBlock verifying that LATEST_SOLIDIFIED_BLOCK_NUM is NOT advanced on hitDown; (2) an integration test for SolidityNode lifecycle; (3) a test at FullNode level for the missing-trust-node case that replaces the deleted testSolidityArgs.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (3)
framework/src/main/java/org/tron/program/SolidityNode.java (2)

177-183: ⚠️ Potential issue | 🟡 Minor

sleep swallows InterruptedException and drops the interrupt flag.

shutdown() relies on ExecutorServiceManager.shutdownAndAwaitTerminationshutdownNow() interrupting workers. Catching Exception and only logging e.getMessage() here clears the interrupt status, so getBlock / processSolidityBlock may iterate one more while (flag) cycle and even re-enter blockQueue.put(...) / blockQueue.take() before noticing flag = false, slowing teardown.

🛡️ Suggested change
   public void sleep(long time) {
     try {
       Thread.sleep(time);
-    } catch (Exception e1) {
-      logger.error(e1.getMessage());
+    } catch (InterruptedException e) {
+      Thread.currentThread().interrupt();
     }
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@framework/src/main/java/org/tron/program/SolidityNode.java` around lines 177
- 183, The sleep method in SolidityNode currently catches Exception and swallows
InterruptedException, clearing the thread's interrupt status; change the catch
to specifically catch InterruptedException, call
Thread.currentThread().interrupt() to restore the interrupt flag, optionally log
the interruption with the exception, and return immediately so workers in
getBlock/processSolidityBlock and blocking calls (blockQueue.put/take) can
observe the interruption during
ExecutorServiceManager.shutdownAndAwaitTermination → shutdownNow() triggered
from shutdown().

138-158: ⚠️ Potential issue | 🟡 Minor

Avoid signaling normal shutdown via bare RuntimeException.

Typo "Solitity" is now fixed, 👍. The remaining concern stands: callers (getBlock, loopProcessBlock, processSolidityBlock) all catch (Exception e) and logger.error(e.getMessage()), so a clean shutdown surfaces as ERROR: SolidityNode is closing. and is indistinguishable from a real failure. In loopProcessBlock the rethrow at line 133 also propagates up out of the try block without being suppressed during shutdown.

Either define a private sentinel type (e.g. class ShuttingDownException extends RuntimeException) and special-case it (or skip logging), or change these helpers to return Optional<Block> / OptionalLong and have callers check flag and break.

Also applies to: 160-175

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@framework/src/main/java/org/tron/program/SolidityNode.java` around lines 138
- 158, Replace the bare RuntimeException used to signal normal shutdown with a
sentinel exception and handle it specially: add a private static class
ShuttingDownException extends RuntimeException (no stack-trace needed) and throw
new ShuttingDownException() from getBlockByNum (and the similar shutdown sites
around 160-175) instead of new RuntimeException("SolidityNode is closing.");
then update callers such as loopProcessBlock, processSolidityBlock and getBlock
to catch ShuttingDownException separately (or rethrow it) so they do not log it
as an error — treat it as a normal shutdown signal (skip logger.error and
break/return) while other Exceptions continue to be logged and handled as
before.
framework/src/main/java/org/tron/core/net/TronNetDelegate.java (1)

236-245: ⚠️ Potential issue | 🔴 Critical

pushVerifiedBlock succeeds silently when processBlock enters the hitDown branch.

When processBlock hits the shutdown condition (lines 248-258), it sets hitDown = true, unparks hitThread, and returns normally — no exception. pushVerifiedBlock then logs "Push block cost: ..." and returns. The caller in SolidityNode.loopProcessBlock (lines 121-136) treats this as a successful push and proceeds to saveLatestSolidifiedBlockNum(blockNum), advancing LATEST_SOLIDIFIED_BLOCK_NUM to a block number that was never persisted to BlockStore. Depending on the race between hitThread's System.exit(0) and the caller's save, the DB ends up in an inconsistent state with misleading INFO logs.

Either propagate a sentinel (e.g. dedicated P2pException TypeEnum or a HitDownException) from processBlock so the caller can break without saving, or check isHitDown() here before logging success and have callers honor it.

🛡️ One possible shape
   public void pushVerifiedBlock(BlockCapsule block) throws P2pException {
     block.generatedByMyself = true;
     long start = System.currentTimeMillis();
     processBlock(block, true);
+    if (hitDown) {
+      throw new P2pException(TypeEnum.SHUTDOWN, "shutdown condition reached");
+    }
     logger.info("Push block cost: {} ms, blockNum: {}, blockHash: {}, trx count: {}.",
         System.currentTimeMillis() - start,
         block.getNum(),
         block.getBlockId(),
         block.getTransactions().size());
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@framework/src/main/java/org/tron/core/net/TronNetDelegate.java` around lines
236 - 245, pushVerifiedBlock currently treats processBlock return as success
even when processBlock sets hitDown and unparks hitThread; update
pushVerifiedBlock to detect shutdown and avoid logging/success behavior or
change processBlock to propagate a sentinel exception: either (A) have
processBlock throw a dedicated P2pException subtype (e.g., HitDownException /
TypeEnum.HIT_DOWN) when it enters the hitDown branch and let pushVerifiedBlock
rethrow it so callers such as SolidityNode.loopProcessBlock can skip
saveLatestSolidifiedBlockNum, or (B) after calling processBlock(block, true)
check process.isHitDown() (or the hitDown flag exposed) and if true skip the
success log and return/throw so callers do not persist the unprocessed block;
update SolidityNode.loopProcessBlock to honor the exception/flag and avoid
advancing LATEST_SOLIDIFIED_BLOCK_NUM when hitDown is observed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@framework/src/main/java/org/tron/core/net/TronNetDelegate.java`:
- Around line 236-245: pushVerifiedBlock currently treats processBlock return as
success even when processBlock sets hitDown and unparks hitThread; update
pushVerifiedBlock to detect shutdown and avoid logging/success behavior or
change processBlock to propagate a sentinel exception: either (A) have
processBlock throw a dedicated P2pException subtype (e.g., HitDownException /
TypeEnum.HIT_DOWN) when it enters the hitDown branch and let pushVerifiedBlock
rethrow it so callers such as SolidityNode.loopProcessBlock can skip
saveLatestSolidifiedBlockNum, or (B) after calling processBlock(block, true)
check process.isHitDown() (or the hitDown flag exposed) and if true skip the
success log and return/throw so callers do not persist the unprocessed block;
update SolidityNode.loopProcessBlock to honor the exception/flag and avoid
advancing LATEST_SOLIDIFIED_BLOCK_NUM when hitDown is observed.

In `@framework/src/main/java/org/tron/program/SolidityNode.java`:
- Around line 177-183: The sleep method in SolidityNode currently catches
Exception and swallows InterruptedException, clearing the thread's interrupt
status; change the catch to specifically catch InterruptedException, call
Thread.currentThread().interrupt() to restore the interrupt flag, optionally log
the interruption with the exception, and return immediately so workers in
getBlock/processSolidityBlock and blocking calls (blockQueue.put/take) can
observe the interruption during
ExecutorServiceManager.shutdownAndAwaitTermination → shutdownNow() triggered
from shutdown().
- Around line 138-158: Replace the bare RuntimeException used to signal normal
shutdown with a sentinel exception and handle it specially: add a private static
class ShuttingDownException extends RuntimeException (no stack-trace needed) and
throw new ShuttingDownException() from getBlockByNum (and the similar shutdown
sites around 160-175) instead of new RuntimeException("SolidityNode is
closing."); then update callers such as loopProcessBlock, processSolidityBlock
and getBlock to catch ShuttingDownException separately (or rethrow it) so they
do not log it as an error — treat it as a normal shutdown signal (skip
logger.error and break/return) while other Exceptions continue to be logged and
handled as before.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6ed13c09-5186-4dfa-a41f-48a7572e20f7

📥 Commits

Reviewing files that changed from the base of the PR and between f0a8f0f and 50c76de.

📒 Files selected for processing (6)
  • framework/src/main/java/org/tron/core/db/Manager.java
  • framework/src/main/java/org/tron/core/net/TronNetDelegate.java
  • framework/src/main/java/org/tron/program/FullNode.java
  • framework/src/main/java/org/tron/program/SolidityNode.java
  • framework/src/test/java/org/tron/core/db/ManagerTest.java
  • framework/src/test/java/org/tron/program/SolidityNodeTest.java
💤 Files with no reviewable changes (3)
  • framework/src/test/java/org/tron/core/db/ManagerTest.java
  • framework/src/main/java/org/tron/core/db/Manager.java
  • framework/src/test/java/org/tron/program/SolidityNodeTest.java

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] SolidityNode supports conditional shutdown

2 participants