-
Notifications
You must be signed in to change notification settings - Fork 6
Feat/merge 4.8.1.1 #131
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/merge 4.8.1.1 #131
Changes from all commits
45e3bf8
25b35f5
44a4bc8
87baada
ddd8c7b
30752bf
a45af58
144571a
d5d9f46
52d7d9d
a79693e
bb3312c
a18e0f3
2d783f3
a358e7f
63832e1
3de20f7
0a2abbe
2d71a45
a1a2a1d
bcb5faf
edb96ef
5a638b3
d375c30
10017f0
c402a43
43c85c9
8c51311
9e8bd69
d2f74bd
67aaf4c
4b00429
5c036cf
0916635
3353eb6
fe467de
65f8ac2
4ecdf33
33fd47a
a069c81
30b1c26
545d3be
7b94819
77b4a66
444884d
93f0931
6d1dc00
0791a7c
6a9dee4
e993fef
23ef376
b4d565c
98e5f7a
10528e6
41e6a91
cc7da22
2e9feef
aaeaf28
e4b46de
97adae3
5ad5605
b7f1bab
454396e
6419ab0
856f94a
6151ab0
c08488e
c8aa6a1
262f93f
546c3fa
ff493cd
011a8b3
1467c4c
ad236f6
d750a28
563443b
bb52fe4
69d2e5b
f90a3af
35178cd
3a7356b
83c3ed4
3b14b8f
24e9492
2d332a4
360b778
ecc776d
41411c8
49a99dd
5649c6b
171f8cc
65f03dc
838ead8
1809e5c
edf87da
fa4fb7f
41b9d97
102440c
ff3c613
c4be43a
ef16da8
fac5cc8
5297ee3
9cf9380
5e2c462
6bf8a50
00723b3
baa2a2e
dc220ac
01bfeb3
050ecff
47ae465
c0cf561
0b56775
48d3761
64338af
df446d3
9c2d556
cc680b9
06e435d
9693b27
ad7ee75
65b76e4
d4c7faa
463eddd
3f12f50
28c825e
d977604
65a7fb1
6c5926a
4bc641e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,7 +29,8 @@ public enum ForkBlockVersionEnum { | |
| VERSION_4_8_0(32, 1596780000000L, 80), | ||
| VERSION_4_8_0_1(33, 1596780000000L, 70), | ||
| VERSION_4_8_1(34, 1596780000000L, 80), | ||
| VERSION_4_8_2(35, 1596780000000L, 80); | ||
| VERSION_4_8_1_1(35, 1596780000000L, 70), | ||
| VERSION_4_8_2(36, 1596780000000L, 80); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Because Useful? React with 👍 / 👎. |
||
| // if add a version, modify BLOCK_VERSION simultaneously | ||
|
|
||
| @Getter | ||
|
|
@@ -78,7 +79,7 @@ public class ChainConstant { | |
| public static final int SINGLE_REPEAT = 1; | ||
| public static final int BLOCK_FILLED_SLOTS_NUMBER = 128; | ||
| public static final int MAX_FROZEN_NUMBER = 1; | ||
| public static final int BLOCK_VERSION = 35; | ||
| public static final int BLOCK_VERSION = 36; | ||
| public static final long FROZEN_PERIOD = 86_400_000L; | ||
| public static final long DELEGATE_PERIOD = 3 * 86_400_000L; | ||
| public static final long TRX_PRECISION = 1000_000L; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,177 @@ | ||
| package org.tron.common.runtime.vm; | ||
|
|
||
| import java.util.Arrays; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.apache.commons.lang3.tuple.Pair; | ||
| import org.junit.AfterClass; | ||
| import org.junit.Assert; | ||
| import org.junit.Before; | ||
| import org.junit.BeforeClass; | ||
| import org.junit.Test; | ||
| import org.tron.common.BaseTest; | ||
| import org.tron.common.parameter.CommonParameter; | ||
| import org.tron.common.runtime.InternalTransaction; | ||
| import org.tron.common.utils.ForkController; | ||
| import org.tron.core.Constant; | ||
| import org.tron.core.config.Parameter.ForkBlockVersionEnum; | ||
| import org.tron.core.config.args.Args; | ||
| import org.tron.core.exception.ContractValidateException; | ||
| import org.tron.core.store.StoreFactory; | ||
| import org.tron.core.vm.PrecompiledContracts; | ||
| import org.tron.core.vm.PrecompiledContracts.PrecompiledContract; | ||
| import org.tron.core.vm.config.ConfigLoader; | ||
| import org.tron.core.vm.config.VMConfig; | ||
| import org.tron.core.vm.program.Program; | ||
| import org.tron.core.vm.program.Program.OutOfTimeException; | ||
| import org.tron.core.vm.program.invoke.ProgramInvokeMockImpl; | ||
| import org.tron.core.vm.utils.MUtil; | ||
| import org.tron.protos.Protocol; | ||
|
|
||
|
|
||
| @Slf4j | ||
| public class Create2ModExpForkTest extends BaseTest { | ||
|
|
||
| // mirrors the private Program.MAX_DEPTH | ||
| private static final int MAX_CALL_DEPTH = 64; | ||
|
|
||
| // mirrors PrecompiledContracts.ModExp.UPPER_BOUND | ||
| private static final int MOD_EXP_UPPER_BOUND = 1024; | ||
|
|
||
| // ModExp precompile address (0x05) | ||
| private static final DataWord MOD_EXP_ADDR = new DataWord( | ||
| "0000000000000000000000000000000000000000000000000000000000000005"); | ||
|
|
||
| @BeforeClass | ||
| public static void init() { | ||
| Args.setParam(new String[] {"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); | ||
| CommonParameter.getInstance().setDebug(true); | ||
| } | ||
|
|
||
| @AfterClass | ||
| public static void destroy() { | ||
| ConfigLoader.disable = false; | ||
| VMConfig.initVmHardFork(false); | ||
| VMConfig.initAllowTvmCompatibleEvm(0); | ||
| Args.clearParam(); | ||
| } | ||
|
|
||
| @Before | ||
| public void setUp() { | ||
| ForkController.instance().init(chainBaseManager); | ||
| deactivateFork(ForkBlockVersionEnum.VERSION_4_8_1_1); | ||
| } | ||
|
|
||
| @Test | ||
| public void checkCPUTimeForCreate2_isGatedByFork() { | ||
| MUtil.checkCPUTimeForCreate2(); | ||
|
|
||
| activateFork(ForkBlockVersionEnum.VERSION_4_8_1_1); | ||
|
|
||
| OutOfTimeException ex = | ||
| Assert.assertThrows(OutOfTimeException.class, MUtil::checkCPUTimeForCreate2); | ||
| Assert.assertEquals("CPU timeout for create2 executing", ex.getMessage()); | ||
| } | ||
|
|
||
| @Test | ||
| public void checkCPUTimeForModExp_isGatedByFork() { | ||
| MUtil.checkCPUTimeForModExp(); | ||
|
|
||
| activateFork(ForkBlockVersionEnum.VERSION_4_8_1_1); | ||
|
|
||
| OutOfTimeException ex = | ||
| Assert.assertThrows(OutOfTimeException.class, MUtil::checkCPUTimeForModExp); | ||
| Assert.assertEquals("CPU timeout for modExp executing", ex.getMessage()); | ||
| } | ||
|
|
||
| @Test | ||
| public void modExp_degenerateInput_throwsOnlyAfterFork() { | ||
| PrecompiledContract modExp = PrecompiledContracts.getContractForAddress(MOD_EXP_ADDR); | ||
| byte[] data = buildModExpInput(MOD_EXP_UPPER_BOUND + 1); | ||
|
|
||
| Pair<Boolean, byte[]> out = modExp.execute(data); | ||
| Assert.assertTrue(out.getLeft()); | ||
|
|
||
| activateFork(ForkBlockVersionEnum.VERSION_4_8_1_1); | ||
|
|
||
| OutOfTimeException ex = | ||
| Assert.assertThrows(OutOfTimeException.class, () -> modExp.execute(data)); | ||
| Assert.assertEquals("CPU timeout for modExp executing", ex.getMessage()); | ||
| } | ||
|
|
||
| @Test | ||
| public void modExp_atUpperBound_doesNotThrowAfterFork() { | ||
| activateFork(ForkBlockVersionEnum.VERSION_4_8_1_1); | ||
|
|
||
| PrecompiledContract modExp = PrecompiledContracts.getContractForAddress(MOD_EXP_ADDR); | ||
| Pair<Boolean, byte[]> out = modExp.execute(buildModExpInput(MOD_EXP_UPPER_BOUND)); | ||
| Assert.assertTrue(out.getLeft()); | ||
| } | ||
|
|
||
| @Test | ||
| public void createContract2_atMaxDepth_legacyPath_throwsAfterFork() | ||
| throws ContractValidateException { | ||
| VMConfig.initAllowTvmCompatibleEvm(0); | ||
| activateFork(ForkBlockVersionEnum.VERSION_4_8_1_1); | ||
|
|
||
| Program program = buildProgramAtMaxDepth(); | ||
| OutOfTimeException ex = Assert.assertThrows(OutOfTimeException.class, | ||
| () -> program.createContract2( | ||
| DataWord.ZERO(), DataWord.ZERO(), DataWord.ZERO(), DataWord.ZERO())); | ||
| Assert.assertEquals("CPU timeout for create2 executing", ex.getMessage()); | ||
| } | ||
|
|
||
| @Test | ||
| public void createContract2_atMaxDepth_compatibleEvmOn_doesNotThrow() | ||
| throws ContractValidateException { | ||
| VMConfig.initAllowTvmCompatibleEvm(1); | ||
| activateFork(ForkBlockVersionEnum.VERSION_4_8_1_1); | ||
|
|
||
| Program program = buildProgramAtMaxDepth(); | ||
| program.createContract2(DataWord.ZERO(), DataWord.ZERO(), DataWord.ZERO(), DataWord.ZERO()); | ||
| Assert.assertEquals(DataWord.ZERO(), program.getStack().pop()); | ||
| } | ||
|
|
||
| // ---- helpers --------------------------------------------------------------------------------- | ||
|
|
||
| private Program buildProgramAtMaxDepth() throws ContractValidateException { | ||
| StoreFactory.init(); | ||
| StoreFactory storeFactory = StoreFactory.getInstance(); | ||
| storeFactory.setChainBaseManager(chainBaseManager); | ||
| byte[] ops = new byte[] {0}; | ||
| ProgramInvokeMockImpl invoke = new ProgramInvokeMockImpl(storeFactory, ops, ops) { | ||
| @Override | ||
| public int getCallDeep() { | ||
| return MAX_CALL_DEPTH; | ||
| } | ||
| }; | ||
| Program program = new Program(ops, ops, invoke, | ||
| new InternalTransaction(Protocol.Transaction.getDefaultInstance(), | ||
| InternalTransaction.TrxType.TRX_UNKNOWN_TYPE)); | ||
| program.setRootTransactionId(new byte[32]); | ||
| return program; | ||
| } | ||
|
|
||
| private byte[] buildModExpInput(int expLen) { | ||
| byte[] data = new byte[96]; | ||
| byte[] expLenWord = new DataWord(expLen).getData(); | ||
| System.arraycopy(expLenWord, 0, data, 32, 32); | ||
| return data; | ||
| } | ||
|
|
||
| private void activateFork(ForkBlockVersionEnum forkVersion) { | ||
| byte[] stats = new byte[27]; | ||
| Arrays.fill(stats, (byte) 1); | ||
| chainBaseManager.getDynamicPropertiesStore().statsByVersion(forkVersion.getValue(), stats); | ||
| long maintenanceTimeInterval = | ||
| chainBaseManager.getDynamicPropertiesStore().getMaintenanceTimeInterval(); | ||
| long hardForkTime = ((forkVersion.getHardForkTime() - 1) / maintenanceTimeInterval + 1) | ||
| * maintenanceTimeInterval; | ||
| chainBaseManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(hardForkTime + 1); | ||
| } | ||
|
|
||
| private void deactivateFork(ForkBlockVersionEnum forkVersion) { | ||
| chainBaseManager.getDynamicPropertiesStore() | ||
| .statsByVersion(forkVersion.getValue(), new byte[27]); | ||
| chainBaseManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(0L); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
ALLOW_TVM_OSAKAis enabled after the 4.8.2 fork,VERSION_4_8_1_1will also have passed, so calldata withbaseLen == 0,modLen == 0, andexpLen > 1024now throwsOutOfTimeExceptionhere before reaching the Osaka branch that should returnPair.of(false, EMPTY_BYTE_ARRAY)for oversized lengths. That changes the TIP-7823/Osaka behavior for this input from a failed precompile call to an exceptional CPU-time abort; move the Osaka length rejection ahead of this legacy timeout check or skip the timeout when Osaka is active.Useful? React with 👍 / 👎.