From fabd4cfbc80c544d5ba2f3000031729fcb828123 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 23:21:00 +0200 Subject: skeleton for /refresh/-testing --- src/mint-lib/test_mint_api.c | 157 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 156 insertions(+), 1 deletion(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index 29ccd1e5..b8ae160f 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -81,7 +81,23 @@ enum OpCode /** * Deposit a coin (pay with it). */ - OC_DEPOSIT + OC_DEPOSIT, + + /** + * Melt a (set of) coins. + */ + OC_REFRESH_MELT, + + /** + * Complete melting session by withdrawing melted coins. + */ + OC_REFRESH_REVEAL, + + /** + * Verify mint's /refresh/link by linking original private key to + * results from #OC_REFRESH_REVEAL step. + */ + OC_REFRESH_LINK }; @@ -112,6 +128,9 @@ struct Command union { + /** + * Information for a #OC_ADMIN_ADD_INCOMING command. + */ struct { @@ -145,6 +164,9 @@ struct Command } admin_add_incoming; + /** + * Information for a #OC_WITHDRAW_STATUS command. + */ struct { @@ -166,8 +188,12 @@ struct Command } withdraw_status; + /** + * Information for a #OC_WITHDRAW_SIGN command. + */ struct { + /** * Which reserve should we withdraw from? */ @@ -210,6 +236,9 @@ struct Command } withdraw_sign; + /** + * Information for a #OC_DEPOSIT command. + */ struct { @@ -258,6 +287,117 @@ struct Command } deposit; + /** + * Information for a #OC_REFRESH_MELT command. + */ + struct + { + + /** + * Information about coins to be melted. + */ + struct + { + + /** + * Amount to melt (including fee). + */ + const char *amount; + + /** + * Reference to withdraw_sign operations for coin to + * be used for the /refresh/melt operation. + */ + const char *coin_ref; + + } *melted_coins; + + /** + * Which reserves should we withdraw the fresh coins from? + */ + const char **reserve_references; + + /** + * Melt handle while operation is running. + */ + struct TALER_MINT_RefreshMeltHandle *rmh; + + /** + * Data used in the refresh operation, set by the interpreter. + */ + char *refresh_data; + + /** + * Number of bytes in @e refresh_data, set by the interpreter. + */ + size_t refresh_data_length; + + /** + * Set by the interpreter (upon completion) to the noreveal + * index selected by the mint. + */ + uint16_t noreveal_index; + + } refresh_melt; + + /** + * Information for a #OC_REFRESH_REVEAL command. + */ + struct + { + + /** + * Melt operation this is the matching reveal for. + */ + const char *melt_ref; + + /** + * Number of fresh coins withdrawn, set by the interpreter. + * Length of the @e fresh_coins array. + */ + unsigned int num_fresh_coins; + + /** + * Information about coins withdrawn, set by the interpreter. + */ + struct + { + + /** + * If @e amount is NULL, this specifies the denomination key to + * use. Otherwise, this will be set (by the interpreter) to the + * denomination PK matching @e amount. + */ + const struct TALER_MINT_DenomPublicKey *pk; + + /** + * Set (by the interpreter) to the mint's signature over the + * coin's public key. + */ + struct TALER_DenominationSignature sig; + + /** + * Set (by the interpreter) to the coin's private key. + */ + struct TALER_CoinSpendPrivateKeyP coin_priv; + + } *fresh_coins; + + } refresh_reveal; + + /** + * Information for a #OC_REFRESH_LINK command. + */ + struct + { + + /** + * Reveal operation this is the matching link for. + */ + const char *reveal_ref; + + } refresh_link; + } details; }; @@ -1009,6 +1149,21 @@ interpreter_run (void *cls, trigger_context_task (); return; } + case OC_REFRESH_MELT: + /* not implemented */ + GNUNET_break (0); + is->ip++; + break; + case OC_REFRESH_REVEAL: + /* not implemented */ + GNUNET_break (0); + is->ip++; + break; + case OC_REFRESH_LINK: + /* not implemented */ + GNUNET_break (0); + is->ip++; + break; default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unknown instruction %d at %u (%s)\n", -- cgit v1.2.3 From e141a743f23158f1a4b7a4454adcc47d85819cf2 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 23:35:51 +0200 Subject: more skeleton code towards testing /refresh --- src/mint-lib/test_mint_api.c | 102 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 15 deletions(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index b8ae160f..0bed31de 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -102,6 +102,28 @@ enum OpCode }; +/** + * Structure specifying details about a coin to be melted. + * Used in a NULL-terminated array as part of command + * specification. + */ +struct MeltDetails +{ + + /** + * Amount to melt (including fee). + */ + const char *amount; + + /** + * Reference to withdraw_sign operations for coin to + * be used for the /refresh/melt operation. + */ + const char *coin_ref; + +}; + + /** * Details for a mint operation to execute. */ @@ -253,6 +275,12 @@ struct Command */ const char *coin_ref; + /** + * If this @e coin_ref refers to an operation that generated + * an array of coins, this value determines which coin to use. + */ + unsigned int coin_idx; + /** * JSON string describing the merchant's "wire details". */ @@ -296,21 +324,7 @@ struct Command /** * Information about coins to be melted. */ - struct - { - - /** - * Amount to melt (including fee). - */ - const char *amount; - - /** - * Reference to withdraw_sign operations for coin to - * be used for the /refresh/melt operation. - */ - const char *coin_ref; - - } *melted_coins; + struct MeltDetails *melted_coins; /** * Which reserves should we withdraw the fresh coins from? @@ -1391,6 +1405,24 @@ run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct InterpreterState *is; + static struct MeltDetails melt_coins_1[] = { + { "coin_ref1", "EUR:1.1" }, // FIXME: pick sensible values + { "coin_ref2", "EUR:1.1" }, // FIXME: pick sensible values + { "coin_ref3", "EUR:1.1" }, // FIXME: pick sensible values + { NULL, NULL } + }; + static const char *melt_fresh_reserves_1[] = { + "create-reserve-1", // FIXME: pick sensible values + "create-reserve-1", // FIXME: pick sensible values + "create-reserve-1", // FIXME: pick sensible values + NULL + }; + static const char *melt_fresh_reserves_2[] = { + "create-reserve-1", // FIXME: pick sensible values + "create-reserve-1", // FIXME: pick sensible values + "create-reserve-1", // FIXME: pick sensible values + NULL + }; static struct Command commands[] = { /* Fill reserve with EUR:5.01, as withdraw fee is 1 ct per config */ @@ -1458,6 +1490,46 @@ run (void *cls, .details.deposit.contract = "{ \"items\"={ \"name\":\"ice cream\", \"value\":2 } }", .details.deposit.transaction_id = 1 }, +#if FUTURE + /* Test running a successful melt operation */ + { .oc = OC_REFRESH_MELT, + .label = "melt-1", + .expected_response_code = MHD_HTTP_OK, + .details.refresh_melt.melted_coins = melt_coins_1, + .details.refresh_melt.reserve_references = melt_fresh_reserves_1 }, + + /* Complete (successful) melt operation, and withdraw the coins */ + { .oc = OC_REFRESH_REVEAL, + .label = "reveal-1", + .melt_ref = "melt-1", + .expected_response_code = MHD_HTTP_OK }, + + /* Test that /refresh/link works */ + { .oc = OC_REFRESH_LINK, + .label = "link-1", + .reveal_ref = "reveal-1", + .expected_response_code = MHD_HTTP_OK }, + + /* Test successfully spending coins from the refresh operation */ + { .oc = OC_DEPOSIT, + .label = "deposit-refreshed-1", + .expected_response_code = MHD_HTTP_OK, + .details.deposit.amount = "EUR:5", // FIXME: pick sensible value + .details.deposit.coin_ref = "reveal-1", + .details.deposit.coin_idx = 0, + .details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account\":42 }", + .details.deposit.contract = "{ \"items\"={ \"name\":\"ice cream\", \"value\":3 } }", + .details.deposit.transaction_id = 2 }, + + /* Test running a failing melt operation */ + { .oc = OC_REFRESH_MELT, + .label = "melt-2", + .expected_response_code = MHD_HTTP_FORBIDDEN, + .details.refresh_melt.melted_coins = melt_coins_1, + .details.refresh_melt.reserve_references = melt_fresh_reserves_2 }, + +#endif + { .oc = OC_END } }; -- cgit v1.2.3 From 6e6f0c48d556799766ab689b3e7ef37c234e05ba Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 14:55:38 +0200 Subject: implementing OC_REFRESH_MELT test command --- src/mint-lib/test_mint_api.c | 178 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 163 insertions(+), 15 deletions(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index 0bed31de..1722b29b 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -327,9 +327,9 @@ struct Command struct MeltDetails *melted_coins; /** - * Which reserves should we withdraw the fresh coins from? + * Denominations of the fresh coins to withdraw. */ - const char **reserve_references; + const char **fresh_amounts; /** * Melt handle while operation is running. @@ -825,7 +825,42 @@ deposit_cb (void *cls, is->ip++; is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, is); +} + + +/** + * Function called with the result of the /refresh/melt operation. + * + * @param cls closure with the interpreter state + * @param http_status HTTP response code, never #MHD_HTTP_OK (200) as for successful intermediate response this callback is skipped. + * 0 if the mint's reply is bogus (fails to follow the protocol) + * @param noreveal_index choice by the mint in the cut-and-choose protocol, + * UINT16_MAX on error + * @param full_response full response from the mint (for logging, in case of errors) + */ +static void +melt_cb (void *cls, + unsigned int http_status, + uint16_t noreveal_index, + json_t *full_response) +{ + struct InterpreterState *is = cls; + struct Command *cmd = &is->commands[is->ip]; + cmd->details.refresh_melt.rmh = NULL; + if (cmd->expected_response_code != http_status) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u to command %s\n", + http_status, + cmd->label); + fail (is); + return; + } + cmd->details.refresh_melt.noreveal_index = noreveal_index; + is->ip++; + is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, + is); } @@ -1164,9 +1199,86 @@ interpreter_run (void *cls, return; } case OC_REFRESH_MELT: - /* not implemented */ - GNUNET_break (0); - is->ip++; + { + unsigned int num_melted_coins; + unsigned int num_fresh_coins; + + cmd->details.refresh_melt.noreveal_index = UINT16_MAX; + for (num_melted_coins=0; + NULL != cmd->details.refresh_melt.melted_coins[num_melted_coins]; + num_melted_coins++) ; + for (num_fresh_coins=0; + NULL != cmd->details.refresh_melt.fresh_amounts[num_fresh_coins]; + num_fresh_coins++) ; + + { + struct TALER_CoinSpendPrivateKeyP melt_privs[num_melted_coins]; + struct TALER_Amount melt_amounts[num_melted_coins]; + struct TALER_DenominationSignature melt_sigs[num_melted_coins]; + struct TALER_MINT_DenomPublicKey melt_pks[num_melted_coins]; + struct TALER_MINT_DenomPublicKey fresh_pks[num_fresh_coins]; + unsigned int i; + + for (i=0;idetails.refresh_melt.melted_coins[i]; + ref = find_command (is, + md->coin_ref); + GNUNET_assert (NULL != ref); + GNUNET_assert (OC_WITHDRAW_SIGN == ref_cmd->oc); + + melt_privs[i] = ref->details.withdraw_sign.coin_priv; + if (GNUNET_OK != + TALER_string_to_amount (md->amount, + &melt_amounts[i])) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to parse amount `%s' at %u\n", + md->amount, + is->ip); + fail (is); + return; + } + melt_sigs[i] = ref->details.withdraw_sign.sig; + melt_pks[i] = ref->details.withdraw_sign.pk; + } + for (i=0;ikeys, + cmd->details.refresh_melt.fresh_amounts[i]); + } + cmd->details.refresh_melt.refresh_data + = TALER_MINT_refresh_prepare (num_melted_coins, + melt_privs, + melt_amounts, + melt_sigs, + melt_pks, + GNUNET_YES, + num_fresh_coins, + fresh_pks, + &cmd->details.refresh_melt.refresh_data_length); + if (NULL == cmd->details.refresh_melt.refresh_data) + { + GNUNET_break (0); + fail (is); + return; + } + cmd->details.refresh_melt.rmh + = TALER_MINT_refresh_melt_execute (mint, + cmd->details.refresh_melt.refresh_data_length, + cmd->details.refresh_melt.refresh_data, + &melt_cb, + is); + if (NULL == cmd->details.refresh_melt.rmh) + { + GNUNET_break (0); + fail (is); + return; + } + trigger_context_task (); + return; + } + } break; case OC_REFRESH_REVEAL: /* not implemented */ @@ -1269,6 +1381,42 @@ do_shutdown (void *cls, cmd->details.deposit.dh = NULL; } break; + case OC_REFRESH_MELT: + if (NULL != cmd->details.refresh_melt.rmh) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Command %u (%s) did not complete\n", + i, + cmd->label); + TALER_MINT_refresh_melt_cancel (cmd->details.refresh_melt.rmh); + cmd->details.refresh_melt.rmh = NULL; + } + GNUNET_free_non_null (cmd->details.refresh_melt.refresh_data); + cmd->details.refresh_melt.refresh_data = NULL; + cmd->details.refresh_melt.refresh_data_length = 0; + break; + case OC_REFRESH_REVEAL: + if (NULL != cmd->details.refresh_reveal.rrh) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Command %u (%s) did not complete\n", + i, + cmd->label); + TALER_MINT_refresh_reveal_cancel (cmd->details.refresh_reveal.rrh); + cmd->details.refresh_reveal.rrh = NULL; + } + break; + case OC_REFRESH_LINK: + if (NULL != cmd->details.refresh_link.rl) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Command %u (%s) did not complete\n", + i, + cmd->label); + TALER_MINT_refresh_link_cancel (cmd->details.refresh_link.rlh); + cmd->details.refresh_link.rlh = NULL; + } + break; default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unknown instruction %d at %u (%s)\n", @@ -1411,16 +1559,16 @@ run (void *cls, { "coin_ref3", "EUR:1.1" }, // FIXME: pick sensible values { NULL, NULL } }; - static const char *melt_fresh_reserves_1[] = { - "create-reserve-1", // FIXME: pick sensible values - "create-reserve-1", // FIXME: pick sensible values - "create-reserve-1", // FIXME: pick sensible values + static const char *melt_fresh_amounts_1[] = { + "EUR:1", // FIXME: pick sensible values + "EUR:1", // FIXME: pick sensible values + "EUR:1", // FIXME: pick sensible values NULL }; - static const char *melt_fresh_reserves_2[] = { - "create-reserve-1", // FIXME: pick sensible values - "create-reserve-1", // FIXME: pick sensible values - "create-reserve-1", // FIXME: pick sensible values + static const char *melt_fresh_amounts_2[] = { + "EUR:1", // FIXME: pick sensible values + "EUR:1", // FIXME: pick sensible values + "EUR:1", // FIXME: pick sensible values NULL }; static struct Command commands[] = @@ -1496,7 +1644,7 @@ run (void *cls, .label = "melt-1", .expected_response_code = MHD_HTTP_OK, .details.refresh_melt.melted_coins = melt_coins_1, - .details.refresh_melt.reserve_references = melt_fresh_reserves_1 }, + .details.refresh_melt.fresh_amounts = melt_fresh_amounts_1 }, /* Complete (successful) melt operation, and withdraw the coins */ { .oc = OC_REFRESH_REVEAL, @@ -1526,7 +1674,7 @@ run (void *cls, .label = "melt-2", .expected_response_code = MHD_HTTP_FORBIDDEN, .details.refresh_melt.melted_coins = melt_coins_1, - .details.refresh_melt.reserve_references = melt_fresh_reserves_2 }, + .details.refresh_melt.fresh_amounts = melt_fresh_amounts_2 }, #endif -- cgit v1.2.3 From aaab2ed2d4de62b36f9e802978cd47a642bf90f0 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 15:24:02 +0200 Subject: fix FTBFS, towards implementing OC_REFRESH_REVEAL --- src/include/taler_mint_service.h | 10 ++-- src/mint-lib/test_mint_api.c | 105 +++++++++++++++++++++++++++++++++------ 2 files changed, 95 insertions(+), 20 deletions(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/include/taler_mint_service.h b/src/include/taler_mint_service.h index ea06d95f..8c5f520d 100644 --- a/src/include/taler_mint_service.h +++ b/src/include/taler_mint_service.h @@ -727,11 +727,11 @@ typedef void * In this case, neither callback will be called. */ struct TALER_MINT_RefreshMeltHandle * -TALER_MINT_refresh_melt_execute (struct TALER_MINT_Handle *mint, - size_t refresh_data_length, - const char *refresh_data, - TALER_MINT_RefreshMeltCallback melt_cb, - void *melt_cb_cls); +TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, + size_t refresh_data_length, + const char *refresh_data, + TALER_MINT_RefreshMeltCallback melt_cb, + void *melt_cb_cls); /** diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index 1722b29b..e5ac2b51 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -365,6 +365,11 @@ struct Command */ const char *melt_ref; + /** + * Reveal handle while operation is running. + */ + struct TALER_MINT_RefreshRevealHandle *rrh; + /** * Number of fresh coins withdrawn, set by the interpreter. * Length of the @e fresh_coins array. @@ -410,6 +415,11 @@ struct Command */ const char *reveal_ref; + /** + * Link handle while operation is running. + */ + struct TALER_MINT_RefreshLinkHandle *rlh; + } refresh_link; } details; @@ -864,6 +874,47 @@ melt_cb (void *cls, } +/** + * Function called with the result of the /refresh/reveal operation. + * + * @param cls closure with the interpreter state + * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request + * 0 if the mint's reply is bogus (fails to follow the protocol) + * @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed + * @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error + * @param sigs array of signature over @a num_coins coins, NULL on error + * @param full_response full response from the mint (for logging, in case of errors) + */ +static void +reveal_cb (void *cls, + unsigned int http_status, + unsigned int num_coins, + const struct TALER_CoinSpendPrivateKeyP *coin_privs, + const struct TALER_DenominationSignature *sigs, + json_t *full_response) +{ + struct InterpreterState *is = cls; + struct Command *cmd = &is->commands[is->ip]; + unsigned int i; + + cmd->details.refresh_reveal.rrh = NULL; + if (cmd->expected_response_code != http_status) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u to command %s\n", + http_status, + cmd->label); + fail (is); + return; + } + cmd->details.refresh_reveal.num_fresh_coins = num_coins; + // FIXME: init rest... + is->ip++; + is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, + is); +} + + /** * Find denomination key matching the given amount. * @@ -1205,7 +1256,7 @@ interpreter_run (void *cls, cmd->details.refresh_melt.noreveal_index = UINT16_MAX; for (num_melted_coins=0; - NULL != cmd->details.refresh_melt.melted_coins[num_melted_coins]; + NULL != cmd->details.refresh_melt.melted_coins[num_melted_coins].amount; num_melted_coins++) ; for (num_fresh_coins=0; NULL != cmd->details.refresh_melt.fresh_amounts[num_fresh_coins]; @@ -1225,7 +1276,7 @@ interpreter_run (void *cls, ref = find_command (is, md->coin_ref); GNUNET_assert (NULL != ref); - GNUNET_assert (OC_WITHDRAW_SIGN == ref_cmd->oc); + GNUNET_assert (OC_WITHDRAW_SIGN == ref->oc); melt_privs[i] = ref->details.withdraw_sign.coin_priv; if (GNUNET_OK != @@ -1240,12 +1291,23 @@ interpreter_run (void *cls, return; } melt_sigs[i] = ref->details.withdraw_sign.sig; - melt_pks[i] = ref->details.withdraw_sign.pk; + melt_pks[i] = *ref->details.withdraw_sign.pk; } for (i=0;ikeys, - cmd->details.refresh_melt.fresh_amounts[i]); + if (GNUNET_OK != + TALER_string_to_amount (cmd->details.refresh_melt.fresh_amounts[i], + &amount)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to parse amount `%s' at %u\n", + cmd->details.withdraw_sign.amount, + is->ip); + fail (is); + return; + } + fresh_pks[i] = *find_pk (is->keys, + &amount); } cmd->details.refresh_melt.refresh_data = TALER_MINT_refresh_prepare (num_melted_coins, @@ -1264,11 +1326,11 @@ interpreter_run (void *cls, return; } cmd->details.refresh_melt.rmh - = TALER_MINT_refresh_melt_execute (mint, - cmd->details.refresh_melt.refresh_data_length, - cmd->details.refresh_melt.refresh_data, - &melt_cb, - is); + = TALER_MINT_refresh_melt (mint, + cmd->details.refresh_melt.refresh_data_length, + cmd->details.refresh_melt.refresh_data, + &melt_cb, + is); if (NULL == cmd->details.refresh_melt.rmh) { GNUNET_break (0); @@ -1281,10 +1343,23 @@ interpreter_run (void *cls, } break; case OC_REFRESH_REVEAL: - /* not implemented */ - GNUNET_break (0); - is->ip++; - break; + ref = find_command (is, + cmd->details.refresh_reveal.melt_ref); + cmd->details.refresh_reveal.rrh + = TALER_MINT_refresh_reveal (mint, + ref->details.refresh_melt.refresh_data_length, + ref->details.refresh_melt.refresh_data, + ref->details.refresh_melt.noreveal_index, + &reveal_cb, + is); + if (NULL == cmd->details.refresh_reveal.rrh) + { + GNUNET_break (0); + fail (is); + return; + } + trigger_context_task (); + return; case OC_REFRESH_LINK: /* not implemented */ GNUNET_break (0); @@ -1407,7 +1482,7 @@ do_shutdown (void *cls, } break; case OC_REFRESH_LINK: - if (NULL != cmd->details.refresh_link.rl) + if (NULL != cmd->details.refresh_link.rlh) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Command %u (%s) did not complete\n", -- cgit v1.2.3 From 2ff3a5462cef04d8968d8f9cdaee486db99115f7 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 15:33:38 +0200 Subject: towards implementing OC_REFRESH_LINK --- src/mint-lib/test_mint_api.c | 110 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 102 insertions(+), 8 deletions(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index e5ac2b51..859d41c4 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -420,6 +420,11 @@ struct Command */ struct TALER_MINT_RefreshLinkHandle *rlh; + /** + * Which of the melted coins should be used for the linkage? + */ + unsigned int coin_idx; + } refresh_link; } details; @@ -908,7 +913,63 @@ reveal_cb (void *cls, return; } cmd->details.refresh_reveal.num_fresh_coins = num_coins; - // FIXME: init rest... + switch (http_status) + { + case MHD_HTTP_OK: + // FIXME: store returned coin keys... + break; + default: + break; + } + + is->ip++; + is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, + is); +} + + +/** + * Function called with the result of a /refresh/link operation. + * + * @param cls closure with the interpreter state + * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request + * 0 if the mint's reply is bogus (fails to follow the protocol) + * @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed + * @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error + * @param sigs array of signature over @a num_coins coins, NULL on error + * @param pubs array of public keys for the @a sigs, NULL on error + * @param full_response full response from the mint (for logging, in case of errors) + */ +static void +link_cb (void *cls, + unsigned int http_status, + unsigned int num_coins, + const struct TALER_CoinSpendPrivateKeyP *coin_privs, + const struct TALER_DenominationSignature *sigs, + const struct TALER_DenominationPublicKey *pubs, + json_t *full_response) +{ + struct InterpreterState *is = cls; + struct Command *cmd = &is->commands[is->ip]; + + cmd->details.refresh_link.rlh = NULL; + if (cmd->expected_response_code != http_status) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u to command %s\n", + http_status, + cmd->label); + fail (is); + return; + } + switch (http_status) + { + case MHD_HTTP_OK: + // FIXME: test returned values... + break; + default: + break; + } is->ip++; is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, is); @@ -1156,6 +1217,7 @@ interpreter_run (void *cls, ref = find_command (is, cmd->details.deposit.coin_ref); GNUNET_assert (NULL != ref); + // FIXME: support OC_REFRESH_REVEAL commands as well! GNUNET_assert (OC_WITHDRAW_SIGN == ref->oc); if (GNUNET_OK != TALER_string_to_amount (cmd->details.deposit.amount, @@ -1337,11 +1399,10 @@ interpreter_run (void *cls, fail (is); return; } - trigger_context_task (); - return; } } - break; + trigger_context_task (); + return; case OC_REFRESH_REVEAL: ref = find_command (is, cmd->details.refresh_reveal.melt_ref); @@ -1361,10 +1422,41 @@ interpreter_run (void *cls, trigger_context_task (); return; case OC_REFRESH_LINK: - /* not implemented */ - GNUNET_break (0); - is->ip++; - break; + /* find reveal command */ + ref = find_command (is, + cmd->details.refresh_link.reveal_ref); + /* find melt command */ + ref = find_command (is, + ref->details.refresh_reveal.melt_ref); + /* find withdraw_sign command */ + { + unsigned int idx; + const struct MeltDetails *md; + unsigned int num_melted_coins; + + for (num_melted_coins=0; + NULL != ref->details.refresh_melt.melted_coins[num_melted_coins].amount; + num_melted_coins++) ; + idx = cmd->details.refresh_link.coin_idx; + GNUNET_assert (idx < num_melted_coins); + md = &ref->details.refresh_melt.melted_coins[idx]; + ref = find_command (is, + md->coin_ref); + } + /* finally, use private key from withdraw sign command */ + cmd->details.refresh_link.rlh + = TALER_MINT_refresh_link (mint, + &ref->details.withdraw_sign.coin_priv, + &link_cb, + is); + if (NULL == cmd->details.refresh_link.rlh) + { + GNUNET_break (0); + fail (is); + return; + } + trigger_context_task (); + return; default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unknown instruction %d at %u (%s)\n", @@ -1628,6 +1720,7 @@ run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct InterpreterState *is; +#if FUTURE static struct MeltDetails melt_coins_1[] = { { "coin_ref1", "EUR:1.1" }, // FIXME: pick sensible values { "coin_ref2", "EUR:1.1" }, // FIXME: pick sensible values @@ -1646,6 +1739,7 @@ run (void *cls, "EUR:1", // FIXME: pick sensible values NULL }; +#endif static struct Command commands[] = { /* Fill reserve with EUR:5.01, as withdraw fee is 1 ct per config */ -- cgit v1.2.3 From bbeb913dc2c78ff3ce951ca17fc0148714865212 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 16:21:49 +0200 Subject: -finish reveal_cb --- src/mint-lib/test_mint_api.c | 99 +++++++++++++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 25 deletions(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index 859d41c4..e7860c66 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -18,6 +18,11 @@ * @brief testcase to test mint's HTTP API interface * @author Sree Harsha Totakura * @author Christian Grothoff + * + * TODO: + * - support depositing coins from /refresh/reveal result + * - test /refresh/-operations + * - check coins returned by link_cb */ #include "platform.h" #include "taler_util.h" @@ -124,6 +129,33 @@ struct MeltDetails }; +/** + * Information about a fresh coin generated by the refresh operation. + */ +struct FreshCoin +{ + + /** + * If @e amount is NULL, this specifies the denomination key to + * use. Otherwise, this will be set (by the interpreter) to the + * denomination PK matching @e amount. + */ + const struct TALER_MINT_DenomPublicKey *pk; + + /** + * Set (by the interpreter) to the mint's signature over the + * coin's public key. + */ + struct TALER_DenominationSignature sig; + + /** + * Set (by the interpreter) to the coin's private key. + */ + struct TALER_CoinSpendPrivateKeyP coin_priv; + +}; + + /** * Details for a mint operation to execute. */ @@ -331,6 +363,12 @@ struct Command */ const char **fresh_amounts; + /** + * Array of the public keys corresponding to + * the @e fresh_amounts, set by the interpreter. + */ + const struct TALER_MINT_DenomPublicKey **fresh_pks; + /** * Melt handle while operation is running. */ @@ -379,28 +417,7 @@ struct Command /** * Information about coins withdrawn, set by the interpreter. */ - struct - { - - /** - * If @e amount is NULL, this specifies the denomination key to - * use. Otherwise, this will be set (by the interpreter) to the - * denomination PK matching @e amount. - */ - const struct TALER_MINT_DenomPublicKey *pk; - - /** - * Set (by the interpreter) to the mint's signature over the - * coin's public key. - */ - struct TALER_DenominationSignature sig; - - /** - * Set (by the interpreter) to the coin's private key. - */ - struct TALER_CoinSpendPrivateKeyP coin_priv; - - } *fresh_coins; + struct FreshCoin *fresh_coins; } refresh_reveal; @@ -900,6 +917,7 @@ reveal_cb (void *cls, { struct InterpreterState *is = cls; struct Command *cmd = &is->commands[is->ip]; + const struct Command *ref; unsigned int i; cmd->details.refresh_reveal.rrh = NULL; @@ -912,11 +930,24 @@ reveal_cb (void *cls, fail (is); return; } + ref = find_command (is, + cmd->details.refresh_reveal.melt_ref); cmd->details.refresh_reveal.num_fresh_coins = num_coins; switch (http_status) { case MHD_HTTP_OK: - // FIXME: store returned coin keys... + cmd->details.refresh_reveal.fresh_coins + = GNUNET_new_array (num_coins, + struct FreshCoin); + for (i=0;idetails.refresh_reveal.fresh_coins[i]; + + fc->pk = ref->details.refresh_melt.fresh_pks[i]; + fc->coin_priv = coin_privs[i]; + fc->sig.rsa_signature + = GNUNET_CRYPTO_rsa_signature_dup (sigs[i].rsa_signature); + } break; default: break; @@ -1324,6 +1355,9 @@ interpreter_run (void *cls, NULL != cmd->details.refresh_melt.fresh_amounts[num_fresh_coins]; num_fresh_coins++) ; + cmd->details.refresh_melt.fresh_pks + = GNUNET_new_array (num_fresh_coins, + const struct TALER_MINT_DenomPublicKey *); { struct TALER_CoinSpendPrivateKeyP melt_privs[num_melted_coins]; struct TALER_Amount melt_amounts[num_melted_coins]; @@ -1368,8 +1402,10 @@ interpreter_run (void *cls, fail (is); return; } - fresh_pks[i] = *find_pk (is->keys, - &amount); + cmd->details.refresh_melt.fresh_pks[i] + = find_pk (is->keys, + &amount); + fresh_pks[i] = *cmd->details.refresh_melt.fresh_pks[i]; } cmd->details.refresh_melt.refresh_data = TALER_MINT_refresh_prepare (num_melted_coins, @@ -1558,6 +1594,8 @@ do_shutdown (void *cls, TALER_MINT_refresh_melt_cancel (cmd->details.refresh_melt.rmh); cmd->details.refresh_melt.rmh = NULL; } + GNUNET_free_non_null (cmd->details.refresh_melt.fresh_pks); + cmd->details.refresh_melt.fresh_pks = NULL; GNUNET_free_non_null (cmd->details.refresh_melt.refresh_data); cmd->details.refresh_melt.refresh_data = NULL; cmd->details.refresh_melt.refresh_data_length = 0; @@ -1572,6 +1610,17 @@ do_shutdown (void *cls, TALER_MINT_refresh_reveal_cancel (cmd->details.refresh_reveal.rrh); cmd->details.refresh_reveal.rrh = NULL; } + { + unsigned int j; + struct FreshCoin *fresh_coins; + + fresh_coins = cmd->details.refresh_reveal.fresh_coins; + for (j=0;jdetails.refresh_reveal.num_fresh_coins;j++) + GNUNET_CRYPTO_rsa_signature_free (fresh_coins[j].sig.rsa_signature); + } + GNUNET_free_non_null (cmd->details.refresh_reveal.fresh_coins); + cmd->details.refresh_reveal.fresh_coins = NULL; + cmd->details.refresh_reveal.num_fresh_coins = 0; break; case OC_REFRESH_LINK: if (NULL != cmd->details.refresh_link.rlh) -- cgit v1.2.3 From f545cd0c4167a7431f21215788e03e80ae9a4d9f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 16:29:32 +0200 Subject: support /deposit from /refresh/reveal'ed coins in test --- src/mint-lib/test_mint_api.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index e7860c66..c36221d6 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -20,7 +20,6 @@ * @author Christian Grothoff * * TODO: - * - support depositing coins from /refresh/reveal result * - test /refresh/-operations * - check coins returned by link_cb */ @@ -1236,6 +1235,9 @@ interpreter_run (void *cls, case OC_DEPOSIT: { struct GNUNET_HashCode h_contract; + const struct TALER_CoinSpendPrivateKeyP *coin_priv; + const struct TALER_MINT_DenomPublicKey *coin_pk; + const struct TALER_DenominationSignature *coin_pk_sig; struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendSignatureP coin_sig; struct GNUNET_TIME_Absolute refund_deadline; @@ -1248,8 +1250,30 @@ interpreter_run (void *cls, ref = find_command (is, cmd->details.deposit.coin_ref); GNUNET_assert (NULL != ref); - // FIXME: support OC_REFRESH_REVEAL commands as well! - GNUNET_assert (OC_WITHDRAW_SIGN == ref->oc); + switch (ref->oc) + { + case OC_WITHDRAW_SIGN: + coin_priv = &ref->details.withdraw_sign.coin_priv; + coin_pk = ref->details.withdraw_sign.pk; + coin_pk_sig = &ref->details.withdraw_sign.sig; + break; + case OC_REFRESH_REVEAL: + { + const struct FreshCoin *fc; + unsigned int idx; + + idx = cmd->details.deposit.coin_idx; + GNUNET_assert (idx < ref->details.refresh_reveal.num_fresh_coins); + fc = &ref->details.refresh_reveal.fresh_coins[idx]; + + coin_priv = &fc->coin_priv; + coin_pk = fc->pk; + coin_pk_sig = &fc->sig; + } + break; + default: + GNUNET_assert (0); + } if (GNUNET_OK != TALER_string_to_amount (cmd->details.deposit.amount, &amount)) @@ -1276,7 +1300,8 @@ interpreter_run (void *cls, fail (is); return; } - GNUNET_CRYPTO_eddsa_key_get_public (&ref->details.withdraw_sign.coin_priv.eddsa_priv, + + GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, &coin_pub.eddsa_pub); if (0 != cmd->details.deposit.refund_deadline.rel_value_us) @@ -1308,11 +1333,11 @@ interpreter_run (void *cls, TALER_amount_hton (&dr.amount_with_fee, &amount); TALER_amount_hton (&dr.deposit_fee, - &ref->details.withdraw_sign.pk->fee_deposit); + &coin_pk->fee_deposit); dr.merchant = merchant_pub; dr.coin_pub = coin_pub; GNUNET_assert (GNUNET_OK == - GNUNET_CRYPTO_eddsa_sign (&ref->details.withdraw_sign.coin_priv.eddsa_priv, + GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv, &dr.purpose, &coin_sig.eddsa_signature)); @@ -1323,8 +1348,8 @@ interpreter_run (void *cls, wire, &h_contract, &coin_pub, - &ref->details.withdraw_sign.sig, - &ref->details.withdraw_sign.pk->key, + coin_pk_sig, + &coin_pk->key, timestamp, cmd->details.deposit.transaction_id, &merchant_pub, -- cgit v1.2.3 From 94b0b28994b4f4563bd0b8e309f96ed14ca9f7c0 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 16:34:40 +0200 Subject: add checks for /refresh/link result --- src/mint-lib/test_mint_api.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index c36221d6..e6ffbc7f 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -21,7 +21,6 @@ * * TODO: * - test /refresh/-operations - * - check coins returned by link_cb */ #include "platform.h" #include "taler_util.h" @@ -981,6 +980,8 @@ link_cb (void *cls, { struct InterpreterState *is = cls; struct Command *cmd = &is->commands[is->ip]; + const struct Command *ref; + unsigned int i; cmd->details.refresh_link.rlh = NULL; if (cmd->expected_response_code != http_status) @@ -992,10 +993,37 @@ link_cb (void *cls, fail (is); return; } + ref = find_command (is, + cmd->details.refresh_link.reveal_ref); switch (http_status) { case MHD_HTTP_OK: - // FIXME: test returned values... + /* check that number of coins returned matches */ + if (num_coins != ref->details.refresh_reveal.num_fresh_coins) + { + GNUNET_break (0); + fail (is); + return; + } + /* check that the coins match */ + for (i=0;idetails.refresh_reveal.fresh_coins[i]; + if ( (0 != memcmp (&coin_privs[i], + &fc->coin_priv, + sizeof (struct TALER_CoinSpendPrivateKeyP))) || + (0 != GNUNET_CRYPTO_rsa_signature_cmp (fc->sig.rsa_signature, + sigs[i].rsa_signature)) || + (0 != GNUNET_CRYPTO_rsa_public_key_cmp (fc->pk->key.rsa_public_key, + pubs[i].rsa_public_key)) ) + { + GNUNET_break (0); + fail (is); + return; + } + } break; default: break; -- cgit v1.2.3 From e982139186a4503d709b1c0aa760534f90cb3ba7 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 17:18:09 +0200 Subject: test logic for actually testing /refresh operations, keeping disabled for now as the test is known to fail (to be investigated) --- src/mint-lib/test-mint-home/config/mint-keyup.conf | 30 ++++++- src/mint-lib/test_mint_api.c | 100 ++++++++++++++------- 2 files changed, 93 insertions(+), 37 deletions(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/mint-lib/test-mint-home/config/mint-keyup.conf b/src/mint-lib/test-mint-home/config/mint-keyup.conf index d8bbc9d2..8ad1f3bb 100644 --- a/src/mint-lib/test-mint-home/config/mint-keyup.conf +++ b/src/mint-lib/test-mint-home/config/mint-keyup.conf @@ -19,6 +19,17 @@ lookahead_provide = 4 weeks 1 day # name begins with "coin_". The rest of the # name is free, but of course following the convention # of "coin_$CURRENCY[_$SUBUNIT]_$VALUE" make sense. +[coin_eur_ct_1] +value = EUR:0.01 +duration_overlap = 5 minutes +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.00 +fee_deposit = EUR:0.00 +fee_refresh = EUR:0.01 +rsa_keysize = 1024 + [coin_eur_ct_10] value = EUR:0.10 duration_overlap = 5 minutes @@ -27,7 +38,18 @@ duration_spend = 2 years duration_legal = 3 years fee_withdraw = EUR:0.01 fee_deposit = EUR:0.01 -fee_refresh = EUR:0.01 +fee_refresh = EUR:0.03 +rsa_keysize = 1024 + +[coin_eur_1] +value = EUR:1 +duration_overlap = 5 minutes +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.01 +fee_deposit = EUR:0.01 +fee_refresh = EUR:0.03 rsa_keysize = 1024 [coin_eur_5] @@ -38,7 +60,7 @@ duration_spend = 2 years duration_legal = 3 years fee_withdraw = EUR:0.01 fee_deposit = EUR:0.01 -fee_refresh = EUR:0.01 +fee_refresh = EUR:0.03 rsa_keysize = 1024 [coin_eur_10] @@ -49,7 +71,7 @@ duration_spend = 2 years duration_legal = 3 years fee_withdraw = EUR:0.01 fee_deposit = EUR:0.01 -fee_refresh = EUR:0.01 +fee_refresh = EUR:0.03 rsa_keysize = 1024 [coin_eur_1000] @@ -60,5 +82,5 @@ duration_spend = 2 years duration_legal = 3 years fee_withdraw = EUR:0.01 fee_deposit = EUR:0.01 -fee_refresh = EUR:0.01 +fee_refresh = EUR:0.03 rsa_keysize = 2048 diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index e6ffbc7f..2ef35f19 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -18,9 +18,6 @@ * @brief testcase to test mint's HTTP API interface * @author Sree Harsha Totakura * @author Christian Grothoff - * - * TODO: - * - test /refresh/-operations */ #include "platform.h" #include "taler_util.h" @@ -1822,26 +1819,25 @@ run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct InterpreterState *is; -#if FUTURE static struct MeltDetails melt_coins_1[] = { - { "coin_ref1", "EUR:1.1" }, // FIXME: pick sensible values - { "coin_ref2", "EUR:1.1" }, // FIXME: pick sensible values - { "coin_ref3", "EUR:1.1" }, // FIXME: pick sensible values + { .amount = "EUR:4", + .coin_ref = "refresh-withdraw-coin-1" }, { NULL, NULL } }; static const char *melt_fresh_amounts_1[] = { - "EUR:1", // FIXME: pick sensible values - "EUR:1", // FIXME: pick sensible values - "EUR:1", // FIXME: pick sensible values - NULL - }; - static const char *melt_fresh_amounts_2[] = { - "EUR:1", // FIXME: pick sensible values - "EUR:1", // FIXME: pick sensible values - "EUR:1", // FIXME: pick sensible values + "EUR:1", + "EUR:1", + "EUR:1", + "EUR:0.1", + "EUR:0.1", + "EUR:0.1", + "EUR:0.1", + "EUR:0.1", + "EUR:0.1", + "EUR:0.1", + /* with 0.03 refresh fees each, this totals up to exactly 4 EUR */ NULL }; -#endif static struct Command commands[] = { /* Fill reserve with EUR:5.01, as withdraw fee is 1 ct per config */ @@ -1909,44 +1905,82 @@ run (void *cls, .details.deposit.contract = "{ \"items\"={ \"name\":\"ice cream\", \"value\":2 } }", .details.deposit.transaction_id = 1 }, -#if FUTURE - /* Test running a successful melt operation */ +#if TEST_REFRESH + /* ***************** /refresh testing ******************** */ + + /* Fill reserve with EUR:5.01, as withdraw fee is 1 ct */ + { .oc = OC_ADMIN_ADD_INCOMING, + .label = "refresh-create-reserve-1", + .expected_response_code = MHD_HTTP_OK, + .details.admin_add_incoming.wire = "{ \"type\":\"TEST\", \"bank\":\"source bank\", \"account\":424 }", + .details.admin_add_incoming.amount = "EUR:5.01" }, + /* Withdraw a 5 EUR coin, at fee of 1 ct */ + { .oc = OC_WITHDRAW_SIGN, + .label = "refresh-withdraw-coin-1", + .expected_response_code = MHD_HTTP_OK, + .details.withdraw_sign.reserve_reference = "refresh-create-reserve-1", + .details.withdraw_sign.amount = "EUR:5" }, + /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin (in full) + (merchant would receive EUR:0.99 due to 1 ct deposit fee) */ + { .oc = OC_DEPOSIT, + .label = "refresh-deposit-partial", + .expected_response_code = MHD_HTTP_OK, + .details.deposit.amount = "EUR:1", + .details.deposit.coin_ref = "refresh-withdraw-coin-1", + .details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account\":42 }", + .details.deposit.contract = "{ \"items\"={ \"name\":\"ice cream\", \"value\"EUR:1 } }", + .details.deposit.transaction_id = 42421 }, + + /* Melt the rest of the coin's value (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */ { .oc = OC_REFRESH_MELT, - .label = "melt-1", + .label = "refresh-melt-1", .expected_response_code = MHD_HTTP_OK, .details.refresh_melt.melted_coins = melt_coins_1, .details.refresh_melt.fresh_amounts = melt_fresh_amounts_1 }, /* Complete (successful) melt operation, and withdraw the coins */ { .oc = OC_REFRESH_REVEAL, - .label = "reveal-1", - .melt_ref = "melt-1", - .expected_response_code = MHD_HTTP_OK }, + .label = "refresh-reveal-1", + .expected_response_code = MHD_HTTP_OK, + .details.refresh_reveal.melt_ref = "refresh-melt-1" }, /* Test that /refresh/link works */ { .oc = OC_REFRESH_LINK, - .label = "link-1", - .reveal_ref = "reveal-1", - .expected_response_code = MHD_HTTP_OK }, + .label = "refresh-link-1", + .expected_response_code = MHD_HTTP_OK, + .details.refresh_link.reveal_ref = "refresh-reveal-1" }, - /* Test successfully spending coins from the refresh operation */ + /* Test successfully spending coins from the refresh operation: + first EUR:1 */ { .oc = OC_DEPOSIT, - .label = "deposit-refreshed-1", + .label = "refresh-deposit-refreshed-1", .expected_response_code = MHD_HTTP_OK, - .details.deposit.amount = "EUR:5", // FIXME: pick sensible value - .details.deposit.coin_ref = "reveal-1", + .details.deposit.amount = "EUR:1", + .details.deposit.coin_ref = "refresh-reveal-1a", .details.deposit.coin_idx = 0, .details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account\":42 }", .details.deposit.contract = "{ \"items\"={ \"name\":\"ice cream\", \"value\":3 } }", .details.deposit.transaction_id = 2 }, + /* Test successfully spending coins from the refresh operation: + finally EUR:0.1 */ + { .oc = OC_DEPOSIT, + .label = "refresh-deposit-refreshed-1b", + .expected_response_code = MHD_HTTP_OK, + .details.deposit.amount = "EUR:0.1", + .details.deposit.coin_ref = "refresh-reveal-1b", + .details.deposit.coin_idx = 4, + .details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account\":42 }", + .details.deposit.contract = "{ \"items\"={ \"name\":\"ice cream\", \"value\":3 } }", + .details.deposit.transaction_id = 2 }, - /* Test running a failing melt operation */ + /* Test running a failing melt operation (same operation again must fail) */ { .oc = OC_REFRESH_MELT, - .label = "melt-2", + .label = "refresh-melt-failing", .expected_response_code = MHD_HTTP_FORBIDDEN, .details.refresh_melt.melted_coins = melt_coins_1, - .details.refresh_melt.fresh_amounts = melt_fresh_amounts_2 }, + .details.refresh_melt.fresh_amounts = melt_fresh_amounts_1 }, + /* *************** end of /refresh testing ************** */ #endif { .oc = OC_END } -- cgit v1.2.3 From 2cccc2a17336da8417ecaa4dabb1f99ee6dd99a1 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 18:11:30 +0200 Subject: fix #3934 --- src/mint-lib/test_mint_api.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index 2ef35f19..4881a3b1 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -1875,6 +1875,7 @@ run (void *cls, .expected_response_code = MHD_HTTP_PAYMENT_REQUIRED, .details.withdraw_sign.reserve_reference = "create-reserve-1", .details.withdraw_sign.amount = "EUR:5" }, + /* Try to double-spend the 5 EUR coin with different wire details */ { .oc = OC_DEPOSIT, .label = "deposit-double-1", @@ -2039,7 +2040,14 @@ main (int argc, "-d", "test-mint-home", NULL); /* give child time to start and bind against the socket */ - sleep (2); + fprintf (stderr, "Waiting for taler-mint-httpd to be ready"); + do + { + fprintf (stderr, "."); + sleep (1); + } + while (0 != system ("wget -q -t 1 http://localhost:8081/agpl -o /dev/null")); + fprintf (stderr, "\n"); result = GNUNET_SYSERR; GNUNET_SCHEDULER_run (&run, NULL); GNUNET_OS_process_kill (mintd, -- cgit v1.2.3 From d0fb01185085d6f4423d5fc2ea726113676749a8 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 18:31:26 +0200 Subject: fixing silly bug --- src/mint-lib/mint_api_refresh.c | 4 ++-- src/mint-lib/test_mint_api.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 442a73e1..58fe1126 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -647,7 +647,7 @@ deserialize_fresh_coin (struct FreshCoin *fc, fc->blinding_key.rsa_blinding_key = GNUNET_CRYPTO_rsa_blinding_key_decode (&buf[sizeof (struct FreshCoinP)], bbuf_size); - if (NULL == fc->blinding_key.rsa_blinding_key) + if (NULL == fc->blinding_key.rsa_blinding_key) { GNUNET_break (0); *ok = GNUNET_NO; @@ -740,7 +740,7 @@ deserialize_melt_data (const char *buf, return NULL; memcpy (&mdp, buf, - buf_size); + sizeof (struct MeltDataP)); md = GNUNET_new (struct MeltData); md->melt_session_hash = mdp.melt_session_hash; for (i=0;i Date: Sun, 9 Aug 2015 19:00:48 +0200 Subject: -some cosmetics --- src/mint-lib/test_mint_api.c | 5 ++++- src/mint/taler-mint-httpd_refresh.c | 7 +++---- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index cc500987..fcc5db10 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -1932,6 +1932,10 @@ run (void *cls, .details.deposit.transaction_id = 42421 }, /* Melt the rest of the coin's value (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */ + +#if TEST_REFRESH + + { .oc = OC_REFRESH_MELT, .label = "refresh-melt-1", .expected_response_code = MHD_HTTP_OK, @@ -1944,7 +1948,6 @@ run (void *cls, .expected_response_code = MHD_HTTP_OK, .details.refresh_reveal.melt_ref = "refresh-melt-1" }, -#if TEST_REFRESH_LINK /* Test that /refresh/link works */ { .oc = OC_REFRESH_LINK, diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c index 0a1ad2a0..f952bec7 100644 --- a/src/mint/taler-mint-httpd_refresh.c +++ b/src/mint/taler-mint-httpd_refresh.c @@ -209,7 +209,7 @@ get_coin_public_info (struct MHD_Connection *connection, /** * Verify that the signature shows that this coin is to be melted into - * the given @a session_pub melting session, and that this is a valid + * the given @a session_hash melting session, and that this is a valid * coin (we know the denomination key and the signature on it is * valid). Essentially, this does all of the per-coin checks that can * be done before the transaction starts. @@ -361,7 +361,6 @@ handle_refresh_melt_json (struct MHD_Connection *connection, unsigned int num_newcoins, const json_t *coin_evs, const json_t *link_encs) - { int res; unsigned int i; @@ -407,8 +406,8 @@ handle_refresh_melt_json (struct MHD_Connection *connection, } coin_count = json_array_size (melt_coins); - coin_melt_details = GNUNET_malloc (coin_count * - sizeof (struct TMH_DB_MeltDetails)); + coin_melt_details = GNUNET_new_array (coin_count, + struct TMH_DB_MeltDetails); for (i=0;i Date: Sun, 9 Aug 2015 21:25:02 +0200 Subject: move struct TALER_MINTDB_RefreshCommitLinkP to taler_signatures.h --- src/include/taler_mintdb_plugin.h | 27 --------------------------- src/include/taler_signatures.h | 25 +++++++++++++++++++++++++ src/mint-lib/test_mint_api.c | 5 ++--- src/mint/taler-mint-httpd_refresh.c | 3 --- 4 files changed, 27 insertions(+), 33 deletions(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index a7a73574..ba83c814 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -388,33 +388,6 @@ struct TALER_MINTDB_RefreshCommitCoin }; -GNUNET_NETWORK_STRUCT_BEGIN - -/** - * @brief For each (old) coin being melted, we have a `struct - * RefreshCommitLinkP` that allows the user to find the shared secret - * to decrypt the respective refresh links for the new coins in the - * `struct TALER_MINTDB_RefreshCommitCoin`. - */ -struct TALER_MINTDB_RefreshCommitLinkP -{ - /** - * Transfer public key, used to decrypt the @e shared_secret_enc - * in combintation with the corresponding private key of the - * coin. - */ - struct TALER_TransferPublicKeyP transfer_pub; - - /** - * Encrypted shared secret to decrypt the link. - */ - struct TALER_EncryptedLinkSecretP shared_secret_enc; -}; - -GNUNET_NETWORK_STRUCT_END - - - /** * @brief Linked list of refresh information linked to a coin. */ diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index 402e67fe..0b05bace 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -648,6 +648,31 @@ struct TALER_MintKeyValidityPS }; +/** + * @brief For each (old) coin being melted, we have a `struct + * RefreshCommitLinkP` that allows the user to find the shared secret + * to decrypt the respective refresh links for the new coins in the + * `struct TALER_MINTDB_RefreshCommitCoin`. + * + * Part of the construction of the refresh session's hash and + * thus of what is signed there. + */ +struct TALER_MINTDB_RefreshCommitLinkP +{ + /** + * Transfer public key, used to decrypt the @e shared_secret_enc + * in combintation with the corresponding private key of the + * coin. + */ + struct TALER_TransferPublicKeyP transfer_pub; + + /** + * Encrypted shared secret to decrypt the link. + */ + struct TALER_EncryptedLinkSecretP shared_secret_enc; +}; + + GNUNET_NETWORK_STRUCT_END #endif diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index fcc5db10..bae96dfb 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -1933,15 +1933,14 @@ run (void *cls, /* Melt the rest of the coin's value (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */ -#if TEST_REFRESH - - { .oc = OC_REFRESH_MELT, .label = "refresh-melt-1", .expected_response_code = MHD_HTTP_OK, .details.refresh_melt.melted_coins = melt_coins_1, .details.refresh_melt.fresh_amounts = melt_fresh_amounts_1 }, +#if TEST_REFRESH + /* Complete (successful) melt operation, and withdraw the coins */ { .oc = OC_REFRESH_REVEAL, .label = "refresh-reveal-1", diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c index eb205ed1..7bcaa799 100644 --- a/src/mint/taler-mint-httpd_refresh.c +++ b/src/mint/taler-mint-httpd_refresh.c @@ -252,9 +252,6 @@ verify_coin_public_info (struct MHD_Connection *connection, body.purpose.size = htonl (sizeof (struct TALER_RefreshMeltCoinAffirmationPS)); body.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT); body.session_hash = *session_hash; - fprintf (stderr, - "Verifying hash %s\n", - GNUNET_h2s (session_hash)); TALER_amount_hton (&body.amount_with_fee, &melt_detail->melt_amount_with_fee); -- cgit v1.2.3 From e08f479eb403cfbcb490dd0b07fd3d384136f446 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 21:38:04 +0200 Subject: -fix testcase, more verbose logging of client protocol errors --- src/mint-lib/test_mint_api.c | 11 ++++++++++- src/mint/taler-mint-httpd_db.c | 8 ++++++-- src/mint/taler-mint-httpd_refresh.c | 4 ++++ 3 files changed, 20 insertions(+), 3 deletions(-) (limited to 'src/mint-lib/test_mint_api.c') diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index bae96dfb..4b1b0f22 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -1835,7 +1835,16 @@ run (void *cls, "EUR:0.1", "EUR:0.1", "EUR:0.1", - /* with 0.03 refresh fees each, this totals up to exactly 4 EUR */ + "EUR:0.1", + "EUR:0.01", + "EUR:0.01", + "EUR:0.01", + "EUR:0.01", + "EUR:0.01", + "EUR:0.01", + /* with 0.01 withdraw fees (except for 1ct coins), + this totals up to exactly EUR:3.97, and with + the 0.03 refresh fee, to EUR:4.0*/ NULL }; static struct Command commands[] = diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index e24102ea..04c2555e 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -550,7 +550,9 @@ refresh_accept_melts (struct MHD_Connection *connection, GNUNET_break (0); TMH_plugin->free_coin_transaction_list (TMH_plugin->cls, tl); - return TMH_RESPONSE_reply_internal_db_error (connection); + return (MHD_YES == + TMH_RESPONSE_reply_internal_db_error (connection)) + ? GNUNET_NO : GNUNET_SYSERR; } /* Refuse to refresh when the coin's value is insufficient for the cost of all transactions. */ @@ -587,7 +589,9 @@ refresh_accept_melts (struct MHD_Connection *connection, &melt)) { GNUNET_break (0); - return GNUNET_SYSERR; + return (MHD_YES == + TMH_RESPONSE_reply_internal_db_error (connection)) + ? GNUNET_NO : GNUNET_SYSERR; } return GNUNET_OK; } diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c index 954d8daf..625fcc50 100644 --- a/src/mint/taler-mint-httpd_refresh.c +++ b/src/mint/taler-mint-httpd_refresh.c @@ -92,6 +92,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, &cost, &total_cost)) ) { + GNUNET_break_op (0); TMH_KS_release (key_state); return TMH_RESPONSE_reply_internal_error (connection, "cost calculation failure"); @@ -115,6 +116,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, &coin_melt_details->melt_amount_with_fee, &fee_melt)) { + GNUNET_break_op (0); TMH_KS_release (key_state); return TMH_RESPONSE_reply_external_error (connection, "Melt contribution below melting fee"); @@ -124,6 +126,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, &melt, &total_melt)) { + GNUNET_break_op (0); TMH_KS_release (key_state); return TMH_RESPONSE_reply_internal_error (connection, "balance calculation failure"); @@ -134,6 +137,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, TALER_amount_cmp (&total_cost, &total_melt)) { + GNUNET_break_op (0); /* We require total value of coins being melted and total value of coins being generated to match! */ return TMH_RESPONSE_reply_json_pack (connection, -- cgit v1.2.3