Skip to content

Commit 91a2f12

Browse files
committed
Merge branch 'develop' into hotfix/restrict_jsonrpc_size
2 parents fd7fdf9 + 328480f commit 91a2f12

23 files changed

Lines changed: 956 additions & 94 deletions
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.tron.core.actuator;
2+
3+
import com.google.protobuf.GeneratedMessageV3;
4+
import org.tron.common.math.StrictMathWrapper;
5+
import org.tron.protos.Protocol.Transaction.Contract.ContractType;
6+
7+
public abstract class AbstractExchangeActuator extends AbstractActuator {
8+
9+
public AbstractExchangeActuator(ContractType type, Class<? extends GeneratedMessageV3> clazz) {
10+
super(type, clazz);
11+
}
12+
13+
protected boolean allowHarden() {
14+
return chainBaseManager.getDynamicPropertiesStore().allowHardenExchangeCalculation();
15+
}
16+
17+
public long subtractExact(long x, long y) {
18+
return allowHarden() ? StrictMathWrapper.subtractExact(x, y) : x - y;
19+
}
20+
21+
public long addExact(long x, long y) {
22+
return allowHarden() ? StrictMathWrapper.addExact(x, y) : x + y;
23+
}
24+
}

actuator/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import org.tron.protos.contract.ExchangeContract.ExchangeCreateContract;
2828

2929
@Slf4j(topic = "actuator")
30-
public class ExchangeCreateActuator extends AbstractActuator {
30+
public class ExchangeCreateActuator extends AbstractExchangeActuator {
3131

3232
public ExchangeCreateActuator() {
3333
super(ContractType.ExchangeCreateContract, ExchangeCreateContract.class);
@@ -57,25 +57,25 @@ public boolean execute(Object object) throws ContractExeException {
5757
long firstTokenBalance = exchangeCreateContract.getFirstTokenBalance();
5858
long secondTokenBalance = exchangeCreateContract.getSecondTokenBalance();
5959

60-
long newBalance = accountCapsule.getBalance() - fee;
60+
long newBalance = subtractExact(accountCapsule.getBalance(), fee);
6161

6262
accountCapsule.setBalance(newBalance);
6363

6464
if (Arrays.equals(firstTokenID, TRX_SYMBOL_BYTES)) {
65-
accountCapsule.setBalance(newBalance - firstTokenBalance);
65+
accountCapsule.setBalance(subtractExact(newBalance, firstTokenBalance));
6666
} else {
6767
accountCapsule
6868
.reduceAssetAmountV2(firstTokenID, firstTokenBalance, dynamicStore, assetIssueStore);
6969
}
7070

7171
if (Arrays.equals(secondTokenID, TRX_SYMBOL_BYTES)) {
72-
accountCapsule.setBalance(newBalance - secondTokenBalance);
72+
accountCapsule.setBalance(subtractExact(newBalance, secondTokenBalance));
7373
} else {
7474
accountCapsule
7575
.reduceAssetAmountV2(secondTokenID, secondTokenBalance, dynamicStore, assetIssueStore);
7676
}
7777

78-
long id = dynamicStore.getLatestExchangeNum() + 1;
78+
long id = addExact(dynamicStore.getLatestExchangeNum(), 1);
7979
long now = dynamicStore.getLatestBlockHeaderTimestamp();
8080
if (dynamicStore.getAllowSameTokenName() == 0) {
8181
//save to old asset store
@@ -124,7 +124,8 @@ public boolean execute(Object object) throws ContractExeException {
124124
}
125125
ret.setExchangeId(id);
126126
ret.setStatus(fee, code.SUCESS);
127-
} catch (BalanceInsufficientException | InvalidProtocolBufferException e) {
127+
} catch (BalanceInsufficientException | InvalidProtocolBufferException
128+
| ArithmeticException e) {
128129
logger.debug(e.getMessage(), e);
129130
ret.setStatus(fee, code.FAILED);
130131
throw new ContractExeException(e.getMessage());
@@ -134,6 +135,14 @@ public boolean execute(Object object) throws ContractExeException {
134135

135136
@Override
136137
public boolean validate() throws ContractValidateException {
138+
try {
139+
return doValidate();
140+
} catch (ArithmeticException e) {
141+
throw new ContractValidateException(e.getMessage());
142+
}
143+
}
144+
145+
private boolean doValidate() throws ContractValidateException {
137146
if (this.any == null) {
138147
throw new ContractValidateException(ActuatorConstant.CONTRACT_NOT_EXIST);
139148
}
@@ -199,7 +208,7 @@ public boolean validate() throws ContractValidateException {
199208
}
200209

201210
if (Arrays.equals(firstTokenID, TRX_SYMBOL_BYTES)) {
202-
if (accountCapsule.getBalance() < (firstTokenBalance + calcFee())) {
211+
if (accountCapsule.getBalance() < addExact(firstTokenBalance, calcFee())) {
203212
throw new ContractValidateException("balance is not enough");
204213
}
205214
} else {
@@ -209,7 +218,7 @@ public boolean validate() throws ContractValidateException {
209218
}
210219

211220
if (Arrays.equals(secondTokenID, TRX_SYMBOL_BYTES)) {
212-
if (accountCapsule.getBalance() < (secondTokenBalance + calcFee())) {
221+
if (accountCapsule.getBalance() < addExact(secondTokenBalance, calcFee())) {
213222
throw new ContractValidateException("balance is not enough");
214223
}
215224
} else {

actuator/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,12 @@
2424
import org.tron.core.store.DynamicPropertiesStore;
2525
import org.tron.core.store.ExchangeStore;
2626
import org.tron.core.store.ExchangeV2Store;
27-
import org.tron.core.utils.TransactionUtil;
2827
import org.tron.protos.Protocol.Transaction.Contract.ContractType;
2928
import org.tron.protos.Protocol.Transaction.Result.code;
3029
import org.tron.protos.contract.ExchangeContract.ExchangeInjectContract;
3130

3231
@Slf4j(topic = "actuator")
33-
public class ExchangeInjectActuator extends AbstractActuator {
32+
public class ExchangeInjectActuator extends AbstractExchangeActuator {
3433

3534
public ExchangeInjectActuator() {
3635
super(ContractType.ExchangeInjectContract, ExchangeInjectContract.class);
@@ -56,8 +55,8 @@ public boolean execute(Object object) throws ContractExeException {
5655
.get(exchangeInjectContract.getOwnerAddress().toByteArray());
5756

5857
ExchangeCapsule exchangeCapsule;
59-
exchangeCapsule = Commons.getExchangeStoreFinal(dynamicStore, exchangeStore, exchangeV2Store).
60-
get(ByteArray.fromLong(exchangeInjectContract.getExchangeId()));
58+
exchangeCapsule = Commons.getExchangeStoreFinal(dynamicStore, exchangeStore, exchangeV2Store)
59+
.get(ByteArray.fromLong(exchangeInjectContract.getExchangeId()));
6160
byte[] firstTokenID = exchangeCapsule.getFirstTokenId();
6261
byte[] secondTokenID = exchangeCapsule.getSecondTokenId();
6362
long firstTokenBalance = exchangeCapsule.getFirstTokenBalance();
@@ -73,27 +72,27 @@ public boolean execute(Object object) throws ContractExeException {
7372
anotherTokenID = secondTokenID;
7473
anotherTokenQuant = floorDiv(multiplyExact(
7574
secondTokenBalance, tokenQuant), firstTokenBalance);
76-
exchangeCapsule.setBalance(firstTokenBalance + tokenQuant,
77-
secondTokenBalance + anotherTokenQuant);
75+
exchangeCapsule.setBalance(addExact(firstTokenBalance, tokenQuant),
76+
addExact(secondTokenBalance, anotherTokenQuant));
7877
} else {
7978
anotherTokenID = firstTokenID;
8079
anotherTokenQuant = floorDiv(multiplyExact(
8180
firstTokenBalance, tokenQuant), secondTokenBalance);
82-
exchangeCapsule.setBalance(firstTokenBalance + anotherTokenQuant,
83-
secondTokenBalance + tokenQuant);
81+
exchangeCapsule.setBalance(addExact(firstTokenBalance, anotherTokenQuant),
82+
addExact(secondTokenBalance, tokenQuant));
8483
}
8584

86-
long newBalance = accountCapsule.getBalance() - calcFee();
85+
long newBalance = subtractExact(accountCapsule.getBalance(), calcFee());
8786
accountCapsule.setBalance(newBalance);
8887

8988
if (Arrays.equals(tokenID, TRX_SYMBOL_BYTES)) {
90-
accountCapsule.setBalance(newBalance - tokenQuant);
89+
accountCapsule.setBalance(subtractExact(newBalance, tokenQuant));
9190
} else {
9291
accountCapsule.reduceAssetAmountV2(tokenID, tokenQuant, dynamicStore, assetIssueStore);
9392
}
9493

9594
if (Arrays.equals(anotherTokenID, TRX_SYMBOL_BYTES)) {
96-
accountCapsule.setBalance(newBalance - anotherTokenQuant);
95+
accountCapsule.setBalance(subtractExact(newBalance, anotherTokenQuant));
9796
} else {
9897
accountCapsule
9998
.reduceAssetAmountV2(anotherTokenID, anotherTokenQuant, dynamicStore, assetIssueStore);
@@ -105,7 +104,8 @@ public boolean execute(Object object) throws ContractExeException {
105104

106105
ret.setExchangeInjectAnotherAmount(anotherTokenQuant);
107106
ret.setStatus(fee, code.SUCESS);
108-
} catch (ItemNotFoundException | InvalidProtocolBufferException e) {
107+
} catch (ItemNotFoundException | InvalidProtocolBufferException
108+
| ArithmeticException e) {
109109
logger.debug(e.getMessage(), e);
110110
ret.setStatus(fee, code.FAILED);
111111
throw new ContractExeException(e.getMessage());
@@ -115,6 +115,14 @@ public boolean execute(Object object) throws ContractExeException {
115115

116116
@Override
117117
public boolean validate() throws ContractValidateException {
118+
try {
119+
return doValidate();
120+
} catch (ArithmeticException e) {
121+
throw new ContractValidateException(e.getMessage());
122+
}
123+
}
124+
125+
private boolean doValidate() throws ContractValidateException {
118126
if (this.any == null) {
119127
throw new ContractValidateException(ActuatorConstant.CONTRACT_NOT_EXIST);
120128
}
@@ -156,8 +164,8 @@ public boolean validate() throws ContractValidateException {
156164

157165
ExchangeCapsule exchangeCapsule;
158166
try {
159-
exchangeCapsule = Commons.getExchangeStoreFinal(dynamicStore, exchangeStore, exchangeV2Store).
160-
get(ByteArray.fromLong(contract.getExchangeId()));
167+
exchangeCapsule = Commons.getExchangeStoreFinal(dynamicStore, exchangeStore, exchangeV2Store)
168+
.get(ByteArray.fromLong(contract.getExchangeId()));
161169

162170
} catch (ItemNotFoundException ex) {
163171
throw new ContractValidateException("Exchange[" + contract.getExchangeId() + ActuatorConstant
@@ -179,9 +187,9 @@ public boolean validate() throws ContractValidateException {
179187
byte[] anotherTokenID;
180188
long anotherTokenQuant;
181189

182-
if (dynamicStore.getAllowSameTokenName() == 1 &&
183-
!Arrays.equals(tokenID, TRX_SYMBOL_BYTES) &&
184-
!isNumber(tokenID)) {
190+
if (dynamicStore.getAllowSameTokenName() == 1
191+
&& !Arrays.equals(tokenID, TRX_SYMBOL_BYTES)
192+
&& !isNumber(tokenID)) {
185193
throw new ContractValidateException("token id is not a valid number");
186194
}
187195

@@ -208,14 +216,14 @@ public boolean validate() throws ContractValidateException {
208216
anotherTokenID = secondTokenID;
209217
anotherTokenQuant = bigSecondTokenBalance.multiply(bigTokenQuant)
210218
.divide(bigFirstTokenBalance).longValueExact();
211-
newTokenBalance = firstTokenBalance + tokenQuant;
212-
newAnotherTokenBalance = secondTokenBalance + anotherTokenQuant;
219+
newTokenBalance = addExact(firstTokenBalance, tokenQuant);
220+
newAnotherTokenBalance = addExact(secondTokenBalance, anotherTokenQuant);
213221
} else {
214222
anotherTokenID = firstTokenID;
215223
anotherTokenQuant = bigFirstTokenBalance.multiply(bigTokenQuant)
216224
.divide(bigSecondTokenBalance).longValueExact();
217-
newTokenBalance = secondTokenBalance + tokenQuant;
218-
newAnotherTokenBalance = firstTokenBalance + anotherTokenQuant;
225+
newTokenBalance = addExact(secondTokenBalance, tokenQuant);
226+
newAnotherTokenBalance = addExact(firstTokenBalance, anotherTokenQuant);
219227
}
220228

221229
if (anotherTokenQuant <= 0) {
@@ -228,7 +236,7 @@ public boolean validate() throws ContractValidateException {
228236
}
229237

230238
if (Arrays.equals(tokenID, TRX_SYMBOL_BYTES)) {
231-
if (accountCapsule.getBalance() < (tokenQuant + calcFee())) {
239+
if (accountCapsule.getBalance() < addExact(tokenQuant, calcFee())) {
232240
throw new ContractValidateException("balance is not enough");
233241
}
234242
} else {
@@ -238,7 +246,7 @@ public boolean validate() throws ContractValidateException {
238246
}
239247

240248
if (Arrays.equals(anotherTokenID, TRX_SYMBOL_BYTES)) {
241-
if (accountCapsule.getBalance() < (anotherTokenQuant + calcFee())) {
249+
if (accountCapsule.getBalance() < addExact(anotherTokenQuant, calcFee())) {
242250
throw new ContractValidateException("balance is not enough");
243251
}
244252
} else {

actuator/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,12 @@
2424
import org.tron.core.store.DynamicPropertiesStore;
2525
import org.tron.core.store.ExchangeStore;
2626
import org.tron.core.store.ExchangeV2Store;
27-
import org.tron.core.utils.TransactionUtil;
2827
import org.tron.protos.Protocol.Transaction.Contract.ContractType;
2928
import org.tron.protos.Protocol.Transaction.Result.code;
3029
import org.tron.protos.contract.ExchangeContract.ExchangeTransactionContract;
3130

3231
@Slf4j(topic = "actuator")
33-
public class ExchangeTransactionActuator extends AbstractActuator {
32+
public class ExchangeTransactionActuator extends AbstractExchangeActuator {
3433

3534
public ExchangeTransactionActuator() {
3635
super(ContractType.ExchangeTransactionContract, ExchangeTransactionContract.class);
@@ -56,8 +55,8 @@ public boolean execute(Object object) throws ContractExeException {
5655
.get(exchangeTransactionContract.getOwnerAddress().toByteArray());
5756

5857
ExchangeCapsule exchangeCapsule = Commons
59-
.getExchangeStoreFinal(dynamicStore, exchangeStore, exchangeV2Store).
60-
get(ByteArray.fromLong(exchangeTransactionContract.getExchangeId()));
58+
.getExchangeStoreFinal(dynamicStore, exchangeStore, exchangeV2Store)
59+
.get(ByteArray.fromLong(exchangeTransactionContract.getExchangeId()));
6160

6261
byte[] firstTokenID = exchangeCapsule.getFirstTokenId();
6362
byte[] secondTokenID = exchangeCapsule.getSecondTokenId();
@@ -67,25 +66,25 @@ public boolean execute(Object object) throws ContractExeException {
6766

6867
byte[] anotherTokenID;
6968
long anotherTokenQuant = exchangeCapsule.transaction(tokenID, tokenQuant,
70-
dynamicStore.allowStrictMath());
69+
dynamicStore.allowStrictMath(), allowHarden());
7170

7271
if (Arrays.equals(tokenID, firstTokenID)) {
7372
anotherTokenID = secondTokenID;
7473
} else {
7574
anotherTokenID = firstTokenID;
7675
}
7776

78-
long newBalance = accountCapsule.getBalance() - calcFee();
77+
long newBalance = subtractExact(accountCapsule.getBalance(), calcFee());
7978
accountCapsule.setBalance(newBalance);
8079

8180
if (Arrays.equals(tokenID, TRX_SYMBOL_BYTES)) {
82-
accountCapsule.setBalance(newBalance - tokenQuant);
81+
accountCapsule.setBalance(subtractExact(newBalance, tokenQuant));
8382
} else {
8483
accountCapsule.reduceAssetAmountV2(tokenID, tokenQuant, dynamicStore, assetIssueStore);
8584
}
8685

8786
if (Arrays.equals(anotherTokenID, TRX_SYMBOL_BYTES)) {
88-
accountCapsule.setBalance(newBalance + anotherTokenQuant);
87+
accountCapsule.setBalance(addExact(newBalance, anotherTokenQuant));
8988
} else {
9089
accountCapsule
9190
.addAssetAmountV2(anotherTokenID, anotherTokenQuant, dynamicStore, assetIssueStore);
@@ -98,7 +97,8 @@ public boolean execute(Object object) throws ContractExeException {
9897

9998
ret.setExchangeReceivedAmount(anotherTokenQuant);
10099
ret.setStatus(fee, code.SUCESS);
101-
} catch (ItemNotFoundException | InvalidProtocolBufferException e) {
100+
} catch (ItemNotFoundException | InvalidProtocolBufferException
101+
| ContractValidateException | ArithmeticException e) {
102102
logger.debug(e.getMessage(), e);
103103
ret.setStatus(fee, code.FAILED);
104104
throw new ContractExeException(e.getMessage());
@@ -109,6 +109,14 @@ public boolean execute(Object object) throws ContractExeException {
109109

110110
@Override
111111
public boolean validate() throws ContractValidateException {
112+
try {
113+
return doValidate();
114+
} catch (ArithmeticException e) {
115+
throw new ContractValidateException(e.getMessage());
116+
}
117+
}
118+
119+
private boolean doValidate() throws ContractValidateException {
112120
if (this.any == null) {
113121
throw new ContractValidateException(ActuatorConstant.CONTRACT_NOT_EXIST);
114122
}
@@ -150,8 +158,8 @@ public boolean validate() throws ContractValidateException {
150158

151159
ExchangeCapsule exchangeCapsule;
152160
try {
153-
exchangeCapsule = Commons.getExchangeStoreFinal(dynamicStore, exchangeStore, exchangeV2Store).
154-
get(ByteArray.fromLong(contract.getExchangeId()));
161+
exchangeCapsule = Commons.getExchangeStoreFinal(dynamicStore, exchangeStore, exchangeV2Store)
162+
.get(ByteArray.fromLong(contract.getExchangeId()));
155163
} catch (ItemNotFoundException ex) {
156164
throw new ContractValidateException("Exchange[" + contract.getExchangeId()
157165
+ ActuatorConstant.NOT_EXIST_STR);
@@ -166,9 +174,9 @@ public boolean validate() throws ContractValidateException {
166174
long tokenQuant = contract.getQuant();
167175
long tokenExpected = contract.getExpected();
168176

169-
if (dynamicStore.getAllowSameTokenName() == 1 &&
170-
!Arrays.equals(tokenID, TRX_SYMBOL_BYTES) &&
171-
!isNumber(tokenID)) {
177+
if (dynamicStore.getAllowSameTokenName() == 1
178+
&& !Arrays.equals(tokenID, TRX_SYMBOL_BYTES)
179+
&& !isNumber(tokenID)) {
172180
throw new ContractValidateException("token id is not a valid number");
173181
}
174182
if (!Arrays.equals(tokenID, firstTokenID) && !Arrays.equals(tokenID, secondTokenID)) {
@@ -191,13 +199,13 @@ public boolean validate() throws ContractValidateException {
191199
long balanceLimit = dynamicStore.getExchangeBalanceLimit();
192200
long tokenBalance = (Arrays.equals(tokenID, firstTokenID) ? firstTokenBalance
193201
: secondTokenBalance);
194-
tokenBalance += tokenQuant;
202+
tokenBalance = addExact(tokenBalance, tokenQuant);
195203
if (tokenBalance > balanceLimit) {
196204
throw new ContractValidateException("token balance must less than " + balanceLimit);
197205
}
198206

199207
if (Arrays.equals(tokenID, TRX_SYMBOL_BYTES)) {
200-
if (accountCapsule.getBalance() < (tokenQuant + calcFee())) {
208+
if (accountCapsule.getBalance() < addExact(tokenQuant, calcFee())) {
201209
throw new ContractValidateException("balance is not enough");
202210
}
203211
} else {
@@ -207,7 +215,7 @@ public boolean validate() throws ContractValidateException {
207215
}
208216

209217
long anotherTokenQuant = exchangeCapsule.transaction(tokenID, tokenQuant,
210-
dynamicStore.allowStrictMath());
218+
dynamicStore.allowStrictMath(), allowHarden());
211219
if (anotherTokenQuant < tokenExpected) {
212220
throw new ContractValidateException("token required must greater than expected");
213221
}

0 commit comments

Comments
 (0)