diff --git a/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java b/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
index 8f3501442f0..296c5f8ee79 100644
--- a/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
+++ b/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
@@ -779,6 +779,21 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
}
break;
}
+ case ALLOW_STRICT_MATH: {
+ if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_8_0)) {
+ throw new ContractValidateException(
+ "Bad chain parameter id [ALLOW_STRICT_MATH]");
+ }
+ if (dynamicPropertiesStore.allowStrictMath()) {
+ throw new ContractValidateException(
+ "[ALLOW_STRICT_MATH] has been valid, no need to propose again");
+ }
+ if (value != 1) {
+ throw new ContractValidateException(
+ "This value[ALLOW_STRICT_MATH] is only allowed to be 1");
+ }
+ break;
+ }
default:
break;
}
@@ -857,7 +872,8 @@ public enum ProposalType { // current value, value range
MAX_DELEGATE_LOCK_PERIOD(78), // (86400, 10512000]
ALLOW_OLD_REWARD_OPT(79), // 0, 1
ALLOW_ENERGY_ADJUSTMENT(81), // 0, 1
- MAX_CREATE_ACCOUNT_TX_SIZE(82); // [500, 10000]
+ MAX_CREATE_ACCOUNT_TX_SIZE(82), // [500, 10000]
+ ALLOW_STRICT_MATH(87); // 0, 1
private long code;
diff --git a/chainbase/src/main/java/org/tron/common/math/Maths.java b/chainbase/src/main/java/org/tron/common/math/Maths.java
new file mode 100644
index 00000000000..4fd95a8d569
--- /dev/null
+++ b/chainbase/src/main/java/org/tron/common/math/Maths.java
@@ -0,0 +1,30 @@
+package org.tron.common.math;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.tron.core.store.DynamicPropertiesStore;
+
+@Component
+@Slf4j(topic = "math")
+public class Maths {
+
+ private static DynamicPropertiesStore dynamicPropertiesStore;
+
+ @Autowired
+ public Maths(@Autowired DynamicPropertiesStore dynamicPropertiesStore) {
+ Maths.dynamicPropertiesStore = dynamicPropertiesStore;
+ }
+
+ /**
+ * Returns the value of the first argument raised to the power of the second argument.
+ * Note dynamicPropertiesStore must be inited before calling this method.
+ * @param a the base.
+ * @param b the exponent.
+ * @return the value {@code a}{@code b}.
+ */
+ public static double pow(double a, double b) {
+ boolean useStrictMath = dynamicPropertiesStore.allowStrictMath();
+ return useStrictMath ? StrictMathWrapper.pow(a, b) : MathWrapper.pow(a, b);
+ }
+}
diff --git a/chainbase/src/main/java/org/tron/core/capsule/ContractStateCapsule.java b/chainbase/src/main/java/org/tron/core/capsule/ContractStateCapsule.java
index 8633534280b..29d37282633 100644
--- a/chainbase/src/main/java/org/tron/core/capsule/ContractStateCapsule.java
+++ b/chainbase/src/main/java/org/tron/core/capsule/ContractStateCapsule.java
@@ -5,6 +5,7 @@
import com.google.protobuf.InvalidProtocolBufferException;
import lombok.extern.slf4j.Slf4j;
+import org.tron.common.math.Maths;
import org.tron.core.store.DynamicPropertiesStore;
import org.tron.protos.contract.SmartContractOuterClass;
import org.tron.protos.contract.SmartContractOuterClass.ContractState;
@@ -119,7 +120,7 @@ public boolean catchUpToCycle(
}
// Calc the decrease percent (decrease factor [75% ~ 100%])
- double decreasePercent = Math.pow(
+ double decreasePercent = Maths.pow(
1 - (double) increaseFactor / DYNAMIC_ENERGY_DECREASE_DIVISION / precisionFactor,
cycleCount
);
diff --git a/chainbase/src/main/java/org/tron/core/capsule/ExchangeProcessor.java b/chainbase/src/main/java/org/tron/core/capsule/ExchangeProcessor.java
index e1b536b3e7a..4977a690192 100644
--- a/chainbase/src/main/java/org/tron/core/capsule/ExchangeProcessor.java
+++ b/chainbase/src/main/java/org/tron/core/capsule/ExchangeProcessor.java
@@ -1,6 +1,7 @@
package org.tron.core.capsule;
import lombok.extern.slf4j.Slf4j;
+import org.tron.common.math.Maths;
@Slf4j(topic = "capsule")
public class ExchangeProcessor {
@@ -16,7 +17,7 @@ private long exchangeToSupply(long balance, long quant) {
long newBalance = balance + quant;
logger.debug("balance + quant: " + newBalance);
- double issuedSupply = -supply * (1.0 - Math.pow(1.0 + (double) quant / newBalance, 0.0005));
+ double issuedSupply = -supply * (1.0 - Maths.pow(1.0 + (double) quant / newBalance, 0.0005));
logger.debug("issuedSupply: " + issuedSupply);
long out = (long) issuedSupply;
supply += out;
@@ -28,7 +29,7 @@ private long exchangeFromSupply(long balance, long supplyQuant) {
supply -= supplyQuant;
double exchangeBalance =
- balance * (Math.pow(1.0 + (double) supplyQuant / supply, 2000.0) - 1.0);
+ balance * (Maths.pow(1.0 + (double) supplyQuant / supply, 2000.0) - 1.0);
logger.debug("exchangeBalance: " + exchangeBalance);
return (long) exchangeBalance;
diff --git a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java
index 2b50ec76af2..4af338f09bb 100644
--- a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java
+++ b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java
@@ -222,6 +222,7 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking
private static final byte[] ALLOW_ENERGY_ADJUSTMENT = "ALLOW_ENERGY_ADJUSTMENT".getBytes();
private static final byte[] MAX_CREATE_ACCOUNT_TX_SIZE = "MAX_CREATE_ACCOUNT_TX_SIZE".getBytes();
+ private static final byte[] ALLOW_STRICT_MATH = "ALLOW_STRICT_MATH".getBytes();
@Autowired
private DynamicPropertiesStore(@Value("properties") String dbName) {
@@ -2876,6 +2877,19 @@ public long getMaxCreateAccountTxSize() {
.map(ByteArray::toLong)
.orElse(CommonParameter.getInstance().getMaxCreateAccountTxSize());
}
+ public long getAllowStrictMath() {
+ return Optional.ofNullable(getUnchecked(ALLOW_STRICT_MATH))
+ .map(BytesCapsule::getData)
+ .map(ByteArray::toLong)
+ .orElse(CommonParameter.getInstance().getAllowStrictMath());
+ }
+ public void saveAllowStrictMath(long allowStrictMath) {
+ this.put(ALLOW_STRICT_MATH, new BytesCapsule(ByteArray.fromLong(allowStrictMath)));
+ }
+
+ public boolean allowStrictMath() {
+ return getAllowStrictMath() == 1L;
+ }
private static class DynamicResourceProperties {
diff --git a/common/src/main/java/org/tron/common/math/MathWrapper.java b/common/src/main/java/org/tron/common/math/MathWrapper.java
new file mode 100644
index 00000000000..d35dc9e586d
--- /dev/null
+++ b/common/src/main/java/org/tron/common/math/MathWrapper.java
@@ -0,0 +1,8 @@
+package org.tron.common.math;
+
+public class MathWrapper {
+
+ public static double pow(double a, double b) {
+ return Math.pow(a, b);
+ }
+}
diff --git a/common/src/main/java/org/tron/common/math/StrictMathWrapper.java b/common/src/main/java/org/tron/common/math/StrictMathWrapper.java
new file mode 100644
index 00000000000..6285f6567c0
--- /dev/null
+++ b/common/src/main/java/org/tron/common/math/StrictMathWrapper.java
@@ -0,0 +1,8 @@
+package org.tron.common.math;
+
+public class StrictMathWrapper {
+
+ public static double pow(double a, double b) {
+ return StrictMath.pow(a, b);
+ }
+}
diff --git a/common/src/main/java/org/tron/common/parameter/CommonParameter.java b/common/src/main/java/org/tron/common/parameter/CommonParameter.java
index 62ed12d856c..1aa3befe8aa 100644
--- a/common/src/main/java/org/tron/common/parameter/CommonParameter.java
+++ b/common/src/main/java/org/tron/common/parameter/CommonParameter.java
@@ -677,6 +677,10 @@ public class CommonParameter {
@Setter
public long maxCreateAccountTxSize = 1000L;
+ @Getter
+ @Setter
+ public long allowStrictMath;
+
private static double calcMaxTimeRatio() {
//return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1)));
return 5.0;
diff --git a/common/src/main/java/org/tron/core/Constant.java b/common/src/main/java/org/tron/core/Constant.java
index da3b2b1becc..96ff41b91da 100644
--- a/common/src/main/java/org/tron/core/Constant.java
+++ b/common/src/main/java/org/tron/core/Constant.java
@@ -386,4 +386,5 @@ public class Constant {
public static final String COMMITTEE_ALLOW_OLD_REWARD_OPT = "committee.allowOldRewardOpt";
public static final String COMMITTEE_ALLOW_ENERGY_ADJUSTMENT = "committee.allowEnergyAdjustment";
+ public static final String COMMITTEE_ALLOW_STRICT_MATH = "committee.allowStrictMath";
}
diff --git a/common/src/main/java/org/tron/core/config/Parameter.java b/common/src/main/java/org/tron/core/config/Parameter.java
index 027c225eb5d..92ed3177f6a 100644
--- a/common/src/main/java/org/tron/core/config/Parameter.java
+++ b/common/src/main/java/org/tron/core/config/Parameter.java
@@ -24,7 +24,8 @@ public enum ForkBlockVersionEnum {
VERSION_4_7_1(27, 1596780000000L, 80),
VERSION_4_7_2(28, 1596780000000L, 80),
VERSION_4_7_4(29, 1596780000000L, 80),
- VERSION_4_7_5(30, 1596780000000L, 80);
+ VERSION_4_7_5(30, 1596780000000L, 80),
+ VERSION_4_8_0(31, 1596780000000L, 80);
// if add a version, modify BLOCK_VERSION simultaneously
@Getter
@@ -73,7 +74,7 @@ public class ChainConstant {
public static final int SINGLE_REPEAT = 1;
public static final int BLOCK_FILLED_SLOTS_NUMBER = 128;
public static final int MAX_FROZEN_NUMBER = 1;
- public static final int BLOCK_VERSION = 30;
+ public static final int BLOCK_VERSION = 31;
public static final long FROZEN_PERIOD = 86_400_000L;
public static final long DELEGATE_PERIOD = 3 * 86_400_000L;
public static final long TRX_PRECISION = 1000_000L;
diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java
index 769274e8f2a..0943723f2f4 100755
--- a/framework/src/main/java/org/tron/core/Wallet.java
+++ b/framework/src/main/java/org/tron/core/Wallet.java
@@ -1343,6 +1343,11 @@ public Protocol.ChainParameters getChainParameters() {
.setValue(dbManager.getDynamicPropertiesStore().getMaxCreateAccountTxSize())
.build());
+ builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder()
+ .setKey("getAllowStrictMath")
+ .setValue(dbManager.getDynamicPropertiesStore().getAllowStrictMath())
+ .build());
+
return builder.build();
}
diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java
index 00142733f74..8853971a5f8 100644
--- a/framework/src/main/java/org/tron/core/config/args/Args.java
+++ b/framework/src/main/java/org/tron/core/config/args/Args.java
@@ -234,6 +234,7 @@ public static void clearParam() {
PARAMETER.maxUnsolidifiedBlocks = 54;
PARAMETER.allowOldRewardOpt = 0;
PARAMETER.allowEnergyAdjustment = 0;
+ PARAMETER.allowStrictMath = 0;
}
/**
@@ -1217,6 +1218,10 @@ public static void setParam(final String[] args, final String confFileName) {
config.hasPath(Constant.COMMITTEE_ALLOW_ENERGY_ADJUSTMENT) ? config
.getInt(Constant.COMMITTEE_ALLOW_ENERGY_ADJUSTMENT) : 0;
+ PARAMETER.allowStrictMath =
+ config.hasPath(Constant.COMMITTEE_ALLOW_STRICT_MATH) ? config
+ .getInt(Constant.COMMITTEE_ALLOW_STRICT_MATH) : 0;
+
logConfig();
}
diff --git a/framework/src/main/java/org/tron/core/consensus/ProposalService.java b/framework/src/main/java/org/tron/core/consensus/ProposalService.java
index d0c106a7e57..29eef1c3cb3 100644
--- a/framework/src/main/java/org/tron/core/consensus/ProposalService.java
+++ b/framework/src/main/java/org/tron/core/consensus/ProposalService.java
@@ -367,6 +367,10 @@ public static boolean process(Manager manager, ProposalCapsule proposalCapsule)
manager.getDynamicPropertiesStore().saveMaxCreateAccountTxSize(entry.getValue());
break;
}
+ case ALLOW_STRICT_MATH: {
+ manager.getDynamicPropertiesStore().saveAllowStrictMath(entry.getValue());
+ break;
+ }
default:
find = false;
break;
diff --git a/framework/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java b/framework/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java
index 3437eb0ea42..5d6473b1c35 100644
--- a/framework/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java
+++ b/framework/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java
@@ -135,5 +135,15 @@ public void testWithdraw() {
}
+ @Test
+ public void testStrictMath() {
+ long supply = 1_000_000_000_000_000_000L;
+ ExchangeProcessor processor = new ExchangeProcessor(supply);
+ long anotherTokenQuant = processor.exchange(4732214, 2202692725330L, 29218);
+ chainBaseManager.getDynamicPropertiesStore().saveAllowStrictMath(1);
+ long result = processor.exchange(4732214, 2202692725330L, 29218);
+ Assert.assertNotEquals(anotherTokenQuant, result);
+ }
+
}