071-auto-refresh.rst (15151B)
1 DD 71: Auto-refresh 2 ################### 3 4 :Design status: Proposed 5 :Implementation status: Prototype 6 :DD shepherd: TBD 7 :Historical contributors: Christian Grothoff 8 :First published: 2025-10-23 9 :Last substantive change: 2026-09-05 10 :Implementation evidence: ``taler-typescript-core`` commit ``4889bee049023c59a125973532b847ec60ab6f1b`` (2026-08-19, feature-branch prototype of the earlier policy) 11 12 Summary 13 ======= 14 15 This document describes when the wallet should automatically refresh 16 non-dirty coins, how exchanges should configure denomination keys for this 17 policy, and how the wallet can bound the cost of keeping a balance. 18 19 It addresses `issue 6563 <https://bugs.gnunet.org/view.php?id=6563>`_, 20 including predictable refresh costs, and its duplicate 21 `issue 7847 <https://bugs.gnunet.org/view.php?id=7847>`_, about synchronized 22 refresh traffic. 23 24 .. note:: 25 26 The prototype implements the earlier policy, not the revisions proposed here. 27 28 29 Motivation 30 ========== 31 32 The wallet must refresh non-dirty coins before they expire, lest the user 33 lose money. Refreshing too early causes avoidable fees and exchange load; 34 waiting too long risks the wallet not going online before expiration. 35 No policy can protect a wallet that remains offline beyond its coins' 36 validity periods. 37 38 39 Requirements 40 ============ 41 42 * Preserve funds under ordinary operating conditions, without clearly 43 avoidable refresh operations. 44 * Spread automatic refresh traffic across wallets holding the same 45 denomination, including when an exchange publishes replacement keys. 46 * Explain expiration risk and the conditions under which refresh-cost 47 estimates apply. 48 * Within an equivalence class of otherwise interchangeable coins, the wallet 49 MUST spend those with the earliest deposit expiration first. 50 * Account for different denomination lifetimes and changes in the exchange's 51 offerings. Operator recommendations are not assumptions that the wallet may 52 make about an arbitrary exchange. 53 54 55 Proposed Solution 56 ================= 57 58 Lifetimes and output selection 59 ------------------------------ 60 61 A day means 24 hours. The thresholds below use fixed durations of 90, 180, 62 and 360 days, not calendar months. For an input denomination define:: 63 64 D = stamp_expire_deposit 65 W = stamp_expire_withdraw 66 G = D - W 67 R = D - now 68 E = min(90 days, G / 4) 69 70 ``G`` is the deposit period after withdrawals close; ``E`` is the adaptive 71 emergency threshold. This policy requires finite timestamps with ``G > 0``. 72 An invalid lifetime must be reported rather than used to schedule refreshes. 73 Already-expired coins follow existing expiry/recovery handling; they must not 74 be treated as ordinary auto-refresh candidates. 75 76 For each eligible input coin, consider feasible, nonempty output selections 77 from currently withdrawable, verified, non-revoked, non-lost denomination 78 keys at its exchange. Respect currency, cipher, age restrictions, and refresh 79 protocol limits. The input must be fresh and available, rather than reserved 80 for a payment or already participating in a refresh. 81 82 Selections must fit the input value after melting and output withdrawal fees, 83 as specified by ``/melt`` in the :doc:`exchange API <../core/api-exchange>`:: 84 85 recovered_value = sum of output coin face values 86 total_cost = input_value - recovered_value 87 output_expiration = earliest deposit expiration among selected outputs 88 output_remaining = output_expiration - now 89 90 ``total_cost`` includes melting fees, output withdrawal fees, and value that 91 cannot be represented by the selected denominations. A refresh is free only 92 if ``total_cost`` is zero, not merely when ``fee_refresh`` is zero. 93 94 Select outputs in this order, before evaluating the refresh rules: 95 96 1. Maximize recovered value. 97 2. Among equally valuable selections, maximize ``output_expiration``. 98 3. Among remaining ties, minimize the number of output coins. 99 4. Break remaining ties by the lexicographic order of sorted denomination 100 hash/count pairs. 101 102 If the chosen selection cannot extend validity or recover positive value, 103 do not melt; wait and report expiration risk when applicable. 104 105 The decision and execution MUST use the same selected outputs. Revalidate 106 input availability, keys, and rule eligibility before melting. If the plan 107 has become invalid, recompute it rather than silently executing a different 108 selection. Once a melt has succeeded, finish that refresh using its committed 109 outputs through the existing refresh lifecycle. 110 111 Refresh rules 112 ------------- 113 114 Evaluate the following rules in priority order using the chosen output 115 selection. Any matching rule makes the input eligible for scheduled refresh: 116 117 1. ``output_remaining > 4 * R``: the refresh provides a substantial extension. 118 2. ``R < 180 days``, ``output_remaining > 360 days``, ``total_cost == 0``, and 119 confirmed external power: opportunistically refresh without losing value. 120 Unknown power state does not qualify for this rule. 121 3. ``R < E`` and ``output_expiration > D``: attempt an emergency extension. 122 123 All inequalities are strict. Equality alone does not satisfy a rule; schedule 124 its next evaluation for the first representable time after the boundary. 125 Battery state gates only rule 2, not necessary refreshes under rules 1 or 3. 126 Apply the decision to all available coins of the input denomination with the 127 same value and compatibility constraints. 128 129 A currently withdrawable output has at least its own ``G`` remaining, well 130 above its emergency threshold of at most ``G / 4``. This prevents repeated 131 emergency refreshes merely because slightly newer short-lived keys appear. 132 133 Scheduling and retries 134 ---------------------- 135 136 On first observing eligibility, choose an independent uniform random delay 137 per wallet and input denomination, using private wallet randomness:: 138 139 urgent_boundary = D - E / 10 140 delay_cap = min(1 day, E / 10, (urgent_boundary - now) / 2) 141 142 Before the urgent boundary, draw a delay from zero to ``delay_cap`` and 143 persist the execution deadline. At or beyond that boundary, attempt refresh 144 immediately. This spreads traffic across wallets, including when new keys 145 are published, while retaining time for retries. 146 147 Restarts, checks, and key updates MUST NOT redraw or postpone the deadline. 148 A missed deadline is due immediately if still eligible. Otherwise retain it 149 until a valid plan is available, without repeatedly executing an ineligible 150 task. Move it earlier if needed for urgency; clear it when no applicable fresh 151 coins remain. Coins of the same denomination may share a wallet's deadline. 152 153 Reevaluate on startup, relevant key or coin changes, external-power changes, 154 and the next known rule boundary. Revalidate before execution and persist 155 in-progress state to prevent duplicate refresh groups. Use randomized retry 156 backoff capped by the time to the urgent boundary; once urgent, cap waits by 157 remaining deposit lifetime without an additional DD71 delay. Avoid busy loops. 158 Outages can still prevent successful refresh. 159 160 Warnings 161 -------- 162 163 Evaluate warnings independently of the selected rule. For ``0 < R < E``, show 164 expiration risk in the currency balance with the exchange, affected amount, 165 and earliest expiration. Pending or failing refreshes retain that indication 166 until successful completion. Distinguish connectivity failures, exchange 167 errors, unavailable suitable replacements according to fresh key information, 168 and a pending refresh; do not infer device-wide offline status. 169 170 After successfully refreshing coins whose pre-melt ``R`` was below ``E``, 171 provide one recovery notice per refresh group, even if rule 1 matched. State 172 that coins close to expiration were renewed; do not assert that the wallet 173 was offline. Show the next relevant date, since safe reopening intervals 174 depend on denomination lifetimes. Already-expired funds use the existing 175 expiry indication. 176 177 Exchange Configuration Recommendations 178 ====================================== 179 180 For a general-purpose exchange, start with this guidance for every relevant 181 denomination family:: 182 183 DURATION_SPEND = 720 days 184 DURATION_WITHDRAW = 30 days 185 186 These are recommendations, not protocol requirements or universal optima. 187 In the exchange implementation, ``DURATION_SPEND`` runs from withdrawal 188 expiration to deposit expiration: it is ``G``, not the interval from key 189 validity start to deposit expiration. With this configuration, a coin acquired 190 during its withdrawal window has between 720 and 750 days left to deposit. 191 192 Rationale 193 --------- 194 195 * Replacement validity of 720--750 days makes rule 1 eligible with roughly 196 180--187.5 days left, leaving substantial margin before the 90-day emergency 197 threshold. Under stable offerings, paid refreshes are separated by at least 198 ``720 - 750 / 4 = 532.5 days`` along each sequence of replacement coins. 199 * The 30-day issuance window limits replacement-lifetime variation to about 200 four percent and limits how long a key is used for issuing coins. It does 201 not eliminate compromise risk during the longer spending period. 202 * Longer spending periods require more coin-state storage; shorter issuance 203 windows require more keys and key-management work. These values balance 204 those costs with occasionally opened wallets, rather than representing a 205 measured optimum. The 720 days are two fixed 360-day periods, not calendar 206 years. 207 208 Keep spending lifetimes comparable across denominations, including affordable 209 change, and fees low enough to permit positive refresh outputs. Maintain 210 continuous replacement-key coverage for all required values, ciphers, and age 211 restrictions. Shorter spending periods require more frequent refreshes and 212 shorter offline intervals; the adaptive rule remains a fallback. 213 214 Follow the :ref:`exchange's denomination-key guidance <Coins-denomination-keys>`: 215 withdrawal overlap must be below ``DURATION_WITHDRAW``; ``LOOKAHEAD_SIGN`` should 216 be at least one year, with offline signing at least every six months. Keys 217 must be signed and published, and are usable only once their validity starts. 218 For lifetime or fee changes, introduce new configuration sections as the 219 manual requires, preserving suitable replacements for existing coins. 220 221 Conditional Annual Refresh-Cost Bound 222 ===================================== 223 224 The fee summary should distinguish a conservative upper bound from an expected 225 charge. The following bound covers keeping the current balance for 365 days 226 without payments or additional withdrawals. It excludes initial withdrawal 227 fees, payment-related refreshes, and losses caused by expiration or an outage. 228 Those risks must not be presented as covered by the estimate. 229 230 Assumptions 231 ----------- 232 233 For this metric, a reasonable denomination/fee structure satisfies: 234 235 * Continuous compatible offerings with stable values, fees, and lifetime 236 bounds. Unpublished future offerings are projection assumptions, not signed 237 commitments. 238 * Every reachable denomination, including small change, admits positive 239 value-first outputs. Refresh completes while output keys remain withdrawable; 240 a delayed reveal outside that window invalidates the estimate. 241 * ``Gmin > 0`` is a lower bound on remaining lifetime at output acquisition; 242 ``Hmax`` bounds all obtainable output lifetimes from above. Full key lifetime 243 from validity start to deposit expiration suffices for ``Hmax``. 244 * ``Delta = Gmin - Hmax / 4 > 0``. 245 * ``0 <= p < 1`` bounds total loss divided by input value for every paid refresh 246 of every reachable denomination and projected selection, including output 247 fees and rounding. 248 249 If these assumptions cannot be established, report the bound as unavailable 250 and explain why. Recompute or withdraw it when assumptions fail; do not ignore 251 unrefreshable dust or assume unknown future fees are zero. 252 253 Calculation and justification 254 ----------------------------- 255 256 For current balance ``B`` and horizon ``T = 365 days``, compute:: 257 258 Delta = Gmin - Hmax / 4 259 N = 1 + floor(T / Delta) 260 annual_loss_bound = B * (1 - (1 - p) ** N) 261 262 Round the monetary bound upward to the currency's supported amount precision. 263 If computing separate bounds per exchange or compatibility group, sum their 264 rounded bounds. The fee summary must show the horizon and assumptions, and 265 label the result a conditional upper bound, not a predicted debit or a 266 promise about future exchange offerings. 267 268 A new coin starts with at least ``Gmin`` remaining. Neither paid rule can 269 match above ``Hmax / 4``: rule 1 requires a fourfold extension, and rule 3 has 270 ``E <= G / 4 <= Hmax / 4``. Paid refreshes are therefore separated by at least 271 ``Delta`` along each sequence of replacement coins. Free refreshes cannot 272 shorten that interval; scheduling delays only lengthen it. The initial ``1`` 273 allows an immediately due refresh of existing holdings. 274 275 Each paid refresh preserves at least ``1 - p`` of its input, including when 276 it splits into multiple outputs. Since every resulting sequence has at most 277 ``N`` paid refreshes, at least ``B * (1 - p) ** N`` remains. If ``p == 0``, the 278 bound is zero. 279 280 With the recommended configuration, ``Gmin = 720 days``, ``Hmax = 750 days``, 281 and ``Delta = 532.5 days``, giving ``N = 1``. If the total loss per paid refresh 282 is bounded by one percent across all reachable denominations, a balance of 283 100 currency units therefore has a conditional annual bound of 1 unit. The 284 one-percent premise must be checked; the key durations alone do not imply it. 285 286 287 Definition of Done 288 ================== 289 290 * [x] Earlier policy prototyped in a wallet-core feature branch 291 * [ ] Revised policy reviewed, implemented, and merged 292 * [ ] Tests cover adaptive and strict thresholds, mixed/empty outputs, fees and 293 rounding, power state, persistent scheduling, retries, and warning overlap 294 * [ ] Fee-bound tests cover zero cost, split outputs, initially due refreshes, 295 and unavailable estimates 296 * [ ] Exchange guidance checked against supported key rotation 297 * [ ] GUI warnings and fee summaries designed and tested with dev experiments 298 * [ ] Implemented behavior documented in the wallet reference 299 300 Alternatives 301 ============ 302 303 The older wallet policy checked an exchange after 75% of the period from 304 withdrawal expiration to deposit expiration had passed, refreshing coins more 305 than 50% into that period. Grouping these operations reduced separate checks, 306 but did not account for replacement lifetimes or absolute offline margins. 307 308 The earlier DD71 policy accepted any extension below a fixed 90-day threshold. 309 That could repeatedly refresh short-lived coins whenever slightly newer keys 310 appeared. The adaptive threshold retains an emergency path without treating 311 all short-lived coins as perpetual emergencies. 312 313 314 Drawbacks 315 ========= 316 317 * This policy does not learn individual wallet usage patterns. 318 * Value-first selection can defer a lifetime extension that would cost more. 319 * The annual bound can be conservative or unavailable, especially with changing 320 offerings or unrefreshable small denominations. 321 * Independent scheduling reduces synchronized traffic; overdue startup checks, 322 widespread outages, and urgent retries can still create bursts. 323 * Longer spending lifetimes increase exchange storage obligations. Operator 324 recommendations must balance those costs against wallet availability.