외부 서비스를 쓰지 않고 노드를 직접 띄워서 운영하고 있었다. 남의 것을 쓰면 그쪽이 멈출 때 우리도 함께 멈추기 때문이다. 대신 우리 노드가 네트워크와 어긋났을 때를 우리가 다뤄야 했다.
Table of contents
Open Table of contents
뒤처져 있어도 대답한다
노드에 잔액을 물으면 대답하는데 그 대답은 노드가 아는 block height 까지의 것이다. 네트워크가 1000번째까지 갔는데 우리 노드가 900번째까지만 받았으면 900번째 기준으로 답하고 그것이 오류 없이 정상 응답으로 온다.
입금이 들어왔는데 노드가 아직 그 블록을 못 받았으면 「입금 없음」이 된다. 사용자는 보냈다고 하는데 우리는 없다고 하는 상태가 된다. 오류가 나면 알 수 있지만 조용히 옛 값이 오면 알 방법이 없었다.
얼마나 뒤처졌는지 재기
자기가 뒤처졌는지는 자기만 봐서는 알 수 없는데 자기가 아는 block height 가 네트워크의 최신인지 확인할 RPC 가 그 안에 없기 때문이다.
그래서 확인을 세 단계로 두었다.
1. 우리 노드가 아는 마지막 block height 를 묻는다
2. 다른 곳에서 네트워크의 최신 block height 를 확인한다
3. 차이를 본다
2번이 문제인데 우리 노드만으로는 자기가 뒤처졌는지 알 수 없어서 공개 조회 서비스 두세 곳을 보고 서로 맞는지 확인한다. 밖과 비교하지 않으면 뒤처졌다는 사실 자체를 알 수 없다는 것이 이 문제의 핵심이었다.
선택지 — 틀린 값보다 멈추는 쪽
차이가 클 때 옛 값이라도 주는 것과 아예 응답을 안 하는 것 중에 무엇을 할지도 정해야 했다.
우리 경우에는 틀린 값이 훨씬 나빴으므로 block height 차이가 기준을 넘으면 조회 자체를 멈추게 했다. 화면에는 지금 확인할 수 없다는 안내가 나간다. 틀린 값으로 판단이 이루어지는 것보다 잠시 못 보는 편이 나았다.
확정되기 전의 값
또 하나는 네트워크 사정에 따라 이미 반영된 것으로 보이던 것이 나중에 되돌려질 수 있다는 점이었다.
네트워크에 갈래가 생겼다가 한쪽이 이기면 진 쪽 내용은 없던 것이 되므로 바로 확정하지 않고 confirmations 가 일정 수를 넘은 뒤에야 확정한다.
| 시점 | 상태 |
|---|---|
| 처음 보였을 때 | 대기 |
| 몇 개 더 쌓인 뒤 | 확인 중 |
| 충분히 쌓인 뒤 | 확정 |
그 수만큼의 블록을 다시 만들어야 그 거래를 지우거나 바꿀 수 있기 때문이고 몇 개를 기다릴지는 네트워크마다 달라 관례를 따랐다. 얼마나 기다릴지는 금액에 따라 다르게 잡았는데 큰 금액일수록 더 기다리게 했다.
멈춘 것을 알아채기
ps 에 프로세스가 살아 있어도 디스크가 찼거나 다른 노드와 연결이 끊겨 진행이 멈추는 경우가 있어서 block height 가 올라가는지를 cron 으로 감시했다.
5분 전 번호와 지금 번호가 같으면 → 멈춘 것
block height 가 5분 동안 안 올라가면 멈춘 것으로 본다. 다만 우리 것만 안 올라가는지 네트워크 전체가 느린지도 함께 봐야 했는데 그래야 우리 문제인지 판정된다. 체인 자료가 계속 늘어나는 것도 df 로 따로 감시해서 여유가 줄면 미리 알게 했는데 디스크가 차는 것이 block height 가 멈추는 원인 중 하나였기 때문이다.
정리
block height가 낮아도 노드는 오류 없이 대답한다- 부르는 쪽은 정상 응답으로 받아 그대로 쓴다
- 자기
block height가 최신인지는 자기만 봐서는 알 수 없다 - 밖의
block height와 비교해야 차이가 드러난다 - 차이가 크면 틀린 값을 주느니 조회를 멈춘다
- 한 번 보인 것이 취소될 수 있다
confirmations가 일정 수를 넘은 뒤에 확정으로 취급한다- 우리만 안 올라가는지 전체가 느린지 함께 본다