Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions app/src/main/java/to/bitkit/services/CoreService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ class ActivityService(
private fun buildUpdatedOnchainActivity(
existingActivity: Activity.Onchain,
confirmationData: ConfirmationData,
ldkValue: ULong,
channelId: String? = null,
): OnchainActivity {
var preservedIsTransfer = existingActivity.v1.isTransfer
Expand All @@ -612,13 +613,20 @@ class ActivityService(

val finalDoesExist = if (confirmationData.isConfirmed) true else existingActivity.v1.doesExist

val preservedValue = if (existingActivity.v1.value > ldkValue) {
existingActivity.v1.value
} else {
ldkValue
}

val updatedOnChain = existingActivity.v1.copy(
confirmed = confirmationData.isConfirmed,
confirmTimestamp = confirmationData.confirmedTimestamp,
doesExist = finalDoesExist,
updatedAt = confirmationData.timestamp,
isTransfer = preservedIsTransfer,
channelId = preservedChannelId,
value = preservedValue,
)

return updatedOnChain
Expand Down Expand Up @@ -667,10 +675,16 @@ class ActivityService(
val timestamp = payment.latestUpdateTimestamp
val confirmationData = getConfirmationStatus(kind, timestamp)

val existingActivity = getActivityById(payment.id)
var existingActivity = getActivityById(payment.id)
if (existingActivity == null) {
getOnchainActivityByTxId(kind.txid)?.let {
existingActivity = Activity.Onchain(it)
}
}

if (existingActivity != null &&
existingActivity is Activity.Onchain &&
(existingActivity.v1.updatedAt ?: 0u) > payment.latestUpdateTimestamp
((existingActivity as Activity.Onchain).v1.updatedAt ?: 0u) > payment.latestUpdateTimestamp
) {
return
}
Expand All @@ -691,10 +705,12 @@ class ActivityService(

val resolvedAddress = resolveAddressForInboundPayment(kind, existingActivity, payment, transactionDetails)

val ldkValue = payment.amountSats ?: 0u
val onChain = if (existingActivity is Activity.Onchain) {
buildUpdatedOnchainActivity(
existingActivity = existingActivity,
existingActivity = existingActivity as Activity.Onchain,
confirmationData = confirmationData,
ldkValue = ldkValue,
channelId = resolvedChannelId,
)
} else {
Expand All @@ -712,8 +728,9 @@ class ActivityService(
return
}

if (existingActivity != null) {
updateActivity(payment.id, Activity.Onchain(onChain))
if (existingActivity != null && existingActivity is Activity.Onchain) {
val existingOnchain = existingActivity.v1
updateActivity(existingOnchain.id, Activity.Onchain(onChain))
} else {
upsertActivity(Activity.Onchain(onChain))
}
Expand Down
87 changes: 75 additions & 12 deletions app/src/main/java/to/bitkit/services/MigrationService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1239,10 +1239,6 @@ class MigrationService @Inject constructor(
if (hasRNMmkvData()) {
val mmkvData = loadRNMmkvData() ?: return

extractRNMetadata(mmkvData)?.let { metadata ->
applyRNMetadata(metadata)
}

extractRNActivities(mmkvData)?.let { activities ->
applyOnchainMetadata(activities)
}
Expand All @@ -1257,6 +1253,10 @@ class MigrationService @Inject constructor(
applyBoostTransactions(boosts)
}
}

extractRNMetadata(mmkvData)?.let { metadata ->
applyRNMetadata(metadata)
}
}

pendingRemoteActivityData?.let { remoteActivities ->
Expand Down Expand Up @@ -1450,6 +1450,19 @@ class MigrationService @Inject constructor(
}
}

val backupValue = item.value.toULong()
if (backupValue > updated.value) {
updated = updated.copy(value = backupValue)
wasUpdated = true
}

item.fee?.let { backupFee ->
if (backupFee.toULong() > updated.fee) {
updated = updated.copy(fee = backupFee.toULong())
wasUpdated = true
}
}

item.address?.let { address ->
if (address.isNotEmpty() && updated.address != address) {
updated = updated.copy(address = address)
Expand All @@ -1460,30 +1473,80 @@ class MigrationService @Inject constructor(
return if (wasUpdated) updated else null
}

@Suppress("CyclomaticComplexMethod", "NestedBlockDepth")
@Suppress("CyclomaticComplexMethod", "NestedBlockDepth", "LongMethod")
private suspend fun applyOnchainMetadata(items: List<RNActivityItem>) {
val onchainItems = items.filter { it.activityType == "onchain" }
var updatedCount = 0
var createdCount = 0

onchainItems.forEach { item ->
val txId = item.txId ?: item.id.takeIf { it.isNotEmpty() } ?: return@forEach

val onchain = activityRepo.getOnchainActivityByTxId(txId)
if (onchain == null) {
Logger.warn("Onchain activity not found for txId: $txId", context = TAG)
return@forEach
}
if (onchain != null) {
updateOnchainActivityMetadata(item, onchain)?.let { updated ->
activityRepo.updateActivity(updated.id, Activity.Onchain(updated))
.onSuccess { updatedCount++ }
.onFailure { e ->
Logger.error(
"Failed to update onchain activity metadata for $txId: $e",
e,
context = TAG
)
}
}
} else {
val timestampSecs = (item.timestamp / MS_PER_SEC).toULong()
val now = (System.currentTimeMillis() / MS_PER_SEC).toULong()

updateOnchainActivityMetadata(item, onchain)?.let { updated ->
activityRepo.updateActivity(updated.id, Activity.Onchain(updated))
val activityTimestamp = if (timestampSecs > 0u) timestampSecs else now

val newOnchain = OnchainActivity(
id = item.id,
txType = if (item.txType == "sent") PaymentType.SENT else PaymentType.RECEIVED,
txId = txId,
value = item.value.toULong(),
fee = (item.fee ?: 0).toULong(),
feeRate = (item.feeRate ?: 1).toULong(),
address = item.address ?: "",
timestamp = activityTimestamp,
confirmed = item.confirmed ?: false,
isBoosted = item.isBoosted ?: false,
boostTxIds = emptyList(),
isTransfer = item.isTransfer ?: false,
confirmTimestamp = item.confirmTimestamp?.let { (it / MS_PER_SEC).toULong() },
channelId = item.channelId,
transferTxId = item.transferTxId,
doesExist = item.exists ?: true,
createdAt = activityTimestamp,
updatedAt = activityTimestamp,
seenAt = now,
)

activityRepo.upsertActivity(Activity.Onchain(newOnchain))
.onSuccess {
createdCount++

item.boostedParents?.takeIf { it.isNotEmpty() }?.let { parents ->
applyBoostedParents(parents, txId)
}
}
.onFailure { e ->
Logger.error(
"Failed to update onchain activity metadata for $txId: $e",
"Failed to create onchain activity for unsupported address $txId: $e",
e,
context = TAG
)
}
}
}

if (updatedCount > 0 || createdCount > 0) {
Logger.info(
"Applied metadata to $updatedCount onchain activities, created $createdCount for unsupported addresses",
context = TAG
)
}
}

@Suppress("LongMethod", "CyclomaticComplexMethod", "NestedBlockDepth")
Expand Down
Loading