skeleton for the interpreter loop to write tests for the mint
This commit is contained in:
parent
cf798e77fe
commit
15956f47c0
@ -50,6 +50,248 @@ static struct GNUNET_SCHEDULER_Task *ctx_task;
|
|||||||
static int result;
|
static int result;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opcodes for the interpreter.
|
||||||
|
*/
|
||||||
|
enum OpCode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Termination code, stops the interpreter loop (with success).
|
||||||
|
*/
|
||||||
|
OC_END = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add funds to a reserve by (faking) incoming wire transfer.
|
||||||
|
*/
|
||||||
|
OC_ADMIN_ADD_INCOMING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Withdraw a coin from a reserve.
|
||||||
|
*/
|
||||||
|
OC_WITHDRAW_SIGN,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deposit a coin (pay with it).
|
||||||
|
*/
|
||||||
|
OC_DEPOSIT
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Details for a mint operation to execute.
|
||||||
|
*/
|
||||||
|
struct Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Opcode of the command.
|
||||||
|
*/
|
||||||
|
enum OpCode oc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Label for the command, can be NULL.
|
||||||
|
*/
|
||||||
|
const char *label;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Details about the command.
|
||||||
|
*/
|
||||||
|
union
|
||||||
|
{
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Label to another admin_add_incoming command if we
|
||||||
|
* should deposit into an existing reserve, NULL if
|
||||||
|
* a fresh reserve should be created.
|
||||||
|
*/
|
||||||
|
const char *reserve_reference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String describing the amount to add to the reserve.
|
||||||
|
*/
|
||||||
|
const char *amount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set (by the interpreter) to the reserve's private key
|
||||||
|
* we used to fill the reserve.
|
||||||
|
*/
|
||||||
|
struct TALER_ReservePrivateKeyP reserve_priv;
|
||||||
|
|
||||||
|
} admin_add_incoming;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Which reserve should we withdraw from?
|
||||||
|
*/
|
||||||
|
const char *reserve_reference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String describing the denomination value we should withdraw.
|
||||||
|
* A corresponding denomination key must exist in the mint's
|
||||||
|
* offerings. Can be NULL if @e pk is set instead.
|
||||||
|
*/
|
||||||
|
const char *amount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
} withdraw_sign;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amount to deposit.
|
||||||
|
*/
|
||||||
|
const char *amount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to a withdraw_sign operation for a coin to
|
||||||
|
* be used for the /deposit operation.
|
||||||
|
*/
|
||||||
|
const char *coin_ref;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON string describing the merchant's "wire details".
|
||||||
|
*/
|
||||||
|
const char *wire_details;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON string describing the contract between the two parties.
|
||||||
|
*/
|
||||||
|
const char *contract;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transaction ID to use.
|
||||||
|
*/
|
||||||
|
uint64_t transaction_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relative time (to add to 'now') to compute the refund deadline.
|
||||||
|
* Zero for no refunds.
|
||||||
|
*/
|
||||||
|
struct GNUNET_TIME_Relative refund_deadline;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set (by the interpreter) to a fresh private key of the merchant,
|
||||||
|
* if @e refund_deadline is non-zero.
|
||||||
|
*/
|
||||||
|
struct TALER_MerchantPublicKeyP merchant_priv;
|
||||||
|
|
||||||
|
} deposit;
|
||||||
|
|
||||||
|
} details;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State of the interpreter loop.
|
||||||
|
*/
|
||||||
|
struct InterpreterState
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Keys from the mint.
|
||||||
|
*/
|
||||||
|
const struct TALER_MINT_Keys *keys;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commands the interpreter will run.
|
||||||
|
*/
|
||||||
|
struct Command *commands;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instruction pointer. Tells #interpreter_run() which
|
||||||
|
* instruction to run next.
|
||||||
|
*/
|
||||||
|
unsigned int ip;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The testcase failed, return with an error code.
|
||||||
|
*
|
||||||
|
* @param is interpreter state to clean up
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
fail (struct InterpreterState *is)
|
||||||
|
{
|
||||||
|
result = GNUNET_SYSERR;
|
||||||
|
GNUNET_free (is);
|
||||||
|
GNUNET_SCHEDULER_shutdown ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the main interpreter loop that performs mint operations.
|
||||||
|
*
|
||||||
|
* @param cls contains the `struct InterpreterState`
|
||||||
|
* @param tc scheduler context
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
interpreter_run (void *cls,
|
||||||
|
const struct GNUNET_SCHEDULER_TaskContext *tc)
|
||||||
|
{
|
||||||
|
struct InterpreterState *is = cls;
|
||||||
|
struct Command *cmd = &is->commands[is->ip++];
|
||||||
|
|
||||||
|
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"Test aborted by shutdown request\n");
|
||||||
|
fail (is);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (cmd->oc)
|
||||||
|
{
|
||||||
|
case OC_END:
|
||||||
|
result = GNUNET_OK;
|
||||||
|
GNUNET_free (is);
|
||||||
|
GNUNET_SCHEDULER_shutdown ();
|
||||||
|
return;
|
||||||
|
case OC_ADMIN_ADD_INCOMING:
|
||||||
|
GNUNET_break (0); // to be implemented!
|
||||||
|
break;
|
||||||
|
case OC_WITHDRAW_SIGN:
|
||||||
|
GNUNET_break (0); // to be implemented!
|
||||||
|
break;
|
||||||
|
case OC_DEPOSIT:
|
||||||
|
GNUNET_break (0); // to be implemented!
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Unknown instruction %d at %u (%s)\n",
|
||||||
|
cmd->oc,
|
||||||
|
is->ip - 1,
|
||||||
|
cmd->label);
|
||||||
|
fail (is);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GNUNET_SCHEDULER_add_now (&interpreter_run,
|
||||||
|
is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function run when the test terminates (good or bad).
|
* Function run when the test terminates (good or bad).
|
||||||
* Cleans up our state.
|
* Cleans up our state.
|
||||||
@ -92,6 +334,26 @@ static void
|
|||||||
cert_cb (void *cls,
|
cert_cb (void *cls,
|
||||||
const struct TALER_MINT_Keys *keys)
|
const struct TALER_MINT_Keys *keys)
|
||||||
{
|
{
|
||||||
|
struct InterpreterState *is;
|
||||||
|
static struct Command commands[] =
|
||||||
|
{
|
||||||
|
{ .oc = OC_ADMIN_ADD_INCOMING,
|
||||||
|
.label = "create-reserve-1",
|
||||||
|
.details.admin_add_incoming.amount = "EUR:5" },
|
||||||
|
{ .oc = OC_WITHDRAW_SIGN,
|
||||||
|
.label = "withdraw-coin-1",
|
||||||
|
.details.withdraw_sign.reserve_reference = "create-reserve-1",
|
||||||
|
.details.withdraw_sign.amount = "EUR:5" },
|
||||||
|
{ .oc = OC_DEPOSIT,
|
||||||
|
.label = "deposit-simple",
|
||||||
|
.details.deposit.amount = "EUR:5",
|
||||||
|
.details.deposit.coin_ref = "withdraw-coin-1",
|
||||||
|
.details.deposit.wire_details = "{ bank=\"my bank\", account=\"42\" }",
|
||||||
|
.details.deposit.contract = "{ items={ name=\"ice cream\", value=1 } }",
|
||||||
|
.details.deposit.transaction_id = 1 },
|
||||||
|
{ .oc = OC_END }
|
||||||
|
};
|
||||||
|
|
||||||
GNUNET_assert (NULL == cls);
|
GNUNET_assert (NULL == cls);
|
||||||
#define ERR(cond) do { if(!(cond)) break; GNUNET_break (0); GNUNET_SCHEDULER_shutdown(); return; } while (0)
|
#define ERR(cond) do { if(!(cond)) break; GNUNET_break (0); GNUNET_SCHEDULER_shutdown(); return; } while (0)
|
||||||
ERR (NULL == keys);
|
ERR (NULL == keys);
|
||||||
@ -105,8 +367,12 @@ cert_cb (void *cls,
|
|||||||
keys->num_denom_keys);
|
keys->num_denom_keys);
|
||||||
#undef ERR
|
#undef ERR
|
||||||
/* TODO: start running rest of test suite here! */
|
/* TODO: start running rest of test suite here! */
|
||||||
result = GNUNET_OK;
|
|
||||||
GNUNET_SCHEDULER_shutdown ();
|
is = GNUNET_new (struct InterpreterState);
|
||||||
|
is->keys = keys;
|
||||||
|
is->commands = commands;
|
||||||
|
GNUNET_SCHEDULER_add_now (&interpreter_run,
|
||||||
|
is);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user