feat(merge): run per-address consolidation as a paced background job

"Keep in each address" posted one task that called z_mergetoaddress for
every batch of every address back to back; each call is a whole-wallet
scan under cs_main, and the daemon runs the ops one at a time anyway.
It is now an App-owned services::ConsolidationRun:

- one RPC at a time; the next merge only after the previous batch left the
  queue and a gap as long as the last call took (2-120 s);
- pauses while the node syncs, the wallet is locked, a send of ours is in
  progress, or another wallet scan is running;
- failures classified: nothing that may have queued is ever resent; a
  breaker stops after 3 dead addresses or 3 failed ops in a row;
- each merge is charged to the scan budget; one re-read and one forced
  balance at the end;
- it keeps running when the dialog closes: a status-bar chip, a run view
  with progress, the wait reason and a Stop button.

The "Into one" merge can no longer be confirmed twice while its call is
in flight. fake_dragonxd gains FAKE_SCAN_SECS, FAKE_MERGE_SERIAL and
FAKE_MERGE_FAIL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-09 11:06:34 -05:00
co-authored by Claude Opus 5.5
parent b29a09eaa0
commit cee8b9d7f6
19 changed files with 1875 additions and 202 deletions
+16
View File
@@ -1183,6 +1183,22 @@
"merge_max_inputs": "배치당 최대 입력 수",
"merge_no_spendable": "아직 통합할 사용 가능한 입력이 없습니다.",
"merge_progress": "통합 중… 몇 분 정도 걸릴 수 있습니다. 이 창을 닫아도 됩니다.",
"merge_run_aborted_toast": "노드 연결이 재설정되어 통합이 중지되었습니다. 계속하려면 다시 실행하세요.",
"merge_run_busy": "통합이 진행 중입니다. 완료될 때까지 기다리거나 먼저 중지하세요.",
"merge_run_chip_fmt": "통합 중 %d/%d",
"merge_run_err_timeout": "노드가 제때 응답하지 않았습니다. 배치가 아직 대기열에 있을 수 있습니다.",
"merge_run_halted_fmt": "반복된 실패로 통합이 중지되었습니다: %s",
"merge_run_migration_pending": "통합하기 전에 시드 마이그레이션을 완료하거나 취소하세요.",
"merge_run_progress_fmt": "통합 중… 배치 %d(약 %d개 중), 지금까지 노트 %d개 병합됨. 이 창을 닫아도 백그라운드에서 계속 진행됩니다.",
"merge_run_start_failed": "통합을 시작할 수 없습니다 — 노드가 연결되어 있지 않습니다.",
"merge_run_status_not_run": "%s — 통합 안 됨(노트 %d개)",
"merge_run_status_waiting": "%s — 대기 중(노트 %d개)",
"merge_run_stop": "중지",
"merge_run_stopped_toast": "통합이 중지되었습니다. 나머지를 병합하려면 다시 실행하세요.",
"merge_run_stopping": "이미 보낸 배치가 끝나면 중지합니다…",
"merge_run_wait_batch": "노드가 응답성을 유지하도록 배치 간격을 두는 중…",
"merge_run_wait_send": "보류 중인 거래가 완료될 때까지 일시 중지됩니다.",
"merge_run_wait_sync": "일시 중지됨: 노드가 아직 동기화 중입니다.",
"merge_scope_failed_fmt": "입력을 읽을 수 없습니다: %s",
"merge_scope_fmt": "투명 입력 %d개 + 보호 입력 %d개 · 사용 가능 약 %s DRGX",
"merge_scope_loading": "입력을 확인하는 중…",