"""Why does tradingEnabled stay 0 after we send it? Verify the arm -> index -> byte chain. REFUTED LIVE 2026-08-06. We served {"type":"tradingEnabled","value":1} on BOTH delivery paths (the standalone /settings route and the userMassInfo.settings member), the client fetched settings four times, and the gate byte 0x1fd2e stayed 0 while the three control gates stayed 1. So the claim "FUT_SETTINGS=keep opens the trading gate" is wrong. This file finds out where the chain actually breaks. THE CHAIN AS CURRENTLY BELIEVED, and every link is a candidate for being the wrong one: 1. deser FUN_18013c6d0 hashes the STRING value of "type" and switches, 42 arms wide. tradingEnabled is atom 0x336. 2. that arm stores into some index of a settings struct 3. applier FUN_18011dc50 copies `param_2[10] == 1` into gate byte +0x1fd2e, and that line was LABELLED tradingEnabled 4. service vtable slot +0x270 reads 0x1fd2e The label in step 3 was inferred from ordering, never verified against step 2. If the tradingEnabled arm writes an index other than 10, the label is simply wrong and 0x1fd2e belongs to some other flag we are not sending. FOUR HYPOTHESES, and the query is designed to separate them rather than confirm one: H1 wrong index: the 0x336 arm writes an index the applier does not copy to 0x1fd2e. H2 the applier never re-runs after a settings response; it runs once, early, from defaults. That fits this morning's observation that the other three gates read 1 with an EMPTY configs array, i.e. from constructor defaults, and would mean NO /settings response can ever move any gate byte. H3 the applier runs but reads a different settings struct instance than the deser wrote. H4 the arm needs a different value shape (a string "1", a bool) than our int 1. CONTROLS: storeEnabled (0x2f1) is labelled as writing +0x1fd2f from param_2[0xb], and the store demonstrably works, so whatever is true of tradingEnabled must be consistent with storeEnabled too. Do the same trace for BOTH and compare. If the store works via a path that does NOT involve this applier (it is known to arrive through the Blaze client-config store), then storeEnabled is NOT a valid control and say so. COVERAGE: print both functions IN FULL with lengths. No absence claim from a truncation. Remember the dispatch-form trap: enumerate case labels, == and != forms, and sub/dec ladders before saying an atom is absent. """ import re import traceback DESER = 0x18013C6D0 # /settings deserializer, 42 arms APPLIER = 0x18011DC50 # the only writer of the gate bytes A_TRADING = 0x336 A_STORE = 0x2F1 def dump(va, title): f = func(va) src = dec(va) print("\n" + "=" * 78) print("%#x %s body %d bytes / decompile %d chars (IN FULL)" % (va, title, f.getBody().getNumAddresses() if f else -1, len(src))) print("=" * 78) print(src) return src try: dsrc = dump(DESER, "settings deserializer") asrc = dump(APPLIER, "gate-byte applier") print("\n" + "=" * 78) print("DISPATCH TARGETS IN THE DESERIALIZER, all four forms") print("=" * 78) found = set() for m in re.finditer(r"case (0x[0-9a-f]+|\d+):", dsrc): found.add(int(m.group(1), 0)) for m in re.finditer(r"[!=]= (0x[0-9a-f]+)\b", dsrc): found.add(int(m.group(1), 16)) print(" %d targets" % len(found)) for a, n in (("tradingEnabled", A_TRADING), ("storeEnabled", A_STORE)): print(" %-16s %#-6x %s" % (a, n, "PRESENT" if n in found else "ABSENT")) print("\n--- the tradingEnabled and storeEnabled arm bodies, to read the index each writes ---") lines = dsrc.split("\n") for want, label in ((A_TRADING, "tradingEnabled"), (A_STORE, "storeEnabled")): idx = None for i, l in enumerate(lines): if re.match(r"\s*case %s:" % hex(want), l) or ("== %s" % hex(want)) in l: idx = i break print("\n### %s (%#x) ###" % (label, want)) if idx is None: print(" not located by either form") continue out = [lines[idx]] for l in lines[idx + 1:]: if re.match(r"\s*case (0x[0-9a-f]+|\d+):", l): break out.append(l) if len(out) > 14: break print("\n".join(out)) print("\n" + "=" * 78) print("APPLIER: every gate-byte write, so the index->byte map can be read directly") print("=" * 78) for l in asrc.split("\n"): if "0x1fd" in l: print(" " + l.strip()) print("\n" + "=" * 78) print("H2: WHO CALLS THE APPLIER, and is it reachable from the settings deserializer?") print("=" * 78) for a, n in callers(APPLIER): print(" caller %#x %s" % (a, n)) print("\n callers of the DESERIALIZER:") for a, n in callers(DESER): print(" caller %#x %s" % (a, n)) print("\n does the deserializer (or anything it calls) reach the applier?") seen, stack, hit = set(), [DESER], [] while stack: cur = stack.pop() if cur in seen: continue seen.add(cur) for a, n in callees(cur): if a == APPLIER: hit.append(cur) if a not in seen and len(seen) < 400: stack.append(a) print(" reached from: %s" % (" ".join("%#x" % h for h in hit) or "NOT REACHABLE within 400 nodes")) except Exception: traceback.print_exc()