Skip to content

fix(vm): make initAllow setters drop leftover local snapshot - #19

Open
vividctrlalt wants to merge 1 commit into
developfrom
fix/vmconfig_init_clears_local
Open

fix(vm): make initAllow setters drop leftover local snapshot#19
vividctrlalt wants to merge 1 commit into
developfrom
fix/vmconfig_init_clears_local

Conversation

@vividctrlalt

Copy link
Copy Markdown
Owner

What

VMConfig.initAllow*(), initDynamicEnergy*(), and initDisableJavaLangMath() write globalSnapshot while getters read current() (the thread-local snapshot if one is present). After tronprotocol#6857, a leftover local snapshot from a prior constant call hides those writes, so callers of init* do not observe the flags they just set.

Why

tronprotocol#6857 split VM config into a process-global snapshot (block processing) and a thread-local snapshot (constant calls). That dual-write is the correct production isolation: current() must keep preferring the local view so a solidity/PBFT constant call cannot pollute HEAD flags.

The test-only init* API (25 test files; production load uses setGlobalSnapshot) was left as "write global, read local". That is a contract bug in the setters themselves. Patching call sites — clearLocalSnapshot() wrappers around init*, clearing the local view from ConfigLoader when disable is set, or BaseTest @After cleanup — treats the symptom and misses any test that still calls plain init*. The one-place fix is: every init* setter that mutates globalSnapshot first drops the leftover local snapshot, then writes the global one. current() is unchanged.

Changes

  • Private forInit() removes the thread-local snapshot and returns globalSnapshot. Every initAllow* / initDynamicEnergy* / initDisableJavaLangMath setter is a single assignment through that helper.
  • VMConfigIsolationTest.testInitIsVisibleWhenLocalSnapshotExists asserts that initAllowTvmLondon(1) is visible even when a stale local snapshot exists. @After still restores the global snapshot.
  • TransactionsMsgHandlerTest: every case that stubs a peer uses a brand-new mock and doReturn. A shared mock plus when(mock.foo()) races handleTransaction calling isBadPeer() on the same mock. Boolean mocks default to false, so an isBadPeer() stub is not added.

Related

tronprotocol#6857

Test plan

  • ./gradlew :framework:test --tests org.tron.common.runtime.vm.VMConfigIsolationTest --tests org.tron.core.net.messagehandler.TransactionsMsgHandlerTest --tests org.tron.common.runtime.vm.AllowTvmLondonTest --tests org.tron.common.runtime.vm.ValidateMultiSignContractTest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant