Skip to content

Commit 6de76fb

Browse files
Merge pull request #6185 from raymondliu0711/feature/vm_cancun_opcodes
feat(tvm): implement TIP-650&TIP-651
2 parents 9f42782 + 60364ab commit 6de76fb

File tree

19 files changed

+291
-1
lines changed

19 files changed

+291
-1
lines changed

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,21 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
809809
}
810810
break;
811811
}
812+
case ALLOW_TVM_CANCUN: {
813+
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_8_0)) {
814+
throw new ContractValidateException(
815+
"Bad chain parameter id [ALLOW_TVM_CANCUN]");
816+
}
817+
if (dynamicPropertiesStore.getAllowTvmCancun() == 1) {
818+
throw new ContractValidateException(
819+
"[ALLOW_TVM_CANCUN] has been valid, no need to propose again");
820+
}
821+
if (value != 1) {
822+
throw new ContractValidateException(
823+
"This value[ALLOW_TVM_CANCUN] is only allowed to be 1");
824+
}
825+
break;
826+
}
812827
default:
813828
break;
814829
}
@@ -888,6 +903,7 @@ public enum ProposalType { // current value, value range
888903
ALLOW_OLD_REWARD_OPT(79), // 0, 1
889904
ALLOW_ENERGY_ADJUSTMENT(81), // 0, 1
890905
MAX_CREATE_ACCOUNT_TX_SIZE(82), // [500, 10000]
906+
ALLOW_TVM_CANCUN(83), // 0, 1
891907
ALLOW_STRICT_MATH(87), // 0, 1
892908
CONSENSUS_LOGIC_OPTIMIZATION(88); // 0, 1
893909

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public class EnergyCost {
5757
private static final long SUICIDE = 0;
5858
private static final long STOP = 0;
5959
private static final long CREATE_DATA = 200;
60+
private static final long TLOAD = 100;
61+
private static final long TSTORE = 100;
6062

6163
public static long getZeroTierCost(Program ignored) {
6264
return ZERO_TIER;
@@ -232,6 +234,26 @@ public static long getSstoreCost(Program program) {
232234

233235
}
234236

237+
public static long getTLoadCost(Program ignored) {
238+
return TLOAD;
239+
}
240+
241+
public static long getTStoreCost(Program ignored) {
242+
return TSTORE;
243+
}
244+
245+
public static long getMCopyCost(Program program) {
246+
Stack stack = program.getStack();
247+
long oldMemSize = program.getMemSize();
248+
249+
int dstOffset = stack.peek().intValue();
250+
int srcOffset = stack.get(stack.size() - 2).intValue();
251+
DataWord maxOffset = new DataWord(Math.max(dstOffset, srcOffset));
252+
return VERY_LOW_TIER + calcMemEnergy(oldMemSize,
253+
memNeeded(maxOffset, stack.get(stack.size() - 3)),
254+
stack.get(stack.size() - 3).longValueSafe(), Op.MCOPY);
255+
}
256+
235257
public static long getLogCost(Program program) {
236258
Stack stack = program.getStack();
237259
long oldMemSize = program.getMemSize();

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,12 @@ public class Op {
145145
// (0x5a) Get the amount of available gas
146146
public static final int GAS = 0x5a;
147147
public static final int JUMPDEST = 0x5b;
148+
// (0x5c) Load word from transient storage
149+
public static final int TLOAD = 0x5c;
150+
// (0x5d) Save word to transient storage
151+
public static final int TSTORE = 0x5d;
152+
// (0x5e) Copy word from memory
153+
public static final int MCOPY = 0x5e;
148154

149155
/* Push Operations */
150156
// Place item on stack

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,37 @@ public static void jumpDestAction(Program program) {
643643
program.step();
644644
}
645645

646+
public static void tLoadAction(Program program) {
647+
DataWord key = program.stackPop();
648+
DataWord address = program.getContractAddress();
649+
650+
byte[] data =
651+
program.getContractState().getTransientStorageValue(address.getData(), key.getData());
652+
DataWord value = data != null ? new DataWord(data) : DataWord.ZERO();
653+
654+
program.stackPush(value);
655+
program.step();
656+
}
657+
658+
public static void tStoreAction(Program program) {
659+
DataWord key = program.stackPop();
660+
DataWord value = program.stackPop();
661+
DataWord address = program.getContractAddress();
662+
663+
program.getContractState()
664+
.updateTransientStorageValue(address.getData(), key.getData(), value.getData());
665+
program.step();
666+
}
667+
668+
public static void mCopyAction(Program program) {
669+
int dstOffset = program.stackPop().intValueSafe();
670+
int srcOffset = program.stackPop().intValueSafe();
671+
int length = program.stackPop().intValueSafe();
672+
673+
program.memoryCopy(dstOffset, srcOffset, length);
674+
program.step();
675+
}
676+
646677
public static void push0Action(Program program) {
647678
program.stackPush(DataWord.ZERO());
648679
program.step();

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public enum Version {
1212
TRON_V1_1,
1313
TRON_V1_2,
1414
TRON_V1_3,
15+
TRON_V1_4,
1516
// add more
1617
// TRON_V2,
1718
// ETH
@@ -24,6 +25,7 @@ public enum Version {
2425
tableMap.put(Version.TRON_V1_1, newTronV11OperationSet());
2526
tableMap.put(Version.TRON_V1_2, newTronV12OperationSet());
2627
tableMap.put(Version.TRON_V1_3, newTronV13OperationSet());
28+
tableMap.put(Version.TRON_V1_4, newTronV14OperationSet());
2729
}
2830

2931
public static JumpTable newTronV10OperationSet() {
@@ -55,12 +57,18 @@ public static JumpTable newTronV13OperationSet() {
5557
return table;
5658
}
5759

60+
public static JumpTable newTronV14OperationSet() {
61+
JumpTable table = newTronV13OperationSet();
62+
appendCancunOperations(table);
63+
return table;
64+
}
65+
5866
// Just for warming up class to avoid out_of_time
5967
public static void init() {}
6068

6169
public static JumpTable getTable() {
6270
// always get the table which has the newest version
63-
JumpTable table = tableMap.get(Version.TRON_V1_3);
71+
JumpTable table = tableMap.get(Version.TRON_V1_4);
6472

6573
// next make the corresponding changes, exclude activating opcode
6674
if (VMConfig.allowHigherLimitForMaxCpuTimeOfOneTx()) {
@@ -652,4 +660,26 @@ public static void adjustForFairEnergy(JumpTable table) {
652660
EnergyCost::getSuicideCost2,
653661
OperationActions::suicideAction));
654662
}
663+
664+
public static void appendCancunOperations(JumpTable table) {
665+
BooleanSupplier proposal = VMConfig::allowTvmCancun;
666+
667+
table.set(new Operation(
668+
Op.TLOAD, 1, 1,
669+
EnergyCost::getTLoadCost,
670+
OperationActions::tLoadAction,
671+
proposal));
672+
673+
table.set(new Operation(
674+
Op.TSTORE, 2, 0,
675+
EnergyCost::getTStoreCost,
676+
OperationActions::tStoreAction,
677+
proposal));
678+
679+
table.set(new Operation(
680+
Op.MCOPY, 3, 0,
681+
EnergyCost::getMCopyCost,
682+
OperationActions::mCopyAction,
683+
proposal));
684+
}
655685
}

actuator/src/main/java/org/tron/core/vm/config/ConfigLoader.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public static void load(StoreFactory storeFactory) {
4141
VMConfig.initAllowTvmShangHai(ds.getAllowTvmShangHai());
4242
VMConfig.initAllowEnergyAdjustment(ds.getAllowEnergyAdjustment());
4343
VMConfig.initAllowStrictMath(ds.getAllowStrictMath());
44+
VMConfig.initAllowTvmCancun(ds.getAllowTvmCancun());
4445
}
4546
}
4647
}

actuator/src/main/java/org/tron/core/vm/config/VMConfig.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public class VMConfig {
5353

5454
private static boolean ALLOW_STRICT_MATH = false;
5555

56+
private static boolean ALLOW_TVM_CANCUN = false;
57+
5658
private VMConfig() {
5759
}
5860

@@ -148,6 +150,10 @@ public static void initAllowStrictMath(long allow) {
148150
ALLOW_STRICT_MATH = allow == 1;
149151
}
150152

153+
public static void initAllowTvmCancun(long allow) {
154+
ALLOW_TVM_CANCUN = allow == 1;
155+
}
156+
151157
public static boolean getEnergyLimitHardFork() {
152158
return CommonParameter.ENERGY_LIMIT_HARD_FORK;
153159
}
@@ -231,4 +237,8 @@ public static boolean allowEnergyAdjustment() {
231237
public static boolean allowStrictMath() {
232238
return ALLOW_STRICT_MATH;
233239
}
240+
241+
public static boolean allowTvmCancun() {
242+
return ALLOW_TVM_CANCUN;
243+
}
234244
}

actuator/src/main/java/org/tron/core/vm/program/ContractState.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,11 @@ public void putDelegatedResourceAccountIndex(Key key, Value value) {
229229
repository.putDelegatedResourceAccountIndex(key, value);
230230
}
231231

232+
@Override
233+
public void putTransientStorageValue(Key address, Key key, Value value) {
234+
repository.putTransientStorageValue(address, key, value);
235+
}
236+
232237
@Override
233238
public long addTokenBalance(byte[] address, byte[] tokenId, long value) {
234239
return repository.addTokenBalance(address, tokenId, value);
@@ -314,6 +319,11 @@ public DelegatedResourceAccountIndexCapsule getDelegatedResourceAccountIndex(byt
314319
return repository.getDelegatedResourceAccountIndex(key);
315320
}
316321

322+
@Override
323+
public byte[] getTransientStorageValue(byte[] address, byte[] key) {
324+
return repository.getTransientStorageValue(address, key);
325+
}
326+
317327
@Override
318328
public void updateDynamicProperty(byte[] word, BytesCapsule bytesCapsule) {
319329
repository.updateDynamicProperty(word, bytesCapsule);
@@ -354,6 +364,11 @@ public void updateDelegatedResourceAccountIndex(byte[] word, DelegatedResourceAc
354364
repository.updateDelegatedResourceAccountIndex(word, delegatedResourceAccountIndexCapsule);
355365
}
356366

367+
@Override
368+
public void updateTransientStorageValue(byte[] address, byte[] key, byte[] value) {
369+
repository.updateTransientStorageValue(address, key, value);
370+
}
371+
357372
@Override
358373
public void putDynamicProperty(Key key, Value value) {
359374
repository.putDynamicProperty(key, value);

actuator/src/main/java/org/tron/core/vm/program/Memory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,14 @@ public List<byte[]> getChunks() {
181181
return new LinkedList<>(chunks);
182182
}
183183

184+
public void copy(int destPos, int srcPos, int size) {
185+
if (size <= 0) {
186+
return;
187+
}
188+
byte[] data = read(srcPos, size);
189+
write(destPos, data, size, false);
190+
}
191+
184192
private int captureMax(int chunkIndex, int chunkOffset, int size, byte[] src, int srcPos) {
185193

186194
byte[] chunk = chunks.get(chunkIndex);

actuator/src/main/java/org/tron/core/vm/program/Program.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,10 @@ public byte[] memoryChunk(int offset, int size) {
429429
return memory.read(offset, size);
430430
}
431431

432+
public void memoryCopy(int dst, int src, int size) {
433+
memory.copy(dst, src, size);
434+
}
435+
432436
/**
433437
* . Allocates extra memory in the program for a specified size, calculated from a given offset
434438
*

0 commit comments

Comments
 (0)