Skip to content

Commit 5510359

Browse files
committed
refactor(vm): extract executeConstantContract for readability
callConstantContract becomes a thin throttle wrapper (acquire / try-finally / release); the TVM execution body moves to a private executeConstantContract. Each method now reads with one concern in mind.
1 parent c25b088 commit 5510359

1 file changed

Lines changed: 61 additions & 47 deletions

File tree

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

Lines changed: 61 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3238,53 +3238,7 @@ public Transaction callConstantContract(TransactionCapsule trxCap,
32383238
}
32393239
}
32403240
try {
3241-
Block headBlock;
3242-
List<BlockCapsule> blockCapsuleList = chainBaseManager.getBlockStore()
3243-
.getBlockByLatestNum(1);
3244-
if (CollectionUtils.isEmpty(blockCapsuleList)) {
3245-
throw new HeaderNotFound("latest block not found");
3246-
} else {
3247-
headBlock = blockCapsuleList.get(0).getInstance();
3248-
}
3249-
3250-
BlockCapsule headBlockCapsule = new BlockCapsule(headBlock);
3251-
TransactionContext context = new TransactionContext(headBlockCapsule, trxCap,
3252-
StoreFactory.getInstance(), true, false);
3253-
VMActuator vmActuator = new VMActuator(true);
3254-
3255-
vmActuator.validate(context);
3256-
vmActuator.execute(context);
3257-
3258-
ProgramResult result = context.getProgramResult();
3259-
if (!isEstimating && result.getException() != null
3260-
|| result.getException() instanceof Program.OutOfTimeException) {
3261-
RuntimeException e = result.getException();
3262-
logger.warn("Constant call failed for reason: {}", e.getMessage());
3263-
throw e;
3264-
}
3265-
3266-
TransactionResultCapsule ret = new TransactionResultCapsule();
3267-
builder.setEnergyUsed(result.getEnergyUsed());
3268-
builder.setEnergyPenalty(result.getEnergyPenaltyTotal());
3269-
builder.addConstantResult(ByteString.copyFrom(result.getHReturn()));
3270-
result.getLogInfoList().forEach(logInfo ->
3271-
builder.addLogs(LogInfo.buildLog(logInfo)));
3272-
result.getInternalTransactions().forEach(it ->
3273-
builder.addInternalTransactions(buildInternalTransaction(it)));
3274-
ret.setStatus(0, code.SUCESS);
3275-
if (StringUtils.isNoneEmpty(result.getRuntimeError())) {
3276-
ret.setStatus(0, code.FAILED);
3277-
retBuilder
3278-
.setMessage(ByteString.copyFromUtf8(result.getRuntimeError()))
3279-
.build();
3280-
}
3281-
if (result.isRevert()) {
3282-
ret.setStatus(0, code.FAILED);
3283-
retBuilder.setMessage(ByteString.copyFromUtf8("REVERT opcode executed"))
3284-
.build();
3285-
}
3286-
trxCap.setResult(ret);
3287-
return trxCap.getInstance();
3241+
return executeConstantContract(trxCap, builder, retBuilder, isEstimating);
32883242
} finally {
32893243
if (acquiredHere) {
32903244
// remove() before release(): clears the slot from this worker's
@@ -3296,6 +3250,66 @@ public Transaction callConstantContract(TransactionCapsule trxCap,
32963250
}
32973251
}
32983252

3253+
/**
3254+
* Runs the actual TVM execution for a constant call. Split out from
3255+
* {@link #callConstantContract} so the public method stays focused on the
3256+
* concurrency-cap wrapper (acquire / try-finally / release) and the VM
3257+
* execution body has no concurrency concerns to read past. Callers must
3258+
* already hold the permit (or have determined that the cap is not engaged);
3259+
* this method does no throttling of its own.
3260+
*/
3261+
private Transaction executeConstantContract(TransactionCapsule trxCap,
3262+
Builder builder, Return.Builder retBuilder, boolean isEstimating)
3263+
throws ContractValidateException, ContractExeException, HeaderNotFound, VMIllegalException {
3264+
Block headBlock;
3265+
List<BlockCapsule> blockCapsuleList = chainBaseManager.getBlockStore()
3266+
.getBlockByLatestNum(1);
3267+
if (CollectionUtils.isEmpty(blockCapsuleList)) {
3268+
throw new HeaderNotFound("latest block not found");
3269+
} else {
3270+
headBlock = blockCapsuleList.get(0).getInstance();
3271+
}
3272+
3273+
BlockCapsule headBlockCapsule = new BlockCapsule(headBlock);
3274+
TransactionContext context = new TransactionContext(headBlockCapsule, trxCap,
3275+
StoreFactory.getInstance(), true, false);
3276+
VMActuator vmActuator = new VMActuator(true);
3277+
3278+
vmActuator.validate(context);
3279+
vmActuator.execute(context);
3280+
3281+
ProgramResult result = context.getProgramResult();
3282+
if (!isEstimating && result.getException() != null
3283+
|| result.getException() instanceof Program.OutOfTimeException) {
3284+
RuntimeException e = result.getException();
3285+
logger.warn("Constant call failed for reason: {}", e.getMessage());
3286+
throw e;
3287+
}
3288+
3289+
TransactionResultCapsule ret = new TransactionResultCapsule();
3290+
builder.setEnergyUsed(result.getEnergyUsed());
3291+
builder.setEnergyPenalty(result.getEnergyPenaltyTotal());
3292+
builder.addConstantResult(ByteString.copyFrom(result.getHReturn()));
3293+
result.getLogInfoList().forEach(logInfo ->
3294+
builder.addLogs(LogInfo.buildLog(logInfo)));
3295+
result.getInternalTransactions().forEach(it ->
3296+
builder.addInternalTransactions(buildInternalTransaction(it)));
3297+
ret.setStatus(0, code.SUCESS);
3298+
if (StringUtils.isNoneEmpty(result.getRuntimeError())) {
3299+
ret.setStatus(0, code.FAILED);
3300+
retBuilder
3301+
.setMessage(ByteString.copyFromUtf8(result.getRuntimeError()))
3302+
.build();
3303+
}
3304+
if (result.isRevert()) {
3305+
ret.setStatus(0, code.FAILED);
3306+
retBuilder.setMessage(ByteString.copyFromUtf8("REVERT opcode executed"))
3307+
.build();
3308+
}
3309+
trxCap.setResult(ret);
3310+
return trxCap.getInstance();
3311+
}
3312+
32993313
public SmartContract getContract(GrpcAPI.BytesMessage bytesMessage) {
33003314
byte[] address = bytesMessage.getValue().toByteArray();
33013315
AccountCapsule accountCapsule = chainBaseManager.getAccountStore().get(address);

0 commit comments

Comments
 (0)