From b8dac975a117c6d04ec1ee1b634c583b184809d6 Mon Sep 17 00:00:00 2001 From: Owen Stanford <92725587+owenstanford@users.noreply.github.com> Date: Fri, 22 Sep 2023 16:40:25 +0300 Subject: [PATCH] CORE-15396 Add support for an expiry timeout on a token claim, this is to support automatic cleanup of orphaned claims. (#1259) --- .../utxo/token/selection/data/TokenClaim.avsc | 6 ++ .../data/TokenClaimSchemaCompatibilityTest.kt | 64 +++++++++++++++++++ .../schema/configuration/LedgerConfig.java | 3 +- .../ledger.utxo/1.0/corda.ledger.utxo.json | 6 ++ 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 data/avro-schema/src/test/kotlin/net/corda/data/ledger/utxo/token/selection/data/TokenClaimSchemaCompatibilityTest.kt diff --git a/data/avro-schema/src/main/resources/avro/net/corda/data/ledger/utxo/token/selection/data/TokenClaim.avsc b/data/avro-schema/src/main/resources/avro/net/corda/data/ledger/utxo/token/selection/data/TokenClaim.avsc index f4dc1ff974..d465d7453d 100644 --- a/data/avro-schema/src/main/resources/avro/net/corda/data/ledger/utxo/token/selection/data/TokenClaim.avsc +++ b/data/avro-schema/src/main/resources/avro/net/corda/data/ledger/utxo/token/selection/data/TokenClaim.avsc @@ -9,6 +9,12 @@ "type": "string", "doc": "Unique identifier for the claim" }, + { + "name": "claimTimestamp", + "type": ["null", "long"], + "default": null, + "doc": "Timestamp of when the claim was made in epoc milliseconds" + }, { "name": "claimedTokenStateRefs", "type": { diff --git a/data/avro-schema/src/test/kotlin/net/corda/data/ledger/utxo/token/selection/data/TokenClaimSchemaCompatibilityTest.kt b/data/avro-schema/src/test/kotlin/net/corda/data/ledger/utxo/token/selection/data/TokenClaimSchemaCompatibilityTest.kt new file mode 100644 index 0000000000..284468df53 --- /dev/null +++ b/data/avro-schema/src/test/kotlin/net/corda/data/ledger/utxo/token/selection/data/TokenClaimSchemaCompatibilityTest.kt @@ -0,0 +1,64 @@ +package net.corda.data.ledger.utxo.token.selection.data + +import org.apache.avro.Schema +import org.apache.avro.SchemaCompatibility +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class TokenClaimSchemaCompatibilityTest { + + @Test + fun `Token Claim schema changes between Corda 5_0 and 5_1 are compatible`() { + val oldSchemaJson = """ + { + "type": "record", + "name": "TokenClaim", + "namespace": "net.corda.data.ledger.utxo.token.selection.data", + "doc": "The set of tokens claimed by a query", + "fields": [ + { + "name": "claimId", + "type": "string", + "doc": "Unique identifier for the claim" + }, + { + "name": "claimedTokenStateRefs", + "type": { + "type": "array", + "items": "string" + }, + "default": [], + "doc": "Deprecated. The List of state refs for the claimed tokens" + }, + { + "name": "claimedTokens", + "type": { + "type": "array", + "items": "net.corda.data.ledger.utxo.token.selection.data.Token" + }, + "default": [], + "doc": "List of claimed tokens" + } + ] +} +""".trimIndent() + + val oldSchema = Schema.Parser() + .addTypes( + mapOf( + Token::class.java.name to Token.`SCHEMA$`, + ) + ) + .parse(oldSchemaJson) + + val newSchema = TokenClaim.`SCHEMA$` + + val compatibility = SchemaCompatibility.checkReaderWriterCompatibility(newSchema, oldSchema) + + Assertions.assertEquals( + compatibility.type, + SchemaCompatibility.SchemaCompatibilityType.COMPATIBLE, + "Failed due to incompatible change. ${compatibility.description}" + ) + } +} \ No newline at end of file diff --git a/data/config-schema/src/main/java/net/corda/schema/configuration/LedgerConfig.java b/data/config-schema/src/main/java/net/corda/schema/configuration/LedgerConfig.java index 21708fb450..c8867ed760 100644 --- a/data/config-schema/src/main/java/net/corda/schema/configuration/LedgerConfig.java +++ b/data/config-schema/src/main/java/net/corda/schema/configuration/LedgerConfig.java @@ -10,6 +10,7 @@ private LedgerConfig() { public static final String UTXO_TOKEN_PERIODIC_CHECK_BLOCK_SIZE = "tokens.periodCheckBlockSize"; public static final String UTXO_TOKEN_SEND_WAKEUP_MAX_RETRY_ATTEMPTS = "tokens.sendWakeUpMaxRetryAttempts"; public static final String UTXO_TOKEN_SEND_WAKEUP_MAX_RETRY_DELAY = "tokens.sendWakeUpMaxRetryDelay"; - public static final String UTXO_TOKEN_CACHED_TOKEN_PAGE_SIZE= "tokens.cachedTokenPageSize"; + public static final String UTXO_TOKEN_CACHED_TOKEN_PAGE_SIZE = "tokens.cachedTokenPageSize"; + public static final String UTXO_TOKEN_CLAIM_TIMEOUT_SECONDS = "tokens.claimTimeoutSeconds"; public static final String UTXO_BACKCHAIN_BATCH_SIZE = "backchain.batchSize"; } diff --git a/data/config-schema/src/main/resources/net/corda/schema/configuration/ledger.utxo/1.0/corda.ledger.utxo.json b/data/config-schema/src/main/resources/net/corda/schema/configuration/ledger.utxo/1.0/corda.ledger.utxo.json index 1c3a5a10d3..0b5b8fb91f 100644 --- a/data/config-schema/src/main/resources/net/corda/schema/configuration/ledger.utxo/1.0/corda.ledger.utxo.json +++ b/data/config-schema/src/main/resources/net/corda/schema/configuration/ledger.utxo/1.0/corda.ledger.utxo.json @@ -52,6 +52,12 @@ "type": "integer", "minimum": 0, "default": 1500 + }, + "claimTimeoutSeconds": { + "description": "Time in seconds before the claim will be automatically released (default 10 minutes)", + "type": "integer", + "minimum": 1, + "default": 600 } } },