[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: Nexus DB.
From: |
gnunet |
Subject: |
[libeufin] branch master updated: Nexus DB. |
Date: |
Wed, 25 Oct 2023 09:44:29 +0200 |
This is an automated email from the git hooks/post-receive script.
ms pushed a commit to branch master
in repository libeufin.
The following commit(s) were added to refs/heads/master by this push:
new b5f49fe4 Nexus DB.
b5f49fe4 is described below
commit b5f49fe4dc38c8e4f818fc45eba7e1264160f581
Author: MS <ms@taler.net>
AuthorDate: Wed Oct 25 09:42:18 2023 +0200
Nexus DB.
Method to create one incoming transaction, bounce it,
and finally create its related initiated outgoing payment
for the reimbursement.
---
database-versioning/libeufin-nexus-procedures.sql | 47 ++++++++++++++++-
.../main/kotlin/tech/libeufin/nexus/Database.kt | 60 +++++++++++++++++++---
nexus/src/test/kotlin/Common.kt | 1 -
nexus/src/test/kotlin/DatabaseTest.kt | 26 ++++++++++
4 files changed, 125 insertions(+), 9 deletions(-)
diff --git a/database-versioning/libeufin-nexus-procedures.sql
b/database-versioning/libeufin-nexus-procedures.sql
index b6150cec..d9e547cd 100644
--- a/database-versioning/libeufin-nexus-procedures.sql
+++ b/database-versioning/libeufin-nexus-procedures.sql
@@ -1,7 +1,50 @@
BEGIN;
SET search_path TO libeufin_nexus;
-CREATE OR REPLACE FUNCTION create_outgoing_tx(
+CREATE OR REPLACE FUNCTION create_incoming_and_bounce(
+ IN in_amount taler_amount
+ ,IN in_wire_transfer_subject TEXT
+ ,IN in_execution_time BIGINT
+ ,IN in_debit_payto_uri TEXT
+ ,IN in_bank_transfer_id TEXT
+ ,IN in_timestamp BIGINT
+) RETURNS void
+LANGUAGE plpgsql AS $$
+BEGIN
+-- creating the bounced incoming transaction.
+INSERT INTO incoming_transactions (
+ amount
+ ,wire_transfer_subject
+ ,execution_time
+ ,debit_payto_uri
+ ,bank_transfer_id
+ ,bounced
+ ) VALUES (
+ in_amount
+ ,in_wire_transfer_subject
+ ,in_execution_time
+ ,in_debit_payto_uri
+ ,in_bank_transfer_id
+ ,true
+ );
+-- creating its reimbursement.
+INSERT INTO initiated_outgoing_transactions (
+ amount
+ ,wire_transfer_subject
+ ,credit_payto_uri
+ ,initiation_time
+ ) VALUES (
+ in_amount
+ ,'refund: ' || in_wire_transfer_subject
+ ,in_debit_payto_uri
+ ,in_timestamp
+ );
+END $$;
+
+COMMENT ON FUNCTION create_incoming_and_bounce(taler_amount, TEXT, BIGINT,
TEXT, TEXT, BIGINT)
+ IS 'creates one incoming transaction with a bounced state and initiates its
related refund.';
+
+CREATE OR REPLACE FUNCTION create_outgoing_payment(
IN in_amount taler_amount
,IN in_wire_transfer_subject TEXT
,IN in_execution_time BIGINT
@@ -51,7 +94,7 @@ THEN
END IF;
END $$;
-COMMENT ON FUNCTION create_outgoing_tx(taler_amount, TEXT, BIGINT, TEXT, TEXT,
BIGINT)
+COMMENT ON FUNCTION create_outgoing_payment(taler_amount, TEXT, BIGINT, TEXT,
TEXT, BIGINT)
IS 'Creates a new outgoing payment and optionally reconciles the related
initiated payment with it. If the initiated payment to reconcile is not found,
it inserts NOTHING.';
CREATE OR REPLACE FUNCTION bounce_payment(
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Database.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/Database.kt
index 50242e8c..d6ad81fa 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Database.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Database.kt
@@ -28,8 +28,7 @@ data class IncomingPayment(
val wireTransferSubject: String?,
val debitPaytoUri: String,
val executionTime: Instant,
- val bankTransferId: String,
- val bounced: Boolean
+ val bankTransferId: String
)
// INITIATED PAYMENTS STRUCTS
@@ -51,8 +50,18 @@ data class InitiatedPayment(
* into the database.
*/
enum class PaymentInitiationOutcome {
+ /**
+ * The Payto address to send the payment to was invalid.
+ */
BAD_CREDIT_PAYTO,
+ /**
+ * The row contains a client_request_uid that exists
+ * already in the database.
+ */
UNIQUE_CONSTRAINT_VIOLATION,
+ /**
+ * Record successfully created.
+ */
SUCCESS
}
@@ -71,7 +80,18 @@ data class OutgoingPayment(
* payment into the database.
*/
enum class OutgoingPaymentOutcome {
+ /**
+ * The caller wanted to link a previously initiated payment
+ * to this outgoing one, but the row ID passed to the inserting
+ * function could not be found in the payment initiations table.
+ * Note: NO insertion takes place in this case.
+ */
INITIATED_COUNTERPART_NOT_FOUND,
+ /**
+ * The outgoing payment got inserted and _in case_ the caller
+ * wanted to link a previously initiated payment to this one, that
+ * succeeded too.
+ */
SUCCESS
}
@@ -148,7 +168,7 @@ class Database(dbConfig: String): java.io.Closeable {
): OutgoingPaymentOutcome = runConn {
val stmt = it.prepareStatement("""
SELECT out_nx_initiated
- FROM create_outgoing_tx(
+ FROM create_outgoing_payment(
(?,?)::taler_amount
,?
,?
@@ -205,6 +225,37 @@ class Database(dbConfig: String): java.io.Closeable {
}
}
+ /**
+ * Creates an incoming payment as bounced _and_ initiates its
+ * reimbursement. Throws exception on unique constraint violation,
+ * or other errors.
+ *
+ * @param paymentData information related to the incoming payment.
+ */
+ suspend fun incomingPaymentCreateBounced(paymentData: IncomingPayment) =
runConn { conn ->
+ val refundTimestamp = Instant.now().toDbMicros()
+ ?: throw Exception("Could not convert refund execution time from
Instant.now() to microsends.")
+ val executionTime = paymentData.executionTime.toDbMicros()
+ ?: throw Exception("Could not convert payment execution time from
Instant to microseconds.")
+ val stmt = conn.prepareStatement("""
+ SELECT create_incoming_and_bounce (
+ (?,?)::taler_amount
+ ,?
+ ,?
+ ,?
+ ,?
+ ,?
+ )""")
+ stmt.setLong(1, paymentData.amount.value)
+ stmt.setInt(2, paymentData.amount.fraction)
+ stmt.setString(3, paymentData.wireTransferSubject)
+ stmt.setLong(4, executionTime)
+ stmt.setString(5, paymentData.debitPaytoUri)
+ stmt.setString(6, paymentData.bankTransferId)
+ stmt.setLong(7, refundTimestamp)
+ stmt.executeQuery()
+ }
+
/**
* Creates a new incoming payment record in the database.
*
@@ -219,14 +270,12 @@ class Database(dbConfig: String): java.io.Closeable {
,execution_time
,debit_payto_uri
,bank_transfer_id
- ,bounced
) VALUES (
(?,?)::taler_amount
,?
,?
,?
,?
- ,?
)
""")
stmt.setLong(1, paymentData.amount.value)
@@ -238,7 +287,6 @@ class Database(dbConfig: String): java.io.Closeable {
stmt.setLong(4, executionTime)
stmt.setString(5, paymentData.debitPaytoUri)
stmt.setString(6, paymentData.bankTransferId)
- stmt.setBoolean(7, paymentData.bounced)
return@runConn stmt.maybeUpdate()
}
diff --git a/nexus/src/test/kotlin/Common.kt b/nexus/src/test/kotlin/Common.kt
index fe4bdcd2..c8f88fca 100644
--- a/nexus/src/test/kotlin/Common.kt
+++ b/nexus/src/test/kotlin/Common.kt
@@ -88,7 +88,6 @@ fun genIncPay(subject: String? = null, rowUuid: String? =
null) =
debitPaytoUri = "payto://iban/not-used",
wireTransferSubject = subject,
executionTime = Instant.now(),
- bounced = false,
bankTransferId = "entropic"
)
diff --git a/nexus/src/test/kotlin/DatabaseTest.kt
b/nexus/src/test/kotlin/DatabaseTest.kt
index d2a2a92d..9aedb99a 100644
--- a/nexus/src/test/kotlin/DatabaseTest.kt
+++ b/nexus/src/test/kotlin/DatabaseTest.kt
@@ -43,6 +43,32 @@ class OutgoingPaymentsTest {
}
class IncomingPaymentsTest {
+ // Tests creating and bouncing incoming payments in one DB transaction.
+ @Test
+ fun incomingAndBounce() {
+ val db = prepDb(TalerConfig(NEXUS_CONFIG_SOURCE))
+ runBlocking {
+ // creating and bouncing one incoming transaction.
+ db.incomingPaymentCreateBounced(genIncPay("incoming and bounced"))
+ db.runConn {
+ // check the bounced flaag is true
+ val checkBounced = it.prepareStatement("""
+ SELECT bounced FROM incoming_transactions WHERE
incoming_transaction_id = 1;
+ """).executeQuery()
+ assertTrue(checkBounced.next())
+ assertTrue(checkBounced.getBoolean("bounced"))
+ // check the related initiated payment exists.
+ val checkInitiated = it.prepareStatement("""
+ SELECT
+ COUNT(initiated_outgoing_transaction_id) AS how_many
+ FROM initiated_outgoing_transactions
+ """).executeQuery()
+ assertTrue(checkInitiated.next())
+ assertEquals(1, checkInitiated.getInt("how_many"))
+ }
+ }
+ }
+
// Tests the function that flags incoming payments as bounced.
@Test
fun incomingPaymentBounce() {
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libeufin] branch master updated: Nexus DB.,
gnunet <=