Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions framework/src/main/java/org/tron/core/db/Manager.java
Original file line number Diff line number Diff line change
Expand Up @@ -1033,23 +1033,6 @@ public void eraseBlock() {
}
}

public void pushVerifiedBlock(BlockCapsule block) throws ContractValidateException,
ContractExeException, ValidateSignatureException, AccountResourceInsufficientException,
TransactionExpirationException, TooBigTransactionException, DupTransactionException,
TaposException, ValidateScheduleException, ReceiptCheckErrException,
VMIllegalException, TooBigTransactionResultException, UnLinkedBlockException,
NonCommonBlockException, BadNumberBlockException, BadBlockException, ZksnarkException,
EventBloomException {
block.generatedByMyself = true;
long start = System.currentTimeMillis();
pushBlock(block);
logger.info("Push block cost: {} ms, blockNum: {}, blockHash: {}, trx count: {}.",
System.currentTimeMillis() - start,
block.getNum(),
block.getBlockId(),
block.getTransactions().size());
}

private void applyBlock(BlockCapsule block) throws ContractValidateException,
ContractExeException, ValidateSignatureException, AccountResourceInsufficientException,
TransactionExpirationException, TooBigTransactionException, DupTransactionException,
Expand Down
11 changes: 11 additions & 0 deletions framework/src/main/java/org/tron/core/net/TronNetDelegate.java
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,17 @@ public Message getData(Sha256Hash hash, InventoryType type) throws P2pException
}
}

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.

logger.info("Push block cost: {} ms, blockNum: {}, blockHash: {}, trx count: {}.",
System.currentTimeMillis() - start,
block.getNum(),
block.getBlockId(),
block.getTransactions().size());
}

public void processBlock(BlockCapsule block, boolean isSync) throws P2pException {
if (!hitDown && dbManager.getLatestSolidityNumShutDown() > 0
&& dbManager.getLatestSolidityNumShutDown() == dbManager.getDynamicPropertiesStore()
Expand Down
26 changes: 18 additions & 8 deletions framework/src/main/java/org/tron/program/FullNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.util.ObjectUtils;
import org.tron.common.application.Application;
import org.tron.common.application.ApplicationFactory;
import org.tron.common.application.TronApplicationContext;
Expand All @@ -28,19 +29,24 @@ public static void main(String[] args) {

LogService.load(parameter.getLogbackPath());

if (parameter.isSolidityNode()) {
SolidityNode.start();
return;
}
if (parameter.isKeystoreFactory()) {
KeystoreFactory.start();
return;
}
logger.info("Full node running.");
if (Args.getInstance().isDebug()) {
logger.info("in debug mode, it won't check energy time");
if (parameter.isSolidityNode()) {
logger.info("Solidity node is running.");
if (ObjectUtils.isEmpty(parameter.getTrustNodeAddr())) {
throw new TronError(new IllegalArgumentException("Trust node is not set."),
TronError.ErrCode.SOLID_NODE_INIT);
}
parameter.setP2pDisable(true);
} else {
logger.info("not in debug mode, it will check energy time");
logger.info("Full node running.");
if (Args.getInstance().isDebug()) {
logger.info("in debug mode, it won't check energy time");
} else {
logger.info("not in debug mode, it will check energy time");
}
}

// init metrics first
Expand All @@ -55,6 +61,10 @@ public static void main(String[] args) {
Application appT = ApplicationFactory.create(context);
context.registerShutdownHook();
appT.startup();
if (parameter.isSolidityNode()) {
SolidityNode node = context.getBean(SolidityNode.class);
node.run();
}
appT.blockUntilShutdown();
}

Expand Down
Loading
Loading