Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
243 changes: 131 additions & 112 deletions README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
import java.util.List;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.tron.common.math.StrictMathWrapper;
import org.tron.common.utils.DecodeUtil;
import org.tron.core.capsule.AccountCapsule;
import org.tron.core.capsule.AssetIssueCapsule;
import org.tron.core.capsule.TransactionResultCapsule;
import org.tron.core.config.Parameter.ForkBlockVersionEnum;
import org.tron.core.exception.BalanceInsufficientException;
import org.tron.core.exception.ContractExeException;
import org.tron.core.exception.ContractValidateException;
Expand Down Expand Up @@ -263,6 +265,16 @@ public boolean validate() throws ContractValidateException {
"frozenDuration must be less than " + maxFrozenSupplyTime + " days "
+ "and more than " + minFrozenSupplyTime + " days");
}
// make sure FrozenSupply.expireTime not overflow
if (chainBaseManager.getForkController().pass(ForkBlockVersionEnum.VERSION_4_8_1)) {
long frozenPeriod = next.getFrozenDays() * FROZEN_PERIOD;
try {
StrictMathWrapper.addExact(assetIssueContract.getStartTime(), frozenPeriod);
} catch (ArithmeticException e) {
throw new ContractValidateException(
"Start time and frozen days would cause expire time overflow");
}
}
remainSupply -= next.getFrozenAmount();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import java.util.Map;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.tron.common.parameter.CommonParameter;
import org.tron.common.utils.DecodeUtil;
import org.tron.common.utils.StringUtil;
import org.tron.core.capsule.ProposalCapsule;
Expand Down Expand Up @@ -53,7 +52,7 @@ public boolean execute(Object result) throws ContractExeException {

long currentMaintenanceTime =
chainBaseManager.getDynamicPropertiesStore().getNextMaintenanceTime();
long now3 = now + CommonParameter.getInstance().getProposalExpireTime();
long now3 = now + chainBaseManager.getDynamicPropertiesStore().getProposalExpireTime();
long round = (now3 - currentMaintenanceTime) / maintenanceTimeInterval;
long expirationTime =
currentMaintenanceTime + (round + 1) * maintenanceTimeInterval;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,28 +170,27 @@ private void executeShielded(List<SpendDescription> spends, List<ReceiveDescript
}
nullifierStore.put(new BytesCapsule(spend.getNullifier().toByteArray()));
}
if (CommonParameter.getInstance().isFullNodeAllowShieldedTransactionArgs()) {
IncrementalMerkleTreeContainer currentMerkle = merkleContainer.getCurrentMerkle();

IncrementalMerkleTreeContainer currentMerkle = merkleContainer.getCurrentMerkle();
try {
currentMerkle.wfcheck();
} catch (ZksnarkException e) {
ret.setStatus(fee, code.FAILED);
ret.setShieldedTransactionFee(fee);
throw new ContractExeException(e.getMessage());
}
//handle receives
for (ReceiveDescription receive : receives) {
try {
currentMerkle.wfcheck();
merkleContainer
.saveCmIntoMerkleTree(currentMerkle, receive.getNoteCommitment().toByteArray());
} catch (ZksnarkException e) {
ret.setStatus(fee, code.FAILED);
ret.setStatus(0, code.FAILED);
ret.setShieldedTransactionFee(fee);
throw new ContractExeException(e.getMessage());
}
//handle receives
for (ReceiveDescription receive : receives) {
try {
merkleContainer
.saveCmIntoMerkleTree(currentMerkle, receive.getNoteCommitment().toByteArray());
} catch (ZksnarkException e) {
ret.setStatus(0, code.FAILED);
ret.setShieldedTransactionFee(fee);
throw new ContractExeException(e.getMessage());
}
}
merkleContainer.setCurrentMerkle(currentMerkle);
}
merkleContainer.setCurrentMerkle(currentMerkle);
}

@Override
Expand Down Expand Up @@ -236,8 +235,7 @@ public boolean validate() throws ContractValidateException {
throw new ContractValidateException("duplicate sapling nullifiers in this transaction");
}
nfSet.add(spendDescription.getNullifier());
if (CommonParameter.getInstance().isFullNodeAllowShieldedTransactionArgs()
&& !merkleContainer.merkleRootExist(spendDescription.getAnchor().toByteArray())) {
if (!merkleContainer.merkleRootExist(spendDescription.getAnchor().toByteArray())) {
throw new ContractValidateException("Rt is invalid.");
}
if (nullifierStore.has(spendDescription.getNullifier().toByteArray())) {
Expand Down
38 changes: 36 additions & 2 deletions actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import static org.tron.core.Constant.CREATE_ACCOUNT_TRANSACTION_MIN_BYTE_SIZE;
import static org.tron.core.Constant.DYNAMIC_ENERGY_INCREASE_FACTOR_RANGE;
import static org.tron.core.Constant.DYNAMIC_ENERGY_MAX_FACTOR_RANGE;
import static org.tron.core.Constant.MAX_PROPOSAL_EXPIRE_TIME;
import static org.tron.core.Constant.MIN_PROPOSAL_EXPIRE_TIME;
import static org.tron.core.config.Parameter.ChainConstant.ONE_YEAR_BLOCK_NUMBERS;

import org.tron.common.utils.ForkController;
Expand Down Expand Up @@ -354,7 +356,8 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
break;
}
case ALLOW_MARKET_TRANSACTION: {
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_1)) {
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_1)
|| forkController.pass(ForkBlockVersionEnum.VERSION_4_8_1)) {
throw new ContractValidateException(
"Bad chain parameter id [ALLOW_MARKET_TRANSACTION]");
}
Expand Down Expand Up @@ -839,6 +842,35 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
}
break;
}
case ALLOW_TVM_SELFDESTRUCT_RESTRICTION: {
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_8_1)) {
throw new ContractValidateException(
"Bad chain parameter id [ALLOW_TVM_SELFDESTRUCT_RESTRICTION]");
}
if (dynamicPropertiesStore.allowTvmSelfdestructRestriction()) {
throw new ContractValidateException(
"[ALLOW_TVM_SELFDESTRUCT_RESTRICTION] has been valid, no need to propose again");
}
if (value != 1) {
throw new ContractValidateException(
"This value[ALLOW_TVM_SELFDESTRUCT_RESTRICTION] is only allowed to be 1");
}
break;
}
case PROPOSAL_EXPIRE_TIME: {
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_8_1)) {
throw new ContractValidateException(
"Bad chain parameter id [PROPOSAL_EXPIRE_TIME]");
}
if (value <= MIN_PROPOSAL_EXPIRE_TIME
|| value >= MAX_PROPOSAL_EXPIRE_TIME) {
throw new ContractValidateException(
"This value[PROPOSAL_EXPIRE_TIME] is only allowed to be greater than "
+ MIN_PROPOSAL_EXPIRE_TIME + " and less than "
+ MAX_PROPOSAL_EXPIRE_TIME + "!");
}
break;
}
default:
break;
}
Expand Down Expand Up @@ -921,7 +953,9 @@ public enum ProposalType { // current value, value range
ALLOW_TVM_CANCUN(83), // 0, 1
ALLOW_STRICT_MATH(87), // 0, 1
CONSENSUS_LOGIC_OPTIMIZATION(88), // 0, 1
ALLOW_TVM_BLOB(89); // 0, 1
ALLOW_TVM_BLOB(89), // 0, 1
PROPOSAL_EXPIRE_TIME(92), // (0, 31536003000)
ALLOW_TVM_SELFDESTRUCT_RESTRICTION(94); // 0, 1

private long code;

Expand Down
9 changes: 9 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/EnergyCost.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public class EnergyCost {
private static final long EXT_CODE_SIZE = 20;
private static final long EXT_CODE_HASH = 400;
private static final long SUICIDE = 0;
private static final long SUICIDE_V2 = 5000;
private static final long STOP = 0;
private static final long CREATE_DATA = 200;
private static final long TLOAD = 100;
Expand Down Expand Up @@ -289,6 +290,14 @@ public static long getSuicideCost2(Program program) {
return getSuicideCost(program);
}

public static long getSuicideCost3(Program program) {
DataWord inheritorAddress = program.getStack().peek();
if (isDeadAccount(program, inheritorAddress)) {
return SUICIDE_V2 + NEW_ACCT_CALL;
}
return SUICIDE_V2;
}

public static long getBalanceCost(Program ignored) {
return BALANCE;
}
Expand Down
15 changes: 15 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/OperationActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -1072,4 +1072,19 @@ public static void suicideAction(Program program) {
program.stop();
}

public static void suicideAction2(Program program) {
if (program.isStaticCall()) {
throw new Program.StaticCallModificationException();
}

if (!program.canSuicide2()) {
program.getResult().setRevert();
} else {
DataWord address = program.stackPop();
program.suicide2(address);
}

program.stop();
}

}
11 changes: 11 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/OperationRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ public static JumpTable getTable() {
adjustForFairEnergy(table);
}

if (VMConfig.allowTvmSelfdestructRestriction()) {
adjustSelfdestruct(table);
}

return table;
}

Expand Down Expand Up @@ -695,4 +699,11 @@ public static void appendCancunOperations(JumpTable table) {
OperationActions::blobBaseFeeAction,
tvmBlobProposal));
}

public static void adjustSelfdestruct(JumpTable table) {
table.set(new Operation(
Op.SUICIDE, 1, 0,
EnergyCost::getSuicideCost3,
OperationActions::suicideAction2));
}
}
56 changes: 40 additions & 16 deletions actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static org.tron.common.utils.ByteUtil.parseWord;
import static org.tron.common.utils.ByteUtil.stripLeadingZeroes;
import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION;
import static org.tron.core.vm.VMConstant.SIG_LENGTH;

import com.google.protobuf.ByteString;

Expand All @@ -41,6 +42,7 @@
import org.apache.commons.lang3.tuple.Triple;
import org.tron.common.crypto.Blake2bfMessageDigest;
import org.tron.common.crypto.Hash;
import org.tron.common.crypto.Rsv;
import org.tron.common.crypto.SignUtils;
import org.tron.common.crypto.SignatureInterface;
import org.tron.common.crypto.zksnark.BN128;
Expand Down Expand Up @@ -201,7 +203,7 @@ public class PrecompiledContracts {
public static PrecompiledContract getOptimizedContractForConstant(PrecompiledContract contract) {
try {
Constructor<?> constructor = contract.getClass().getDeclaredConstructor();
return (PrecompiledContracts.PrecompiledContract) constructor.newInstance();
return (PrecompiledContracts.PrecompiledContract) constructor.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down Expand Up @@ -352,22 +354,13 @@ private static byte[] encodeMultiRes(byte[]... words) {
}

private static byte[] recoverAddrBySign(byte[] sign, byte[] hash) {
byte v;
byte[] r;
byte[] s;
byte[] out = null;
if (ArrayUtils.isEmpty(sign) || sign.length < 65) {
return new byte[0];
}
try {
r = Arrays.copyOfRange(sign, 0, 32);
s = Arrays.copyOfRange(sign, 32, 64);
v = sign[64];
if (v < 27) {
v += 27;
}

SignatureInterface signature = SignUtils.fromComponents(r, s, v,
Rsv rsv = Rsv.fromSignature(sign);
SignatureInterface signature = SignUtils.fromComponents(rsv.getR(), rsv.getS(), rsv.getV(),
CommonParameter.getInstance().isECKeyCryptoEngine());
if (signature.validateComponents()) {
out = SignUtils.signatureToAddress(hash, signature,
Expand Down Expand Up @@ -403,6 +396,20 @@ private static byte[][] extractBytesArray(DataWord[] words, int offset, byte[] d
return bytesArray;
}

private static byte[][] extractSigArray(DataWord[] words, int offset, byte[] data) {
if (offset > words.length - 1) {
return new byte[0][];
}
int len = words[offset].intValueSafe();
byte[][] bytesArray = new byte[len][];
for (int i = 0; i < len; i++) {
int bytesOffset = words[offset + i + 1].intValueSafe() / WORD_SIZE;
bytesArray[i] = extractBytes(data, (bytesOffset + offset + 2) * WORD_SIZE,
SIG_LENGTH);
}
return bytesArray;
}

private static byte[] extractBytes(byte[] data, int offset, int len) {
return Arrays.copyOfRange(data, offset, offset + len);
}
Expand Down Expand Up @@ -944,8 +951,15 @@ public Pair<Boolean, byte[]> execute(byte[] rawData) {
byte[] hash = Sha256Hash.hash(CommonParameter
.getInstance().isECKeyCryptoEngine(), combine);

byte[][] signatures = extractBytesArray(
words, words[3].intValueSafe() / WORD_SIZE, rawData);
if (VMConfig.allowTvmSelfdestructRestriction()) {
int sigArraySize = words[words[3].intValueSafe() / WORD_SIZE].intValueSafe();
if (sigArraySize > MAX_SIZE) {
return Pair.of(true, DATA_FALSE);
}
}
byte[][] signatures = VMConfig.allowTvmSelfdestructRestriction() ?
extractSigArray(words, words[3].intValueSafe() / WORD_SIZE, rawData) :
extractBytesArray(words, words[3].intValueSafe() / WORD_SIZE, rawData);

if (signatures.length == 0 || signatures.length > MAX_SIZE) {
return Pair.of(true, DATA_FALSE);
Expand Down Expand Up @@ -1029,8 +1043,18 @@ private Pair<Boolean, byte[]> doExecute(byte[] data)
throws InterruptedException, ExecutionException {
DataWord[] words = DataWord.parseArray(data);
byte[] hash = words[0].getData();
byte[][] signatures = extractBytesArray(
words, words[1].intValueSafe() / WORD_SIZE, data);

if (VMConfig.allowTvmSelfdestructRestriction()) {
int sigArraySize = words[words[1].intValueSafe() / WORD_SIZE].intValueSafe();
int addrArraySize = words[words[2].intValueSafe() / WORD_SIZE].intValueSafe();
if (sigArraySize > MAX_SIZE || addrArraySize > MAX_SIZE) {
return Pair.of(true, DATA_FALSE);
}
}

byte[][] signatures = VMConfig.allowTvmSelfdestructRestriction() ?
extractSigArray(words, words[1].intValueSafe() / WORD_SIZE, data) :
extractBytesArray(words, words[1].intValueSafe() / WORD_SIZE, data);
byte[][] addresses = extractBytes32Array(
words, words[2].intValueSafe() / WORD_SIZE);
int cnt = signatures.length;
Expand Down
5 changes: 4 additions & 1 deletion actuator/src/main/java/org/tron/core/vm/VM.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ public static void play(Program program, JumpTable jumpTable) {
} catch (JVMStackOverFlowException | OutOfTimeException e) {
throw e;
} catch (RuntimeException e) {
if (StringUtils.isEmpty(e.getMessage())) {
// https://openjdk.org/jeps/358
// https://bugs.openjdk.org/browse/JDK-8220715
// since jdk 14, the NullPointerExceptions message is not empty
if (e instanceof NullPointerException || StringUtils.isEmpty(e.getMessage())) {
logger.warn("Unknown Exception occurred, tx id: {}",
Hex.toHexString(program.getRootTransactionId()), e);
program.setRuntimeFailure(new RuntimeException("Unknown Exception"));
Expand Down
1 change: 1 addition & 0 deletions actuator/src/main/java/org/tron/core/vm/VMConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public class VMConstant {

public static final int CONTRACT_NAME_LENGTH = 32;
public static final int MIN_TOKEN_ID = 1_000_000;
public static final int SIG_LENGTH = 65;

// Numbers
public static final int ONE_HUNDRED = 100;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public static void load(StoreFactory storeFactory) {
VMConfig.initAllowTvmCancun(ds.getAllowTvmCancun());
VMConfig.initDisableJavaLangMath(ds.getConsensusLogicOptimization());
VMConfig.initAllowTvmBlob(ds.getAllowTvmBlob());
VMConfig.initAllowTvmSelfdestructRestriction(ds.getAllowTvmSelfdestructRestriction());
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/program/ContractState.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ public void updateContractState(byte[] address, ContractStateCapsule contractSta
repository.updateContractState(address, contractStateCapsule);
}

@Override
public void putNewContract(byte[] address) {
repository.putNewContract(address);
}

@Override
public boolean isNewContract(byte[] address) {
return repository.isNewContract(address);
}

@Override
public void updateAccount(byte[] address, AccountCapsule accountCapsule) {
repository.updateAccount(address, accountCapsule);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public void write(int address, byte[] data, int dataSize, boolean limited) {

public void extendAndWrite(int address, int allocSize, byte[] data) {
extend(address, allocSize);
write(address, data, data.length, false);
write(address, data, allocSize, false);
}

public void extend(int address, int size) {
Expand Down
Loading
Loading