feat(vm): close shielded TRC20 progressively#6829
Closed
317787106 wants to merge 1 commit into
Closed
Conversation
Add committee governance proposal CLOSE_SHIELDED_TRC20_TRANSACTION (id 80, value range 0-3) that progressively disables the shielded TRC20 precompiled contracts: 0 -> off (default, no behavior change) 1 -> disable mint (verifyMintProof) 2 -> disable mint + transfer (verifyTransferProof) 3 -> disable mint + transfer + burn (verifyBurnProof) When a level is engaged, the corresponding proof precompile short-circuits to (success, 32 zero bytes) before any verification so the caller's unused energy is refunded instead of being fully burned; Program tags the call with a runtime error (shield mint/transfer/burn not allowed) and VMActuator turns that into a REVERT with no state change. Validation is gated to fork v4.8.2. The parameter is persisted in DynamicPropertiesStore, applied through ProposalService, loaded into the VM via VMConfig/ConfigLoader, exposed in Wallet.getChainParameters, and configurable through committee.closeShieldedTRC20Transaction (reference.conf). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds a committee governance proposal
CLOSE_SHIELDED_TRC20_TRANSACTION(id 80, value range 0–3) that progressively disables the shielded TRC20 precompiled contracts:01verifyMintProof)2verifyTransferProof)3verifyBurnProof)When a level is engaged, the corresponding proof precompile short-circuits to
(success, 32 zero bytes)before any verification;Programtags the call with a specific runtime error (shield trc20 mint/transfer/burn not allowed), andVMActuatorpreserves that reason and marks the call asREVERT(no state change) instead of overwriting it with the generic"REVERT opcode executed".The parameter is:
DynamicPropertiesStore(CLOSE_SHIELDED_TRC20_TRANSACTION),ProposalService,VMConfig/ConfigLoader,Wallet.getChainParametersasgetCloseShieldedTRC20Transaction,committee.closeShieldedTRC20Transaction(seereference.conf),Design note — why close via "success + revert" instead of failing the precompile (energy cost)
The proof precompile's
execute()deliberately returns success(true, 32 zero bytes)when a level is closed, rather than throwing an exception, returning(false, …), or having the contract lookup returnnull. The reason is energy accounting inProgram.callToPrecompiledAddress:refundEnergy(msg.getEnergy() − requiredEnergy)— only the precompile's fixed cost (getEnergyForData, e.g. 150000) is consumed.execute()/ the contract lookup,execute()returningfalse, or no contract found) is the "spend all energy on failure" path:refundEnergy(0), which burns the entire remaining energy of the call.So if the close were implemented by making the precompile fail, every blocked mint/transfer/burn call would penalize the caller with a full-energy burn. Instead we let
execute()return normally, then setruntimeError(shield mint/transfer/burn not allowed) on the result afterwards and letVMActuatorturn it into aREVERT. This yields the same revert outcome (no state change) while refunding the caller's unused energy, avoiding the all-energy-consumed penalty.Why are these changes required?
Governance needs a controlled, staged way to wind down shielded TRC20 support rather than an all-or-nothing switch. Closing in the order mint → transfer → burn lets the network first stop new shielded notes from being created, then stop moving them, while keeping burn open last so existing holders can still unshield (exit) their funds before the feature is fully closed. Default
0keeps current behavior, so the change is inert until a proposal is approved post-4.8.2.This PR has been tested by:
ProposalUtilTest— proposal 80 is rejected before fork v4.8.2 (even with earlier forks active) and validates the 0–3 range afterwards.ProposalServiceTest— approving the proposal persists the value into the dynamic properties store.PrecompiledContractsTest— each proof precompile short-circuits to(success, zero)at its matching close level.RpcApiServicesTest— store initialization with the new key.reference.confbean-parity, key-name, and comment-coverage gatesFollow up
N/A
Extra details
Adapted to the v4.8.2 codebase:
VMConfiglives incommon, and the committee parameter is wired through theCommitteeConfigbean +reference.conf(replacing the oldConstant.COMMITTEE_*/Args.hasPathstyle). Proposal code80was unused on this branch (it skips 79 → 81), so no renumbering was needed.