From e121d549fcc02efe00350ab4fe01a22220d9f149 Mon Sep 17 00:00:00 2001 From: Antoine A <> Date: Fri, 15 Mar 2024 16:00:35 +0100 Subject: FIx cashin idempotency when conversion is enabled --- database-versioning/libeufin-nexus-procedures.sql | 17 ++++++++++------- testbench/src/main/kotlin/Main.kt | 2 +- testbench/src/test/kotlin/IntegrationTest.kt | 21 ++++++++++----------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/database-versioning/libeufin-nexus-procedures.sql b/database-versioning/libeufin-nexus-procedures.sql index ed68ecc9..b941a739 100644 --- a/database-versioning/libeufin-nexus-procedures.sql +++ b/database-versioning/libeufin-nexus-procedures.sql @@ -216,13 +216,16 @@ SELECT reg.out_found, reg.out_tx_id INTO out_found, out_tx_id; -- Register as talerable bounce -INSERT INTO talerable_incoming_transactions ( - incoming_transaction_id - ,reserve_public_key -) VALUES ( - out_tx_id - ,in_reserve_public_key -) ON CONFLICT (incoming_transaction_id) DO NOTHING; +IF NOT EXISTS(SELECT 1 FROM talerable_incoming_transactions WHERE incoming_transaction_id = out_tx_id) THEN + -- We cannot use ON CONFLICT here because conversion use a trigger before insertion that isn't idempotent + INSERT INTO talerable_incoming_transactions ( + incoming_transaction_id + ,reserve_public_key + ) VALUES ( + out_tx_id + ,in_reserve_public_key + ); +END IF; END $$; COMMENT ON FUNCTION register_incoming_and_talerable IS ' Creates one row in the incoming transactions table and one row diff --git a/testbench/src/main/kotlin/Main.kt b/testbench/src/main/kotlin/Main.kt index cc553ee8..7c6b9db4 100644 --- a/testbench/src/main/kotlin/Main.kt +++ b/testbench/src/main/kotlin/Main.kt @@ -132,7 +132,7 @@ class Cli : CliktCommand("Run integration tests on banks provider") { }) } put("reset-db", "dbinit -r $flags") - put("recover", "Recover old transactions", "ebics-fetch $ebicsFlags --pinned-start 2022-01-01 notification") + put("recover", "Recover old transactions", "ebics-fetch $ebicsFlags --pinned-start 2024-01-01 notification") put("fetch", "Fetch all documents", "ebics-fetch $ebicsFlags") put("ack", "Fetch CustomerAcknowledgement", "ebics-fetch $ebicsFlags acknowledgement") put("status", "Fetch CustomerPaymentStatusReport", "ebics-fetch $ebicsFlags status") diff --git a/testbench/src/test/kotlin/IntegrationTest.kt b/testbench/src/test/kotlin/IntegrationTest.kt index 2f529a90..b6ede6c0 100644 --- a/testbench/src/test/kotlin/IntegrationTest.kt +++ b/testbench/src/test/kotlin/IntegrationTest.kt @@ -119,15 +119,10 @@ class IntegrationTest { suspend fun checkCount(db: NexusDb, nbIncoming: Int, nbBounce: Int, nbTalerable: Int) { db.conn { conn -> - conn.prepareStatement("SELECT count(*) FROM incoming_transactions").oneOrNull { - assertEquals(nbIncoming, it.getInt(1)) - } - conn.prepareStatement("SELECT count(*) FROM bounced_transactions").oneOrNull { - assertEquals(nbBounce, it.getInt(1)) - } - conn.prepareStatement("SELECT count(*) FROM talerable_incoming_transactions").oneOrNull { - assertEquals(nbTalerable, it.getInt(1)) - } + val cIncoming = conn.prepareStatement("SELECT count(*) FROM incoming_transactions").one { it.getInt(1) } + val cBounce = conn.prepareStatement("SELECT count(*) FROM bounced_transactions").one { it.getInt(1) } + val cTalerable = conn.prepareStatement("SELECT count(*) FROM talerable_incoming_transactions").one { it.getInt(1) } + assertEquals(Triple(nbIncoming, nbBounce, nbTalerable), Triple(cIncoming, cBounce, cTalerable)) } } @@ -202,18 +197,22 @@ class IntegrationTest { }.assertNoContent() // Check success - ingestIncomingPayment(db, IncomingPayment( + val valid_payment = IncomingPayment( amount = TalerAmount("EUR:10"), debitPaytoUri = userPayTo.toString(), wireTransferSubject = "Success ${Base32Crockford32B.rand().encoded()}", executionTime = Instant.now(), bankId = "success" - )) + ) + ingestIncomingPayment(db, valid_payment) checkCount(db, 2, 1, 1) client.get("http://0.0.0.0:8080/accounts/exchange/transactions") { basicAuth("exchange", "password") }.assertOkJson() + // Check idempotency + ingestIncomingPayment(db, valid_payment) + checkCount(db, 2, 1, 1) // TODO check double insert cashin with different subject } } -- cgit v1.2.3