Skip to content

Commit

Permalink
wip - send spend action
Browse files Browse the repository at this point in the history
  • Loading branch information
abenso committed Nov 8, 2024
1 parent 4c1be97 commit 0505887
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 40 deletions.
3 changes: 2 additions & 1 deletion app/rust/src/parser/plans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use self::{
action::ActionC, action::ActionPlan, detection::DetectionDataPlan,
detection::DetectionDataPlanC, memo::MemoPlanC,
};
use crate::parser::bytes::BytesC;

use super::{ObjectList, TransactionParameters};

Expand Down Expand Up @@ -81,7 +82,7 @@ pub struct TransactionPlan<'a> {
#[repr(C)]
#[cfg_attr(any(feature = "derive-debug", test), derive(Debug))]
pub struct TransactionPlanC {
pub actions: [ActionC; ACTION_DATA_QTY],
pub actions_hashes: [BytesC; ACTION_DATA_QTY],
pub transaction_parameters: TransactionParametersC,
pub memo: MemoPlanC,
pub detection_data: DetectionDataPlanC,
Expand Down
46 changes: 46 additions & 0 deletions app/rust/src/parser/plans/spend.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use core::{mem::MaybeUninit, ptr::addr_of_mut};

use crate::parser::{address::AddressC, bytes::BytesC};

use crate::{
parser::{Fq, Fr, Note, Position},
FromBytes, ParserError,
Expand Down Expand Up @@ -65,3 +67,47 @@ impl<'b> FromBytes<'b> for SpendPlan<'b> {
Ok(input)
}
}

#[repr(C)]
#[derive(Clone)]
#[cfg_attr(any(feature = "derive-debug", test), derive(Debug))]
pub struct AmountC {
pub lo: u64,
pub hi: u64,
}

#[repr(C)]
#[derive(Clone)]
#[cfg_attr(any(feature = "derive-debug", test), derive(Debug))]
pub struct AssetIdC {
pub inner: BytesC,
}

#[repr(C)]
#[derive(Clone)]
#[cfg_attr(any(feature = "derive-debug", test), derive(Debug))]
pub struct ValueC {
pub amount: AmountC,
pub asset_id: AssetIdC,
}

#[repr(C)]
#[derive(Clone)]
#[cfg_attr(any(feature = "derive-debug", test), derive(Debug))]
pub struct NoteC {
pub value: ValueC,
pub rseed: BytesC,
pub address: AddressC,
}

#[repr(C)]
#[derive(Clone)]
#[cfg_attr(any(feature = "derive-debug", test), derive(Debug))]
pub struct SpendPlanC {
pub note: NoteC,
pub position: u64,
pub randomizer: BytesC,
pub value_blinding: BytesC,
pub proof_blinding_r: BytesC,
pub proof_blinding_s: BytesC,
}
21 changes: 13 additions & 8 deletions app/src/parser_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ void print_string(const char *str) {

bool decode_action(pb_istream_t *stream, const pb_field_t *field, void **arg) {
penumbra_core_transaction_v1_ActionPlan action = penumbra_core_transaction_v1_ActionPlan_init_default;
spend_plan_t spend_plan;

action_t *decode_arg = (action_t *)*arg;
if (decode_arg == NULL) {
Expand All @@ -66,18 +65,17 @@ bool decode_action(pb_istream_t *stream, const pb_field_t *field, void **arg) {
return false;
}

const uint8_t *first_byte = stream->state;
uint16_t data_size = stream->bytes_left;
decode_arg[actions_qty].action.ptr = first_byte + 3;
decode_arg[actions_qty].action.len = data_size - 3;
Bytes_t action_data;
action_data.ptr = stream->state + 3;
action_data.len = stream->bytes_left - 3;

if (!pb_decode(stream, penumbra_core_transaction_v1_ActionPlan_fields, &action)) {
return false;
}
decode_arg[actions_qty].action_type = action.which_action;
switch (action.which_action) {
case penumbra_core_transaction_v1_ActionPlan_spend_tag:
decode_spend_plan(&decode_arg[actions_qty].action, &spend_plan);
decode_spend_plan(&action_data, &decode_arg[actions_qty].action.spend);
print_string("Spend action detected \n");
break;
case penumbra_core_transaction_v1_ActionPlan_output_tag:
Expand Down Expand Up @@ -137,6 +135,7 @@ bool decode_detection_data(pb_istream_t *stream, const pb_field_t *field, void *

parser_error_t _read(parser_context_t *c, parser_tx_t *v) {
Bytes_t data;
action_t actions_plan[ACTIONS_QTY];
data.ptr = c->buffer;
data.len = c->bufferLen;
actions_qty = 0;
Expand All @@ -156,7 +155,7 @@ parser_error_t _read(parser_context_t *c, parser_tx_t *v) {

// actions callbacks
request.actions.funcs.decode = &decode_action;
request.actions.arg = &v->plan.actions;
request.actions.arg = &actions_plan;

// detection data callbacks
request.detection_data.clue_plans.funcs.decode = &decode_detection_data;
Expand Down Expand Up @@ -191,7 +190,13 @@ parser_error_t _read(parser_context_t *c, parser_tx_t *v) {

// print actions
for (uint16_t i = 0; i < ACTIONS_QTY; i++) {
print_buffer(&v->plan.actions[i].action, "real actions");
switch (actions_plan[i].action_type) {
case penumbra_core_transaction_v1_ActionPlan_spend_tag:
printf("spend action detected\n");
printf("amount hi: %lu\n", actions_plan[i].action.spend.note.value.amount.hi);
printf("amount lo: %lu\n", actions_plan[i].action.spend.note.value.amount.lo);
break;
}
}

// print memo
Expand Down
10 changes: 8 additions & 2 deletions app/src/parser_txdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,17 @@ typedef struct {

typedef struct {
uint8_t action_type;
Bytes_t action;
union {
spend_plan_t spend;
} action;
} action_t;

typedef struct {
action_t actions[ACTIONS_QTY];
Bytes_t action_hash;
} action_hash_t;

typedef struct {
action_hash_t actions_hash[ACTIONS_QTY];
transaction_parameters_t transaction_parameters;
memo_plan_t memo;
detection_data_t detection_data;
Expand Down
8 changes: 4 additions & 4 deletions tests_zemu/tests/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ const APP_PATH_FL = resolve('../app/output/app_flex.elf')

export const models: IDeviceModel[] = [
// { name: 'nanos', prefix: 'S', path: APP_PATH_S },
{ name: 'nanox', prefix: 'X', path: APP_PATH_X },
// { name: 'nanox', prefix: 'X', path: APP_PATH_X },
{ name: 'nanosp', prefix: 'SP', path: APP_PATH_SP },
{ name: 'stax', prefix: 'ST', path: APP_PATH_ST },
{ name: 'flex', prefix: 'FL', path: APP_PATH_FL },
// { name: 'stax', prefix: 'ST', path: APP_PATH_ST },
// { name: 'flex', prefix: 'FL', path: APP_PATH_FL },
]

export const defaultOptions = {
Expand All @@ -29,5 +29,5 @@ export const defaultOptions = {
}

export const txBlobExample =
'0aaf020aac020aa1010a290a0308904e12220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a1012207fa50bfe8946e53b33e8328672a0c6300ad9333c04707475f2d6cc502ec8513a1a520a50e0783360338067fc2ba548f460b3f06f33d3e756ebefa8a8c08c5e12a1e667df228df0720fb9bd963894183bc447e1c7ef591fa9625d4a66b7703eec2ec1ef543454673bb61a4f2a3d861114d6891d691a208d0887fd0d20bd002c336054772d56b8f9704a80ac8da45533e72f155f7145032220d1241d9d9f051c437455998e7c1eff33cd085ba9a9092d852d0381278bb6b1012a205e3505d5b6b1b99a8284f054bd650e8d4b64a23f6322c05a0ccee46bb481cb0932208c6abfdd0dd9111868fbed6a30c9dd5477b123f7aefd15bc73b68185f0a036110ab2020aaf020aa2010a2a0a0408a09c0112220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a10122079ce0fe2f6695ebe61c22edb8de45e1290448500e0058156cb4e29f4d7234f091a520a50e0783360338067fc2ba548f460b3f06f33d3e756ebefa8a8c08c5e12a1e667df228df0720fb9bd963894183bc447e1c7ef591fa9625d4a66b7703eec2ec1ef543454673bb61a4f2a3d861114d6891d6910011a20c3021eb39eed577b5d609f5436d9128ff6c8bcc13e326a4fcab5c749e2f489002220c05b9ffb6512d40cc8cf03eb1e2b47f3fcc323a0f2db077362b2300eb77658022a20a45a2fc5a64032c3a68ce4ec9c542b564cfaa9b14d3af386bd142a645212540f32208cb5d93be25ba643ee760f56624cd051e53ca0e7047e4a95a5faf82f0636f60d0a8b021288020a2a0a0408b0ea0112220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a1012520a50e0783360338067fc2ba548f460b3f06f33d3e756ebefa8a8c08c5e12a1e667df228df0720fb9bd963894183bc447e1c7ef591fa9625d4a66b7703eec2ec1ef543454673bb61a4f2a3d861114d6891d691a20cde64106162059a6800918036eb3c0e9b2872f56d4902259fba9b52d18dbd7c52220a1417029703aa865b08f19acc96eba15928a2178956f6c9c538ea5577a03ef032a20df5538e38602a2bd15119182c50d0f1b22fd8deba0a728a8fbbfb7e9b8c6fc0932207dee2a1d6d9c85ba68560cfa514b73897e77fe0355d92c9cc2bb3b522b5f3d110abc021ab9020ad0010a480a220a20116d0cd6de9349c686f5802f7c98179e70d4898a38e1cc3df93705c94e941d0c12220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a10120408a08d061a02080122040a0208032a520a50e0783360338067fc2ba548f460b3f06f33d3e756ebefa8a8c08c5e12a1e667df228df0720fb9bd963894183bc447e1c7ef591fa9625d4a66b7703eec2ec1ef543454673bb61a4f2a3d861114d6891d69322057798bc1a097c26b47e61a9870ca98eb8cbe48e9cba4db86f5d8b67c12086afb1220fbf22b3005fdd84a03bdf0950c851a9c6e0618b0eea1004ca75e53ce3deef1031a205f9ddbd8093a028de6597d03d785302d8336e20a2148e15ae016bad0536d7e0122200d358f3968b24d5e612504b211cadb44ace485ceb3ad38821aa96b926279e6001213120d70656e756d6272612d746573741a020a0022f4012a780a520a50e0783360338067fc2ba548f460b3f06f33d3e756ebefa8a8c08c5e12a1e667df228df0720fb9bd963894183bc447e1c7ef591fa9625d4a66b7703eec2ec1ef543454673bb61a4f2a3d861114d6891d691220361218d216cfe90f77f54f045ff21b464795517c05057c595fd59e4958e3941718032a780a520a50e0783360338067fc2ba548f460b3f06f33d3e756ebefa8a8c08c5e12a1e667df228df0720fb9bd963894183bc447e1c7ef591fa9625d4a66b7703eec2ec1ef543454673bb61a4f2a3d861114d6891d69122013296da8c9dfdf969be7c7bd74e67e80977cd91635eb32038619f62c732dc46a18022a780a540a520a506ece16f387e0b932082cb0cf6823590fc287d068d6f684a36d1fb19bfd6dce8b22850f535824aeb66cb8c41309e6f5b2d58ff7b651ef4e09a09c7e48d770d190880e1827b47823a1d01f0c4b438a7b43122018bd5cedd0eb952244a296c1e3fba4f417ebdcc1cfec04cb9441a394316a58bd'
'0aaf020aac020aa1010a290a0308954e12220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a101220c923f2f89ccea2aafe13dca34d083faf4894f156f604dc3d4817bf6717096e331a520a50e0783360338067fc2ba548f460b3f06f33d3e756ebefa8a8c08c5e12a1e667df228df0720fb9bd963894183bc447e1c7ef591fa9625d4a66b7703eec2ec1ef543454673bb61a4f2a3d861114d6891d691a2080b306db5db558a2d0cd19ad587c1f28b5b9f8139901ade057cba921fc76c7032220bf3a56c1b6236f007ea136ad1fb0735e03e4ccae3a5c93af28326485e3bb65002a20f7298845c66cba673959f9d3ca44d0831c90cd925c92afc1cf5299185a3f120b32202d700f646468f7434f34adc9854d8e8e5b8bb86d35f343db0fd8126ce49ad6030ab2020aaf020aa2010a2a0a0408a09c0112220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a1012204988c0704b1c5beb92aa58168d75e32e8edbd60c2e7ec470bc50440f1a21f3eb1a520a50e0783360338067fc2ba548f460b3f06f33d3e756ebefa8a8c08c5e12a1e667df228df0720fb9bd963894183bc447e1c7ef591fa9625d4a66b7703eec2ec1ef543454673bb61a4f2a3d861114d6891d6910011a205550f06f9c3ba695c9bab8f317cc4bcd7f62e90f80de421ae70161678cc4200322200e93266e84a34cce2bd5b6021d78226e68f6f760b688765ddbc19b451ced11022a2069e48038c64d148608a27e9846ff74a85b0bc86188f3e5ca037c20b16476ff0032209ee9410d61a376540f140f88d38b0785f8c7852bd11512ea92281003aad805030a8b021288020a2a0a0408b0ea0112220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a1012520a50e0783360338067fc2ba548f460b3f06f33d3e756ebefa8a8c08c5e12a1e667df228df0720fb9bd963894183bc447e1c7ef591fa9625d4a66b7703eec2ec1ef543454673bb61a4f2a3d861114d6891d691a20cee6fb736d421932e6c2b895ae1a0f65b6769ddbf96dfec8d0965d1487549e6622205994ad1abed78f6b5d48fc72eb114742d1b04f94a842621897eca948beb91c002a206c5beeab2d967b5347e002a7e453abee0ee9d9f0239fbc855c05502cdca459113220df0cd5b18b09548339a7d13e8fcdb6a5a8f0dc7fc8a587aa74ee746df2bba1100abc021ab9020ad0010a480a220a20116d0cd6de9349c686f5802f7c98179e70d4898a38e1cc3df93705c94e941d0c12220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a10120408a08d061a02080122040a0208032a520a50e0783360338067fc2ba548f460b3f06f33d3e756ebefa8a8c08c5e12a1e667df228df0720fb9bd963894183bc447e1c7ef591fa9625d4a66b7703eec2ec1ef543454673bb61a4f2a3d861114d6891d69322096f795c0f70ae89247c62febde1488f3673b0fd48e03517b60b17fcc375d2fa912202efb6351ce1af7c5612481ad4660fd184db5e73908224455b50d7fe79f2bdf001a20a4cfed973f3f025070f6de90d2a2ea1336922cce1fbf0f1be443554e9652770a222081dc04672db59a2d011d82aa980a50012de22048b59f719e626f7c15b64a2e111213120d70656e756d6272612d746573741a020a0022f4012a780a520a50e0783360338067fc2ba548f460b3f06f33d3e756ebefa8a8c08c5e12a1e667df228df0720fb9bd963894183bc447e1c7ef591fa9625d4a66b7703eec2ec1ef543454673bb61a4f2a3d861114d6891d69122083f70f7faa82e24925010fd9fd248fb2bf16f96fb3d1f2aa984696b4f91fbc8d18032a780a520a50e0783360338067fc2ba548f460b3f06f33d3e756ebefa8a8c08c5e12a1e667df228df0720fb9bd963894183bc447e1c7ef591fa9625d4a66b7703eec2ec1ef543454673bb61a4f2a3d861114d6891d6912209ce6c8171c50847dffc5112fde5e1245fa1e561ea4ef2b0259ee3443fb9b26eb18022a780a540a520a50a39eff5d22636e107f0d0797fe9d89d79c98326fe640f8ef8dbe738148555c6d9f9bfc4059a190226bca124981087b604539638a0b16fd0a3ea73d47bb40604a02607ab23ffe910f636ba4b307db3cde1220a19b520a3749f7511bb02e0eed2e51fb2a6019920cb9dc7ba3f41906c91305c1'

50 changes: 25 additions & 25 deletions tests_zemu/tests/standard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,31 +184,31 @@ describe('Standard', function () {
})

// TODO: WIP
// test.concurrent.each(models)('sign', async function (m) {
// const sim = new Zemu(m.path)
// try {
// await sim.start({ ...defaultOptions, model: m.name })
// const app = new PenumbraApp(sim.getTransport())

// const messageToSign = Buffer.from(txBlobExample, 'hex')
// console.log("messageToSignLength!!!!!", messageToSign.length)
// console.log("messageToSign!!!!!", messageToSign)
// // do not wait here... we need to navigate
// const signatureRequest = app.sign(PEN_PATH, ACCOUNT_ID, messageToSign)

// // Wait until we are not in the main menu
// // await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot())
// // await sim.compareSnapshotsAndApprove('.', `${m.prefix.toLowerCase()}-sign`)
test.only.each(models)('sign', async function (m) {
const sim = new Zemu(m.path)
try {
await sim.start({ ...defaultOptions, model: m.name })
const app = new PenumbraApp(sim.getTransport())

const messageToSign = Buffer.from(txBlobExample, 'hex')
console.log("messageToSignLength!!!!!", messageToSign.length)
console.log("messageToSign!!!!!", messageToSign)
// do not wait here... we need to navigate
const signatureRequest = app.sign(PEN_PATH, ACCOUNT_ID, messageToSign)

// Wait until we are not in the main menu
// await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot())
// await sim.compareSnapshotsAndApprove('.', `${m.prefix.toLowerCase()}-sign`)


// const signatureResponse = await signatureRequest
// console.log(signatureResponse)

// // Now verify the signature
// // const valid = ed25519.verify(signatureResponse.signature, messageToSign, pubKey)
// // expect(valid).toEqual(true)
// } finally {
// await sim.close()
// }
// })
const signatureResponse = await signatureRequest
console.log(signatureResponse)

// Now verify the signature
// const valid = ed25519.verify(signatureResponse.signature, messageToSign, pubKey)
// expect(valid).toEqual(true)
} finally {
await sim.close()
}
})
})

0 comments on commit 0505887

Please sign in to comment.