Skip to content

Commit a61e9f1

Browse files
committed
Merge branch 'master' into fix/stale-graph-reset
2 parents de50b85 + cd71e00 commit a61e9f1

6 files changed

Lines changed: 86 additions & 33 deletions

File tree

app/src/main/java/to/bitkit/repositories/BlocktankRepo.kt

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ class BlocktankRepo @Inject constructor(
134134
}
135135
}
136136

137-
suspend fun refreshOrders() = withContext(bgDispatcher) {
138-
if (isRefreshing) return@withContext
137+
suspend fun refreshOrders(): Result<Unit> = withContext(bgDispatcher) {
138+
if (isRefreshing) return@withContext Result.success(Unit)
139139
isRefreshing = true
140140

141141
runCatching {
@@ -172,11 +172,9 @@ class BlocktankRepo @Inject constructor(
172172
context = TAG
173173
)
174174
openChannelWithPaidOrders()
175-
}.onFailure {
176-
Logger.error("Failed to refresh orders", it, context = TAG)
175+
}.also {
176+
isRefreshing = false
177177
}
178-
179-
isRefreshing = false
180178
}
181179

182180
suspend fun refreshMinCjitSats() = withContext(bgDispatcher) {
@@ -303,7 +301,7 @@ class BlocktankRepo @Inject constructor(
303301
): Result<IBtOrder?> = withContext(bgDispatcher) {
304302
runCatching {
305303
if (refresh) {
306-
refreshOrders()
304+
refreshOrders().getOrThrow()
307305
}
308306
val order = _blocktankState.value.orders.find { it.id == orderId }
309307
return@runCatching order

app/src/main/java/to/bitkit/ui/screens/shop/shopDiscover/MapWebViewClient.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@ class MapWebViewClient(
3838
)
3939
onLoadingStateChanged(false)
4040

41-
error?.let {
42-
if (it.errorCode == ERROR_HOST_LOOKUP ||
43-
it.errorCode == ERROR_CONNECT ||
44-
it.errorCode == ERROR_TIMEOUT ||
45-
it.errorCode == ERROR_FILE_NOT_FOUND
46-
) {
47-
onError?.invoke()
41+
if (request?.isForMainFrame == true) {
42+
error?.let {
43+
if (it.errorCode == ERROR_HOST_LOOKUP ||
44+
it.errorCode == ERROR_CONNECT ||
45+
it.errorCode == ERROR_TIMEOUT ||
46+
it.errorCode == ERROR_FILE_NOT_FOUND
47+
) {
48+
onError?.invoke()
49+
}
4850
}
4951
}
5052
}

app/src/main/java/to/bitkit/ui/screens/shop/shopWebView/ShopWebViewClient.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,15 @@ class ShopWebViewClient(
6262
)
6363
onLoadingStateChanged(false)
6464

65-
error?.let {
66-
if (it.errorCode == ERROR_HOST_LOOKUP ||
67-
it.errorCode == ERROR_CONNECT ||
68-
it.errorCode == ERROR_TIMEOUT ||
69-
it.errorCode == ERROR_FILE_NOT_FOUND
70-
) {
71-
onError()
65+
if (request?.isForMainFrame == true) {
66+
error?.let {
67+
if (it.errorCode == ERROR_HOST_LOOKUP ||
68+
it.errorCode == ERROR_CONNECT ||
69+
it.errorCode == ERROR_TIMEOUT ||
70+
it.errorCode == ERROR_FILE_NOT_FOUND
71+
) {
72+
onError()
73+
}
7274
}
7375
}
7476
}

app/src/main/java/to/bitkit/ui/settings/lightning/LightningConnectionsViewModel.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@ import to.bitkit.ext.createChannelDetails
3232
import to.bitkit.ext.filterOpen
3333
import to.bitkit.ext.filterPending
3434
import to.bitkit.models.Toast
35+
import to.bitkit.models.TransferType
3536
import to.bitkit.repositories.ActivityRepo
3637
import to.bitkit.repositories.BlocktankRepo
3738
import to.bitkit.repositories.LightningRepo
3839
import to.bitkit.repositories.LogsRepo
40+
import to.bitkit.repositories.TransferRepo
3941
import to.bitkit.repositories.WalletRepo
4042
import to.bitkit.ui.shared.toast.ToastEventBus
4143
import to.bitkit.utils.Logger
@@ -51,6 +53,7 @@ class LightningConnectionsViewModel @Inject constructor(
5153
private val logsRepo: LogsRepo,
5254
private val walletRepo: WalletRepo,
5355
private val activityRepo: ActivityRepo,
56+
private val transferRepo: TransferRepo,
5457
) : ViewModel() {
5558

5659
private val _uiState = MutableStateFlow(LightningConnectionsUiState())
@@ -452,6 +455,12 @@ class LightningConnectionsViewModel @Inject constructor(
452455

453456
lightningRepo.closeChannel(channel).fold(
454457
onSuccess = {
458+
transferRepo.createTransfer(
459+
type = TransferType.COOP_CLOSE,
460+
amountSats = channel.amountOnClose.toLong(),
461+
channelId = channel.channelId,
462+
fundingTxId = channel.fundingTxo?.txid,
463+
)
455464
walletRepo.syncNodeAndWallet()
456465

457466
ToastEventBus.send(

app/src/main/java/to/bitkit/viewmodels/TransferViewModel.kt

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -263,19 +263,40 @@ class TransferViewModel @Inject constructor(
263263
}
264264

265265
private suspend fun pollUntil(orderId: String, condition: (IBtOrder) -> Boolean): IBtOrder? {
266+
var consecutiveErrors = 0
267+
266268
while (true) {
267-
val order = blocktankRepo.getOrder(orderId, refresh = true).getOrNull()
268-
if (order == null) {
269-
Logger.error("Order not found: '$orderId'", context = TAG)
270-
return null
271-
}
272-
if (order.state2 == BtOrderState2.EXPIRED) {
273-
Logger.error("Order expired: '$orderId'", context = TAG)
274-
return null
275-
}
276-
if (condition(order)) {
277-
return order
278-
}
269+
blocktankRepo.getOrder(orderId, refresh = true).fold(
270+
onSuccess = { order ->
271+
consecutiveErrors = 0
272+
273+
if (order == null) {
274+
Logger.error("Order not found: '$orderId'", context = TAG)
275+
return null
276+
}
277+
if (order.state2 == BtOrderState2.EXPIRED) {
278+
Logger.error("Order expired: '$orderId'", context = TAG)
279+
return null
280+
}
281+
if (condition(order)) {
282+
return order
283+
}
284+
},
285+
onFailure = {
286+
consecutiveErrors++
287+
Logger.warn(
288+
"Failed to fetch order '$orderId' (attempt $consecutiveErrors/$MAX_CONSECUTIVE_ERRORS)",
289+
it,
290+
context = TAG
291+
)
292+
293+
if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {
294+
Logger.error("Too many consecutive errors polling order '$orderId', giving up", context = TAG)
295+
return null
296+
}
297+
}
298+
)
299+
279300
delay(POLL_INTERVAL_MS)
280301
}
281302
}
@@ -539,6 +560,7 @@ class TransferViewModel @Inject constructor(
539560
private const val TAG = "TransferViewModel"
540561
private const val MIN_STEP_DELAY_MS = 500L
541562
private const val POLL_INTERVAL_MS = 2_500L
563+
private const val MAX_CONSECUTIVE_ERRORS = 5
542564
const val LN_SETUP_STEP_0 = 0
543565
const val LN_SETUP_STEP_1 = 1
544566
const val LN_SETUP_STEP_2 = 2

app/src/test/java/to/bitkit/repositories/BlocktankRepoTest.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,24 @@ class BlocktankRepoTest : BaseUnitTest() {
172172
assertTrue(result.isSuccess)
173173
assertNull(result.getOrThrow())
174174
}
175+
176+
@Test
177+
fun `refreshOrders returns failure when server throws`() {
178+
sut = createSut()
179+
whenever { coreService.blocktank.orders(refresh = true) }.thenThrow(RuntimeException("Network error"))
180+
test {
181+
val result = sut.refreshOrders()
182+
assertTrue(result.isFailure)
183+
}
184+
}
185+
186+
@Test
187+
fun `getOrder returns failure when refresh fails`() {
188+
sut = createSut()
189+
whenever { coreService.blocktank.orders(refresh = true) }.thenThrow(RuntimeException("Network error"))
190+
test {
191+
val result = sut.getOrder(testOrder1.id, refresh = true)
192+
assertTrue(result.isFailure)
193+
}
194+
}
175195
}

0 commit comments

Comments
 (0)