@@ -131,40 +131,41 @@ class BlocktankRepo @Inject constructor(
131131 suspend fun getCjitEntry (channel : ChannelDetails ): IcJitEntry ? = withContext(bgDispatcher) {
132132 val fundingTxId = channel.fundingTxo?.txid ? : return @withContext null
133133
134- fun cachedMatch (): IcJitEntry ? = _blocktankState .value.cjitEntries
135- . firstOrNull { it.channel?.fundingTx?.id == fundingTxId }
134+ fun List<IcJitEntry>. matching (): IcJitEntry ? =
135+ firstOrNull { it.channel?.fundingTx?.id == fundingTxId }
136136
137- cachedMatch()?.let { return @withContext it }
137+ val cached = _blocktankState .value.cjitEntries
138+ cached.matching()?.let { return @withContext it }
138139
139140 // A ChannelReady can only be a CJIT if a live cached entry is still awaiting its channel; otherwise skip
140141 // the server round-trip so a non-CJIT transfer confirmation isn't delayed by a slow Blocktank API.
141- val hasPendingCjit = _blocktankState .value.cjitEntries .any {
142+ val hasPendingCjit = cached .any {
142143 it.channel == null && it.state != CJitStateEnum .EXPIRED && it.state != CJitStateEnum .FAILED
143144 }
144145 if (! hasPendingCjit) return @withContext null
145146
146- refreshCjitEntries()
147- return @withContext cachedMatch ()
147+ // Match against the freshly fetched list so a concurrent refreshOrders() can't clobber state before we read.
148+ return @withContext refreshCjitEntries().matching ()
148149 }
149150
150- private suspend fun refreshCjitEntries () {
151+ private suspend fun refreshCjitEntries (): List < IcJitEntry > {
151152 repeat(CJIT_REFRESH_ATTEMPTS ) { attempt ->
152153 runCatching {
153154 withTimeout(CJIT_REFRESH_TIMEOUT ) {
154155 coreService.blocktank.cjitEntries(refresh = true )
155156 }
156157 }.onSuccess { entries ->
157158 _blocktankState .update { it.copy(cjitEntries = entries.toImmutableList()) }
158- return
159+ return entries
159160 }.onFailure {
160161 if (it is CancellationException && it !is TimeoutCancellationException ) throw it
161162 if (attempt == CJIT_REFRESH_ATTEMPTS - 1 ) {
162163 Logger .warn(" Failed to refresh CJIT entries; using cached state" , it, context = TAG )
163- return
164164 }
165165 }
166166 delay(CJIT_REFRESH_RETRY_DELAY )
167167 }
168+ return _blocktankState .value.cjitEntries
168169 }
169170
170171 suspend fun refreshInfo () = withContext(bgDispatcher) {
0 commit comments