Skip to content

Commit

Permalink
delegation and undelegation effect hash
Browse files Browse the repository at this point in the history
  • Loading branch information
abenso committed Nov 19, 2024
1 parent f122a6f commit c922a21
Show file tree
Hide file tree
Showing 17 changed files with 273 additions and 185 deletions.
6 changes: 3 additions & 3 deletions app/rust/include/rslib.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ parser_error_t rs_compute_address(keys_t *keys, uint32_t account, uint8_t *rando

// use to compute the full-viewing key
parser_error_t rs_compute_keys(keys_t *keys);
int32_t rs_bech32_encode(const uint8_t *hrp_ptr, size_t hrp_len, const uint8_t *data_ptr, size_t data_len,
uint8_t *output_ptr, size_t output_len);

parser_error_t rs_compute_transaction_plan(transaction_plan_t *plan, uint8_t *output, size_t output_len);

parser_error_t rs_spend_action_hash(spend_key_bytes_t *sk, spend_plan_t *plan, uint8_t *output, size_t output_len);
parser_error_t rs_output_action_hash(spend_key_bytes_t *sk, output_plan_t *plan, bytes_t *memo_key, uint8_t *output, size_t output_len);

int32_t rs_bech32_encode(const uint8_t *hrp_ptr, size_t hrp_len, const uint8_t *data_ptr, size_t data_len,
uint8_t *output_ptr, size_t output_len);
parser_error_t rs_generic_action_hash(bytes_t *data, uint8_t action_type, uint8_t *output, size_t output_len);

#ifdef __cplusplus
}
Expand Down
2 changes: 0 additions & 2 deletions app/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,13 @@ use arrayref as _;
pub(crate) mod address;
mod bolos;
pub mod constants;
pub mod effect_hash;
pub mod ffi;
pub(crate) mod keys;
pub mod network;
pub mod parser;
mod utils;
pub mod wallet_id;

pub use effect_hash::EffectHash;
pub use parser::{FromBytes, ParserError, ViewError};
pub(crate) use utils::prf::{expand_fq, expand_fr};

Expand Down
2 changes: 1 addition & 1 deletion app/rust/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub mod nullifier;
pub mod rseed;
pub mod symmetric;
pub mod value;

pub mod effect_hash;
pub use error::ParserError;

#[derive(Clone, Copy, PartialEq, Eq)]
Expand Down
34 changes: 31 additions & 3 deletions app/rust/src/parser/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,37 @@ use crate::constants::ACTION_DATA_QTY;

#[derive(Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum ActionType {
Spend = 0,
Output = 1,
pub enum ActionPlan {
Spend = 1,
Output = 2,
Swap = 3,
SwapClaim = 4,
ValidatorDefinition = 16,
IbcAction = 17,
ProposalSubmit = 18,
ProposalWithdraw = 19,
ValidatorVote = 20,
DelegatorVote = 21,
ProposalDepositClaim = 22,
PositionOpen = 30,
PositionClose = 31,
PositionWithdraw = 32,
Delegate = 40,
Undelegate = 41,
UndelegateClaim = 42,
CommunityPoolSpend = 50,
CommunityPoolOutput = 51,
CommunityPoolDeposit = 52,
Ics20Withdrawal = 200,
ActionDutchAuctionSchedule = 53,
ActionDutchAuctionEnd = 54,
ActionDutchAuctionWithdraw = 55,
}

impl ActionPlan {
pub fn from(action_type: u8) -> Self {
unsafe { std::mem::transmute(action_type) }
}
}

#[repr(C)]
Expand Down
2 changes: 1 addition & 1 deletion app/rust/src/parser/detection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

use crate::address::Address;
use crate::constants::DETECTION_DATA_QTY;
use crate::effect_hash::{create_personalized_state, EffectHash};
use crate::parser::effect_hash::{create_personalized_state, EffectHash};
use crate::parser::clue_plan::CluePlanC;
use crate::ParserError;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,17 @@ impl EffectHash {
pub fn from_array(array: [u8; 64]) -> Self {
EffectHash(array)
}
}

impl EffectHash {
pub fn as_bytes(&self) -> &[u8; 64] {
&self.0
}

pub fn from_proto_effecting_data(personalization: &str, data: &[u8]) -> EffectHash {
let mut state = create_personalized_state(personalization);
state.update(data);

EffectHash(*state.finalize().as_array())
}
}

impl AsRef<[u8]> for EffectHash {
Expand Down
3 changes: 2 additions & 1 deletion app/rust/src/parser/memo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ use super::memo_plain_text::MemoPlaintextC;
use super::symmetric::{PayloadKey, PayloadKind};
use crate::constants::{MEMO_CIPHERTEXT_LEN_BYTES, MEMO_LEN_BYTES};
use crate::ParserError;
use crate::{effect_hash::create_personalized_state, parser::bytes::BytesC, EffectHash};
use crate::parser::effect_hash::{create_personalized_state, EffectHash};
use crate::parser::bytes::BytesC;

#[repr(C)]
#[derive(Default)]
Expand Down
2 changes: 1 addition & 1 deletion app/rust/src/parser/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
use crate::effect_hash::{create_personalized_state, EffectHash};
use crate::parser::effect_hash::{create_personalized_state, EffectHash};

use super::bytes::BytesC;

Expand Down
42 changes: 41 additions & 1 deletion app/rust/src/parser/plans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ use crate::parser::{
detection::DetectionDataPlanC,
memo::MemoPlanC,
action::ActionsHashC,
action::ActionPlan,
};

use crate::keys::spend_key::SpendKeyBytes;
use crate::effect_hash::EffectHash;
use crate::parser::effect_hash::EffectHash;
use crate::parser::bytes::BytesC;
use crate::parser::parameters::TransactionParametersC;
use crate::ParserError;
Expand Down Expand Up @@ -147,6 +148,45 @@ pub unsafe extern "C" fn rs_output_action_hash(
ParserError::Ok as u32
}

#[no_mangle]
/// Use to compute an address and write it back into output
/// argument.
pub unsafe extern "C" fn rs_generic_action_hash(
data: &BytesC,
action_type: u8,
output: *mut u8,
output_len: usize,
) -> u32 {
crate::zlog("rs_generic_action_hash\x00");
let output = std::slice::from_raw_parts_mut(output, output_len);

if output.len() < 64 {
return ParserError::Ok as u32;
}

let action_type = ActionPlan::from(action_type);
let effect_hash: EffectHash;
if let Ok(data_to_hash) = data.get_bytes() {
match action_type {
ActionPlan::Delegate => {
effect_hash = EffectHash::from_proto_effecting_data("/penumbra.core.component.stake.v1.Delegate", data_to_hash);
}
ActionPlan::Undelegate => {
effect_hash = EffectHash::from_proto_effecting_data("/penumbra.core.component.stake.v1.Undelegate", data_to_hash);
}
_ => {
return ParserError::UnexpectedData as u32;
}
}

let body_hash_array = effect_hash.as_bytes();
let copy_len: usize = core::cmp::min(output.len(), body_hash_array.len());
output[..copy_len].copy_from_slice(&body_hash_array[..copy_len]);
}

ParserError::UnexpectedData as u32
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion app/rust/src/parser/plans/output.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::address::Address;
use crate::effect_hash::{create_personalized_state, EffectHash};
use crate::keys::FullViewingKey;
use crate::parser::note::Note;
use crate::parser::{
Expand All @@ -11,6 +10,7 @@ use crate::parser::{
value::{Sign, Value, ValueC},
commitment::Commitment,
symmetric::PayloadKey,
effect_hash::{create_personalized_state, EffectHash},
};
use crate::ParserError;
use decaf377::Fr;
Expand Down
2 changes: 1 addition & 1 deletion app/rust/src/parser/plans/spend.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::effect_hash::{create_personalized_state, EffectHash};
use crate::keys::FullViewingKey;
use crate::parser::{
bytes::BytesC,
note::{Note, NoteC},
commitment::Commitment,
nullifier::Nullifier,
value::{Sign, Value},
effect_hash::{create_personalized_state, EffectHash},
};
use crate::ParserError;
use decaf377::Fr;
Expand Down
15 changes: 9 additions & 6 deletions app/src/parser_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,12 @@ bool decode_action(pb_istream_t *stream, const pb_field_t *field, void **arg) {
return false;
}

bytes_t action_data;
action_data.ptr = stream->state + 3;
action_data.len = stream->bytes_left - 3;
bytes_t action_data = {
.ptr = stream->state + 3,
.len = stream->bytes_left - 3
};

decode_arg[actions_qty].action_data = action_data;

if (!pb_decode(stream, penumbra_core_transaction_v1_ActionPlan_fields, &action)) {
return false;
Expand Down Expand Up @@ -223,8 +226,8 @@ 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];
bytes_t data = {0};
action_t actions_plan[ACTIONS_QTY] = {0};
data.ptr = c->buffer;
data.len = c->bufferLen;
actions_qty = 0;
Expand Down Expand Up @@ -305,7 +308,7 @@ parser_error_t _read(parser_context_t *c, parser_tx_t *v) {
print_buffer(&v->plan.memo.plaintext.return_address.alt_bech32m, "real memo return address alt bech32m");

for (uint16_t i = 0; i < actions_qty; i++) {
compute_action_hash(&actions_plan[i].action.spend, actions_plan[i].action_type, &v->plan.actions.hashes[i]);
compute_action_hash(&actions_plan[i], &v->plan.actions.hashes[i]);
}
v->plan.actions.qty = actions_qty;

Expand Down
17 changes: 10 additions & 7 deletions app/src/parser_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ parser_error_t compute_transaction_plan(transaction_plan_t *plan, uint8_t *effec
return parser_ok;
}

parser_error_t compute_action_hash(spend_plan_t *plan, uint8_t action_type, action_hash_t *output) {
if (plan == NULL || output == NULL)
parser_error_t compute_action_hash(action_t *action, action_hash_t *output) {
if (action == NULL || output == NULL)
return parser_unexpected_error;

// TODO: we need to get the spend key
Expand All @@ -58,16 +58,19 @@ parser_error_t compute_action_hash(spend_plan_t *plan, uint8_t action_type, acti
};

bytes_t memo = {0};
switch (action_type) {
switch (action->action_type) {
case penumbra_core_transaction_v1_ActionPlan_spend_tag:
if (rs_spend_action_hash(&sk_bytes, plan, (uint8_t *)output, 64) != parser_ok) {
if (rs_spend_action_hash(&sk_bytes, &action->action.spend, (uint8_t *)output, 64) != parser_ok)
return parser_unexpected_error;
}
break;
case penumbra_core_transaction_v1_ActionPlan_output_tag:
if (rs_output_action_hash(&sk_bytes, plan, &memo, (uint8_t *)output, 64) != parser_ok) {
if (rs_output_action_hash(&sk_bytes, &action->action.output, &memo, (uint8_t *)output, 64) != parser_ok)
return parser_unexpected_error;
break;
case penumbra_core_transaction_v1_ActionPlan_delegate_tag:
case penumbra_core_transaction_v1_ActionPlan_undelegate_tag:
if (rs_generic_action_hash(&action->action_data, action->action_type, (uint8_t *)output, 64) != parser_ok)
return parser_unexpected_error;
}
break;
default:
return parser_unexpected_error;
Expand Down
2 changes: 1 addition & 1 deletion app/src/parser_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ extern "C" {
#include "zxmacros.h"

parser_error_t compute_transaction_plan(transaction_plan_t *plan, uint8_t *effect_hash, uint16_t effect_hash_len);
parser_error_t compute_action_hash(spend_plan_t *plan, uint8_t action_type, action_hash_t *output);
parser_error_t compute_action_hash(action_t *action, action_hash_t *output);

#ifdef __cplusplus
}
Expand Down
1 change: 1 addition & 0 deletions app/src/parser_txdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ typedef struct {

typedef struct {
uint8_t action_type;
bytes_t action_data;
union {
spend_plan_t spend;
output_plan_t output;
Expand Down
17 changes: 13 additions & 4 deletions tests/parser_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,26 @@
#include "gmock/gmock.h"
#include "parser.h"
#include "parser_txdef.h"
#include "zxformat.h"


using namespace std;

TEST(SCALE, ReadBytes) {
parser_context_t ctx;
parser_tx_t tx_obj;
parser_context_t ctx = {0};
parser_tx_t tx_obj = {0};
parser_error_t err;
uint8_t buffer[6000];
auto bufferLen = parseHexString(
buffer, sizeof(buffer),
"0a9102128e020a300a0a089e92c9dbf28597800112220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a1012520a5084506123bb61575ea404e7734087db179136b0e9cc1f62ff29880c5199fe8176c2a1b57c60b61d79b955d145b503c30d6e233b33ddc598b7f6404befdbb39b27c209cf3e7c43044106c9b90d500c74461a20e21e9d6e187cd382414758297fafb4b1a06a4dc6efb9299b2d70d72c0ceec288222099e2b31b8470c3b28a61342a4e8e9dc03aa89a2d1cdb55b19b4d82319df87e012a201be58b456e9d10eddfe2cb2839d554e1e36d25ae82b018355d0ce9b17e8e0a12322097c33e865ddc7b32075fe88f54f03a10a7a7758e354eb0efc49bcbb7fb2805040a9102128e020a300a0a08f89e99f6e2a8bea60812220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a1012520a503b0c5b6250417576213e2a7eeee16e9a816b91cef8336be9c5b1d125f9e6e2769ccbc85fdd2bd1d29e92e78e659d5801964116ecc280156d2247a9433b5bb803682e26e9b6fa4dc59f9a3fb0c9ce662a1a20160054d1d9ce5b6db1fa846074dca4df8929f8123551eb600a52a693ee0815ad2220bb71525bc61fb4cdb82087468a0944361a5c394e7f24262f488e459224be9d032a20cac86a6cc8ae51f861e3cc2f023f256c89d298b0194936eb2253d5d4bdf1800c322026e955748103e77c098257ca9df191006d6bcc1ba7e0577a1d91dff264a8d0000a9102128e020a300a0a088bca90dc90ada4850512220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a1012520a501a02f34fd21d6a56d6cd308717d955b580af5462dd56b06f95e9d1d3f41d172e5a5a64c34857aa962024132d576dc02b16f881198f2465b9565d475ac97040c96f7f742b4eda3028b5f8ad9a9ab4a19d1a203f9ea78658e69d1750a841138818dd7cc1c6cdd02456a522616e0ce44cb1211a22208c2fd85a84e184a6fa3d2f644f1f6efe1f53f22c60addb9b00db453364d018032a20fc29fc2dee02e0e42af1a7874da7988828c8b5685069e9faab7a79f1d9b7d40032209df349c1cdfd9d0dada6333b14282f93632cf1ee4578239640dd2e184eb9a7030abe020abb020aa8010a300a0a0891db8cc1cec2829a0112220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a101220e406c5db8fd46de42bfa23021b24fba56aed33dd995c82af14ee66331655a5271a520a50890bc98e3698aa4578e419b028da5672e627c280d8b06166f4c42d5366bccf1fcf3b296cd61e8d744a21f75f2fb697183e18595d8a79008539d8fb138b405db09db65cc42d54c0e772e5d42d5f20b52f108495d5d38a89171a205434dbfd666bd395970e388f5b40e17ec166ab8a373919944a746e15926305012220b9b89bf8112d8f70501a485aa4d2eadd427e21d7a7c4c480335a5e1845fd44002a20e653e5cdaa0c1bf13a739544df995658622d44c44d2bcc1f270597e694c3220232209375bb05762a06306e8c3c81778a875a638d969df8f567bb80a37b982a176f120abe020abb020aa8010a300a0a089dd8f2fad1e2ed9e0812220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a1012203ab4367b3b7a3957e045bf4b4f6ef49112883f20161e9ea815ff6c7e9b72a0281a520a50890bc98e3698aa4578e419b028da5672e627c280d8b06166f4c42d5366bccf1fcf3b296cd61e8d744a21f75f2fb697183e18595d8a79008539d8fb138b405db09db65cc42d54c0e772e5d42d5f20b52f1085d0e884e0d73c1a20b0b138c127a91b4ed70c1bfe86738d66da4179d24001bad903622a5cba86060422203a339b4017ef099f4fa9f0e9f538b4a412adf436aa4274042c5689b57a54d4002a20e22e518d5e3ca1364372bb41bf715a2b875913df69ef04d102cba287b376ae0132202f95351d4a308667fef2551c24ca71dfb38ebde9c4ea112a5fdf5aeaef49c70e125508eff9ada202123f6b6f62687462637676666b6665696c6571706766786e75656b6279666376762d323737383432363234373330323535303935353735323131303131353638391a0c0a0a08a8cbd3dbcd9be3aa0a");
"0a47ca02440a220a20f9b7b3723506cca29bdfb54b409d7ffff96f23aaa8998101f23ff9ec4c955c861a0a08b9a1f789a28c94de02220a08b5a8ba94d2b2ed8d032a0608d10910d109123808e0d6e5821b1223706e7964772d31383432333733323334373436313838363932363135333332333035341a0b0a0908c6e09fded6c3cb37");

err = parser_parse(&ctx, buffer, bufferLen, &tx_obj);
ASSERT_EQ(err, parser_ok) << parser_getErrorDescription(err);

//parser_parse(&ctx, buffer, bufferLen, &tx_obj);
std::string expected = "09cb80cda44cd051971bcc9fa1acc71a4d4366d52b2f4ee49fdc15eb18d30dbde75373d5cfbadf467277da61907a21ec8ce3d5dd9c04af70ee67ce4beff7bcae";
char actual[129];
array_to_hexstr(actual, sizeof(actual), tx_obj.effect_hash, sizeof(tx_obj.effect_hash));

EXPECT_EQ(std::string(actual), expected);
}
Loading

0 comments on commit c922a21

Please sign in to comment.