Repository navigation
fix(api): harden external input validation - #21
0xbigapple wants to merge 17 commits into
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
There was a problem hiding this comment.
1 issue found across 15 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/test/java/org/tron/core/services/interfaceOnSolidity/http/RewardBrokerageAddressValidationTest.java">
<violation number="1" location="framework/src/test/java/org/tron/core/services/interfaceOnSolidity/http/RewardBrokerageAddressValidationTest.java:42">
P3: The Solidity and PBFT test files duplicate the entire harness (reflection-backed wallet factory, request builder, inject helper, and the reward/brokerage rejection test) differing only in the wallet type and injected field name. Extract a shared base class or parameterized harness to avoid maintaining the same assertions in two places.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| } | ||
|
|
||
| @Test | ||
| public void rewardAndBrokerageMirrorsRejectMalformedAddresses() throws Exception { |
There was a problem hiding this comment.
P3: The Solidity and PBFT test files duplicate the entire harness (reflection-backed wallet factory, request builder, inject helper, and the reward/brokerage rejection test) differing only in the wallet type and injected field name. Extract a shared base class or parameterized harness to avoid maintaining the same assertions in two places.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At framework/src/test/java/org/tron/core/services/interfaceOnSolidity/http/RewardBrokerageAddressValidationTest.java, line 42:
<comment>The Solidity and PBFT test files duplicate the entire harness (reflection-backed wallet factory, request builder, inject helper, and the reward/brokerage rejection test) differing only in the wallet type and injected field name. Extract a shared base class or parameterized harness to avoid maintaining the same assertions in two places.</comment>
<file context>
@@ -0,0 +1,57 @@
+ }
+
+ @Test
+ public void rewardAndBrokerageMirrorsRejectMalformedAddresses() throws Exception {
+ GetRewardOnSolidityServlet reward = new GetRewardOnSolidityServlet();
+ inject(reward, "walletOnSolidity", walletOnSolidity());
</file context>
There was a problem hiding this comment.
1 issue found across 17 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="framework/src/main/java/org/tron/core/services/http/Util.java">
<violation number="1" location="framework/src/main/java/org/tron/core/services/http/Util.java:705">
P2: For multibyte UTF-8 bodies, this check counts characters instead of request bytes and buffers well beyond `httpMaxMessageSize` before rejecting. Count bytes from the input stream while reading so the early bound matches the configured limit.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| new InputStreamReader(request.getInputStream()))) { | ||
| int read; | ||
| while ((read = reader.read(buffer)) != -1) { | ||
| if (sb.length() + read > limit) { |
There was a problem hiding this comment.
P2: For multibyte UTF-8 bodies, this check counts characters instead of request bytes and buffers well beyond httpMaxMessageSize before rejecting. Count bytes from the input stream while reading so the early bound matches the configured limit.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At framework/src/main/java/org/tron/core/services/http/Util.java, line 705:
<comment>For multibyte UTF-8 bodies, this check counts characters instead of request bytes and buffers well beyond `httpMaxMessageSize` before rejecting. Count bytes from the input stream while reading so the early bound matches the configured limit.</comment>
<file context>
@@ -673,14 +684,33 @@ private static String checkGetParam(HttpServletRequest request, String key) thro
+ new InputStreamReader(request.getInputStream()))) {
+ int read;
+ while ((read = reader.read(buffer)) != -1) {
+ if (sb.length() + read > limit) {
+ throw new Exception("body size is too big, the limit is " + limit);
+ }
</file context>
2c3bb5c to
248cbe0
Compare
There was a problem hiding this comment.
3 issues found across 40 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="framework/src/main/java/org/tron/core/services/http/JsonFormat.java">
<violation number="1" location="framework/src/main/java/org/tron/core/services/http/JsonFormat.java:864">
P3: `escapeBytesSelfType` hex-renders the entire oversized ByteString (2 hex chars per byte), so a 64KB attacker-controlled address field is echoed as a ~128KB hex string in visible-mode responses — larger than the base58 rendering it replaces and contrary to the PR's stated goal of avoiding echoing oversized attacker-controlled values. The log-side helper introduced in the same change truncates to a 4-byte head; this response path does not.</violation>
<violation number="2" location="framework/src/main/java/org/tron/core/services/http/JsonFormat.java:1708">
P2: This guard still accepts non-empty 1–20-byte hex values as addresses, while the visible Base58 path rejects any length other than 21 bytes. Reject non-empty lengths other than `Constant.TRON_ADDRESS_SIZE` here, preserving empty optional address fields.</violation>
</file>
<file name="framework/src/test/java/org/tron/core/WalletMockTest.java">
<violation number="1" location="framework/src/test/java/org/tron/core/WalletMockTest.java:910">
P3: This transfer test passes with a completely empty ReceiveDescription (zero-length commitment, value, epk, zkproof, c_enc, c_out), so it only proves the new count check (1-2 receives) succeeds. The PR claims unusable inputs are rejected with ContractValidateException, but a fully empty receive description still produces a trigger input here. Either use a populated ReceiveDescription or add assertions that empty/invalid receive descriptions are rejected, so the hardened validation path is actually exercised.</violation>
</file>
Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.
Re-trigger cubic
| if (!selfType) { | ||
| result = unescapeBytes(escaped); | ||
| if (HttpSelfFormatFieldName.isAddressFormat(fieldName) | ||
| && result.size() > Constant.TRON_ADDRESS_SIZE) { |
There was a problem hiding this comment.
P2: This guard still accepts non-empty 1–20-byte hex values as addresses, while the visible Base58 path rejects any length other than 21 bytes. Reject non-empty lengths other than Constant.TRON_ADDRESS_SIZE here, preserving empty optional address fields.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At framework/src/main/java/org/tron/core/services/http/JsonFormat.java, line 1708:
<comment>This guard still accepts non-empty 1–20-byte hex values as addresses, while the visible Base58 path rejects any length other than 21 bytes. Reject non-empty lengths other than `Constant.TRON_ADDRESS_SIZE` here, preserving empty optional address fields.</comment>
<file context>
@@ -1701,6 +1704,10 @@ public ByteString consumeByteString(final String fieldName, boolean selfType)
if (!selfType) {
result = unescapeBytes(escaped);
+ if (HttpSelfFormatFieldName.isAddressFormat(fieldName)
+ && result.size() > Constant.TRON_ADDRESS_SIZE) {
+ throw new InvalidEscapeSequence("invalid address for field: " + fieldName);
+ }
</file context>
| && result.size() > Constant.TRON_ADDRESS_SIZE) { | |
| && result.size() != 0 | |
| && result.size() != Constant.TRON_ADDRESS_SIZE) { |
| GrpcAPI.ShieldedTRC20Parameters shieldedTRC20Parameters = | ||
| GrpcAPI.ShieldedTRC20Parameters.newBuilder() | ||
| .addSpendDescription(spendDescription) | ||
| .addReceiveDescription(ShieldContract.ReceiveDescription.getDefaultInstance()) |
There was a problem hiding this comment.
P3: This transfer test passes with a completely empty ReceiveDescription (zero-length commitment, value, epk, zkproof, c_enc, c_out), so it only proves the new count check (1-2 receives) succeeds. The PR claims unusable inputs are rejected with ContractValidateException, but a fully empty receive description still produces a trigger input here. Either use a populated ReceiveDescription or add assertions that empty/invalid receive descriptions are rejected, so the hardened validation path is actually exercised.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At framework/src/test/java/org/tron/core/WalletMockTest.java, line 910:
<comment>This transfer test passes with a completely empty ReceiveDescription (zero-length commitment, value, epk, zkproof, c_enc, c_out), so it only proves the new count check (1-2 receives) succeeds. The PR claims unusable inputs are rejected with ContractValidateException, but a fully empty receive description still produces a trigger input here. Either use a populated ReceiveDescription or add assertions that empty/invalid receive descriptions are rejected, so the hardened validation path is actually exercised.</comment>
<file context>
@@ -907,6 +907,7 @@ public void testGetTriggerInputForShieldedTRC20Contract1()
GrpcAPI.ShieldedTRC20Parameters shieldedTRC20Parameters =
GrpcAPI.ShieldedTRC20Parameters.newBuilder()
.addSpendDescription(spendDescription)
+ .addReceiveDescription(ShieldContract.ReceiveDescription.getDefaultInstance())
.setParameterType("transfer")
.build();
</file context>
| @@ -861,6 +861,9 @@ static String escapeBytes(ByteString input, final String fieldName, boolean self | |||
| static String escapeBytesSelfType(ByteString input, final String fieldName) { | |||
| //Address | |||
| if (HttpSelfFormatFieldName.isAddressFormat(fieldName)) { | |||
| if (input.size() > Constant.TRON_ADDRESS_SIZE) { | |||
There was a problem hiding this comment.
P3: escapeBytesSelfType hex-renders the entire oversized ByteString (2 hex chars per byte), so a 64KB attacker-controlled address field is echoed as a ~128KB hex string in visible-mode responses — larger than the base58 rendering it replaces and contrary to the PR's stated goal of avoiding echoing oversized attacker-controlled values. The log-side helper introduced in the same change truncates to a 4-byte head; this response path does not.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At framework/src/main/java/org/tron/core/services/http/JsonFormat.java, line 864:
<comment>`escapeBytesSelfType` hex-renders the entire oversized ByteString (2 hex chars per byte), so a 64KB attacker-controlled address field is echoed as a ~128KB hex string in visible-mode responses — larger than the base58 rendering it replaces and contrary to the PR's stated goal of avoiding echoing oversized attacker-controlled values. The log-side helper introduced in the same change truncates to a 4-byte head; this response path does not.</comment>
<file context>
@@ -861,6 +861,9 @@ static String escapeBytes(ByteString input, final String fieldName, boolean self
static String escapeBytesSelfType(ByteString input, final String fieldName) {
//Address
if (HttpSelfFormatFieldName.isAddressFormat(fieldName)) {
+ if (input.size() > Constant.TRON_ADDRESS_SIZE) {
+ return ByteArray.toHexString(input.toByteArray());
+ }
</file context>
caa932e to
77572d3
Compare
77572d3 to
562aae7
Compare
There was a problem hiding this comment.
1 existing issue remains and 3 new issues found across 30 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="framework/src/main/java/org/tron/core/services/http/GetBrokerageServlet.java">
<violation number="1" location="framework/src/main/java/org/tron/core/services/http/GetBrokerageServlet.java:22">
P3: This catch-all around `Util.getAddress` routes every exception into the debug-level client-error path, but `getAddress` already converts all expected request-input failures to `InvalidHttpParameterException` (blank/missing address, malformed hex or base58, unparseable JSON body). Anything else that escapes it — e.g. an `IOException` from reading the POST body in `getRequestValue`, or an unexpected runtime failure — is a genuine server-side fault, and `Util.processError` now hides it at DEBUG while reporting it to the client as a parameter error. Per the new `Util.processServerError` contract, server-side failures should be logged at ERROR. Catch `InvalidHttpParameterException` in the parsing block and let unexpected exceptions hit the second catch (single try block with both catch clauses). `GetRewardServlet` has the identical issue.</violation>
</file>
<file name="framework/src/main/java/org/tron/core/services/http/TriggerSmartContractServlet.java">
<violation number="1" location="framework/src/main/java/org/tron/core/services/http/TriggerSmartContractServlet.java:39">
P3: These throws are still swallowed by the generic `catch (Exception e)` below, which formats the response as `e.getClass() + " : " + errString`. The only visible effect of swapping the type is that the OTHER_ERROR message now exposes the internal class name `org.tron.core.exception.InvalidHttpParameterException`, which contradicts this PR's handling of the same exception in `Util.processError`/`clientMessage` (clean message, no class prefix) used by the other affected servlets. Add an explicit catch for `InvalidHttpParameterException` before the generic one, returning just `e.getMessage()`, so the validation message is surfaced without the internal FQN.</violation>
</file>
<file name="framework/src/test/java/org/tron/core/WalletContractAddressLoggingTest.java">
<violation number="1" location="framework/src/test/java/org/tron/core/WalletContractAddressLoggingTest.java:37">
P3: The test only proves Base58 is never touched; it never asserts the log output that the PR's safety property is about. `assertNull(…getContract(…))` and `getContractInfo` are true on any null-account path, so this test passes even if the account-missing log line is deleted entirely, and it also passes if `getAddressString` regressed to logging the full oversized value (e.g. `ByteArray.toHexString(address)` for all 32 KB) — the same log-bloat/DoS the change is meant to prevent. Capture the logged message (e.g. a `ListAppender` on the Wallet logger) and assert it is bounded and contains the `invalid-address(...len=...)` form, or capture the string returned per call and assert bound + absence of the raw value.</violation>
</file>
Requires human review: Auto-approval blocked because this review re-detected 1 unresolved issue already reported by Cubic.
View guided diff | Turn on auto-fix | Re-trigger cubic
| byte[] address; | ||
| try { | ||
| address = Util.getAddress(request); | ||
| } catch (Exception e) { |
There was a problem hiding this comment.
P3: This catch-all around Util.getAddress routes every exception into the debug-level client-error path, but getAddress already converts all expected request-input failures to InvalidHttpParameterException (blank/missing address, malformed hex or base58, unparseable JSON body). Anything else that escapes it — e.g. an IOException from reading the POST body in getRequestValue, or an unexpected runtime failure — is a genuine server-side fault, and Util.processError now hides it at DEBUG while reporting it to the client as a parameter error. Per the new Util.processServerError contract, server-side failures should be logged at ERROR. Catch InvalidHttpParameterException in the parsing block and let unexpected exceptions hit the second catch (single try block with both catch clauses). GetRewardServlet has the identical issue.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At framework/src/main/java/org/tron/core/services/http/GetBrokerageServlet.java, line 22:
<comment>This catch-all around `Util.getAddress` routes every exception into the debug-level client-error path, but `getAddress` already converts all expected request-input failures to `InvalidHttpParameterException` (blank/missing address, malformed hex or base58, unparseable JSON body). Anything else that escapes it — e.g. an `IOException` from reading the POST body in `getRequestValue`, or an unexpected runtime failure — is a genuine server-side fault, and `Util.processError` now hides it at DEBUG while reporting it to the client as a parameter error. Per the new `Util.processServerError` contract, server-side failures should be logged at ERROR. Catch `InvalidHttpParameterException` in the parsing block and let unexpected exceptions hit the second catch (single try block with both catch clauses). `GetRewardServlet` has the identical issue.</comment>
<file context>
@@ -17,18 +16,19 @@ public class GetBrokerageServlet extends RateLimiterServlet {
+ byte[] address;
+ try {
+ address = Util.getAddress(request);
+ } catch (Exception e) {
+ Util.processError(e, response);
+ return;
</file context>
| JSONObject jsonObject = JSONObject.parseObject(contract); | ||
| if (StringUtil.isNullOrEmpty(jsonObject.getString(Util.OWNER_ADDRESS))) { | ||
| throw new InvalidParameterException(Util.OWNER_ADDRESS + " isn't set."); | ||
| throw new InvalidHttpParameterException(Util.OWNER_ADDRESS + " isn't set."); |
There was a problem hiding this comment.
P3: These throws are still swallowed by the generic catch (Exception e) below, which formats the response as e.getClass() + " : " + errString. The only visible effect of swapping the type is that the OTHER_ERROR message now exposes the internal class name org.tron.core.exception.InvalidHttpParameterException, which contradicts this PR's handling of the same exception in Util.processError/clientMessage (clean message, no class prefix) used by the other affected servlets. Add an explicit catch for InvalidHttpParameterException before the generic one, returning just e.getMessage(), so the validation message is surfaced without the internal FQN.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At framework/src/main/java/org/tron/core/services/http/TriggerSmartContractServlet.java, line 39:
<comment>These throws are still swallowed by the generic `catch (Exception e)` below, which formats the response as `e.getClass() + " : " + errString`. The only visible effect of swapping the type is that the OTHER_ERROR message now exposes the internal class name `org.tron.core.exception.InvalidHttpParameterException`, which contradicts this PR's handling of the same exception in `Util.processError`/`clientMessage` (clean message, no class prefix) used by the other affected servlets. Add an explicit catch for `InvalidHttpParameterException` before the generic one, returning just `e.getMessage()`, so the validation message is surfaced without the internal FQN.</comment>
<file context>
@@ -36,10 +36,10 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) {
JSONObject jsonObject = JSONObject.parseObject(contract);
if (StringUtil.isNullOrEmpty(jsonObject.getString(Util.OWNER_ADDRESS))) {
- throw new InvalidParameterException(Util.OWNER_ADDRESS + " isn't set.");
+ throw new InvalidHttpParameterException(Util.OWNER_ADDRESS + " isn't set.");
}
if (StringUtil.isNullOrEmpty(jsonObject.getString(Util.CONTRACT_ADDRESS))) {
</file context>
| try (MockedStatic<Base58> base58 = mockStatic(Base58.class)) { | ||
| assertNull(wallet.getContract(message)); | ||
| assertNull(wallet.getContractInfo(message)); | ||
| base58.verifyNoInteractions(); |
There was a problem hiding this comment.
P3: The test only proves Base58 is never touched; it never asserts the log output that the PR's safety property is about. assertNull(…getContract(…)) and getContractInfo are true on any null-account path, so this test passes even if the account-missing log line is deleted entirely, and it also passes if getAddressString regressed to logging the full oversized value (e.g. ByteArray.toHexString(address) for all 32 KB) — the same log-bloat/DoS the change is meant to prevent. Capture the logged message (e.g. a ListAppender on the Wallet logger) and assert it is bounded and contains the invalid-address(...len=...) form, or capture the string returned per call and assert bound + absence of the raw value.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At framework/src/test/java/org/tron/core/WalletContractAddressLoggingTest.java, line 37:
<comment>The test only proves Base58 is never touched; it never asserts the log output that the PR's safety property is about. `assertNull(…getContract(…))` and `getContractInfo` are true on any null-account path, so this test passes even if the account-missing log line is deleted entirely, and it also passes if `getAddressString` regressed to logging the full oversized value (e.g. `ByteArray.toHexString(address)` for all 32 KB) — the same log-bloat/DoS the change is meant to prevent. Capture the logged message (e.g. a `ListAppender` on the Wallet logger) and assert it is bounded and contains the `invalid-address(...len=...)` form, or capture the string returned per call and assert bound + absence of the raw value.</comment>
<file context>
@@ -0,0 +1,41 @@
+ try (MockedStatic<Base58> base58 = mockStatic(Base58.class)) {
+ assertNull(wallet.getContract(message));
+ assertNull(wallet.getContractInfo(message));
+ base58.verifyNoInteractions();
+ }
+ }
</file context>
c551518 to
52ce473
Compare
getContract and getContractInfo answer null for an address that is not well formed, before the account store is read.
A string or number longer than 64 characters is rejected before BigDecimal sees it, and Permission_id must convert identically through both coercion paths, so a value one path silently reinterprets no longer gets through.
getAddress reports every way a request can fail to name an address as one fixed message, and the reward and brokerage servlets write it, so the fullnode, solidity and PBFT endpoints no longer differ on a given malformed request. An absent address is one of those ways: it used to be answered with the service default.
52ce473 to
65485f1
Compare
❌ Math Usage Detection ResultsFound forbidden usage of Please review if this usage is intended. Caution Note: You should use |
Mint takes exactly one receive description and transfer takes one or two of each. The counts are checked before the merge loops, because ByteUtil.merge copies the accumulated buffer on every iteration and checking afterwards would make an unbounded list quadratic.
… failure An amount string past 80 characters and a trigger input the builder rejects are answered as a ContractValidateException naming the argument, instead of escaping the wallet as an IllegalArgumentException.
JsonFormat renders address fields over 21 bytes as hex instead of Base58 (visible=true). The hello handshake, PBFT SR list, trigger constant check and getContract logs render addresses via WalletUtil.getAddressString, which Base58Check-encodes only 20- and 21-byte input and renders anything else as hex of at most 21 bytes.
65485f1 to
a74278e
Compare
The response sanitizer forwards only a whitelist of exception types and turns the rest into "internal server error", which hid the fixed texts of HTTP parameter validation. Those checks now throw InvalidHttpParameterException, which the sanitizer forwards; java.security.InvalidParameterException stays off the whitelist because the JDK and libraries throw it too. The checks used only by triggersmartcontract, triggerconstantcontract and estimateenergy keep InvalidParameterException, since those servlets format their own errors.
- drop the address guard from contract queries; the log line bounds the address itself - report an unusable address as InvalidHttpParameterException through processError - accept Permission_id only as a JSON int or a decimal string - keep the cause of a rejected Permission_id
a74278e to
ba54931
Compare
Unlike transfer, mint has no merge loop, so an oversized receive list costs no quadratic time and its count check is left out of this change. Also keep the cause of the invalid amount error, and record only log events from the test thread in Base58MessageLoggingTest.
Mint takes exactly one receive description and burn at most one; extra entries used to be dropped silently. getAddressString formats null as invalid-address(null). The transfer vectors now use populated descriptions and cover both signature paths; their expected digests are the pre-change output.
What does this PR do?
This PR hardens externally reachable API inputs before expensive or ambiguous processing:
addressconsistently ongetRewardandgetBrokeragevisible=trueresponses, sobroadcasthex, which echoes the submitted transaction even when it rejects it, no longer spends quadratic time encoding an oversized address such asraw_data.auths[].account.addressWalletUtil.getAddressString, which Base58Check-encodes only 20- and 21-byte values and renders any other length asinvalid-address(<hex of at most 21 bytes>,len=N), instead of Base58Check-encoding the whole valueUtil.getJsonLongValue(contract deploy and trigger values, exchange and proposal IDs), in string or numeric form, to 64 characters beforeBigDecimalconversion, and rejects values that are not exact 64-bit integersPermission_idonly as a JSON integer or a decimal integer string within the 32-bit rangeBigIntegerconversion, and reports an unusable amount or trigger input as aContractValidateExceptionInvalidHttpParameterExceptionfor HTTP parameter validation and lets the error sanitizer pass its message through, without echoing the rejected valueWhy are these changes required?
Malformed inputs could previously trigger disproportionate CPU work, silently truncate or wrap numeric values, or return plausible results for structurally invalid addresses.
These changes reject invalid inputs before expensive conversion, encoding, storage access, or repeated buffer merging.
This PR has been tested by:
Compatibility
Breaking, limited to requests with missing or invalid input; requests with valid input keep their existing behavior.
getRewardandgetBrokerageno longer substitute a default for an address they never received.Util.getAddressnow either returns a valid address or throws, so a request that carries noaddressat all is rejected like any other unusable one:GET /wallet/getRewardwithout the parameter answered{"reward": 0}and now answers{"Error":"INVALID address"}. The same applies togetBrokerageand to both endpoints on/walletsolidityand the PBFT mirror, six in total. A caller that relied on the zero default has to send an address.visible=true, an address field longer than 21 bytes is rendered as hex instead of Base58CheckPermission_idvalues other than a 32-bit JSON integer or decimal integer string are rejected, including booleans, fractions, overflowing integers, explicitnull, floating-point forms such as1.0or1e2, and strings such as"1,000"or"1.0";trueused to be applied as permission 1,1.0and"1.0"as 1,1e2as 100, and"1,000"as 1000node.allowShieldedTransactionApiflag is enabled (disabled by default):createShieldedContractParameters,createShieldedContractParametersWithoutAskandgetTriggerInputForShieldedTRC20Contract; such a value already exceeded the 256-bit range unless padded with leading zerosgetTriggerInputForShieldedTRC20Contractrejects a transfer with no or more than two receive descriptionsinternal server error, such askey [x] does not exist, an overflowing integer, or an unusable shielded TRC20 trigger input, now answer the specific messageFollow up
Extra details