Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public enum Cursor {
//true:fullnode, false:soliditynode
private ThreadLocal<Cursor> cursor = new ThreadLocal<>();
private ThreadLocal<Long> offset = new ThreadLocal<>();
private Snapshot head;
private volatile Snapshot head;

public Chainbase(Snapshot head) {
this.head = head;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ public class CommonParameter {

protected static CommonParameter PARAMETER = new CommonParameter();

// Default QPS values for rate limiters
public static final int DEFAULT_RATE_LIMITER_GLOBAL_QPS = 1000;
public static final int DEFAULT_RATE_LIMITER_GLOBAL_IP_QPS = 1000;
public static final int DEFAULT_RATE_LIMITER_GLOBAL_API_QPS = 1000;

// Runtime chain state: set by VMConfig.initVmHardFork()
// when the energy-limit governance proposal is activated.
// Legacy: should belong to VMConfig, not here.
Expand Down Expand Up @@ -373,12 +378,12 @@ public class CommonParameter {
public RateLimiterInitialization rateLimiterInitialization;
@Getter
@Setter
public int rateLimiterGlobalQps = 50000; // from clearParam(), consistent with mainnet.conf
public int rateLimiterGlobalQps = DEFAULT_RATE_LIMITER_GLOBAL_QPS; // from clearParam(), consistent with mainnet.conf
@Getter
@Setter
public int rateLimiterGlobalIpQps = 10000; // from clearParam(), consistent with mainnet.conf
public int rateLimiterGlobalIpQps = DEFAULT_RATE_LIMITER_GLOBAL_IP_QPS; // from clearParam(), consistent with mainnet.conf
@Getter
public int rateLimiterGlobalApiQps = 1000; // from clearParam(), consistent with mainnet.conf
public int rateLimiterGlobalApiQps = DEFAULT_RATE_LIMITER_GLOBAL_API_QPS; // from clearParam(), consistent with mainnet.conf
@Getter
@Setter
public double rateLimiterSyncBlockChain; // clearParam: 3.0
Expand Down
12 changes: 12 additions & 0 deletions common/src/main/java/org/tron/common/utils/ByteArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ public static BigInteger hexToBigInteger(String input) {
}

public static long jsonHexToLong(String x) throws JsonRpcInvalidParamsException {
// Constants for input length validation to prevent DDoS attacks
int MAX_HEX_LONG_LENGTH = 20; // For 64-bit long values (18 chars for 0x7FFFFFFFFFFFFFFF) + safety buffer
if (x == null || x.length() > MAX_HEX_LONG_LENGTH) {
throw new JsonRpcInvalidParamsException("Input cannot be null or too long");
}

if (!x.startsWith("0x")) {
throw new JsonRpcInvalidParamsException("Incorrect hex syntax");
}
Expand All @@ -160,6 +166,12 @@ public static long jsonHexToLong(String x) throws JsonRpcInvalidParamsException
}

public static int jsonHexToInt(String x) throws Exception {
// Constants for input length validation to prevent DDoS attacks
int MAX_HEX_INT_LENGTH = 12; // For 32-bit int values (10 chars for 0x7FFFFFFF) + safety buffer
if (x == null || x.length() > MAX_HEX_INT_LENGTH) {
throw new Exception("Incorrect string length");
}

if (!x.startsWith("0x")) {
throw new Exception("Incorrect hex syntax");
}
Expand Down
7 changes: 3 additions & 4 deletions framework/src/main/java/org/tron/core/config/args/Args.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ public class Args extends CommonParameter {
private static final ConcurrentHashMap<Long, BlockingQueue<ContractEventTrigger>>
solidityContractEventTriggerMap = new ConcurrentHashMap<>();


/**
* set parameters.
*/
Expand Down Expand Up @@ -711,15 +710,15 @@ public static void applyConfigParams(

PARAMETER.rateLimiterGlobalQps =
config.hasPath(ConfigKey.RATE_LIMITER_GLOBAL_QPS) ? config
.getInt(ConfigKey.RATE_LIMITER_GLOBAL_QPS) : 50000;
.getInt(ConfigKey.RATE_LIMITER_GLOBAL_QPS) : DEFAULT_RATE_LIMITER_GLOBAL_QPS;

PARAMETER.rateLimiterGlobalIpQps =
config.hasPath(ConfigKey.RATE_LIMITER_GLOBAL_IP_QPS) ? config
.getInt(ConfigKey.RATE_LIMITER_GLOBAL_IP_QPS) : 10000;
.getInt(ConfigKey.RATE_LIMITER_GLOBAL_IP_QPS) : DEFAULT_RATE_LIMITER_GLOBAL_IP_QPS;

PARAMETER.rateLimiterGlobalApiQps =
config.hasPath(ConfigKey.RATE_LIMITER_GLOBAL_API_QPS) ? config
.getInt(ConfigKey.RATE_LIMITER_GLOBAL_API_QPS) : 1000;
.getInt(ConfigKey.RATE_LIMITER_GLOBAL_API_QPS) : DEFAULT_RATE_LIMITER_GLOBAL_API_QPS;

PARAMETER.rateLimiterInitialization = getRateLimiterFromConfig(config);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@

@Slf4j(topic = "API")
public class JsonRpcApiUtil {
/**
* Maximum allowed length for block identifiers to prevent DDoS attacks.
* Supports block hashes (66 chars) + safety buffer.
*/
private static final int MAX_BLOCK_IDENTIFIER_LENGTH = 128;

public static byte[] convertToTronAddress(byte[] address) {
byte[] newAddress = new byte[21];
Expand Down Expand Up @@ -85,6 +90,13 @@ public static String getMethodSign(String method) {
return Hex.toHexString(selector);
}

public static void validateBlockNumOrHashOrTag(String input)
throws JsonRpcInvalidParamsException {
if (input == null || input.length() > MAX_BLOCK_IDENTIFIER_LENGTH) {
throw new JsonRpcInvalidParamsException("input is null or length exceeds maximum allowed");

Choose a reason for hiding this comment

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

what about also check tags and BlockNumer in this function?

Copy link
Owner Author

@Sunny6889 Sunny6889 Mar 20, 2026

Choose a reason for hiding this comment

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

Hi good idea, but because want to limit the PR changes to only one scope a time

}
}

public static TriggerSmartContract triggerCallContract(byte[] address, byte[] contractAddress,
long callValue, byte[] data, long tokenValue, String tokenId) {
TriggerSmartContract.Builder builder = TriggerSmartContract.newBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static org.tron.core.services.jsonrpc.JsonRpcApiUtil.getTransactionIndex;
import static org.tron.core.services.jsonrpc.JsonRpcApiUtil.getTxID;
import static org.tron.core.services.jsonrpc.JsonRpcApiUtil.triggerCallContract;
import static org.tron.core.services.jsonrpc.JsonRpcApiUtil.validateBlockNumOrHashOrTag;

import com.alibaba.fastjson.JSON;
import com.google.common.cache.Cache;
Expand Down Expand Up @@ -296,6 +297,7 @@ public String web3Sha3(String data) throws JsonRpcInvalidParamsException {
@Override
public String ethGetBlockTransactionCountByHash(String blockHash)
throws JsonRpcInvalidParamsException {
validateBlockNumOrHashOrTag(blockHash);
Block b = getBlockByJsonHash(blockHash);
if (b == null) {
return null;
Expand All @@ -308,6 +310,7 @@ public String ethGetBlockTransactionCountByHash(String blockHash)
@Override
public String ethGetBlockTransactionCountByNumber(String blockNumOrTag)
throws JsonRpcInvalidParamsException {
validateBlockNumOrHashOrTag(blockNumOrTag);
List<Transaction> list = wallet.getTransactionsByJsonBlockId(blockNumOrTag);
if (list == null) {
return null;
Expand All @@ -327,6 +330,7 @@ public BlockResult ethGetBlockByHash(String blockHash, Boolean fullTransactionOb
@Override
public BlockResult ethGetBlockByNumber(String blockNumOrTag, Boolean fullTransactionObjects)
throws JsonRpcInvalidParamsException {
validateBlockNumOrHashOrTag(blockNumOrTag);
final Block b = wallet.getByJsonBlockId(blockNumOrTag);
return (b == null ? null : getBlockResult(b, fullTransactionObjects));
}
Expand Down Expand Up @@ -393,6 +397,9 @@ public String getLatestBlockNum() {
@Override
public String getTrxBalance(String address, String blockNumOrTag)
throws JsonRpcInvalidParamsException {
// Add length check and validate hex format to prevent DDoS attacks
validateBlockNumOrHashOrTag(blockNumOrTag);

if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag)
|| PENDING_STR.equalsIgnoreCase(blockNumOrTag)
|| FINALIZED_STR.equalsIgnoreCase(blockNumOrTag)) {
Expand All @@ -409,12 +416,6 @@ public String getTrxBalance(String address, String blockNumOrTag)
}
return ByteArray.toJsonHex(balance);
} else {
try {
ByteArray.hexToBigInteger(blockNumOrTag);
} catch (Exception e) {
throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR);
}

throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR);
}
}
Expand Down Expand Up @@ -535,6 +536,7 @@ private String call(byte[] ownerAddressByte, byte[] contractAddressByte, long va
@Override
public String getStorageAt(String address, String storageIdx, String blockNumOrTag)
throws JsonRpcInvalidParamsException {
validateBlockNumOrHashOrTag(blockNumOrTag);
if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag)
|| PENDING_STR.equalsIgnoreCase(blockNumOrTag)
|| FINALIZED_STR.equalsIgnoreCase(blockNumOrTag)) {
Expand All @@ -558,19 +560,14 @@ public String getStorageAt(String address, String storageIdx, String blockNumOrT
DataWord value = storage.getValue(new DataWord(ByteArray.fromHexString(storageIdx)));
return ByteArray.toJsonHex(value == null ? new byte[32] : value.getData());
} else {
try {
ByteArray.hexToBigInteger(blockNumOrTag);
} catch (Exception e) {
throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR);
}

throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR);
}
}

@Override
public String getABIOfSmartContract(String contractAddress, String blockNumOrTag)
throws JsonRpcInvalidParamsException {
validateBlockNumOrHashOrTag(blockNumOrTag);
if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag)
|| PENDING_STR.equalsIgnoreCase(blockNumOrTag)
|| FINALIZED_STR.equalsIgnoreCase(blockNumOrTag)) {
Expand All @@ -589,12 +586,6 @@ public String getABIOfSmartContract(String contractAddress, String blockNumOrTag
}

} else {
try {

Choose a reason for hiding this comment

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

why remove this check?

Copy link
Owner Author

Choose a reason for hiding this comment

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

As I think this check is no need and cost computational resources.

ByteArray.hexToBigInteger(blockNumOrTag);
} catch (Exception e) {
throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR);
}

throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR);
}
}
Expand Down Expand Up @@ -791,6 +782,7 @@ private TransactionResult getTransactionByBlockAndIndex(Block block, String inde
@Override
public TransactionResult getTransactionByBlockHashAndIndex(String blockHash, String index)
throws JsonRpcInvalidParamsException {
validateBlockNumOrHashOrTag(blockHash);
final Block block = getBlockByJsonHash(blockHash);

if (block == null) {
Expand All @@ -803,6 +795,9 @@ public TransactionResult getTransactionByBlockHashAndIndex(String blockHash, Str
@Override
public TransactionResult getTransactionByBlockNumberAndIndex(String blockNumOrTag, String index)
throws JsonRpcInvalidParamsException {
// Add length check and validate hex format to prevent DDoS attacks
validateBlockNumOrHashOrTag(blockNumOrTag);

Block block = wallet.getByJsonBlockId(blockNumOrTag);
if (block == null) {
return null;
Expand Down Expand Up @@ -888,6 +883,8 @@ private TransactionContext findTransactionContext(TransactionInfoList infoList,
@Override
public List<TransactionReceipt> getBlockReceipts(String blockNumOrHashOrTag)
throws JsonRpcInvalidParamsException, JsonRpcInternalException {
// Add length check and validate hex format to prevent DDoS attacks
validateBlockNumOrHashOrTag(blockNumOrHashOrTag);

Block block = null;

Expand Down Expand Up @@ -973,6 +970,8 @@ public String getCall(CallArguments transactionCall, Object blockParamObj)

long blockNumber;
try {
// Add length check to prevent DDoS attacks
validateBlockNumOrHashOrTag(blockNumOrTag);
blockNumber = ByteArray.hexToBigInteger(blockNumOrTag).longValue();
} catch (Exception e) {
throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR);
Expand Down Expand Up @@ -1014,12 +1013,6 @@ public String getCall(CallArguments transactionCall, Object blockParamObj)
return call(addressData, contractAddressData, transactionCall.parseValue(),
ByteArray.fromHexString(transactionCall.getData()));
} else {
try {
ByteArray.hexToBigInteger(blockNumOrTag);
} catch (Exception e) {
throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR);
}

throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR);
}
}
Expand Down
8 changes: 4 additions & 4 deletions framework/src/main/resources/config.conf
Original file line number Diff line number Diff line change
Expand Up @@ -442,10 +442,10 @@ rate.limiter = {
# disconnect = 1.0
}

# global qps, default 50000
global.qps = 50000
# IP-based global qps, default 10000
global.ip.qps = 10000
# global qps, default 1000
global.qps = 1000
# IP-based global qps, default 1000
global.ip.qps = 1000
}


Expand Down
Loading
Loading