Skip to content

Commit

Permalink
Add ics20 parser
Browse files Browse the repository at this point in the history
  • Loading branch information
abenso committed Nov 26, 2024
1 parent 664b16f commit 8f93643
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 153 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ file(GLOB_RECURSE LIB_SRC
${CMAKE_CURRENT_SOURCE_DIR}/app/src/plan/output_plan.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/plan/delegate_plan.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/plan/undelegate_plan.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/plan/ics20_withdrawal.c
)

add_library(app_lib STATIC ${LIB_SRC})
Expand Down
3 changes: 3 additions & 0 deletions app/rust/src/parser/plans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ pub unsafe extern "C" fn rs_generic_action_hash(
ActionPlan::Undelegate => {
effect_hash = EffectHash::from_proto_effecting_data("/penumbra.core.component.stake.v1.Undelegate", data_to_hash);
}
ActionPlan::Ics20Withdrawal => {
effect_hash = EffectHash::from_proto_effecting_data("/penumbra.core.component.ibc.v1.Ics20Withdrawal", data_to_hash);
}
_ => {
return ParserError::UnexpectedData as u32;
}
Expand Down
18 changes: 15 additions & 3 deletions app/src/parser_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "output_plan.h"
#include "delegate_plan.h"
#include "undelegate_plan.h"
#include "ics20_withdrawal.h"
#include "zxformat.h"

static bool decode_action(pb_istream_t *stream, const pb_field_t *field, void **arg);
Expand All @@ -34,7 +35,9 @@ static uint16_t actions_qty = 0;
static uint16_t detection_data_qty = 0;

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;
if (arg == NULL || *arg == NULL) {
return false;
}

action_t *decode_arg = (action_t *)*arg;
if (decode_arg == NULL) {
Expand All @@ -45,27 +48,36 @@ bool decode_action(pb_istream_t *stream, const pb_field_t *field, void **arg) {
return false;
}

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

decode_arg[actions_qty].action_data = action_data;
bytes_t action_data = {.ptr = stream->state + 3, .len = stream->bytes_left - 3};
bytes_t ics20_withdrawal_data = {.ptr = stream->state + 4, .len = stream->bytes_left - 4};

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_arg[actions_qty].action_data = action_data;
CHECK_ERROR(decode_spend_plan(&action_data, &decode_arg[actions_qty].action.spend));
break;
case penumbra_core_transaction_v1_ActionPlan_output_tag:
decode_arg[actions_qty].action_data = action_data;
CHECK_ERROR(decode_output_plan(&action_data, &decode_arg[actions_qty].action.output));
break;
case penumbra_core_transaction_v1_ActionPlan_delegate_tag:
decode_arg[actions_qty].action_data = action_data;
CHECK_ERROR(decode_delegate_plan(&action_data, &decode_arg[actions_qty].action.delegate));
break;
case penumbra_core_transaction_v1_ActionPlan_undelegate_tag:
decode_arg[actions_qty].action_data = action_data;
CHECK_ERROR(decode_undelegate_plan(&action_data, &decode_arg[actions_qty].action.undelegate));
break;
case penumbra_core_transaction_v1_ActionPlan_ics20_withdrawal_tag:
decode_arg[actions_qty].action_data = ics20_withdrawal_data;
CHECK_ERROR(decode_ics20_withdrawal_plan(&ics20_withdrawal_data, &decode_arg[actions_qty].action.ics20_withdrawal));
break;
default:
return false;
}
Expand Down
1 change: 1 addition & 0 deletions app/src/parser_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ zxerr_t compute_action_hash(action_t *action, spend_key_bytes_t *sk_bytes, bytes
break;
case penumbra_core_transaction_v1_ActionPlan_delegate_tag:
case penumbra_core_transaction_v1_ActionPlan_undelegate_tag:
case penumbra_core_transaction_v1_ActionPlan_ics20_withdrawal_tag:
if (rs_generic_action_hash(&action->action_data, action->action_type, (uint8_t *)output, 64) != parser_ok) {
return zxerr_encoding_failed;
}
Expand Down
26 changes: 26 additions & 0 deletions app/src/parser_txdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ typedef struct {
asset_id_t asset_id;
} fee_t;

typedef struct {
bytes_t inner;
} denom_t;

typedef struct {
uint64_t revision_number;
uint64_t revision_height;
} height_t;

typedef struct {
note_t note;
uint64_t position;
Expand Down Expand Up @@ -123,6 +132,22 @@ typedef struct {
bool has_from_epoch;
epoch_t from_epoch;
} undelegate_plan_t;

typedef struct {
bool has_amount;
amount_t amount;
bool has_denom;
denom_t denom;
bytes_t destination_chain_address;
bool has_return_address;
address_plan_t return_address;
bool has_timeout_height;
height_t timeout_height;
uint64_t timeout_time;
bytes_t source_channel;
bool use_compat_address;
} ics20_withdrawal_plan_t;

typedef struct {
address_plan_t return_address;
bytes_t text;
Expand Down Expand Up @@ -151,6 +176,7 @@ typedef struct {
output_plan_t output;
delegate_plan_t delegate;
undelegate_plan_t undelegate;
ics20_withdrawal_plan_t ics20_withdrawal;
} action;
} action_t;

Expand Down
61 changes: 61 additions & 0 deletions app/src/plan/ics20_withdrawal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*******************************************************************************
* (c) 2018 - 2023 Zondax AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/

#include "parser_impl.h"
#include "parser_interface.h"
#include "parser_pb_utils.h"
#include "pb_common.h"
#include "pb_decode.h"
#include "protobuf/penumbra/core/transaction/v1/transaction.pb.h"
#include "zxformat.h"

parser_error_t decode_ics20_withdrawal_plan(const bytes_t *data, ics20_withdrawal_plan_t *withdrawal) {
penumbra_core_component_ibc_v1_Ics20Withdrawal withdrawal_plan = penumbra_core_component_ibc_v1_Ics20Withdrawal_init_default;

pb_istream_t withdrawal_stream = pb_istream_from_buffer(data->ptr, data->len);
CHECK_APP_CANARY()

// Set up fixed size fields
fixed_size_field_t return_address_arg;
setup_decode_fixed_field(&withdrawal_plan.return_address.inner, &return_address_arg, &withdrawal->return_address.inner, 80);

// Set up variable size fields
variable_size_field_t denom_arg, destination_chain_address_arg, source_channel_arg;
setup_decode_variable_field(&withdrawal_plan.denom.denom, &denom_arg, &withdrawal->denom.inner);
setup_decode_variable_field(&withdrawal_plan.destination_chain_address, &destination_chain_address_arg, &withdrawal->destination_chain_address);
setup_decode_variable_field(&withdrawal_plan.source_channel, &source_channel_arg, &withdrawal->source_channel);

if (!pb_decode(&withdrawal_stream, penumbra_core_component_ibc_v1_Ics20Withdrawal_fields, &withdrawal_plan)) {
return parser_undelegate_plan_error;
}

withdrawal->has_amount = withdrawal_plan.has_amount;
if (withdrawal_plan.has_amount) {
withdrawal->amount.lo = withdrawal_plan.amount.lo;
withdrawal->amount.hi = withdrawal_plan.amount.hi;
}
withdrawal->has_denom = withdrawal_plan.has_denom;
withdrawal->has_return_address = withdrawal_plan.has_return_address;
withdrawal->has_timeout_height = withdrawal_plan.has_timeout_height;
if (withdrawal_plan.has_timeout_height) {
withdrawal->timeout_height.revision_number = withdrawal_plan.timeout_height.revision_number;
withdrawal->timeout_height.revision_height = withdrawal_plan.timeout_height.revision_height;
}
withdrawal->timeout_time = withdrawal_plan.timeout_time;
withdrawal->use_compat_address = withdrawal_plan.use_compat_address;

return parser_ok;
}
37 changes: 37 additions & 0 deletions app/src/plan/ics20_withdrawal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*******************************************************************************
* (c) 2018 - 2023 Zondax AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#pragma once

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <zxmacros.h>

#include "parser_common.h"
#include "parser_txdef.h"
#include "pb_common.h"
#include "pb_decode.h"
#include "zxtypes.h"

#ifdef __cplusplus
extern "C" {
#endif

parser_error_t decode_ics20_withdrawal_plan(const bytes_t *data, ics20_withdrawal_plan_t *withdrawal);

#ifdef __cplusplus
}
#endif
Loading

0 comments on commit 8f93643

Please sign in to comment.