Skip to content

Commit 354e1af

Browse files
authored
Merge pull request #5079 from yanghang8612/feature/optimize_trigger_interface
feature: optimize trigger interface
2 parents 8a45628 + 5643063 commit 354e1af

7 files changed

Lines changed: 82 additions & 73 deletions

File tree

chainbase/src/main/java/org/tron/core/db/TransactionTrace.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ public void pay() throws BalanceInsufficientException {
255255
AccountCapsule origin = accountStore.get(originAccount);
256256
AccountCapsule caller = accountStore.get(callerAccount);
257257
if (dynamicPropertiesStore.supportUnfreezeDelay()
258-
&& receipt.getReceipt().getResult().equals(contractResult.SUCCESS)) {
258+
&& getRuntimeResult().getException() == null && !getRuntimeResult().isRevert()) {
259259

260260
// just fo caller is not origin, we set the related field for origin account
261261
if (origin != null && !caller.getAddress().equals(origin.getAddress())) {

framework/src/main/java/org/tron/core/Wallet.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2840,7 +2840,7 @@ public Transaction triggerContract(TriggerSmartContract
28402840
triggerSmartContract.getData().toByteArray());
28412841

28422842
if (isConstant(abi, selector)) {
2843-
return callConstantContract(trxCap, builder, retBuilder);
2843+
return callConstantContract(trxCap, builder, retBuilder, false);
28442844
} else {
28452845
return trxCap.getInstance();
28462846
}
@@ -2958,13 +2958,19 @@ private Transaction cleanContextAndTriggerConstantContract(
29582958
txExtBuilder.clear();
29592959
txRetBuilder.clear();
29602960
transaction = triggerConstantContract(
2961-
triggerSmartContract, txCap, txExtBuilder, txRetBuilder);
2961+
triggerSmartContract, txCap, txExtBuilder, txRetBuilder, true);
29622962
return transaction;
29632963
}
29642964

29652965
public Transaction triggerConstantContract(TriggerSmartContract triggerSmartContract,
29662966
TransactionCapsule trxCap, Builder builder, Return.Builder retBuilder)
29672967
throws ContractValidateException, ContractExeException, HeaderNotFound, VMIllegalException {
2968+
return triggerConstantContract(triggerSmartContract, trxCap, builder, retBuilder, false);
2969+
}
2970+
2971+
public Transaction triggerConstantContract(TriggerSmartContract triggerSmartContract,
2972+
TransactionCapsule trxCap, Builder builder, Return.Builder retBuilder, boolean isEstimating)
2973+
throws ContractValidateException, ContractExeException, HeaderNotFound, VMIllegalException {
29682974

29692975
if (triggerSmartContract.getContractAddress().isEmpty()) { // deploy contract
29702976
CreateSmartContract.Builder deployBuilder = CreateSmartContract.newBuilder();
@@ -2989,11 +2995,11 @@ public Transaction triggerConstantContract(TriggerSmartContract triggerSmartCont
29892995
throw new ContractValidateException("Smart contract is not exist.");
29902996
}
29912997
}
2992-
return callConstantContract(trxCap, builder, retBuilder);
2998+
return callConstantContract(trxCap, builder, retBuilder, isEstimating);
29932999
}
29943000

29953001
public Transaction callConstantContract(TransactionCapsule trxCap,
2996-
Builder builder, Return.Builder retBuilder)
3002+
Builder builder, Return.Builder retBuilder, boolean isEstimating)
29973003
throws ContractValidateException, ContractExeException, HeaderNotFound, VMIllegalException {
29983004

29993005
if (!Args.getInstance().isSupportConstant()) {
@@ -3009,15 +3015,17 @@ public Transaction callConstantContract(TransactionCapsule trxCap,
30093015
headBlock = blockCapsuleList.get(0).getInstance();
30103016
}
30113017

3012-
TransactionContext context = new TransactionContext(new BlockCapsule(headBlock), trxCap,
3018+
BlockCapsule headBlockCapsule = new BlockCapsule(headBlock);
3019+
TransactionContext context = new TransactionContext(headBlockCapsule, trxCap,
30133020
StoreFactory.getInstance(), true, false);
30143021
VMActuator vmActuator = new VMActuator(true);
30153022

30163023
vmActuator.validate(context);
30173024
vmActuator.execute(context);
30183025

30193026
ProgramResult result = context.getProgramResult();
3020-
if (result.getException() != null) {
3027+
if (!isEstimating && result.getException() != null
3028+
|| result.getException() instanceof Program.OutOfTimeException) {
30213029
RuntimeException e = result.getException();
30223030
logger.warn("Constant call has an error {}", e.getMessage());
30233031
throw e;
@@ -3026,6 +3034,9 @@ public Transaction callConstantContract(TransactionCapsule trxCap,
30263034
TransactionResultCapsule ret = new TransactionResultCapsule();
30273035
builder.setEnergyUsed(result.getEnergyUsed());
30283036
builder.setEnergyPenalty(result.getEnergyPenaltyTotal());
3037+
builder.setBlockNumber(headBlockCapsule.getNum());
3038+
builder.setBlockHash(ByteString.copyFrom(headBlockCapsule.getBlockId().getBytes()));
3039+
builder.setEnergyPenalty(result.getEnergyPenaltyTotal());
30293040
builder.addConstantResult(ByteString.copyFrom(result.getHReturn()));
30303041
result.getLogInfoList().forEach(logInfo ->
30313042
builder.addLogs(LogInfo.buildLog(logInfo)));

framework/src/main/java/org/tron/core/services/http/EstimateEnergyServlet.java

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import com.google.protobuf.ByteString;
55
import io.netty.util.internal.StringUtil;
66
import java.io.IOException;
7-
import java.security.InvalidParameterException;
87
import java.util.stream.Collectors;
98
import javax.servlet.http.HttpServletRequest;
109
import javax.servlet.http.HttpServletResponse;
@@ -25,26 +24,12 @@
2524
@Slf4j(topic = "API")
2625
public class EstimateEnergyServlet extends RateLimiterServlet {
2726

28-
private final String functionSelector = "function_selector";
29-
3027
@Autowired
3128
private Wallet wallet;
3229

3330
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
3431
}
3532

36-
protected void validateParameter(String contract) {
37-
JSONObject jsonObject = JSONObject.parseObject(contract);
38-
if (!jsonObject.containsKey("owner_address")
39-
|| StringUtil.isNullOrEmpty(jsonObject.getString("owner_address"))) {
40-
throw new InvalidParameterException("owner_address isn't set.");
41-
}
42-
if (!jsonObject.containsKey("contract_address")
43-
|| StringUtil.isNullOrEmpty(jsonObject.getString("contract_address"))) {
44-
throw new InvalidParameterException("contract_address isn't set.");
45-
}
46-
}
47-
4833
protected void doPost(HttpServletRequest request, HttpServletResponse response)
4934
throws IOException {
5035
TriggerSmartContract.Builder build = TriggerSmartContract.newBuilder();
@@ -57,21 +42,19 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
5742
.collect(Collectors.joining(System.lineSeparator()));
5843
Util.checkBodySize(contract);
5944
visible = Util.getVisiblePost(contract);
60-
validateParameter(contract);
45+
Util.validateParameter(contract);
6146
JsonFormat.merge(contract, build, visible);
6247
JSONObject jsonObject = JSONObject.parseObject(contract);
6348

64-
boolean isFunctionSelectorSet = jsonObject.containsKey(functionSelector)
65-
&& !StringUtil.isNullOrEmpty(jsonObject.getString(functionSelector));
66-
String data;
49+
boolean isFunctionSelectorSet =
50+
!StringUtil.isNullOrEmpty(jsonObject.getString(Util.FUNCTION_SELECTOR));
6751
if (isFunctionSelectorSet) {
68-
String selector = jsonObject.getString(functionSelector);
69-
String parameter = jsonObject.getString("parameter");
70-
data = Util.parseMethod(selector, parameter);
52+
String selector = jsonObject.getString(Util.FUNCTION_SELECTOR);
53+
String parameter = jsonObject.getString(Util.FUNCTION_PARAMETER);
54+
String data = Util.parseMethod(selector, parameter);
7155
build.setData(ByteString.copyFrom(ByteArray.fromHexString(data)));
72-
} else {
73-
build.setData(ByteString.copyFrom(new byte[0]));
7456
}
57+
7558
TransactionCapsule trxCap = wallet.createTransactionCapsule(build.build(),
7659
Protocol.Transaction.Contract.ContractType.TriggerSmartContract);
7760

framework/src/main/java/org/tron/core/services/http/TriggerConstantContractServlet.java

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import com.google.protobuf.ByteString;
55
import io.netty.util.internal.StringUtil;
66
import java.io.IOException;
7-
import java.security.InvalidParameterException;
87
import java.util.stream.Collectors;
98
import javax.servlet.http.HttpServletRequest;
109
import javax.servlet.http.HttpServletResponse;
@@ -27,26 +26,12 @@
2726
@Slf4j(topic = "API")
2827
public class TriggerConstantContractServlet extends RateLimiterServlet {
2928

30-
private final String functionSelector = "function_selector";
31-
3229
@Autowired
3330
private Wallet wallet;
3431

3532
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
3633
}
3734

38-
protected void validateParameter(String contract) {
39-
JSONObject jsonObject = JSONObject.parseObject(contract);
40-
if (!jsonObject.containsKey("owner_address")
41-
|| StringUtil.isNullOrEmpty(jsonObject.getString("owner_address"))) {
42-
throw new InvalidParameterException("owner_address isn't set.");
43-
}
44-
if (!jsonObject.containsKey("contract_address")
45-
|| StringUtil.isNullOrEmpty(jsonObject.getString("contract_address"))) {
46-
throw new InvalidParameterException("contract_address isn't set.");
47-
}
48-
}
49-
5035
protected void doPost(HttpServletRequest request, HttpServletResponse response)
5136
throws IOException {
5237
TriggerSmartContract.Builder build = TriggerSmartContract.newBuilder();
@@ -58,21 +43,19 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
5843
.collect(Collectors.joining(System.lineSeparator()));
5944
Util.checkBodySize(contract);
6045
visible = Util.getVisiblePost(contract);
61-
validateParameter(contract);
46+
Util.validateParameter(contract);
6247
JsonFormat.merge(contract, build, visible);
6348
JSONObject jsonObject = JSONObject.parseObject(contract);
6449

65-
boolean isFunctionSelectorSet = jsonObject.containsKey(functionSelector)
66-
&& !StringUtil.isNullOrEmpty(jsonObject.getString(functionSelector));
67-
String data;
50+
boolean isFunctionSelectorSet =
51+
!StringUtil.isNullOrEmpty(jsonObject.getString(Util.FUNCTION_SELECTOR));
6852
if (isFunctionSelectorSet) {
69-
String selector = jsonObject.getString(functionSelector);
70-
String parameter = jsonObject.getString("parameter");
71-
data = Util.parseMethod(selector, parameter);
53+
String selector = jsonObject.getString(Util.FUNCTION_SELECTOR);
54+
String parameter = jsonObject.getString(Util.FUNCTION_PARAMETER);
55+
String data = Util.parseMethod(selector, parameter);
7256
build.setData(ByteString.copyFrom(ByteArray.fromHexString(data)));
73-
} else {
74-
build.setData(ByteString.copyFrom(new byte[0]));
7557
}
58+
7659
TransactionCapsule trxCap = wallet
7760
.createTransactionCapsule(build.build(), ContractType.TriggerSmartContract);
7861

framework/src/main/java/org/tron/core/services/http/TriggerSmartContractServlet.java

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,24 @@
2727
@Slf4j(topic = "API")
2828
public class TriggerSmartContractServlet extends RateLimiterServlet {
2929

30-
private final String functionSelector = "function_selector";
31-
3230
@Autowired
3331
private Wallet wallet;
3432

3533
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
3634
}
3735

38-
protected void validateParameter(String contract) {
36+
private void validateParameter(String contract) {
3937
JSONObject jsonObject = JSONObject.parseObject(contract);
40-
if (!jsonObject.containsKey("owner_address")
41-
|| StringUtil.isNullOrEmpty(jsonObject.getString("owner_address"))) {
42-
throw new InvalidParameterException("owner_address isn't set.");
38+
if (StringUtil.isNullOrEmpty(jsonObject.getString(Util.OWNER_ADDRESS))) {
39+
throw new InvalidParameterException(Util.OWNER_ADDRESS + " isn't set.");
40+
}
41+
if (StringUtil.isNullOrEmpty(jsonObject.getString(Util.CONTRACT_ADDRESS))) {
42+
throw new InvalidParameterException(Util.CONTRACT_ADDRESS + " isn't set.");
4343
}
44-
if (!jsonObject.containsKey("contract_address")
45-
|| StringUtil.isNullOrEmpty(jsonObject.getString("contract_address"))) {
46-
throw new InvalidParameterException("contract_address isn't set.");
44+
if (!StringUtil.isNullOrEmpty(jsonObject.getString(Util.FUNCTION_SELECTOR))
45+
^ StringUtil.isNullOrEmpty(jsonObject.getString(Util.CALL_DATA))) {
46+
throw new InvalidParameterException("Only one of "
47+
+ Util.FUNCTION_SELECTOR + " and " + Util.CALL_DATA + " can be set.");
4748
}
4849
}
4950

@@ -62,16 +63,13 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
6263
JsonFormat.merge(contract, build, visible);
6364
JSONObject jsonObject = JSONObject.parseObject(contract);
6465

65-
boolean isFunctionSelectorSet = jsonObject.containsKey(functionSelector)
66-
&& !StringUtil.isNullOrEmpty(jsonObject.getString(functionSelector));
67-
String data;
66+
boolean isFunctionSelectorSet =
67+
!StringUtil.isNullOrEmpty(jsonObject.getString(Util.FUNCTION_SELECTOR));
6868
if (isFunctionSelectorSet) {
69-
String selector = jsonObject.getString(functionSelector);
70-
String parameter = jsonObject.getString("parameter");
71-
data = Util.parseMethod(selector, parameter);
69+
String selector = jsonObject.getString(Util.FUNCTION_SELECTOR);
70+
String parameter = jsonObject.getString(Util.FUNCTION_PARAMETER);
71+
String data = Util.parseMethod(selector, parameter);
7272
build.setData(ByteString.copyFrom(ByteArray.fromHexString(data)));
73-
} else {
74-
build.setData(ByteString.copyFrom(new byte[0]));
7573
}
7674

7775
build.setCallTokenValue(Util.getJsonLongValue(jsonObject, "call_token_value"));

framework/src/main/java/org/tron/core/services/http/Util.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ public class Util {
6464
public static final String EXTRA_DATA = "extra_data";
6565
public static final String PARAMETER = "parameter";
6666

67+
// Used for TVM http interfaces
68+
public static final String OWNER_ADDRESS = "owner_address";
69+
public static final String CONTRACT_ADDRESS = "contract_address";
70+
public static final String FUNCTION_SELECTOR = "function_selector";
71+
public static final String FUNCTION_PARAMETER = "parameter";
72+
public static final String CALL_DATA = "data";
73+
6774
public static String printTransactionFee(String transactionFee) {
6875
JSONObject jsonObject = new JSONObject();
6976
JSONObject receipt = JSONObject.parseObject(transactionFee);
@@ -213,7 +220,7 @@ public static JSONObject printTransactionToJSON(Transaction transaction, boolean
213220
.parseObject(JsonFormat.printToString(deployContract, selfType));
214221
byte[] ownerAddress = deployContract.getOwnerAddress().toByteArray();
215222
byte[] contractAddress = generateContractAddress(transaction, ownerAddress);
216-
jsonTransaction.put("contract_address", ByteArray.toHexString(contractAddress));
223+
jsonTransaction.put(CONTRACT_ADDRESS, ByteArray.toHexString(contractAddress));
217224
break;
218225
default:
219226
Class clazz = TransactionFactory.getContract(contract.getType());
@@ -536,4 +543,29 @@ public static List<Log> convertLogAddressToTronAddress(TransactionInfo transacti
536543
return newLogList;
537544
}
538545

546+
/**
547+
* Validate parameters for trigger constant and estimate energy
548+
* - Rule-1: owner address must be set
549+
* - Rule-2: either contract address is set or call data is set
550+
* - Rule-3: only one of function selector and call data can be set
551+
* @param contract parameters in json format
552+
* @throws InvalidParameterException if validation is not passed, this kind of exception is thrown
553+
*/
554+
public static void validateParameter(String contract) throws InvalidParameterException {
555+
JSONObject jsonObject = JSONObject.parseObject(contract);
556+
if (StringUtils.isEmpty(jsonObject.getString(OWNER_ADDRESS))) {
557+
throw new InvalidParameterException(OWNER_ADDRESS + " isn't set.");
558+
}
559+
if (StringUtils.isEmpty(jsonObject.getString(CONTRACT_ADDRESS))
560+
&& StringUtils.isEmpty(jsonObject.getString(CALL_DATA))) {
561+
throw new InvalidParameterException("At least one of "
562+
+ CONTRACT_ADDRESS + " and " + CALL_DATA + " must be set.");
563+
}
564+
if (!StringUtils.isEmpty(jsonObject.getString(FUNCTION_SELECTOR))
565+
^ StringUtils.isEmpty(jsonObject.getString(CALL_DATA))) {
566+
throw new InvalidParameterException("Only one of "
567+
+ FUNCTION_SELECTOR + " and " + CALL_DATA + " can be set.");
568+
}
569+
}
570+
539571
}

protocol/src/main/protos/api/api.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,8 @@ message TransactionExtention {
12011201
repeated TransactionInfo.Log logs = 6;
12021202
repeated InternalTransaction internal_transactions = 7;
12031203
int64 energy_penalty = 8;
1204+
int64 block_number = 9;
1205+
bytes block_hash = 10;
12041206
}
12051207

12061208
message EstimateEnergyMessage {

0 commit comments

Comments
 (0)