gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-anastasis] branch master updated: first fun


From: gnunet
Subject: [GNUnet-SVN] [taler-anastasis] branch master updated: first fun
Date: Thu, 17 Oct 2019 10:53:45 +0200

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

grothoff pushed a commit to branch master
in repository anastasis.

The following commit(s) were added to refs/heads/master by this push:
     new 20abbdd  first fun
20abbdd is described below

commit 20abbdd05f01bc7333d73afafd6e3d8345227bc0
Author: Christian Grothoff <address@hidden>
AuthorDate: Thu Oct 17 10:53:38 2019 +0200

    first fun
---
 src/backup-db/plugin_anastasis_postgres.c | 278 +++++++++++++++++++++++++-----
 src/include/anastasis_database_plugin.h   |   5 +-
 2 files changed, 233 insertions(+), 50 deletions(-)

diff --git a/src/backup-db/plugin_anastasis_postgres.c 
b/src/backup-db/plugin_anastasis_postgres.c
index b9e4646..9ff91cb 100644
--- a/src/backup-db/plugin_anastasis_postgres.c
+++ b/src/backup-db/plugin_anastasis_postgres.c
@@ -67,10 +67,10 @@ postgres_drop_tables (void *cls)
 {
   struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_ExecuteStatement es[] = {
-    GNUNET_PQ_make_try_execute ("DROP TABLE IF EXISTS anastasis_truth 
CASCADE;"),
+    GNUNET_PQ_make_try_execute ("DROP TABLE IF EXISTS anastasis_truth;"),
     GNUNET_PQ_make_try_execute ("DROP TABLE IF EXISTS anastasis_user 
CASCADE;"),
-    GNUNET_PQ_make_try_execute ("DROP TABLE IF EXISTS anastasis_payment 
CASCADE;"),
-    GNUNET_PQ_make_try_execute ("DROP TABLE IF EXISTS 
anastasis_recoverydocument CASCADE;"),
+    GNUNET_PQ_make_try_execute ("DROP TABLE IF EXISTS anastasis_payment;"),
+    GNUNET_PQ_make_try_execute ("DROP TABLE IF EXISTS 
anastasis_recoverydocument;"),
 
     GNUNET_PQ_EXECUTE_STATEMENT_END
   };
@@ -235,7 +235,7 @@ postgres_store_recovery_document (void *cls,
     GNUNET_PQ_query_param_auto_from_type (anastasis_pub),
     GNUNET_PQ_query_param_fixed_size (data, data_size),
     GNUNET_PQ_query_param_auto_from_type (payment_secret),
-    GNUNET_PQ_query_param_uint32 (version),
+    //    GNUNET_PQ_query_param_uint32 (version),
     GNUNET_PQ_query_param_end
   };
   
@@ -249,12 +249,64 @@ postgres_store_recovery_document (void *cls,
                                              params);
 }
 
+
+static int
+begin_transaction (struct PostgresClosure *pg)
+{
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  if (GNUNET_OK !=
+      GNUNET_PQ_exec_statements (pg->conn,
+                                 es))
+  {
+    TALER_LOG_ERROR ("Failed to start transaction\n");
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+static void
+rollback (struct PostgresClosure *pg)
+{
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("ROLLBACK"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  if (GNUNET_OK !=
+      GNUNET_PQ_exec_statements (pg->conn,
+                                 es))
+  {
+    TALER_LOG_ERROR ("Failed to rollback transaction\n");
+    GNUNET_break (0);
+  }
+}
+
+
+static enum GNUNET_DB_QueryStatus 
+commit_transaction (struct PostgresClosure *pg)
+{
+  struct GNUNET_PQ_QueryParam no_params[] = {
+    GNUNET_PQ_query_param_end
+  };
+
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                            "do_commit",
+                                            no_params);
+}
+
+
+
 /**
  * FIXME
  * Insert proposal data and its hashcode into db
  *
  * @param cls closure
- * @param payment_id identifier of the payment
  * @param amount amount of taler to be paid
  * @param anastasis_pub anastasis's public key
  * @param num_uploads number of uploads the user can make
@@ -264,7 +316,6 @@ postgres_store_recovery_document (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_record_payment (void *cls,
-                         const uint32_t *payment_id,
                          const struct TALER_Amount *amount,
                          const struct ANASTASIS_AccountPubP *anastasis_pub,
                          unsigned int *num_uploads,
@@ -272,32 +323,131 @@ postgres_record_payment (void *cls,
                          const struct ANASTASIS_PaymentSecretP *payment_secret)
 {
   struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_auto_from_type (payment_id),
-    GNUNET_PQ_query_param_auto_from_type (amount),
-    GNUNET_PQ_query_param_auto_from_type (anastasis_pub),
-    GNUNET_PQ_query_param_absolute_time (&lifetime_inc),
-    GNUNET_PQ_query_param_end
-  };
-
+  enum GNUNET_DB_QueryStatus qs;
+  struct GNUNET_TIME_Absolute paid_until;
+  
+  check_connection (pg);
   if (GNUNET_OK !=
-      TALER_JSON_hash (contract_terms,
-                       &h_contract_terms))
+      begin_transaction (pg))
   {
     GNUNET_break (0);
-    return GNUNET_SYSERR;
+    return GNUNET_DB_STATUS_HARD_ERROR;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "inserting contract terms: order_id: %s, anastasis_pub: %s, 
h_contract_terms: %s.\n",
-              order_id,
-              TALER_B2S (anastasis_pub),
-              GNUNET_h2s (&h_contract_terms));
-  check_connection (pg);
-  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                             "insert_contract_terms",
-                                             params);
+  
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_auto_from_type (anastasis_pub),
+      GNUNET_PQ_query_param_end
+    };
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      TALER_PQ_result_spec_absolute_time ("paid_until",
+                                         &paid_until),
+      GNUNET_PQ_result_spec_end
+    };
+    
+    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                   "user_select",
+                                                   params,
+                                                   rs);
+    switch (qs)
+    {
+    case GNUNET_DB_STATUS_HARD_ERROR:
+      rollback (pg);
+      return qs;
+    case GNUNET_DB_STATUS_SOFT_ERROR:
+      // FIXME: or: retry internally?
+      rollback (pg);      
+      return qs;
+    case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+      paid_until = GNUNET_TIME_absolute_get ();
+      break;
+    case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+      paid_until = GNUNET_TIME_absolute_max (GNUNET_TIME_absolute_get (),
+                                            paid_until);
+      break;
+    }
+  }
+  paid_until = GNUNET_TIME_absolute_add (paid_until,
+                                        lifetime_inc);
+  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+    {
+      /* user did not yet exist, create */
+      struct GNUNET_PQ_QueryParam params[] = {
+        GNUNET_PQ_query_param_auto_from_type (anastasis_pub),
+       GNUNET_PQ_query_param_absolute_time (&paid_until),
+       GNUNET_PQ_query_param_end
+      };
+      
+      qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                              "user_insert",
+                                              params);
+    }
+  else
+    {
+      /* user exists, update */
+      struct GNUNET_PQ_QueryParam params[] = {
+       GNUNET_PQ_query_param_absolute_time (&paid_until),
+        GNUNET_PQ_query_param_auto_from_type (anastasis_pub),
+       GNUNET_PQ_query_param_end
+      };
+      
+      qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                              "user_update",
+                                              params);      
+    }
+  switch (qs)
+    {
+    case GNUNET_DB_STATUS_HARD_ERROR:
+      rollback (pg);
+      return qs;
+    case GNUNET_DB_STATUS_SOFT_ERROR:
+      // FIXME: or: retry internally?
+      rollback (pg);      
+      return qs;
+    case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+      GNUNET_break (0);
+      rollback (pg);      
+      return GNUNET_DB_STATUS_HARD_ERROR;
+    case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:      
+      break;
+    }
+
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_auto_from_type (anastasis_pub),
+      GNUNET_PQ_query_param_uint32 (post_counter),
+      GNUNET_PQ_query_param_auto_from_type (payment_secret),
+      GNUNET_PQ_query_param_end
+    };
+
+    qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                            "payment_insert",
+                                            params);
+ 
+    switch (qs)
+    {
+    case GNUNET_DB_STATUS_HARD_ERROR:
+      rollback (pg);
+      return qs;
+    case GNUNET_DB_STATUS_SOFT_ERROR:
+      rollback (pg);      
+      return qs;
+    case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+      GNUNET_break (0);
+      rollback (pg);      
+      return GNUNET_DB_STATUS_HARD_ERROR;
+    case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:      
+      break;
+    }
+  }
+
+  qs = commit_transaction (pg);
+  if (qs < 0)
+    return qs;
+  return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
 }
 
+
 /**
  * Initialize Postgres database subsystem.
  *
@@ -316,35 +466,69 @@ libtaler_plugin_anastasis_db_postgres_init (void *cls)
        The contract terms will change (nonce will be added) when moved to the
        contract terms table */
     GNUNET_PQ_make_execute ("CREATE TABLE anastasis_truth
-                            ( truth_id uuid PRIMARY KEY NOT NULL,
-                              truth bytea,
-                              expiration timestamp
-                            );"),                 
-
+                            ( truth_id UUID PRIMARY KEY NOT NULL,
+                              truth BYTEA NOT NULL,
+                              expiration TIMESTAMP NOT NULL
+                            );"),              
     GNUNET_PQ_make_execute ("CREATE TABLE anastasis_user
-                            ( user_id bytea PRIMARY KEY,
-                              downloads integer,
-                              last_payment timestamp
-                            );"),
-                    
+                            ( user_id BYTEA PRIMARY KEY 
CHECK(LENGTH(user_id)=32),
+                              paid_until TIMESTAMP NOT NULL
+                            );"),                    
     GNUNET_PQ_make_execute ("CREATE TABLE anastasis_payments
-                            ( payment_id integer PRIMARY KEY,
-                              user_id bytea REFERENCES anastasis_user(user_id),
-                              postcounter integer,
-                              payment_secret bytea, 
-                              transaction_time timestamp,
-                              paid_until timestamp
+                            ( payment_id BIGSERIAL PRIMARY KEY,
+                              user_id BYTEA NOT NULL REFERENCES 
anastasis_user(user_id),
+                              post_counter INTEGER,
+                              payment_identifier BYTEA NOT NULL 
CHECK(LENGTH(payment_secret)=32), 
+                              transaction_time TIMESTAMP NOT NULL DEFAULT NOW()
                             );"),
-
     GNUNET_PQ_make_execute ("CREATE TABLE anastasis_recoverydocument
-                            ( user_id bytea REFERENCES anastasis_user(user_id),
-                              version integer,
-                              recovery_data bytea,
+                            ( user_id BYTEA NOT NULL REFERENCES 
anastasis_user(user_id),
+                              version INTEGER,
+                              recovery_data BYTEA,
                               PRIMARY KEY (user_id, version)
                             );"),
-
     GNUNET_PQ_EXECUTE_STATEMENT_END
   };
+  struct GNUNET_PQ_PreparedStatement ps[] = {                               
+    GNUNET_PQ_make_prepare ("user_insert",
+                            "INSERT INTO anastasis_user "
+                            "(user_id"
+                            ",paid_until"
+                            ") VALUES "
+                            "($1, $2);",
+                            2),
+    GNUNET_PQ_make_prepare ("do_commit",
+                            "COMMIT",
+                            0),
+    GNUNET_PQ_make_prepare ("user_select",
+                            "SELECT"
+                           " paid_until "
+                            "FROM anastasis_user"
+                            " WHERE user_id=$1"
+                            " FOR UPDATE;",
+                            1),
+    GNUNET_PQ_make_prepare ("user_update",
+                            "UPDATE anastasis_user"
+                           " SET "
+                            " paid_until=$1"
+                            " WHERE user_id=$2;",
+                            2),
+    GNUNET_PQ_make_prepare ("user_insert",
+                            "INSERT INTO anastasis_user "
+                           "(user_id"
+                           ",paid_until"
+                            ") VALUES($1,$2)",
+                            2),
+    GNUNET_PQ_make_prepare ("payment_insert",
+                            "INSERT INTO anastasis_payments "
+                            "(user_id"
+                            ",post_counter"
+                           ",payment_identifier",
+                            ") VALUES "
+                            "($1, $2, $3);",
+                            3),
+    GNUNET_PQ_PREPARED_STATEMENT_END
+  };
 
   pg = GNUNET_new (struct PostgresClosure);
   pg->cfg = cfg;
diff --git a/src/include/anastasis_database_plugin.h 
b/src/include/anastasis_database_plugin.h
index 6ce9c6d..0ab6931 100644
--- a/src/include/anastasis_database_plugin.h
+++ b/src/include/anastasis_database_plugin.h
@@ -114,17 +114,16 @@ struct AnastasisDatabasePlugin
    * @param payment_id identifier of the payment
    * @param amount how much was paid
    * @param anastasis_pub public key of the user's account
-   * @param num_uploads how many uploads does @a amount pay for
+   * @param initial_post_counter how many uploads does @a amount pay for
    * @param lifetime_inc for how long does @a amount pay for account 
maintenance
    * @param payment_secret identifier for the payment, used to later charge on 
uploads
    * @return transaction status
    */
   enum GNUNET_DB_QueryStatus
   (*record_payment)(void *cls,
-                    const uint32_t payment_id,
                     const struct TALER_Amount *amount,
                     const struct ANASTASIS_AccountPubP *anastasis_pub,
-                    unsigned int num_uploads,
+                    unsigned int initial_post_counter,
                     struct GNUNET_TIME_Relative lifetime_inc,
                     const struct ANASTASIS_PaymentSecretP *payment_secret);
 

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

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