From 3c95b643745f7993cf3d1fa87689497b2f04dc09 Mon Sep 17 00:00:00 2001 From: owenstanford Date: Fri, 1 Sep 2023 12:18:32 +0100 Subject: [PATCH 1/2] NOTICK - Claim debug --- .../services/TokenCacheEventProcessor.kt | 49 +++++++++++++++++++ .../services/TokenCacheEventProcessorTest.kt | 10 ++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/components/ledger/ledger-utxo-token-cache/src/main/kotlin/net/corda/ledger/utxo/token/cache/services/TokenCacheEventProcessor.kt b/components/ledger/ledger-utxo-token-cache/src/main/kotlin/net/corda/ledger/utxo/token/cache/services/TokenCacheEventProcessor.kt index 077d7950e8e..a98be505d66 100644 --- a/components/ledger/ledger-utxo-token-cache/src/main/kotlin/net/corda/ledger/utxo/token/cache/services/TokenCacheEventProcessor.kt +++ b/components/ledger/ledger-utxo-token-cache/src/main/kotlin/net/corda/ledger/utxo/token/cache/services/TokenCacheEventProcessor.kt @@ -1,15 +1,20 @@ package net.corda.ledger.utxo.token.cache.services +import net.corda.data.ledger.utxo.token.selection.data.TokenAmount import net.corda.data.ledger.utxo.token.selection.event.TokenPoolCacheEvent import net.corda.data.ledger.utxo.token.selection.key.TokenPoolCacheKey import net.corda.data.ledger.utxo.token.selection.state.TokenPoolCacheState import net.corda.ledger.utxo.token.cache.converters.EntityConverter import net.corda.ledger.utxo.token.cache.converters.EventConverter +import net.corda.ledger.utxo.token.cache.entities.PoolCacheState +import net.corda.ledger.utxo.token.cache.entities.TokenCache import net.corda.ledger.utxo.token.cache.entities.TokenEvent import net.corda.ledger.utxo.token.cache.handlers.TokenEventHandler import net.corda.messaging.api.processor.StateAndEventProcessor import net.corda.messaging.api.records.Record import org.slf4j.LoggerFactory +import java.math.BigDecimal +import java.math.BigInteger class TokenCacheEventProcessor constructor( private val eventConverter: EventConverter, @@ -48,9 +53,20 @@ class TokenCacheEventProcessor constructor( "Received an event with and unrecognized payload '${tokenEvent.javaClass}'" } + val sb = StringBuffer() + sb.appendLine( + "Token Selection Request type = ${handler.javaClass.simpleName} Pool = ${nonNullableState.poolKey}" + ) + sb.appendLine("Before Handler:") + sb.append(getTokenSummary(tokenCache, poolCacheState)) + val result = handler.handle(tokenCache, poolCacheState, tokenEvent) ?: return StateAndEventProcessor.Response(poolCacheState.toAvro(), listOf()) + sb.appendLine("After Handler:") + sb.append(getTokenSummary(tokenCache, poolCacheState)) + log.info(sb.toString()) + return StateAndEventProcessor.Response( poolCacheState.toAvro(), listOf(result) @@ -60,4 +76,37 @@ class TokenCacheEventProcessor constructor( return StateAndEventProcessor.Response(state, listOf(), markForDLQ = true) } } + + private fun getTokenSummary(tokenCache: TokenCache, state: PoolCacheState): String { + val cachedTokenValue = tokenCache.sumOf { it.amount } + val cachedTokenCount = tokenCache.count() + val avroState = state.toAvro() + val sb = StringBuffer() + sb.appendLine("Token Cache Summary:") + sb.appendLine("Token Balance: $cachedTokenValue") + sb.appendLine("Token Count : $cachedTokenCount") + val tokenIndex = tokenCache.associateBy { it.stateRef } + + avroState.tokenClaims.forEach { + val claimedTokens = it.claimedTokenStateRefs.mapNotNull { ref-> tokenIndex[ref] } + val claimCount = claimedTokens.size + val claimBalance = claimedTokens.sumOf { token-> token.amount } + val tokens = claimedTokens.joinToString(" ") { token-> "(${token.amount})" } + sb.appendLine( + "Claim : ${it.claimId} Token Count $claimCount Token Balance $claimBalance Tokens:${tokens}" + ) + } + return sb.toString() + } + + private fun amountToBigDecimal(avroTokenAmount: TokenAmount): BigDecimal { + val unscaledValueBytes = ByteArray(avroTokenAmount.unscaledValue.remaining()) + .apply { avroTokenAmount.unscaledValue.get(this) } + + avroTokenAmount.unscaledValue.position(0) + return BigDecimal( + BigInteger(unscaledValueBytes), + avroTokenAmount.scale + ) + } } diff --git a/components/ledger/ledger-utxo-token-cache/src/test/kotlin/net/corda/ledger/utxo/token/cache/impl/services/TokenCacheEventProcessorTest.kt b/components/ledger/ledger-utxo-token-cache/src/test/kotlin/net/corda/ledger/utxo/token/cache/impl/services/TokenCacheEventProcessorTest.kt index 7fb324c00b7..2aa1db88020 100644 --- a/components/ledger/ledger-utxo-token-cache/src/test/kotlin/net/corda/ledger/utxo/token/cache/impl/services/TokenCacheEventProcessorTest.kt +++ b/components/ledger/ledger-utxo-token-cache/src/test/kotlin/net/corda/ledger/utxo/token/cache/impl/services/TokenCacheEventProcessorTest.kt @@ -7,6 +7,7 @@ import net.corda.data.ledger.utxo.token.selection.state.TokenPoolCacheState import net.corda.messaging.api.records.Record import net.corda.ledger.utxo.token.cache.converters.EntityConverter import net.corda.ledger.utxo.token.cache.converters.EventConverter +import net.corda.ledger.utxo.token.cache.entities.CachedToken import net.corda.ledger.utxo.token.cache.entities.PoolCacheState import net.corda.ledger.utxo.token.cache.entities.TokenCache import net.corda.ledger.utxo.token.cache.entities.TokenEvent @@ -28,7 +29,10 @@ class TokenCacheEventProcessorTest { private val mockHandler = mock>() private val tokenCacheEventHandlerMap = mutableMapOf, TokenEventHandler>() private val event = FakeTokenEvent() - private val tokenCache = mock() + private val tokenCache = mock().apply { + whenever(iterator()).thenReturn(listOf().iterator()) + } + private val cachePoolState = mock() private val stateIn = TokenPoolCacheState() private val tokenPoolCacheEvent = TokenPoolCacheEvent(POOL_CACHE_KEY, null) @@ -86,7 +90,7 @@ class TokenCacheEventProcessorTest { fun `forward an event to its handler and return the response`() { tokenPoolCacheEvent.payload = "message" - val outputState = TokenPoolCacheState() + val outputState = TokenPoolCacheState().apply { tokenClaims = listOf() } val handlerResponse = Record("", "", null) whenever(entityConverter.toTokenCache(stateIn)).thenReturn(tokenCache) @@ -109,7 +113,7 @@ class TokenCacheEventProcessorTest { fun `null state will be defaulted to an empty state before processing`() { tokenPoolCacheEvent.payload = "message" - val outputState = TokenPoolCacheState() + val outputState = TokenPoolCacheState().apply { tokenClaims = listOf() } val handlerResponse = Record("", "", null) whenever(entityConverter.toTokenCache(any())).thenReturn(tokenCache) From 2097b79118f79ca27aee4e3b66cc453ae43d8e1a Mon Sep 17 00:00:00 2001 From: owenstanford Date: Fri, 1 Sep 2023 19:03:12 +0100 Subject: [PATCH 2/2] NOTICK - Claim debug --- .../services/TokenCacheEventProcessor.kt | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/components/ledger/ledger-utxo-token-cache/src/main/kotlin/net/corda/ledger/utxo/token/cache/services/TokenCacheEventProcessor.kt b/components/ledger/ledger-utxo-token-cache/src/main/kotlin/net/corda/ledger/utxo/token/cache/services/TokenCacheEventProcessor.kt index a98be505d66..84936fb509f 100644 --- a/components/ledger/ledger-utxo-token-cache/src/main/kotlin/net/corda/ledger/utxo/token/cache/services/TokenCacheEventProcessor.kt +++ b/components/ledger/ledger-utxo-token-cache/src/main/kotlin/net/corda/ledger/utxo/token/cache/services/TokenCacheEventProcessor.kt @@ -61,16 +61,20 @@ class TokenCacheEventProcessor constructor( sb.append(getTokenSummary(tokenCache, poolCacheState)) val result = handler.handle(tokenCache, poolCacheState, tokenEvent) - ?: return StateAndEventProcessor.Response(poolCacheState.toAvro(), listOf()) sb.appendLine("After Handler:") sb.append(getTokenSummary(tokenCache, poolCacheState)) log.info(sb.toString()) - return StateAndEventProcessor.Response( - poolCacheState.toAvro(), - listOf(result) - ) + return if (result == null) { + StateAndEventProcessor.Response(poolCacheState.toAvro(), listOf()) + } else { + StateAndEventProcessor.Response( + poolCacheState.toAvro(), + listOf(result) + ) + } + } catch (e: Exception) { log.error("Unexpected error while processing event '${event}'. The event will be sent to the DLQ.", e) return StateAndEventProcessor.Response(state, listOf(), markForDLQ = true) @@ -88,10 +92,10 @@ class TokenCacheEventProcessor constructor( val tokenIndex = tokenCache.associateBy { it.stateRef } avroState.tokenClaims.forEach { - val claimedTokens = it.claimedTokenStateRefs.mapNotNull { ref-> tokenIndex[ref] } + val claimedTokens = it.claimedTokenStateRefs.mapNotNull { ref -> tokenIndex[ref] } val claimCount = claimedTokens.size - val claimBalance = claimedTokens.sumOf { token-> token.amount } - val tokens = claimedTokens.joinToString(" ") { token-> "(${token.amount})" } + val claimBalance = claimedTokens.sumOf { token -> token.amount } + val tokens = claimedTokens.joinToString(" ") { token -> "(${token.amount})" } sb.appendLine( "Claim : ${it.claimId} Token Count $claimCount Token Balance $claimBalance Tokens:${tokens}" )