Skip to content

Commit 8f6f59a

Browse files
committed
refactor(jsonrpc): centralize block selector parsing into JsonRpcApiUtil
1 parent 039821c commit 8f6f59a

6 files changed

Lines changed: 410 additions & 192 deletions

File tree

framework/src/main/java/org/tron/core/Wallet.java

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,6 @@
3232
import static org.tron.core.config.Parameter.DatabaseConstants.PROPOSAL_COUNT_LIMIT_MAX;
3333
import static org.tron.core.config.Parameter.DatabaseConstants.WITNESS_COUNT_LIMIT_MAX;
3434
import static org.tron.core.services.jsonrpc.JsonRpcApiUtil.parseEnergyFee;
35-
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.EARLIEST_STR;
36-
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.FINALIZED_STR;
37-
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.LATEST_STR;
38-
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.PENDING_STR;
39-
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.TAG_PENDING_SUPPORT_ERROR;
4035
import static org.tron.core.vm.utils.FreezeV2Util.getV2EnergyUsage;
4136
import static org.tron.core.vm.utils.FreezeV2Util.getV2NetUsage;
4237
import static org.tron.protos.contract.Common.ResourceCode;
@@ -193,7 +188,6 @@
193188
import org.tron.core.exception.VMIllegalException;
194189
import org.tron.core.exception.ValidateSignatureException;
195190
import org.tron.core.exception.ZksnarkException;
196-
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
197191
import org.tron.core.net.TronNetDelegate;
198192
import org.tron.core.net.TronNetService;
199193
import org.tron.core.net.message.adv.TransactionMessage;
@@ -711,6 +705,10 @@ public long getSolidBlockNum() {
711705
return chainBaseManager.getDynamicPropertiesStore().getLatestSolidifiedBlockNum();
712706
}
713707

708+
public long getHeadBlockNum() {
709+
return chainBaseManager.getHeadBlockNum();
710+
}
711+
714712
public BlockCapsule getBlockCapsuleByNum(long blockNum) {
715713
try {
716714
return chainBaseManager.getBlockByNum(blockNum);
@@ -733,37 +731,6 @@ public long getTransactionCountByBlockNum(long blockNum) {
733731
return count;
734732
}
735733

736-
public Block getByJsonBlockId(String id) throws JsonRpcInvalidParamsException {
737-
if (EARLIEST_STR.equalsIgnoreCase(id)) {
738-
return getBlockByNum(0);
739-
} else if (LATEST_STR.equalsIgnoreCase(id)) {
740-
return getNowBlock();
741-
} else if (FINALIZED_STR.equalsIgnoreCase(id)) {
742-
return getSolidBlock();
743-
} else if (PENDING_STR.equalsIgnoreCase(id)) {
744-
throw new JsonRpcInvalidParamsException(TAG_PENDING_SUPPORT_ERROR);
745-
} else {
746-
long blockNumber;
747-
try {
748-
blockNumber = ByteArray.hexToBigInteger(id).longValue();
749-
} catch (Exception e) {
750-
throw new JsonRpcInvalidParamsException("invalid block number");
751-
}
752-
753-
return getBlockByNum(blockNumber);
754-
}
755-
}
756-
757-
public List<Transaction> getTransactionsByJsonBlockId(String id)
758-
throws JsonRpcInvalidParamsException {
759-
if (PENDING_STR.equalsIgnoreCase(id)) {
760-
throw new JsonRpcInvalidParamsException(TAG_PENDING_SUPPORT_ERROR);
761-
} else {
762-
Block block = getByJsonBlockId(id);
763-
return block != null ? block.getTransactionsList() : null;
764-
}
765-
}
766-
767734
public WitnessList getWitnessList() {
768735
WitnessList.Builder builder = WitnessList.newBuilder();
769736
List<WitnessCapsule> witnessCapsuleList = chainBaseManager.getWitnessStore().getAllWitnesses();

framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcApiUtil.java

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
package org.tron.core.services.jsonrpc;
22

3-
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.EARLIEST_STR;
4-
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.FINALIZED_STR;
5-
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.LATEST_STR;
6-
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.PENDING_STR;
7-
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.TAG_PENDING_SUPPORT_ERROR;
8-
93
import com.google.common.base.Throwables;
104
import com.google.common.primitives.Longs;
115
import com.google.protobuf.Any;
@@ -57,6 +51,15 @@
5751
@Slf4j(topic = "API")
5852
public class JsonRpcApiUtil {
5953

54+
public static final String EARLIEST_STR = "earliest";
55+
public static final String PENDING_STR = "pending";
56+
public static final String LATEST_STR = "latest";
57+
public static final String FINALIZED_STR = "finalized";
58+
public static final String SAFE_STR = "safe";
59+
public static final String TAG_PENDING_SUPPORT_ERROR = "TAG pending not supported";
60+
public static final String TAG_SAFE_SUPPORT_ERROR = "TAG safe not supported";
61+
public static final String BLOCK_NUM_ERROR = "invalid block number";
62+
6063
public static byte[] convertToTronAddress(byte[] address) {
6164
byte[] newAddress = new byte[21];
6265
byte[] temp = new byte[] {Wallet.getAddressPreFixByte()};
@@ -515,20 +518,48 @@ public static long parseEnergyFee(long timestamp, String energyPriceHistory) {
515518
return -1;
516519
}
517520

518-
public static long getByJsonBlockId(String blockNumOrTag, Wallet wallet)
521+
public static boolean isBlockTag(String tag) {
522+
return LATEST_STR.equalsIgnoreCase(tag)
523+
|| EARLIEST_STR.equalsIgnoreCase(tag)
524+
|| FINALIZED_STR.equalsIgnoreCase(tag)
525+
|| PENDING_STR.equalsIgnoreCase(tag)
526+
|| SAFE_STR.equalsIgnoreCase(tag);
527+
}
528+
529+
public static long parseBlockTag(String tag, Wallet wallet)
519530
throws JsonRpcInvalidParamsException {
520-
if (PENDING_STR.equalsIgnoreCase(blockNumOrTag)) {
521-
throw new JsonRpcInvalidParamsException(TAG_PENDING_SUPPORT_ERROR);
531+
if (LATEST_STR.equalsIgnoreCase(tag)) {
532+
// Use getNowBlock() to fetch the latest persisted block directly from blockStore,
533+
// avoiding a race with updateDynamicProperties that updates latestBlockHeaderNumber
534+
// before the block is written to blockStore/blockIndexStore.
535+
return wallet.getNowBlock().getBlockHeader().getRawData().getNumber();
522536
}
523-
if (StringUtils.isEmpty(blockNumOrTag) || LATEST_STR.equalsIgnoreCase(blockNumOrTag)) {
524-
return -1;
525-
} else if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag)) {
537+
if (EARLIEST_STR.equalsIgnoreCase(tag)) {
526538
return 0;
527-
} else if (FINALIZED_STR.equalsIgnoreCase(blockNumOrTag)) {
539+
}
540+
if (FINALIZED_STR.equalsIgnoreCase(tag)) {
528541
return wallet.getSolidBlockNum();
529-
} else {
530-
return ByteArray.jsonHexToLong(blockNumOrTag);
531542
}
543+
if (PENDING_STR.equalsIgnoreCase(tag)) {
544+
throw new JsonRpcInvalidParamsException(TAG_PENDING_SUPPORT_ERROR);
545+
}
546+
if (SAFE_STR.equalsIgnoreCase(tag)) {
547+
throw new JsonRpcInvalidParamsException(TAG_SAFE_SUPPORT_ERROR);
548+
}
549+
throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR);
550+
}
551+
552+
/**
553+
* Parse a block tag or hex number. Uses strict jsonHexToLong (requires 0x prefix) for hex.
554+
* Callers needing flexible hex parsing (0x -> hex, bare number -> decimal) should use
555+
* isBlockTag/parseBlockTag and handle hex separately with hexToBigInteger.
556+
*/
557+
public static long parseBlockNumber(String blockNumOrTag, Wallet wallet)
558+
throws JsonRpcInvalidParamsException {
559+
if (isBlockTag(blockNumOrTag)) {
560+
return parseBlockTag(blockNumOrTag, wallet);
561+
}
562+
return ByteArray.jsonHexToLong(blockNumOrTag);
532563
}
533564

534565
public static String generateFilterId() {

0 commit comments

Comments
 (0)