jam
jam copied to clipboard
fix: handle expiry date of timelocked utxos correctly
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.
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.
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.
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.
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.