Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some improvements and fix PIC issues when formatting amounts #173

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/Makefile.version
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
APPVERSION_M=0
APPVERSION_N=24
APPVERSION_P=4
APPVERSION_P=5
24 changes: 24 additions & 0 deletions app/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions app/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ hex = { version = "0.4", default-features = false }
serde-json-core = { version = "0.4.0", default-features = false }
serde = { version = "1.0", default-features = false, features = ["derive"] }
nom = { version = "7.1.2", default-features = false }
lexical-core = { version = "0.7", features = [
"libm",
], default-features = false }


[dependencies.arrayvec]
Expand Down
3 changes: 3 additions & 0 deletions app/rust/src/parser/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,12 @@ pub unsafe extern "C" fn _last_block_ptr(
) -> u16 {
if let Some(tx) = parsed_obj_from_state(tx_t as _).and_then(|obj| obj.transaction()) {
let block = tx.last_transaction_block();

*block_ptr = block.as_ptr();
return block.len() as _;
}

*block_ptr = core::ptr::null_mut();
0
}

Expand Down
14 changes: 13 additions & 1 deletion app/rust/src/parser/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const BYTE_STRING_HEADER_LEN: usize = "\x17Stacks Signed Message:\n".as_bytes().
const MAX_ASCII_LEN: usize = 270;

#[repr(C)]
#[cfg_attr(test, derive(Debug))]
pub struct Message<'a>(ByteString<'a>);

impl<'a> Message<'a> {
Expand Down Expand Up @@ -45,9 +46,20 @@ impl<'a> Message<'a> {
}

#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Copy, Clone, PartialEq)]
pub struct ByteString<'a>(&'a [u8]);

#[cfg(test)]
impl<'a> core::fmt::Debug for ByteString<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "ByteString(\"")?;
for byte in self.0 {
write!(f, "{:02x}", byte)?;
}
write!(f, "\")")
}
}

impl<'a> ByteString<'a> {
pub fn is_msg(data: &'a [u8]) -> bool {
Self::contain_header(data)
Expand Down
6 changes: 4 additions & 2 deletions app/rust/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ mod jwt;
mod message;
mod parsed_obj;
mod parser_common;
mod post_condition;
mod post_conditions;
mod principal;
mod spending_condition;
mod structured_msg;
mod transaction;
mod transaction_auth;
mod transaction_payload;
mod tx_post_conditions;
mod utils;
mod value;
pub use error::ParserError;
Expand All @@ -20,10 +21,11 @@ pub use jwt::Jwt;
pub use message::{ByteString, Message};
pub use parsed_obj::{ParsedObj, Tag};
pub use parser_common::*;
pub use post_condition::{FungibleConditionCode, TransactionPostCondition};
pub use post_conditions::{FungibleConditionCode, TransactionPostCondition};
pub use principal::*;
pub use structured_msg::{Domain, StructuredMsg};
pub use transaction::Transaction;
pub use transaction_auth::TransactionAuth;
pub use tx_post_conditions::{PostConditions, TransactionPostConditionMode};
pub use utils::*;
pub use value::{Int128, Tuple, UInt128, Value, ValueId};
53 changes: 53 additions & 0 deletions app/rust/src/parser/parsed_obj.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#![allow(non_camel_case_types, non_snake_case, clippy::missing_safety_doc)]

use crate::bolos::c_zemu_log_stack;

use super::{error::ParserError, transaction::Transaction, Message};
use super::{Jwt, StructuredMsg};

Expand Down Expand Up @@ -56,6 +58,7 @@ impl<'a> ParsedObj<'a> {
}

pub fn read(&mut self, data: &'a [u8]) -> Result<(), ParserError> {
c_zemu_log_stack("ParsedObj::read\x00");
if data.is_empty() {
return Err(ParserError::NoData);
}
Expand All @@ -65,15 +68,19 @@ impl<'a> ParsedObj<'a> {

unsafe {
if Message::is_message(data) {
c_zemu_log_stack("Tag::Msg\x00");
self.tag = Tag::Message;
self.obj.read_msg(data)
} else if Jwt::is_jwt(data) {
c_zemu_log_stack("Tag::Jwt\x00");
self.tag = Tag::Jwt;
self.obj.read_jwt(data)
} else if StructuredMsg::is_msg(data) {
c_zemu_log_stack("Tag::StructuredMsg\x00");
self.tag = Tag::StructuredMsg;
self.obj.read_structured_msg(data)
} else {
c_zemu_log_stack("Tag::Transaction\x00");
self.tag = Tag::Transaction;
self.obj.read_tx(data)
}
Expand All @@ -99,6 +106,7 @@ impl<'a> ParsedObj<'a> {
value: &mut [u8],
page_idx: u8,
) -> Result<u8, ParserError> {
c_zemu_log_stack("ParsedObj::get_item\x00");
unsafe {
match self.tag {
Tag::Transaction => {
Expand Down Expand Up @@ -259,6 +267,38 @@ impl<'a> Obj<'a> {
}
}

#[cfg(test)]
impl<'a> core::fmt::Debug for ParsedObj<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut debug_struct = f.debug_struct("ParsedObj");
debug_struct.field("tag", &self.tag);

// Safety: We're matching on the tag to ensure we access the correct
// union variant. The union is guaranteed to be initialized with the
// correct variant and that variant won't change during the lifetime
// of the object.
match self.tag {
Tag::Transaction => unsafe {
debug_struct.field("obj", &self.obj.tx);
},
Tag::Message => unsafe {
debug_struct.field("obj", &self.obj.msg);
},
Tag::Jwt => unsafe {
debug_struct.field("obj", &self.obj.jwt);
},
Tag::StructuredMsg => unsafe {
debug_struct.field("obj", &self.obj.structured_msg);
},
Tag::Invalid => {
debug_struct.field("obj", &"<invalid>");
}
}

debug_struct.finish()
}
}

#[cfg(test)]
mod test {
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -793,4 +833,17 @@ mod test {
msg.read(&bytes).unwrap();
ParsedObj::validate(&mut msg).unwrap();
}

#[test]
fn test_swap_tx() {
let input = "000000000104009ef3889fd070159edcd8ef88a0ec87cea1592c83000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000302000000060002169ef3889fd070159edcd8ef88a0ec87cea1592c830100000000000027100003167c5f674a8fd08efa61dd9b11121e046dd2c892730a756e6976322d636f72650300000000000000000103167c5f674a8fd08efa61dd9b11121e046dd2c892730a756e6976322d636f7265168c5e2f8d25627d6edebeb6d10fa3300f5acc8441086c6f6e67636f696e086c6f6e67636f696e0300000000000000000103167c5f674a8fd08efa61dd9b11121e046dd2c892730a756e6976322d636f7265168c5e2f8d25627d6edebeb6d10fa3300f5acc8441086c6f6e67636f696e086c6f6e67636f696e0300000000000000000102169ef3889fd070159edcd8ef88a0ec87cea1592c83168c5e2f8d25627d6edebeb6d10fa3300f5acc8441086c6f6e67636f696e086c6f6e67636f696e030000000000000000010316402da2c079e5d31d58b9cfc7286d1b1eb2f7834e0f616d6d2d7661756c742d76322d303116402da2c079e5d31d58b9cfc7286d1b1eb2f7834e0a746f6b656e2d616c657804616c65780300000000011c908a02162ec1a2dc2904ebc8b408598116c75e42c51afa2617726f757465722d76656c61722d616c65782d762d312d320d737761702d68656c7065722d6100000007010000000000000000000000000000271001000000000000000000000000011c908a040c00000002016106167c5f674a8fd08efa61dd9b11121e046dd2c892730477737478016206168c5e2f8d25627d6edebeb6d10fa3300f5acc8441086c6f6e67636f696e06167c5f674a8fd08efa61dd9b11121e046dd2c8927312756e6976322d73686172652d6665652d746f0c0000000201610616402da2c079e5d31d58b9cfc7286d1b1eb2f7834e0b746f6b656e2d776c6f6e6701620616402da2c079e5d31d58b9cfc7286d1b1eb2f7834e0a746f6b656e2d616c65780c0000000101610100000000000000000000000005f5e100";
let bytes = hex::decode(input).unwrap();
let mut msg = ParsedObj::from_bytes(&bytes).unwrap();

msg.read(&bytes).unwrap();

ParsedObj::validate(&mut msg).unwrap();

std::println!("tx: {:?}", msg);
}
}
5 changes: 3 additions & 2 deletions app/rust/src/parser/parser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ pub const C32_ENCODED_ADDRS_LENGTH: usize = 48;
pub const NUM_SUPPORTED_POST_CONDITIONS: usize = 16;
pub const SIGNATURE_LEN: usize = 65;
pub const PUBKEY_LEN: usize = 33;
pub const TOKEN_TRANSFER_MEMO_LEN: usize = 34;
pub const MEMO_LEN: usize = 34;
pub const AMOUNT_LEN: usize = 8;

// A recursion limit use to control ram usage when parsing
// contract-call arguments that comes in a transaction
pub const TX_DEPTH_LIMIT: u8 = 3;
pub const TX_DEPTH_LIMIT: u8 = 8;

// Use to limit recursion when parsing nested clarity values that comes as part of a structured
// message. the limit is higher than the one use when parsing contract-args in transactions
Expand Down
Loading
Loading