Skip to content

Commit

Permalink
feat(math): migrate all operations from java.lang.Math to java.lang.S…
Browse files Browse the repository at this point in the history
…trictMath
  • Loading branch information
halibobo1205 committed Dec 3, 2024
1 parent 2b41e57 commit a1afbd2
Show file tree
Hide file tree
Showing 60 changed files with 536 additions and 216 deletions.
93 changes: 93 additions & 0 deletions .github/workflows/math-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: Check Math Usage

on:
push:
branches: [ 'master', 'release_**' ]
pull_request:
branches: [ 'develop', 'release_**' ]
workflow_dispatch:

jobs:
check-math:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Check for java.lang.Math usage
id: check-math
shell: bash
run: |
echo "Checking for java.lang.Math usage..."
touch math_usage.txt
while IFS= read -r file; do
filename=$(basename "$file")
if [[ "$filename" == "StrictMathWrapper.java" || "$filename" == "MathWrapper.java" ]]; then
continue
fi
perl -0777 -ne '
s/"([^"\\]|\\.)*"//g;
s/'\''([^'\''\\]|\\.)*'\''//g;
s!/\*([^*]|\*[^/])*\*/!!g;
s!//[^\n]*!!g;
$hasMath = 0;
$hasMath = 1 if /^[\s]*import[\s]+java\.lang\.Math\b/m;
$hasMath = 1 if /\bjava\s*\.\s*lang\s*\.\s*Math\s*\./;
$hasMath = 1 if /(?<![\w\.])(?<!Strict)Math\s*\./;
print "$ARGV\n" if $hasMath;
' "$file" >> math_usage.txt
done < <(find . -type f -name "*.java")
sort -u math_usage.txt -o math_usage.txt
if [ -s math_usage.txt ]; then
echo "❌ Error: Forbidden Math usage found in the following files:"
cat math_usage.txt
echo "math_found=true" >> $GITHUB_OUTPUT
echo "Please use org.tron.common.math.StrictMathWrapper instead of direct Math usage."
else
echo "✅ No forbidden Math usage found"
echo "math_found=false" >> $GITHUB_OUTPUT
fi
- name: Upload findings
if: steps.check-math.outputs.math_found == 'true'
uses: actions/upload-artifact@v4
with:
name: math-usage-report
path: math_usage.txt

- name: Create comment
if: github.event_name == 'pull_request' && steps.check-math.outputs.math_found == 'true'
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const findings = fs.readFileSync('math_usage.txt', 'utf8');
const body = `### ❌ Math Usage Detection Results
Found forbidden usage of \`java.lang.Math\` in the following files:
\`\`\`
${findings}
\`\`\`
**Please review if this usage is intended.**
> [!CAUTION]
> Note: You should use \`org.tron.common.math.StrictMathWrapper\`.
> If you need to use \`java.lang.Math\`, please provide a justification.
`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
- name: Fail if Math usage found
if: steps.check-math.outputs.math_found == 'true'
run: exit 1
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.tron.core.actuator;

import static java.util.stream.Collectors.toList;
import static org.tron.common.math.StrictMathWrapper.addExact;

import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
Expand Down Expand Up @@ -111,7 +112,7 @@ private boolean checkPermission(Permission permission) throws ContractValidateEx
throw new ContractValidateException("key's weight should be greater than 0");
}
try {
weightSum = Math.addExact(weightSum, key.getWeight());
weightSum = addExact(weightSum, key.getWeight());
} catch (ArithmeticException e) {
throw new ContractValidateException(e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.tron.core.actuator;

import static org.tron.common.math.StrictMathWrapper.floorDiv;
import static org.tron.common.math.StrictMathWrapper.multiplyExact;
import static org.tron.core.capsule.utils.TransactionUtil.isNumber;
import static org.tron.core.config.Parameter.ChainSymbol.TRX_SYMBOL_BYTES;

Expand All @@ -24,7 +26,6 @@
import org.tron.core.store.DynamicPropertiesStore;
import org.tron.core.store.ExchangeStore;
import org.tron.core.store.ExchangeV2Store;
import org.tron.core.utils.TransactionUtil;
import org.tron.protos.Protocol.Transaction.Contract.ContractType;
import org.tron.protos.Protocol.Transaction.Result.code;
import org.tron.protos.contract.ExchangeContract.ExchangeInjectContract;
Expand Down Expand Up @@ -71,14 +72,14 @@ public boolean execute(Object object) throws ContractExeException {

if (Arrays.equals(tokenID, firstTokenID)) {
anotherTokenID = secondTokenID;
anotherTokenQuant = Math
.floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance);
anotherTokenQuant = floorDiv(multiplyExact(
secondTokenBalance, tokenQuant), firstTokenBalance);
exchangeCapsule.setBalance(firstTokenBalance + tokenQuant,
secondTokenBalance + anotherTokenQuant);
} else {
anotherTokenID = firstTokenID;
anotherTokenQuant = Math
.floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance);
anotherTokenQuant = floorDiv(multiplyExact(
firstTokenBalance, tokenQuant), secondTokenBalance);
exchangeCapsule.setBalance(firstTokenBalance + anotherTokenQuant,
secondTokenBalance + tokenQuant);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,12 @@ public boolean execute(Object object) throws ContractExeException {
BigInteger bigTokenQuant = new BigInteger(String.valueOf(tokenQuant));
if (Arrays.equals(tokenID, firstTokenID)) {
anotherTokenID = secondTokenID;
// anotherTokenQuant = Math
// .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance);
anotherTokenQuant = bigSecondTokenBalance.multiply(bigTokenQuant)
.divide(bigFirstTokenBalance).longValueExact();
exchangeCapsule.setBalance(firstTokenBalance - tokenQuant,
secondTokenBalance - anotherTokenQuant);
} else {
anotherTokenID = firstTokenID;
// anotherTokenQuant = Math
// .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance);
anotherTokenQuant = bigFirstTokenBalance.multiply(bigTokenQuant)
.divide(bigSecondTokenBalance).longValueExact();
exchangeCapsule.setBalance(firstTokenBalance - anotherTokenQuant,
Expand Down Expand Up @@ -210,8 +206,6 @@ public boolean validate() throws ContractValidateException {
BigDecimal bigSecondTokenBalance = new BigDecimal(String.valueOf(secondTokenBalance));
BigDecimal bigTokenQuant = new BigDecimal(String.valueOf(tokenQuant));
if (Arrays.equals(tokenID, firstTokenID)) {
// anotherTokenQuant = Math
// .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance);
anotherTokenQuant = bigSecondTokenBalance.multiply(bigTokenQuant)
.divideToIntegralValue(bigFirstTokenBalance).longValueExact();
if (firstTokenBalance < tokenQuant || secondTokenBalance < anotherTokenQuant) {
Expand All @@ -230,8 +224,6 @@ public boolean validate() throws ContractValidateException {
}

} else {
// anotherTokenQuant = Math
// .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance);
anotherTokenQuant = bigFirstTokenBalance.multiply(bigTokenQuant)
.divideToIntegralValue(bigSecondTokenBalance).longValueExact();
if (secondTokenBalance < tokenQuant || firstTokenBalance < anotherTokenQuant) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

package org.tron.core.actuator;

import static org.tron.common.math.StrictMathWrapper.addExact;
import static org.tron.common.math.StrictMathWrapper.subtractExact;
import static org.tron.core.actuator.ActuatorConstant.CONTRACT_NOT_EXIST;
import static org.tron.core.actuator.ActuatorConstant.STORE_NOT_EXIST;
import static org.tron.core.actuator.ActuatorConstant.TX_RESULT_NULL;
Expand Down Expand Up @@ -244,7 +246,7 @@ public boolean validate() throws ContractValidateException {
long fee = calcFee();

if (Arrays.equals(sellTokenID, "_".getBytes())) {
if (ownerAccount.getBalance() < Math.addExact(sellTokenQuantity, fee)) {
if (ownerAccount.getBalance() < addExact(sellTokenQuantity, fee)) {
throw new ContractValidateException("No enough balance !");
}
} else {
Expand Down Expand Up @@ -447,7 +449,7 @@ private void matchSingleOrder(MarketOrderCapsule takerOrderCapsule,
takerOrderCapsule.setSellTokenQuantityRemain(0);
MarketUtils.updateOrderState(takerOrderCapsule, State.INACTIVE, marketAccountStore);

makerOrderCapsule.setSellTokenQuantityRemain(Math.subtractExact(
makerOrderCapsule.setSellTokenQuantityRemain(subtractExact(
makerOrderCapsule.getSellTokenQuantityRemain(), takerBuyTokenQuantityRemain));
} else {
// taker > maker
Expand Down Expand Up @@ -475,7 +477,7 @@ private void matchSingleOrder(MarketOrderCapsule takerOrderCapsule,
return;
} else {
makerOrderCapsule.setSellTokenQuantityRemain(0);
takerOrderCapsule.setSellTokenQuantityRemain(Math.subtractExact(
takerOrderCapsule.setSellTokenQuantityRemain(subtractExact(
takerOrderCapsule.getSellTokenQuantityRemain(), makerBuyTokenQuantityReceive));
}
}
Expand Down Expand Up @@ -524,7 +526,8 @@ private MarketOrderCapsule createAndSaveOrder(AccountCapsule accountCapsule,

private void transferBalanceOrToken(AccountCapsule accountCapsule) {
if (Arrays.equals(sellTokenID, "_".getBytes())) {
accountCapsule.setBalance(Math.subtractExact(accountCapsule.getBalance(), sellTokenQuantity));
accountCapsule.setBalance(subtractExact(
accountCapsule.getBalance(), sellTokenQuantity));
} else {
accountCapsule
.reduceAssetAmountV2(sellTokenID, sellTokenQuantity, dynamicStore, assetIssueStore);
Expand All @@ -537,7 +540,7 @@ private void addTrxOrToken(MarketOrderCapsule orderCapsule, long num,

byte[] buyTokenId = orderCapsule.getBuyTokenId();
if (Arrays.equals(buyTokenId, "_".getBytes())) {
accountCapsule.setBalance(Math.addExact(accountCapsule.getBalance(), num));
accountCapsule.setBalance(addExact(accountCapsule.getBalance(), num));
} else {
accountCapsule
.addAssetAmountV2(buyTokenId, num, dynamicStore, assetIssueStore);
Expand All @@ -550,7 +553,7 @@ private void addTrxOrToken(MarketOrderCapsule orderCapsule, long num) {

byte[] buyTokenId = orderCapsule.getBuyTokenId();
if (Arrays.equals(buyTokenId, "_".getBytes())) {
accountCapsule.setBalance(Math.addExact(accountCapsule.getBalance(), num));
accountCapsule.setBalance(addExact(accountCapsule.getBalance(), num));
} else {
accountCapsule
.addAssetAmountV2(buyTokenId, num, dynamicStore, assetIssueStore);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@

package org.tron.core.actuator;

import static org.tron.common.math.StrictMathWrapper.addExact;
import static org.tron.common.math.StrictMathWrapper.floorDiv;
import static org.tron.common.math.StrictMathWrapper.multiplyExact;
import static org.tron.common.math.StrictMathWrapper.subtractExact;

import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import java.util.Arrays;
Expand Down Expand Up @@ -64,8 +69,8 @@ public boolean execute(Object object) throws ContractExeException {
//subtract from owner address
byte[] ownerAddress = participateAssetIssueContract.getOwnerAddress().toByteArray();
AccountCapsule ownerAccount = accountStore.get(ownerAddress);
long balance = Math.subtractExact(ownerAccount.getBalance(), cost);
balance = Math.subtractExact(balance, fee);
long balance = subtractExact(ownerAccount.getBalance(), cost);
balance = subtractExact(balance, fee);
ownerAccount.setBalance(balance);
byte[] key = participateAssetIssueContract.getAssetName().toByteArray();

Expand All @@ -74,14 +79,14 @@ public boolean execute(Object object) throws ContractExeException {
assetIssueCapsule = Commons
.getAssetIssueStoreFinal(dynamicStore, assetIssueStore, assetIssueV2Store).get(key);

long exchangeAmount = Math.multiplyExact(cost, assetIssueCapsule.getNum());
exchangeAmount = Math.floorDiv(exchangeAmount, assetIssueCapsule.getTrxNum());
long exchangeAmount = multiplyExact(cost, assetIssueCapsule.getNum());
exchangeAmount = floorDiv(exchangeAmount, assetIssueCapsule.getTrxNum());
ownerAccount.addAssetAmountV2(key, exchangeAmount, dynamicStore, assetIssueStore);

//add to to_address
byte[] toAddress = participateAssetIssueContract.getToAddress().toByteArray();
AccountCapsule toAccount = accountStore.get(toAddress);
toAccount.setBalance(Math.addExact(toAccount.getBalance(), cost));
toAccount.setBalance(addExact(toAccount.getBalance(), cost));
if (!toAccount.reduceAssetAmountV2(key, exchangeAmount, dynamicStore, assetIssueStore)) {
throw new ContractExeException("reduceAssetAmount failed !");
}
Expand Down Expand Up @@ -156,7 +161,7 @@ public boolean validate() throws ContractValidateException {
try {
//Whether the balance is enough
long fee = calcFee();
if (ownerAccount.getBalance() < Math.addExact(amount, fee)) {
if (ownerAccount.getBalance() < addExact(amount, fee)) {
throw new ContractValidateException("No enough balance !");
}

Expand All @@ -181,8 +186,8 @@ public boolean validate() throws ContractValidateException {

int trxNum = assetIssueCapsule.getTrxNum();
int num = assetIssueCapsule.getNum();
long exchangeAmount = Math.multiplyExact(amount, num);
exchangeAmount = Math.floorDiv(exchangeAmount, trxNum);
long exchangeAmount = multiplyExact(amount, num);
exchangeAmount = floorDiv(exchangeAmount, trxNum);
if (exchangeAmount <= 0) {
throw new ContractValidateException("Can not process the exchange!");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.tron.core.actuator;

import static org.tron.common.math.StrictMathWrapper.addExact;
import static org.tron.common.math.StrictMathWrapper.subtractExact;
import static org.tron.core.capsule.TransactionCapsule.getShieldTransactionHashIgnoreTypeException;
import static org.tron.core.utils.ZenChainParams.ZC_ENCCIPHERTEXT_SIZE;
import static org.tron.core.utils.ZenChainParams.ZC_OUTCIPHERTEXT_SIZE;
Expand Down Expand Up @@ -96,9 +98,9 @@ public boolean execute(Object result)

//adjust and verify total shielded pool value
try {
Commons.adjustTotalShieldedPoolValue(
Math.addExact(Math.subtractExact(shieldedTransferContract.getToAmount(),
shieldedTransferContract.getFromAmount()), fee), dynamicStore);
Commons.adjustTotalShieldedPoolValue(addExact(subtractExact(
shieldedTransferContract.getToAmount(),
shieldedTransferContract.getFromAmount()), fee), dynamicStore);
} catch (ArithmeticException | BalanceInsufficientException e) {
logger.debug(e.getMessage(), e);
ret.setStatus(0, code.FAILED);
Expand Down Expand Up @@ -327,9 +329,11 @@ private void checkProof(List<SpendDescription> spendDescriptions,
long totalShieldedPoolValue = dynamicStore
.getTotalShieldedPoolValue();
try {
valueBalance = Math.addExact(Math.subtractExact(shieldedTransferContract.getToAmount(),
valueBalance = addExact(subtractExact(
shieldedTransferContract.getToAmount(),
shieldedTransferContract.getFromAmount()), fee);
totalShieldedPoolValue = Math.subtractExact(totalShieldedPoolValue, valueBalance);
totalShieldedPoolValue = subtractExact(
totalShieldedPoolValue, valueBalance);
} catch (ArithmeticException e) {
logger.debug(e.getMessage(), e);
throw new ZkProofValidateException(e.getMessage(), true);
Expand Down Expand Up @@ -452,7 +456,7 @@ private void validateTransparent(ShieldedTransferContract shieldedTransferContra
AccountCapsule toAccount = accountStore.get(toAddress);
if (toAccount != null) {
try {
Math.addExact(getZenBalance(toAccount), toAmount);
addExact(getZenBalance(toAccount), toAmount);
} catch (ArithmeticException e) {
logger.debug(e.getMessage(), e);
throw new ContractValidateException(e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.tron.core.actuator;

import static org.tron.common.math.StrictMathWrapper.addExact;
import static org.tron.core.config.Parameter.ChainConstant.TRANSFER_FEE;

import com.google.protobuf.ByteString;
Expand Down Expand Up @@ -58,7 +59,7 @@ public boolean execute(Object object) throws ContractExeException {
fee = fee + dynamicStore.getCreateNewAccountFeeInSystemContract();
}

Commons.adjustBalance(accountStore, ownerAddress, -(Math.addExact(fee, amount)));
Commons.adjustBalance(accountStore, ownerAddress, -(addExact(fee, amount)));
if (dynamicStore.supportBlackHoleOptimization()) {
dynamicStore.burnTrx(fee);
} else {
Expand Down Expand Up @@ -156,15 +157,15 @@ public boolean validate() throws ContractValidateException {
}
}

if (balance < Math.addExact(amount, fee)) {
if (balance < addExact(amount, fee)) {
logger.warn("Balance is not sufficient. Account: {}, balance: {}, amount: {}, fee: {}.",
StringUtil.encode58Check(ownerAddress), balance, amount, fee);
throw new ContractValidateException(
"Validate TransferContract error, balance is not sufficient.");
}

if (toAccount != null) {
Math.addExact(toAccount.getBalance(), amount);
addExact(toAccount.getBalance(), amount);
}
} catch (ArithmeticException e) {
logger.debug(e.getMessage(), e);
Expand Down
Loading

0 comments on commit a1afbd2

Please sign in to comment.