Skip to content

Commit b672f81

Browse files
author
Wenhua Zhang
committed
Merge branch 'release_v4.4.0' into feature/api_access_config
2 parents ac9b9ba + 5bc9942 commit b672f81

51 files changed

Lines changed: 1435 additions & 249 deletions

File tree

Some content is hidden

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

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.tron.common.utils.Commons;
1111
import org.tron.common.utils.DecodeUtil;
1212
import org.tron.core.capsule.AccountCapsule;
13+
import org.tron.core.capsule.ContractCapsule;
1314
import org.tron.core.capsule.TransactionResultCapsule;
1415
import org.tron.core.exception.BalanceInsufficientException;
1516
import org.tron.core.exception.ContractExeException;
@@ -137,6 +138,23 @@ public boolean validate() throws ContractValidateException {
137138

138139
}
139140

141+
// after AllowTvmCompatibleEvm proposal, send trx to smartContract which version is one
142+
// by actuator is not allowed.
143+
if (dynamicStore.getAllowTvmCompatibleEvm() == 1
144+
&& toAccount != null
145+
&& toAccount.getType() == AccountType.Contract) {
146+
147+
ContractCapsule contractCapsule = chainBaseManager.getContractStore().get(toAddress);
148+
if (contractCapsule == null) { // this can not happen
149+
throw new ContractValidateException(
150+
"Account type is Contract, but it is not exist in contract store.");
151+
} else if (contractCapsule.getContractVersion() == 1) {
152+
throw new ContractValidateException(
153+
"Cannot transfer TRX to a smartContract which version is one. " +
154+
"Instead please use TriggerSmartContract ");
155+
}
156+
}
157+
140158
if (balance < Math.addExact(amount, fee)) {
141159
throw new ContractValidateException(
142160
"Validate TransferContract error, balance is not sufficient.");

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

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -177,24 +177,14 @@ public void execute(Object object) throws ContractExeException {
177177
vm.play(program);
178178
result = program.getResult();
179179

180-
if (isConstantCall) {
181-
long callValue = TransactionCapsule.getCallValue(trx.getRawData().getContract(0));
182-
long callTokenValue = TransactionUtil
183-
.getCallTokenValue(trx.getRawData().getContract(0));
184-
if (callValue > 0 || callTokenValue > 0) {
185-
result.setRuntimeError("constant cannot set call value or call token value.");
186-
result.rejectInternalTransactions();
187-
}
188-
if (result.getException() != null) {
189-
result.setRuntimeError(result.getException().getMessage());
190-
result.rejectInternalTransactions();
191-
}
192-
context.setProgramResult(result);
193-
return;
194-
}
195-
196180
if (TrxType.TRX_CONTRACT_CREATION_TYPE == trxType && !result.isRevert()) {
197181
byte[] code = program.getResult().getHReturn();
182+
if (code.length != 0 && vmConfig.allowTvmLondon() && code[0] == (byte) 0xEF) {
183+
if (null == result.getException()) {
184+
result.setException(Program.Exception
185+
.invalidCodeException());
186+
}
187+
}
198188
long saveCodeEnergy = (long) getLength(code) * EnergyCost.getInstance().getCREATE_DATA();
199189
long afterSpend = program.getEnergyLimitLeft().longValue() - saveCodeEnergy;
200190
if (afterSpend < 0) {
@@ -211,6 +201,15 @@ public void execute(Object object) throws ContractExeException {
211201
}
212202
}
213203

204+
if (isConstantCall) {
205+
if (result.getException() != null) {
206+
result.setRuntimeError(result.getException().getMessage());
207+
result.rejectInternalTransactions();
208+
}
209+
context.setProgramResult(result);
210+
return;
211+
}
212+
214213
if (result.getException() != null || result.isRevert()) {
215214
result.getDeleteAccounts().clear();
216215
result.getLogInfoList().clear();
@@ -297,7 +296,12 @@ private void create()
297296
if (contract == null) {
298297
throw new ContractValidateException("Cannot get CreateSmartContract from transaction");
299298
}
300-
SmartContract newSmartContract = contract.getNewContract();
299+
SmartContract newSmartContract;
300+
if (VMConfig.allowTvmCompatibleEvm()) {
301+
newSmartContract = contract.getNewContract().toBuilder().setVersion(1).build();
302+
} else {
303+
newSmartContract = contract.getNewContract().toBuilder().clearVersion().build();
304+
}
301305
if (!contract.getOwnerAddress().equals(newSmartContract.getOriginAddress())) {
302306
logger.info("OwnerAddress not equals OriginAddress");
303307
throw new ContractValidateException("OwnerAddress is not equals OriginAddress");
@@ -360,6 +364,9 @@ private void create()
360364
} else {
361365
energyLimit = getAccountEnergyLimitWithFloatRatio(creator, feeLimit, callValue);
362366
}
367+
if (isConstantCall) {
368+
energyLimit = CommonParameter.getInstance().maxEnergyLimitForConstant;
369+
}
363370

364371
checkTokenValueAndId(tokenValue, tokenId);
365372

@@ -377,6 +384,9 @@ private void create()
377384
vmShouldEndInUs, energyLimit);
378385
this.vm = new VM();
379386
this.program = new Program(ops, programInvoke, rootInternalTransaction, vmConfig);
387+
if (VMConfig.allowTvmCompatibleEvm()) {
388+
this.program.setContractVersion(1);
389+
}
380390
byte[] txId = TransactionUtil.getTransactionId(trx).getBytes();
381391
this.program.setRootTransactionId(txId);
382392
if (enableEventListener && isCheckTransaction()) {
@@ -459,7 +469,6 @@ private void call()
459469

460470
byte[] code = repository.getCode(contractAddress);
461471
if (isNotEmpty(code)) {
462-
463472
long feeLimit = trx.getRawData().getFeeLimit();
464473
if (feeLimit < 0 || feeLimit > repository.getDynamicPropertiesStore().getMaxFeeLimit()) {
465474
logger.info("invalid feeLimit {}", feeLimit);
@@ -469,7 +478,7 @@ private void call()
469478
AccountCapsule caller = repository.getAccount(callerAddress);
470479
long energyLimit;
471480
if (isConstantCall) {
472-
energyLimit = VMConstant.ENERGY_LIMIT_IN_CONSTANT_TX;
481+
energyLimit = CommonParameter.getInstance().maxEnergyLimitForConstant;
473482
} else {
474483
AccountCapsule creator = repository
475484
.getAccount(deployedContract.getInstance().getOriginAddress().toByteArray());
@@ -492,6 +501,9 @@ private void call()
492501
this.vm = new VM();
493502
rootInternalTransaction = new InternalTransaction(trx, trxType);
494503
this.program = new Program(code, programInvoke, rootInternalTransaction, vmConfig);
504+
if (VMConfig.allowTvmCompatibleEvm()) {
505+
this.program.setContractVersion(deployedContract.getContractVersion());
506+
}
495507
byte[] txId = TransactionUtil.getTransactionId(trx).getBytes();
496508
this.program.setRootTransactionId(txId);
497509

actuator/src/main/java/org/tron/core/utils/ProposalUtil.java

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,17 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
383383
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_1_2)) {
384384
throw new ContractValidateException("Bad chain parameter id [MAX_FEE_LIMIT]");
385385
}
386-
if (value < 0 || value > 10_000_000_000L) {
386+
if (value < 0) {
387387
throw new ContractValidateException(
388-
"Bad MAX_FEE_LIMIT parameter value, valid range is [0,10_000_000_000L]");
388+
"Bad MAX_FEE_LIMIT parameter value, value must not be negative");
389+
} else if (value > 10_000_000_000L) {
390+
if (dynamicPropertiesStore.getAllowTvmLondon() == 0) {
391+
throw new ContractValidateException(
392+
"Bad MAX_FEE_LIMIT parameter value, valid range is [0,10_000_000_000L]");
393+
}
394+
if (value > LONG_VALUE) {
395+
throw new ContractValidateException(LONG_VALUE_ERROR);
396+
}
389397
}
390398
break;
391399
}
@@ -469,7 +477,6 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
469477
}
470478
break;
471479
}
472-
473480
case FREE_NET_LIMIT: {
474481
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_3)) {
475482
throw new ContractValidateException("Bad chain parameter id [FREE_NET_LIMIT]");
@@ -502,6 +509,28 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
502509
}
503510
break;
504511
}
512+
case ALLOW_TVM_LONDON: {
513+
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_4)) {
514+
throw new ContractValidateException(
515+
"Bad chain parameter id [ALLOW_TVM_LONDON]");
516+
}
517+
if (value != 1) {
518+
throw new ContractValidateException(
519+
"This value[ALLOW_TVM_LONDON] is only allowed to be 1");
520+
}
521+
break;
522+
}
523+
case ALLOW_TVM_COMPATIBLE_EVM: {
524+
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_4)) {
525+
throw new ContractValidateException(
526+
"Bad chain parameter id [ALLOW_TVM_COMPATIBLE_EVM]");
527+
}
528+
if (value != 1) {
529+
throw new ContractValidateException(
530+
"This value[ALLOW_TVM_COMPATIBLE_EVM] is only allowed to be 1");
531+
}
532+
break;
533+
}
505534
default:
506535
break;
507536
}
@@ -552,16 +581,18 @@ public enum ProposalType { // current value, value range
552581
ALLOW_MARKET_TRANSACTION(44), // {0, 1}
553582
MARKET_SELL_FEE(45), // 0 [0,10_000_000_000]
554583
MARKET_CANCEL_FEE(46), // 0 [0,10_000_000_000]
555-
MAX_FEE_LIMIT(47), // [0, 10_000_000_000]
584+
MAX_FEE_LIMIT(47), // [0, 100_000_000_000] TRX
556585
ALLOW_TRANSACTION_FEE_POOL(48), // 0, 1
557586
ALLOW_BLACKHOLE_OPTIMIZATION(49),// 0,1
558587
ALLOW_NEW_RESOURCE_MODEL(51),// 0,1
559588
ALLOW_TVM_FREEZE(52), // 0, 1
560589
ALLOW_ACCOUNT_ASSET_OPTIMIZATION(53), // 1
561590
// ALLOW_NEW_REWARD_ALGORITHM(58), // 0, 1
562591
ALLOW_TVM_VOTE(59), // 0, 1
592+
ALLOW_TVM_COMPATIBLE_EVM(60), // 0, 1
563593
FREE_NET_LIMIT(61), // 5000, [0, 100_000]
564-
TOTAL_NET_LIMIT(62); // 43_200_000_000L, [0, 1000_000_000_000L]
594+
TOTAL_NET_LIMIT(62), // 43_200_000_000L, [0, 1000_000_000_000L]
595+
ALLOW_TVM_LONDON(63); // 0, 1
565596

566597
private long code;
567598

actuator/src/main/java/org/tron/core/vm/OpCode.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ public enum OpCode {
244244
* (0x47) Get current account balance
245245
*/
246246
SELFBALANCE(0x47, 0, 1, Tier.LowTier),
247+
/**
248+
* (0x48) Get block's basefee
249+
*/
250+
BASEFEE(0x48, 0, 1, Tier.BaseTier),
247251

248252

249253
/* Memory, Storage and Flow Operations */

actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
import static org.tron.common.utils.BIUtil.isZero;
2525
import static org.tron.common.utils.ByteUtil.*;
2626
import static org.tron.core.db.TransactionTrace.convertToTronAddress;
27+
import static java.util.Arrays.copyOfRange;
2728

2829
import java.math.BigInteger;
30+
import java.security.MessageDigest;
2931
import java.util.ArrayList;
3032
import java.util.Arrays;
3133
import java.util.HashSet;
@@ -45,6 +47,8 @@
4547
import lombok.extern.slf4j.Slf4j;
4648
import org.apache.commons.lang3.ArrayUtils;
4749
import org.apache.commons.lang3.tuple.Pair;
50+
import org.tron.common.crypto.Blake2bfMessageDigest;
51+
import org.tron.common.crypto.Hash;
4852
import org.tron.common.crypto.SignUtils;
4953
import org.tron.common.crypto.SignatureInterface;
5054
import org.tron.common.crypto.zksnark.BN128;
@@ -107,6 +111,9 @@ public class PrecompiledContracts {
107111
private static final ReceivedVoteCount receivedVoteCount = new ReceivedVoteCount();
108112
private static final TotalVoteCount totalVoteCount = new TotalVoteCount();
109113

114+
private static final EthRipemd160 ethRipemd160 = new EthRipemd160();
115+
private static final Blake2F blake2F = new Blake2F();
116+
110117
private static final DataWord ecRecoverAddr = new DataWord(
111118
"0000000000000000000000000000000000000000000000000000000000000001");
112119
private static final DataWord sha256Addr = new DataWord(
@@ -147,6 +154,11 @@ public class PrecompiledContracts {
147154
"0000000000000000000000000000000000000000000000000000000001000009");
148155
private static final DataWord totalVoteCountAddr = new DataWord(
149156
"000000000000000000000000000000000000000000000000000000000100000a");
157+
private static final DataWord ethRipemd160Addr = new DataWord(
158+
"0000000000000000000000000000000000000000000000000000000000020003");
159+
private static final DataWord blake2FAddr = new DataWord(
160+
"0000000000000000000000000000000000000000000000000000000000020009");
161+
150162

151163
public static PrecompiledContract getContractForAddress(DataWord address) {
152164

@@ -214,6 +226,12 @@ public static PrecompiledContract getContractForAddress(DataWord address) {
214226
if (VMConfig.allowTvmVote() && address.equals(totalVoteCountAddr)) {
215227
return totalVoteCount;
216228
}
229+
if (VMConfig.allowTvmCompatibleEvm() && address.equals(ethRipemd160Addr)) {
230+
return ethRipemd160;
231+
}
232+
if (VMConfig.allowTvmCompatibleEvm() && address.equals(blake2FAddr)) {
233+
return blake2F;
234+
}
217235

218236
return null;
219237
}
@@ -1721,4 +1739,66 @@ public Pair<Boolean, byte[]> execute(byte[] data) {
17211739
}
17221740
}
17231741

1742+
public static class EthRipemd160 extends PrecompiledContract {
1743+
1744+
1745+
@Override
1746+
public long getEnergyForData(byte[] data) {
1747+
1748+
if (data == null) {
1749+
return 600;
1750+
}
1751+
return 600L + (data.length + 31) / 32 * 120;
1752+
}
1753+
1754+
@Override
1755+
public Pair<Boolean, byte[]> execute(byte[] data) {
1756+
1757+
byte[] result;
1758+
if (data == null) {
1759+
result = Hash.ripemd160(EMPTY_BYTE_ARRAY);
1760+
} else {
1761+
result = Hash.ripemd160(data);
1762+
}
1763+
return Pair.of(true, new DataWord(result).getData());
1764+
}
1765+
}
1766+
1767+
public static class Blake2F extends PrecompiledContract {
1768+
1769+
1770+
@Override
1771+
public long getEnergyForData(byte[] data) {
1772+
1773+
if (data.length != 213 || (data[212] & 0xFE) != 0) {
1774+
return 0;
1775+
}
1776+
final byte[] roundsBytes = copyOfRange(data, 0, 4);
1777+
final BigInteger rounds = new BigInteger(1, roundsBytes);
1778+
return rounds.longValue();
1779+
}
1780+
1781+
@Override
1782+
public Pair<Boolean, byte[]> execute(byte[] data) {
1783+
1784+
if (data.length != 213) {
1785+
logger.info("Incorrect input length. Expected {} and got {}", 213, data.length);
1786+
return Pair.of(false, DataWord.ZERO().getData());
1787+
}
1788+
if ((data[212] & 0xFE) != 0) {
1789+
logger.info("Incorrect finalization flag, expected 0 or 1 and got {}", data[212]);
1790+
return Pair.of(false, DataWord.ZERO().getData());
1791+
}
1792+
final MessageDigest digest = new Blake2bfMessageDigest();
1793+
byte[] result;
1794+
try {
1795+
digest.update(data);
1796+
result = digest.digest();
1797+
} catch (Exception e) {
1798+
return Pair.of(true, EMPTY_BYTE_ARRAY);
1799+
}
1800+
return Pair.of(true, result);
1801+
}
1802+
}
1803+
17241804
}

0 commit comments

Comments
 (0)