aboutsummaryrefslogtreecommitdiff
path: root/src/exchangedb/plugin_exchangedb_postgres.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchangedb/plugin_exchangedb_postgres.c')
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c2559
1 files changed, 1257 insertions, 1302 deletions
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 724f8022f..a36664fdc 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -55,7 +55,7 @@
55 * @param field name of the database field to fetch amount from 55 * @param field name of the database field to fetch amount from
56 * @param amountp[out] pointer to amount to set 56 * @param amountp[out] pointer to amount to set
57 */ 57 */
58#define TALER_PQ_RESULT_SPEC_AMOUNT_NBO(field, \ 58#define TALER_PQ_RESULT_SPEC_AMOUNT_NBO(field, \
59 amountp) TALER_PQ_result_spec_amount_nbo ( \ 59 amountp) TALER_PQ_result_spec_amount_nbo ( \
60 field,pg->currency,amountp) 60 field,pg->currency,amountp)
61 61
@@ -65,15 +65,15 @@
65 * @param result PQ result object of the PQ operation that failed 65 * @param result PQ result object of the PQ operation that failed
66 * @param conn SQL connection that was used 66 * @param conn SQL connection that was used
67 */ 67 */
68#define BREAK_DB_ERR(result,conn) do { \ 68#define BREAK_DB_ERR(result,conn) do { \
69 GNUNET_break (0); \ 69 GNUNET_break (0); \
70 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ 70 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
71 "Database failure: %s/%s/%s/%s/%s", \ 71 "Database failure: %s/%s/%s/%s/%s", \
72 PQresultErrorField (result, PG_DIAG_MESSAGE_PRIMARY), \ 72 PQresultErrorField (result, PG_DIAG_MESSAGE_PRIMARY), \
73 PQresultErrorField (result, PG_DIAG_MESSAGE_DETAIL), \ 73 PQresultErrorField (result, PG_DIAG_MESSAGE_DETAIL), \
74 PQresultErrorMessage (result), \ 74 PQresultErrorMessage (result), \
75 PQresStatus (PQresultStatus (result)), \ 75 PQresStatus (PQresultStatus (result)), \
76 PQerrorMessage (conn)); \ 76 PQerrorMessage (conn)); \
77} while (0) 77} while (0)
78 78
79 79
@@ -85,7 +85,7 @@ struct TALER_EXCHANGEDB_Session
85 /** 85 /**
86 * Postgres connection handle. 86 * Postgres connection handle.
87 */ 87 */
88 PGconn *conn; 88 struct GNUNET_PQ_Context *conn;
89 89
90 /** 90 /**
91 * Name of the current transaction, for debugging. 91 * Name of the current transaction, for debugging.
@@ -104,7 +104,7 @@ struct PostgresClosure
104 104
105 /** 105 /**
106 * Thread-local database connection. 106 * Thread-local database connection.
107 * Contains a pointer to `PGconn` or NULL. 107 * Contains a pointer to `struct GNUNET_PQ_Context` or NULL.
108 */ 108 */
109 pthread_key_t db_conn_threadlocal; 109 pthread_key_t db_conn_threadlocal;
110 110
@@ -168,19 +168,15 @@ postgres_drop_tables (void *cls)
168 GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS denominations CASCADE;"), 168 GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS denominations CASCADE;"),
169 GNUNET_PQ_EXECUTE_STATEMENT_END 169 GNUNET_PQ_EXECUTE_STATEMENT_END
170 }; 170 };
171 PGconn *conn; 171 struct GNUNET_PQ_Context *conn;
172 int ret;
173 172
174 /* FIXME: use GNUNET_PQ_connect_with_cfg instead? */ 173 conn = GNUNET_PQ_connect (pc->connection_cfg_str,
175 conn = GNUNET_PQ_connect (pc->connection_cfg_str); 174 es,
175 NULL);
176 if (NULL == conn) 176 if (NULL == conn)
177 return GNUNET_SYSERR; 177 return GNUNET_SYSERR;
178 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 178 GNUNET_PQ_disconnect (conn);
179 "Dropping ALL tables\n"); 179 return GNUNET_OK;
180 ret = GNUNET_PQ_exec_statements (conn,
181 es);
182 PQfinish (conn);
183 return ret;
184} 180}
185 181
186 182
@@ -207,8 +203,8 @@ postgres_create_tables (void *cls)
207 ",expire_withdraw INT8 NOT NULL" 203 ",expire_withdraw INT8 NOT NULL"
208 ",expire_deposit INT8 NOT NULL" 204 ",expire_deposit INT8 NOT NULL"
209 ",expire_legal INT8 NOT NULL" 205 ",expire_legal INT8 NOT NULL"
210 ",coin_val INT8 NOT NULL" /* value of this denom */ 206 ",coin_val INT8 NOT NULL" /* value of this denom */
211 ",coin_frac INT4 NOT NULL" /* fractional value of this denom */ 207 ",coin_frac INT4 NOT NULL" /* fractional value of this denom */
212 ",fee_withdraw_val INT8 NOT NULL" 208 ",fee_withdraw_val INT8 NOT NULL"
213 ",fee_withdraw_frac INT4 NOT NULL" 209 ",fee_withdraw_frac INT4 NOT NULL"
214 ",fee_deposit_val INT8 NOT NULL" 210 ",fee_deposit_val INT8 NOT NULL"
@@ -300,7 +296,7 @@ postgres_create_tables (void *cls)
300 GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS reserves_out" 296 GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS reserves_out"
301 "(reserve_out_serial_id BIGSERIAL UNIQUE" 297 "(reserve_out_serial_id BIGSERIAL UNIQUE"
302 ",h_blind_ev BYTEA PRIMARY KEY CHECK (LENGTH(h_blind_ev)=64)" 298 ",h_blind_ev BYTEA PRIMARY KEY CHECK (LENGTH(h_blind_ev)=64)"
303 ",denom_pub_hash BYTEA NOT NULL REFERENCES denominations (denom_pub_hash)" /* do NOT CASCADE on DELETE, we may keep the denomination key alive! */ 299 ",denom_pub_hash BYTEA NOT NULL REFERENCES denominations (denom_pub_hash)" /* do NOT CASCADE on DELETE, we may keep the denomination key alive! */
304 ",denom_sig BYTEA NOT NULL" 300 ",denom_sig BYTEA NOT NULL"
305 ",reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE" 301 ",reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE"
306 ",reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)" 302 ",reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)"
@@ -419,7 +415,7 @@ postgres_create_tables (void *cls)
419 ",rtransaction_id INT8 NOT NULL" 415 ",rtransaction_id INT8 NOT NULL"
420 ",amount_with_fee_val INT8 NOT NULL" 416 ",amount_with_fee_val INT8 NOT NULL"
421 ",amount_with_fee_frac INT4 NOT NULL" 417 ",amount_with_fee_frac INT4 NOT NULL"
422 ",PRIMARY KEY (coin_pub, merchant_pub, h_contract_terms, rtransaction_id)" /* this combo must be unique, and we usually select by coin_pub */ 418 ",PRIMARY KEY (coin_pub, merchant_pub, h_contract_terms, rtransaction_id)" /* this combo must be unique, and we usually select by coin_pub */
423 ");"), 419 ");"),
424 GNUNET_PQ_make_try_execute ("CREATE INDEX refunds_coin_pub_index " 420 GNUNET_PQ_make_try_execute ("CREATE INDEX refunds_coin_pub_index "
425 "ON refunds(coin_pub)"), 421 "ON refunds(coin_pub)"),
@@ -455,7 +451,7 @@ postgres_create_tables (void *cls)
455 ",closing_fee_val INT8 NOT NULL" 451 ",closing_fee_val INT8 NOT NULL"
456 ",closing_fee_frac INT4 NOT NULL" 452 ",closing_fee_frac INT4 NOT NULL"
457 ",master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)" 453 ",master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)"
458 ",PRIMARY KEY (wire_method, start_date)" /* this combo must be unique */ 454 ",PRIMARY KEY (wire_method, start_date)" /* this combo must be unique */
459 ");"), 455 ");"),
460 /* Index for lookup_transactions statement on wtid */ 456 /* Index for lookup_transactions statement on wtid */
461 GNUNET_PQ_make_try_execute ("CREATE INDEX aggregation_tracking_wtid_index " 457 GNUNET_PQ_make_try_execute ("CREATE INDEX aggregation_tracking_wtid_index "
@@ -466,7 +462,7 @@ postgres_create_tables (void *cls)
466 /* Table for /payback information */ 462 /* Table for /payback information */
467 GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS payback " 463 GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS payback "
468 "(payback_uuid BIGSERIAL UNIQUE" 464 "(payback_uuid BIGSERIAL UNIQUE"
469 ",coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)" /* do NOT CASCADE on delete, we may keep the coin alive! */ 465 ",coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)" /* do NOT CASCADE on delete, we may keep the coin alive! */
470 ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)" 466 ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)"
471 ",coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)" 467 ",coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)"
472 ",amount_val INT8 NOT NULL" 468 ",amount_val INT8 NOT NULL"
@@ -486,7 +482,7 @@ postgres_create_tables (void *cls)
486 /* Table for /payback-refresh information */ 482 /* Table for /payback-refresh information */
487 GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS payback_refresh " 483 GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS payback_refresh "
488 "(payback_refresh_uuid BIGSERIAL UNIQUE" 484 "(payback_refresh_uuid BIGSERIAL UNIQUE"
489 ",coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)" /* do NOT CASCADE on delete, we may keep the coin alive! */ 485 ",coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)" /* do NOT CASCADE on delete, we may keep the coin alive! */
490 ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)" 486 ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)"
491 ",coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)" 487 ",coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)"
492 ",amount_val INT8 NOT NULL" 488 ",amount_val INT8 NOT NULL"
@@ -518,1168 +514,15 @@ postgres_create_tables (void *cls)
518 "ON prewire(finished);"), 514 "ON prewire(finished);"),
519 GNUNET_PQ_EXECUTE_STATEMENT_END 515 GNUNET_PQ_EXECUTE_STATEMENT_END
520 }; 516 };
521 PGconn *conn; 517 struct GNUNET_PQ_Context *conn;
522 int ret;
523 518
524 /* FIXME: use GNUNET_PQ_connect_with_cfg instead? */ 519 conn = GNUNET_PQ_connect (pc->connection_cfg_str,
525 conn = GNUNET_PQ_connect (pc->connection_cfg_str); 520 es,
521 NULL);
526 if (NULL == conn) 522 if (NULL == conn)
527 return GNUNET_SYSERR; 523 return GNUNET_SYSERR;
528 ret = GNUNET_PQ_exec_statements (conn, 524 GNUNET_PQ_disconnect (conn);
529 es); 525 return GNUNET_OK;
530 PQfinish (conn);
531 return ret;
532}
533
534
535/**
536 * Setup prepared statements.
537 *
538 * @param db_conn connection handle to initialize
539 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
540 */
541static int
542postgres_prepare (PGconn *db_conn)
543{
544 struct GNUNET_PQ_PreparedStatement ps[] = {
545 /* Used in #postgres_insert_denomination_info() */
546 GNUNET_PQ_make_prepare ("denomination_insert",
547 "INSERT INTO denominations "
548 "(denom_pub_hash"
549 ",denom_pub"
550 ",master_pub"
551 ",master_sig"
552 ",valid_from"
553 ",expire_withdraw"
554 ",expire_deposit"
555 ",expire_legal"
556 ",coin_val" /* value of this denom */
557 ",coin_frac" /* fractional value of this denom */
558 ",fee_withdraw_val"
559 ",fee_withdraw_frac"
560 ",fee_deposit_val"
561 ",fee_deposit_frac"
562 ",fee_refresh_val"
563 ",fee_refresh_frac"
564 ",fee_refund_val"
565 ",fee_refund_frac"
566 ") VALUES "
567 "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
568 " $11, $12, $13, $14, $15, $16, $17, $18);",
569 18),
570 /* Used in #postgres_iterate_denomination_info() */
571 GNUNET_PQ_make_prepare ("denomination_iterate",
572 "SELECT"
573 " master_pub"
574 ",master_sig"
575 ",valid_from"
576 ",expire_withdraw"
577 ",expire_deposit"
578 ",expire_legal"
579 ",coin_val" /* value of this denom */
580 ",coin_frac" /* fractional value of this denom */
581 ",fee_withdraw_val"
582 ",fee_withdraw_frac"
583 ",fee_deposit_val"
584 ",fee_deposit_frac"
585 ",fee_refresh_val"
586 ",fee_refresh_frac"
587 ",fee_refund_val"
588 ",fee_refund_frac"
589 ",denom_pub"
590 " FROM denominations;",
591 0),
592 /* Used in #postgres_get_denomination_info() */
593 GNUNET_PQ_make_prepare ("denomination_get",
594 "SELECT"
595 " master_pub"
596 ",master_sig"
597 ",valid_from"
598 ",expire_withdraw"
599 ",expire_deposit"
600 ",expire_legal"
601 ",coin_val" /* value of this denom */
602 ",coin_frac" /* fractional value of this denom */
603 ",fee_withdraw_val"
604 ",fee_withdraw_frac"
605 ",fee_deposit_val"
606 ",fee_deposit_frac"
607 ",fee_refresh_val"
608 ",fee_refresh_frac"
609 ",fee_refund_val"
610 ",fee_refund_frac"
611 " FROM denominations"
612 " WHERE denom_pub_hash=$1;",
613 1),
614 /* Used in #postgres_insert_denomination_revocation() */
615 GNUNET_PQ_make_prepare ("denomination_revocation_insert",
616 "INSERT INTO denomination_revocations "
617 "(denom_pub_hash"
618 ",master_sig"
619 ") VALUES "
620 "($1, $2);",
621 2),
622 /* Used in #postgres_get_denomination_revocation() */
623 GNUNET_PQ_make_prepare ("denomination_revocation_get",
624 "SELECT"
625 " master_sig"
626 ",denom_revocations_serial_id"
627 " FROM denomination_revocations"
628 " WHERE denom_pub_hash=$1;",
629 1),
630 /* Used in #postgres_reserve_get() */
631 GNUNET_PQ_make_prepare ("reserve_get",
632 "SELECT"
633 " current_balance_val"
634 ",current_balance_frac"
635 ",expiration_date"
636 ",gc_date"
637 " FROM reserves"
638 " WHERE reserve_pub=$1"
639 " LIMIT 1"
640 " FOR UPDATE;",
641 1),
642 /* Used in #postgres_reserves_in_insert() when the reserve is new */
643 GNUNET_PQ_make_prepare ("reserve_create",
644 "INSERT INTO reserves "
645 "(reserve_pub"
646 ",account_details"
647 ",current_balance_val"
648 ",current_balance_frac"
649 ",expiration_date"
650 ",gc_date"
651 ") VALUES "
652 "($1, $2, $3, $4, $5, $6);",
653 6),
654 /* Used in #postgres_insert_reserve_closed() */
655 GNUNET_PQ_make_prepare ("reserves_close_insert",
656 "INSERT INTO reserves_close "
657 "(reserve_pub"
658 ",execution_date"
659 ",wtid"
660 ",receiver_account"
661 ",amount_val"
662 ",amount_frac"
663 ",closing_fee_val"
664 ",closing_fee_frac"
665 ") VALUES "
666 "($1, $2, $3, $4, $5, $6, $7, $8);",
667 8),
668 /* Used in #reserves_update() when the reserve is updated */
669 GNUNET_PQ_make_prepare ("reserve_update",
670 "UPDATE reserves"
671 " SET"
672 " expiration_date=$1"
673 ",gc_date=$2"
674 ",current_balance_val=$3"
675 ",current_balance_frac=$4"
676 " WHERE"
677 " reserve_pub=$5;",
678 5),
679 /* Used in #postgres_reserves_in_insert() to store transaction details */
680 GNUNET_PQ_make_prepare ("reserves_in_add_transaction",
681 "INSERT INTO reserves_in "
682 "(reserve_pub"
683 ",wire_reference"
684 ",credit_val"
685 ",credit_frac"
686 ",exchange_account_section"
687 ",sender_account_details"
688 ",execution_date"
689 ") VALUES "
690 "($1, $2, $3, $4, $5, $6, $7) "
691 "ON CONFLICT DO NOTHING;",
692 7),
693 /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
694 transactions for reserves with serial id '\geq' the given parameter */
695 GNUNET_PQ_make_prepare ("reserves_in_get_latest_wire_reference",
696 "SELECT"
697 " wire_reference"
698 " FROM reserves_in"
699 " WHERE exchange_account_section=$1"
700 " ORDER BY reserve_in_serial_id DESC"
701 " LIMIT 1;",
702 1),
703 /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
704 transactions for reserves with serial id '\geq' the given parameter */
705 GNUNET_PQ_make_prepare ("audit_reserves_in_get_transactions_incr",
706 "SELECT"
707 " reserve_pub"
708 ",wire_reference"
709 ",credit_val"
710 ",credit_frac"
711 ",execution_date"
712 ",sender_account_details"
713 ",reserve_in_serial_id"
714 " FROM reserves_in"
715 " WHERE reserve_in_serial_id>=$1"
716 " ORDER BY reserve_in_serial_id;",
717 1),
718 /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
719 transactions for reserves with serial id '\geq' the given parameter */
720 GNUNET_PQ_make_prepare (
721 "audit_reserves_in_get_transactions_incr_by_account",
722 "SELECT"
723 " reserve_pub"
724 ",wire_reference"
725 ",credit_val"
726 ",credit_frac"
727 ",execution_date"
728 ",sender_account_details"
729 ",reserve_in_serial_id"
730 " FROM reserves_in"
731 " WHERE reserve_in_serial_id>=$1 AND exchange_account_section=$2"
732 " ORDER BY reserve_in_serial_id;",
733 2),
734 /* Used in #postgres_get_reserve_history() to obtain inbound transactions
735 for a reserve */
736 GNUNET_PQ_make_prepare ("reserves_in_get_transactions",
737 "SELECT"
738 " wire_reference"
739 ",credit_val"
740 ",credit_frac"
741 ",execution_date"
742 ",sender_account_details"
743 " FROM reserves_in"
744 " WHERE reserve_pub=$1"
745 " FOR UPDATE;",
746 1),
747 /* Lock withdraw table; NOTE: we may want to eventually shard the
748 deposit table to avoid this lock being the main point of
749 contention limiting transaction performance. */
750 GNUNET_PQ_make_prepare ("lock_withdraw",
751 "LOCK TABLE reserves_out;",
752 0),
753 /* Used in #postgres_insert_withdraw_info() to store
754 the signature of a blinded coin with the blinded coin's
755 details before returning it during /reserve/withdraw. We store
756 the coin's denomination information (public key, signature)
757 and the blinded message as well as the reserve that the coin
758 is being withdrawn from and the signature of the message
759 authorizing the withdrawal. */
760 GNUNET_PQ_make_prepare ("insert_withdraw_info",
761 "INSERT INTO reserves_out "
762 "(h_blind_ev"
763 ",denom_pub_hash"
764 ",denom_sig"
765 ",reserve_pub"
766 ",reserve_sig"
767 ",execution_date"
768 ",amount_with_fee_val"
769 ",amount_with_fee_frac"
770 ") VALUES "
771 "($1, $2, $3, $4, $5, $6, $7, $8);",
772 8),
773 /* Used in #postgres_get_withdraw_info() to
774 locate the response for a /reserve/withdraw request
775 using the hash of the blinded message. Used to
776 make sure /reserve/withdraw requests are idempotent. */
777 GNUNET_PQ_make_prepare ("get_withdraw_info",
778 "SELECT"
779 " denom_pub_hash"
780 ",denom_sig"
781 ",reserve_sig"
782 ",reserve_pub"
783 ",execution_date"
784 ",amount_with_fee_val"
785 ",amount_with_fee_frac"
786 ",denom.fee_withdraw_val"
787 ",denom.fee_withdraw_frac"
788 " FROM reserves_out"
789 " JOIN denominations denom"
790 " USING (denom_pub_hash)"
791 " WHERE h_blind_ev=$1"
792 " FOR UPDATE;",
793 1),
794 /* Used during #postgres_get_reserve_history() to
795 obtain all of the /reserve/withdraw operations that
796 have been performed on a given reserve. (i.e. to
797 demonstrate double-spending) */
798 GNUNET_PQ_make_prepare ("get_reserves_out",
799 "SELECT"
800 " h_blind_ev"
801 ",denom_pub_hash"
802 ",denom_sig"
803 ",reserve_sig"
804 ",execution_date"
805 ",amount_with_fee_val"
806 ",amount_with_fee_frac"
807 ",denom.fee_withdraw_val"
808 ",denom.fee_withdraw_frac"
809 " FROM reserves_out"
810 " JOIN denominations denom"
811 " USING (denom_pub_hash)"
812 " WHERE reserve_pub=$1"
813 " FOR UPDATE",
814 1),
815 /* Used in #postgres_select_reserves_out_above_serial_id() */
816 GNUNET_PQ_make_prepare ("audit_get_reserves_out_incr",
817 "SELECT"
818 " h_blind_ev"
819 ",denom.denom_pub"
820 ",denom_sig"
821 ",reserve_sig"
822 ",reserve_pub"
823 ",execution_date"
824 ",amount_with_fee_val"
825 ",amount_with_fee_frac"
826 ",reserve_out_serial_id"
827 " FROM reserves_out"
828 " JOIN denominations denom"
829 " USING (denom_pub_hash)"
830 " WHERE reserve_out_serial_id>=$1"
831 " ORDER BY reserve_out_serial_id ASC;",
832 1),
833
834 /* Used in #postgres_count_known_coins() */
835 GNUNET_PQ_make_prepare ("count_known_coins",
836 "SELECT"
837 " COUNT(*) AS count"
838 " FROM known_coins"
839 " WHERE denom_pub_hash=$1;",
840 1),
841 /* Used in #postgres_get_known_coin() to fetch
842 the denomination public key and signature for
843 a coin known to the exchange. */
844 GNUNET_PQ_make_prepare ("get_known_coin",
845 "SELECT"
846 " denom_pub_hash"
847 ",denom_sig"
848 " FROM known_coins"
849 " WHERE coin_pub=$1"
850 " FOR UPDATE;",
851 1),
852 /* Lock deposit table; NOTE: we may want to eventually shard the
853 deposit table to avoid this lock being the main point of
854 contention limiting transaction performance. */
855 GNUNET_PQ_make_prepare ("lock_known_coins",
856 "LOCK TABLE known_coins;",
857 0),
858 /* Used in #postgres_insert_known_coin() to store
859 the denomination public key and signature for
860 a coin known to the exchange. */
861 GNUNET_PQ_make_prepare ("insert_known_coin",
862 "INSERT INTO known_coins "
863 "(coin_pub"
864 ",denom_pub_hash"
865 ",denom_sig"
866 ") VALUES "
867 "($1,$2,$3);",
868 3),
869
870 /* Used in #postgres_insert_melt() to store
871 high-level information about a melt operation */
872 GNUNET_PQ_make_prepare ("insert_melt",
873 "INSERT INTO refresh_commitments "
874 "(rc "
875 ",old_coin_pub "
876 ",old_coin_sig "
877 ",amount_with_fee_val "
878 ",amount_with_fee_frac "
879 ",noreveal_index "
880 ") VALUES "
881 "($1, $2, $3, $4, $5, $6);",
882 6),
883 /* Used in #postgres_get_melt() to fetch
884 high-level information about a melt operation */
885 GNUNET_PQ_make_prepare ("get_melt",
886 "SELECT"
887 " kc.denom_pub_hash"
888 ",denom.fee_refresh_val"
889 ",denom.fee_refresh_frac"
890 ",old_coin_pub"
891 ",old_coin_sig"
892 ",amount_with_fee_val"
893 ",amount_with_fee_frac"
894 ",noreveal_index"
895 " FROM refresh_commitments"
896 " JOIN known_coins kc"
897 " ON (refresh_commitments.old_coin_pub = kc.coin_pub)"
898 " JOIN denominations denom"
899 " ON (kc.denom_pub_hash = denom.denom_pub_hash)"
900 " WHERE rc=$1;",
901 1),
902 /* Used in #postgres_get_melt_index() to fetch
903 the noreveal index from a previous melt operation */
904 GNUNET_PQ_make_prepare ("get_melt_index",
905 "SELECT"
906 " noreveal_index"
907 " FROM refresh_commitments"
908 " WHERE rc=$1;",
909 1),
910 /* Used in #postgres_select_refreshs_above_serial_id() to fetch
911 refresh session with id '\geq' the given parameter */
912 GNUNET_PQ_make_prepare ("audit_get_refresh_commitments_incr",
913 "SELECT"
914 " denom.denom_pub"
915 ",old_coin_pub"
916 ",old_coin_sig"
917 ",amount_with_fee_val"
918 ",amount_with_fee_frac"
919 ",noreveal_index"
920 ",melt_serial_id"
921 ",rc"
922 " FROM refresh_commitments"
923 " JOIN known_coins kc"
924 " ON (refresh_commitments.old_coin_pub = kc.coin_pub)"
925 " JOIN denominations denom"
926 " ON (kc.denom_pub_hash = denom.denom_pub_hash)"
927 " WHERE melt_serial_id>=$1"
928 " ORDER BY melt_serial_id ASC;",
929 1),
930 /* Query the 'refresh_commitments' by coin public key */
931 GNUNET_PQ_make_prepare ("get_refresh_session_by_coin",
932 "SELECT"
933 " rc"
934 ",old_coin_sig"
935 ",amount_with_fee_val"
936 ",amount_with_fee_frac"
937 ",denom.fee_refresh_val "
938 ",denom.fee_refresh_frac "
939 ",melt_serial_id"
940 " FROM refresh_commitments"
941 " JOIN known_coins "
942 " ON (refresh_commitments.old_coin_pub = known_coins.coin_pub)"
943 " JOIN denominations denom USING (denom_pub_hash)"
944 " WHERE old_coin_pub=$1;",
945 1),
946
947 /* Store information about the desired denominations for a
948 refresh operation, used in #postgres_insert_refresh_reveal() */
949 GNUNET_PQ_make_prepare ("insert_refresh_revealed_coin",
950 "INSERT INTO refresh_revealed_coins "
951 "(rc "
952 ",newcoin_index "
953 ",link_sig "
954 ",denom_pub_hash "
955 ",coin_ev"
956 ",h_coin_ev"
957 ",ev_sig"
958 ") VALUES "
959 "($1, $2, $3, $4, $5, $6, $7);",
960 7),
961 /* Obtain information about the coins created in a refresh
962 operation, used in #postgres_get_refresh_reveal() */
963 GNUNET_PQ_make_prepare ("get_refresh_revealed_coins",
964 "SELECT "
965 " newcoin_index"
966 ",denom.denom_pub"
967 ",link_sig"
968 ",coin_ev"
969 ",ev_sig"
970 " FROM refresh_revealed_coins"
971 " JOIN denominations denom "
972 " USING (denom_pub_hash)"
973 " WHERE rc=$1"
974 " ORDER BY newcoin_index ASC"
975 " FOR UPDATE;",
976 1),
977
978 /* Used in #postgres_insert_refresh_reveal() to store the transfer
979 keys we learned */
980 GNUNET_PQ_make_prepare ("insert_refresh_transfer_keys",
981 "INSERT INTO refresh_transfer_keys "
982 "(rc"
983 ",transfer_pub"
984 ",transfer_privs"
985 ") VALUES "
986 "($1, $2, $3);",
987 3),
988 /* Used in #postgres_get_refresh_reveal() to retrieve transfer
989 keys from /refresh/reveal */
990 GNUNET_PQ_make_prepare ("get_refresh_transfer_keys",
991 "SELECT"
992 " transfer_pub"
993 ",transfer_privs"
994 " FROM refresh_transfer_keys"
995 " WHERE rc=$1;",
996 1),
997
998
999 /* Used in #postgres_insert_refund() to store refund information */
1000 GNUNET_PQ_make_prepare ("insert_refund",
1001 "INSERT INTO refunds "
1002 "(coin_pub "
1003 ",merchant_pub "
1004 ",merchant_sig "
1005 ",h_contract_terms "
1006 ",rtransaction_id "
1007 ",amount_with_fee_val "
1008 ",amount_with_fee_frac "
1009 ") VALUES "
1010 "($1, $2, $3, $4, $5, $6, $7);",
1011 7),
1012 /* Query the 'refunds' by coin public key */
1013 GNUNET_PQ_make_prepare ("get_refunds_by_coin",
1014 "SELECT"
1015 " merchant_pub"
1016 ",merchant_sig"
1017 ",h_contract_terms"
1018 ",rtransaction_id"
1019 ",amount_with_fee_val"
1020 ",amount_with_fee_frac"
1021 ",denom.fee_refund_val "
1022 ",denom.fee_refund_frac "
1023 ",refund_serial_id"
1024 " FROM refunds"
1025 " JOIN known_coins USING (coin_pub)"
1026 " JOIN denominations denom USING (denom_pub_hash)"
1027 " WHERE coin_pub=$1;",
1028 1),
1029 /* Fetch refunds with rowid '\geq' the given parameter */
1030 GNUNET_PQ_make_prepare ("audit_get_refunds_incr",
1031 "SELECT"
1032 " merchant_pub"
1033 ",merchant_sig"
1034 ",h_contract_terms"
1035 ",rtransaction_id"
1036 ",denom.denom_pub"
1037 ",coin_pub"
1038 ",amount_with_fee_val"
1039 ",amount_with_fee_frac"
1040 ",refund_serial_id"
1041 " FROM refunds"
1042 " JOIN known_coins kc USING (coin_pub)"
1043 " JOIN denominations denom ON (kc.denom_pub_hash = denom.denom_pub_hash)"
1044 " WHERE refund_serial_id>=$1"
1045 " ORDER BY refund_serial_id ASC;",
1046 1),
1047 /* Lock deposit table; NOTE: we may want to eventually shard the
1048 deposit table to avoid this lock being the main point of
1049 contention limiting transaction performance. */
1050 GNUNET_PQ_make_prepare ("lock_deposit",
1051 "LOCK TABLE deposits;",
1052 0),
1053 /* Store information about a /deposit the exchange is to execute.
1054 Used in #postgres_insert_deposit(). */
1055 GNUNET_PQ_make_prepare ("insert_deposit",
1056 "INSERT INTO deposits "
1057 "(coin_pub"
1058 ",amount_with_fee_val"
1059 ",amount_with_fee_frac"
1060 ",timestamp"
1061 ",refund_deadline"
1062 ",wire_deadline"
1063 ",merchant_pub"
1064 ",h_contract_terms"
1065 ",h_wire"
1066 ",coin_sig"
1067 ",wire"
1068 ") VALUES "
1069 "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
1070 " $11);",
1071 11),
1072 /* Fetch an existing deposit request, used to ensure idempotency
1073 during /deposit processing. Used in #postgres_have_deposit(). */
1074 GNUNET_PQ_make_prepare ("get_deposit",
1075 "SELECT"
1076 " amount_with_fee_val"
1077 ",amount_with_fee_frac"
1078 ",timestamp"
1079 ",refund_deadline"
1080 ",wire_deadline"
1081 ",h_contract_terms"
1082 ",h_wire"
1083 " FROM deposits"
1084 " WHERE ((coin_pub=$1)"
1085 " AND (merchant_pub=$3)"
1086 " AND (h_contract_terms=$2))"
1087 " FOR UPDATE;",
1088 3),
1089 /* Fetch deposits with rowid '\geq' the given parameter */
1090 GNUNET_PQ_make_prepare ("audit_get_deposits_incr",
1091 "SELECT"
1092 " amount_with_fee_val"
1093 ",amount_with_fee_frac"
1094 ",timestamp"
1095 ",merchant_pub"
1096 ",denom.denom_pub"
1097 ",coin_pub"
1098 ",coin_sig"
1099 ",refund_deadline"
1100 ",wire_deadline"
1101 ",h_contract_terms"
1102 ",wire"
1103 ",done"
1104 ",deposit_serial_id"
1105 " FROM deposits"
1106 " JOIN known_coins USING (coin_pub)"
1107 " JOIN denominations denom USING (denom_pub_hash)"
1108 " WHERE ("
1109 " (deposit_serial_id>=$1)"
1110 " )"
1111 " ORDER BY deposit_serial_id ASC;",
1112 1),
1113 /* Fetch an existing deposit request.
1114 Used in #postgres_wire_lookup_deposit_wtid(). */
1115 GNUNET_PQ_make_prepare ("get_deposit_for_wtid",
1116 "SELECT"
1117 " amount_with_fee_val"
1118 ",amount_with_fee_frac"
1119 ",denom.fee_deposit_val"
1120 ",denom.fee_deposit_frac"
1121 ",wire_deadline"
1122 " FROM deposits"
1123 " JOIN known_coins USING (coin_pub)"
1124 " JOIN denominations denom USING (denom_pub_hash)"
1125 " WHERE ("
1126 " (coin_pub=$1)"
1127 " AND (merchant_pub=$2)"
1128 " AND (h_contract_terms=$3)"
1129 " AND (h_wire=$4)"
1130 " );",
1131 4),
1132 /* Used in #postgres_get_ready_deposit() */
1133 GNUNET_PQ_make_prepare ("deposits_get_ready",
1134 "SELECT"
1135 " deposit_serial_id"
1136 ",amount_with_fee_val"
1137 ",amount_with_fee_frac"
1138 ",denom.fee_deposit_val"
1139 ",denom.fee_deposit_frac"
1140 ",wire_deadline"
1141 ",h_contract_terms"
1142 ",wire"
1143 ",merchant_pub"
1144 ",coin_pub"
1145 " FROM deposits"
1146 " JOIN known_coins USING (coin_pub)"
1147 " JOIN denominations denom USING (denom_pub_hash)"
1148 " WHERE tiny=FALSE"
1149 " AND done=FALSE"
1150 " AND wire_deadline<=$1"
1151 " AND refund_deadline<$1"
1152 " ORDER BY wire_deadline ASC"
1153 " LIMIT 1;",
1154 1),
1155 /* Used in #postgres_iterate_matching_deposits() */
1156 GNUNET_PQ_make_prepare ("deposits_iterate_matching",
1157 "SELECT"
1158 " deposit_serial_id"
1159 ",amount_with_fee_val"
1160 ",amount_with_fee_frac"
1161 ",denom.fee_deposit_val"
1162 ",denom.fee_deposit_frac"
1163 ",wire_deadline"
1164 ",h_contract_terms"
1165 ",coin_pub"
1166 " FROM deposits"
1167 " JOIN known_coins"
1168 " USING (coin_pub)"
1169 " JOIN denominations denom"
1170 " USING (denom_pub_hash)"
1171 " WHERE"
1172 " merchant_pub=$1 AND"
1173 " h_wire=$2 AND"
1174 " done=FALSE"
1175 " ORDER BY wire_deadline ASC"
1176 " LIMIT "
1177 TALER_EXCHANGEDB_MATCHING_DEPOSITS_LIMIT_STR ";",
1178 2),
1179 /* Used in #postgres_mark_deposit_tiny() */
1180 GNUNET_PQ_make_prepare ("mark_deposit_tiny",
1181 "UPDATE deposits"
1182 " SET tiny=TRUE"
1183 " WHERE deposit_serial_id=$1",
1184 1),
1185 /* Used in #postgres_mark_deposit_done() */
1186 GNUNET_PQ_make_prepare ("mark_deposit_done",
1187 "UPDATE deposits"
1188 " SET done=TRUE"
1189 " WHERE deposit_serial_id=$1;",
1190 1),
1191 /* Used in #postgres_test_deposit_done() */
1192 GNUNET_PQ_make_prepare ("test_deposit_done",
1193 "SELECT done"
1194 " FROM deposits"
1195 " WHERE coin_pub=$1"
1196 " AND merchant_pub=$2"
1197 " AND h_contract_terms=$3"
1198 " AND h_wire=$4;",
1199 5),
1200 /* Used in #postgres_get_coin_transactions() to obtain information
1201 about how a coin has been spend with /deposit requests. */
1202 GNUNET_PQ_make_prepare ("get_deposit_with_coin_pub",
1203 "SELECT"
1204 " amount_with_fee_val"
1205 ",amount_with_fee_frac"
1206 ",denom.fee_deposit_val"
1207 ",denom.fee_deposit_frac"
1208 ",timestamp"
1209 ",refund_deadline"
1210 ",wire_deadline"
1211 ",merchant_pub"
1212 ",h_contract_terms"
1213 ",h_wire"
1214 ",wire"
1215 ",coin_sig"
1216 ",deposit_serial_id"
1217 " FROM deposits"
1218 " JOIN known_coins"
1219 " USING (coin_pub)"
1220 " JOIN denominations denom"
1221 " USING (denom_pub_hash)"
1222 " WHERE coin_pub=$1"
1223 " FOR UPDATE;",
1224 1),
1225
1226 /* Used in #postgres_get_link_data(). */
1227 GNUNET_PQ_make_prepare ("get_link",
1228 "SELECT "
1229 " tp.transfer_pub"
1230 ",denoms.denom_pub"
1231 ",rrc.ev_sig"
1232 ",rrc.link_sig"
1233 " FROM refresh_commitments"
1234 " JOIN refresh_revealed_coins rrc"
1235 " USING (rc)"
1236 " JOIN refresh_transfer_keys tp"
1237 " USING (rc)"
1238 " JOIN denominations denoms"
1239 " ON (rrc.denom_pub_hash = denoms.denom_pub_hash)"
1240 " WHERE old_coin_pub=$1"
1241 " ORDER BY tp.transfer_pub",
1242 1),
1243 /* Used in #postgres_lookup_wire_transfer */
1244 GNUNET_PQ_make_prepare ("lookup_transactions",
1245 "SELECT"
1246 " aggregation_serial_id"
1247 ",deposits.h_contract_terms"
1248 ",deposits.wire"
1249 ",deposits.h_wire"
1250 ",deposits.coin_pub"
1251 ",deposits.merchant_pub"
1252 ",wire_out.execution_date"
1253 ",deposits.amount_with_fee_val"
1254 ",deposits.amount_with_fee_frac"
1255 ",denom.fee_deposit_val"
1256 ",denom.fee_deposit_frac"
1257 ",denom.denom_pub"
1258 " FROM aggregation_tracking"
1259 " JOIN deposits"
1260 " USING (deposit_serial_id)"
1261 " JOIN known_coins"
1262 " USING (coin_pub)"
1263 " JOIN denominations denom"
1264 " USING (denom_pub_hash)"
1265 " JOIN wire_out"
1266 " USING (wtid_raw)"
1267 " WHERE wtid_raw=$1;",
1268 1),
1269 /* Used in #postgres_wire_lookup_deposit_wtid */
1270 GNUNET_PQ_make_prepare ("lookup_deposit_wtid",
1271 "SELECT"
1272 " aggregation_tracking.wtid_raw"
1273 ",wire_out.execution_date"
1274 ",amount_with_fee_val"
1275 ",amount_with_fee_frac"
1276 ",denom.fee_deposit_val"
1277 ",denom.fee_deposit_frac"
1278 " FROM deposits"
1279 " JOIN aggregation_tracking"
1280 " USING (deposit_serial_id)"
1281 " JOIN known_coins"
1282 " USING (coin_pub)"
1283 " JOIN denominations denom"
1284 " USING (denom_pub_hash)"
1285 " JOIN wire_out"
1286 " USING (wtid_raw)"
1287 " WHERE coin_pub=$1"
1288 " AND h_contract_terms=$2"
1289 " AND h_wire=$3"
1290 " AND merchant_pub=$4;",
1291 4),
1292 /* Used in #postgres_insert_aggregation_tracking */
1293 GNUNET_PQ_make_prepare ("insert_aggregation_tracking",
1294 "INSERT INTO aggregation_tracking "
1295 "(deposit_serial_id"
1296 ",wtid_raw"
1297 ") VALUES "
1298 "($1, $2);",
1299 2),
1300 /* Used in #postgres_get_wire_fee() */
1301 GNUNET_PQ_make_prepare ("get_wire_fee",
1302 "SELECT "
1303 " start_date"
1304 ",end_date"
1305 ",wire_fee_val"
1306 ",wire_fee_frac"
1307 ",closing_fee_val"
1308 ",closing_fee_frac"
1309 ",master_sig"
1310 " FROM wire_fee"
1311 " WHERE wire_method=$1"
1312 " AND start_date <= $2"
1313 " AND end_date > $2;",
1314 2),
1315 /* Used in #postgres_insert_wire_fee */
1316 GNUNET_PQ_make_prepare ("insert_wire_fee",
1317 "INSERT INTO wire_fee "
1318 "(wire_method"
1319 ",start_date"
1320 ",end_date"
1321 ",wire_fee_val"
1322 ",wire_fee_frac"
1323 ",closing_fee_val"
1324 ",closing_fee_frac"
1325 ",master_sig"
1326 ") VALUES "
1327 "($1, $2, $3, $4, $5, $6, $7, $8);",
1328 8),
1329 /* Used in #postgres_store_wire_transfer_out */
1330 GNUNET_PQ_make_prepare ("insert_wire_out",
1331 "INSERT INTO wire_out "
1332 "(execution_date"
1333 ",wtid_raw"
1334 ",wire_target"
1335 ",exchange_account_section"
1336 ",amount_val"
1337 ",amount_frac"
1338 ") VALUES "
1339 "($1, $2, $3, $4, $5, $6);",
1340 6),
1341 /* Used in #postgres_wire_prepare_data_insert() to store
1342 wire transfer information before actually committing it with the bank */
1343 GNUNET_PQ_make_prepare ("wire_prepare_data_insert",
1344 "INSERT INTO prewire "
1345 "(type"
1346 ",buf"
1347 ") VALUES "
1348 "($1, $2);",
1349 2),
1350 /* Used in #postgres_wire_prepare_data_mark_finished() */
1351 GNUNET_PQ_make_prepare ("wire_prepare_data_mark_done",
1352 "UPDATE prewire"
1353 " SET finished=true"
1354 " WHERE prewire_uuid=$1;",
1355 1),
1356 /* Used in #postgres_wire_prepare_data_get() */
1357 GNUNET_PQ_make_prepare ("wire_prepare_data_get",
1358 "SELECT"
1359 " prewire_uuid"
1360 ",type"
1361 ",buf"
1362 " FROM prewire"
1363 " WHERE finished=false"
1364 " ORDER BY prewire_uuid ASC"
1365 " LIMIT 1;",
1366 0),
1367
1368 /* Used in #postgres_select_deposits_missing_wire */
1369 GNUNET_PQ_make_prepare ("deposits_get_overdue",
1370 "SELECT"
1371 " deposit_serial_id"
1372 ",coin_pub"
1373 ",amount_with_fee_val"
1374 ",amount_with_fee_frac"
1375 ",wire"
1376 ",wire_deadline"
1377 ",tiny"
1378 ",done"
1379 " FROM deposits"
1380 " WHERE wire_deadline >= $1"
1381 " AND wire_deadline < $2"
1382 " AND NOT (EXISTS (SELECT 1"
1383 " FROM refunds"
1384 " WHERE (refunds.coin_pub = deposits.coin_pub))"
1385 " OR EXISTS (SELECT 1"
1386 " FROM aggregation_tracking"
1387 " WHERE (aggregation_tracking.deposit_serial_id = deposits.deposit_serial_id)))"
1388 " ORDER BY wire_deadline ASC",
1389 2),
1390 /* Used in #postgres_gc() */
1391 GNUNET_PQ_make_prepare ("gc_prewire",
1392 "DELETE"
1393 " FROM prewire"
1394 " WHERE finished=true;",
1395 0),
1396 /* Used in #postgres_select_wire_out_above_serial_id() */
1397 GNUNET_PQ_make_prepare ("audit_get_wire_incr",
1398 "SELECT"
1399 " wireout_uuid"
1400 ",execution_date"
1401 ",wtid_raw"
1402 ",wire_target"
1403 ",amount_val"
1404 ",amount_frac"
1405 " FROM wire_out"
1406 " WHERE wireout_uuid>=$1"
1407 " ORDER BY wireout_uuid ASC;",
1408 1),
1409 /* Used in #postgres_select_wire_out_above_serial_id_by_account() */
1410 GNUNET_PQ_make_prepare ("audit_get_wire_incr_by_account",
1411 "SELECT"
1412 " wireout_uuid"
1413 ",execution_date"
1414 ",wtid_raw"
1415 ",wire_target"
1416 ",amount_val"
1417 ",amount_frac"
1418 " FROM wire_out"
1419 " WHERE wireout_uuid>=$1 AND exchange_account_section=$2"
1420 " ORDER BY wireout_uuid ASC;",
1421 2),
1422 /* Used in #postgres_insert_payback_request() to store payback
1423 information */
1424 GNUNET_PQ_make_prepare ("payback_insert",
1425 "INSERT INTO payback "
1426 "(coin_pub"
1427 ",coin_sig"
1428 ",coin_blind"
1429 ",amount_val"
1430 ",amount_frac"
1431 ",timestamp"
1432 ",h_blind_ev"
1433 ") VALUES "
1434 "($1, $2, $3, $4, $5, $6, $7);",
1435 7),
1436 /* Used in #postgres_insert_payback_request() to store payback-refresh
1437 information */
1438 GNUNET_PQ_make_prepare ("payback_refresh_insert",
1439 "INSERT INTO payback_refresh "
1440 "(coin_pub"
1441 ",coin_sig"
1442 ",coin_blind"
1443 ",amount_val"
1444 ",amount_frac"
1445 ",timestamp"
1446 ",h_blind_ev"
1447 ") VALUES "
1448 "($1, $2, $3, $4, $5, $6, $7);",
1449 7),
1450 /* Used in #postgres_select_payback_above_serial_id() to obtain payback transactions */
1451 GNUNET_PQ_make_prepare ("payback_get_incr",
1452 "SELECT"
1453 " payback_uuid"
1454 ",timestamp"
1455 ",ro.reserve_pub"
1456 ",coin_pub"
1457 ",coin_sig"
1458 ",coin_blind"
1459 ",h_blind_ev"
1460 ",coins.denom_pub_hash"
1461 ",denoms.denom_pub"
1462 ",coins.denom_sig"
1463 ",amount_val"
1464 ",amount_frac"
1465 " FROM payback"
1466 " JOIN known_coins coins"
1467 " USING (coin_pub)"
1468 " JOIN reserves_out ro"
1469 " USING (h_blind_ev)"
1470 " JOIN denominations denoms"
1471 " ON (coins.denom_pub_hash = denoms.denom_pub_hash)"
1472 " WHERE payback_uuid>=$1"
1473 " ORDER BY payback_uuid ASC;",
1474 1),
1475 /* Used in #postgres_select_payback_refresh_above_serial_id() to obtain
1476 payback-refresh transactions */
1477 GNUNET_PQ_make_prepare ("payback_refresh_get_incr",
1478 "SELECT"
1479 " payback_refresh_uuid"
1480 ",timestamp"
1481 ",rc.old_coin_pub"
1482 ",coin_pub"
1483 ",coin_sig"
1484 ",coin_blind"
1485 ",h_blind_ev"
1486 ",coins.denom_pub_hash"
1487 ",denoms.denom_pub"
1488 ",coins.denom_sig"
1489 ",amount_val"
1490 ",amount_frac"
1491 " FROM payback_refresh"
1492 " JOIN refresh_revealed_coins rrc"
1493 " ON (rrc.coin_ev = h_blind_ev)"
1494 " JOIN refresh_commitments rc"
1495 " ON (rrc.rc = rc.rc)"
1496 " JOIN known_coins coins"
1497 " USING (coin_pub)"
1498 " JOIN denominations denoms"
1499 " ON (coins.denom_pub_hash = denoms.denom_pub_hash)"
1500 " WHERE payback_refresh_uuid>=$1"
1501 " ORDER BY payback_refresh_uuid ASC;",
1502 1),
1503 /* Used in #postgres_select_reserve_closed_above_serial_id() to
1504 obtain information about closed reserves */
1505 GNUNET_PQ_make_prepare ("reserves_close_get_incr",
1506 "SELECT"
1507 " close_uuid"
1508 ",reserve_pub"
1509 ",execution_date"
1510 ",wtid"
1511 ",receiver_account"
1512 ",amount_val"
1513 ",amount_frac"
1514 ",closing_fee_val"
1515 ",closing_fee_frac"
1516 " FROM reserves_close"
1517 " WHERE close_uuid>=$1"
1518 " ORDER BY close_uuid ASC;",
1519 1),
1520 /* Used in #postgres_get_reserve_history() to obtain payback transactions
1521 for a reserve */
1522 GNUNET_PQ_make_prepare ("payback_by_reserve",
1523 "SELECT"
1524 " coin_pub"
1525 ",coin_sig"
1526 ",coin_blind"
1527 ",amount_val"
1528 ",amount_frac"
1529 ",timestamp"
1530 ",coins.denom_pub_hash"
1531 ",coins.denom_sig"
1532 " FROM payback"
1533 " JOIN known_coins coins"
1534 " USING (coin_pub)"
1535 " JOIN reserves_out ro"
1536 " USING (h_blind_ev)"
1537 " WHERE ro.reserve_pub=$1"
1538 " FOR UPDATE;",
1539 1),
1540 /* Used in #postgres_get_coin_transactions() to obtain payback transactions
1541 affecting old coins of refreshed coins */
1542 GNUNET_PQ_make_prepare ("payback_by_old_coin",
1543 "SELECT"
1544 " coin_pub"
1545 ",coin_sig"
1546 ",coin_blind"
1547 ",amount_val"
1548 ",amount_frac"
1549 ",timestamp"
1550 ",coins.denom_pub_hash"
1551 ",coins.denom_sig"
1552 ",payback_refresh_uuid"
1553 " FROM payback_refresh"
1554 " JOIN known_coins coins"
1555 " USING (coin_pub)"
1556 " WHERE h_blind_ev IN"
1557 " (SELECT rrc.h_coin_ev"
1558 " FROM refresh_commitments"
1559 " JOIN refresh_revealed_coins rrc"
1560 " USING (rc)"
1561 " WHERE old_coin_pub=$1)"
1562 " FOR UPDATE;",
1563 1),
1564 /* Used in #postgres_get_reserve_history() */
1565 GNUNET_PQ_make_prepare ("close_by_reserve",
1566 "SELECT"
1567 " amount_val"
1568 ",amount_frac"
1569 ",closing_fee_val"
1570 ",closing_fee_frac"
1571 ",execution_date"
1572 ",receiver_account"
1573 ",wtid"
1574 " FROM reserves_close"
1575 " WHERE reserve_pub=$1"
1576 " FOR UPDATE",
1577 1),
1578 /* Used in #postgres_get_expired_reserves() */
1579 GNUNET_PQ_make_prepare ("get_expired_reserves",
1580 "SELECT"
1581 " expiration_date"
1582 ",account_details"
1583 ",reserve_pub"
1584 ",current_balance_val"
1585 ",current_balance_frac"
1586 " FROM reserves"
1587 " WHERE expiration_date<=$1"
1588 " AND (current_balance_val != 0 "
1589 " OR current_balance_frac != 0)"
1590 " ORDER BY expiration_date ASC"
1591 " LIMIT 1;",
1592 1),
1593 /* Used in #postgres_get_coin_transactions() to obtain payback transactions
1594 for a coin */
1595 GNUNET_PQ_make_prepare ("payback_by_coin",
1596 "SELECT"
1597 " ro.reserve_pub"
1598 ",coin_sig"
1599 ",coin_blind"
1600 ",amount_val"
1601 ",amount_frac"
1602 ",timestamp"
1603 ",coins.denom_pub_hash"
1604 ",coins.denom_sig"
1605 ",payback_uuid"
1606 " FROM payback"
1607 " JOIN known_coins coins"
1608 " USING (coin_pub)"
1609 " JOIN reserves_out ro"
1610 " USING (h_blind_ev)"
1611 " WHERE payback.coin_pub=$1"
1612 " FOR UPDATE;",
1613 1),
1614 /* Used in #postgres_get_coin_transactions() to obtain payback transactions
1615 for a refreshed coin */
1616 GNUNET_PQ_make_prepare ("payback_by_refreshed_coin",
1617 "SELECT"
1618 " rc.old_coin_pub"
1619 ",coin_sig"
1620 ",coin_blind"
1621 ",amount_val"
1622 ",amount_frac"
1623 ",timestamp"
1624 ",coins.denom_pub_hash"
1625 ",coins.denom_sig"
1626 ",payback_refresh_uuid"
1627 " FROM payback_refresh"
1628 " JOIN refresh_revealed_coins rrc"
1629 " ON (rrc.coin_ev = h_blind_ev)"
1630 " JOIN refresh_commitments rc"
1631 " ON (rrc.rc = rc.rc)"
1632 " JOIN known_coins coins"
1633 " USING (coin_pub)"
1634 " WHERE coin_pub=$1"
1635 " FOR UPDATE;",
1636 1),
1637 /* Used in #postgres_get_reserve_by_h_blind() */
1638 GNUNET_PQ_make_prepare ("reserve_by_h_blind",
1639 "SELECT"
1640 " reserve_pub"
1641 " FROM reserves_out"
1642 " WHERE h_blind_ev=$1"
1643 " LIMIT 1"
1644 " FOR UPDATE;",
1645 1),
1646 /* Used in #postgres_get_old_coin_by_h_blind() */
1647 GNUNET_PQ_make_prepare ("old_coin_by_h_blind",
1648 "SELECT"
1649 " rcom.old_coin_pub"
1650 " FROM refresh_revealed_coins"
1651 " JOIN refresh_commitments rcom"
1652 " USING (rc)"
1653 " WHERE h_coin_ev=$1"
1654 " LIMIT 1"
1655 " FOR UPDATE;",
1656 1),
1657 /* used in #postgres_commit */
1658 GNUNET_PQ_make_prepare ("do_commit",
1659 "COMMIT",
1660 0),
1661 GNUNET_PQ_make_prepare ("gc_denominations",
1662 "DELETE"
1663 " FROM denominations"
1664 " WHERE expire_legal < $1;",
1665 1),
1666 GNUNET_PQ_make_prepare ("gc_reserves",
1667 "DELETE"
1668 " FROM reserves"
1669 " WHERE gc_date < $1"
1670 " AND current_balance_val = 0"
1671 " AND current_balance_frac = 0;",
1672 1),
1673 GNUNET_PQ_make_prepare ("gc_wire_fee",
1674 "DELETE"
1675 " FROM wire_fee"
1676 " WHERE end_date < $1;",
1677 1),
1678 GNUNET_PQ_PREPARED_STATEMENT_END
1679 };
1680
1681 return GNUNET_PQ_prepare_statements (db_conn,
1682 ps);
1683} 526}
1684 527
1685 528
@@ -1692,13 +535,14 @@ static void
1692db_conn_destroy (void *cls) 535db_conn_destroy (void *cls)
1693{ 536{
1694 struct TALER_EXCHANGEDB_Session *session = cls; 537 struct TALER_EXCHANGEDB_Session *session = cls;
1695 PGconn *db_conn; 538 struct GNUNET_PQ_Context *db_conn;
1696 539
1697 if (NULL == session) 540 if (NULL == session)
1698 return; 541 return;
1699 db_conn = session->conn; 542 db_conn = session->conn;
543 session->conn = NULL;
1700 if (NULL != db_conn) 544 if (NULL != db_conn)
1701 PQfinish (db_conn); 545 GNUNET_PQ_disconnect (session->conn);
1702 GNUNET_free (session); 546 GNUNET_free (session);
1703} 547}
1704 548
@@ -1714,44 +558,18 @@ static struct TALER_EXCHANGEDB_Session *
1714postgres_get_session (void *cls) 558postgres_get_session (void *cls)
1715{ 559{
1716 struct PostgresClosure *pc = cls; 560 struct PostgresClosure *pc = cls;
1717 PGconn *db_conn; 561 struct GNUNET_PQ_Context *db_conn;
1718 struct TALER_EXCHANGEDB_Session *session; 562 struct TALER_EXCHANGEDB_Session *session;
1719 563
1720 if (NULL != (session = pthread_getspecific (pc->db_conn_threadlocal))) 564 if (NULL != (session = pthread_getspecific (pc->db_conn_threadlocal)))
1721 { 565 {
1722 if (CONNECTION_BAD == PQstatus (session->conn)) 566 GNUNET_PQ_reconnect_if_down (session->conn);
1723 { 567 return session;
1724 /**
1725 * Reset the thread-local database-handle. Disconnects from the
1726 * DB. Needed after the database server restarts as we need to
1727 * properly reconnect. */
1728 GNUNET_assert (0 ==
1729 pthread_setspecific (pc->db_conn_threadlocal,
1730 NULL));
1731 PQfinish (session->conn);
1732 GNUNET_free (session);
1733 }
1734 else
1735 {
1736 return session;
1737 }
1738 } 568 }
1739 /* FIXME: use GNUNET_PQ_connect_with_cfg instead? */
1740 db_conn = GNUNET_PQ_connect (pc->connection_cfg_str);
1741 if (NULL == db_conn)
1742 return NULL;
1743 if (GNUNET_OK !=
1744 postgres_prepare (db_conn))
1745 { 569 {
1746 GNUNET_break (0);
1747 PQfinish (db_conn);
1748 return NULL;
1749 }
1750
1751#if AUTO_EXPLAIN 570#if AUTO_EXPLAIN
1752 /* Enable verbose logging to see where queries do not 571 /* Enable verbose logging to see where queries do not
1753 properly use indices */ 572 properly use indices */
1754 {
1755 struct GNUNET_PQ_ExecuteStatement es[] = { 573 struct GNUNET_PQ_ExecuteStatement es[] = {
1756 GNUNET_PQ_make_try_execute ("LOAD 'auto_explain';"), 574 GNUNET_PQ_make_try_execute ("LOAD 'auto_explain';"),
1757 GNUNET_PQ_make_try_execute ("SET auto_explain.log_min_duration=50;"), 575 GNUNET_PQ_make_try_execute ("SET auto_explain.log_min_duration=50;"),
@@ -1761,19 +579,1136 @@ postgres_get_session (void *cls)
1761 GNUNET_PQ_make_try_execute ("SET enable_seqscan=OFF;"), 579 GNUNET_PQ_make_try_execute ("SET enable_seqscan=OFF;"),
1762 GNUNET_PQ_EXECUTE_STATEMENT_END 580 GNUNET_PQ_EXECUTE_STATEMENT_END
1763 }; 581 };
1764 582#else
1765 (void) GNUNET_PQ_exec_statements (db_conn, 583 struct GNUNET_PQ_ExecuteStatement *es = NULL;
1766 es);
1767 }
1768#endif 584#endif
585 struct GNUNET_PQ_PreparedStatement ps[] = {
586 /* Used in #postgres_insert_denomination_info() */
587 GNUNET_PQ_make_prepare ("denomination_insert",
588 "INSERT INTO denominations "
589 "(denom_pub_hash"
590 ",denom_pub"
591 ",master_pub"
592 ",master_sig"
593 ",valid_from"
594 ",expire_withdraw"
595 ",expire_deposit"
596 ",expire_legal"
597 ",coin_val" /* value of this denom */
598 ",coin_frac" /* fractional value of this denom */
599 ",fee_withdraw_val"
600 ",fee_withdraw_frac"
601 ",fee_deposit_val"
602 ",fee_deposit_frac"
603 ",fee_refresh_val"
604 ",fee_refresh_frac"
605 ",fee_refund_val"
606 ",fee_refund_frac"
607 ") VALUES "
608 "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
609 " $11, $12, $13, $14, $15, $16, $17, $18);",
610 18),
611 /* Used in #postgres_iterate_denomination_info() */
612 GNUNET_PQ_make_prepare ("denomination_iterate",
613 "SELECT"
614 " master_pub"
615 ",master_sig"
616 ",valid_from"
617 ",expire_withdraw"
618 ",expire_deposit"
619 ",expire_legal"
620 ",coin_val" /* value of this denom */
621 ",coin_frac" /* fractional value of this denom */
622 ",fee_withdraw_val"
623 ",fee_withdraw_frac"
624 ",fee_deposit_val"
625 ",fee_deposit_frac"
626 ",fee_refresh_val"
627 ",fee_refresh_frac"
628 ",fee_refund_val"
629 ",fee_refund_frac"
630 ",denom_pub"
631 " FROM denominations;",
632 0),
633 /* Used in #postgres_get_denomination_info() */
634 GNUNET_PQ_make_prepare ("denomination_get",
635 "SELECT"
636 " master_pub"
637 ",master_sig"
638 ",valid_from"
639 ",expire_withdraw"
640 ",expire_deposit"
641 ",expire_legal"
642 ",coin_val" /* value of this denom */
643 ",coin_frac" /* fractional value of this denom */
644 ",fee_withdraw_val"
645 ",fee_withdraw_frac"
646 ",fee_deposit_val"
647 ",fee_deposit_frac"
648 ",fee_refresh_val"
649 ",fee_refresh_frac"
650 ",fee_refund_val"
651 ",fee_refund_frac"
652 " FROM denominations"
653 " WHERE denom_pub_hash=$1;",
654 1),
655 /* Used in #postgres_insert_denomination_revocation() */
656 GNUNET_PQ_make_prepare ("denomination_revocation_insert",
657 "INSERT INTO denomination_revocations "
658 "(denom_pub_hash"
659 ",master_sig"
660 ") VALUES "
661 "($1, $2);",
662 2),
663 /* Used in #postgres_get_denomination_revocation() */
664 GNUNET_PQ_make_prepare ("denomination_revocation_get",
665 "SELECT"
666 " master_sig"
667 ",denom_revocations_serial_id"
668 " FROM denomination_revocations"
669 " WHERE denom_pub_hash=$1;",
670 1),
671 /* Used in #postgres_reserve_get() */
672 GNUNET_PQ_make_prepare ("reserve_get",
673 "SELECT"
674 " current_balance_val"
675 ",current_balance_frac"
676 ",expiration_date"
677 ",gc_date"
678 " FROM reserves"
679 " WHERE reserve_pub=$1"
680 " LIMIT 1"
681 " FOR UPDATE;",
682 1),
683 /* Used in #postgres_reserves_in_insert() when the reserve is new */
684 GNUNET_PQ_make_prepare ("reserve_create",
685 "INSERT INTO reserves "
686 "(reserve_pub"
687 ",account_details"
688 ",current_balance_val"
689 ",current_balance_frac"
690 ",expiration_date"
691 ",gc_date"
692 ") VALUES "
693 "($1, $2, $3, $4, $5, $6);",
694 6),
695 /* Used in #postgres_insert_reserve_closed() */
696 GNUNET_PQ_make_prepare ("reserves_close_insert",
697 "INSERT INTO reserves_close "
698 "(reserve_pub"
699 ",execution_date"
700 ",wtid"
701 ",receiver_account"
702 ",amount_val"
703 ",amount_frac"
704 ",closing_fee_val"
705 ",closing_fee_frac"
706 ") VALUES "
707 "($1, $2, $3, $4, $5, $6, $7, $8);",
708 8),
709 /* Used in #reserves_update() when the reserve is updated */
710 GNUNET_PQ_make_prepare ("reserve_update",
711 "UPDATE reserves"
712 " SET"
713 " expiration_date=$1"
714 ",gc_date=$2"
715 ",current_balance_val=$3"
716 ",current_balance_frac=$4"
717 " WHERE"
718 " reserve_pub=$5;",
719 5),
720 /* Used in #postgres_reserves_in_insert() to store transaction details */
721 GNUNET_PQ_make_prepare ("reserves_in_add_transaction",
722 "INSERT INTO reserves_in "
723 "(reserve_pub"
724 ",wire_reference"
725 ",credit_val"
726 ",credit_frac"
727 ",exchange_account_section"
728 ",sender_account_details"
729 ",execution_date"
730 ") VALUES "
731 "($1, $2, $3, $4, $5, $6, $7) "
732 "ON CONFLICT DO NOTHING;",
733 7),
734 /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
735 transactions for reserves with serial id '\geq' the given parameter */
736 GNUNET_PQ_make_prepare ("reserves_in_get_latest_wire_reference",
737 "SELECT"
738 " wire_reference"
739 " FROM reserves_in"
740 " WHERE exchange_account_section=$1"
741 " ORDER BY reserve_in_serial_id DESC"
742 " LIMIT 1;",
743 1),
744 /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
745 transactions for reserves with serial id '\geq' the given parameter */
746 GNUNET_PQ_make_prepare ("audit_reserves_in_get_transactions_incr",
747 "SELECT"
748 " reserve_pub"
749 ",wire_reference"
750 ",credit_val"
751 ",credit_frac"
752 ",execution_date"
753 ",sender_account_details"
754 ",reserve_in_serial_id"
755 " FROM reserves_in"
756 " WHERE reserve_in_serial_id>=$1"
757 " ORDER BY reserve_in_serial_id;",
758 1),
759 /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
760 transactions for reserves with serial id '\geq' the given parameter */
761 GNUNET_PQ_make_prepare (
762 "audit_reserves_in_get_transactions_incr_by_account",
763 "SELECT"
764 " reserve_pub"
765 ",wire_reference"
766 ",credit_val"
767 ",credit_frac"
768 ",execution_date"
769 ",sender_account_details"
770 ",reserve_in_serial_id"
771 " FROM reserves_in"
772 " WHERE reserve_in_serial_id>=$1 AND exchange_account_section=$2"
773 " ORDER BY reserve_in_serial_id;",
774 2),
775 /* Used in #postgres_get_reserve_history() to obtain inbound transactions
776 for a reserve */
777 GNUNET_PQ_make_prepare ("reserves_in_get_transactions",
778 "SELECT"
779 " wire_reference"
780 ",credit_val"
781 ",credit_frac"
782 ",execution_date"
783 ",sender_account_details"
784 " FROM reserves_in"
785 " WHERE reserve_pub=$1"
786 " FOR UPDATE;",
787 1),
788 /* Lock withdraw table; NOTE: we may want to eventually shard the
789 deposit table to avoid this lock being the main point of
790 contention limiting transaction performance. */
791 GNUNET_PQ_make_prepare ("lock_withdraw",
792 "LOCK TABLE reserves_out;",
793 0),
794 /* Used in #postgres_insert_withdraw_info() to store
795 the signature of a blinded coin with the blinded coin's
796 details before returning it during /reserve/withdraw. We store
797 the coin's denomination information (public key, signature)
798 and the blinded message as well as the reserve that the coin
799 is being withdrawn from and the signature of the message
800 authorizing the withdrawal. */
801 GNUNET_PQ_make_prepare ("insert_withdraw_info",
802 "INSERT INTO reserves_out "
803 "(h_blind_ev"
804 ",denom_pub_hash"
805 ",denom_sig"
806 ",reserve_pub"
807 ",reserve_sig"
808 ",execution_date"
809 ",amount_with_fee_val"
810 ",amount_with_fee_frac"
811 ") VALUES "
812 "($1, $2, $3, $4, $5, $6, $7, $8);",
813 8),
814 /* Used in #postgres_get_withdraw_info() to
815 locate the response for a /reserve/withdraw request
816 using the hash of the blinded message. Used to
817 make sure /reserve/withdraw requests are idempotent. */
818 GNUNET_PQ_make_prepare ("get_withdraw_info",
819 "SELECT"
820 " denom_pub_hash"
821 ",denom_sig"
822 ",reserve_sig"
823 ",reserve_pub"
824 ",execution_date"
825 ",amount_with_fee_val"
826 ",amount_with_fee_frac"
827 ",denom.fee_withdraw_val"
828 ",denom.fee_withdraw_frac"
829 " FROM reserves_out"
830 " JOIN denominations denom"
831 " USING (denom_pub_hash)"
832 " WHERE h_blind_ev=$1"
833 " FOR UPDATE;",
834 1),
835 /* Used during #postgres_get_reserve_history() to
836 obtain all of the /reserve/withdraw operations that
837 have been performed on a given reserve. (i.e. to
838 demonstrate double-spending) */
839 GNUNET_PQ_make_prepare ("get_reserves_out",
840 "SELECT"
841 " h_blind_ev"
842 ",denom_pub_hash"
843 ",denom_sig"
844 ",reserve_sig"
845 ",execution_date"
846 ",amount_with_fee_val"
847 ",amount_with_fee_frac"
848 ",denom.fee_withdraw_val"
849 ",denom.fee_withdraw_frac"
850 " FROM reserves_out"
851 " JOIN denominations denom"
852 " USING (denom_pub_hash)"
853 " WHERE reserve_pub=$1"
854 " FOR UPDATE",
855 1),
856 /* Used in #postgres_select_reserves_out_above_serial_id() */
857 GNUNET_PQ_make_prepare ("audit_get_reserves_out_incr",
858 "SELECT"
859 " h_blind_ev"
860 ",denom.denom_pub"
861 ",denom_sig"
862 ",reserve_sig"
863 ",reserve_pub"
864 ",execution_date"
865 ",amount_with_fee_val"
866 ",amount_with_fee_frac"
867 ",reserve_out_serial_id"
868 " FROM reserves_out"
869 " JOIN denominations denom"
870 " USING (denom_pub_hash)"
871 " WHERE reserve_out_serial_id>=$1"
872 " ORDER BY reserve_out_serial_id ASC;",
873 1),
874
875 /* Used in #postgres_count_known_coins() */
876 GNUNET_PQ_make_prepare ("count_known_coins",
877 "SELECT"
878 " COUNT(*) AS count"
879 " FROM known_coins"
880 " WHERE denom_pub_hash=$1;",
881 1),
882 /* Used in #postgres_get_known_coin() to fetch
883 the denomination public key and signature for
884 a coin known to the exchange. */
885 GNUNET_PQ_make_prepare ("get_known_coin",
886 "SELECT"
887 " denom_pub_hash"
888 ",denom_sig"
889 " FROM known_coins"
890 " WHERE coin_pub=$1"
891 " FOR UPDATE;",
892 1),
893 /* Lock deposit table; NOTE: we may want to eventually shard the
894 deposit table to avoid this lock being the main point of
895 contention limiting transaction performance. */
896 GNUNET_PQ_make_prepare ("lock_known_coins",
897 "LOCK TABLE known_coins;",
898 0),
899 /* Used in #postgres_insert_known_coin() to store
900 the denomination public key and signature for
901 a coin known to the exchange. */
902 GNUNET_PQ_make_prepare ("insert_known_coin",
903 "INSERT INTO known_coins "
904 "(coin_pub"
905 ",denom_pub_hash"
906 ",denom_sig"
907 ") VALUES "
908 "($1,$2,$3);",
909 3),
910
911 /* Used in #postgres_insert_melt() to store
912 high-level information about a melt operation */
913 GNUNET_PQ_make_prepare ("insert_melt",
914 "INSERT INTO refresh_commitments "
915 "(rc "
916 ",old_coin_pub "
917 ",old_coin_sig "
918 ",amount_with_fee_val "
919 ",amount_with_fee_frac "
920 ",noreveal_index "
921 ") VALUES "
922 "($1, $2, $3, $4, $5, $6);",
923 6),
924 /* Used in #postgres_get_melt() to fetch
925 high-level information about a melt operation */
926 GNUNET_PQ_make_prepare ("get_melt",
927 "SELECT"
928 " kc.denom_pub_hash"
929 ",denom.fee_refresh_val"
930 ",denom.fee_refresh_frac"
931 ",old_coin_pub"
932 ",old_coin_sig"
933 ",amount_with_fee_val"
934 ",amount_with_fee_frac"
935 ",noreveal_index"
936 " FROM refresh_commitments"
937 " JOIN known_coins kc"
938 " ON (refresh_commitments.old_coin_pub = kc.coin_pub)"
939 " JOIN denominations denom"
940 " ON (kc.denom_pub_hash = denom.denom_pub_hash)"
941 " WHERE rc=$1;",
942 1),
943 /* Used in #postgres_get_melt_index() to fetch
944 the noreveal index from a previous melt operation */
945 GNUNET_PQ_make_prepare ("get_melt_index",
946 "SELECT"
947 " noreveal_index"
948 " FROM refresh_commitments"
949 " WHERE rc=$1;",
950 1),
951 /* Used in #postgres_select_refreshs_above_serial_id() to fetch
952 refresh session with id '\geq' the given parameter */
953 GNUNET_PQ_make_prepare ("audit_get_refresh_commitments_incr",
954 "SELECT"
955 " denom.denom_pub"
956 ",old_coin_pub"
957 ",old_coin_sig"
958 ",amount_with_fee_val"
959 ",amount_with_fee_frac"
960 ",noreveal_index"
961 ",melt_serial_id"
962 ",rc"
963 " FROM refresh_commitments"
964 " JOIN known_coins kc"
965 " ON (refresh_commitments.old_coin_pub = kc.coin_pub)"
966 " JOIN denominations denom"
967 " ON (kc.denom_pub_hash = denom.denom_pub_hash)"
968 " WHERE melt_serial_id>=$1"
969 " ORDER BY melt_serial_id ASC;",
970 1),
971 /* Query the 'refresh_commitments' by coin public key */
972 GNUNET_PQ_make_prepare ("get_refresh_session_by_coin",
973 "SELECT"
974 " rc"
975 ",old_coin_sig"
976 ",amount_with_fee_val"
977 ",amount_with_fee_frac"
978 ",denom.fee_refresh_val "
979 ",denom.fee_refresh_frac "
980 ",melt_serial_id"
981 " FROM refresh_commitments"
982 " JOIN known_coins "
983 " ON (refresh_commitments.old_coin_pub = known_coins.coin_pub)"
984 " JOIN denominations denom USING (denom_pub_hash)"
985 " WHERE old_coin_pub=$1;",
986 1),
987
988 /* Store information about the desired denominations for a
989 refresh operation, used in #postgres_insert_refresh_reveal() */
990 GNUNET_PQ_make_prepare ("insert_refresh_revealed_coin",
991 "INSERT INTO refresh_revealed_coins "
992 "(rc "
993 ",newcoin_index "
994 ",link_sig "
995 ",denom_pub_hash "
996 ",coin_ev"
997 ",h_coin_ev"
998 ",ev_sig"
999 ") VALUES "
1000 "($1, $2, $3, $4, $5, $6, $7);",
1001 7),
1002 /* Obtain information about the coins created in a refresh
1003 operation, used in #postgres_get_refresh_reveal() */
1004 GNUNET_PQ_make_prepare ("get_refresh_revealed_coins",
1005 "SELECT "
1006 " newcoin_index"
1007 ",denom.denom_pub"
1008 ",link_sig"
1009 ",coin_ev"
1010 ",ev_sig"
1011 " FROM refresh_revealed_coins"
1012 " JOIN denominations denom "
1013 " USING (denom_pub_hash)"
1014 " WHERE rc=$1"
1015 " ORDER BY newcoin_index ASC"
1016 " FOR UPDATE;",
1017 1),
1018
1019 /* Used in #postgres_insert_refresh_reveal() to store the transfer
1020 keys we learned */
1021 GNUNET_PQ_make_prepare ("insert_refresh_transfer_keys",
1022 "INSERT INTO refresh_transfer_keys "
1023 "(rc"
1024 ",transfer_pub"
1025 ",transfer_privs"
1026 ") VALUES "
1027 "($1, $2, $3);",
1028 3),
1029 /* Used in #postgres_get_refresh_reveal() to retrieve transfer
1030 keys from /refresh/reveal */
1031 GNUNET_PQ_make_prepare ("get_refresh_transfer_keys",
1032 "SELECT"
1033 " transfer_pub"
1034 ",transfer_privs"
1035 " FROM refresh_transfer_keys"
1036 " WHERE rc=$1;",
1037 1),
1038
1039
1040 /* Used in #postgres_insert_refund() to store refund information */
1041 GNUNET_PQ_make_prepare ("insert_refund",
1042 "INSERT INTO refunds "
1043 "(coin_pub "
1044 ",merchant_pub "
1045 ",merchant_sig "
1046 ",h_contract_terms "
1047 ",rtransaction_id "
1048 ",amount_with_fee_val "
1049 ",amount_with_fee_frac "
1050 ") VALUES "
1051 "($1, $2, $3, $4, $5, $6, $7);",
1052 7),
1053 /* Query the 'refunds' by coin public key */
1054 GNUNET_PQ_make_prepare ("get_refunds_by_coin",
1055 "SELECT"
1056 " merchant_pub"
1057 ",merchant_sig"
1058 ",h_contract_terms"
1059 ",rtransaction_id"
1060 ",amount_with_fee_val"
1061 ",amount_with_fee_frac"
1062 ",denom.fee_refund_val "
1063 ",denom.fee_refund_frac "
1064 ",refund_serial_id"
1065 " FROM refunds"
1066 " JOIN known_coins USING (coin_pub)"
1067 " JOIN denominations denom USING (denom_pub_hash)"
1068 " WHERE coin_pub=$1;",
1069 1),
1070 /* Fetch refunds with rowid '\geq' the given parameter */
1071 GNUNET_PQ_make_prepare ("audit_get_refunds_incr",
1072 "SELECT"
1073 " merchant_pub"
1074 ",merchant_sig"
1075 ",h_contract_terms"
1076 ",rtransaction_id"
1077 ",denom.denom_pub"
1078 ",coin_pub"
1079 ",amount_with_fee_val"
1080 ",amount_with_fee_frac"
1081 ",refund_serial_id"
1082 " FROM refunds"
1083 " JOIN known_coins kc USING (coin_pub)"
1084 " JOIN denominations denom ON (kc.denom_pub_hash = denom.denom_pub_hash)"
1085 " WHERE refund_serial_id>=$1"
1086 " ORDER BY refund_serial_id ASC;",
1087 1),
1088 /* Lock deposit table; NOTE: we may want to eventually shard the
1089 deposit table to avoid this lock being the main point of
1090 contention limiting transaction performance. */
1091 GNUNET_PQ_make_prepare ("lock_deposit",
1092 "LOCK TABLE deposits;",
1093 0),
1094 /* Store information about a /deposit the exchange is to execute.
1095 Used in #postgres_insert_deposit(). */
1096 GNUNET_PQ_make_prepare ("insert_deposit",
1097 "INSERT INTO deposits "
1098 "(coin_pub"
1099 ",amount_with_fee_val"
1100 ",amount_with_fee_frac"
1101 ",timestamp"
1102 ",refund_deadline"
1103 ",wire_deadline"
1104 ",merchant_pub"
1105 ",h_contract_terms"
1106 ",h_wire"
1107 ",coin_sig"
1108 ",wire"
1109 ") VALUES "
1110 "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
1111 " $11);",
1112 11),
1113 /* Fetch an existing deposit request, used to ensure idempotency
1114 during /deposit processing. Used in #postgres_have_deposit(). */
1115 GNUNET_PQ_make_prepare ("get_deposit",
1116 "SELECT"
1117 " amount_with_fee_val"
1118 ",amount_with_fee_frac"
1119 ",timestamp"
1120 ",refund_deadline"
1121 ",wire_deadline"
1122 ",h_contract_terms"
1123 ",h_wire"
1124 " FROM deposits"
1125 " WHERE ((coin_pub=$1)"
1126 " AND (merchant_pub=$3)"
1127 " AND (h_contract_terms=$2))"
1128 " FOR UPDATE;",
1129 3),
1130 /* Fetch deposits with rowid '\geq' the given parameter */
1131 GNUNET_PQ_make_prepare ("audit_get_deposits_incr",
1132 "SELECT"
1133 " amount_with_fee_val"
1134 ",amount_with_fee_frac"
1135 ",timestamp"
1136 ",merchant_pub"
1137 ",denom.denom_pub"
1138 ",coin_pub"
1139 ",coin_sig"
1140 ",refund_deadline"
1141 ",wire_deadline"
1142 ",h_contract_terms"
1143 ",wire"
1144 ",done"
1145 ",deposit_serial_id"
1146 " FROM deposits"
1147 " JOIN known_coins USING (coin_pub)"
1148 " JOIN denominations denom USING (denom_pub_hash)"
1149 " WHERE ("
1150 " (deposit_serial_id>=$1)"
1151 " )"
1152 " ORDER BY deposit_serial_id ASC;",
1153 1),
1154 /* Fetch an existing deposit request.
1155 Used in #postgres_wire_lookup_deposit_wtid(). */
1156 GNUNET_PQ_make_prepare ("get_deposit_for_wtid",
1157 "SELECT"
1158 " amount_with_fee_val"
1159 ",amount_with_fee_frac"
1160 ",denom.fee_deposit_val"
1161 ",denom.fee_deposit_frac"
1162 ",wire_deadline"
1163 " FROM deposits"
1164 " JOIN known_coins USING (coin_pub)"
1165 " JOIN denominations denom USING (denom_pub_hash)"
1166 " WHERE ("
1167 " (coin_pub=$1)"
1168 " AND (merchant_pub=$2)"
1169 " AND (h_contract_terms=$3)"
1170 " AND (h_wire=$4)"
1171 " );",
1172 4),
1173 /* Used in #postgres_get_ready_deposit() */
1174 GNUNET_PQ_make_prepare ("deposits_get_ready",
1175 "SELECT"
1176 " deposit_serial_id"
1177 ",amount_with_fee_val"
1178 ",amount_with_fee_frac"
1179 ",denom.fee_deposit_val"
1180 ",denom.fee_deposit_frac"
1181 ",wire_deadline"
1182 ",h_contract_terms"
1183 ",wire"
1184 ",merchant_pub"
1185 ",coin_pub"
1186 " FROM deposits"
1187 " JOIN known_coins USING (coin_pub)"
1188 " JOIN denominations denom USING (denom_pub_hash)"
1189 " WHERE tiny=FALSE"
1190 " AND done=FALSE"
1191 " AND wire_deadline<=$1"
1192 " AND refund_deadline<$1"
1193 " ORDER BY wire_deadline ASC"
1194 " LIMIT 1;",
1195 1),
1196 /* Used in #postgres_iterate_matching_deposits() */
1197 GNUNET_PQ_make_prepare ("deposits_iterate_matching",
1198 "SELECT"
1199 " deposit_serial_id"
1200 ",amount_with_fee_val"
1201 ",amount_with_fee_frac"
1202 ",denom.fee_deposit_val"
1203 ",denom.fee_deposit_frac"
1204 ",wire_deadline"
1205 ",h_contract_terms"
1206 ",coin_pub"
1207 " FROM deposits"
1208 " JOIN known_coins"
1209 " USING (coin_pub)"
1210 " JOIN denominations denom"
1211 " USING (denom_pub_hash)"
1212 " WHERE"
1213 " merchant_pub=$1 AND"
1214 " h_wire=$2 AND"
1215 " done=FALSE"
1216 " ORDER BY wire_deadline ASC"
1217 " LIMIT "
1218 TALER_EXCHANGEDB_MATCHING_DEPOSITS_LIMIT_STR ";",
1219 2),
1220 /* Used in #postgres_mark_deposit_tiny() */
1221 GNUNET_PQ_make_prepare ("mark_deposit_tiny",
1222 "UPDATE deposits"
1223 " SET tiny=TRUE"
1224 " WHERE deposit_serial_id=$1",
1225 1),
1226 /* Used in #postgres_mark_deposit_done() */
1227 GNUNET_PQ_make_prepare ("mark_deposit_done",
1228 "UPDATE deposits"
1229 " SET done=TRUE"
1230 " WHERE deposit_serial_id=$1;",
1231 1),
1232 /* Used in #postgres_test_deposit_done() */
1233 GNUNET_PQ_make_prepare ("test_deposit_done",
1234 "SELECT done"
1235 " FROM deposits"
1236 " WHERE coin_pub=$1"
1237 " AND merchant_pub=$2"
1238 " AND h_contract_terms=$3"
1239 " AND h_wire=$4;",
1240 5),
1241 /* Used in #postgres_get_coin_transactions() to obtain information
1242 about how a coin has been spend with /deposit requests. */
1243 GNUNET_PQ_make_prepare ("get_deposit_with_coin_pub",
1244 "SELECT"
1245 " amount_with_fee_val"
1246 ",amount_with_fee_frac"
1247 ",denom.fee_deposit_val"
1248 ",denom.fee_deposit_frac"
1249 ",timestamp"
1250 ",refund_deadline"
1251 ",wire_deadline"
1252 ",merchant_pub"
1253 ",h_contract_terms"
1254 ",h_wire"
1255 ",wire"
1256 ",coin_sig"
1257 ",deposit_serial_id"
1258 " FROM deposits"
1259 " JOIN known_coins"
1260 " USING (coin_pub)"
1261 " JOIN denominations denom"
1262 " USING (denom_pub_hash)"
1263 " WHERE coin_pub=$1"
1264 " FOR UPDATE;",
1265 1),
1266
1267 /* Used in #postgres_get_link_data(). */
1268 GNUNET_PQ_make_prepare ("get_link",
1269 "SELECT "
1270 " tp.transfer_pub"
1271 ",denoms.denom_pub"
1272 ",rrc.ev_sig"
1273 ",rrc.link_sig"
1274 " FROM refresh_commitments"
1275 " JOIN refresh_revealed_coins rrc"
1276 " USING (rc)"
1277 " JOIN refresh_transfer_keys tp"
1278 " USING (rc)"
1279 " JOIN denominations denoms"
1280 " ON (rrc.denom_pub_hash = denoms.denom_pub_hash)"
1281 " WHERE old_coin_pub=$1"
1282 " ORDER BY tp.transfer_pub",
1283 1),
1284 /* Used in #postgres_lookup_wire_transfer */
1285 GNUNET_PQ_make_prepare ("lookup_transactions",
1286 "SELECT"
1287 " aggregation_serial_id"
1288 ",deposits.h_contract_terms"
1289 ",deposits.wire"
1290 ",deposits.h_wire"
1291 ",deposits.coin_pub"
1292 ",deposits.merchant_pub"
1293 ",wire_out.execution_date"
1294 ",deposits.amount_with_fee_val"
1295 ",deposits.amount_with_fee_frac"
1296 ",denom.fee_deposit_val"
1297 ",denom.fee_deposit_frac"
1298 ",denom.denom_pub"
1299 " FROM aggregation_tracking"
1300 " JOIN deposits"
1301 " USING (deposit_serial_id)"
1302 " JOIN known_coins"
1303 " USING (coin_pub)"
1304 " JOIN denominations denom"
1305 " USING (denom_pub_hash)"
1306 " JOIN wire_out"
1307 " USING (wtid_raw)"
1308 " WHERE wtid_raw=$1;",
1309 1),
1310 /* Used in #postgres_wire_lookup_deposit_wtid */
1311 GNUNET_PQ_make_prepare ("lookup_deposit_wtid",
1312 "SELECT"
1313 " aggregation_tracking.wtid_raw"
1314 ",wire_out.execution_date"
1315 ",amount_with_fee_val"
1316 ",amount_with_fee_frac"
1317 ",denom.fee_deposit_val"
1318 ",denom.fee_deposit_frac"
1319 " FROM deposits"
1320 " JOIN aggregation_tracking"
1321 " USING (deposit_serial_id)"
1322 " JOIN known_coins"
1323 " USING (coin_pub)"
1324 " JOIN denominations denom"
1325 " USING (denom_pub_hash)"
1326 " JOIN wire_out"
1327 " USING (wtid_raw)"
1328 " WHERE coin_pub=$1"
1329 " AND h_contract_terms=$2"
1330 " AND h_wire=$3"
1331 " AND merchant_pub=$4;",
1332 4),
1333 /* Used in #postgres_insert_aggregation_tracking */
1334 GNUNET_PQ_make_prepare ("insert_aggregation_tracking",
1335 "INSERT INTO aggregation_tracking "
1336 "(deposit_serial_id"
1337 ",wtid_raw"
1338 ") VALUES "
1339 "($1, $2);",
1340 2),
1341 /* Used in #postgres_get_wire_fee() */
1342 GNUNET_PQ_make_prepare ("get_wire_fee",
1343 "SELECT "
1344 " start_date"
1345 ",end_date"
1346 ",wire_fee_val"
1347 ",wire_fee_frac"
1348 ",closing_fee_val"
1349 ",closing_fee_frac"
1350 ",master_sig"
1351 " FROM wire_fee"
1352 " WHERE wire_method=$1"
1353 " AND start_date <= $2"
1354 " AND end_date > $2;",
1355 2),
1356 /* Used in #postgres_insert_wire_fee */
1357 GNUNET_PQ_make_prepare ("insert_wire_fee",
1358 "INSERT INTO wire_fee "
1359 "(wire_method"
1360 ",start_date"
1361 ",end_date"
1362 ",wire_fee_val"
1363 ",wire_fee_frac"
1364 ",closing_fee_val"
1365 ",closing_fee_frac"
1366 ",master_sig"
1367 ") VALUES "
1368 "($1, $2, $3, $4, $5, $6, $7, $8);",
1369 8),
1370 /* Used in #postgres_store_wire_transfer_out */
1371 GNUNET_PQ_make_prepare ("insert_wire_out",
1372 "INSERT INTO wire_out "
1373 "(execution_date"
1374 ",wtid_raw"
1375 ",wire_target"
1376 ",exchange_account_section"
1377 ",amount_val"
1378 ",amount_frac"
1379 ") VALUES "
1380 "($1, $2, $3, $4, $5, $6);",
1381 6),
1382 /* Used in #postgres_wire_prepare_data_insert() to store
1383 wire transfer information before actually committing it with the bank */
1384 GNUNET_PQ_make_prepare ("wire_prepare_data_insert",
1385 "INSERT INTO prewire "
1386 "(type"
1387 ",buf"
1388 ") VALUES "
1389 "($1, $2);",
1390 2),
1391 /* Used in #postgres_wire_prepare_data_mark_finished() */
1392 GNUNET_PQ_make_prepare ("wire_prepare_data_mark_done",
1393 "UPDATE prewire"
1394 " SET finished=true"
1395 " WHERE prewire_uuid=$1;",
1396 1),
1397 /* Used in #postgres_wire_prepare_data_get() */
1398 GNUNET_PQ_make_prepare ("wire_prepare_data_get",
1399 "SELECT"
1400 " prewire_uuid"
1401 ",type"
1402 ",buf"
1403 " FROM prewire"
1404 " WHERE finished=false"
1405 " ORDER BY prewire_uuid ASC"
1406 " LIMIT 1;",
1407 0),
1408
1409 /* Used in #postgres_select_deposits_missing_wire */
1410 GNUNET_PQ_make_prepare ("deposits_get_overdue",
1411 "SELECT"
1412 " deposit_serial_id"
1413 ",coin_pub"
1414 ",amount_with_fee_val"
1415 ",amount_with_fee_frac"
1416 ",wire"
1417 ",wire_deadline"
1418 ",tiny"
1419 ",done"
1420 " FROM deposits"
1421 " WHERE wire_deadline >= $1"
1422 " AND wire_deadline < $2"
1423 " AND NOT (EXISTS (SELECT 1"
1424 " FROM refunds"
1425 " WHERE (refunds.coin_pub = deposits.coin_pub))"
1426 " OR EXISTS (SELECT 1"
1427 " FROM aggregation_tracking"
1428 " WHERE (aggregation_tracking.deposit_serial_id = deposits.deposit_serial_id)))"
1429 " ORDER BY wire_deadline ASC",
1430 2),
1431 /* Used in #postgres_select_wire_out_above_serial_id() */
1432 GNUNET_PQ_make_prepare ("audit_get_wire_incr",
1433 "SELECT"
1434 " wireout_uuid"
1435 ",execution_date"
1436 ",wtid_raw"
1437 ",wire_target"
1438 ",amount_val"
1439 ",amount_frac"
1440 " FROM wire_out"
1441 " WHERE wireout_uuid>=$1"
1442 " ORDER BY wireout_uuid ASC;",
1443 1),
1444 /* Used in #postgres_select_wire_out_above_serial_id_by_account() */
1445 GNUNET_PQ_make_prepare ("audit_get_wire_incr_by_account",
1446 "SELECT"
1447 " wireout_uuid"
1448 ",execution_date"
1449 ",wtid_raw"
1450 ",wire_target"
1451 ",amount_val"
1452 ",amount_frac"
1453 " FROM wire_out"
1454 " WHERE wireout_uuid>=$1 AND exchange_account_section=$2"
1455 " ORDER BY wireout_uuid ASC;",
1456 2),
1457 /* Used in #postgres_insert_payback_request() to store payback
1458 information */
1459 GNUNET_PQ_make_prepare ("payback_insert",
1460 "INSERT INTO payback "
1461 "(coin_pub"
1462 ",coin_sig"
1463 ",coin_blind"
1464 ",amount_val"
1465 ",amount_frac"
1466 ",timestamp"
1467 ",h_blind_ev"
1468 ") VALUES "
1469 "($1, $2, $3, $4, $5, $6, $7);",
1470 7),
1471 /* Used in #postgres_insert_payback_request() to store payback-refresh
1472 information */
1473 GNUNET_PQ_make_prepare ("payback_refresh_insert",
1474 "INSERT INTO payback_refresh "
1475 "(coin_pub"
1476 ",coin_sig"
1477 ",coin_blind"
1478 ",amount_val"
1479 ",amount_frac"
1480 ",timestamp"
1481 ",h_blind_ev"
1482 ") VALUES "
1483 "($1, $2, $3, $4, $5, $6, $7);",
1484 7),
1485 /* Used in #postgres_select_payback_above_serial_id() to obtain payback transactions */
1486 GNUNET_PQ_make_prepare ("payback_get_incr",
1487 "SELECT"
1488 " payback_uuid"
1489 ",timestamp"
1490 ",ro.reserve_pub"
1491 ",coin_pub"
1492 ",coin_sig"
1493 ",coin_blind"
1494 ",h_blind_ev"
1495 ",coins.denom_pub_hash"
1496 ",denoms.denom_pub"
1497 ",coins.denom_sig"
1498 ",amount_val"
1499 ",amount_frac"
1500 " FROM payback"
1501 " JOIN known_coins coins"
1502 " USING (coin_pub)"
1503 " JOIN reserves_out ro"
1504 " USING (h_blind_ev)"
1505 " JOIN denominations denoms"
1506 " ON (coins.denom_pub_hash = denoms.denom_pub_hash)"
1507 " WHERE payback_uuid>=$1"
1508 " ORDER BY payback_uuid ASC;",
1509 1),
1510 /* Used in #postgres_select_payback_refresh_above_serial_id() to obtain
1511 payback-refresh transactions */
1512 GNUNET_PQ_make_prepare ("payback_refresh_get_incr",
1513 "SELECT"
1514 " payback_refresh_uuid"
1515 ",timestamp"
1516 ",rc.old_coin_pub"
1517 ",coin_pub"
1518 ",coin_sig"
1519 ",coin_blind"
1520 ",h_blind_ev"
1521 ",coins.denom_pub_hash"
1522 ",denoms.denom_pub"
1523 ",coins.denom_sig"
1524 ",amount_val"
1525 ",amount_frac"
1526 " FROM payback_refresh"
1527 " JOIN refresh_revealed_coins rrc"
1528 " ON (rrc.coin_ev = h_blind_ev)"
1529 " JOIN refresh_commitments rc"
1530 " ON (rrc.rc = rc.rc)"
1531 " JOIN known_coins coins"
1532 " USING (coin_pub)"
1533 " JOIN denominations denoms"
1534 " ON (coins.denom_pub_hash = denoms.denom_pub_hash)"
1535 " WHERE payback_refresh_uuid>=$1"
1536 " ORDER BY payback_refresh_uuid ASC;",
1537 1),
1538 /* Used in #postgres_select_reserve_closed_above_serial_id() to
1539 obtain information about closed reserves */
1540 GNUNET_PQ_make_prepare ("reserves_close_get_incr",
1541 "SELECT"
1542 " close_uuid"
1543 ",reserve_pub"
1544 ",execution_date"
1545 ",wtid"
1546 ",receiver_account"
1547 ",amount_val"
1548 ",amount_frac"
1549 ",closing_fee_val"
1550 ",closing_fee_frac"
1551 " FROM reserves_close"
1552 " WHERE close_uuid>=$1"
1553 " ORDER BY close_uuid ASC;",
1554 1),
1555 /* Used in #postgres_get_reserve_history() to obtain payback transactions
1556 for a reserve */
1557 GNUNET_PQ_make_prepare ("payback_by_reserve",
1558 "SELECT"
1559 " coin_pub"
1560 ",coin_sig"
1561 ",coin_blind"
1562 ",amount_val"
1563 ",amount_frac"
1564 ",timestamp"
1565 ",coins.denom_pub_hash"
1566 ",coins.denom_sig"
1567 " FROM payback"
1568 " JOIN known_coins coins"
1569 " USING (coin_pub)"
1570 " JOIN reserves_out ro"
1571 " USING (h_blind_ev)"
1572 " WHERE ro.reserve_pub=$1"
1573 " FOR UPDATE;",
1574 1),
1575 /* Used in #postgres_get_coin_transactions() to obtain payback transactions
1576 affecting old coins of refreshed coins */
1577 GNUNET_PQ_make_prepare ("payback_by_old_coin",
1578 "SELECT"
1579 " coin_pub"
1580 ",coin_sig"
1581 ",coin_blind"
1582 ",amount_val"
1583 ",amount_frac"
1584 ",timestamp"
1585 ",coins.denom_pub_hash"
1586 ",coins.denom_sig"
1587 ",payback_refresh_uuid"
1588 " FROM payback_refresh"
1589 " JOIN known_coins coins"
1590 " USING (coin_pub)"
1591 " WHERE h_blind_ev IN"
1592 " (SELECT rrc.h_coin_ev"
1593 " FROM refresh_commitments"
1594 " JOIN refresh_revealed_coins rrc"
1595 " USING (rc)"
1596 " WHERE old_coin_pub=$1)"
1597 " FOR UPDATE;",
1598 1),
1599 /* Used in #postgres_get_reserve_history() */
1600 GNUNET_PQ_make_prepare ("close_by_reserve",
1601 "SELECT"
1602 " amount_val"
1603 ",amount_frac"
1604 ",closing_fee_val"
1605 ",closing_fee_frac"
1606 ",execution_date"
1607 ",receiver_account"
1608 ",wtid"
1609 " FROM reserves_close"
1610 " WHERE reserve_pub=$1"
1611 " FOR UPDATE",
1612 1),
1613 /* Used in #postgres_get_expired_reserves() */
1614 GNUNET_PQ_make_prepare ("get_expired_reserves",
1615 "SELECT"
1616 " expiration_date"
1617 ",account_details"
1618 ",reserve_pub"
1619 ",current_balance_val"
1620 ",current_balance_frac"
1621 " FROM reserves"
1622 " WHERE expiration_date<=$1"
1623 " AND (current_balance_val != 0 "
1624 " OR current_balance_frac != 0)"
1625 " ORDER BY expiration_date ASC"
1626 " LIMIT 1;",
1627 1),
1628 /* Used in #postgres_get_coin_transactions() to obtain payback transactions
1629 for a coin */
1630 GNUNET_PQ_make_prepare ("payback_by_coin",
1631 "SELECT"
1632 " ro.reserve_pub"
1633 ",coin_sig"
1634 ",coin_blind"
1635 ",amount_val"
1636 ",amount_frac"
1637 ",timestamp"
1638 ",coins.denom_pub_hash"
1639 ",coins.denom_sig"
1640 ",payback_uuid"
1641 " FROM payback"
1642 " JOIN known_coins coins"
1643 " USING (coin_pub)"
1644 " JOIN reserves_out ro"
1645 " USING (h_blind_ev)"
1646 " WHERE payback.coin_pub=$1"
1647 " FOR UPDATE;",
1648 1),
1649 /* Used in #postgres_get_coin_transactions() to obtain payback transactions
1650 for a refreshed coin */
1651 GNUNET_PQ_make_prepare ("payback_by_refreshed_coin",
1652 "SELECT"
1653 " rc.old_coin_pub"
1654 ",coin_sig"
1655 ",coin_blind"
1656 ",amount_val"
1657 ",amount_frac"
1658 ",timestamp"
1659 ",coins.denom_pub_hash"
1660 ",coins.denom_sig"
1661 ",payback_refresh_uuid"
1662 " FROM payback_refresh"
1663 " JOIN refresh_revealed_coins rrc"
1664 " ON (rrc.coin_ev = h_blind_ev)"
1665 " JOIN refresh_commitments rc"
1666 " ON (rrc.rc = rc.rc)"
1667 " JOIN known_coins coins"
1668 " USING (coin_pub)"
1669 " WHERE coin_pub=$1"
1670 " FOR UPDATE;",
1671 1),
1672 /* Used in #postgres_get_reserve_by_h_blind() */
1673 GNUNET_PQ_make_prepare ("reserve_by_h_blind",
1674 "SELECT"
1675 " reserve_pub"
1676 " FROM reserves_out"
1677 " WHERE h_blind_ev=$1"
1678 " LIMIT 1"
1679 " FOR UPDATE;",
1680 1),
1681 /* Used in #postgres_get_old_coin_by_h_blind() */
1682 GNUNET_PQ_make_prepare ("old_coin_by_h_blind",
1683 "SELECT"
1684 " rcom.old_coin_pub"
1685 " FROM refresh_revealed_coins"
1686 " JOIN refresh_commitments rcom"
1687 " USING (rc)"
1688 " WHERE h_coin_ev=$1"
1689 " LIMIT 1"
1690 " FOR UPDATE;",
1691 1),
1692 /* used in #postgres_commit */
1693 GNUNET_PQ_make_prepare ("do_commit",
1694 "COMMIT",
1695 0),
1696 GNUNET_PQ_PREPARED_STATEMENT_END
1697 };
1769 1698
1699 db_conn = GNUNET_PQ_connect (pc->connection_cfg_str,
1700 es,
1701 ps);
1702 }
1703 if (NULL == db_conn)
1704 return NULL;
1770 session = GNUNET_new (struct TALER_EXCHANGEDB_Session); 1705 session = GNUNET_new (struct TALER_EXCHANGEDB_Session);
1771 session->conn = db_conn; 1706 session->conn = db_conn;
1772 if (0 != pthread_setspecific (pc->db_conn_threadlocal, 1707 if (0 != pthread_setspecific (pc->db_conn_threadlocal,
1773 session)) 1708 session))
1774 { 1709 {
1775 GNUNET_break (0); 1710 GNUNET_break (0);
1776 PQfinish (db_conn); 1711 GNUNET_PQ_disconnect (db_conn);
1777 GNUNET_free (session); 1712 GNUNET_free (session);
1778 return NULL; 1713 return NULL;
1779 } 1714 }
@@ -1787,7 +1722,7 @@ postgres_get_session (void *cls)
1787 * @param cls the `struct PostgresClosure` with the plugin-specific state 1722 * @param cls the `struct PostgresClosure` with the plugin-specific state
1788 * @param session the database connection 1723 * @param session the database connection
1789 * @param name unique name identifying the transaction (for debugging) 1724 * @param name unique name identifying the transaction (for debugging)
1790 * must point to a constant 1725 * must point to a constant
1791 * @return #GNUNET_OK on success 1726 * @return #GNUNET_OK on success
1792 */ 1727 */
1793static int 1728static int
@@ -1795,25 +1730,22 @@ postgres_start (void *cls,
1795 struct TALER_EXCHANGEDB_Session *session, 1730 struct TALER_EXCHANGEDB_Session *session,
1796 const char *name) 1731 const char *name)
1797{ 1732{
1798 PGresult *result; 1733 struct GNUNET_PQ_ExecuteStatement es[] = {
1799 ExecStatusType ex; 1734 GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"),
1735 GNUNET_PQ_EXECUTE_STATEMENT_END
1736 };
1800 1737
1801 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1738 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1802 "Starting transaction on %p\n", 1739 "Starting transaction on %p\n",
1803 session->conn); 1740 session->conn);
1804 result = PQexec (session->conn, 1741 if (GNUNET_OK !=
1805 "START TRANSACTION ISOLATION LEVEL SERIALIZABLE"); 1742 GNUNET_PQ_exec_statements (session->conn,
1806 if (PGRES_COMMAND_OK != 1743 es))
1807 (ex = PQresultStatus (result)))
1808 { 1744 {
1809 TALER_LOG_ERROR ("Failed to start transaction (%s): %s\n", 1745 TALER_LOG_ERROR ("Failed to start transaction\n");
1810 PQresStatus (ex),
1811 PQerrorMessage (session->conn));
1812 GNUNET_break (0); 1746 GNUNET_break (0);
1813 PQclear (result);
1814 return GNUNET_SYSERR; 1747 return GNUNET_SYSERR;
1815 } 1748 }
1816 PQclear (result);
1817 session->transaction_name = name; 1749 session->transaction_name = name;
1818 return GNUNET_OK; 1750 return GNUNET_OK;
1819} 1751}
@@ -1830,16 +1762,17 @@ static void
1830postgres_rollback (void *cls, 1762postgres_rollback (void *cls,
1831 struct TALER_EXCHANGEDB_Session *session) 1763 struct TALER_EXCHANGEDB_Session *session)
1832{ 1764{
1833 PGresult *result; 1765 struct GNUNET_PQ_ExecuteStatement es[] = {
1766 GNUNET_PQ_make_execute ("ROLLBACK"),
1767 GNUNET_PQ_EXECUTE_STATEMENT_END
1768 };
1834 1769
1835 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1836 "Rolling back transaction on %p\n", 1771 "Rolling back transaction on %p\n",
1837 session->conn); 1772 session->conn);
1838 result = PQexec (session->conn, 1773 GNUNET_break (GNUNET_OK ==
1839 "ROLLBACK"); 1774 GNUNET_PQ_exec_statements (session->conn,
1840 GNUNET_break (PGRES_COMMAND_OK == 1775 es));
1841 PQresultStatus (result));
1842 PQclear (result);
1843 session->transaction_name = NULL; 1776 session->transaction_name = NULL;
1844} 1777}
1845 1778
@@ -1880,15 +1813,16 @@ static void
1880postgres_preflight (void *cls, 1813postgres_preflight (void *cls,
1881 struct TALER_EXCHANGEDB_Session *session) 1814 struct TALER_EXCHANGEDB_Session *session)
1882{ 1815{
1883 PGresult *result; 1816 struct GNUNET_PQ_ExecuteStatement es[] = {
1884 ExecStatusType status; 1817 GNUNET_PQ_make_execute ("COMMIT"),
1818 GNUNET_PQ_EXECUTE_STATEMENT_END
1819 };
1885 1820
1886 if (NULL == session->transaction_name) 1821 if (NULL == session->transaction_name)
1887 return; /* all good */ 1822 return; /* all good */
1888 result = PQexec (session->conn, 1823 if (GNUNET_OK ==
1889 "COMMIT"); 1824 GNUNET_PQ_exec_statements (session->conn,
1890 status = PQresultStatus (result); 1825 es))
1891 if (PGRES_COMMAND_OK == status)
1892 { 1826 {
1893 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1827 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1894 "BUG: Preflight check committed transaction `%s'!\n", 1828 "BUG: Preflight check committed transaction `%s'!\n",
@@ -1901,7 +1835,6 @@ postgres_preflight (void *cls,
1901 session->transaction_name); 1835 session->transaction_name);
1902 } 1836 }
1903 session->transaction_name = NULL; 1837 session->transaction_name = NULL;
1904 PQclear (result);
1905} 1838}
1906 1839
1907 1840
@@ -2664,7 +2597,7 @@ add_bank_to_exchange (void *cls,
2664 tail = append_rh (rhc); 2597 tail = append_rh (rhc);
2665 tail->type = TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE; 2598 tail->type = TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE;
2666 tail->details.bank = bt; 2599 tail->details.bank = bt;
2667 } /* end of 'while (0 < rows)' */ 2600 } /* end of 'while (0 < rows)' */
2668} 2601}
2669 2602
2670 2603
@@ -2781,7 +2714,7 @@ add_payback (void *cls,
2781 tail = append_rh (rhc); 2714 tail = append_rh (rhc);
2782 tail->type = TALER_EXCHANGEDB_RO_PAYBACK_COIN; 2715 tail->type = TALER_EXCHANGEDB_RO_PAYBACK_COIN;
2783 tail->details.payback = payback; 2716 tail->details.payback = payback;
2784 } /* end of 'while (0 < rows)' */ 2717 } /* end of 'while (0 < rows)' */
2785} 2718}
2786 2719
2787 2720
@@ -2837,7 +2770,7 @@ add_exchange_to_bank (void *cls,
2837 tail = append_rh (rhc); 2770 tail = append_rh (rhc);
2838 tail->type = TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK; 2771 tail->type = TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK;
2839 tail->details.closing = closing; 2772 tail->details.closing = closing;
2840 } /* end of 'while (0 < rows)' */ 2773 } /* end of 'while (0 < rows)' */
2841} 2774}
2842 2775
2843 2776
@@ -2998,7 +2931,7 @@ postgres_have_deposit (void *cls,
2998 expand the API with a 'get_deposit' function to return the 2931 expand the API with a 'get_deposit' function to return the
2999 original transaction details to be used for an error message 2932 original transaction details to be used for an error message
3000 in the future!) #3838 */ 2933 in the future!) #3838 */
3001 return 0; /* Counts as if the transaction was not there */ 2934 return 0; /* Counts as if the transaction was not there */
3002 } 2935 }
3003 return 1; 2936 return 1;
3004} 2937}
@@ -3495,7 +3428,7 @@ postgres_ensure_coin_known (void *cls,
3495 if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) 3428 if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
3496 { 3429 {
3497 GNUNET_CRYPTO_rsa_signature_free (known_coin.denom_sig.rsa_signature); 3430 GNUNET_CRYPTO_rsa_signature_free (known_coin.denom_sig.rsa_signature);
3498 return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; /* no change! */ 3431 return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; /* no change! */
3499 } 3432 }
3500 GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs); 3433 GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs);
3501 /* if not known, insert it */ 3434 /* if not known, insert it */
@@ -3505,7 +3438,7 @@ postgres_ensure_coin_known (void *cls,
3505 if (0 >= qs) 3438 if (0 >= qs)
3506 { 3439 {
3507 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) 3440 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
3508 qs = GNUNET_DB_STATUS_HARD_ERROR; /* should be impossible */ 3441 qs = GNUNET_DB_STATUS_HARD_ERROR; /* should be impossible */
3509 GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); 3442 GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
3510 return qs; 3443 return qs;
3511 } 3444 }
@@ -3729,8 +3662,8 @@ postgres_select_refunds_by_coin (void *cls,
3729 * @param session database handle to use, NULL if not run in any transaction 3662 * @param session database handle to use, NULL if not run in any transaction
3730 * @param rc commitment hash to use to locate the operation 3663 * @param rc commitment hash to use to locate the operation
3731 * @param[out] refresh_melt where to store the result; note that 3664 * @param[out] refresh_melt where to store the result; note that
3732 * refresh_melt->session.coin.denom_sig will be set to NULL 3665 * refresh_melt->session.coin.denom_sig will be set to NULL
3733 * and is not fetched by this routine (as it is not needed by the client) 3666 * and is not fetched by this routine (as it is not needed by the client)
3734 * @return transaction status 3667 * @return transaction status
3735 */ 3668 */
3736static enum GNUNET_DB_QueryStatus 3669static enum GNUNET_DB_QueryStatus
@@ -4055,7 +3988,7 @@ postgres_get_refresh_reveal (void *cls,
4055 case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: 3988 case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
4056 goto cleanup; 3989 goto cleanup;
4057 case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: 3990 case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
4058 default: /* can have more than one result */ 3991 default: /* can have more than one result */
4059 break; 3992 break;
4060 } 3993 }
4061 switch (grctx.qs) 3994 switch (grctx.qs)
@@ -4064,7 +3997,7 @@ postgres_get_refresh_reveal (void *cls,
4064 case GNUNET_DB_STATUS_SOFT_ERROR: 3997 case GNUNET_DB_STATUS_SOFT_ERROR:
4065 goto cleanup; 3998 goto cleanup;
4066 case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: 3999 case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
4067 case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: /* should be impossible */ 4000 case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: /* should be impossible */
4068 break; 4001 break;
4069 } 4002 }
4070 4003
@@ -5038,7 +4971,7 @@ postgres_lookup_wire_transfer (void *cls,
5038 * @param cb function to call with the result 4971 * @param cb function to call with the result
5039 * @param cb_cls closure to pass to @a cb 4972 * @param cb_cls closure to pass to @a cb
5040 * @return transaction status code 4973 * @return transaction status code
5041- */ 4974 - */
5042static enum GNUNET_DB_QueryStatus 4975static enum GNUNET_DB_QueryStatus
5043postgres_wire_lookup_deposit_wtid (void *cls, 4976postgres_wire_lookup_deposit_wtid (void *cls,
5044 struct TALER_EXCHANGEDB_Session *session, 4977 struct TALER_EXCHANGEDB_Session *session,
@@ -5121,7 +5054,7 @@ postgres_wire_lookup_deposit_wtid (void *cls,
5121 if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) 5054 if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
5122 { 5055 {
5123 /* Ok, we're aware of the transaction, but it has not yet been 5056 /* Ok, we're aware of the transaction, but it has not yet been
5124 executed */ 5057 executed */
5125 cb (cb_cls, 5058 cb (cb_cls,
5126 NULL, 5059 NULL,
5127 &amount_with_fee, 5060 &amount_with_fee,
@@ -5618,8 +5551,10 @@ static int
5618postgres_start_deferred_wire_out (void *cls, 5551postgres_start_deferred_wire_out (void *cls,
5619 struct TALER_EXCHANGEDB_Session *session) 5552 struct TALER_EXCHANGEDB_Session *session)
5620{ 5553{
5621 PGresult *result; 5554 struct GNUNET_PQ_ExecuteStatement es[] = {
5622 ExecStatusType ex; 5555 GNUNET_PQ_make_execute ("SET CONSTRAINTS wire_out_ref DEFERRED"),
5556 GNUNET_PQ_EXECUTE_STATEMENT_END
5557 };
5623 5558
5624 postgres_preflight (cls, 5559 postgres_preflight (cls,
5625 session); 5560 session);
@@ -5628,22 +5563,17 @@ postgres_start_deferred_wire_out (void *cls,
5628 session, 5563 session,
5629 "deferred wire out")) 5564 "deferred wire out"))
5630 return GNUNET_SYSERR; 5565 return GNUNET_SYSERR;
5631 result = PQexec (session->conn, 5566 if (GNUNET_OK !=
5632 "SET CONSTRAINTS wire_out_ref DEFERRED"); 5567 GNUNET_PQ_exec_statements (session->conn,
5633 if (PGRES_COMMAND_OK != 5568 es))
5634 (ex = PQresultStatus (result)))
5635 { 5569 {
5636 TALER_LOG_ERROR ( 5570 TALER_LOG_ERROR (
5637 "Failed to defer wire_out_ref constraint on transaction (%s): %s\n", 5571 "Failed to defer wire_out_ref constraint on transaction\n");
5638 PQresStatus (ex),
5639 PQerrorMessage (session->conn));
5640 GNUNET_break (0); 5572 GNUNET_break (0);
5641 PQclear (result);
5642 postgres_rollback (cls, 5573 postgres_rollback (cls,
5643 session); 5574 session);
5644 return GNUNET_SYSERR; 5575 return GNUNET_SYSERR;
5645 } 5576 }
5646 PQclear (result);
5647 return GNUNET_OK; 5577 return GNUNET_OK;
5648} 5578}
5649 5579
@@ -5711,7 +5641,7 @@ postgres_gc (void *cls)
5711 TALER_PQ_query_param_absolute_time (&long_ago), 5641 TALER_PQ_query_param_absolute_time (&long_ago),
5712 GNUNET_PQ_query_param_end 5642 GNUNET_PQ_query_param_end
5713 }; 5643 };
5714 PGconn *conn; 5644 struct GNUNET_PQ_Context *conn;
5715 int ret; 5645 int ret;
5716 5646
5717 now = GNUNET_TIME_absolute_get (); 5647 now = GNUNET_TIME_absolute_get ();
@@ -5723,35 +5653,60 @@ postgres_gc (void *cls)
5723 GNUNET_TIME_relative_multiply ( 5653 GNUNET_TIME_relative_multiply (
5724 GNUNET_TIME_UNIT_YEARS, 5654 GNUNET_TIME_UNIT_YEARS,
5725 10)); 5655 10));
5726 /* FIXME: use GNUNET_PQ_connect_with_cfg instead? */
5727 conn = GNUNET_PQ_connect (pg->connection_cfg_str);
5728 if (NULL == conn)
5729 return GNUNET_SYSERR;
5730 ret = postgres_prepare (conn);
5731 if (GNUNET_OK == ret)
5732 { 5656 {
5733 if ( 5657 struct GNUNET_PQ_PreparedStatement ps[] = {
5734 (0 > GNUNET_PQ_eval_prepared_non_select (conn, 5658 /* Used in #postgres_gc() */
5735 "gc_reserves", 5659 GNUNET_PQ_make_prepare ("gc_prewire",
5736 params_time)) || 5660 "DELETE"
5737 (0 > GNUNET_PQ_eval_prepared_non_select (conn, 5661 " FROM prewire"
5738 "gc_prewire", 5662 " WHERE finished=true;",
5739 params_none)) || 5663 0),
5740 (0 > GNUNET_PQ_eval_prepared_non_select (conn, 5664 GNUNET_PQ_make_prepare ("gc_reserves",
5741 "gc_wire_fee", 5665 "DELETE"
5742 params_ancient_time)) 5666 " FROM reserves"
5743 ) 5667 " WHERE gc_date < $1"
5744 ret = GNUNET_SYSERR; 5668 " AND current_balance_val = 0"
5745 /* This one may fail due to foreign key constraints from 5669 " AND current_balance_frac = 0;",
5746 payback and reserves_out tables to known_coins; these 5670 1),
5747 are NOT using 'ON DROP CASCADE' and might keep denomination 5671 GNUNET_PQ_make_prepare ("gc_wire_fee",
5748 keys alive for a bit longer, thus causing this statement 5672 "DELETE"
5749 to fail. */ 5673 " FROM wire_fee"
5750 (void) GNUNET_PQ_eval_prepared_non_select (conn, 5674 " WHERE end_date < $1;",
5751 "gc_denominations", 5675 1),
5752 params_time); 5676 GNUNET_PQ_make_prepare ("gc_denominations",
5677 "DELETE"
5678 " FROM denominations"
5679 " WHERE expire_legal < $1;",
5680 1),
5681 GNUNET_PQ_PREPARED_STATEMENT_END
5682 };
5683
5684 conn = GNUNET_PQ_connect (pg->connection_cfg_str,
5685 NULL,
5686 ps);
5753 } 5687 }
5754 PQfinish (conn); 5688 if (NULL == conn)
5689 return GNUNET_SYSERR;
5690 ret = GNUNET_OK;
5691 if ( (0 > GNUNET_PQ_eval_prepared_non_select (conn,
5692 "gc_reserves",
5693 params_time)) ||
5694 (0 > GNUNET_PQ_eval_prepared_non_select (conn,
5695 "gc_prewire",
5696 params_none)) ||
5697 (0 > GNUNET_PQ_eval_prepared_non_select (conn,
5698 "gc_wire_fee",
5699 params_ancient_time)) )
5700 ret = GNUNET_SYSERR;
5701 /* This one may fail due to foreign key constraints from
5702 payback and reserves_out tables to known_coins; these
5703 are NOT using 'ON DROP CASCADE' and might keep denomination
5704 keys alive for a bit longer, thus causing this statement
5705 to fail. */
5706 (void) GNUNET_PQ_eval_prepared_non_select (conn,
5707 "gc_denominations",
5708 params_time);
5709 GNUNET_PQ_disconnect (conn);
5755 return ret; 5710 return ret;
5756} 5711}
5757 5712