Skip to content

[bug]: full recovery (seed + backup import) resets address key derivation — new addresses reuse historical script keys, breaking receives #2221

Description

@satscribe

Background

The wallet asset backup (tapcli assets backup export/import) does not preserve the address key derivation state. After a node loses its ~/.tapd directory (LND wallet intact) and restores via assets backup import, every new tapcli addrs new re-derives script keys that were already used by pre-loss addresses/outputs. The custodian logs make this visible:

GRDN: Taproot addr <p2tr> was already added to wallet before, skipping

A counterparty that holds proofs for those historical script keys (e.g. the node that originally sent assets to this wallet) then fails to send to any new address of the restored node:

unable to fund address send: error funding packet:
error extracting allocations: output amount exceeds input sum

The same sender pays a fresh third node without issues, and the restored node's addresses were confirmed to carry script keys identical to keys that currently anchor existing assets (we observed a new address re-using the exact script key that holds the wallet's own current balance).

Net effect: a node restored from the native backup cannot receive from its previous counterparties — in practice its main peers — and on-chain address/key reuse is silently reintroduced. A file-level backup of ~/.tapd (which preserves the key counters) does not exhibit the problem.

This compounds with #2220 (grouped assets restored unspendable): together they mean the native backup path currently cannot fully recover a wallet.

Your environment

  • tapd v0.8.0-alpha (commit v0.8.0), integrated mode inside litd v0.17.0-alpha
  • lnd v0.21.1-beta (integrated)
  • regtest, bitcoind 27.1 backend, Docker (official lightninglabs/lightning-terminal:v0.17.0-alpha image)

Steps to reproduce

  1. Node A mints an asset and sends 100 units to node B via a V1 address (universe proof courier); do a few back-and-forth transfers so several script keys have been used.
  2. Node B: tapcli assets backup export --mode raw --output_file b.bin.
  3. Stop node B; move ~/.tapd away (keep ~/.lnd untouched); start node B; tapcli assets backup import --backup_file b.bin.
  4. Node B: tapcli addrs new --asset_id <id> --amt 9 → tapd logs "already added to wallet before, skipping"; the new address's script key equals a historical one.
  5. Node A: tapcli assets send --addr <new B address> → fails with "output amount exceeds input sum". Repeating with additional fresh addresses from B fails the same way; sending to a clean node C succeeds.

Expected behaviour

Either the backup carries the address/script-key derivation state, or the restore path re-syncs the key index (or addrs new skips keys that already have proofs/outputs), so that a restored wallet can safely receive again without key reuse.

Actual behaviour

Restored wallets re-derive already-used script keys; senders holding proofs for those keys fail with allocation errors, and address reuse is reintroduced silently.

Metadata

Metadata

Assignees

Labels

backupbugSomething isn't working

Type

No type

Projects

Status
✅ Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions