feat(shadow-fork): fork mainnet, and run a witness slate that can solidify - #220
Open
Sunny6889 wants to merge 2 commits into
Open
feat(shadow-fork): fork mainnet, and run a witness slate that can solidify#220Sunny6889 wants to merge 2 commits into
Sunny6889 wants to merge 2 commits into
Conversation
scripts/poc-shadow-fork.sh shelled out to Python's tronpy to make the one keypair a fork needs, because — as its own comment said — trond had no subcommand for it. That put `pip install tronpy` between an operator and a shadow fork, for forty lines of secp256k1 and Keccak this repository already carries for txgen. Add `trond shadow-fork keygen`, which fills the gap the parent command's doc comment anticipated, and point the script at it. The derivation moves from tools/txgen into internal/tronaddr so both callers share one copy rather than growing a second. With --out the key goes to a 0600 file as shell exports, which is the shape the script sources; without it the pair goes to stdout. The JSON form deliberately omits the private key when --out was given: the caller asked for it on disk, and stdout ends up in logs and agent transcripts. Python is no longer a prerequisite anywhere in the shadow-fork path.
The PoC could only do one thing: a single-witness fork of Nile. Both limits mattered. Nile does not have mainnet's accounts, contracts or token supply, so a fork of it cannot answer what an upgrade does to the state that exists. SHADOW_FORK_NETWORK now picks the chain; the value flows into the snapshot download and into the intent's `network`, which has to agree with it because java-tron checks the genesis block against the network HOCON at boot and crash-loops on a mismatch. One witness produces blocks but never solidifies them — the confirmation count sits at 1, far below the 2/3 a block needs before java-tron treats it as irreversible. Nothing that reads solidified state could be tested, and a solidification stall could not be reproduced at all. SHADOW_FORK_WITNESS_COUNT now sets the slate size: `trond shadow-fork keygen --count` generates the keypairs, the script writes one witnesses entry and one funded account per witness, gives each node its own ports and data directory, and deploys through `trond network create` rather than `apply` so the peers find each other. fork.conf and the intent are generated rather than sed-substituted: their arrays are as long as the witness count, which a placeholder template cannot express. Each node gets a copy of the mutated database because java-tron opens its LevelDB exclusively. Defaults are unchanged — nile, one witness — so the cheap PoC still runs as before, and a stash written before --count existed still resolves: the first witness stays unsuffixed, the rest are numbered from 2.
Sunny6889
force-pushed
the
feat/shadow-fork-mainnet-multiwitness
branch
from
August 20, 2026 07:16
e3d49f8 to
d526753
Compare
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?
Makes
scripts/poc-shadow-fork.shable to fork mainnet, and to run more than one witness.SHADOW_FORK_NETWORKflows into both the snapshot download and the intent'snetwork. Those must agree — java-tron validates the genesis block against the network HOCON at boot and crash-loops with "Genesis block modify" on a mismatch. Peer isolation stays as it was (empty seed list + bumpednode.p2p.version).SHADOW_FORK_WITNESS_COUNTgenerates that many keypairs, writes onewitnessesentry and one funded account each, gives every node its own ports and data directory, and deploys throughtrond network createinstead ofapplyso the peers find each other.fork.confand the intent are generated rather than sed-substituted, because their arrays scale with the count.trond shadow-fork keygensubcommand (--count,--out,--output json) replaces thetronpycall the script used for witness keys. The derivation already existed for txgen, sotools/txgen/address.gomoves tointernal/tronaddrand both share one copy; the txgen diff is mechanical.No new tool or binary — the pipeline strings together
snapshot download,shadow-fork keygen,shadow-fork mutate,network createandconfig validate.Defaults are unchanged (nile, one witness) and key stashes written before this PR still resolve.
SchemaVersion1.15.0 → 1.16.0 (MINOR: new command, no existing schema touched).Why are these changes required?
tronpywas a barrier to entry. The script shelled out to Python to make a single keypair; its own comment noted trond had no subcommand for it. A Go project's test harness neededpip install tronpybefore it would run.This PR has been tested by:
Follow up
Extra details