Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tvm): implement TIP-650&TIP-651 #5886

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,21 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
}
break;
}
case ALLOW_TVM_CANCUN: {
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_8_0)) {
throw new ContractValidateException(
"Bad chain parameter id [ALLOW_TVM_CANCUN]");
}
if (dynamicPropertiesStore.getAllowTvmCancun() == 1) {
throw new ContractValidateException(
"[ALLOW_TVM_CANCUN] has been valid, no need to propose again");
}
if (value != 1) {
throw new ContractValidateException(
"This value[ALLOW_TVM_CANCUN] is only allowed to be 1");
}
break;
}
default:
break;
}
Expand Down Expand Up @@ -857,7 +872,8 @@ public enum ProposalType { // current value, value range
MAX_DELEGATE_LOCK_PERIOD(78), // (86400, 10512000]
ALLOW_OLD_REWARD_OPT(79), // 0, 1
ALLOW_ENERGY_ADJUSTMENT(81), // 0, 1
MAX_CREATE_ACCOUNT_TX_SIZE(82); // [500, 10000]
MAX_CREATE_ACCOUNT_TX_SIZE(82), // [500, 10000]
ALLOW_TVM_CANCUN(83); // 0, 1

private long code;

Expand Down
22 changes: 22 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 @@ -57,6 +57,8 @@ public class EnergyCost {
private static final long SUICIDE = 0;
private static final long STOP = 0;
private static final long CREATE_DATA = 200;
private static final long TLOAD = 100;
private static final long TSTORE = 100;

public static long getZeroTierCost(Program ignored) {
return ZERO_TIER;
Expand Down Expand Up @@ -232,6 +234,26 @@ public static long getSstoreCost(Program program) {

}

public static long getTLoadCost(Program ignored) {
return TLOAD;
}

public static long getTStoreCost(Program ignored) {
return TSTORE;
}

public static long getMCopyCost(Program program) {
Stack stack = program.getStack();
long oldMemSize = program.getMemSize();

int dstOffset = stack.peek().intValue();
int srcOffset = stack.get(stack.size() - 2).intValue();
DataWord maxOffset = new DataWord(Math.max(dstOffset, srcOffset));
return VERY_LOW_TIER + calcMemEnergy(oldMemSize,
memNeeded(maxOffset, stack.get(stack.size() - 3)),
stack.get(stack.size() - 3).longValueSafe(), Op.MCOPY);
}

public static long getLogCost(Program program) {
Stack stack = program.getStack();
long oldMemSize = program.getMemSize();
Expand Down
6 changes: 6 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/Op.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ public class Op {
// (0x5a) Get the amount of available gas
public static final int GAS = 0x5a;
public static final int JUMPDEST = 0x5b;
// (0x5c) Load word from transient storage
public static final int TLOAD = 0x5c;
// (0x5d) Save word to transient storage
public static final int TSTORE = 0x5d;
// (0x5e) Copy word from memory
public static final int MCOPY = 0x5e;

/* Push Operations */
// Place item on stack
Expand Down
31 changes: 31 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 @@ -643,6 +643,37 @@ public static void jumpDestAction(Program program) {
program.step();
}

public static void tLoadAction(Program program) {
DataWord key = program.stackPop();
DataWord address = program.getContractAddress();

byte[] data =
program.getContractState().getTransientStorageValue(address.getData(), key.getData());
DataWord value = data != null ? new DataWord(data) : DataWord.ZERO();

program.stackPush(value);
program.step();
}

public static void tStoreAction(Program program) {
DataWord key = program.stackPop();
DataWord value = program.stackPop();
DataWord address = program.getContractAddress();

program.getContractState()
.updateTransientStorageValue(address.getData(), key.getData(), value.getData());
program.step();
}

public static void mCopyAction(Program program) {
int dstOffset = program.stackPop().intValueSafe();
int srcOffset = program.stackPop().intValueSafe();
int length = program.stackPop().intValueSafe();

program.memoryCopy(dstOffset, srcOffset, length);
program.step();
}

public static void push0Action(Program program) {
program.stackPush(DataWord.ZERO());
program.step();
Expand Down
32 changes: 31 additions & 1 deletion actuator/src/main/java/org/tron/core/vm/OperationRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public enum Version {
TRON_V1_1,
TRON_V1_2,
TRON_V1_3,
TRON_V1_4,
// add more
// TRON_V2,
// ETH
Expand All @@ -24,6 +25,7 @@ public enum Version {
tableMap.put(Version.TRON_V1_1, newTronV11OperationSet());
tableMap.put(Version.TRON_V1_2, newTronV12OperationSet());
tableMap.put(Version.TRON_V1_3, newTronV13OperationSet());
tableMap.put(Version.TRON_V1_4, newTronV14OperationSet());
}

public static JumpTable newTronV10OperationSet() {
Expand Down Expand Up @@ -55,12 +57,18 @@ public static JumpTable newTronV13OperationSet() {
return table;
}

public static JumpTable newTronV14OperationSet() {
JumpTable table = newTronV13OperationSet();
appendCancunOperations(table);
return table;
}

// Just for warming up class to avoid out_of_time
public static void init() {}

public static JumpTable getTable() {
// always get the table which has the newest version
JumpTable table = tableMap.get(Version.TRON_V1_3);
JumpTable table = tableMap.get(Version.TRON_V1_4);

// next make the corresponding changes, exclude activating opcode
if (VMConfig.allowHigherLimitForMaxCpuTimeOfOneTx()) {
Expand Down Expand Up @@ -652,4 +660,26 @@ public static void adjustForFairEnergy(JumpTable table) {
EnergyCost::getSuicideCost2,
OperationActions::suicideAction));
}

public static void appendCancunOperations(JumpTable table) {
BooleanSupplier proposal = VMConfig::allowTvmCancun;

table.set(new Operation(
Op.TLOAD, 1, 1,
EnergyCost::getTLoadCost,
OperationActions::tLoadAction,
proposal));

table.set(new Operation(
Op.TSTORE, 2, 0,
EnergyCost::getTStoreCost,
OperationActions::tStoreAction,
proposal));

table.set(new Operation(
Op.MCOPY, 3, 0,
EnergyCost::getMCopyCost,
OperationActions::mCopyAction,
proposal));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public static void load(StoreFactory storeFactory) {
VMConfig.initDynamicEnergyMaxFactor(ds.getDynamicEnergyMaxFactor());
VMConfig.initAllowTvmShangHai(ds.getAllowTvmShangHai());
VMConfig.initAllowEnergyAdjustment(ds.getAllowEnergyAdjustment());
VMConfig.initAllowTvmCancun(ds.getAllowTvmCancun());
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/config/VMConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public class VMConfig {

private static boolean ALLOW_ENERGY_ADJUSTMENT = false;

private static boolean ALLOW_TVM_CANCUN = false;

private VMConfig() {
}

Expand Down Expand Up @@ -142,6 +144,10 @@ public static void initAllowEnergyAdjustment(long allow) {
ALLOW_ENERGY_ADJUSTMENT = allow == 1;
}

public static void initAllowTvmCancun(long allow) {
ALLOW_TVM_CANCUN = allow == 1;
}

public static boolean getEnergyLimitHardFork() {
return CommonParameter.ENERGY_LIMIT_HARD_FORK;
}
Expand Down Expand Up @@ -221,4 +227,8 @@ public static boolean allowTvmShanghai() {
public static boolean allowEnergyAdjustment() {
return ALLOW_ENERGY_ADJUSTMENT;
}

public static boolean allowTvmCancun() {
return ALLOW_TVM_CANCUN;
}
}
15 changes: 15 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 @@ -229,6 +229,11 @@ public void putDelegatedResourceAccountIndex(Key key, Value value) {
repository.putDelegatedResourceAccountIndex(key, value);
}

@Override
public void putTransientStorageValue(Key address, Key key, Value value) {
repository.putTransientStorageValue(address, key, value);
}

@Override
public long addTokenBalance(byte[] address, byte[] tokenId, long value) {
return repository.addTokenBalance(address, tokenId, value);
Expand Down Expand Up @@ -314,6 +319,11 @@ public DelegatedResourceAccountIndexCapsule getDelegatedResourceAccountIndex(byt
return repository.getDelegatedResourceAccountIndex(key);
}

@Override
public byte[] getTransientStorageValue(byte[] address, byte[] key) {
return repository.getTransientStorageValue(address, key);
}

@Override
public void updateDynamicProperty(byte[] word, BytesCapsule bytesCapsule) {
repository.updateDynamicProperty(word, bytesCapsule);
Expand Down Expand Up @@ -354,6 +364,11 @@ public void updateDelegatedResourceAccountIndex(byte[] word, DelegatedResourceAc
repository.updateDelegatedResourceAccountIndex(word, delegatedResourceAccountIndexCapsule);
}

@Override
public void updateTransientStorageValue(byte[] address, byte[] key, byte[] value) {
repository.updateTransientStorageValue(address, key, value);
}

@Override
public void putDynamicProperty(Key key, Value value) {
repository.putDynamicProperty(key, value);
Expand Down
8 changes: 8 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/program/Memory.java
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ public List<byte[]> getChunks() {
return new LinkedList<>(chunks);
}

public void copy(int destPos, int srcPos, int size) {
if (size <= 0) {
return;
}
byte[] data = read(srcPos, size);
write(destPos, data, size, false);
}

private int captureMax(int chunkIndex, int chunkOffset, int size, byte[] src, int srcPos) {

byte[] chunk = chunks.get(chunkIndex);
Expand Down
4 changes: 4 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/program/Program.java
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,10 @@ public byte[] memoryChunk(int offset, int size) {
return memory.read(offset, size);
}

public void memoryCopy(int dst, int src, int size) {
memory.copy(dst, src, size);
}

/**
* . Allocates extra memory in the program for a specified size, calculated from a given offset
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public interface Repository {

DelegatedResourceAccountIndexCapsule getDelegatedResourceAccountIndex(byte[] key);

byte[] getTransientStorageValue(byte[] address, byte[] key);

void deleteContract(byte[] address);

void createContract(byte[] address, ContractCapsule contractCapsule);
Expand Down Expand Up @@ -71,6 +73,8 @@ public interface Repository {

void updateDelegatedResourceAccountIndex(byte[] word, DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule);

void updateTransientStorageValue(byte[] address, byte[] key, byte[] value);

void saveCode(byte[] address, byte[] code);

byte[] getCode(byte[] address);
Expand Down Expand Up @@ -113,6 +117,8 @@ public interface Repository {

void putDelegatedResourceAccountIndex(Key key, Value value);

void putTransientStorageValue(Key address, Key key, Value value);

long addTokenBalance(byte[] address, byte[] tokenId, long value);

long getTokenBalance(byte[] address, byte[] tokenId);
Expand Down
Loading
Loading