Prior to this commit, decodepsbt_inputs would call TxDoc during initialization which lives in another TLU. TxDoc relies on CURRENCY_UNIT to be initialized when it may not have been (note this is different from the TLU containing decodepsbt_inputs which also has a CURRENCY_UNIT). Fix this by lazy initializing decodepsbt_inputs. Also prevent the issue in the future by doing the same for decodepsbt_outputs and getblock_vin.
Curious why the CI missed this, it broke fuzzamoto. It was introduced in fadf901fd4b4d95bd0dd046b8d44a1154c5ea9a8. I was able to trigger this with clang-21 and ASAN_OPTIONS="detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1":
0=================================================================
1==926804==ERROR: AddressSanitizer: initialization-order-fiasco on address 0x5631e5784288 at pc 0x5631e3309f9c bp 0x7ffdb6abc7b0 sp 0x7ffdb6abc7a8
2READ of size 8 at 0x5631e5784288 thread T0
3 [#0](/bitcoin-bitcoin/0/) 0x5631e3309f9b in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>::size() const /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/basic_string.h:1064:16
4 [#1](/bitcoin-bitcoin/1/) 0x5631e3309f9b in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> std::operator+<char, std::char_traits<char>, std::allocator<char>>(char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/basic_string.tcc:618:35
5 [#2](/bitcoin-bitcoin/2/) 0x5631e4238948 in TxDoc(TxDocOptions const&) /root/bitcoin/src/rpc/rawtransaction_util.cpp:382:76
6 [#3](/bitcoin-bitcoin/3/) 0x5631e316945e in __cxx_global_var_init.9 /root/bitcoin/src/rpc/rawtransaction.cpp:784:17
7 [#4](/bitcoin-bitcoin/4/) 0x5631e3186355 in _GLOBAL__sub_I_rawtransaction.cpp /root/bitcoin/src/rpc/rawtransaction.cpp
8 [#5](/bitcoin-bitcoin/5/) 0x7fa6ca046375 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x27375) (BuildId: 79005c16293efa45b441fed45f4f29b138557e9e)
9 [#6](/bitcoin-bitcoin/6/) 0x5631e31cf160 in _start (/root/bitcoin/build/bin/bitcoind+0x25b160)
10
110x5631e5784288 is located 56 bytes before global variable 'CURRENCY_ATOM[abi:cxx11]' defined in '/root/bitcoin/src/policy/feerate.h:20' (0x5631e57842c0) of size 32
12 registered at:
13 [#0](/bitcoin-bitcoin/0/) 0x5631e31e5738 in __asan_register_globals /root/llvm-project/compiler-rt/lib/asan/asan_globals.cpp:431:3
14 [#1](/bitcoin-bitcoin/1/) 0x5631e31e68a9 in __asan_register_elf_globals /root/llvm-project/compiler-rt/lib/asan/asan_globals.cpp:414:3
15
160x5631e5784288 is located 8 bytes inside of global variable 'CURRENCY_UNIT[abi:cxx11]' defined in '/root/bitcoin/src/policy/feerate.h:19' (0x5631e5784280) of size 32
17 registered at:
18 [#0](/bitcoin-bitcoin/0/) 0x5631e31e5738 in __asan_register_globals /root/llvm-project/compiler-rt/lib/asan/asan_globals.cpp:431:3
19 [#1](/bitcoin-bitcoin/1/) 0x5631e31e68a9 in __asan_register_elf_globals /root/llvm-project/compiler-rt/lib/asan/asan_globals.cpp:414:3
20
21SUMMARY: AddressSanitizer: initialization-order-fiasco /root/bitcoin/src/rpc/rawtransaction_util.cpp:382:76 in TxDoc(TxDocOptions const&)
22Shadow bytes around the buggy address:
23 0x5631e5784000: f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6
24 0x5631e5784080: f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6
25 0x5631e5784100: f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6
26 0x5631e5784180: f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6
27 0x5631e5784200: f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6
28=>0x5631e5784280: f6[f6]f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6
29 0x5631e5784300: f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6
30 0x5631e5784380: f6 f6 f6 f6 01 f9 f9 f9 f6 f6 f6 f6 f6 f6 f6 f6
31 0x5631e5784400: f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6
32 0x5631e5784480: f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6
33 0x5631e5784500: f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 00 00 00 00
34Shadow byte legend (one shadow byte represents 8 application bytes):
35 Addressable: 00
36 Partially addressable: 01 02 03 04 05 06 07
37 Heap left redzone: fa
38 Freed heap region: fd
39 Stack left redzone: f1
40 Stack mid redzone: f2
41 Stack right redzone: f3
42 Stack after return: f5
43 Stack use after scope: f8
44 Global redzone: f9
45 Global init order: f6
46 Poisoned by user: f7
47 Container overflow: fc
48 Array cookie: ac
49 Intra object redzone: bb
50 ASan internal: fe
51 Left alloca redzone: ca
52 Right alloca redzone: cb
53==926804==ABORTING
Can be reviewed with git diff HEAD~1 -w since it’s mostly indentation.