Skip to content

Commit

Permalink
action dutch auction withdraw support
Browse files Browse the repository at this point in the history
  • Loading branch information
abenso committed Jan 24, 2025
1 parent 3338ea0 commit 4449c8d
Show file tree
Hide file tree
Showing 17 changed files with 9,329 additions and 7,618 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ file(GLOB_RECURSE LIB_SRC
${CMAKE_CURRENT_SOURCE_DIR}/app/src/plan/position_withdraw.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/plan/action_dutch_auction_schedule.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/plan/action_dutch_auction_end.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/plan/action_dutch_auction_withdraw.c
)

add_library(app_lib STATIC ${LIB_SRC})
Expand Down
2 changes: 2 additions & 0 deletions app/rust/include/rslib.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ parser_error_t rs_swap_action_hash(swap_plan_t *plan, uint8_t *output, size_t ou
parser_error_t rs_undelegate_claim_action_hash(undelegate_claim_plan_t *plan, uint8_t *output, size_t output_len);
parser_error_t rs_delegator_vote_action_hash(delegator_vote_plan_t *plan, uint8_t *output, size_t output_len);
parser_error_t rs_position_withdraw_action_hash(position_withdraw_plan_t *plan, uint8_t *output, size_t output_len);
parser_error_t rs_action_dutch_auction_withdraw_action_hash(action_dutch_auction_withdraw_plan_t *plan, uint8_t *output,
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);

parser_error_t rs_get_asset_id_from_metadata(const bytes_t *metadata, uint8_t *asset_id, uint16_t asset_id_len);
Expand Down
7 changes: 7 additions & 0 deletions app/rust/src/parser/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ impl Commitment {
proto
}

pub fn to_proto_action_dutch_auction_withdraw(&self) -> [u8; Self::PROTO_LEN] {
let mut proto = [0u8; Self::PROTO_LEN];
proto[0..4].copy_from_slice(&[0x1a, 0x22, 0x0a, 0x20]);
proto[4..].copy_from_slice(&self.0 .0);
proto
}

/// Returns the vartime_compress byte representation
/// of the internal defac377::Element
pub fn bytes_compress(&self) -> [u8; Self::LEN] {
Expand Down
1 change: 1 addition & 0 deletions app/rust/src/parser/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub enum ParserError {
PositionWithdrawPlanError,
DutchAuctionSchedulePlanError,
DutchAuctionEndPlanError,
DutchAuctionWithdrawPlanError,

// Chain related
InvalidChainId,
Expand Down
100 changes: 100 additions & 0 deletions app/rust/src/parser/plans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use crate::parser::effect_hash::EffectHash;
use crate::parser::parameters::ParametersHash;
use crate::ParserError;

pub mod action_dutch_auction_withdraw;
pub mod delegator_vote;
pub mod output;
pub mod position_withdraw;
Expand Down Expand Up @@ -311,6 +312,34 @@ pub unsafe extern "C" fn rs_position_withdraw_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_action_dutch_auction_withdraw_action_hash(
plan: &action_dutch_auction_withdraw::ActionDutchAuctionWithdrawPlanC,
output: *mut u8,
output_len: usize,
) -> u32 {
crate::zlog("rs_action_dutch_auction_withdraw_action_hash\x00");
let output = std::slice::from_raw_parts_mut(output, output_len);

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

let body_hash_bytes = plan.effect_hash();

if let Ok(body_hash_bytes) = body_hash_bytes {
let body_hash_array = body_hash_bytes.as_array();
let copy_len: usize = core::cmp::min(output.len(), body_hash_array.len());
output[..copy_len].copy_from_slice(&body_hash_array[..copy_len]);
} else {
return ParserError::DutchAuctionWithdrawPlanError as u32;
}

ParserError::Ok as u32
}

#[no_mangle]
/// Use to compute an address and write it back into output
/// argument.
Expand Down Expand Up @@ -1045,4 +1074,75 @@ mod tests {
panic!("position_withdraw_hash is not Ok");
}
}

#[test]
fn test_dutch_auction_withdraw_action_hash() {
let auction_id_bytes =
hex::decode("c2ccae788b3e9972476a483dbff593a0739f64e2f45ee623fe72d0999224ce43")
.unwrap();

let dummy_auction_id = IdC {
inner: BytesC::from_slice(&auction_id_bytes),
};

// Create dummy ActionC
let dummy_amount_r1 = AmountC {
lo: 640799722200830187,
hi: 0,
};

let dummy_amount_r2 = AmountC {
lo: 975333553020304634,
hi: 0,
};

let pair_1_bytes =
hex::decode("29ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a10")
.unwrap();

let dummy_reward_1 = IdC {
inner: BytesC::from_slice(&pair_1_bytes),
};

let pair_2_bytes =
hex::decode("29ea9c2f3371f6a487e7e95c247041f4a356f983eb064e5d2b3bcf322ca96a10")
.unwrap();

let dummy_reward_2 = IdC {
inner: BytesC::from_slice(&pair_2_bytes),
};

let dummy_reserves_input = ValueC {
has_amount: true,
amount: dummy_amount_r1,
has_asset_id: true,
asset_id: dummy_reward_1,
};

let dummy_reserves_output = ValueC {
has_amount: true,
amount: dummy_amount_r2,
has_asset_id: true,
asset_id: dummy_reward_2,
};

let dummy_action = action_dutch_auction_withdraw::ActionDutchAuctionWithdrawPlanC {
has_auction_id: true,
auction_id: dummy_auction_id,
seq: 589632218,
has_reserves_input: true,
reserves_input: dummy_reserves_input,
has_reserves_output: true,
reserves_output: dummy_reserves_output,
};

let dutch_auction_withdraw_hash = dummy_action.effect_hash();
let expected_hash = "696b6c9ab8c3abcc9316c062b08bcce64cb0387f1dc69a3f0db70ef490336bab4d89be958a7d3c10ad84dc63179222f5b7ae412a98fd29fad67ce4ee821502c4";
if let Ok(dutch_auction_withdraw_hash_bytes) = dutch_auction_withdraw_hash {
let computed_hash = hex::encode(dutch_auction_withdraw_hash_bytes.as_array());
assert_eq!(computed_hash, expected_hash);
} else {
panic!("dutch_auction_withdraw_hash is not Ok");
}
}
}
114 changes: 114 additions & 0 deletions app/rust/src/parser/plans/action_dutch_auction_withdraw.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*******************************************************************************
* (c) 2024 Zondax GmbH
*
* 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.
********************************************************************************/

use crate::parser::{
balance::Balance,
commitment::Commitment,
effect_hash::{create_personalized_state, EffectHash},
id::IdC,
value::{Imbalance, Sign, Value, ValueC},
};
use crate::utils::protobuf::encode_varint;
use crate::ParserError;
use decaf377::Fr;

pub struct ActionDutchAuctionWithdraw {
pub auction_id: [u8; 32],
pub seq: u64,
pub reserves_commitment: Commitment,
}

#[repr(C)]
#[derive(Clone)]
#[cfg_attr(any(feature = "derive-debug", test), derive(Debug))]
pub struct ActionDutchAuctionWithdrawPlanC {
pub has_auction_id: bool,
pub auction_id: IdC,
pub seq: u64,
pub has_reserves_input: bool,
pub reserves_input: ValueC,
pub has_reserves_output: bool,
pub reserves_output: ValueC,
}

impl ActionDutchAuctionWithdrawPlanC {
pub fn effect_hash(&self) -> Result<EffectHash, ParserError> {
let action_dutch_auction_withdraw = self.to_action()?;

let mut state = create_personalized_state(
"/penumbra.core.component.auction.v1.ActionDutchAuctionWithdraw",
);

// auction_id
state.update(&[0x0a, 0x22, 0x0a, 0x20]);
state.update(&action_dutch_auction_withdraw.auction_id);

// sequence
let mut encoded = [0u8; 11];
encoded[0] = 0x10;
let pos = 1;
let len = encode_varint(action_dutch_auction_withdraw.seq, &mut encoded[pos..]);
state.update(&encoded[..len + 1]);

// reserves_commitment
state.update(
&action_dutch_auction_withdraw
.reserves_commitment
.to_proto_action_dutch_auction_withdraw(),
);

let hash = state.finalize();
Ok(EffectHash(*hash.as_array()))
}

pub fn to_action(&self) -> Result<ActionDutchAuctionWithdraw, ParserError> {
let auction_id: [u8; 32] = self
.auction_id
.inner
.get_bytes()?
.try_into()
.map_err(|_| ParserError::InvalidLength)?;

let reserves_commitment = self.reserves_commitment()?;

let action_dutch_auction_withdraw = ActionDutchAuctionWithdraw {
auction_id,
seq: self.seq,
reserves_commitment,
};

Ok(action_dutch_auction_withdraw)
}

pub fn reserves_balance(&self) -> Result<Balance, ParserError> {
let mut balance = Balance::new();

let reserves_input = Value::try_from(self.reserves_input.clone())?;
balance.insert(Imbalance {
value: reserves_input,
sign: Sign::Provided,
})?;

let reserves_output = Value::try_from(self.reserves_output.clone())?;
balance = balance.add(&reserves_output, Sign::Provided)?;

Ok(balance)
}

pub fn reserves_commitment(&self) -> Result<Commitment, ParserError> {
self.reserves_balance()?.commit(Fr::ZERO)
}
}
1 change: 1 addition & 0 deletions app/src/common/parser_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ typedef enum {
parser_position_withdraw_plan_error,
parser_action_dutch_auction_schedule_plan_error,
parser_action_dutch_auction_end_plan_error,
parser_action_dutch_auction_withdraw_plan_error,

// Chain related
parser_invalid_chain_id,
Expand Down
3 changes: 3 additions & 0 deletions app/src/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,6 @@

// Constant to use to allocate a buffer on the stack to hold the formatting of an dutch_auction_end action
#define DUTCH_AUCTION_END_DISPLAY_MAX_LEN 100

// Constant to use to allocate a buffer on the stack to hold the formatting of an dutch_auction_withdraw action
#define DUTCH_AUCTION_WITHDRAW_DISPLAY_MAX_LEN (2 * VALUE_DISPLAY_MAX_LEN + ASSET_ID_LEN + 88) // 444
9 changes: 9 additions & 0 deletions app/src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "action_dutch_auction_end.h"
#include "action_dutch_auction_schedule.h"
#include "action_dutch_auction_withdraw.h"
#include "coin.h"
#include "crypto.h"
#include "delegate.h"
Expand Down Expand Up @@ -135,6 +136,9 @@ parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_item
case penumbra_core_transaction_v1_ActionPlan_action_dutch_auction_end_tag:
CHECK_ERROR(action_dutch_auction_end_getNumItems(ctx, &action_num_items));
break;
case penumbra_core_transaction_v1_ActionPlan_action_dutch_auction_withdraw_tag:
CHECK_ERROR(action_dutch_auction_withdraw_getNumItems(ctx, &action_num_items));
break;
default:
return parser_unexpected_error;
}
Expand Down Expand Up @@ -257,6 +261,11 @@ parser_error_t parser_getItem(const parser_context_t *ctx, uint8_t displayIdx, c
ctx, &ctx->tx_obj->actions_plan[action_idx].action.action_dutch_auction_end, action_idx + 1, outKey,
outKeyLen, outVal, outValLen, pageIdx, pageCount))
break;
case penumbra_core_transaction_v1_ActionPlan_action_dutch_auction_withdraw_tag:
CHECK_ERROR(action_dutch_auction_withdraw_getItem(
ctx, &ctx->tx_obj->actions_plan[action_idx].action.action_dutch_auction_withdraw, action_idx + 1, outKey,
outKeyLen, outVal, outValLen, pageIdx, pageCount))
break;
default:
return parser_unexpected_error;
}
Expand Down
6 changes: 6 additions & 0 deletions app/src/parser_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "action_dutch_auction_end.h"
#include "action_dutch_auction_schedule.h"
#include "action_dutch_auction_withdraw.h"
#include "delegate.h"
#include "delegator_vote.h"
#include "ics20_withdrawal.h"
Expand Down Expand Up @@ -145,6 +146,11 @@ bool decode_action(pb_istream_t *stream, const pb_field_t *field, void **arg) {
CHECK_ACTION_ERROR(decode_action_dutch_auction_end_plan(
&action_data_3, &decode_arg[actions_qty].action.action_dutch_auction_end));
break;
case penumbra_core_transaction_v1_ActionPlan_action_dutch_auction_withdraw_tag:
decode_arg[actions_qty].action_data = action_data_4;
CHECK_ACTION_ERROR(decode_action_dutch_auction_withdraw_plan(
&action_data_4, &decode_arg[actions_qty].action.action_dutch_auction_withdraw));
break;
default:
return false;
}
Expand Down
6 changes: 6 additions & 0 deletions app/src/parser_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ zxerr_t compute_action_hash(action_t *action, bytes_t *memo_key, hash_t *output)
return zxerr_encoding_failed;
}
break;
case penumbra_core_transaction_v1_ActionPlan_action_dutch_auction_withdraw_tag:
if (rs_action_dutch_auction_withdraw_action_hash(&action->action.action_dutch_auction_withdraw,
(uint8_t *)output, 64) != parser_ok) {
return zxerr_encoding_failed;
}
break;
default:
return zxerr_unknown;
}
Expand Down
11 changes: 11 additions & 0 deletions app/src/parser_txdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,16 @@ typedef struct {
auction_id_t auction_id;
} action_dutch_auction_end_plan_t;

typedef struct {
bool has_auction_id;
auction_id_t auction_id;
uint64_t seq;
bool has_reserves_input;
value_t reserves_input;
bool has_reserves_output;
value_t reserves_output;
} action_dutch_auction_withdraw_plan_t;

typedef struct {
address_plan_t return_address;
bytes_t text;
Expand Down Expand Up @@ -372,6 +382,7 @@ typedef struct {
position_withdraw_plan_t position_withdraw;
action_dutch_auction_schedule_plan_t action_dutch_auction_schedule;
action_dutch_auction_end_plan_t action_dutch_auction_end;
action_dutch_auction_withdraw_plan_t action_dutch_auction_withdraw;
} action;
} action_t;

Expand Down
Loading

0 comments on commit 4449c8d

Please sign in to comment.