feat(pesos): spec 21 con el certificado de Laurha, en vivo desde el bloque 98268

GSUN-3 (dos tercios para pagar del tesoro, commit anterior) entra con sus pesos medidos.

- scripts/bench/certificados/2026-11-02-spec21-laurha.rs: el fundido de Laurha
  (sha256 03fbaf72), el máximo de 5 procesos en el santuario de la rp1 sobre el wasm de banco
  6f75bb59. Control negativo de Laurha: en el mínimo, las 14 que no cambian quedan entre
  0,990 y 1,002.
- weights.rs: submit_treasury_proposal, finalize_proposal y finalize_override cambian de
  esqueleto (leen y escriben TreasurySupermajorityOf). Se les puso el bloque del certificado y
  luego se ensamblaron los cuatro certificados. --comprobar coincide, y ningún peso baja
  respecto a spec 20.
- Cola de cast_vote: 130,07 µs de un solo proceso. Se cobra; sobre spec 20 (127,72) es un +1,8 %.
- E2E (rv17_tesoro.py) paso 2e: busca el bloque del upgrade sólo dentro de la ventana de estado
  del nodo (~256 bloques), o lo toma de ORIGIN_BLOQUE_UPGRADE. La primera versión pedía el
  estado de bloques podados y el RPC no respondía.

En vivo en la testnet de la casa, con el WASM 048ea752:
- contrafactual: contra spec 20, el E2E reprueba en 2c porque TreasurySupermajorityOf no existe;
- set_code en el bloque 98268: CodeUpdated, la firma vieja se rechaza, la nueva entra, y la
  finalidad avanza;
- E2E verde del 0 al 5, con 2c (2, 3), 2d (la sembrada sin marca) y 2e (frontera en 98268:
  5 propuestas de antes sin marca y 2 de después con ella).

Pruebas: 373 del workspace, 0 fallan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
CharonandClaude Opus 5.5 committed 2026-11-03 23:39:47 -05:00
1 parent 4be7da78c3
commit 935ca1ef5e
3 files changed
+841 -57

No files matched your search

+28 -10
View File
@@ -306,18 +306,36 @@ def frontera_del_upgrade():
"""2e · B = primer bloque cuyo estado dice spec >= 21 (búsqueda binaria). Una propuesta de
tesoro con start_block <= B la creó el runtime anterior y no lleva marca; una posterior,
sí. Cualquier otra combinación reprueba."""
# Un nodo que no es de archivo sólo guarda el estado de los últimos ~256 bloques (medido el
# 3-nov: la primera versión buscaba por toda la cadena y el RPC no tenía el estado de los
# bloques viejos). Se busca dentro de esa ventana; si el upgrade es más viejo, se pasa
# ORIGIN_BLOQUE_UPGRADE (lo imprime upgrade_en_vivo.py en su paso 1).
def spec(n):
return rpc("state_getRuntimeVersion", [rpc("chain_getBlockHash", [n])["result"]])["result"]["specVersion"]
lo, hi = 0, best()
if spec(hi) < 21:
h = rpc("chain_getBlockHash", [n]).get("result")
r = rpc("state_getRuntimeVersion", [h]) if h else {}
return r.get("result", {}).get("specVersion") # None si el estado ya está podado
hi = best()
if (spec(hi) or 0) < 21:
falla("2e: la cadena no llegó a spec 21")
while lo < hi:
mid = (lo + hi) // 2
if spec(mid) >= 21:
hi = mid
else:
lo = mid + 1
b = lo
if os.environ.get("ORIGIN_BLOQUE_UPGRADE"):
b = int(os.environ["ORIGIN_BLOQUE_UPGRADE"])
if spec(b) is not None and spec(b) < 21:
falla(f"2e: ORIGIN_BLOQUE_UPGRADE={b} todavía es spec {spec(b)}")
if spec(b - 1) is not None and spec(b - 1) >= 21:
falla(f"2e: ORIGIN_BLOQUE_UPGRADE={b} no es el primero en spec 21")
else:
lo = max(0, hi - 250)
if spec(lo) is None:
falla(f"2e: el nodo no tiene el estado del bloque #{lo}; pasa ORIGIN_BLOQUE_UPGRADE")
if spec(lo) >= 21:
falla(f"2e: el upgrade es anterior a #{lo}, fuera de la ventana de estado; pasa ORIGIN_BLOQUE_UPGRADE")
while lo < hi:
mid = (lo + hi) // 2
if spec(mid) >= 21:
hi = mid
else:
lo = mid + 1
b = lo
pref = "0x" + twox128("Governance") + twox128("TreasuryActions")
claves, desde = [], None
while True: