diff --git a/app/core/_secrets.py b/app/core/_secrets.py index 989f8af..54902bb 100644 --- a/app/core/_secrets.py +++ b/app/core/_secrets.py @@ -41,15 +41,20 @@ def _init_seed_via_db() -> bytes: # Wait for table to exist start = time.time() - with engine.connect() as conn: - while not db_ready(conn): - time.sleep(0.5) - if time.time() - start > 120: - raise TimeoutError("service_config table not available") + # Wait for table existence, reconnecting to avoid stale transactions + while True: + with engine.connect() as conn: + if db_ready(conn): + break + time.sleep(0.5) + if time.time() - start > 120: + raise TimeoutError("service_config table not available") - def read_seed() -> Optional[bytes]: - try: - with Session(bind=conn) as s: + def read_seed() -> Optional[bytes]: + # Use a fresh connection/session per read to avoid snapshot staleness + try: + with engine.connect() as rconn: + with Session(bind=rconn) as s: row = s.query(ServiceConfigValue).filter(ServiceConfigValue.key == 'private_key').first() if not row: return None @@ -58,8 +63,8 @@ def _init_seed_via_db() -> bytes: packed = json.loads(packed) seed_hex = packed.get('value') return bytes.fromhex(seed_hex) if seed_hex else None - except Exception: - return None + except Exception: + return None seed = read_seed() if seed: @@ -69,16 +74,13 @@ def _init_seed_via_db() -> bytes: seed = _load_seed_from_env_or_generate() # Try insert; if another primary raced, ignore try: - with Session(bind=conn) as s: - s.add(ServiceConfigValue(key='private_key', packed_value={"value": seed.hex()})) - s.commit() + with engine.connect() as wconn: + with Session(bind=wconn) as s: + s.add(ServiceConfigValue(key='private_key', packed_value={"value": seed.hex()})) + s.commit() make_log("HotWallet", "Seed saved in service_config by primary", level='info') return seed except Exception: - try: - conn.rollback() - except Exception: - pass # Read again in case of race seed2 = read_seed() if seed2: