Skip to content

Commit

Permalink
Add position close action (#30)
Browse files Browse the repository at this point in the history
* add parser and effect hash computation

* add ui
  • Loading branch information
abenso authored Jan 20, 2025
1 parent f55c63c commit 46a06a3
Show file tree
Hide file tree
Showing 16 changed files with 4,649 additions and 4,428 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ file(GLOB_RECURSE LIB_SRC
${CMAKE_CURRENT_SOURCE_DIR}/app/src/plan/undelegate_claim.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/plan/delegator_vote.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/plan/position_open.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/plan/position_close.c
)

add_library(app_lib STATIC ${LIB_SRC})
Expand Down
6 changes: 6 additions & 0 deletions app/rust/src/parser/plans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,12 @@ pub unsafe extern "C" fn rs_generic_action_hash(
data_to_hash,
);
}
ActionPlan::PositionClose => {
effect_hash = EffectHash::from_proto_effecting_data(
"/penumbra.core.component.dex.v1.PositionClose",
data_to_hash,
);
}
_ => {
return ParserError::UnexpectedData as u32;
}
Expand Down
6 changes: 6 additions & 0 deletions app/src/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
#define IDENTITY_KEY_BECH32_PREFIX "penumbravalid"
#define IDENTITY_KEY_LEN 32

#define POSITION_ID_BECH32_PREFIX "plpid"
#define POSITION_ID_LEN 32

// Common BECH32m constants
#define CHECKSUM_LENGTH 8
#define BECH32_BITS_PER_CHAR 5
Expand Down Expand Up @@ -105,3 +108,6 @@

// Constant to use to allocate a buffer on the stack to hold the formatting of an position_open action
#define POSITION_OPEN_DISPLAY_MAX_LEN (2 * VALUE_DISPLAY_MAX_LEN + 110) // = 434

// Constant to use to allocate a buffer on the stack to hold the formatting of an position_close action
#define POSITION_CLOSE_DISPLAY_MAX_LEN 100 // = 100
14 changes: 11 additions & 3 deletions app/src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@
#include "parameters.h"
#include "parser_common.h"
#include "parser_impl.h"
#include "position_close.h"
#include "position_open.h"
#include "spend.h"
#include "swap.h"
#include "tx_metadata.h"
#include "undelegate.h"
#include "undelegate_claim.h"
#include "position_open.h"

static uint8_t action_idx = 0;

Expand Down Expand Up @@ -120,6 +121,9 @@ parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_item
case penumbra_core_transaction_v1_ActionPlan_position_open_tag:
CHECK_ERROR(position_open_getNumItems(ctx, &action_num_items));
break;
case penumbra_core_transaction_v1_ActionPlan_position_close_tag:
CHECK_ERROR(position_close_getNumItems(ctx, &action_num_items));
break;
default:
return parser_unexpected_error;
}
Expand Down Expand Up @@ -220,8 +224,12 @@ parser_error_t parser_getItem(const parser_context_t *ctx, uint8_t displayIdx, c
action_idx + 1, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount))
break;
case penumbra_core_transaction_v1_ActionPlan_position_open_tag:
CHECK_ERROR(position_open_getItem(ctx, &ctx->tx_obj->actions_plan[action_idx].action.position_open, action_idx + 1,
outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount))
CHECK_ERROR(position_open_getItem(ctx, &ctx->tx_obj->actions_plan[action_idx].action.position_open,
action_idx + 1, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount))
break;
case penumbra_core_transaction_v1_ActionPlan_position_close_tag:
CHECK_ERROR(position_close_getItem(ctx, &ctx->tx_obj->actions_plan[action_idx].action.position_close,
action_idx + 1, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount))
break;
default:
return parser_unexpected_error;
Expand Down
7 changes: 6 additions & 1 deletion app/src/parser_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@
#include "parser_pb_utils.h"
#include "pb_common.h"
#include "pb_decode.h"
#include "position_close.h"
#include "position_open.h"
#include "protobuf/penumbra/core/transaction/v1/transaction.pb.h"
#include "spend.h"
#include "swap.h"
#include "undelegate.h"
#include "undelegate_claim.h"
#include "position_open.h"
#include "zxformat.h"

#define ACTION_OFFSET_3 3
Expand Down Expand Up @@ -122,6 +123,10 @@ bool decode_action(pb_istream_t *stream, const pb_field_t *field, void **arg) {
decode_arg[actions_qty].action_data = action_data_4;
CHECK_ACTION_ERROR(decode_position_open_plan(&action_data_4, &decode_arg[actions_qty].action.position_open));
break;
case penumbra_core_transaction_v1_ActionPlan_position_close_tag:
decode_arg[actions_qty].action_data = action_data_3;
CHECK_ACTION_ERROR(decode_position_close_plan(&action_data_3, &decode_arg[actions_qty].action.position_close));
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 @@ -71,6 +71,7 @@ zxerr_t compute_action_hash(action_t *action, bytes_t *memo_key, hash_t *output)
case penumbra_core_transaction_v1_ActionPlan_delegate_tag:
case penumbra_core_transaction_v1_ActionPlan_undelegate_tag:
case penumbra_core_transaction_v1_ActionPlan_position_open_tag:
case penumbra_core_transaction_v1_ActionPlan_position_close_tag:
if (rs_generic_action_hash(&action->action_data, action->action_type, (uint8_t *)output, 64) != parser_ok) {
return zxerr_encoding_failed;
}
Expand Down
10 changes: 10 additions & 0 deletions app/src/parser_txdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ typedef struct {
bool close_on_fill;
} position_t;

typedef struct {
bytes_t inner;
} position_id_t;

typedef struct {
note_t note;
uint64_t position;
Expand Down Expand Up @@ -284,6 +288,11 @@ typedef struct {
position_t position;
} position_open_plan_t;

typedef struct {
bool has_position_id;
position_id_t position_id;
} position_close_plan_t;

typedef struct {
address_plan_t return_address;
bytes_t text;
Expand Down Expand Up @@ -317,6 +326,7 @@ typedef struct {
undelegate_claim_plan_t undelegate_claim;
delegator_vote_plan_t delegator_vote;
position_open_plan_t position_open;
position_close_plan_t position_close;
} action;
} action_t;

Expand Down
89 changes: 89 additions & 0 deletions app/src/plan/position_close.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*******************************************************************************
* (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 "position_close.h"

#include "note.h"
#include "parser_pb_utils.h"
#include "ui_utils.h"
#include "zxformat.h"

parser_error_t decode_position_close_plan(const bytes_t *data, position_close_plan_t *position_close) {
penumbra_core_component_dex_v1_PositionClose position_close_pb =
penumbra_core_component_dex_v1_PositionClose_init_default;

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

// Set up fixed size fields
fixed_size_field_t position_id_arg;
setup_decode_fixed_field(&position_close_pb.position_id.inner, &position_id_arg, &position_close->position_id.inner,
ASSET_ID_LEN);

if (!pb_decode(&stream, penumbra_core_component_dex_v1_PositionClose_fields, &position_close_pb)) {
return parser_output_plan_error;
}

position_close->has_position_id = position_close_pb.has_position_id;

return parser_ok;
}

parser_error_t position_close_getNumItems(const parser_context_t *ctx, uint8_t *num_items) {
UNUSED(ctx);
*num_items = 1;
return parser_ok;
}

parser_error_t position_close_getItem(const parser_context_t *ctx, const position_close_plan_t *position_close,
uint8_t actionIdx, char *outKey, uint16_t outKeyLen, char *outVal, uint16_t outValLen,
uint8_t pageIdx, uint8_t *pageCount) {
parser_error_t err = parser_no_data;
if (position_close == NULL || outKey == NULL || outVal == NULL || outKeyLen == 0 || outValLen == 0) {
return err;
}

char bufferUI[POSITION_CLOSE_DISPLAY_MAX_LEN] = {0};

snprintf(outKey, outKeyLen, "Action_%d", actionIdx);
CHECK_ERROR(position_close_printValue(ctx, position_close, bufferUI, sizeof(bufferUI)));
pageString(outVal, outValLen, bufferUI, pageIdx, pageCount);

return parser_ok;
}

parser_error_t position_close_printValue(const parser_context_t *ctx, const position_close_plan_t *position_close,
char *outVal, uint16_t outValLen) {
if (ctx == NULL || position_close == NULL || outVal == NULL) {
return parser_no_data;
}

if (outValLen < POSITION_CLOSE_DISPLAY_MAX_LEN) {
return parser_unexpected_buffer_end;
}

MEMZERO(outVal, outValLen);

// add action title
snprintf(outVal, outValLen, "PositionClose Position ID ");
uint16_t written_value = strlen(outVal);

MEMCPY(outVal + written_value, position_close->position_id.inner.ptr, position_close->position_id.inner.len);

CHECK_ERROR(encodePositionId(position_close->position_id.inner.ptr, position_close->position_id.inner.len,
outVal + written_value, outValLen - written_value));

return parser_ok;
}
35 changes: 35 additions & 0 deletions app/src/plan/position_close.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*******************************************************************************
* (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 <zxmacros.h>

#include "parser_common.h"

#ifdef __cplusplus
extern "C" {
#endif

parser_error_t decode_position_close_plan(const bytes_t *data, position_close_plan_t *output);
parser_error_t position_close_getNumItems(const parser_context_t *ctx, uint8_t *num_items);
parser_error_t position_close_getItem(const parser_context_t *ctx, const position_close_plan_t *output, uint8_t displayIdx,
char *outKey, uint16_t outKeyLen, char *outVal, uint16_t outValLen, uint8_t actionIdx,
uint8_t *pageCount);
parser_error_t position_close_printValue(const parser_context_t *ctx, const position_close_plan_t *output, char *outVal,
uint16_t outValLen);
#ifdef __cplusplus
}
#endif
3 changes: 1 addition & 2 deletions app/src/plan/position_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,7 @@ parser_error_t position_open_printValue(const parser_context_t *ctx, const posit
// add close_on_fill
if (position_open->position.close_on_fill) {
snprintf(outVal + written_value, outValLen - written_value, " Close on fill: true");
}
}

return parser_ok;
}

8 changes: 5 additions & 3 deletions app/src/plan/position_open.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ extern "C" {

parser_error_t decode_position_open_plan(const bytes_t *data, position_open_plan_t *output);
parser_error_t position_open_getNumItems(const parser_context_t *ctx, uint8_t *num_items);
parser_error_t position_open_getItem(const parser_context_t *ctx, const position_open_plan_t *output, uint8_t displayIdx, char *outKey,
uint16_t outKeyLen, char *outVal, uint16_t outValLen, uint8_t actionIdx, uint8_t *pageCount);
parser_error_t position_open_printValue(const parser_context_t *ctx, const position_open_plan_t *output, char *outVal, uint16_t outValLen);
parser_error_t position_open_getItem(const parser_context_t *ctx, const position_open_plan_t *output, uint8_t displayIdx,
char *outKey, uint16_t outKeyLen, char *outVal, uint16_t outValLen, uint8_t actionIdx,
uint8_t *pageCount);
parser_error_t position_open_printValue(const parser_context_t *ctx, const position_open_plan_t *output, char *outVal,
uint16_t outValLen);
#ifdef __cplusplus
}
#endif
9 changes: 9 additions & 0 deletions app/src/ui_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ parser_error_t encodeIdentityKey(const uint8_t *identity_key, uint16_t identity_
identity_key_len, out, out_len);
}

parser_error_t encodePositionId(const uint8_t *position_id, uint16_t position_id_len, char *out, uint16_t out_len) {
// Validate input length
if (position_id_len != POSITION_ID_LEN) {
return parser_invalid_address;
}
return printBech32Encoded(POSITION_ID_BECH32_PREFIX, sizeof(POSITION_ID_BECH32_PREFIX) - 1, position_id, position_id_len,
out, out_len);
}

parser_error_t uint128_to_str(char *data, int dataLen, uint64_t high, uint64_t low) {
if (data == NULL) return parser_no_data;
if (dataLen < U128_STR_MAX_LEN) return parser_value_out_of_range;
Expand Down
1 change: 1 addition & 0 deletions app/src/ui_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ parser_error_t printShortAddress(const uint8_t *address, uint16_t address_len, c
parser_error_t encodeAddress(const uint8_t *address, uint16_t address_len, char *out, uint16_t out_len);
parser_error_t printAssetId(const uint8_t *asset, uint16_t asset_len, char *out, uint16_t out_len);
parser_error_t encodeIdentityKey(const uint8_t *identity_key, uint16_t identity_key_len, char *out, uint16_t out_len);
parser_error_t encodePositionId(const uint8_t *position_id, uint16_t position_id_len, char *out, uint16_t out_len);

/**
* Converts a 128-bit unsigned integer to its decimal string representation.
Expand Down
23 changes: 5 additions & 18 deletions tests/parser_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,9 @@ TEST(SCALE, ReadBytes) {
zxerr_t zxerr;

uint8_t buffer[6000];
auto bufferLen = parseHexString(
buffer, sizeof(buffer),
"0aaf01f201ab010aa8010a640a18120a08e0ec81d6c1b2b59b021a0a08fefa92ed958bd4a50d12480a220a2029ea9c2f3371f6a487e7e95c247"
"041f4a356f983eb064e5d2b3bcf322ca96a1012220a2029ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a10122000"
"000000000000000000000000000000000000000000000000000000000000001a02080122180a0a08c7f2cdf9f2e5fb8407120a08a0a7b4ef80c"
"ca0e20c280112311221626a2d3834333039393235303336313933333433373530393738363435343930351a0c0a0a08a2d5eb8ec9aab7cb092a"
"87040ae2030a520a505ba4d5f0ecdfe87e4d76f6c6adc54c0cebd5a29d5e3428409326920df48f88f9be38e96472777a885fdfe3a18ce9afbfb"
"27c0b262feda69c2146b334c0c918ad463a8468d15bb09664848ebe5e5fe30c128b03205863636e55203675752030627033617a207932392020"
"58556572677420647147202033497431692039553920205374766b593950687642207347784e2079546c7962353474753751674e72522038472"
"06173473237346f554e2073354b34436235203320564a6c3220744271456e79772078652047204b686f205146206a3920384e42764733793269"
"6c474a6a323339302044207a3269476e6c20453220695345563935656734636e572038662064306c315a46324c2032203072203137632039664"
"64f207a6e446b393520555438594e4c3878204866792052726437703876364220386e374170312020333349202035206e79322049566c386f20"
"69205639302020356f4620656453783920203834206f2066376e6b365677446920207a202038344b31392052445934206955516f44394245517"
"73746474f2075614f6a6632374a467320206431756a62207439506d2035783546303035206c6968596454382020476e46463973487647434f4a"
"52596f33384d6a6a475951207573472031352075344a70787365671220f79e4ad6b1d9f0bc7f268a0af4ce8cb14c34421bef47ae65a3f5428bf"
"54b035e");
auto bufferLen = parseHexString(buffer, sizeof(buffer),
"0a27fa01240a220a202e5581b4d438439f4801a1eece8f8d0c7c670ac383d5bb2bd36f7c5c8393e433121e0"
"8ed9906120a70656e756d6272612d311a0c0a0a08efe1c491a49cd7a80d");

err = parser_parse(&ctx, buffer, bufferLen, &tx_obj);
ASSERT_EQ(err, parser_ok) << parser_getErrorDescription(err);
Expand All @@ -71,8 +58,8 @@ TEST(SCALE, ReadBytes) {
ASSERT_EQ(zxerr, zxerr_ok);

std::string expected =
"54814cada1609da600716b8259c9e3206eec9b337e9217590b948ab7e0908180577e43063d40abd2fcce0c90aa4a33ed32fd6050bdf27f5bc4f"
"9576147bf4c82";
"2b1d981e9b0628512ea5d9f2ef7bf9670e876b6ad6289a50ad069b9cc54669d3d11951a481fc837d034d611f27f081b05f17a1243d5a2d1569b"
"0759f35c757e5";
char actual[129];
array_to_hexstr(actual, sizeof(actual), tx_obj.effect_hash, sizeof(tx_obj.effect_hash));

Expand Down
Loading

0 comments on commit 46a06a3

Please sign in to comment.