README.md (8048B)
1 # Docker Compose end-to-end tests 2 3 This harness runs the six-node network with a deliberately isolated consensus 4 profile, iuna-local-e2e-5s-v1. Its target block time is 5 seconds, its Docker 5 subnet is 172.29.0.0/24, and its management ports are 28661 through 28666. 6 The optional sync-test node uses 28667. The regular local testnet keeps its 7 10-minute target and can run alongside it. 8 9 The e2e binary refuses to start unless IUNA_LOCAL_TESTNET=true. Its profile ID 10 is part of the launch-profile hash, so a 5-second checkpoint cannot be loaded by 11 the regular local-testnet build. 12 13 ## Everyday workflow 14 15 Start a fresh network: 16 17 ```sh 18 ./e2e/iuna_e2e.py reset 19 ./e2e/iuna_e2e.py up --build 20 ./e2e/iuna_e2e.py status 21 ``` 22 23 Start from a committed checkpoint and wait for all nodes to converge: 24 25 ```sh 26 ./e2e/iuna_e2e.py up --snapshot pre-objective-finality 27 ./e2e/iuna_e2e.py wait 1001 --converge 28 ``` 29 30 Run the same flow as one test, including log collection on failure and teardown: 31 32 ```sh 33 ./e2e/iuna_e2e.py smoke \ 34 --from pre-objective-finality \ 35 --through 1001 36 ``` 37 38 Run the complete assertion suite (build the image on the first scenario): 39 40 ```sh 41 ./e2e/iuna_e2e.py test --build 42 ``` 43 44 Run the standard post-activation gate used by deployment: 45 46 ```sh 47 ./e2e/iuna_e2e.py test post-activation --build 48 ``` 49 50 This verifies the committed checkpoints, crosses 999 through 1001, then restores 51 the first objective checkpoint, advances the restarted network through 1007, 52 interrupts both an empty-node bootstrap and stale range sync, and runs a physical 53 3-3 P2P partition/recovery scenario. 54 55 Tests can also be selected individually: 56 57 ```sh 58 ./e2e/iuna_e2e.py test snapshots 59 ./e2e/iuna_e2e.py test fallback-activation 60 ./e2e/iuna_e2e.py test objective-finality 61 ./e2e/iuna_e2e.py test checkpoint-restart 62 ./e2e/iuna_e2e.py test sync-resilience 63 ./e2e/iuna_e2e.py test partition-recovery 64 ``` 65 66 Preserve a machine-readable phase report and complete container logs: 67 68 ```sh 69 ./e2e/iuna_e2e.py test sync-resilience \ 70 --evidence-dir release-evidence 71 ``` 72 73 snapshots is fast and does not need Docker. It verifies checksums, manifest 74 metadata, the six stored chain databases, canonical heights and tips, and the 75 profile of every committed checkpoint. The network scenarios restore the 76 checkpoint before a protocol boundary and assert six-node convergence, the 77 isolated e2e profile, finality state, canonical block identity, and the read-only 78 blocks, network-health, peers, mempool, and wallet APIs on every node. 79 80 fallback-activation crosses height 300 and checks that objective finality has 81 not activated early. objective-finality crosses heights 1000 and 1001 and 82 requires a certified checkpoint. checkpoint-restart proves that the certified 83 checkpoint survives a full six-node restart, advances through height 1007, and 84 that block 1007 is finalized by a ticket derived from a burn included at height 85 1002 or later. At that height, the ticket maturity and expiry windows exclude 86 every pre-pipeline burn, so this covers a complete post-activation burn-to-block 87 lifecycle. 88 89 partition-recovery gives the e2e containers network-administration capability 90 and installs temporary firewall rules that split the six real node processes 91 into two connected groups of three. It requires both islands to converge 92 internally on different tips containing new recovery blocks, removes the rules, 93 requires six-node convergence, restarts node6 with its existing data, and waits 94 for a new rank-0 ticket block that finalizes at or beyond the canonical recovery 95 height. The disposable scenario deterministically leaves one automatic finalizer 96 active per island; disabling the other members cancels their in-flight VDFs 97 before partitioning. Before healing it also stops one island's worker so a single 98 canonical branch can overtake the other. It restores every node's original 99 finalization settings after convergence, avoiding both a recovery-less small 100 island and competing recovery branches. 101 102 sync-resilience restores the mature six-node checkpoint and adds a seventh, 103 non-finalizing syncnode with a fresh data directory. It interrupts that node 104 before its fetched chain is persisted, then requires a successful restart and 105 seven-node convergence. Next it gives the same node the height-299 chain/UI 106 fixture, waits until the management API reports active incremental range 107 validation, interrupts it again, and requires the persisted stale node to 108 resume and converge. The six reference nodes start with finalization paused so 109 the sync target stays fixed and fork races are not conflated with the sync 110 failure being tested. 111 112 Each evidence run is stored in a timestamped directory with report.json and 113 nodes.log. The report records the base Git revision, dirty-worktree flag, an 114 exact SHA-256 fingerprint of all tracked working-tree contents, and per-phase 115 node tips and checkpoints. Scenario-specific phases add the sync start, 116 validated and target heights or both partition recovery heights, the canonical 117 recovery block, the restarted service, and the resumed rank-0 ticket. The tree 118 fingerprint also identifies the tested state while deployment has staged 119 version changes that are committed and tagged only after all gates pass. 120 It is updated after every completed phase so a failed run remains useful. Raw 121 node logs contain public node/wallet addresses but no configuration files, 122 passwords, wallet ciphertext, or recovery phrases. deployment.sh enables this 123 automatically under release-evidence/; set IUNA_RELEASE_EVIDENCE_DIR to copy 124 release evidence to another retained location. 125 126 Use --keep on smoke to leave a failed or successful network running. Stop a 127 network without deleting its mutable data with: 128 129 ```sh 130 ./e2e/iuna_e2e.py down 131 ``` 132 133 Runtime data lives in e2e/.runtime and is ignored by Git. Set 134 IUNA_E2E_RUNTIME_DIR, IUNA_E2E_SNAPSHOTS_DIR, IUNA_E2E_PROJECT, or the 135 IUNA_E2E_*_PORT variables when a test needs independent paths or ports. 136 reset only removes the six service directories beneath that configured runtime 137 directory plus the disposable sync-node directory; committed checkpoints are 138 never touched. 139 140 ## Building mature checkpoints 141 142 checkpoints.json records the protocol boundaries worth preserving: 143 144 - 299 and 300: fallback-ticket invalidation; 145 - 999 and 1000: signing v1, replay protection, grinding resistance, and 146 objective-finality activation; 147 - 1001: the first block that can certify checkpoint 1000. 148 149 Generate all missing checkpoints during one continuous run: 150 151 ```sh 152 ./e2e/iuna_e2e.py reset 153 ./e2e/iuna_e2e.py up --build 154 ./e2e/iuna_e2e.py capture-plan 155 ``` 156 157 At five seconds per block, reaching height 1001 takes roughly 84 minutes plus 158 startup and synchronization overhead. This is a one-time fixture-building job; 159 normal tests restore the resulting checkpoints in seconds. Capture one custom 160 boundary with: 161 162 ```sh 163 ./e2e/iuna_e2e.py capture pre-objective-finality --height 999 164 ``` 165 166 Capture waits until the bootstrap SQLite checkpoint reaches the requested 167 height, then pauses all containers before copying anything. An e2e-only helper 168 materializes the canonical compact chain at the exact requested height, even if 169 the live chain advanced across that height between polls. That canonical chain 170 database and its prebuilt UI projection are paired with every node's encrypted 171 test wallet and configuration. 172 Keeping all six identities matters because their mature tickets and committee 173 lineage must remain usable after restore. Persisting the derived UI database 174 keeps mature-checkpoint startup fast. SQLite's backup API removes WAL dependence, 175 a manifest records the live source height plus every exact node height and tip, 176 and SHA-256 checksums are verified before restore. 177 178 Snapshots use the intentionally public Compose password testtesttest unless 179 IUNA_TESTNET_PASSWORD was set while they were generated. They are disposable 180 test credentials only. Use the same password when restoring a snapshot. 181 182 Commit reviewed snapshot directories under e2e/snapshots/. Do not commit the 183 mutable e2e/.runtime directory.