gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: -more work on extended fakebank


From: gnunet
Subject: [taler-exchange] branch master updated: -more work on extended fakebank API
Date: Mon, 15 Aug 2022 20:23:04 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new f76f6457 -more work on extended fakebank API
f76f6457 is described below

commit f76f645732d97aee4d7cc4b9fae44bdbd6ec57be
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon Aug 15 20:23:02 2022 +0200

    -more work on extended fakebank API
---
 contrib/gana            |   2 +-
 src/bank-lib/fakebank.c | 407 +++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 372 insertions(+), 37 deletions(-)

diff --git a/contrib/gana b/contrib/gana
index 1a8af54b..e340b038 160000
--- a/contrib/gana
+++ b/contrib/gana
@@ -1 +1 @@
-Subproject commit 1a8af54b491e8300287eb7afb08ba22b91107f9a
+Subproject commit e340b038e3a5ae3fbb87a68b534bd2646df5e6f0
diff --git a/src/bank-lib/fakebank.c b/src/bank-lib/fakebank.c
index e423c115..2f1d7868 100644
--- a/src/bank-lib/fakebank.c
+++ b/src/bank-lib/fakebank.c
@@ -118,6 +118,60 @@ struct LongPoller
  */
 struct Transaction;
 
+
+/**
+ * Information we keep per withdraw operation.
+ */
+struct WithdrawalOperation
+{
+  /**
+   * Unique (random) operation ID.
+   */
+  struct GNUNET_ShortHashCode wopid;
+
+  /**
+   * Debited account.
+   */
+  struct Account *debit_account;
+
+  /**
+   * Target exchange account, or NULL if unknown.
+   */
+  char *exchange_account;
+
+  /**
+   * Resulting transaction, if any. Otherwise NULL.
+   */
+  struct Transaction *transaction;
+
+  /**
+   * Amount transferred.
+   */
+  struct TALER_Amount amount;
+
+  /**
+   * Public key of the reserve, wire transfer subject.
+   */
+  struct TALER_ReservePublicKeyP reserve_pub;
+
+  /**
+   * Was the withdrawal aborted?
+   */
+  bool aborted;
+
+  /**
+   * Did the bank confirm the withdrawal?
+   */
+  bool confirmation_done;
+
+  /**
+   * Is @e reserve_pub initialized?
+   */
+  bool selection_done;
+
+};
+
+
 /**
  * Per account information.
  */
@@ -365,6 +419,13 @@ struct TALER_FAKEBANK_Handle
    */
   struct GNUNET_CONTAINER_MultiPeerMap *rpubs;
 
+  /**
+   * Hashmap of short hashes (wopids) to
+   * `struct WithdrawalOperation`.
+   * Used to lookup withdrawal operations.
+   */
+  struct GNUNET_CONTAINER_MultiShortmap *wops;
+
   /**
    * Lock for accessing @a rpubs map.
    */
@@ -481,6 +542,35 @@ static void
 run_mhd (void *cls);
 
 
+/**
+ * Find withdrawal operation @a wopid in @a h.
+ *
+ * @param h fakebank handle
+ * @param wopid withdrawal operation ID as a string
+ * @return NULL if operation was not found
+ */
+static struct WithdrawalOperation *
+lookup_withdrawal_operation (struct TALER_FAKEBANK_Handle *h,
+                             const char *wopid)
+{
+  struct GNUNET_ShortHashCode sh;
+
+  if (NULL == h->wops)
+    return NULL;
+  if (GNUNET_OK !=
+      GNUNET_STRINGS_string_to_data (wopid,
+                                     strlen (wopid),
+                                     &sh,
+                                     sizeof (sh)))
+  {
+    GNUNET_break_op (0);
+    return NULL;
+  }
+  return GNUNET_CONTAINER_multishortmap_get (h->wops,
+                                             &sh);
+}
+
+
 /**
  * Trigger the @a lp. Frees associated resources,
  * except the entry of @a lp in the timeout heap.
@@ -1268,7 +1358,14 @@ TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle 
*h)
 }
 
 
-static int
+/**
+ * Helper function to free memory when finished.
+ *
+ * @param cls NULL
+ * @param key key of the account to free (ignored)
+ * @param val a `struct Account` to free.
+ */
+static enum GNUNET_GenericReturnValue
 free_account (void *cls,
               const struct GNUNET_HashCode *key,
               void *val)
@@ -1285,6 +1382,28 @@ free_account (void *cls,
 }
 
 
+/**
+ * Helper function to free memory when finished.
+ *
+ * @param cls NULL
+ * @param key key of the operation to free (ignored)
+ * @param val a `struct WithdrawalOperation *` to free.
+ */
+static enum GNUNET_GenericReturnValue
+free_withdraw_op (void *cls,
+                  const struct GNUNET_ShortHashCode *key,
+                  void *val)
+{
+  struct WithdrawalOperation *wo = val;
+
+  (void) cls;
+  (void) key;
+  GNUNET_free (wo->exchange_account);
+  GNUNET_free (wo);
+  return GNUNET_OK;
+}
+
+
 void
 TALER_FAKEBANK_stop (struct TALER_FAKEBANK_Handle *h)
 {
@@ -1365,6 +1484,13 @@ TALER_FAKEBANK_stop (struct TALER_FAKEBANK_Handle *h)
                                            NULL);
     GNUNET_CONTAINER_multihashmap_destroy (h->accounts);
   }
+  if (NULL != h->wops)
+  {
+    GNUNET_CONTAINER_multishortmap_iterate (h->wops,
+                                            &free_withdraw_op,
+                                            NULL);
+    GNUNET_CONTAINER_multishortmap_destroy (h->wops);
+  }
   GNUNET_CONTAINER_multihashmap_destroy (h->uuid_map);
   GNUNET_CONTAINER_multipeermap_destroy (h->rpubs);
   GNUNET_CONTAINER_heap_destroy (h->lp_heap);
@@ -2530,27 +2656,42 @@ get_withdrawal_operation (struct TALER_FAKEBANK_Handle 
*h,
                           struct GNUNET_TIME_Relative lp,
                           void **con_cls)
 {
-  // FIXME: check if ready, if so, return reply.
+  struct WithdrawalOperation *wo;
 
+  wo = lookup_withdrawal_operation (h,
+                                    wopid);
+  if (NULL == wo)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_TRANSACTION_NOT_FOUND,
+                                       wopid);
+  }
   if ( (NULL != *con_cls) ||
-       (GNUNET_TIME_relative_is_zero (lp)) )
+       (GNUNET_TIME_relative_is_zero (lp)) ||
+       wo->confirmation_done ||
+       wo->aborted)
   {
-    // FIXME: timeout, return with negative status
-    struct TALER_Amount amount;
+    json_t *wt;
 
+    wt = json_array ();
+    GNUNET_assert (NULL != wt);
+    GNUNET_assert (0 ==
+                   json_array_append_new (wt,
+                                          json_string ("x-taler-bank")));
     return TALER_MHD_REPLY_JSON_PACK (
       connection,
       MHD_HTTP_OK,
       GNUNET_JSON_pack_bool ("aborted",
-                             false),
+                             wo->aborted),
       GNUNET_JSON_pack_bool ("selection_done",
-                             false),
+                             wo->selection_done),
       GNUNET_JSON_pack_bool ("transfer_done",
-                             false),
+                             wo->confirmation_done),
       TALER_JSON_pack_amount ("amount",
-                              &amount),
+                              &wo->amount),
       GNUNET_JSON_pack_array_steal ("wire_types",
-                                    json_array ()));
+                                    wt));
   }
 
   // FIXME: needs variant of 'start_lp()'
@@ -2576,18 +2717,49 @@ do_post_withdrawal (struct TALER_FAKEBANK_Handle *h,
                     struct MHD_Connection *connection,
                     const char *wopid,
                     const struct TALER_ReservePublicKeyP *reserve_pub,
-                    const void *exchange_url)
+                    const char *exchange_url)
 {
-  GNUNET_break (0); // FIXME: not implemented!
-  if (0)
+  struct WithdrawalOperation *wo;
+
+  wo = lookup_withdrawal_operation (h,
+                                    wopid);
+  if (NULL == wo)
   {
-    return TALER_MHD_REPLY_JSON_PACK (
-      connection,
-      MHD_HTTP_OK,
-      GNUNET_JSON_pack_bool ("transfer_done",
-                             true));
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_TRANSACTION_NOT_FOUND,
+                                       wopid);
   }
-  return MHD_NO;
+  if ( (wo->selection_done) &&
+       (0 != GNUNET_memcmp (&wo->reserve_pub,
+                            reserve_pub)) )
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_CONFLICT,
+                                       
TALER_EC_BANK_WITHDRAWAL_OPERATION_RESERVE_SELECTION_CONFLICT,
+                                       NULL);
+  }
+  // FIXME: check if reserve_pub is known. If so:
+  if (0)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_CONFLICT,
+                                       
TALER_EC_BANK_DUPLICATE_RESERVE_PUB_SUBJECT,
+                                       NULL);
+  }
+  wo->reserve_pub = *reserve_pub;
+  GNUNET_free (wo->exchange_account);       // FIXME: or conflict if changed?
+  wo->exchange_account = GNUNET_strdup ("FIXME");        // we have 
'exchange_url', how is this useful?
+  wo->selection_done = true;
+  GNUNET_break (0); // FIXME: not implemented!
+  // FIXME: do we auto-confirm? Or do we want to allow aborts?
+  wo->confirmation_done = true;
+  // FIXME: trigger transfer? but we need the exchange account for that!
+  return TALER_MHD_REPLY_JSON_PACK (
+    connection,
+    MHD_HTTP_OK,
+    GNUNET_JSON_pack_bool ("transfer_done",
+                           wo->confirmation_done));
 }
 
 
@@ -2790,7 +2962,19 @@ get_account_access (struct TALER_FAKEBANK_Handle *h,
                     const char *account_name,
                     void **con_cls)
 {
-  struct TALER_Amount amount; // FIXME: balance...
+  struct Account *acc;
+
+  acc = lookup_account (h,
+                        account_name,
+                        NULL);
+  if (NULL == acc)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_UNKNOWN_ACCOUNT,
+                                       account_name);
+  }
+
   return TALER_MHD_REPLY_JSON_PACK (
     connection,
     MHD_HTTP_OK,
@@ -2800,9 +2984,11 @@ get_account_access (struct TALER_FAKEBANK_Handle *h,
       "balance",
       GNUNET_JSON_PACK (
         GNUNET_JSON_pack_string ("credit_debit_indicator",
-                                 "credit"),
+                                 acc->is_negative
+                                 ? "debit"
+                                 : "credit"),
         TALER_JSON_pack_amount ("amount",
-                                &amount))));
+                                &acc->balance))));
 }
 
 
@@ -2824,19 +3010,55 @@ get_account_withdrawals_access (struct 
TALER_FAKEBANK_Handle *h,
                                 const char *withdrawal_id,
                                 void **con_cls)
 {
-  struct TALER_Amount amount; // FIXME: balance...
+  struct WithdrawalOperation *wo;
+  struct Account *acc;
+
+  wo = lookup_withdrawal_operation (h,
+                                    withdrawal_id);
+  if (NULL == wo)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_TRANSACTION_NOT_FOUND,
+                                       withdrawal_id);
+  }
+  acc = lookup_account (h,
+                        account_name,
+                        NULL);
+  if (NULL == acc)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_UNKNOWN_ACCOUNT,
+                                       account_name);
+  }
+  if (wo->debit_account != acc)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_TRANSACTION_NOT_FOUND,
+                                       account_name);
+  }
   return TALER_MHD_REPLY_JSON_PACK (
     connection,
     MHD_HTTP_OK,
-    GNUNET_JSON_pack_string ("paytoUri",
-                             "payto://FIXME"),
-    GNUNET_JSON_pack_object_steal (
-      "balance",
-      GNUNET_JSON_PACK (
-        GNUNET_JSON_pack_string ("credit_debit_indicator",
-                                 "credit"),
-        TALER_JSON_pack_amount ("amount",
-                                &amount))));
+    GNUNET_JSON_pack_bool ("aborted",
+                           wo->aborted),
+    GNUNET_JSON_pack_bool ("selection_done",
+                           wo->selection_done),
+    GNUNET_JSON_pack_bool ("transfer_done",
+                           wo->confirmation_done),
+    GNUNET_JSON_pack_allow_null (
+      GNUNET_JSON_pack_string ("selected_exchange_account",
+                               wo->exchange_account)),
+    GNUNET_JSON_pack_allow_null (
+      wo->selection_done
+      ? GNUNET_JSON_pack_data_auto ("selected_reserve_pub",
+                                    &wo->reserve_pub)
+      : GNUNET_JSON_pack_string ("selected_reserve_pub",
+                                 NULL)),
+    TALER_JSON_pack_amount ("amount",
+                            &wo->amount));
 }
 
 
@@ -2855,9 +3077,47 @@ do_post_account_withdrawals_access (struct 
TALER_FAKEBANK_Handle *h,
                                     const char *account_name,
                                     const struct TALER_Amount *amount)
 {
-  GNUNET_break (0); // FIXME!
+  struct Account *acc;
+  struct WithdrawalOperation *wo;
 
-  return MHD_NO;
+  acc = lookup_account (h,
+                        account_name,
+                        NULL);
+  if (NULL == acc)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_UNKNOWN_ACCOUNT,
+                                       account_name);
+  }
+  wo = GNUNET_new (struct WithdrawalOperation);
+  wo->debit_account = acc;
+  wo->amount = *amount;
+  if (NULL == h->wops)
+  {
+    h->wops = GNUNET_CONTAINER_multishortmap_create (32,
+                                                     GNUNET_YES);
+  }
+  while (1)
+  {
+    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+                                &wo->wopid,
+                                sizeof (wo->wopid));
+    if (GNUNET_OK ==
+        GNUNET_CONTAINER_multishortmap_put (h->wops,
+                                            &wo->wopid,
+                                            wo,
+                                            
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
+      break;
+  }
+
+  return TALER_MHD_REPLY_JSON_PACK (
+    connection,
+    MHD_HTTP_OK,
+    GNUNET_JSON_pack_string ("taler_withdraw_uri",
+                             "taler://withdraw/FIXME"),
+    GNUNET_JSON_pack_data_auto ("withdrawal_id",
+                                &wo->wopid));
 }
 
 
@@ -2957,7 +3217,44 @@ access_withdrawals_abort (struct TALER_FAKEBANK_Handle 
*h,
                           size_t *upload_data_size,
                           void **con_cls)
 {
-  // fIXME: actual abort logic here...
+  struct WithdrawalOperation *wo;
+  struct Account *acc;
+
+  wo = lookup_withdrawal_operation (h,
+                                    withdrawal_id);
+  if (NULL == wo)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_TRANSACTION_NOT_FOUND,
+                                       withdrawal_id);
+  }
+  acc = lookup_account (h,
+                        account_name,
+                        NULL);
+  if (NULL == acc)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_UNKNOWN_ACCOUNT,
+                                       account_name);
+  }
+  if (wo->debit_account != acc)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_TRANSACTION_NOT_FOUND,
+                                       account_name);
+  }
+  if (wo->confirmation_done)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_CONFLICT,
+                                       TALER_EC_BANK_ABORT_CONFIRM_CONFLICT,
+                                       account_name);
+  }
+  wo->aborted = true;
+  // FIXME: resume long-pollers here...
   return TALER_MHD_reply_json (connection,
                                json_object (),
                                MHD_HTTP_OK);
@@ -2985,7 +3282,45 @@ access_withdrawals_confirm (struct TALER_FAKEBANK_Handle 
*h,
                             size_t *upload_data_size,
                             void **con_cls)
 {
-  // FIXME: actual confirm logic here...
+  struct WithdrawalOperation *wo;
+  struct Account *acc;
+
+  wo = lookup_withdrawal_operation (h,
+                                    withdrawal_id);
+  if (NULL == wo)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_TRANSACTION_NOT_FOUND,
+                                       withdrawal_id);
+  }
+  acc = lookup_account (h,
+                        account_name,
+                        NULL);
+  if (NULL == acc)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_UNKNOWN_ACCOUNT,
+                                       account_name);
+  }
+  if (wo->debit_account != acc)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_BANK_TRANSACTION_NOT_FOUND,
+                                       account_name);
+  }
+  if (wo->aborted)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_CONFLICT,
+                                       TALER_EC_BANK_CONFIRM_ABORT_CONFLICT,
+                                       account_name);
+  }
+  wo->confirmation_done = true;
+  // FIXME: resume long-pollers here...
+  // FIXME: trigger transaction here?
   return TALER_MHD_reply_json (connection,
                                json_object (),
                                MHD_HTTP_OK);

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]