-
Notifications
You must be signed in to change notification settings - Fork 1.6k
feat(vm): implement TIP-7823 #6611
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
base: develop
Are you sure you want to change the base?
Changes from all commits
443ada0
4e1eef4
8dd8e7d
708c9b1
a8fa3d4
0663e17
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 |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| package org.tron.common.runtime.vm; | ||
|
|
||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.apache.commons.lang3.tuple.Pair; | ||
| import org.junit.Assert; | ||
| import org.junit.Test; | ||
| import org.tron.common.utils.ByteUtil; | ||
| import org.tron.core.vm.PrecompiledContracts; | ||
| import org.tron.core.vm.config.ConfigLoader; | ||
| import org.tron.core.vm.config.VMConfig; | ||
|
|
||
| @Slf4j | ||
| public class AllowTvmOsakaTest extends VMTestBase { | ||
|
Contributor
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. The current test only covers two cases: all-zero lengths (valid) and an oversized baseLen (invalid). Please add the following cases: baseLen == 1024 → should succeed (boundary value) All limits exceeded while allowTvmOsaka is disabled → should succeed (no restriction applied)
Author
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. Thanks for the review! All suggested test cases have been added in the latest commit:
Also added a helper method toLenBytes(int) for cleaner ABI-encoded length construction. All tests pass locally. |
||
|
|
||
| private static final PrecompiledContracts.PrecompiledContract modExp = | ||
| new PrecompiledContracts.ModExp(); | ||
|
|
||
| private static byte[] toLenBytes(int value) { | ||
| byte[] b = new byte[32]; | ||
| b[28] = (byte) ((value >> 24) & 0xFF); | ||
| b[29] = (byte) ((value >> 16) & 0xFF); | ||
| b[30] = (byte) ((value >> 8) & 0xFF); | ||
| b[31] = (byte) (value & 0xFF); | ||
| return b; | ||
| } | ||
|
|
||
| @Test | ||
| public void testEIP7823() { | ||
| ConfigLoader.disable = true; | ||
| VMConfig.initAllowTvmOsaka(1); | ||
|
|
||
| try { | ||
| // all-zero lengths: should succeed | ||
| Pair<Boolean, byte[]> result = modExp.execute( | ||
| ByteUtil.merge(toLenBytes(0), toLenBytes(0), toLenBytes(0))); | ||
| Assert.assertTrue(result.getLeft()); | ||
|
|
||
| // baseLen == 1024: boundary, should succeed | ||
| result = modExp.execute( | ||
| ByteUtil.merge(toLenBytes(1024), toLenBytes(0), toLenBytes(0))); | ||
| Assert.assertTrue(result.getLeft()); | ||
|
|
||
| // baseLen == 1025: just over the limit, should fail | ||
| result = modExp.execute( | ||
| ByteUtil.merge(toLenBytes(1025), toLenBytes(0), toLenBytes(0))); | ||
| Assert.assertFalse(result.getLeft()); | ||
|
|
||
| // oversized expLen only: should fail | ||
| result = modExp.execute( | ||
| ByteUtil.merge(toLenBytes(0), toLenBytes(1025), toLenBytes(0))); | ||
| Assert.assertFalse(result.getLeft()); | ||
|
|
||
| // oversized modLen only: should fail | ||
| result = modExp.execute( | ||
| ByteUtil.merge(toLenBytes(0), toLenBytes(0), toLenBytes(1025))); | ||
| Assert.assertFalse(result.getLeft()); | ||
| } finally { | ||
| VMConfig.initAllowTvmOsaka(0); | ||
| ConfigLoader.disable = false; | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void testEIP7823DisabledShouldPass() { | ||
| ConfigLoader.disable = true; | ||
| VMConfig.initAllowTvmOsaka(0); | ||
|
|
||
| try { | ||
| // all limits exceeded while osaka is disabled: should succeed (no restriction) | ||
| Pair<Boolean, byte[]> result = modExp.execute( | ||
| ByteUtil.merge(toLenBytes(2048), toLenBytes(2048), toLenBytes(2048))); | ||
| Assert.assertTrue(result.getLeft()); | ||
| } finally { | ||
| ConfigLoader.disable = false; | ||
| } | ||
| } | ||
| } | ||
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.
Hey @ouy95917, just a quick curiosity question here — is there a specific calculation or reasoning behind why baseLen, expLen, and modLen are each capped at 1024 bytes specifically? I'm wondering whether this was driven by cryptographic practicality (e.g., covering RSA-8192 as the largest real-world key size), or some other consideration from the EIP authors. Any context you can share — or a pointer to the relevant EIP discussion thread — would be greatly appreciated. Thanks!
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.
The 1024-byte (8192-bit) limit was mainly driven by cryptographic practicality — it covers RSA keys up to 8192 bits, which is the largest size used in practice. Ethereum's on-chain analysis (~7 years of mainnet data) confirmed the max observed input was only 513 bytes, so 1024 gives plenty of headroom.
There's a more detailed discussion on this in the TIP issue: tronprotocol/tips#826 — covers the rationale, error semantics, security background, etc. Worth a read if you're interested.