diff options
author | Antoine A <> | 2023-10-13 11:17:13 +0000 |
---|---|---|
committer | Antoine A <> | 2023-10-13 11:17:13 +0000 |
commit | 15269b462cc172258702377babe03529de29234c (patch) | |
tree | 6be9d28a1abf3422e2e79a19e15852b5a7ff02ef | |
parent | d7064c851ae27cd5495f509fbc191df710e9e724 (diff) | |
download | libeufin-15269b462cc172258702377babe03529de29234c.tar.gz libeufin-15269b462cc172258702377babe03529de29234c.tar.bz2 libeufin-15269b462cc172258702377babe03529de29234c.zip |
Move all transaction metadata logic in a single file
4 files changed, 73 insertions, 26 deletions
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt index 14cc1666..2e73e065 100644 --- a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt +++ b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt @@ -768,49 +768,40 @@ class Database(dbConfig: String, private val bankCurrency: String): java.io.Clos BankTransactionResult.CONFLICT } else -> { + val metadata = TxMetadata.parse(tx.subject) if (it.getBoolean("out_creditor_is_exchange")) { - // Parse subject - val reservePub = try { - EddsaPublicKey(tx.subject) - } catch (e: Exception) { - null - } - if (reservePub != null) { - val rowId = it.getLong("out_credit_row_id") + val rowId = it.getLong("out_credit_row_id") + if (metadata is IncomingTxMetadata) { + val stmt = conn.prepareStatement(""" INSERT INTO taler_exchange_incoming (reserve_pub, bank_transaction) VALUES (?, ?) """) - stmt.setBytes(1, reservePub.raw) + stmt.setBytes(1, metadata.reservePub.raw) stmt.setLong(2, rowId) stmt.executeUpdate() conn.execSQLUpdate("NOTIFY incoming_tx, '${"${tx.creditorAccountId} $rowId"}'") } else { // TODO bounce + logger.warn("exchange account ${tx.creditorAccountId} received a transaction $rowId with malformed metadata, will bounce in future version") } - } else if (it.getBoolean("out_debtor_is_exchange")) { - // Parse subject - val metadata = try { - val split = tx.subject.split(" ", limit=2) ; - Pair(ShortHashCode(split[0]), split[2]) - } catch (e: Exception) { - null - } - if (metadata != null) { - val rowId = it.getLong("out_debit_row_id") + } + if (it.getBoolean("out_debtor_is_exchange")) { + val rowId = it.getLong("out_debit_row_id") + if (metadata is OutgoingTxMetadata) { val stmt = conn.prepareStatement(""" INSERT INTO taler_exchange_outgoing (wtid, exchange_base_url, bank_transaction) VALUES (?, ?, ?) """) - stmt.setBytes(1, metadata.first.raw) - stmt.setString(2, metadata.second) + stmt.setBytes(1, metadata.wtid.raw) + stmt.setString(2, metadata.exchangeBaseUrl) stmt.setLong(3, rowId) stmt.executeUpdate() conn.execSQLUpdate("NOTIFY outgoing_tx, '${"${tx.debtorAccountId} $rowId"}'") } else { - // TODO log ? + logger.warn("exchange account ${tx.debtorAccountId} sent a transaction $rowId with malformed metadata") } } BankTransactionResult.SUCCESS @@ -1498,7 +1489,7 @@ class Database(dbConfig: String, private val bankCurrency: String): java.io.Clos pmtInfId: String = "not used", endToEndId: String = "not used", ): TalerTransferCreationResult = conn { conn -> - val subject = "${req.wtid.encoded()} ${req.exchange_base_url}" + val subject = OutgoingTxMetadata(req.wtid, req.exchange_base_url).toString() val stmt = conn.prepareStatement(""" SELECT out_exchange_balance_insufficient diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Metadata.kt b/bank/src/main/kotlin/tech/libeufin/bank/Metadata.kt new file mode 100644 index 00000000..119de048 --- /dev/null +++ b/bank/src/main/kotlin/tech/libeufin/bank/Metadata.kt @@ -0,0 +1,54 @@ +/* + * This file is part of LibEuFin. + * Copyright (C) 2019 Stanisci and Dold. + + * LibEuFin is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3, or + * (at your option) any later version. + + * LibEuFin is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + + * You should have received a copy of the GNU Affero General Public + * License along with LibEuFin; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/> + */ +package tech.libeufin.bank + +sealed interface TxMetadata { + // TODO versioning ? + companion object { + fun parse(subject: String): TxMetadata? { + // IncomingTxMetadata + try { + return IncomingTxMetadata(EddsaPublicKey(subject)) + } catch (e: Exception) { } + + // OutgoingTxMetadata + try { + val (wtid, exchangeBaseUrl) = subject.split(" ", limit=2) ; + return OutgoingTxMetadata(ShortHashCode(wtid), exchangeBaseUrl) + } catch (e: Exception) { } + + // No well formed metadata + return null + } + + fun encode(metadata: TxMetadata): String { + return when (metadata) { + is IncomingTxMetadata -> "${metadata.reservePub}" + is OutgoingTxMetadata -> "${metadata.wtid} ${metadata.exchangeBaseUrl}" + } + } + } +} + +data class IncomingTxMetadata(val reservePub: EddsaPublicKey): TxMetadata { + override fun toString(): String = TxMetadata.encode(this) +} +data class OutgoingTxMetadata(val wtid: ShortHashCode, val exchangeBaseUrl: String): TxMetadata { + override fun toString(): String = TxMetadata.encode(this) +}
\ No newline at end of file diff --git a/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApiHandlers.kt b/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApiHandlers.kt index 7dfbe1c5..1971ba29 100644 --- a/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApiHandlers.kt +++ b/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApiHandlers.kt @@ -136,9 +136,11 @@ fun Routing.talerWireGatewayHandlers(db: Database, ctx: BankApplicationContext) "Currency mismatch", TalerErrorCode.TALER_EC_GENERIC_CURRENCY_MISMATCH ) + + val subject = IncomingTxMetadata(req.reserve_pub).toString() // TODO check conflict in transaction - if (db.bankTransactionCheckExists(req.reserve_pub.encoded()) != null) + if (db.bankTransactionCheckExists(subject) != null) throw conflict( "Reserve pub. already used", TalerErrorCode.TALER_EC_BANK_DUPLICATE_RESERVE_PUB_SUBJECT @@ -158,7 +160,7 @@ fun Routing.talerWireGatewayHandlers(db: Database, ctx: BankApplicationContext) amount = req.amount, creditorAccountId = exchangeAccount.id, transactionDate = txTimestamp, - subject = req.reserve_pub.encoded() + subject = subject ) val res = db.bankTransactionCreate(op) /** diff --git a/bank/src/test/kotlin/TalerApiTest.kt b/bank/src/test/kotlin/TalerApiTest.kt index 0cdd450a..ebe74fde 100644 --- a/bank/src/test/kotlin/TalerApiTest.kt +++ b/bank/src/test/kotlin/TalerApiTest.kt @@ -74,7 +74,7 @@ class TalerApiTest { BankInternalTransaction( creditorAccountId = from, debtorAccountId = to, - subject = randShortHashCode().encoded(), + subject = IncomingTxMetadata(randShortHashCode()).toString(), amount = TalerAmount( 10, 0, "KUDOS"), accountServicerReference = "acct-svcr-ref", endToEndId = "end-to-end-id", |