diff options
Diffstat (limited to 'src/exchangedb/plugin_exchangedb_postgres.c')
-rw-r--r-- | src/exchangedb/plugin_exchangedb_postgres.c | 2559 |
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 | */ | ||
541 | static int | ||
542 | postgres_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 | |||
1692 | db_conn_destroy (void *cls) | 535 | db_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 * | |||
1714 | postgres_get_session (void *cls) | 558 | postgres_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 | */ |
1793 | static int | 1728 | static 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 | |||
1830 | postgres_rollback (void *cls, | 1762 | postgres_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 | |||
1880 | postgres_preflight (void *cls, | 1813 | postgres_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 | */ |
3736 | static enum GNUNET_DB_QueryStatus | 3669 | static 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 | - */ |
5042 | static enum GNUNET_DB_QueryStatus | 4975 | static enum GNUNET_DB_QueryStatus |
5043 | postgres_wire_lookup_deposit_wtid (void *cls, | 4976 | postgres_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 | |||
5618 | postgres_start_deferred_wire_out (void *cls, | 5551 | postgres_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 | ||