Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
191 commits
Select commit Hold shift + click to select a range
5f7c663
feat(chainbase): add archive state collector
bladehan1 Jul 17, 2026
86efea7
feat(chainbase): persist archive block history
bladehan1 Jul 17, 2026
2607d4f
feat(chainbase): add scalable state archive
bladehan1 Aug 18, 2026
b8a56b8
feat(block): add offline block file tools
bladehan1 Aug 14, 2026
500a50b
feat(block): add offline block replay
bladehan1 Aug 14, 2026
78745bf
fix(block): flush replay snapshot tail
bladehan1 Aug 14, 2026
a82975e
feat(block): add resumable HTTP export
bladehan1 Aug 18, 2026
303c28b
fix(block): parse large HTTP block ranges
bladehan1 Aug 18, 2026
c12bb71
feat(block): replay consecutive block chunks
bladehan1 Aug 19, 2026
d070a47
feat(chainbase): persist archive recovery state
bladehan1 Aug 19, 2026
5ddb88a
feat(chainbase): pin archive engine generations
bladehan1 Aug 19, 2026
5702e77
feat(chainbase): publish archive recovery state
bladehan1 Aug 19, 2026
e20ce4f
feat(chainbase): coordinate archive recovery
bladehan1 Aug 20, 2026
b45e7ea
feat(chainbase): capture archive mutations
bladehan1 Aug 20, 2026
cb3dd60
test(chainbase): cover archive capture recovery
bladehan1 Aug 20, 2026
6a64182
test(chainbase): cover consecutive archive targets
bladehan1 Aug 20, 2026
afff315
feat(chainbase): own archive block projections
bladehan1 Aug 20, 2026
cb7c2d0
refactor(chainbase): exclude abi from archive state
bladehan1 Aug 20, 2026
aaae524
test(chainbase): cover archive projection ownership
bladehan1 Aug 20, 2026
730cfe9
feat(chainbase): seal archive flush receipts
bladehan1 Aug 20, 2026
966c216
test(chainbase): cover durable flush sealing
bladehan1 Aug 20, 2026
d0fd12e
test(chainbase): assert legacy asset freeze
bladehan1 Aug 20, 2026
ac6d5af
feat(chainbase): bind archive exact-26 scope
bladehan1 Aug 20, 2026
fc70854
test(chainbase): reject stale archive scopes
bladehan1 Aug 20, 2026
f73a2cf
refactor(chainbase): centralize archive scope identity
bladehan1 Aug 20, 2026
dc9bee4
feat(chainbase): bind archive progress scope
bladehan1 Aug 20, 2026
87c2223
feat(chainbase): bind serving generation scope
bladehan1 Aug 20, 2026
4ade822
feat(chainbase): add P66 asset archive codec
bladehan1 Aug 20, 2026
acb5078
refactor(chainbase): unify P66 asset projection codec
bladehan1 Aug 20, 2026
72223e4
feat(chainbase): bind p66 phase to mutation plans
bladehan1 Aug 20, 2026
0d3573f
feat(chainbase): integrate archive startup recovery
bladehan1 Aug 21, 2026
b9ce207
feat(chainbase): integrate archive normal flush
bladehan1 Aug 21, 2026
e4b93c8
feat(chainbase): bootstrap archive base
bladehan1 Aug 21, 2026
34792e4
fix(chainbase): align archive source set
bladehan1 Aug 21, 2026
6b49efb
fix(chainbase): bind archive flush topology
bladehan1 Aug 21, 2026
953f07f
feat(chainbase): support multi-target archive flush
bladehan1 Aug 21, 2026
97a4781
fix(chainbase): bind batched flush topology
bladehan1 Aug 21, 2026
6014cab
feat(chainbase): add path state commitment codec
bladehan1 Aug 21, 2026
fc53dd0
feat(chainbase): add path-addressed trie core
bladehan1 Aug 21, 2026
c929b85
feat(chainbase): aggregate path state roots
bladehan1 Aug 21, 2026
55dfa14
feat(chainbase): validate path state mutations
bladehan1 Aug 21, 2026
6389928
test(chainbase): verify path state engines
bladehan1 Aug 21, 2026
482d892
feat(chainbase): define path state participants
bladehan1 Aug 21, 2026
a307844
feat(chainbase): canonicalize path state values
bladehan1 Aug 21, 2026
adebb07
feat(chainbase): bind path state transitions
bladehan1 Aug 21, 2026
0e3ba6b
feat(chainbase): define path state persistence
bladehan1 Aug 21, 2026
24a05a0
feat(chainbase): persist path state authority
bladehan1 Aug 21, 2026
a488379
feat(chainbase): add native path node stores
bladehan1 Aug 21, 2026
47ac8f3
feat(chainbase): batch path state progress
bladehan1 Aug 21, 2026
2a7ac71
feat(chainbase): recover path state base
bladehan1 Aug 21, 2026
fe2d928
feat(chainbase): restore durable path leaves
bladehan1 Aug 21, 2026
eeb28ef
feat(chainbase): inherit path state layers
bladehan1 Aug 21, 2026
cd2379d
feat(chainbase): recover path state layers
bladehan1 Aug 21, 2026
6b9e7e6
feat(chainbase): bound path state layers
bladehan1 Aug 21, 2026
a230298
feat(chainbase): switch path state ancestry
bladehan1 Aug 21, 2026
559d0ca
feat(chainbase): retire path state forks
bladehan1 Aug 22, 2026
9ce2c23
test(chainbase): guard current-only path state
bladehan1 Aug 22, 2026
6c01f51
feat(chainbase): integrate native archive lifecycle
bladehan1 Aug 25, 2026
983ae8d
test(chainbase): remove legacy archive coverage
bladehan1 Aug 25, 2026
4af8a1f
test(chainbase): cover native archive lifecycle
bladehan1 Aug 25, 2026
548018e
fix(common): handle short market price keys
bladehan1 Aug 25, 2026
685a520
fix(chainbase): guard archive readable state
bladehan1 Aug 25, 2026
9083436
feat(chainbase): add bounded archive range index
bladehan1 Aug 25, 2026
b4e75aa
feat(framework): add archive startup diagnostics
bladehan1 Aug 25, 2026
0cb79c7
feat(chainbase): add exact archive serving index
bladehan1 Aug 26, 2026
af9e5fc
feat(chainbase): add path state rebuild coordinator
bladehan1 Aug 27, 2026
dc334b3
feat(chainbase): add path state native snapshot source
bladehan1 Aug 27, 2026
91224ef
feat(chainbase): validate path state p66 layout
bladehan1 Aug 27, 2026
4a00563
feat(chainbase): resume path state rebuild
bladehan1 Aug 27, 2026
85ce728
feat(chainbase): add path state catch-up queue
bladehan1 Aug 27, 2026
44fcb02
perf(trie): update path state nodes locally
bladehan1 Aug 27, 2026
15c8bae
perf(trie): store layer node deltas
bladehan1 Aug 27, 2026
692face
perf(trie): store layer leaf deltas
bladehan1 Aug 27, 2026
8ec1f83
perf(trie): reuse immutable parent state
bladehan1 Aug 27, 2026
061ae62
feat(trie): own committed snapshot head
bladehan1 Aug 27, 2026
386b919
feat(trie): prepare state transition in memory
bladehan1 Aug 27, 2026
9e9e9f1
test(trie): verify rebuild with oracle
bladehan1 Aug 27, 2026
5f946fd
feat(config): admit path state root startup
bladehan1 Aug 27, 2026
2c28be0
feat(db): attach path state root startup
bladehan1 Aug 27, 2026
792b109
feat(db): rebuild path state root on startup
bladehan1 Aug 27, 2026
ced0fa2
feat(db): attach path state block transitions
bladehan1 Aug 27, 2026
4fc4ea7
feat(db): rewind path state during reorg
bladehan1 Aug 27, 2026
bb979aa
feat(db): compact durable path state base
bladehan1 Aug 27, 2026
5bdc900
feat(db): migrate path state on P66 activation
bladehan1 Aug 27, 2026
c11cbba
feat(db): expose path state runtime status
bladehan1 Aug 27, 2026
3d9b0d0
test(db): verify path state shadow equivalence
bladehan1 Aug 27, 2026
3c6c7cd
feat(db): publish non-consensus path state root
bladehan1 Aug 27, 2026
320b2d9
chore(db): merge archive history partitioning
bladehan1 Aug 27, 2026
adce11f
fix(db): admit empty path state index keys
bladehan1 Aug 27, 2026
8e157fe
fix(db): project lazy account assets during rebuild
bladehan1 Aug 27, 2026
77a3cf4
perf(db): reduce path state rebuild memory
bladehan1 Aug 29, 2026
f9bcb08
perf(chainbase): avoid path state cross-store reads
bladehan1 Aug 29, 2026
2526575
perf(chainbase): parallelize state root rebuild stores
bladehan1 Aug 29, 2026
045d746
perf(chainbase): bound large state root rebuilds
bladehan1 Aug 30, 2026
79daeae
perf(chainbase): report state root rebuild progress
bladehan1 Aug 30, 2026
5cae30b
fix(chainbase): bound path-state rebuild memory
bladehan1 Aug 30, 2026
44a6004
fix(chainbase): migrate rebuild checkpoints lazily
bladehan1 Aug 30, 2026
82186a8
fix(chainbase): skip absent asset projections
bladehan1 Aug 30, 2026
7cabe9a
feat(chainbase): report trie build progress
bladehan1 Aug 30, 2026
e8d1de6
fix(chainbase): retire rebuild spools
bladehan1 Aug 30, 2026
cb02526
fix(chainbase): recover failed store rebuilds
bladehan1 Aug 31, 2026
3e29a07
feat(chainbase): add physical path state runtime
bladehan1 Aug 31, 2026
580adc8
perf(trie): batch physical state bootstrap writes
bladehan1 Sep 1, 2026
91aee17
perf(trie): optimize physical state updates
bladehan1 Sep 1, 2026
327f892
perf(trie): cache transition node reads
bladehan1 Sep 2, 2026
d5a719b
perf(trie): parallelize path state updates
bladehan1 Sep 2, 2026
800d758
feat(jsonrpc): support historical eth_call
bladehan1 Sep 2, 2026
4375546
feat(trie): add physical state root oracle
bladehan1 Sep 2, 2026
ff087e4
feat(chainbase): add checkpointed state archive
bladehan1 Sep 4, 2026
75b7e02
perf(trie): reduce path state block overhead
bladehan1 Sep 4, 2026
cf9fe67
fix(chainbase): honor archive index engine
bladehan1 Sep 5, 2026
716188b
fix(chainbase): wire common checkpoint runtime
bladehan1 Sep 5, 2026
c50ed88
fix(chainbase): flush common checkpoint on close
bladehan1 Sep 5, 2026
7f06ba6
fix(chainbase): isolate common checkpoint recovery
bladehan1 Sep 5, 2026
82c5dd7
fix(chainbase): honor archive engine configuration
bladehan1 Sep 5, 2026
a72dd17
feat(db): configure archive database profiles
bladehan1 Sep 5, 2026
2220c30
fix(db): preserve path state format compatibility
bladehan1 Sep 5, 2026
b1fc774
perf(db): reuse archive checkpoint index handle
bladehan1 Sep 5, 2026
306bce9
fix(chainbase): bound path state snapshot retention
bladehan1 Sep 5, 2026
0e08ae7
feat(chainbase): add checkpoint phase timings
bladehan1 Sep 6, 2026
c5fa8e5
perf(chainbase): reuse archive checkpoint writer
bladehan1 Sep 6, 2026
c720fd1
feat(chainbase): add state archive hot store
bladehan1 Sep 7, 2026
5f8504f
feat(db): add rocksdb hot store column families
bladehan1 Sep 8, 2026
26b6397
fix(chainbase): integrate checkpoint recovery
bladehan1 Sep 8, 2026
8267192
refactor(db): remove mutation view digest
bladehan1 Sep 8, 2026
c49ce3b
fix(chainbase): bound path-state snapshot retention
bladehan1 Sep 8, 2026
ac94546
perf(chainbase): retain archive serving writer
bladehan1 Sep 9, 2026
0d50a38
style(chainbase): clarify path-state prefixes
bladehan1 Sep 9, 2026
0deedce
fix(chainbase): prevent path-state worker stalls
bladehan1 Sep 9, 2026
96de4c3
feat(chainbase): add append-file state archive
bladehan1 Sep 10, 2026
965449d
feat(chainbase): add archive catalog serving
bladehan1 Sep 10, 2026
d705fe2
fix(chainbase): seal previously marked segments
bladehan1 Sep 10, 2026
46bfeb5
perf(chainbase): bound archive recovery reads
bladehan1 Sep 10, 2026
7e82bc9
feat(chainbase): merge p66 snapshot pipeline
bladehan1 Sep 10, 2026
24f62e8
fix(chainbase): preserve p66 recovery format
bladehan1 Sep 10, 2026
b925773
perf(chainbase): reduce archive bookkeeping
bladehan1 Sep 10, 2026
56ac7e0
feat(chainbase): isolate archive index worker
bladehan1 Sep 10, 2026
970f19d
build(chainbase): support high rocksdb x86 candidate
bladehan1 Sep 10, 2026
154a430
build(chainbase): allow explicit amd jdk17 candidate
bladehan1 Sep 10, 2026
ab6d3c6
feat(platform): allow opt-in x86 java17 candidate
bladehan1 Sep 10, 2026
63c43d3
fix(chainbase): recover finalized archive appends safely
bladehan1 Sep 11, 2026
ac77650
perf(chainbase): reuse and time serving index
bladehan1 Sep 11, 2026
6d355ee
perf(chainbase): reuse checkpoint suffix nodes
bladehan1 Sep 11, 2026
57d9b8b
fix(chainbase): retain large serving filters
bladehan1 Sep 11, 2026
0ef129d
perf(db): retain large account trie filters
bladehan1 Sep 12, 2026
41c62fc
feat(db): add fine-grained pathstate attribution
bladehan1 Sep 12, 2026
f05ba49
feat(db): extend pathstate read attribution
bladehan1 Sep 12, 2026
64c7fec
feat(db): observe pathstate rocksdb cache events
bladehan1 Sep 12, 2026
d442c74
fix(common): satisfy math and config checks
bladehan1 Sep 12, 2026
5fb79de
perf(db): add bounded read cache candidate
bladehan1 Sep 12, 2026
1b0e91e
perf(db): add account cache capacity candidate
bladehan1 Sep 12, 2026
17f9312
feat(metrics): add chainbase execution attribution
bladehan1 Sep 12, 2026
c540f29
feat(metrics): attribute business cache reads
bladehan1 Sep 12, 2026
41db798
style(metrics): align cache attribution formatting
bladehan1 Sep 12, 2026
b4292a2
feat(db): add account cache capacity probe
bladehan1 Sep 13, 2026
5c32636
feat(metrics): sample native get internals
bladehan1 Sep 13, 2026
9345dac
feat(metrics): attribute business read waits
bladehan1 Sep 13, 2026
b3f6663
refactor(db): remove unadopted cache probes
bladehan1 Sep 14, 2026
0a2309a
test(db): add process-kill recovery tests for archive rotation and wal
bladehan1 Sep 14, 2026
9be5383
fix(archive): bound catalog generation retention to three
bladehan1 Sep 15, 2026
7c6ee72
feat(archive): wire historical query rpc and vm context
bladehan1 Sep 15, 2026
8b212be
feat(db): reopen archive from the persisted proof boundary
bladehan1 Sep 15, 2026
6331db2
fix(archive): use fast reopen for published proof
bladehan1 Sep 15, 2026
b3496a8
fix(chainbase): align archive recovery with checkpoint
bladehan1 Sep 15, 2026
531d2a1
fix(chainbase): align lagging archive catalog
bladehan1 Sep 15, 2026
ebdc0e6
fix(chainbase): resume archive catalog retention
bladehan1 Sep 15, 2026
8d3dffc
feat(chainbase): add catalogless archive v4
bladehan1 Sep 17, 2026
79f6cff
feat(chainbase): add geth-style archive index
bladehan1 Sep 17, 2026
b4e198f
fix(chainbase): read committed archive prefixes
bladehan1 Sep 17, 2026
0a36226
feat(config): add test archive handoff
bladehan1 Sep 18, 2026
bcb22e2
perf(chainbase): bound serving archive validation
bladehan1 Sep 18, 2026
8caf29d
perf(chainbase): batch background serving updates
bladehan1 Sep 18, 2026
34eee3a
fix(chainbase): always materialize p66 snapshots
bladehan1 Sep 18, 2026
c976d60
perf(chainbase): pin path-state l0 index and isolate compaction io
bladehan1 Sep 18, 2026
19dac1f
Merge remote-tracking branch 'origin/develop' into feature/state_archive
bladehan1 Sep 20, 2026
fe7347a
fix(chainbase): satisfy math and checkstyle checks
bladehan1 Sep 20, 2026
c8199b7
fix(vm): tolerate null store factory in repository root
bladehan1 Sep 20, 2026
1d51d7f
fix(chainbase): migrate account assets on direct root writes
bladehan1 Sep 20, 2026
403aadb
fix(chainbase): restore v3 archive segment target identity
bladehan1 Sep 20, 2026
ef7c09c
fix(chainbase): tolerate repeated manager asset-lane attachment
bladehan1 Sep 20, 2026
5e7d4e7
test(chainbase): adapt snapshot checks for the account-asset lane
bladehan1 Sep 20, 2026
a452676
test(chainbase): restore format-v1 path engine root vector
bladehan1 Sep 20, 2026
7000391
test(net): verify pushblock with explicit sync source
bladehan1 Sep 20, 2026
df0ad2b
perf(db): move serving-index flush io out of coordinator monitor
bladehan1 Sep 20, 2026
3835c1d
test(chainbase): refreeze v3 format baselines at restored target
bladehan1 Sep 20, 2026
443bc1b
test(framework): log started test events for hang diagnosis
bladehan1 Sep 20, 2026
c5ab080
fix(chainbase): surface serving owner native errors to waiters
bladehan1 Sep 20, 2026
539bdc2
test(framework): gate leveldb-backed archive tests on arm64
bladehan1 Sep 20, 2026
0721f34
test(chainbase): accept rocksdb 9 bloom filter options spelling
bladehan1 Sep 20, 2026
fffec38
refactor(chainbase): remove v4 and v3 append-file archive formats
bladehan1 Sep 21, 2026
b76ddef
test(framework): align append file mapping assertion with v5 only format
bladehan1 Sep 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
49 changes: 39 additions & 10 deletions actuator/src/main/java/org/tron/core/actuator/VMActuator.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.LongSupplier;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -56,8 +57,10 @@
import org.tron.core.vm.program.ProgramPrecompile;
import org.tron.core.vm.program.invoke.ProgramInvoke;
import org.tron.core.vm.program.invoke.ProgramInvokeFactory;
import org.tron.core.vm.repository.CurrentRepositoryProvider;
import org.tron.core.vm.repository.Repository;
import org.tron.core.vm.repository.RepositoryImpl;
import org.tron.core.vm.repository.RepositoryProvider;
import org.tron.core.vm.utils.MUtil;
import org.tron.protos.Protocol;
import org.tron.protos.Protocol.Block;
Expand Down Expand Up @@ -99,8 +102,15 @@ public class VMActuator implements Actuator2 {

private LogInfoTriggerParser logInfoTriggerParser;

private final RepositoryProvider repositoryProvider;

public VMActuator(boolean isConstantCall) {
this(isConstantCall, CurrentRepositoryProvider.INSTANCE);
}

public VMActuator(boolean isConstantCall, RepositoryProvider repositoryProvider) {
this.isConstantCall = isConstantCall;
this.repositoryProvider = Objects.requireNonNull(repositoryProvider, "repositoryProvider");
this.maxEnergyLimit = CommonParameter.getInstance().maxEnergyLimitForConstant;
}

Expand All @@ -113,6 +123,11 @@ private static long getEnergyFee(long callerEnergyUsage, long callerEnergyFrozen
.divide(BigInteger.valueOf(callerEnergyTotal)).longValueExact();
}

private long dynamicLong(String key, LongSupplier currentValue) {
return rootRepository.isHistorical()
? ConfigLoader.property(rootRepository, key) : currentValue.getAsLong();
}

@Override
public void validate(Object object) throws ContractValidateException {

Expand All @@ -121,16 +136,24 @@ public void validate(Object object) throws ContractValidateException {
throw new RuntimeException("TransactionContext is null");
}

// Load Config
ConfigLoader.load(context.getStoreFactory(), isConstantCall);
rootRepository = Objects.requireNonNull(repositoryProvider.createRoot(context),
"repositoryProvider returned null");
if (rootRepository.isHistorical()) {
if (!isConstantCall) {
throw new ContractValidateException("Historical execution must be a constant call");
}
ConfigLoader.load(rootRepository);
} else {
ConfigLoader.load(context.getStoreFactory(), isConstantCall);
}
// Warm up registry class
OperationRegistry.init();
trx = context.getTrxCap().getInstance();
// If tx`s fee limit is set, use it to calc max energy limit for constant call
if (isConstantCall && trx.getRawData().getFeeLimit() > 0) {
maxEnergyLimit = min(maxEnergyLimit, trx.getRawData().getFeeLimit()
/ context.getStoreFactory().getChainBaseManager()
.getDynamicPropertiesStore().getEnergyFee(), VMConfig.disableJavaLangMath());
/ dynamicLong("ENERGY_FEE", () -> context.getStoreFactory().getChainBaseManager()
.getDynamicPropertiesStore().getEnergyFee()), VMConfig.disableJavaLangMath());
}
blockCap = context.getBlockCap();
if ((VMConfig.allowTvmFreeze() || VMConfig.allowTvmFreezeV2())
Expand All @@ -139,8 +162,10 @@ public void validate(Object object) throws ContractValidateException {
}
//Route Type
ContractType contractType = this.trx.getRawData().getContract(0).getType();
//Prepare Repository
rootRepository = RepositoryImpl.createRoot(context.getStoreFactory());
if (rootRepository.isHistorical() && contractType != ContractType.TriggerSmartContract) {
throw new ContractValidateException(
"Historical execution only supports TriggerSmartContract");
}

enableEventListener = context.isEventPluginLoaded();

Expand Down Expand Up @@ -481,7 +506,8 @@ static void checkContractNameLength(SmartContract contract) throws ContractValid
private void call()
throws ContractValidateException {

if (!rootRepository.getDynamicPropertiesStore().supportVM()) {
if (dynamicLong("ALLOW_CREATION_OF_CONTRACTS",
() -> rootRepository.getDynamicPropertiesStore().getAllowCreationOfContracts()) != 1L) {
logger.info("vm work is off, need to be opened by the committee");
throw new ContractValidateException("VM work is off, need to be opened by the committee");
}
Expand Down Expand Up @@ -526,10 +552,12 @@ private void call()
byte[] code = rootRepository.getCode(contractAddress);
if (isNotEmpty(code)) {
long feeLimit = trx.getRawData().getFeeLimit();
if (feeLimit < 0 || feeLimit > rootRepository.getDynamicPropertiesStore().getMaxFeeLimit()) {
long maxFeeLimit = dynamicLong("MAX_FEE_LIMIT",
() -> rootRepository.getDynamicPropertiesStore().getMaxFeeLimit());
if (feeLimit < 0 || feeLimit > maxFeeLimit) {
logger.info("invalid feeLimit {}", feeLimit);
throw new ContractValidateException("feeLimit must be >= 0 and <= "
+ rootRepository.getDynamicPropertiesStore().getMaxFeeLimit());
+ maxFeeLimit);
}
AccountCapsule caller = rootRepository.getAccount(callerAddress);
long energyLimit;
Expand All @@ -542,7 +570,8 @@ private void call()
}

long thisTxCPULimitInUs = calculateCpuLimitInUs(isConstantCall,
rootRepository.getDynamicPropertiesStore().getMaxCpuTimeOfOneTx(),
dynamicLong("MAX_CPU_TIME_OF_ONE_TX",
() -> rootRepository.getDynamicPropertiesStore().getMaxCpuTimeOfOneTx()),
getCpuLimitInUsRatio(), CommonParameter.getInstance().getConstantCallTimeoutMs());
long vmStartInUs = System.nanoTime() / VMConstant.ONE_THOUSAND;
long vmShouldEndInUs = vmStartInUs + thisTxCPULimitInUs;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.tron.core.vm;

/** Fail-closed rejection for a state capability unavailable to historical execution. */
public class HistoricalCapabilityException extends RuntimeException {

public HistoricalCapabilityException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.tron.core.vm;

/** Runtime allowlist for capabilities reachable only after bytecode dispatch. */
public final class HistoricalExecutionGuard {

private HistoricalExecutionGuard() {
}

public static void requirePrecompileAllowed(
PrecompiledContracts.PrecompiledContract contract) {
if (contract instanceof PrecompiledContracts.Identity
|| contract instanceof PrecompiledContracts.Sha256
|| contract instanceof PrecompiledContracts.Ripempd160
|| contract instanceof PrecompiledContracts.ECRecover
|| contract instanceof PrecompiledContracts.ModExp
|| contract instanceof PrecompiledContracts.BN128Addition
|| contract instanceof PrecompiledContracts.BN128Multiplication
|| contract instanceof PrecompiledContracts.BN128Pairing
|| contract instanceof PrecompiledContracts.EthRipemd160
|| contract instanceof PrecompiledContracts.Blake2F
|| contract instanceof PrecompiledContracts.P256Verify) {
return;
}
throw new HistoricalCapabilityException(
"Precompile is not allowed by historical execution: "
+ contract.getClass().getSimpleName());
}
}
8 changes: 8 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 @@ -1070,6 +1070,10 @@ public static void revertAction(Program program) {
}

public static void suicideAction(Program program) {
if (program.getContractState().isHistorical()) {
throw new HistoricalCapabilityException(
"SELFDESTRUCT is not supported by historical execution");
}
if (program.isStaticCall()) {
throw new Program.StaticCallModificationException();
}
Expand All @@ -1085,6 +1089,10 @@ public static void suicideAction(Program program) {
}

public static void suicideAction2(Program program) {
if (program.getContractState().isHistorical()) {
throw new HistoricalCapabilityException(
"SELFDESTRUCT is not supported by historical execution");
}
if (program.isStaticCall()) {
throw new Program.StaticCallModificationException();
}
Expand Down
7 changes: 7 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/VM.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@ public static void play(Program program, JumpTable jumpTable) {
long factor = DYNAMIC_ENERGY_FACTOR_DECIMAL;
long energyUsage = 0L;
// hoist once per execution: avoids a per-opcode VMConfig.current() thread-local lookup
final boolean historical = program.getContractState().isHistorical();
final boolean allowDynamicEnergy = VMConfig.allowDynamicEnergy();

if (allowDynamicEnergy) {
factor = program.updateContextContractFactor();
}

while (!program.isStopped()) {
if (historical) {
program.getContractState().checkHistoricalQueryActive();
}
if (VMConfig.vmTrace()) {
program.saveOpTrace();
}
Expand Down Expand Up @@ -88,6 +92,9 @@ public static void play(Program program, JumpTable jumpTable) {

/* exec op action */
op.execute(program);
if (historical) {
program.getContractState().checkHistoricalQueryActive();
}

program.setPreviouslyExecutedOp((byte) op.getOpcode());
} catch (RuntimeException e) {
Expand Down
60 changes: 57 additions & 3 deletions actuator/src/main/java/org/tron/core/vm/config/ConfigLoader.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package org.tron.core.vm.config;

import static org.tron.core.capsule.ReceiptCapsule.checkForEnergyLimit;

import lombok.extern.slf4j.Slf4j;
import org.tron.common.parameter.CommonParameter;
import org.tron.core.store.DynamicPropertiesStore;
import org.tron.core.store.StoreFactory;
import org.tron.core.vm.HistoricalCapabilityException;
import org.tron.core.vm.repository.Repository;

@Slf4j(topic = "VMConfigLoader")
public class ConfigLoader {
Expand All @@ -21,8 +21,9 @@ public static void load(StoreFactory storeFactory, boolean isolate) {
DynamicPropertiesStore ds = storeFactory.getChainBaseManager().getDynamicPropertiesStore();
VMConfig.setVmTrace(CommonParameter.getInstance().isVmTrace());
if (ds != null) {
VMConfig.initVmHardFork(checkForEnergyLimit(ds));
VMConfig.Snapshot snapshot = new VMConfig.Snapshot();
snapshot.energyLimitHardFork = ds.getLatestBlockHeaderNumber()
>= CommonParameter.getInstance().getBlockNumForEnergyLimit();
snapshot.allowMultiSign = ds.getAllowMultiSign() == 1;
snapshot.allowTvmTransferTrc10 = ds.getAllowTvmTransferTrc10() == 1;
snapshot.allowTvmConstantinople = ds.getAllowTvmConstantinople() == 1;
Expand Down Expand Up @@ -53,9 +54,62 @@ public static void load(StoreFactory storeFactory, boolean isolate) {
if (isolate) {
VMConfig.setLocalSnapshot(snapshot);
} else {
VMConfig.initVmHardFork(snapshot.energyLimitHardFork);
VMConfig.setGlobalSnapshot(snapshot);
}
}
}
}

/** Loads an isolated VM view exclusively from a Repository's request-owned state source. */
public static void load(Repository repository) {
if (disable) {
throw new HistoricalCapabilityException(
"Historical VM config loading cannot be disabled");
}
VMConfig.setVmTrace(CommonParameter.getInstance().isVmTrace());
VMConfig.Snapshot snapshot = new VMConfig.Snapshot();
snapshot.energyLimitHardFork = property(repository, "latest_block_header_number")
>= CommonParameter.getInstance().getBlockNumForEnergyLimit();
snapshot.allowMultiSign = enabled(repository, "ALLOW_MULTI_SIGN");
snapshot.allowTvmTransferTrc10 = enabled(repository, "ALLOW_TVM_TRANSFER_TRC10");
snapshot.allowTvmConstantinople = enabled(repository, "ALLOW_TVM_CONSTANTINOPLE");
snapshot.allowTvmSolidity059 = enabled(repository, "ALLOW_TVM_SOLIDITY_059");
snapshot.allowShieldedTRC20Transaction =
enabled(repository, "ALLOW_SHIELDED_TRC20_TRANSACTION");
snapshot.allowTvmIstanbul = enabled(repository, "ALLOW_TVM_ISTANBUL");
snapshot.allowTvmFreeze = enabled(repository, "ALLOW_TVM_FREEZE");
snapshot.allowTvmVote = enabled(repository, "ALLOW_TVM_VOTE");
snapshot.allowTvmLondon = enabled(repository, "ALLOW_TVM_LONDON");
snapshot.allowTvmCompatibleEvm = enabled(repository, "ALLOW_TVM_COMPATIBLE_EVM");
snapshot.allowHigherLimitForMaxCpuTimeOfOneTx =
enabled(repository, "ALLOW_HIGHER_LIMIT_FOR_MAX_CPU_TIME_OF_ONE_TX");
snapshot.allowTvmFreezeV2 = property(repository, "UNFREEZE_DELAY_DAYS") > 0;
snapshot.allowOptimizedReturnValueOfChainId =
enabled(repository, "ALLOW_OPTIMIZED_RETURN_VALUE_OF_CHAIN_ID");
snapshot.allowDynamicEnergy = enabled(repository, "ALLOW_DYNAMIC_ENERGY");
snapshot.dynamicEnergyThreshold = property(repository, "DYNAMIC_ENERGY_THRESHOLD");
snapshot.dynamicEnergyIncreaseFactor = property(repository, "DYNAMIC_ENERGY_INCREASE_FACTOR");
snapshot.dynamicEnergyMaxFactor = property(repository, "DYNAMIC_ENERGY_MAX_FACTOR");
snapshot.allowTvmShanghai = enabled(repository, "ALLOW_TVM_SHANGHAI");
snapshot.allowEnergyAdjustment = enabled(repository, "ALLOW_ENERGY_ADJUSTMENT");
snapshot.allowStrictMath = enabled(repository, "ALLOW_STRICT_MATH");
snapshot.allowTvmCancun = enabled(repository, "ALLOW_TVM_CANCUN");
snapshot.disableJavaLangMath = enabled(repository, "CONSENSUS_LOGIC_OPTIMIZATION");
snapshot.allowTvmBlob = enabled(repository, "ALLOW_TVM_BLOB");
snapshot.allowTvmSelfdestructRestriction =
enabled(repository, "ALLOW_TVM_SELFDESTRUCT_RESTRICTION");
snapshot.allowTvmOsaka = enabled(repository, "ALLOW_TVM_OSAKA");
snapshot.allowHardenResourceCalculation =
enabled(repository, "ALLOW_HARDEN_RESOURCE_CALCULATION");
VMConfig.setLocalSnapshot(snapshot);
}

public static long property(Repository repository, String key) {
return repository.getDynamicPropertyLong(key);
}

private static boolean enabled(Repository repository, String key) {
return property(repository, key) == 1L;
}
}
10 changes: 10 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 @@ -41,6 +41,16 @@ public void setProgramListener(ProgramListener listener) {
this.programListener = listener;
}

@Override
public void checkHistoricalQueryActive() {
repository.checkHistoricalQueryActive();
}

@Override
public boolean isHistorical() {
return repository.isHistorical();
}

@Override
public AssetIssueCapsule getAssetIssue(byte[] tokenId) {
return repository.getAssetIssue(tokenId);
Expand Down
14 changes: 12 additions & 2 deletions actuator/src/main/java/org/tron/core/vm/program/Program.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
import org.tron.core.exception.TronException;
import org.tron.core.utils.TransactionUtil;
import org.tron.core.vm.EnergyCost;
import org.tron.core.vm.HistoricalCapabilityException;
import org.tron.core.vm.HistoricalExecutionGuard;
import org.tron.core.vm.MessageCall;
import org.tron.core.vm.Op;
import org.tron.core.vm.OperationRegistry;
Expand Down Expand Up @@ -820,6 +822,10 @@ public void createContract(DataWord value, DataWord memStart, DataWord memSize)

private void createContractImpl(DataWord value, byte[] programCode, byte[] newAddress,
boolean isCreate2) {
if (getContractState().isHistorical()) {
throw new HistoricalCapabilityException(
"CREATE and CREATE2 are not supported by historical execution");
}
byte[] senderAddress = getContextAddress();

if (logger.isDebugEnabled()) {
Expand Down Expand Up @@ -1671,6 +1677,10 @@ public void callToPrecompiledAddress(MessageCall msg,
PrecompiledContracts.PrecompiledContract contract) {
returnDataBuffer = null; // reset return buffer right before the call

if (getContractState().isHistorical()) {
HistoricalExecutionGuard.requirePrecompileAllowed(contract);
}

if (getCallDeep() == MAX_DEPTH) {
stackPushZero();
this.refundEnergy(msg.getEnergy().longValue(), " call deep limit reach");
Expand Down Expand Up @@ -2374,11 +2384,11 @@ public long updateContextContractFactor() {

if (contractStateCapsule == null) {
contractStateCapsule = new ContractStateCapsule(
contractState.getDynamicPropertiesStore().getCurrentCycleNumber());
contractState.getDynamicPropertyLong("CURRENT_CYCLE_NUMBER"));
contractState.updateContractState(getContextAddress(), contractStateCapsule);
} else {
if (contractStateCapsule.catchUpToCycle(
contractState.getDynamicPropertiesStore().getCurrentCycleNumber(),
contractState.getDynamicPropertyLong("CURRENT_CYCLE_NUMBER"),
VMConfig.getDynamicEnergyThreshold(),
VMConfig.getDynamicEnergyIncreaseFactor(),
VMConfig.getDynamicEnergyMaxFactor(),
Expand Down
Loading
Loading