Skip to content

Commit 196d92e

Browse files
authored
Merge pull request #1430 from tronprotocol/develop
calc storage create new storage; fix bug for storage in vote; fix bug for runtime-bytecode
2 parents a86d99f + 1ff2e78 commit 196d92e

File tree

58 files changed

+3000
-860
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+3000
-860
lines changed

src/main/java/org/tron/common/runtime/Runtime.java

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static java.lang.Math.max;
44
import static java.lang.Math.min;
5+
import static org.apache.commons.lang3.ArrayUtils.getLength;
56
import static org.apache.commons.lang3.ArrayUtils.isEmpty;
67
import static org.tron.common.runtime.utils.MUtil.convertToTronAddress;
78
import static org.tron.common.runtime.utils.MUtil.transfer;
@@ -26,6 +27,7 @@
2627
import org.spongycastle.util.encoders.Hex;
2728
import org.tron.common.runtime.config.SystemProperties;
2829
import org.tron.common.runtime.vm.DataWord;
30+
import org.tron.common.runtime.vm.EnergyCost;
2931
import org.tron.common.runtime.vm.PrecompiledContracts;
3032
import org.tron.common.runtime.vm.VM;
3133
import org.tron.common.runtime.vm.program.InternalTransaction;
@@ -95,7 +97,7 @@ public class Runtime {
9597
/**
9698
* For blockCap's trx run
9799
*/
98-
public Runtime(TransactionTrace trace, BlockCapsule block, Deposit deosit,
100+
public Runtime(TransactionTrace trace, BlockCapsule block, Deposit deposit,
99101
ProgramInvokeFactory programInvokeFactory) {
100102
this.trace = trace;
101103
this.trx = trace.getTrx().getInstance();
@@ -107,7 +109,7 @@ public Runtime(TransactionTrace trace, BlockCapsule block, Deposit deosit,
107109
this.blockCap = new BlockCapsule(Block.newBuilder().build());
108110
this.executorType = ET_PRE_TYPE;
109111
}
110-
this.deposit = deosit;
112+
this.deposit = deposit;
111113
this.programInvokeFactory = programInvokeFactory;
112114
this.energyProcessor = new EnergyProcessor(deposit.getDbManager());
113115
this.storageMarket = new StorageMarket(deposit.getDbManager());
@@ -293,8 +295,9 @@ private double getThisTxCPULimitInUsRatio() {
293295
/*
294296
**/
295297
private void create()
296-
throws ContractValidateException {
298+
throws ContractValidateException {
297299
if (!deposit.getDbManager().getDynamicPropertiesStore().supportVM()) {
300+
logger.error("vm work is off, need to be opened by the committee");
298301
throw new ContractValidateException("vm work is off, need to be opened by the committee");
299302
}
300303

@@ -307,11 +310,14 @@ private void create()
307310

308311
long percent = contract.getNewContract().getConsumeUserResourcePercent();
309312
if (percent < 0 || percent > 100) {
313+
logger.error("percent must be >= 0 and <= 100");
310314
throw new ContractValidateException("percent must be >= 0 and <= 100");
311315
}
312316

313317
// insure the new contract address haven't exist
314318
if (deposit.getAccount(contractAddress) != null) {
319+
logger.error("Trying to create a contract with existing contract address: " + Wallet
320+
.encode58Check(contractAddress));
315321
throw new ContractValidateException(
316322
"Trying to create a contract with existing contract address: " + Wallet
317323
.encode58Check(contractAddress));
@@ -342,6 +348,11 @@ private void create()
342348
long vmShouldEndInUs = vmStartInUs + thisTxCPULimitInUs;
343349

344350
long feeLimit = trx.getRawData().getFeeLimit();
351+
if (feeLimit < 0) {
352+
logger.info("feeLimit < 0");
353+
throw new ContractValidateException("feeLimit must be >= 0");
354+
}
355+
345356
long energyLimit = getEnergyLimit(creator, feeLimit, callValue);
346357
byte[] ops = newSmartContract.getBytecode().toByteArray();
347358
InternalTransaction internalTransaction = new InternalTransaction(trx);
@@ -351,9 +362,9 @@ private void create()
351362
blockCap.getInstance(), deposit, vmStartInUs, vmShouldEndInUs, energyLimit);
352363
this.vm = new VM(config);
353364
this.program = new Program(ops, programInvoke, internalTransaction, config, this.blockCap);
354-
Program.setRootTransactionId(new TransactionCapsule(trx).getTransactionId().getBytes());
355-
Program.resetNonce();
356-
Program.setRootCallConstant(isCallConstant());
365+
this.program.setRootTransactionId(new TransactionCapsule(trx).getTransactionId().getBytes());
366+
this.program.resetNonce();
367+
this.program.setRootCallConstant(isCallConstant());
357368
} catch (Exception e) {
358369
logger.error(e.getMessage());
359370
throw new ContractValidateException(e.getMessage());
@@ -381,9 +392,10 @@ private void create()
381392
*/
382393

383394
private void call()
384-
throws ContractValidateException {
395+
throws ContractValidateException {
385396

386397
if (!deposit.getDbManager().getDynamicPropertiesStore().supportVM()) {
398+
logger.error("vm work is off, need to be opened by the committee");
387399
throw new ContractValidateException("VM work is off, need to be opened by the committee");
388400
}
389401

@@ -413,6 +425,10 @@ private void call()
413425
long vmShouldEndInUs = vmStartInUs + thisTxCPULimitInUs;
414426

415427
long feeLimit = trx.getRawData().getFeeLimit();
428+
if (feeLimit < 0) {
429+
logger.info("feeLimit < 0");
430+
throw new ContractValidateException("feeLimit must be >= 0");
431+
}
416432
long energyLimit;
417433
if (isCallConstant(contractAddress)) {
418434
energyLimit = Constant.MAX_ENERGY_IN_TX;
@@ -427,9 +443,9 @@ private void call()
427443
InternalTransaction internalTransaction = new InternalTransaction(trx);
428444
this.program = new Program(null, code, programInvoke, internalTransaction, config,
429445
this.blockCap);
430-
Program.setRootTransactionId(new TransactionCapsule(trx).getTransactionId().getBytes());
431-
Program.resetNonce();
432-
Program.setRootCallConstant(isCallConstant());
446+
this.program.setRootTransactionId(new TransactionCapsule(trx).getTransactionId().getBytes());
447+
this.program.resetNonce();
448+
this.program.setRootCallConstant(isCallConstant());
433449
}
434450

435451
program.getResult().setContractAddress(contractAddress);
@@ -443,6 +459,17 @@ private void call()
443459

444460
public void go() {
445461
try {
462+
463+
TransactionCapsule trxCap = new TransactionCapsule(trx);
464+
if (null != trxCap.getContractRet() && contractResult.OUT_OF_TIME
465+
.equals(trxCap.getContractRet())) {
466+
result = program.getResult();
467+
program.spendAllEnergy();
468+
runtimeError = "Haven Time Out";
469+
result.setException(Program.Exception.notEnoughTime("Haven Time Out"));
470+
throw Program.Exception.notEnoughTime("Haven Time Out");
471+
}
472+
446473
if (vm != null) {
447474
vm.play(program);
448475

@@ -457,6 +484,21 @@ public void go() {
457484
return;
458485
}
459486

487+
if (TRX_CONTRACT_CREATION_TYPE == trxType && !result.isRevert()) {
488+
byte[] code = program.getResult().getHReturn();
489+
long saveCodeEnergy = getLength(code) * EnergyCost.getInstance().getCREATE_DATA();
490+
long afterSpend = program.getEnergyLimitLeft().longValue() - saveCodeEnergy;
491+
if (afterSpend < 0) {
492+
result.setException(
493+
Program.Exception
494+
.notEnoughSpendEnergy("No energy to save just created contract code",
495+
saveCodeEnergy, program.getEnergyLimitLeft().longValue()));
496+
} else {
497+
result.spendEnergy(saveCodeEnergy);
498+
// have saveCode in create()
499+
}
500+
}
501+
460502
if (result.getException() != null || result.isRevert()) {
461503
result.getDeleteAccounts().clear();
462504
result.getLogInfoList().clear();
@@ -480,6 +522,7 @@ public void go() {
480522
runtimeError = result.getException().getMessage();
481523
logger.error("runtime error is :{}", result.getException().getMessage());
482524
} catch (Throwable e) {
525+
program.spendAllEnergy();
483526
if (Objects.isNull(result.getException())) {
484527
logger.error(e.getMessage(), e);
485528
result.setException(new RuntimeException("Unknown Throwable"));
@@ -506,9 +549,17 @@ public boolean isCallConstant() throws ContractValidateException {
506549
TriggerSmartContract triggerContractFromTransaction = ContractCapsule
507550
.getTriggerContractFromTransaction(trx);
508551
if (TRX_CONTRACT_CALL_TYPE.equals(trxType)) {
509-
ABI abi = deposit
510-
.getContract(triggerContractFromTransaction.getContractAddress().toByteArray())
511-
.getInstance().getAbi();
552+
553+
ContractCapsule contract = deposit
554+
.getContract(triggerContractFromTransaction.getContractAddress().toByteArray());
555+
if (contract == null) {
556+
logger.error("contract: {} is not in contract store", Wallet
557+
.encode58Check(triggerContractFromTransaction.getContractAddress().toByteArray()));
558+
throw new ContractValidateException("contract: " + Wallet
559+
.encode58Check(triggerContractFromTransaction.getContractAddress().toByteArray())
560+
+ " is not in contract store");
561+
}
562+
ABI abi = contract.getInstance().getAbi();
512563
if (Wallet.isConstant(abi, triggerContractFromTransaction)) {
513564
return true;
514565
}

0 commit comments

Comments
 (0)