Skip to content

Commit 979567e

Browse files
Merge pull request #6232 from raymondliu0711/feature/add_blob_opcodes
feat(tvm): add blob opcodes and kzg precompile contract
2 parents fa23379 + a6bf35c commit 979567e

File tree

29 files changed

+17351
-1
lines changed

29 files changed

+17351
-1
lines changed

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,21 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
824824
}
825825
break;
826826
}
827+
case ALLOW_TVM_BLOB: {
828+
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_8_0)) {
829+
throw new ContractValidateException(
830+
"Bad chain parameter id [ALLOW_TVM_BLOB]");
831+
}
832+
if (dynamicPropertiesStore.getAllowTvmBlob() == 1) {
833+
throw new ContractValidateException(
834+
"[ALLOW_TVM_BLOB] has been valid, no need to propose again");
835+
}
836+
if (value != 1) {
837+
throw new ContractValidateException(
838+
"This value[ALLOW_TVM_BLOB] is only allowed to be 1");
839+
}
840+
break;
841+
}
827842
default:
828843
break;
829844
}
@@ -905,7 +920,8 @@ public enum ProposalType { // current value, value range
905920
MAX_CREATE_ACCOUNT_TX_SIZE(82), // [500, 10000]
906921
ALLOW_TVM_CANCUN(83), // 0, 1
907922
ALLOW_STRICT_MATH(87), // 0, 1
908-
CONSENSUS_LOGIC_OPTIMIZATION(88); // 0, 1
923+
CONSENSUS_LOGIC_OPTIMIZATION(88), // 0, 1
924+
ALLOW_TVM_BLOB(89); // 0, 1
909925

910926
private long code;
911927

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ public class Op {
120120
public static final int SELFBALANCE = 0x47;
121121
// (0x48) Get block's basefee
122122
public static final int BASEFEE = 0x48;
123+
// (0x49) Get blob hash
124+
public static final int BLOBHASH = 0x49;
125+
// (0x4a) Get block's blob basefee
126+
public static final int BLOBBASEFEE = 0x4a;
123127

124128
/* Memory, Storage and Flow Operations */
125129
// (0x50) Remove item from stack

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,17 @@ public static void mCopyAction(Program program) {
677677
program.step();
678678
}
679679

680+
public static void blobHashAction(Program program) {
681+
program.stackPop();
682+
program.stackPush(DataWord.ZERO());
683+
program.step();
684+
}
685+
686+
public static void blobBaseFeeAction(Program program) {
687+
program.stackPush(DataWord.ZERO());
688+
program.step();
689+
}
690+
680691
public static void push0Action(Program program) {
681692
program.stackPush(DataWord.ZERO());
682693
program.step();

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ public static void adjustForFairEnergy(JumpTable table) {
663663

664664
public static void appendCancunOperations(JumpTable table) {
665665
BooleanSupplier proposal = VMConfig::allowTvmCancun;
666+
BooleanSupplier tvmBlobProposal = VMConfig::allowTvmBlob;
666667

667668
table.set(new Operation(
668669
Op.TLOAD, 1, 1,
@@ -681,5 +682,17 @@ public static void appendCancunOperations(JumpTable table) {
681682
EnergyCost::getMCopyCost,
682683
OperationActions::mCopyAction,
683684
proposal));
685+
686+
table.set(new Operation(
687+
Op.BLOBHASH, 1, 1,
688+
EnergyCost::getVeryLowTierCost,
689+
OperationActions::blobHashAction,
690+
tvmBlobProposal));
691+
692+
table.set(new Operation(
693+
Op.BLOBBASEFEE, 0, 1,
694+
EnergyCost::getBaseTierCost,
695+
OperationActions::blobBaseFeeAction,
696+
tvmBlobProposal));
684697
}
685698
}

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package org.tron.core.vm;
22

33
import static java.util.Arrays.copyOfRange;
4+
import static org.tron.common.crypto.ckzg4844.CKZG4844JNI.BLS_MODULUS;
5+
import static org.tron.common.crypto.ckzg4844.CKZG4844JNI.FIELD_ELEMENTS_PER_BLOB;
46
import static org.tron.common.math.Maths.max;
57
import static org.tron.common.math.Maths.min;
68
import static org.tron.common.runtime.vm.DataWord.WORD_SIZE;
@@ -32,6 +34,7 @@
3234
import java.util.concurrent.ExecutorService;
3335
import java.util.concurrent.Future;
3436
import java.util.concurrent.TimeUnit;
37+
import org.tron.common.crypto.ckzg4844.CKZG4844JNI;
3538
import lombok.AllArgsConstructor;
3639
import lombok.Getter;
3740
import lombok.Setter;
@@ -104,6 +107,7 @@ public class PrecompiledContracts {
104107

105108
private static final EthRipemd160 ethRipemd160 = new EthRipemd160();
106109
private static final Blake2F blake2F = new Blake2F();
110+
private static final KZGPointEvaluation kzgPointEvaluation = new KZGPointEvaluation();
107111

108112
// FreezeV2 PrecompileContracts
109113
private static final GetChainParameter getChainParameter = new GetChainParameter();
@@ -198,6 +202,9 @@ public class PrecompiledContracts {
198202
private static final DataWord blake2FAddr = new DataWord(
199203
"0000000000000000000000000000000000000000000000000000000000020009");
200204

205+
private static final DataWord kzgPointEvaluationAddr = new DataWord(
206+
"000000000000000000000000000000000000000000000000000000000002000a");
207+
201208
public static PrecompiledContract getOptimizedContractForConstant(PrecompiledContract contract) {
202209
try {
203210
Constructor<?> constructor = contract.getClass().getDeclaredConstructor();
@@ -279,6 +286,9 @@ public static PrecompiledContract getContractForAddress(DataWord address) {
279286
if (VMConfig.allowTvmCompatibleEvm() && address.equals(blake2FAddr)) {
280287
return blake2F;
281288
}
289+
if (VMConfig.allowTvmBlob() && address.equals(kzgPointEvaluationAddr)) {
290+
return kzgPointEvaluation;
291+
}
282292

283293
if (VMConfig.allowTvmFreezeV2()) {
284294
if (address.equals(getChainParameterAddr)) {
@@ -2191,4 +2201,49 @@ public Pair<Boolean, byte[]> execute(byte[] data) {
21912201
}
21922202
}
21932203

2204+
public static class KZGPointEvaluation extends PrecompiledContract {
2205+
2206+
private static final int BLOB_VERIFY_INPUT_LENGTH = 192;
2207+
private static final byte BLOB_COMMITMENT_VERSION_KZG = 0x01;
2208+
private static final byte[] BLOB_PRECOMPILED_RETURN_VALUE =
2209+
ByteUtil.merge(ByteUtil.longTo32Bytes(FIELD_ELEMENTS_PER_BLOB),
2210+
ByteUtil.bigIntegerToBytes(BLS_MODULUS, 32));
2211+
2212+
@Override
2213+
public long getEnergyForData(byte[] data) {
2214+
return 50000;
2215+
}
2216+
2217+
@Override
2218+
public Pair<Boolean, byte[]> execute(byte[] data) {
2219+
if (data == null || data.length != BLOB_VERIFY_INPUT_LENGTH) {
2220+
return Pair.of(false, DataWord.ZERO().getData());
2221+
}
2222+
2223+
byte[] versionedHash = parseBytes(data, 0, 32);
2224+
byte[] z = parseBytes(data, 32, 32);
2225+
byte[] y = parseBytes(data, 64, 32);
2226+
byte[] commitment = parseBytes(data, 96, 48);
2227+
byte[] proof = parseBytes(data, 144, 48);
2228+
2229+
byte[] hash = Sha256Hash.hash(
2230+
CommonParameter.getInstance().isECKeyCryptoEngine(), commitment);
2231+
hash[0] = BLOB_COMMITMENT_VERSION_KZG;
2232+
if (!Arrays.equals(versionedHash, hash)) {
2233+
return Pair.of(false, DataWord.ZERO().getData());
2234+
}
2235+
2236+
try {
2237+
if (CKZG4844JNI.verifyKzgProof(commitment, z, y, proof)) {
2238+
return Pair.of(true, BLOB_PRECOMPILED_RETURN_VALUE);
2239+
} else {
2240+
return Pair.of(false, DataWord.ZERO().getData());
2241+
}
2242+
} catch (RuntimeException exception) {
2243+
logger.warn("KZG point evaluation precompile contract failed", exception);
2244+
return Pair.of(false, DataWord.ZERO().getData());
2245+
}
2246+
}
2247+
}
2248+
21942249
}

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
@@ -43,6 +43,7 @@ public static void load(StoreFactory storeFactory) {
4343
VMConfig.initAllowStrictMath(ds.getAllowStrictMath());
4444
VMConfig.initAllowTvmCancun(ds.getAllowTvmCancun());
4545
VMConfig.initDisableJavaLangMath(ds.getConsensusLogicOptimization());
46+
VMConfig.initAllowTvmBlob(ds.getAllowTvmBlob());
4647
}
4748
}
4849
}

chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking<BytesCapsule>
230230

231231
private static final byte[] ALLOW_TVM_CANCUN = "ALLOW_TVM_CANCUN".getBytes();
232232

233+
private static final byte[] ALLOW_TVM_BLOB = "ALLOW_TVM_BLOB".getBytes();
234+
233235
@Autowired
234236
private DynamicPropertiesStore(@Value("properties") String dbName) {
235237
super(dbName);
@@ -2933,6 +2935,17 @@ public long getAllowTvmCancun() {
29332935
.orElse(CommonParameter.getInstance().getAllowTvmCancun());
29342936
}
29352937

2938+
public void saveAllowTvmBlob(long allowTvmBlob) {
2939+
this.put(ALLOW_TVM_BLOB, new BytesCapsule(ByteArray.fromLong(allowTvmBlob)));
2940+
}
2941+
2942+
public long getAllowTvmBlob() {
2943+
return Optional.ofNullable(getUnchecked(ALLOW_TVM_BLOB))
2944+
.map(BytesCapsule::getData)
2945+
.map(ByteArray::toLong)
2946+
.orElse(CommonParameter.getInstance().getAllowTvmBlob());
2947+
}
2948+
29362949
private static class DynamicResourceProperties {
29372950

29382951
private static final byte[] ONE_DAY_NET_LIMIT = "ONE_DAY_NET_LIMIT".getBytes();

common/src/main/java/org/tron/common/parameter/CommonParameter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,10 @@ public class CommonParameter {
713713
@Setter
714714
public long allowTvmCancun;
715715

716+
@Getter
717+
@Setter
718+
public long allowTvmBlob;
719+
716720
private static double calcMaxTimeRatio() {
717721
//return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1)));
718722
return 5.0;

common/src/main/java/org/tron/core/Constant.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,4 +401,6 @@ public class Constant {
401401
= "committee.consensusLogicOptimization";
402402

403403
public static final String COMMITTEE_ALLOW_TVM_CANCUN = "committee.allowTvmCancun";
404+
405+
public static final String COMMITTEE_ALLOW_TVM_BLOB = "committee.allowTvmBlob";
404406
}

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

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

5858
private static Boolean DISABLE_JAVA_LANG_MATH = false;
5959

60+
private static boolean ALLOW_TVM_BLOB = false;
61+
6062
private VMConfig() {
6163
}
6264

@@ -160,6 +162,10 @@ public static void initDisableJavaLangMath(long allow) {
160162
DISABLE_JAVA_LANG_MATH = allow == 1;
161163
}
162164

165+
public static void initAllowTvmBlob(long allow) {
166+
ALLOW_TVM_BLOB = allow == 1;
167+
}
168+
163169
public static boolean getEnergyLimitHardFork() {
164170
return CommonParameter.ENERGY_LIMIT_HARD_FORK;
165171
}
@@ -251,4 +257,8 @@ public static boolean allowTvmCancun() {
251257
public static boolean disableJavaLangMath() {
252258
return DISABLE_JAVA_LANG_MATH;
253259
}
260+
261+
public static boolean allowTvmBlob() {
262+
return ALLOW_TVM_BLOB;
263+
}
254264
}

0 commit comments

Comments
 (0)