jam icon indicating copy to clipboard operation
jam copied to clipboard

fix: handle expiry date of timelocked utxos correctly

Open theborakompanioni opened this issue 2 years ago • 1 comments

Good: Jam does not let you unfreeze timelocked addresses before it's expiration date.

Problem: However, currently, Jam will treat any utxo with a truthy value for "locktime" as locked, hence non-spendable.

Timelocked utxos have a "locktime" attribute, e.g.

{
  "utxos": [
    {
      "address": "bcrt1qh9l476ezjfexhhzjkrx7ndnjlqz42c679tmlrxv7yfl3sgkn9e9sm3qqat",
      "path": "m/84'/1'/0'/2/24:1640995200",
      "label": "",
      "value": 12345678,
      "tries": 0,
      "tries_remaining": 3,
      "external": false,
      "mixdepth": 0,
      "confirmations": 1,
      "frozen": false,
      "locktime": "2022-01-01 00:00:00",
      "utxo": "1fe0743adc0992b45c49e40f9f613e8486df581e7d754d4cde17957b7d92256e:0"
    }
  ]
}

If the "locktime" value represents a date in the past, the utxo is spendable. Notice the "path" includes the expiry date as unix timestamp separated from the BIP32 path.

~~It seems jmwalletd will unfreeze timelocked funds when the expiry date has passed - at least if you deposit to an address with a timelock in the past; no test was done what happens when the funds expire naturally by actual passing of time.~~ Jam should possibly only take "frozen" utxos into account, when calculating the "spendable" amount.

theborakompanioni avatar Jun 01 '22 10:06 theborakompanioni

It seems jmwalletd will unfreeze timelocked funds when the expiry date has passed - at least if you deposit to an address with a timelock in the past; no test was done what happens when the funds expire naturally by actual passing of time.

Not quite. From fidelity-bonds.md#spending-time-locked-coins:

Coins living on time-locked addresses are automatically frozen with JoinMarket's coin control feature, so before spending you need to unfreeze the coins.

It is not possible to passively spend these untimelocked coins in your yield generator [...]

It is possible to spend these untimelocked coins in a coinjoin as a taker.

theborakompanioni avatar Jun 03 '22 00:06 theborakompanioni

Jam should possibly only take "frozen" UTXOs into account, when calculating the "spendable" amount.

So you mean we should completely ignore timelocked UTXOs? I'm not sure I understand what you're suggesting correctly.

dergigi avatar Sep 14 '22 12:09 dergigi

So you mean we should completely ignore timelocked UTXOs? I'm not sure I understand what you're suggesting correctly.

At the time the statement was made the believe was that timelocked addresses are always frozen before the expiry date is reached, but you can in fact unfreeze the utxo before the date is reached (not in Jam, but from the command line or manually via the API). This will lead to errors, e.g. when the Jar A (FBs are always in Jar A) is swept. But it is definitely an edge case we should not worry too much about.

The code changed quite a bit already since the ticket was created. Before, the code was:

const frozenOrLockedUtxos = utxos.filter((utxo) => utxo.frozen || utxo.locktime)

Currently it is already taking into account the actual locktime value:

  const frozenOrLockedUtxos = utxos.filter((utxo) => utxo.frozen || fb.utxo.isLocked(utxo, refTime))

I will review the behaviour and make adaptions, if it's even necessary at all.

theborakompanioni avatar Sep 15 '22 09:09 theborakompanioni

So, after testing this again, it seems everything is handled correctly.

We might have another issue with getting rid of expired non-frozed FB utxo, though: https://github.com/JoinMarket-Org/joinmarket-clientserver/issues/1369 As this is not related to this issue, I am closing it now. Feel free to reopen if you think this is a mistake.

theborakompanioni avatar Sep 29 '22 14:09 theborakompanioni