Skip to content

Commit

Permalink
decode transaction and calculate id
Browse files Browse the repository at this point in the history
  • Loading branch information
b00f committed Oct 8, 2024
1 parent e64bbc3 commit e288bb7
Show file tree
Hide file tree
Showing 11 changed files with 264 additions and 138 deletions.
1 change: 0 additions & 1 deletion rust/Cargo.lock

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

2 changes: 1 addition & 1 deletion rust/chains/tw_pactus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ tw_encoding = { path = "../../tw_encoding" }

[dev-dependencies]
tw_encoding = { path = "../../tw_encoding" }
hex = "0.4.3"

23 changes: 12 additions & 11 deletions rust/chains/tw_pactus/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl TryFrom<u8> for AddressType {
}

impl Encodable for AddressType {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<usize, Error> {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<(), Error> {
(self.clone() as u8).encode(w)
}

Expand Down Expand Up @@ -120,16 +120,16 @@ impl fmt::Display for Address {
}

impl Encodable for Address {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<usize, Error> {
let mut len = self.addr_type.encode(w)?;
fn encode(&self, w: &mut dyn std::io::Write) -> Result<(), Error> {
self.addr_type.encode(w)?;

if self.is_treasury() {
return Ok(len);
return Ok(());
}

len += self.pub_hash.encode(w)?;
self.pub_hash.encode(w)?;

Ok(len)
Ok(())
}

fn encoded_size(&self) -> usize {
Expand Down Expand Up @@ -205,10 +205,9 @@ mod test {
assert!(addr.is_treasury());

let mut w = Vec::new();
let len = addr.encode(&mut w).unwrap();
addr.encode(&mut w).unwrap();
assert_eq!(w.to_vec(), [0x00]);
assert_eq!(addr.encoded_size(), 1);
assert_eq!(len, 1);
}

#[test]
Expand All @@ -226,15 +225,14 @@ mod test {
assert!(!addr.is_treasury());

let mut w = Vec::new();
let len = addr.encode(&mut w).unwrap();
addr.encode(&mut w).unwrap();
assert_eq!(
w.to_vec(),
"03000102030405060708090a0b0c0d0e0f00010203"
.decode_hex()
.unwrap()
);
assert_eq!(addr.encoded_size(), 21);
assert_eq!(len, 21);
}

#[test]
Expand All @@ -245,7 +243,10 @@ mod test {

let addr = deserialize::<Address>(&data).unwrap();
assert!(!addr.is_treasury());
assert_eq!(addr.to_string(), "pc1rqqqsyqcyq5rqwzqfpg9scrgwpuqqzqsr36kkra");
assert_eq!(
addr.to_string(),
"pc1rqqqsyqcyq5rqwzqfpg9scrgwpuqqzqsr36kkra"
);
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion rust/chains/tw_pactus/src/amount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::encoder::{error::Error, var_int::VarInt, Decodable, Encodable};
pub struct Amount(pub i64);

impl Encodable for Amount {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<usize, Error> {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<(), Error> {
VarInt::from(self.0 as usize).encode(w)
}

Expand Down
2 changes: 1 addition & 1 deletion rust/chains/tw_pactus/src/encoder/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub(crate) fn decode_var_slice(r: &mut dyn std::io::Read) -> Result<Vec<u8>, Err
}

pub(crate) fn decode_fix_slice(r: &mut dyn std::io::Read, len: usize) -> Result<Vec<u8>, Error> {
let mut buf = vec![0; len as usize];
let mut buf = vec![0; len];
r.read_exact(&mut buf)?;

Ok(buf)
Expand Down
32 changes: 17 additions & 15 deletions rust/chains/tw_pactus/src/encoder/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ use super::error::Error;
use crate::encoder::var_int::VarInt;
use crate::encoder::Encodable;

pub(crate) fn encode_var_slice(data: &[u8], w: &mut dyn std::io::Write) -> Result<usize, Error> {
let mut len = VarInt::from(data.len()).encode(w)?;
len += w.write(data)?;
pub(crate) fn encode_var_slice(data: &[u8], w: &mut dyn std::io::Write) -> Result<(), Error> {
VarInt::from(data.len()).encode(w)?;
w.write_all(data)?;

Ok(len)
Ok(())
}

pub(crate) fn encode_fix_slice(data: &[u8], w: &mut dyn std::io::Write) -> Result<usize, Error> {
Ok(w.write(data)?)
pub(crate) fn encode_fix_slice(data: &[u8], w: &mut dyn std::io::Write) -> Result<(), Error> {
w.write_all(data)?;

Ok(())
}

impl Encodable for Vec<u8> {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<usize, Error> {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<(), Error> {
encode_var_slice(self, w)
}

Expand All @@ -32,7 +34,7 @@ impl Encodable for Vec<u8> {
}

impl Encodable for String {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<usize, Error> {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<(), Error> {
encode_var_slice(self.as_bytes(), w)
}

Expand All @@ -42,7 +44,7 @@ impl Encodable for String {
}

impl Encodable for PublicKey {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<usize, Error> {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<(), Error> {
encode_fix_slice(self.as_slice(), w)
}

Expand All @@ -52,7 +54,7 @@ impl Encodable for PublicKey {
}

impl Encodable for Signature {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<usize, Error> {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<(), Error> {
encode_fix_slice(self.to_bytes().as_slice(), w)
}

Expand All @@ -62,7 +64,7 @@ impl Encodable for Signature {
}

impl<const N: usize> Encodable for Hash<N> {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<usize, Error> {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<(), Error> {
encode_fix_slice(self.as_slice(), w)
}

Expand All @@ -73,10 +75,10 @@ impl<const N: usize> Encodable for Hash<N> {

impl Encodable for u8 {
#[inline]
fn encode(&self, w: &mut dyn std::io::Write) -> Result<usize, Error> {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<(), Error> {
w.write_u8(*self)?;

Ok(1)
Ok(())
}

#[inline]
Expand All @@ -89,10 +91,10 @@ macro_rules! impl_encodable_for_int {
($int:ty, $size:literal, $write_fn:tt) => {
impl Encodable for $int {
#[inline]
fn encode(&self, w: &mut dyn std::io::Write) -> Result<usize, Error> {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<(), Error> {
w.$write_fn::<LittleEndian>(*self)?;

Ok($size)
Ok(())
}

#[inline]
Expand Down
2 changes: 0 additions & 2 deletions rust/chains/tw_pactus/src/encoder/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use tw_coin_entry::error::prelude::{SigningError, SigningErrorType};


/// Errors encountered when encoding or decoding data.
#[derive(Debug)]
pub enum Error {
Expand All @@ -14,7 +13,6 @@ impl From<std::io::Error> for Error {
}
}


impl From<Error> for SigningError {
fn from(_: Error) -> Self {
SigningError::new(SigningErrorType::Error_input_parse)
Expand Down
2 changes: 1 addition & 1 deletion rust/chains/tw_pactus/src/encoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub fn deserialize<T: Decodable>(data: &[u8]) -> Result<T, Error> {
/// Trait for encoding an object into a consistent byte sequence.
pub trait Encodable {
/// Encode the object in consistent and deterministic way.
fn encode(&self, w: &mut dyn std::io::Write) -> Result<usize, Error>;
fn encode(&self, w: &mut dyn std::io::Write) -> Result<(), Error>;

/// Determine the size of serialized object.
fn encoded_size(&self) -> usize;
Expand Down
22 changes: 12 additions & 10 deletions rust/chains/tw_pactus/src/encoder/var_int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,18 @@ impl Deref for VarInt {
}

impl Encodable for VarInt {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<usize, Error> {
fn encode(&self, w: &mut dyn std::io::Write) -> Result<(), Error> {
let mut val = self.0;
let mut len = 0;
// Make sure that there is one after this
while val >= 0x80 {
let n = (val as u8 & 0x7f) | 0x80;
len += w.write(&[n])?;
w.write_all(&[n])?;
val >>= 7; // It should be in multiples of 7, this should just get the next part
}

len += w.write(&[val as u8])?;
w.write_all(&[val as u8])?;

Ok(len)
Ok(())
}

fn encoded_size(&self) -> usize {
Expand Down Expand Up @@ -94,7 +93,7 @@ impl Decodable for VarInt {
mod tests {

use super::*;
use crate::encoder::{self, deserialize};
use crate::encoder::deserialize;

#[test]
fn test_var_int_encode_data() {
Expand Down Expand Up @@ -160,19 +159,22 @@ mod tests {
let mut w = Vec::new();
let var_int = VarInt(*value);
let encoded_size = var_int.encoded_size();
let len = var_int.encode(&mut w).unwrap();
var_int.encode(&mut w).unwrap();
let out = w.as_slice();

assert_eq!(out, *encoded, "Test {i} failed: data mismatch");
assert_eq!(len, out.len(), "Test {i} failed: encoded size mismatch");
assert_eq!(len, encoded_size, "Test {i} failed: data size mismatch",);
assert_eq!(
encoded_size,
out.len(),
"Test {i} failed: encoded size mismatch"
);
}
}

#[test]
fn test_var_int_decode() {
for (i, (value, data)) in VARINT_TEST_CASES.iter().enumerate() {
let var_int = deserialize::<VarInt>(*data).unwrap();
let var_int = deserialize::<VarInt>(data).unwrap();

assert_eq!(*value, *var_int, "Test {i} failed: value mismatch");
}
Expand Down
14 changes: 5 additions & 9 deletions rust/chains/tw_pactus/src/modules/transaction_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use tw_coin_entry::error::prelude::*;
use tw_coin_entry::modules::transaction_util::TransactionUtil;
use tw_encoding::hex;

use crate::encoder::deserialize;
use crate::transaction::Transaction;

pub struct PactusTransactionUtil;

Expand All @@ -18,16 +20,10 @@ impl TransactionUtil for PactusTransactionUtil {

impl PactusTransactionUtil {
fn calc_tx_hash_impl(_coin: &dyn CoinContext, encoded_tx: &str) -> SigningResult<String> {
let txn_bytes = hex::decode(encoded_tx).map_err(|_| SigningErrorType::Error_input_parse)?;
let trx_bytes = hex::decode(encoded_tx).map_err(|_| SigningErrorType::Error_input_parse)?;

todo!()
// // Deserialize the transaction
// let tx: Transaction = deserialize(&tx).map_err(|_| SigningErrorType::Error_input_parse)?;
let trx = deserialize::<Transaction>(&trx_bytes)?;

// // Calculate the transaction ID
// let txid = tx.txid();

// // Note: to_string() returns the reversed byte order, which is the RPC format
// Ok(txid.to_string())
Ok(hex::encode(trx.id(), false))
}
}
Loading

0 comments on commit e288bb7

Please sign in to comment.