Skip to content

Commit

Permalink
fix rust tests
Browse files Browse the repository at this point in the history
  • Loading branch information
b00f committed Oct 29, 2024
1 parent 5a261dd commit e182d6a
Show file tree
Hide file tree
Showing 11 changed files with 297 additions and 178 deletions.
8 changes: 5 additions & 3 deletions rust/chains/tw_pactus/src/encoder/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ pub(crate) fn decode_var_slice(r: &mut dyn std::io::Read) -> Result<Vec<u8>, Err
Ok(buf)
}

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

Expand All @@ -39,15 +41,15 @@ impl Decodable for String {

impl Decodable for PublicKey {
fn decode(r: &mut dyn std::io::Read) -> Result<Self, Error> {
let data = decode_fix_slice::<PublicKey::LEN>(r)?;
let data = decode_fix_slice::<{ PublicKey::LEN }>(r)?;
PublicKey::try_from(data.as_slice())
.map_err(|_| self::Error::ParseFailed("Invalid Public Key"))
}
}

impl Decodable for Signature {
fn decode(r: &mut dyn std::io::Read) -> Result<Self, Error> {
let data = decode_fix_slice::<Signature::LEN>(r)?;
let data = decode_fix_slice::<{ Signature::LEN }>(r)?;
Signature::try_from(data.as_slice())
.map_err(|_| self::Error::ParseFailed("Invalid Signature"))
}
Expand Down
9 changes: 7 additions & 2 deletions rust/chains/tw_pactus/src/modules/tx_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// Copyright © 2017 Trust Wallet.

use crate::transaction::payload::{TransferPayload, BondPayload, Payload};
use crate::transaction::payload::{BondPayload, Payload, TransferPayload};
use crate::transaction::Transaction;
use crate::types::{Address, Amount, ValidatorPublicKey};
use std::str::FromStr;
Expand Down Expand Up @@ -31,7 +31,12 @@ impl TxBuilder {
None
};

Box::new(BondPayload::new(sender, receiver, Amount(pld.stake), public_key))
Box::new(BondPayload::new(
sender,
receiver,
Amount(pld.stake),
public_key,
))
},
Pactus::Proto::mod_TransactionMessage::OneOfpayload::None => {
return SigningError::err(SigningErrorType::Error_invalid_params)
Expand Down
5 changes: 3 additions & 2 deletions rust/chains/tw_pactus/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pub mod payload;

use std::fmt::Debug;

use payload::{Payload, PayloadType, TransferPayload};
use payload::{BondPayload, Payload, PayloadType, TransferPayload};
use tw_coin_entry::error::prelude::SigningResult;
use tw_hash::blake2::blake2_b;
use tw_keypair::ed25519::sha512::{PrivateKey, PublicKey};
Expand Down Expand Up @@ -145,8 +145,9 @@ impl Decodable for Transaction {
let fee = Amount::decode(r)?;
let memo = String::decode(r)?;
let payload_type = PayloadType::decode(r)?;
let payload = match payload_type {
let payload: Box<dyn Payload> = match payload_type {
PayloadType::Transfer => Box::new(TransferPayload::decode(r)?),
PayloadType::Bond => Box::new(BondPayload::decode(r)?),
_ => return Err(EncoderError::ParseFailed("Unsupported payload")),
};

Expand Down
34 changes: 18 additions & 16 deletions rust/chains/tw_pactus/src/transaction/payload/bond.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ pub struct BondPayload {
}

impl BondPayload {
pub fn new(sender: Address, receiver: Address, stake: Amount, public_key: Option<ValidatorPublicKey>) -> Self {
pub fn new(
sender: Address,
receiver: Address,
stake: Amount,
public_key: Option<ValidatorPublicKey>,
) -> Self {
BondPayload {
sender,
receiver,
Expand All @@ -34,29 +39,25 @@ impl Encodable for BondPayload {

match self.public_key {
Some(ref public_key) => {
BLS_PUBLIC_KEY_SIZE as u8.encode(w)?;
(BLS_PUBLIC_KEY_SIZE as u8).encode(w)?;
public_key.encode(w)?;
}
},
None => {
0u8.encode(w)?;
}
},
}

self.stake.encode(w)?;
Ok(())
}

fn encoded_size(&self) -> usize {
self.sender.encoded_size() +
self.receiver.encoded_size() +
self.stake.encoded_size() +
match self.public_key {
Some(ref public_key) => {
1 + public_key.encoded_size()
}
None => {
1
}
self.sender.encoded_size()
+ self.receiver.encoded_size()
+ self.stake.encoded_size()
+ match self.public_key {
Some(ref public_key) => 1 + public_key.encoded_size(),
None => 1,
}
}
}
Expand All @@ -65,9 +66,8 @@ impl Decodable for BondPayload {
fn decode(r: &mut dyn std::io::Read) -> Result<Self, EncoderError> {
let sender = Address::decode(r)?;
let receiver = Address::decode(r)?;
let stake = Amount::decode(r)?;
let mut public_key = None;

let mut public_key = None;
let public_key_size: u8 = u8::decode(r)?;

if public_key_size == BLS_PUBLIC_KEY_SIZE as u8 {
Expand All @@ -76,6 +76,8 @@ impl Decodable for BondPayload {
return Err(EncoderError::ParseFailed("invalid public key size"));
}

let stake = Amount::decode(r)?;

Ok(BondPayload {
sender,
receiver,
Expand Down
4 changes: 2 additions & 2 deletions rust/chains/tw_pactus/src/transaction/payload/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
mod transfer;
mod bond;
mod transfer;

pub use transfer::TransferPayload;
pub use bond::BondPayload;
pub use transfer::TransferPayload;

use std::fmt::Debug;

Expand Down
7 changes: 4 additions & 3 deletions rust/chains/tw_pactus/src/types/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use tw_memory::Data;
use crate::encoder::error::Error;
use crate::encoder::{Decodable, Encodable};

const HRP: &str = "pc";
const ADDRESS_HRP: &str = "pc";
const TREASURY_ADDRESS_STRING: &str = "000000000000000000000000000000000000000000";

/// Enum for Pactus address types.
Expand Down Expand Up @@ -114,7 +114,8 @@ impl fmt::Display for Address {

b32.push(bech32::u5::try_from_u8(self.addr_type.clone() as u8).map_err(|_| fmt::Error)?);
b32.extend_from_slice(&self.pub_hash.to_vec().to_base32());
bech32::encode_to_fmt(f, HRP, &b32, bech32::Variant::Bech32m).map_err(|_| fmt::Error)?
bech32::encode_to_fmt(f, ADDRESS_HRP, &b32, bech32::Variant::Bech32m)
.map_err(|_| fmt::Error)?
}
}

Expand Down Expand Up @@ -171,7 +172,7 @@ impl FromStr for Address {

let (hrp, b32, _variant) = bech32::decode(s).map_err(|_| AddressError::FromBech32Error)?;

if hrp != HRP {
if hrp != ADDRESS_HRP {
return Err(AddressError::InvalidHrp);
}

Expand Down
93 changes: 80 additions & 13 deletions rust/chains/tw_pactus/src/types/validator_public_key.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use std::str::FromStr;
use tw_coin_entry::error::prelude::TWError;
use tw_hash::H160;
use crate::encoder::{Decodable, Encodable};
use crate::encoder::error::Error;
use crate::encoder::{encode::encode_fix_slice, decode::decode_fix_slice};
use crate::types::Address;
use crate::types::address::AddressType;
use crate::encoder::{decode::decode_fix_slice, encode::encode_fix_slice};
use crate::encoder::{Decodable, Encodable};
use bech32::FromBase32;
use std::str::FromStr;
use tw_keypair::KeyPairError;

pub const BLS_PUBLIC_KEY_SIZE: usize = 96;
pub const PUBLIC_KEY_HRP: &str = "public";

#[derive(Debug)]
pub struct ValidatorPublicKey(pub [u8; BLS_PUBLIC_KEY_SIZE]);
Expand All @@ -24,15 +23,83 @@ impl Encodable for ValidatorPublicKey {

impl Decodable for ValidatorPublicKey {
fn decode(r: &mut dyn std::io::Read) -> Result<Self, Error> {
Ok(ValidatorPublicKey(decode_fix_slice::<BLS_PUBLIC_KEY_SIZE>(r)?))
Ok(ValidatorPublicKey(decode_fix_slice::<BLS_PUBLIC_KEY_SIZE>(
r,
)?))
}
}


impl FromStr for ValidatorPublicKey {
type Err = TWError<String>;
type Err = KeyPairError;

fn from_str(s: &str) -> Result<Self, TWError<String>> {
todo!("implement me!!")
fn from_str(s: &str) -> Result<Self, KeyPairError> {
let (hrp, b32, _variant) = bech32::decode(s).map_err(|_| KeyPairError::InvalidPublicKey)?;
if hrp != PUBLIC_KEY_HRP {
return Err(KeyPairError::InvalidPublicKey);
}

let b8 = Vec::<u8>::from_base32(&b32[1..]).map_err(|_| KeyPairError::InvalidPublicKey)?;
let pub_data = b8.try_into().map_err(|_| KeyPairError::InvalidPublicKey)?;

Ok(ValidatorPublicKey(pub_data))
}
}
}

#[cfg(test)]
mod test {
use std::str::FromStr;

use tw_encoding::hex::DecodeHex;

use crate::types::ValidatorPublicKey;

#[test]
fn test_public_key_string() {
struct TestCase<'a> {
name: &'a str,
pub_key_str: &'a str,
pub_key_data: &'a str,
}

// Define a list of test cases for encoding and decoding
let test_cases = vec![
TestCase {
name: "invalid checksum",
pub_key_str: "public1p4u8hfytl2pj6l9rj0t54gxcdmna4hq52ncqkkqjf3arha5mlk3x4mzpyjkhmdl20jae7f65aamjrvqcvf4sudcapz52ctcwc8r9wz3z2gwxs38880cgvfy49ta5ssyjut05myd4zgmjqstggmetyuyg7v5jhx470",
pub_key_data: "",
},
TestCase {
name: "invalid length: 95",
pub_key_str: "public1p4u8hfytl2pj6l9rj0t54gxcdmna4hq52ncqkkqjf3arha5mlk3x4mzpyjkhmdl20jae7f65aamjrvqcvf4sudcapz52ctcwc8r9wz3z2gwxs38880cgvfy49ta5ssyjut05myd4zgmjqstggmetyuyg73y98kl",
pub_key_data: "",
},
TestCase {
name: "invalid HRP",
pub_key_str: "xxx1p4u8hfytl2pj6l9rj0t54gxcdmna4hq52ncqkkqjf3arha5mlk3x4mzpyjkhmdl20jae7f65aamjrvqcvf4sudcapz52ctcwc8r9wz3z2gwxs38880cgvfy49ta5ssyjut05myd4zgmjqstggmetyuyg7v5evslaq",
pub_key_data: "",
},
TestCase {
name: "OK",
pub_key_str: "public1p4u8hfytl2pj6l9rj0t54gxcdmna4hq52ncqkkqjf3arha5mlk3x4mzpyjkhmdl20jae7f65aamjrvqcvf4sudcapz52ctcwc8r9wz3z2gwxs38880cgvfy49ta5ssyjut05myd4zgmjqstggmetyuyg7v5jhx47a",
pub_key_data: "af0f74917f5065af94727ae9541b0ddcfb5b828a9e016b02498f477ed37fb44d5d882495afb6fd4f9773e4ea9deee436030c4d61c6e3a1151585e1d838cae1444a438d089ce77e10c492a55f6908125c5be9b236a246e4082d08de564e111e65",
},
];

for case in test_cases {
let pub_key_data = case.pub_key_data.decode_hex().unwrap().to_vec();
let test_result = ValidatorPublicKey::from_str(case.pub_key_str);

if pub_key_data.is_empty() {
assert!(test_result.is_err());
} else {
assert!(test_result.is_ok());
assert_eq!(
test_result.unwrap().0.to_vec(),
pub_key_data,
"test {} failed",
case.name
);
}
}
}
}
Loading

0 comments on commit e182d6a

Please sign in to comment.