66import static org .apache .commons .lang3 .ArrayUtils .isNotEmpty ;
77import static org .tron .common .runtime .utils .MUtil .convertToTronAddress ;
88import static org .tron .common .runtime .utils .MUtil .transfer ;
9+ import static org .tron .common .runtime .vm .VMConstant .CONTRACT_NAME_LENGTH ;
10+ import static org .tron .common .runtime .vm .VMConstant .REASON_ALREADY_TIME_OUT ;
911import static org .tron .common .runtime .vm .VMUtils .saveProgramTraceFile ;
1012import static org .tron .common .runtime .vm .VMUtils .zipAndEncode ;
1113import static org .tron .common .runtime .vm .program .InternalTransaction .ExecutorType .ET_NORMAL_TYPE ;
@@ -73,17 +75,17 @@ public class Runtime {
7375 private VMConfig config = VMConfig .getInstance ();
7476
7577 private Transaction trx ;
76- private BlockCapsule blockCap = null ;
78+ private BlockCapsule blockCap ;
7779 private Deposit deposit ;
78- private ProgramInvokeFactory programInvokeFactory = null ;
80+ private ProgramInvokeFactory programInvokeFactory ;
7981 private String runtimeError ;
8082
81- private EnergyProcessor energyProcessor = null ;
83+ private EnergyProcessor energyProcessor ;
8284 private ProgramResult result = new ProgramResult ();
8385
8486
85- private VM vm = null ;
86- private Program program = null ;
87+ private VM vm ;
88+ private Program program ;
8789 private InternalTransaction rootInternalTransaction ;
8890
8991 @ Getter
@@ -93,6 +95,7 @@ public class Runtime {
9395
9496 //tx trace
9597 private TransactionTrace trace ;
98+ private boolean isStaticCall ;
9699
97100 /**
98101 * For blockCap's trx run
@@ -113,7 +116,7 @@ public Runtime(TransactionTrace trace, BlockCapsule block, Deposit deposit,
113116 this .programInvokeFactory = programInvokeFactory ;
114117 this .energyProcessor = new EnergyProcessor (deposit .getDbManager ());
115118
116- Transaction . Contract . ContractType contractType = this .trx .getRawData ().getContract (0 ).getType ();
119+ ContractType contractType = this .trx .getRawData ().getContract (0 ).getType ();
117120 switch (contractType .getNumber ()) {
118121 case ContractType .TriggerSmartContract_VALUE :
119122 trxType = TRX_CONTRACT_CALL_TYPE ;
@@ -130,7 +133,6 @@ public Runtime(TransactionTrace trace, BlockCapsule block, Deposit deposit,
130133 /**
131134 * For constant trx with latest blockCap.
132135 */
133- private boolean isStaticCall = false ;
134136 public Runtime (Transaction tx , BlockCapsule block , DepositImpl deposit ,
135137 ProgramInvokeFactory programInvokeFactory , boolean isStaticCall ) {
136138 this (tx , block , deposit , programInvokeFactory );
@@ -145,12 +147,12 @@ public Runtime(Transaction tx, BlockCapsule block, DepositImpl deposit,
145147 this .executorType = ET_PRE_TYPE ;
146148 this .blockCap = block ;
147149 this .energyProcessor = new EnergyProcessor (deposit .getDbManager ());
148- Transaction . Contract . ContractType contractType = tx .getRawData ().getContract (0 ).getType ();
150+ ContractType contractType = tx .getRawData ().getContract (0 ).getType ();
149151 switch (contractType .getNumber ()) {
150- case Transaction . Contract . ContractType .TriggerSmartContract_VALUE :
152+ case ContractType .TriggerSmartContract_VALUE :
151153 trxType = TRX_CONTRACT_CALL_TYPE ;
152154 break ;
153- case Transaction . Contract . ContractType .CreateSmartContract_VALUE :
155+ case ContractType .CreateSmartContract_VALUE :
154156 trxType = TRX_CONTRACT_CREATION_TYPE ;
155157 break ;
156158 default :
@@ -176,13 +178,13 @@ public BigInteger getBlockCPULeftInUs() {
176178 // insure blockCap is not null
177179 BigInteger curBlockHaveElapsedCPUInUs =
178180 BigInteger .valueOf (
179- 1000 * (DateTime .now ().getMillis () - blockCap .getInstance ().getBlockHeader ()
181+ Constant . ONE_THOUSAND * (DateTime .now ().getMillis () - blockCap .getInstance ().getBlockHeader ()
180182 .getRawData ()
181183 .getTimestamp ())); // us
182184 BigInteger curBlockCPULimitInUs = BigInteger .valueOf ((long )
183- (1000 * ChainConstant .BLOCK_PRODUCED_INTERVAL * 0.5
185+ (Constant . ONE_THOUSAND * ChainConstant .BLOCK_PRODUCED_INTERVAL * 0.5
184186 * Args .getInstance ().getBlockProducedTimeOut ()
185- / 100 )); // us
187+ / Constant . ONE_HUNDRED )); // us
186188
187189 return curBlockCPULimitInUs .subtract (curBlockHaveElapsedCPUInUs );
188190
@@ -207,21 +209,22 @@ public void execute()
207209
208210 private long getEnergyLimit (AccountCapsule account , long feeLimit , long callValue ) {
209211
210- long SUN_PER_ENERGY = deposit .getDbManager ().getDynamicPropertiesStore ().getEnergyFee () == 0
211- ? Constant .SUN_PER_ENERGY :
212- deposit .getDbManager ().getDynamicPropertiesStore ().getEnergyFee ();
212+ long sunPerEnergy = Constant .SUN_PER_ENERGY ;
213+ if (deposit .getDbManager ().getDynamicPropertiesStore ().getEnergyFee () != 0 ){
214+ sunPerEnergy = deposit .getDbManager ().getDynamicPropertiesStore ().getEnergyFee ();
215+ }
213216 // can change the calc way
214217 long leftEnergyFromFreeze = energyProcessor .getAccountLeftEnergyFromFreeze (account );
215218 callValue = max (callValue , 0 );
216219 long energyFromBalance = Math
217- .floorDiv (max (account .getBalance () - callValue , 0 ), SUN_PER_ENERGY );
220+ .floorDiv (max (account .getBalance () - callValue , 0 ), sunPerEnergy );
218221
219222 long energyFromFeeLimit ;
220223 long totalBalanceForEnergyFreeze = account .getAccountResource ().getFrozenBalanceForEnergy ()
221224 .getFrozenBalance ();
222225 if (0 == totalBalanceForEnergyFreeze ) {
223226 energyFromFeeLimit =
224- feeLimit / SUN_PER_ENERGY ;
227+ feeLimit / sunPerEnergy ;
225228 } else {
226229 long totalEnergyFromFreeze = energyProcessor
227230 .calculateGlobalEnergyLimit (totalBalanceForEnergyFreeze );
@@ -236,7 +239,7 @@ private long getEnergyLimit(AccountCapsule account, long feeLimit, long callValu
236239 } else {
237240 energyFromFeeLimit = Math
238241 .addExact (leftEnergyFromFreeze ,
239- (feeLimit - leftBalanceForEnergyFreeze ) / SUN_PER_ENERGY );
242+ (feeLimit - leftBalanceForEnergyFreeze ) / sunPerEnergy );
240243 }
241244 }
242245
@@ -258,11 +261,11 @@ private long getEnergyLimit(AccountCapsule creator, AccountCapsule caller,
258261 .getContract (contract .getContractAddress ().toByteArray ()).getInstance ();
259262 long consumeUserResourcePercent = smartContract .getConsumeUserResourcePercent ();
260263
261- consumeUserResourcePercent = max (0 , min (consumeUserResourcePercent , 100 ));
264+ consumeUserResourcePercent = max (0 , min (consumeUserResourcePercent , Constant . ONE_HUNDRED ));
262265
263266 if (creatorEnergyLimit * consumeUserResourcePercent
264- > (100 - consumeUserResourcePercent ) * callerEnergyLimit ) {
265- return Math .floorDiv (callerEnergyLimit * 100 , consumeUserResourcePercent );
267+ > (Constant . ONE_HUNDRED - consumeUserResourcePercent ) * callerEnergyLimit ) {
268+ return Math .floorDiv (callerEnergyLimit * Constant . ONE_HUNDRED , consumeUserResourcePercent );
266269 } else {
267270 return Math .addExact (callerEnergyLimit , creatorEnergyLimit );
268271 }
@@ -310,19 +313,19 @@ private void create()
310313 logger .info ("OwnerAddress not equals OriginAddress" );
311314 throw new VMIllegalException ("OwnerAddress is not equals OriginAddress" );
312315 }
313- byte [] code = newSmartContract .getBytecode ().toByteArray ();
314- byte [] contractAddress = Wallet .generateContractAddress (trx );
316+
315317 byte [] contractName = newSmartContract .getName ().getBytes ();
316318
317- if (contractName .length > 32 ) {
319+ if (contractName .length > CONTRACT_NAME_LENGTH ) {
318320 throw new ContractValidateException ("contractName's length cannot be greater than 32" );
319321 }
320322
321323 long percent = contract .getNewContract ().getConsumeUserResourcePercent ();
322- if (percent < 0 || percent > 100 ) {
324+ if (percent < 0 || percent > Constant . ONE_HUNDRED ) {
323325 throw new ContractValidateException ("percent must be >= 0 and <= 100" );
324326 }
325327
328+ byte [] contractAddress = Wallet .generateContractAddress (trx );
326329 // insure the new contract address haven't exist
327330 if (deposit .getAccount (contractAddress ) != null ) {
328331 throw new ContractValidateException (
@@ -335,29 +338,24 @@ private void create()
335338 long callValue = newSmartContract .getCallValue ();
336339 // create vm to constructor smart contract
337340 try {
338-
339- AccountCapsule creator = this .deposit
340- .getAccount (newSmartContract .getOriginAddress ().toByteArray ());
341-
342- long MAX_CPU_TIME_OF_ONE_TX = deposit .getDbManager ().getDynamicPropertiesStore ()
343- .getMaxCpuTimeOfOneTx () * 1000 ;
344-
345- long thisTxCPULimitInUs = (long ) (MAX_CPU_TIME_OF_ONE_TX * getThisTxCPULimitInUsRatio ());
346-
347- long vmStartInUs = System .nanoTime () / 1000 ;
348- long vmShouldEndInUs = vmStartInUs + thisTxCPULimitInUs ;
349-
350341 long feeLimit = trx .getRawData ().getFeeLimit ();
351342 if (feeLimit < 0 || feeLimit > VMConfig .MAX_FEE_LIMIT ) {
352343 logger .info ("invalid feeLimit {}" , feeLimit );
353344 throw new ContractValidateException (
354345 "feeLimit must be >= 0 and <= " + VMConfig .MAX_FEE_LIMIT );
355346 }
356347
348+ AccountCapsule creator = this .deposit
349+ .getAccount (newSmartContract .getOriginAddress ().toByteArray ());
357350 long energyLimit = getEnergyLimit (creator , feeLimit , callValue );
358351 byte [] ops = newSmartContract .getBytecode ().toByteArray ();
359352 rootInternalTransaction = new InternalTransaction (trx , trxType );
360353
354+ long maxCpuTimeOfOneTx = deposit .getDbManager ().getDynamicPropertiesStore ()
355+ .getMaxCpuTimeOfOneTx () * Constant .ONE_THOUSAND ;
356+ long thisTxCPULimitInUs = (long ) (maxCpuTimeOfOneTx * getThisTxCPULimitInUsRatio ());
357+ long vmStartInUs = System .nanoTime () / Constant .ONE_THOUSAND ;
358+ long vmShouldEndInUs = vmStartInUs + thisTxCPULimitInUs ;
361359 ProgramInvoke programInvoke = programInvokeFactory
362360 .createProgramInvoke (TRX_CONTRACT_CREATION_TYPE , executorType , trx ,
363361 blockCap .getInstance (), deposit , vmStartInUs , vmShouldEndInUs , energyLimit );
@@ -376,6 +374,7 @@ private void create()
376374 Protocol .AccountType .Contract );
377375
378376 deposit .createContract (contractAddress , new ContractCapsule (newSmartContract ));
377+ byte [] code = newSmartContract .getBytecode ().toByteArray ();
379378 deposit .saveCode (contractAddress , ProgramPrecompile .getCode (code ));
380379
381380 // transfer from callerAddress to contractAddress according to callValue
@@ -417,33 +416,30 @@ private void call()
417416 byte [] code = this .deposit .getCode (contractAddress );
418417 long callValue = contract .getCallValue ();
419418 if (isNotEmpty (code )) {
420- AccountCapsule caller = this .deposit .getAccount (contract .getOwnerAddress ().toByteArray ());
421- AccountCapsule creator = this .deposit .getAccount (
422- deployedContract .getInstance ()
423- .getOriginAddress ().toByteArray ());
424-
425- long MAX_CPU_TIME_OF_ONE_TX = deposit .getDbManager ().getDynamicPropertiesStore ()
426- .getMaxCpuTimeOfOneTx () * 1000 ;
427- long thisTxCPULimitInUs =
428- (long ) (MAX_CPU_TIME_OF_ONE_TX * getThisTxCPULimitInUsRatio ());
429-
430- long vmStartInUs = System .nanoTime () / 1000 ;
431- long vmShouldEndInUs = vmStartInUs + thisTxCPULimitInUs ;
432419
433420 long feeLimit = trx .getRawData ().getFeeLimit ();
434421 if (feeLimit < 0 || feeLimit > VMConfig .MAX_FEE_LIMIT ) {
435422 logger .info ("invalid feeLimit {}" , feeLimit );
436423 throw new ContractValidateException (
437424 "feeLimit must be >= 0 and <= " + VMConfig .MAX_FEE_LIMIT );
438425 }
426+ AccountCapsule caller = this .deposit .getAccount (contract .getOwnerAddress ().toByteArray ());
439427 long energyLimit ;
440428 if (isCallConstant (contractAddress )) {
441429 isStaticCall = true ;
442430 energyLimit = Constant .MAX_ENERGY_IN_TX ;
443431 } else {
432+ AccountCapsule creator = this .deposit .getAccount (
433+ deployedContract .getInstance ()
434+ .getOriginAddress ().toByteArray ());
444435 energyLimit = getEnergyLimit (creator , caller , contract , feeLimit , callValue );
445436 }
446-
437+ long maxCpuTimeOfOneTx = deposit .getDbManager ().getDynamicPropertiesStore ()
438+ .getMaxCpuTimeOfOneTx () * Constant .ONE_THOUSAND ;
439+ long thisTxCPULimitInUs =
440+ (long ) (maxCpuTimeOfOneTx * getThisTxCPULimitInUsRatio ());
441+ long vmStartInUs = System .nanoTime () / Constant .ONE_THOUSAND ;
442+ long vmShouldEndInUs = vmStartInUs + thisTxCPULimitInUs ;
447443 ProgramInvoke programInvoke = programInvokeFactory
448444 .createProgramInvoke (TRX_CONTRACT_CALL_TYPE , executorType , trx ,
449445 blockCap .getInstance (), deposit , vmStartInUs , vmShouldEndInUs , energyLimit );
@@ -473,13 +469,12 @@ public void go() {
473469
474470 TransactionCapsule trxCap = new TransactionCapsule (trx );
475471 if (null != blockCap && blockCap .generatedByMyself && null != trxCap .getContractRet ()
476- && contractResult .OUT_OF_TIME
477- .equals (trxCap .getContractRet ())) {
472+ && contractResult .OUT_OF_TIME == trxCap .getContractRet ()) {
478473 result = program .getResult ();
479474 program .spendAllEnergy ();
480- runtimeError = "Haven Time Out" ;
481- result .setException (Program .Exception .notEnoughTime ("Haven Time Out" ));
482- throw Program .Exception .notEnoughTime ("Haven Time Out" );
475+ runtimeError = REASON_ALREADY_TIME_OUT ;
476+ result .setException (Program .Exception .notEnoughTime (REASON_ALREADY_TIME_OUT ));
477+ throw Program .Exception .notEnoughTime (REASON_ALREADY_TIME_OUT );
483478 }
484479
485480 vm .play (program );
@@ -496,7 +491,7 @@ public void go() {
496491
497492 if (TRX_CONTRACT_CREATION_TYPE == trxType && !result .isRevert ()) {
498493 byte [] code = program .getResult ().getHReturn ();
499- long saveCodeEnergy = getLength (code ) * EnergyCost .getInstance ().getCREATE_DATA ();
494+ long saveCodeEnergy = ( long ) getLength (code ) * EnergyCost .getInstance ().getCREATE_DATA ();
500495 long afterSpend = program .getEnergyLimitLeft ().longValue () - saveCodeEnergy ;
501496 if (afterSpend < 0 ) {
502497 if (null == result .getException ()) {
@@ -544,7 +539,7 @@ public void go() {
544539 logger .info ("timeout: {}" , result .getException ().getMessage ());
545540 } catch (ContractValidateException e ) {
546541 logger .info ("when check constant, {}" , e .getMessage ());
547- }catch (Throwable e ) {
542+ } catch (Throwable e ) {
548543 program .spendAllEnergy ();
549544 result = program .getResult ();
550545 result .rejectInternalTransactions ();
@@ -560,7 +555,7 @@ public void go() {
560555 trace .setBill (result .getEnergyUsed ());
561556 }
562557
563- private long getEnergyFee (long callerEnergyUsage , long callerEnergyFrozen ,
558+ private static long getEnergyFee (long callerEnergyUsage , long callerEnergyFrozen ,
564559 long callerEnergyTotal ) {
565560 if (callerEnergyTotal <= 0 ) {
566561 return 0 ;
@@ -573,7 +568,7 @@ public boolean isCallConstant() throws ContractValidateException {
573568
574569 TriggerSmartContract triggerContractFromTransaction = ContractCapsule
575570 .getTriggerContractFromTransaction (trx );
576- if (TRX_CONTRACT_CALL_TYPE . equals ( trxType ) ) {
571+ if (TRX_CONTRACT_CALL_TYPE == trxType ) {
577572
578573 ContractCapsule contract = deposit
579574 .getContract (triggerContractFromTransaction .getContractAddress ().toByteArray ());
@@ -594,7 +589,7 @@ public boolean isCallConstant() throws ContractValidateException {
594589
595590 private boolean isCallConstant (byte [] address ) throws ContractValidateException {
596591
597- if (TRX_CONTRACT_CALL_TYPE . equals ( trxType ) ) {
592+ if (TRX_CONTRACT_CALL_TYPE == trxType ) {
598593 ABI abi = deposit .getContract (address ).getInstance ().getAbi ();
599594 if (Wallet .isConstant (abi , ContractCapsule .getTriggerContractFromTransaction (trx ))) {
600595 return true ;
0 commit comments