체인에서는 입금이 확인됐는데 잔액에 안 들어온다는 문의가 왔다. deposits 를 SELECT 해 보니 상태가 여전히 확인 중이었다.
SELECT status, confirmations, updated_at
FROM deposits WHERE txid = ?;
status 가 confirming 이고 confirmations 가 2 라 확인이 안 쌓인 것처럼 보였다.
Table of contents
Open Table of contents
증상 — 확인됐는데 안 들어오는 잔액
확인이 안 쌓였다고 보면 손으로 잔액에 반영하는 것이 다음 순서였다. 그런데 그 값이 어디서 채워지는 컬럼인지를 먼저 확인하기로 했다.
확인해 보니 confirmations 는 노드가 직접 쓰는 값이 아니라 확인 수집 워커가 gettransaction 으로 조회해 UPDATE 로 채우는 컬럼이었다.
수집 워커 실행 → 노드에 gettransaction → 컬럼 갱신
그러면 그 값은 마지막으로 수집한 시점의 확인 수를 담고 있는 것이었다.
원인 — 갱신 시각의 위치
같은 행의 updated_at 이 문의 시각보다 열흘 넘게 앞이었다.
문의 3월 20일
updated_at 3월 9일
3월 9일 뒤로 이 행이 한 번도 안 바뀐 것이다.
즉 이 값은 열흘 전에 수집된 것이고 그 뒤로 한 번도 갱신되지 않았다. 그날 프로세스 매니저를 재구성하면서 이 코인의 수집 워커만 목록에서 빠져 다시 안 올라온 것이 원인이었다. 확인이 안 쌓인 것이 아니라 쌓인 것을 볼 수 있는 값이 아니었다.
재수집이 없으면 그 시점에 멈춘다
수집으로 채워지는 컬럼은 다시 수집해 UPDATE 하지 않으면 마지막 수집 시점에서 멈춘다. 체인의 확인 수가 어떻게 쌓이든 그 값은 그대로 있다.
그래서 이런 컬럼을 볼 때는 값과 updated_at 을 함께 봐야 한다. updated_at 이 문제 발생보다 앞이면 그 값으로는 아무것도 판단할 수 없다.
원본 스냅샷과 필드 뜻
다행히 수집할 때 받은 원본 응답을 그대로 저장해 둔 자리가 있어서 그것을 열어 봤다. 거기에는 노드가 준 confirmations 가 2 로 그대로 들어 있었고 blockhash 도 있었다.
그 필드가 무엇을 뜻하는지를 Bitcoin Core 0.17 의 gettransaction 공식 문서로 확인해 보니 그 트랜잭션이 들어간 블록 위에 쌓인 블록 수라, 노드에 지금 다시 물으면 수백으로 나올 값이었다. 실제로 노드에 직접 조회하니 그렇게 나왔다. 우리 화면의 「확인 중」과 노드의 숫자가 일대일로 맞지 않아서 확인이 필요한 자리였다.
검증 — 원장 이력의 교차 확인
여기에 원장 표와 JOIN 해 실제 이력까지 교차로 봤는데 문의한 입금은 ledger_entries 에 아직 안 잡혀 있었다. 손으로 반영하는 것 대신 워커를 되살려 재수집하게 두는 쪽을 골랐다. 이유는 손으로 넣은 뒤 워커가 살아나면 같은 입금이 두 번 잡혀서다.
멈춘 값만 보고 손으로 반영했으면 며칠 뒤 이중 반영이 됐을 것이다. 값과 시각과 원본과 이력 넷을 맞춰 보고 나서야 조치가 잔액이 아니라 워커 쪽이라는 답이 나왔다.
정리
- 수집으로 채워지는 컬럼은 재수집이 없으면 멈춘다
- 멈춘 값을 보고 확인이 안 쌓였다고 오판한다
- 값과
updated_at을 함께 본다 updated_at이 문제 발생보다 앞이면 그 값은 판단 근거가 아니다- 수집 원본 스냅샷이 있으면 그것이 그 시점의 실제 상태다
- 노드 필드가 우리 값의 어느 것인지 문서로 확인한다
- 원장 표와
JOIN해 교차 확인한다 - 조치는 멈춘 값이 아니라 멈춘 수집 쪽에 한다