Skip to content

Commit

Permalink
Use rs-stellar-xdr for serialization/deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
tluijken committed Sep 26, 2023
1 parent 99c3b79 commit 949cb53
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 286 deletions.
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ edition = "2021"
reqwest = { version = "0.11.4", features = ["json"] }
url = "2.2.2"
tokio = { version = "1.15.0", features = ["full"] }
xdr-codec = "0.4.4"
xdrgen = "0.4.4"
stellar-xdr = { version = "0.0.17", features = ["base64"] }

[build-dependencies]
8 changes: 4 additions & 4 deletions src/horizon_client/horizon_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ async fn handle_response<TResponse: Default>(
println!("Response: {:?}", response);
match response.status() {
reqwest::StatusCode::OK => {
let response = response.text().await.map_err(|e| e.to_string())?;
let _response = response.text().await.map_err(|e| e.to_string())?;
Ok(TResponse::default())
//decode(&response.as_bytes()).map_err(|e| e.to_string());
// match result {
Expand All @@ -112,8 +112,6 @@ fn url_validate(url: &str) -> Result<(), String> {

#[cfg(test)]
mod tests {
use crate::horizon_client;

use super::*;

#[test]
Expand Down Expand Up @@ -163,7 +161,9 @@ mod tests {
single_account_request
.set_account_id("GDQJUTQYK2MQX2VGDR2FYWLIYAQIEGXTQVTFEMGH2BEWFG4BRUY4CKI7".to_string());

let _single_account_response = horizon_client.get_single_account(&single_account_request).await;
let _single_account_response = horizon_client
.get_single_account(&single_account_request)
.await;

assert!(_single_account_response.is_ok());
}
Expand Down
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@ mod accounts;
mod horizon_client;
mod models;
mod xdr;

327 changes: 48 additions & 279 deletions src/xdr/mod.rs
Original file line number Diff line number Diff line change
@@ -1,49 +1,8 @@
use xdr_codec;

use self::stub_data::LedgerHeader;

/// Encodes a value to XDR.
/// # Arguments
/// * `value` - The value to encode
/// # Returns
/// The encoded value
/// # Errors
/// Returns an error if the encoding fails
pub fn encode<T>(value: &T) -> Result<String, String> {
todo!();
}

/// decodes a value from XDR.
/// # Arguments
/// * `bytes` - The bytes to decode
/// # Returns
/// The decoded value
/// # Errors
/// Returns an error if the decoding fails
/// # Remarks
pub fn decode<T>(mut bytes: &[u8]) -> Result<LedgerHeader, String>
where
T: Default,
{
println!("bytes: {:?}", bytes);
let xdr: Result<LedgerHeader, xdr_codec::Error> = xdr_codec::unpack(&mut bytes);
match xdr {
Ok(v) => Ok(v),
Err(e) => {
Err(e.to_string())
},
}
}

#[cfg(test)]
mod tests {
use super::*;
use stub_data::*;

#[test]
fn encode_ledger_header() {
let ledger_header = "";
}
use ::stellar_xdr::ReadXdr;
use stellar_xdr::curr as stellar_xdr;

// TODO, add vice versa.
// https://developers.stellar.org/docs/encyclopedia/xdr#parsing-xdr
Expand All @@ -53,247 +12,57 @@ mod tests {
fn decode_ledger_header() {
// Decode online at : https://stellar.github.io/xdr-viewer/?type=LedgerHeader&network=public
let encoded = "AAAAAGPZj1Nu5o0bJ7W4nyOvUxG3Vpok+vFAOtC1K2M7B76ZuZRHr9UdXKbTKiclfOjy72YZFJUkJPVcKT5htvorm1QAAAAAZImGNAAAAAAAAAABAAAAAKgkzRi8nXUGTSmaW1uspDvDqi8yaTgVPYwvm7XLbfAzAAAAQLuRQK8ocAjytwfQelkpwZQa5+jReIO0pbr/9BbUbIffRxQN4Z76J3qDIn5lSJpn0OkYL8ZLPGP0W/S1vlTj5w/fP2GYBKkv20BXGS3EPddI6neK3FK8SYzoBSTAFLgRGXNSJ+05hGEpEjdoewhEaqLJsJbgyYpGLa3aVp8F3SSEAAAAAg3gtrOnZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkBfXhAAAAAGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=".as_bytes();

let decoded = decode::<LedgerHeader>(&encoded).unwrap();

assert_eq!(decoded.ledger_version, 0);
assert_eq!(decoded.previous_ledger_hash, "Y9mPU27mjRsntbifI69TEbdWmiT68UA60LUrYzsHvpk=".to_string());
assert_eq!(decoded.tx_set_hash, "uZRHr9UdXKbTKiclfOjy72YZFJUkJPVcKT5htvorm1Q=".to_string());
assert_eq!(decoded.close_time, 1686734388);

// let decoded = decode::<LedgerHeader>(&encoded).unwrap();
// assert_eq!(decoded, LedgerHeader::default());
// assert_eq!(decoded.ledger_version, 0);
// assert_eq!(
// decoded.previous_ledger_hash,
// "7KhW4Ac9wghySdySntMcCcO6v+8uaHtoXQUT2+ZImhg="
// );
// assert_eq!(decoded.scp_value, "");
// assert_eq!(
// decoded.tx_set_hash,
// "jqmROBaaGtCUsskwAA+EA0DXG49VbiW3E/OP5gIanTc="
// );
// assert_eq!(decoded.close_time, 1686734395);
// assert_eq!(decoded.upgrades.len(), 0);
// assert_eq!(decoded.ext, vec!["stellarValueSigned"]);
// assert_eq!(decoded.lc_value_signature, "");
// assert_eq!(decoded.node_id, vec!["publicKeyTypeEd25519"]);
// assert_eq!(
// decoded.ed25519,
// "7KhW4Ac9wghySdySntMcCcO6v+8uaHtoXQUT2+ZImhg="
// );
// assert_eq!(
// decoded.signature,
// "jqmROBaaGtCUsskwAA+EA0DXG49VbiW3E/OP5gIanTc="
// );
// assert_eq!(
// decoded.tx_set_result_hash,
// "jqmROBaaGtCUsskwAA+EA0DXG49VbiW3E/OP5gIanTc="
// );
// assert_eq!(
// decoded.bucket_list_hash,
// "jqmROBaaGtCUsskwAA+EA0DXG49VbiW3E/OP5gIanTc="
// );
// assert_eq!(decoded.ledger_seq, 3);
// assert_eq!(decoded.total_coins, 1000000000000000000);
// assert_eq!(decoded.fee_pool, 0);
// assert_eq!(decoded.inflation_seq, 0);
// assert_eq!(decoded.id_pool, 0);
// assert_eq!(decoded.base_fee, 100);
// assert_eq!(decoded.base_reserve, 100000000);
// assert_eq!(decoded.max_tx_set_size, 100);
// // assert_eq!(decoded.skip_list, vec![
// // "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
// // "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
// // "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
// // "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="]);
}
}

mod stub_data {
use xdr_codec::Unpack;

#[derive(Debug)]
pub struct LedgerHeader {
pub ledger_version: i32,
pub previous_ledger_hash: String,
pub scp_value: String,
pub tx_set_hash: String,
pub close_time: i64,
pub upgrades: Vec<String>,
pub ext: Vec<String>,
pub lc_value_signature: String,
pub node_id: Vec<String>,
pub ed25519: String,
pub signature: String,
pub tx_set_result_hash: String,
pub bucket_list_hash: String,
pub ledger_seq: i32,
pub total_coins: i64,
pub fee_pool: i64,
pub inflation_seq: i32,
pub id_pool: i64,
pub base_fee: i32,
pub base_reserve: i64,
pub max_tx_set_size: i32,
pub skip_list: Vec<String>,
}

impl PartialEq for LedgerHeader {
fn eq(&self, other: &Self) -> bool {
true
}
}
let decoded = stellar_xdr::LedgerHeader::from_xdr_base64(encoded).unwrap();
println!("Decoded: {:?}", decoded);

assert_eq!(decoded.ledger_version, 0);
assert_eq!(
decoded.previous_ledger_hash.to_string(),
"63d98f536ee68d1b27b5b89f23af5311b7569a24faf1403ad0b52b633b07be99"
);
assert_eq!(decoded.scp_value.upgrades.len(), 0);
assert_eq!(
decoded.scp_value.tx_set_hash.to_string(),
"b99447afd51d5ca6d32a27257ce8f2ef661914952424f55c293e61b6fa2b9b54"
);
assert_eq!(decoded.scp_value.close_time.0, 1686734388);
assert_eq!(
decoded.tx_set_result_hash.to_string(),
"df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
);

impl Unpack<&[u8]> for LedgerHeader {
fn unpack(input: &mut &[u8]) -> xdr_codec::Result<(Self, usize)> {
let mut size = 0;
let ledger_header = LedgerHeader {
ledger_version: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
print!("ledger_version: {:?}\n", v);
v
},
previous_ledger_hash: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
scp_value: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
tx_set_hash: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
close_time: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
upgrades: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
ext: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
lc_value_signature: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
node_id: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
ed25519: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
signature: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
tx_set_result_hash: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
bucket_list_hash: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
ledger_seq: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
total_coins: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
fee_pool: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
inflation_seq: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
id_pool: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
base_fee: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
base_reserve: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
max_tx_set_size: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
skip_list: {
let (v, sz) = Unpack::unpack(input)?;
size += sz;
v
},
};

println!("-------------LEDGER HEADER: {:?}", ledger_header);
Ok((ledger_header, size))
match decoded.scp_value.ext {
::stellar_xdr::StellarValueExt::Signed(signed) => {
assert_eq!(
signed.node_id.0.discriminant().to_string(),
"PublicKeyTypeEd25519"
);
assert_eq!(signed.node_id.0.name().to_string(), "PublicKeyTypeEd25519");
// todo check node-id public key
// todo check signature
}
_ => panic!("Expected signed"),
}
}

impl Default for LedgerHeader {
fn default() -> Self {
Self {
ledger_version: 0,
previous_ledger_hash: "".to_string(),
scp_value: "".to_string(),
tx_set_hash: "".to_string(),
close_time: 0,
upgrades: vec![],
ext: vec![],
lc_value_signature: "".to_string(),
node_id: vec![],
ed25519: "".to_string(),
signature: "".to_string(),
tx_set_result_hash: "".to_string(),
bucket_list_hash: "".to_string(),
ledger_seq: 0,
total_coins: 0,
fee_pool: 0,
inflation_seq: 0,
id_pool: 0,
base_fee: 0,
base_reserve: 0,
max_tx_set_size: 0,
skip_list: vec![],
}
assert_eq!(
decoded.bucket_list_hash.to_string(),
"735227ed398461291237687b08446aa2c9b096e0c98a462dadda569f05dd2484"
);
assert_eq!(decoded.ledger_seq, 2);
assert_eq!(decoded.total_coins, 1000000000000000000);
assert_eq!(decoded.fee_pool, 0);
assert_eq!(decoded.inflation_seq, 0);
assert_eq!(decoded.id_pool, 0);
assert_eq!(decoded.base_fee, 100);
assert_eq!(decoded.base_reserve, 100000000);
assert_eq!(decoded.max_tx_set_size, 100);
assert_eq!(decoded.ext, stellar_xdr::LedgerHeaderExt::V0);
for decoded in decoded.skip_list {
assert_eq!(
decoded.to_string(),
"0000000000000000000000000000000000000000000000000000000000000000"
);
}
}
}

0 comments on commit 949cb53

Please sign in to comment.