diff options
author | Christian Grothoff <grothoff@gnunet.org> | 2023-12-10 00:55:49 +0900 |
---|---|---|
committer | Christian Grothoff <grothoff@gnunet.org> | 2023-12-10 00:55:49 +0900 |
commit | cfdbc9a3c3fba99982beaf156794cb51494e0c3f (patch) | |
tree | 07052b2458b21ecb21a8be031f9c23756968716c | |
parent | 1a9f82e0e5e85e81f3381d32730855d4c4880c56 (diff) | |
parent | 25f93cf043632f520954aa2adcc8afa38a5c92f2 (diff) |
Merge branch 'master' of git+ssh://git.taler.net/exchange
-rw-r--r-- | src/exchange/taler-exchange-httpd_batch-deposit.c | 50 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_db.c | 11 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_responses.c | 22 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_responses.h | 21 | ||||
-rw-r--r-- | src/exchangedb/exchange_do_deposit.sql | 1 | ||||
-rw-r--r-- | src/exchangedb/exchange_do_insert_or_update_policy_details.sql | 6 | ||||
-rw-r--r-- | src/exchangedb/pg_do_deposit.c | 1 | ||||
-rw-r--r-- | src/include/taler_extensions_policy.h | 2 | ||||
-rw-r--r-- | src/util/exchange_signatures.c | 3 |
9 files changed, 91 insertions, 26 deletions
diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c b/src/exchange/taler-exchange-httpd_batch-deposit.c index 9f66a99a4..835a974fc 100644 --- a/src/exchange/taler-exchange-httpd_batch-deposit.c +++ b/src/exchange/taler-exchange-httpd_batch-deposit.c @@ -60,16 +60,24 @@ struct BatchDepositContext */ struct TALER_EXCHANGEDB_BatchDeposit bd; + /** - * Additional details for policy extension relevant for this - * deposit operation, possibly NULL! + * Total amount that is accumulated with this deposit, + * without fee. */ - json_t *policy_json; + struct TALER_Amount accumulated_total_without_fee; /** - * Hash over the merchant's payto://-URI with the wire salt. + * True, if no policy was present in the request. Then + * @e policy_json is NULL and @e h_policy will be all zero. */ - struct TALER_MerchantWireHashP h_wire; + bool has_no_policy; + + /** + * Additional details for policy extension relevant for this + * deposit operation, possibly NULL! + */ + json_t *policy_json; /** * If @e policy_json was present, the corresponding policy extension @@ -84,6 +92,11 @@ struct BatchDepositContext struct TALER_ExtensionPolicyHashP h_policy; /** + * Hash over the merchant's payto://-URI with the wire salt. + */ + struct TALER_MerchantWireHashP h_wire; + + /** * When @e policy_details are persisted, this contains the id of the record * in the policy_details table. */ @@ -121,11 +134,11 @@ reply_batch_deposit_success ( &TEH_keys_exchange_sign_, &bd->h_contract_terms, &dc->h_wire, - NULL != dc->policy_json ? &dc->h_policy : NULL, + dc->has_no_policy ? NULL : &dc->h_policy, dc->exchange_timestamp, bd->wire_deadline, bd->refund_deadline, - &dc->policy_details.accumulated_total, /* excludes fees */ + &dc->accumulated_total_without_fee, bd->num_cdis, csigs, &dc->bd.merchant_pub, @@ -176,13 +189,13 @@ batch_deposit_transaction (void *cls, /* If the deposit has a policy associated to it, persist it. This will * insert or update the record. */ - if (NULL != dc->policy_json) + if (! dc->has_no_policy) { qs = TEH_plugin->persist_policy_details ( TEH_plugin->cls, &dc->policy_details, &dc->bd.policy_details_serial_id, - &dc->policy_details.accumulated_total, + &dc->accumulated_total_without_fee, &dc->policy_details.fulfillment_state); if (qs < 0) return qs; @@ -237,13 +250,13 @@ batch_deposit_transaction (void *cls, in_conflict ? "in conflict" : "no conflict"); if (in_conflict) { - /* FIXME: #7267 conflicting contract != insufficient funds */ + /* FIXME: #8002 conflicting contract != insufficient funds */ *mhd_ret = TEH_RESPONSE_reply_coin_insufficient_funds ( connection, TALER_EC_EXCHANGE_DEPOSIT_CONFLICTING_CONTRACT, - &bd->cdis[0 /* SEE FIXME-#7267 Oec above! */].coin.denom_pub_hash, - &bd->cdis[0 /* SEE FIXME-#7267 Oec above! */].coin.coin_pub); + &bd->cdis[0 /* SEE FIXME-#8002 Oec above! */].coin.denom_pub_hash, + &bd->cdis[0 /* SEE FIXME-#8002 Oec above! */].coin.coin_pub); return GNUNET_DB_STATUS_HARD_ERROR; } if (! balance_ok) @@ -495,7 +508,7 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_json ("policy", &dc.policy_json), - NULL), + &dc.has_no_policy), GNUNET_JSON_spec_timestamp ("timestamp", &bd->wallet_timestamp), GNUNET_JSON_spec_mark_optional ( @@ -571,8 +584,12 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, &bd->wire_salt, &dc.h_wire); + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (TEH_currency, + &dc.accumulated_total_without_fee)); + /* handle policy, if present */ - if (NULL != dc.policy_json) + if (! dc.has_no_policy) { const char *error_hint = NULL; @@ -641,10 +658,11 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, &amount_without_fee, &cdis[i].amount_with_fee, &deposit_fees[i])); + GNUNET_assert (0 <= TALER_amount_add ( - &dc.policy_details.accumulated_total, - &dc.policy_details.accumulated_total, + &dc.accumulated_total_without_fee, + &dc.accumulated_total_without_fee, &amount_without_fee)); } if (GNUNET_OK != res) diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 5660074ee..a00a97856 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -37,14 +37,14 @@ TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin, { enum TALER_EXCHANGEDB_CoinKnownStatus cks; struct TALER_DenominationHashP h_denom_pub; - struct TALER_AgeCommitmentHash age_hash; + struct TALER_AgeCommitmentHash h_age_commitment; /* make sure coin is 'known' in database */ cks = TEH_plugin->ensure_coin_known (TEH_plugin->cls, coin, known_coin_id, &h_denom_pub, - &age_hash); + &h_age_commitment); switch (cks) { case TALER_EXCHANGEDB_CKS_ADDED: @@ -70,13 +70,12 @@ TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin, &coin->coin_pub); return GNUNET_DB_STATUS_HARD_ERROR; case TALER_EXCHANGEDB_CKS_AGE_CONFLICT: - /* FIXME: insufficient_funds != Age conflict! See issue #7267, need new - * strategy for evidence gathering */ - *mhd_ret = TEH_RESPONSE_reply_coin_insufficient_funds ( + *mhd_ret = TEH_RESPONSE_reply_coin_age_commitment_conflict ( connection, TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_AGE_HASH, &h_denom_pub, - &coin->coin_pub); + &coin->coin_pub, + &h_age_commitment); return GNUNET_DB_STATUS_HARD_ERROR; } GNUNET_assert (0); diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 322da3877..c1aa9db6f 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -178,6 +178,28 @@ TEH_RESPONSE_reply_coin_insufficient_funds ( MHD_RESULT +TEH_RESPONSE_reply_coin_age_commitment_conflict ( + struct MHD_Connection *connection, + enum TALER_ErrorCode ec, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_AgeCommitmentHash *h_age_commitment_hash) +{ + return TALER_MHD_REPLY_JSON_PACK ( + connection, + TALER_ErrorCode_get_http_status_safe (ec), + TALER_JSON_pack_ec (ec), + GNUNET_JSON_pack_data_auto ("coin_pub", + coin_pub), + GNUNET_JSON_pack_data_auto ("h_denom_pub", + h_denom_pub), + GNUNET_JSON_pack_data_auto ("h_age_commitment_hash", + h_age_commitment_hash) + ); +} + + +MHD_RESULT TEH_RESPONSE_reply_reserve_insufficient_balance ( struct MHD_Connection *connection, enum TALER_ErrorCode ec, diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h index 8adf1136b..5fe106e17 100644 --- a/src/exchange/taler-exchange-httpd_responses.h +++ b/src/exchange/taler-exchange-httpd_responses.h @@ -160,6 +160,27 @@ TEH_RESPONSE_reply_coin_insufficient_funds ( const struct TALER_CoinSpendPublicKeyP *coin_pub); /** + * Send proof that a request is invalid to client because of + * a conflicting value for the age commitment hash of a coin. + * This function will create a message with the conflicting + * hash value for the age commitment of the given coin. + * + * @param connection connection to the client + * @param ec error code to return + * @param h_denom_pub hash of the denomination of the coin + * @param coin_pub public key of the coin + * @param h_age_commitment hash of the age commitment as found in the database + * @return MHD result code + */ +MHD_RESULT +TEH_RESPONSE_reply_coin_age_commitment_conflict ( + struct MHD_Connection *connection, + enum TALER_ErrorCode ec, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_AgeCommitmentHash *h_age_commitment); + +/** * Fundamental details about a purse. */ struct TEH_PurseDetails diff --git a/src/exchangedb/exchange_do_deposit.sql b/src/exchangedb/exchange_do_deposit.sql index 1156c7de5..7116117ff 100644 --- a/src/exchangedb/exchange_do_deposit.sql +++ b/src/exchangedb/exchange_do_deposit.sql @@ -142,6 +142,7 @@ THEN IF NOT FOUND THEN -- Deposit exists, but with *strange* differences. Not allowed. + -- FIXME #8002: Surely we need to provide the client more data in this case. out_conflict=TRUE; RETURN; END IF; diff --git a/src/exchangedb/exchange_do_insert_or_update_policy_details.sql b/src/exchangedb/exchange_do_insert_or_update_policy_details.sql index 53cd2989e..85e52d3d3 100644 --- a/src/exchangedb/exchange_do_insert_or_update_policy_details.sql +++ b/src/exchangedb/exchange_do_insert_or_update_policy_details.sql @@ -93,14 +93,14 @@ BEGIN -- Set the fulfillment_state according to the values. -- For now, we only update the state when it was INSUFFICIENT. - -- FIXME: What to do in case of Failure or other state? - IF (out_fullfillment_state = 1) -- INSUFFICIENT + -- FIXME[oec] #7999: What to do in case of Failure or other state? + IF (out_fullfillment_state = 2) -- INSUFFICIENT THEN IF (out_accumulated_total.val >= cur_commitment.val OR (out_accumulated_total.val = cur_commitment.val AND out_accumulated_total.frac >= cur_commitment.frac)) THEN - out_fulfillment_state = 2; -- READY + out_fulfillment_state = 3; -- READY END IF; END IF; diff --git a/src/exchangedb/pg_do_deposit.c b/src/exchangedb/pg_do_deposit.c index 0ba45b628..64e7886a7 100644 --- a/src/exchangedb/pg_do_deposit.c +++ b/src/exchangedb/pg_do_deposit.c @@ -83,6 +83,7 @@ TEH_PG_do_deposit ( GNUNET_PQ_result_spec_uint32 ("insufficient_balance_coin_index", bad_balance_index), balance_ok), + /* FIXME #8002: We need more data to communicate the conflict to the client */ GNUNET_PQ_result_spec_bool ("conflicted", ctr_conflict), GNUNET_PQ_result_spec_end diff --git a/src/include/taler_extensions_policy.h b/src/include/taler_extensions_policy.h index 7750f58f1..b10c0d8a2 100644 --- a/src/include/taler_extensions_policy.h +++ b/src/include/taler_extensions_policy.h @@ -28,6 +28,8 @@ /* * @brief Describes the states of fulfillment of a policy bound to a deposit + * NOTE: These values must be in sync with their use in stored procedures, f.e. + * exchange_do_insert_or_update_policy_details. */ enum TALER_PolicyFulfillmentState { diff --git a/src/util/exchange_signatures.c b/src/util/exchange_signatures.c index bc5fe439f..aaefb5cec 100644 --- a/src/util/exchange_signatures.c +++ b/src/util/exchange_signatures.c @@ -120,7 +120,8 @@ TALER_exchange_online_deposit_confirmation_sign ( .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp), .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline), .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline), - .merchant_pub = *merchant_pub + .merchant_pub = *merchant_pub, + .h_policy = {{{0}}} }; struct GNUNET_HashContext *hc; |