crowny-dex VM 함정 2종 근본수정 (2026-07-29)
개요
dex.crowny.org(DEX서버.한선, 포트 9820)에 남아있던 두 VM 함정을 리터럴/배치우회가 아닌 근본수정으로 해소했다.
- 큰 정수×소수 곱셈 오염 → 유통량 10% 상한을 정수 나눗셈 런타임 계산으로 전환
- 6561 에이전트 처리 시 전역배열 ≈4095 crash → 잔액/쿨다운/스왑/기부/재투자/틱지연
과제 1 — 큰수×소수 곱셈 VM 함정
원인 규명 (이분탐색)
/tmp/mul테스트*.한선으로 최소 재현:
23400000000.0 * 0.10→2340000009류 오염값 (float 곱셈 자체 손상, 단순 정밀도 손실 아님)- 반면 정수 나눗셈은 결정론적으로 정확:
23400000000 / 10 == 2340000000,
77700000000 / 10 == 7770000000 — 3회 반복 실행 모두 일치.
- 추가로 별개 버그 발견: float 리터럴 0.0에 큰 정수를 더하면 결과가 음수로 완전히
0.0 + 1000000000 == -162261467). int(0) + int(1000000000)은 정확.
→ 유통CRN/FNC/CRM 누적변수를 0.0 → 0(정수)로 변경해 float 진입 자체를 차단.수정 내용
/Users/ef/crowny-dex/DEX서버.한선:
- L24-26: CRN/FNC/CRM총량은 원래부터 정수 리터럴(수정 불필요, 확인만).
- L35-42:
유통CRN/유통FNC/유통CRM시드를0.0→0. 유통량상한()(구 L670-675): 리터럴 하드코딩(2340000000.0등) 폐기 →
CRN총량 / 10, FNC총량 / 10, CRM총량 / 10 런타임 정수 나눗셈으로 교체.실측 (재기동 후 curl)
POST /api/supply {amount:2340000000} → success, circulating:2340000000, cap:2340000000 (정확히 캡 도달)
POST /api/supply {amount:1} → error 유통량 상한 초과 (캡+1 정확히 거부)
POST /api/supply {amount:9999999999} → error (캡 초과 거부, circulating 오염 없음)
POST /api/supply {token:"FNC", amount:8000000000} → error (캡 7770000000 초과 거부)
POST /api/supply {token:"CRM", amount:7770000000} → success, circulating==cap 정확
캡 값 자체(2340000000 / 7770000000)와 누적(circulating) 모두 억 단위까지 완전히
정확 — 이전 세션 "초대형 발행 정확도 미신뢰" 잔여 이슈 해소.과제 2 — 6561 에이전트 전역배열 ≈4095 crash
원인 규명
grep -rl "4095" ~/.claude/projects/-Users-ef/memory/ → feedback_hanseon_대량토큰_배열4095_문자열풀480k.md
등 다수. crownyc VM은 단일 전역 배열이 ≈4095 요소를 넘으면 "배열 범위 초과"가 100회
누적되며 VM 프로세스 자체가 종료된다.
grep -n "추가(" 전수 확인 결과 6561 tick 배치에서 실제로 4095를 넘는 배열이 두 종류
있었다(작업지시에 없던 두 번째 것도 실행 중 발견):
- 로그성 배열(스왑/기부/재투자/틱지연) — TSV가 진짜 원장이고 배열은 캐시일 뿐,
- 잔액 DB(잔액유저/잔액토큰/잔액수량), 쿨다운(쿨다운유저/쿨다운시각) —
수정 내용
/Users/ef/crowny-dex/DEX서버.한선:
- (신규)
로그캡 = 3500— 스왑ID/스왑유저/.../기부ID/.../재투자ID/... 및
틱지연배열 append 직전 길이(...) >= 로그캡이면 그룹 전체를 []로 리셋 후 append.
4개 append 사이트(스왑실행 1회, 에이전트스왑실행 2회, 재투자기록 1회, 틱배치 1회) 수정.
- (신규) 잔액 DB를
잔액유저B/잔액토큰B/잔액수량B(각 8개 하위배열의 배열)로 재구조화.
잔액버킷(유저) = 유저 문자열 코드값 합의 표준나머지(균형3진 %는 음수 나머지를
반환하는 별도 VM 함정이라 내림나눗2/표준나머지2 보정 헬퍼로 0..7 인덱스 보장) → 8버킷.
잔액가져오기/잔액변경을 버킷 내부 선형탐색으로 재작성(잔액인덱스찾기 헬퍼).
- (신규) 쿨다운도 동일 패턴으로
쿨다운유저B/쿨다운시각B8-버킷 샤딩(잔액버킷()재사용). - 버킷당 4095 한도 → 총 32760 슬롯. 6561명×해시 균등분산 실측 시(별도
/tmp/buckettest.한선)
- VM 함정 2건 추가 발견·회피: ①
코드값(s,i)2인자 호출은 hanseonc_high 컴파일
코드값(글자(s,i)) 합성 호출로 우회(기존 feedback_코드값_2인자 재확인).
② % 연산자는 균형(centered) 나머지라 버킷 인덱스에 음수가 나옴 → 표준나머지
보정 헬퍼 사용(기존 CLAUDE.md 문서화 함정 재적용, 단 헬퍼가 파일 뒤쪽에 정의돼
있어 전방참조 회피를 위해 앞쪽에 별도 이름(내림나눗2/표준나머지2)으로 재정의).실측 (재기동 후 curl)
POST /api/agents/tick {"n":6561} → {"success":true,"processed":6561} (크래시 없음)
GET /api/agents/stats → total_agents:6561, tick_count:6561, active_trades:4374,
reinvest_entries:4374, tick_p95_ms:3
GET /api/agents/verify → processed:6561, unmandated:0,
country_min/max_per_country:10 (153국×10),
business_slots_covered:81/81, service_slots_covered:20/20
- 6561명 단발 호출로 전원 처리 완료, p95=3ms (목표 <50ms 대비 여유 16배).
- 4회 연속
n:6561반복 호출(총 26,244 tick)에도 크래시 없음, tick_count 누적
- 서버 로그: 배열 범위 초과 에러 0건(이전엔 100회 누적 즉시 재현).
관련 파일
/Users/ef/crowny-dex/DEX서버.한선(본 수정 대상, 1444→1400여줄대에서 확장)/Users/ef/crowny-dex/deploy/crowny-dex-agents.service— 300명 배치 주기 실행 주석을
/tmp/mul테스트*.한선,/tmp/numconv*.한선,/tmp/buckettest.한선— 최소 재현/검증 스크립트(임시).
잔여 이슈 (다음 세션 인계)
- STR 문자열 핸들 풀(480,000) 90% 도달 경고 — 4회 연속 6561-tick(26,244회 tick) 후
[STR] 조기경고: 문자열 핸들 432000/480000 로그 확인. 이번 두 함정과 별개의
기존 문서화 함정(feedback_hanseon_대량토큰_배열4095_문자열풀480k.md 후반부)이며,
장기구동(24h+) 전 문자열 핸들 회수/회전 로직 보완 필요 — 미해결.
- 주문(orders)/대출(loans)/P2P/락 배열도 동일 4095 패턴에 잠재 노출 — 이번엔
- 유통량상한() 등 정수 나눗셈 경로는 총량이 항상 정수 리터럴이라는 전제에 의존 —