Skip to content

Commit 973a4dc

Browse files
authored
Merge pull request #4112 from tronprotocol/release_v4.4.0
Release v4.4.0
2 parents 0b8485f + dae97ce commit 973a4dc

File tree

183 files changed

+11752
-888
lines changed

Some content is hidden

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

183 files changed

+11752
-888
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ This guide walks the user through the TRON Quickstart (v2.0.0) image setup.
6767
# Deploy
6868
* [Build](./build.md) Please build java-tron after cloning the project
6969
* [Run](./run.md) Run java-tron
70-
70+
* [Build & Run by shell script](./shell.md)
7171
# Deployment
7272
[Deployment Guide](https://tronprotocol.github.io/documentation-en/developers/deployment/)
7373
walks the user through how to deploy a FullNode and an SR node.

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: 44 additions & 31 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");
@@ -346,19 +350,23 @@ private void create()
346350
long energyLimit;
347351
// according to version
348352

349-
if (StorageUtils.getEnergyLimitHardFork()) {
350-
if (callValue < 0) {
351-
throw new ContractValidateException("callValue must be >= 0");
352-
}
353-
if (tokenValue < 0) {
354-
throw new ContractValidateException("tokenValue must be >= 0");
355-
}
356-
if (newSmartContract.getOriginEnergyLimit() <= 0) {
357-
throw new ContractValidateException("The originEnergyLimit must be > 0");
358-
}
359-
energyLimit = getAccountEnergyLimitWithFixRatio(creator, feeLimit, callValue);
353+
if (isConstantCall) {
354+
energyLimit = CommonParameter.getInstance().maxEnergyLimitForConstant;
360355
} else {
361-
energyLimit = getAccountEnergyLimitWithFloatRatio(creator, feeLimit, callValue);
356+
if (StorageUtils.getEnergyLimitHardFork()) {
357+
if (callValue < 0) {
358+
throw new ContractValidateException("callValue must be >= 0");
359+
}
360+
if (tokenValue < 0) {
361+
throw new ContractValidateException("tokenValue must be >= 0");
362+
}
363+
if (newSmartContract.getOriginEnergyLimit() <= 0) {
364+
throw new ContractValidateException("The originEnergyLimit must be > 0");
365+
}
366+
energyLimit = getAccountEnergyLimitWithFixRatio(creator, feeLimit, callValue);
367+
} else {
368+
energyLimit = getAccountEnergyLimitWithFloatRatio(creator, feeLimit, callValue);
369+
}
362370
}
363371

364372
checkTokenValueAndId(tokenValue, tokenId);
@@ -377,6 +385,9 @@ private void create()
377385
vmShouldEndInUs, energyLimit);
378386
this.vm = new VM();
379387
this.program = new Program(ops, programInvoke, rootInternalTransaction, vmConfig);
388+
if (VMConfig.allowTvmCompatibleEvm()) {
389+
this.program.setContractVersion(1);
390+
}
380391
byte[] txId = TransactionUtil.getTransactionId(trx).getBytes();
381392
this.program.setRootTransactionId(txId);
382393
if (enableEventListener && isCheckTransaction()) {
@@ -459,7 +470,6 @@ private void call()
459470

460471
byte[] code = repository.getCode(contractAddress);
461472
if (isNotEmpty(code)) {
462-
463473
long feeLimit = trx.getRawData().getFeeLimit();
464474
if (feeLimit < 0 || feeLimit > repository.getDynamicPropertiesStore().getMaxFeeLimit()) {
465475
logger.info("invalid feeLimit {}", feeLimit);
@@ -469,7 +479,7 @@ private void call()
469479
AccountCapsule caller = repository.getAccount(callerAddress);
470480
long energyLimit;
471481
if (isConstantCall) {
472-
energyLimit = VMConstant.ENERGY_LIMIT_IN_CONSTANT_TX;
482+
energyLimit = CommonParameter.getInstance().maxEnergyLimitForConstant;
473483
} else {
474484
AccountCapsule creator = repository
475485
.getAccount(deployedContract.getInstance().getOriginAddress().toByteArray());
@@ -492,6 +502,9 @@ private void call()
492502
this.vm = new VM();
493503
rootInternalTransaction = new InternalTransaction(trx, trxType);
494504
this.program = new Program(code, programInvoke, rootInternalTransaction, vmConfig);
505+
if (VMConfig.allowTvmCompatibleEvm()) {
506+
this.program.setContractVersion(deployedContract.getContractVersion());
507+
}
495508
byte[] txId = TransactionUtil.getTransactionId(trx).getBytes();
496509
this.program.setRootTransactionId(txId);
497510

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)