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

Provide module for Vec<u8> to hex string serialization #186

Merged
merged 2 commits into from
May 3, 2022
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
51 changes: 51 additions & 0 deletions crates/model/src/bytes_hex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//! Serialization of Vec<u8> to 0x prefixed hex string

use serde::{de::Error, Deserialize, Deserializer, Serializer};
use std::borrow::Cow;

pub fn serialize<S, T>(bytes: T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: AsRef<[u8]>,
{
let mut v = vec![0u8; 2 + bytes.as_ref().len() * 2];
v[0] = b'0';
v[1] = b'x';
// Unwrap because only possible error is vector wrong size which cannot happen.
hex::encode_to_slice(bytes, &mut v[2..]).unwrap();
// Unwrap because encoded data is always valid utf8.
serializer.serialize_str(&String::from_utf8(v).unwrap())
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: Deserializer<'de>,
{
let prefixed_hex_str = Cow::<str>::deserialize(deserializer)?;
let hex_str = prefixed_hex_str
.strip_prefix("0x")
.ok_or_else(|| D::Error::custom("missing '0x' prefix"))?;
hex::decode(hex_str).map_err(D::Error::custom)
}

#[cfg(test)]
mod tests {

#[derive(Debug, serde::Deserialize, serde::Serialize, Eq, PartialEq)]
struct S {
#[serde(with = "super")]
b: Vec<u8>,
}

#[test]
fn json() {
let orig = S { b: vec![0, 1] };
let serialized = serde_json::to_value(&orig).unwrap();
let expected = serde_json::json!({
"b": "0x0001"
});
assert_eq!(serialized, expected);
let deserialized: S = serde_json::from_value(expected).unwrap();
assert_eq!(orig, deserialized);
}
}
1 change: 1 addition & 0 deletions crates/model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

pub mod app_id;
pub mod auction;
pub mod bytes_hex;
pub mod order;
pub mod ratio_as_decimal;
pub mod signature;
Expand Down
4 changes: 2 additions & 2 deletions crates/shared/src/balancer_sor_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use model::u256_decimal;
use num::BigInt;
use reqwest::{Client, IntoUrl, Url};
use serde::{Deserialize, Serialize};
use web3::types::Bytes;

/// Trait for mockable Balancer SOR API.
#[mockall::automock]
Expand Down Expand Up @@ -149,7 +148,8 @@ pub struct Swap {
#[serde(with = "u256_decimal")]
pub amount: U256,
/// Additional user data to pass to the pool.
pub user_data: Bytes,
#[serde(with = "model::bytes_hex")]
pub user_data: Vec<u8>,
}

impl Quote {
Expand Down
5 changes: 2 additions & 3 deletions crates/shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ use std::{
future::Future,
time::{Duration, Instant},
};
use web3::types::Bytes;

pub type Web3Transport = DynTransport;
pub type Web3 = DynWeb3;
Expand All @@ -66,10 +65,10 @@ pub async fn measure_time<T>(future: impl Future<Output = T>, timer: impl FnOnce
}

pub fn debug_bytes(
bytes: &Bytes,
bytes: impl AsRef<[u8]>,
formatter: &mut std::fmt::Formatter,
) -> Result<(), std::fmt::Error> {
formatter.write_fmt(format_args!("0x{}", hex::encode(&bytes.0)))
formatter.write_fmt(format_args!("0x{}", hex::encode(bytes.as_ref())))
}

/// anyhow errors are not clonable natively. This is a workaround that creates a new anyhow error
Expand Down
4 changes: 2 additions & 2 deletions crates/shared/src/oneinch_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! <https://docs.1inch.io/docs/aggregation-protocol/api/swagger>
//! Although there is no documentation about API v4.1, it exists and is identical to v4.0 except it
//! uses EIP 1559 gas prices.
use crate::solver_utils::{deserialize_prefixed_hex, Slippage};
use crate::solver_utils::Slippage;
use anyhow::{ensure, Context, Result};
use cached::{Cached, TimedCache};
use ethcontract::{H160, U256};
Expand Down Expand Up @@ -360,7 +360,7 @@ pub struct ProtocolRouteSegment {
pub struct Transaction {
pub from: H160,
pub to: H160,
#[serde(deserialize_with = "deserialize_prefixed_hex")]
#[serde(with = "model::bytes_hex")]
pub data: Vec<u8>,
#[serde(with = "u256_decimal")]
pub value: U256,
Expand Down
4 changes: 2 additions & 2 deletions crates/shared/src/paraswap_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use serde::{
};
use serde_json::Value;
use thiserror::Error;
use web3::types::Bytes;

const BASE_URL: &str = "https://apiv5.paraswap.io";

Expand Down Expand Up @@ -325,7 +324,8 @@ pub struct TransactionBuilderResponse {
pub value: U256,
/// the calldata for the transaction
#[derivative(Debug(format_with = "debug_bytes"))]
pub data: Bytes,
#[serde(with = "model::bytes_hex")]
pub data: Vec<u8>,
/// the suggested gas price
#[serde(with = "u256_decimal")]
pub gas_price: U256,
Expand Down
11 changes: 0 additions & 11 deletions crates/shared/src/solver_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,3 @@ where
let decimal_str = Cow::<str>::deserialize(deserializer)?;
decimal_str.parse::<f64>().map_err(D::Error::custom)
}

pub fn deserialize_prefixed_hex<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: Deserializer<'de>,
{
let prefixed_hex_str = Cow::<str>::deserialize(deserializer)?;
let hex_str = prefixed_hex_str
.strip_prefix("0x")
.ok_or_else(|| D::Error::custom("hex missing '0x' prefix"))?;
hex::decode(hex_str).map_err(D::Error::custom)
}
3 changes: 1 addition & 2 deletions crates/shared/src/univ3_router_api.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Bindings for an instance of https://github.com/cowprotocol/univ3-api .

use crate::solver_utils::deserialize_prefixed_hex;
use anyhow::{Context, Result};
use model::u256_decimal;
use primitive_types::{H160, U256};
Expand Down Expand Up @@ -32,7 +31,7 @@ pub struct Response {
pub quote: U256,
#[serde(with = "serde_with::rust::display_fromstr")]
pub gas: u64,
#[serde(deserialize_with = "deserialize_prefixed_hex")]
#[serde(with = "model::bytes_hex")]
pub call_data: Vec<u8>,
}

Expand Down
16 changes: 8 additions & 8 deletions crates/shared/src/zeroex_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use reqwest::{Client, IntoUrl, Url};
use serde::Deserialize;
use std::collections::HashSet;
use thiserror::Error;
use web3::types::Bytes;

const ORDERS_MAX_PAGE_SIZE: usize = 1_000;

Expand Down Expand Up @@ -137,7 +136,8 @@ impl Default for OrdersQuery {
pub struct OrderMetadata {
#[derivative(Default(value = "chrono::MIN_DATETIME"))]
pub created_at: DateTime<Utc>,
pub order_hash: Bytes,
#[serde(with = "model::bytes_hex")]
pub order_hash: Vec<u8>,
#[serde(with = "serde_with::rust::display_fromstr")]
pub remaining_fillable_taker_amount: u128,
}
Expand Down Expand Up @@ -261,7 +261,8 @@ pub struct SwapResponse {
pub price: PriceResponse,
pub to: H160,
#[derivative(Debug(format_with = "debug_bytes"))]
pub data: Bytes,
#[serde(with = "model::bytes_hex")]
pub data: Vec<u8>,
#[serde(with = "u256_decimal")]
pub value: U256,
}
Expand Down Expand Up @@ -587,11 +588,10 @@ mod tests {
per_page: 1000,
records: vec![OrderRecord {
metadata: OrderMetadata {
order_hash: Bytes(
order_hash:
hex::decode(
"003427369d4c2a6b0aceeb7b315bb9a6086bc6fc4c887aa51efc73b662c9d127"
).unwrap()
),
).unwrap(),
remaining_fillable_taker_amount: 262467000000000000u128,
created_at: Utc.ymd(2022, 2, 26).and_hms_milli(6, 59, 0, 440)
},
Expand Down Expand Up @@ -646,9 +646,9 @@ mod tests {
estimated_gas: 111000,
},
to: crate::addr!("def1c0ded9bec7f1a1670819833240f027b25eff"),
data: Bytes(hex::decode(
data: hex::decode(
"d9627aa40000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000001206e6c0056936e100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006810e776880c02933d47db1b9fc05908e5386b96869584cd0000000000000000000000001000000000000000000000000000000000000011000000000000000000000000000000000000000000000092415e982f60d431ba"
).unwrap()),
).unwrap(),
value: U256::from_dec_str("0").unwrap(),
}
);
Expand Down
2 changes: 1 addition & 1 deletion crates/solver/src/liquidity/zeroex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl ZeroExLiquidity {
}

let limit_order = LimitOrder {
id: hex::encode(&record.metadata.order_hash.0),
id: hex::encode(&record.metadata.order_hash),
sell_token: record.order.maker_token,
buy_token: record.order.taker_token,
sell_amount,
Expand Down
1 change: 1 addition & 0 deletions crates/solver/src/settlement_access_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ impl AccessListEstimating for TenderlyAccessList {
) -> Result<Vec<Result<AccessList>>> {
Ok(futures::future::join_all(txs.iter().map(|tx| async {
let (from, to, input) = resolve_call_request(tx)?;
let input = input.0;
let block_number = self.tenderly.block_number(&self.network_id).await?;

let request = TenderlyRequest {
Expand Down
7 changes: 4 additions & 3 deletions crates/solver/src/settlement_simulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use reqwest::{
};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use shared::Web3;
use web3::types::{AccessList, BlockId, Bytes};
use web3::types::{AccessList, BlockId};

const SIMULATE_BATCH_SIZE: usize = 10;

Expand Down Expand Up @@ -169,7 +169,7 @@ pub async fn simulate_before_after_access_list(
network_id,
block_number,
from,
input: transaction.input,
input: transaction.input.0,
to,
generate_access_list: false,
transaction_index: Some(transaction_index),
Expand Down Expand Up @@ -248,7 +248,8 @@ pub struct TenderlyRequest {
pub network_id: String,
pub block_number: u64,
pub from: Address,
pub input: Bytes,
#[serde(with = "model::bytes_hex")]
pub input: Vec<u8>,
pub to: Address,
#[serde(skip_serializing_if = "Option::is_none")]
pub transaction_index: Option<u64>,
Expand Down
2 changes: 1 addition & 1 deletion crates/solver/src/solver/balancer_sor_solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ impl Interaction for BatchSwap {
swap.asset_in_index.into(),
swap.asset_out_index.into(),
swap.amount,
Bytes(swap.user_data.0.clone()),
Bytes(swap.user_data.clone()),
)
})
.collect();
Expand Down
2 changes: 1 addition & 1 deletion crates/solver/src/solver/paraswap_solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ fn decimals(token_info: &HashMap<H160, TokenInfo>, token: &H160) -> Result<usize

impl Interaction for TransactionBuilderResponse {
fn encode(&self) -> Vec<EncodedInteraction> {
vec![(self.to, self.value, Bytes(self.data.0.clone()))]
vec![(self.to, self.value, Bytes(self.data.clone()))]
}
}

Expand Down
8 changes: 4 additions & 4 deletions crates/solver/src/solver/zeroex_solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ impl From<ZeroExResponseError> for SettlementError {

impl Interaction for SwapResponse {
fn encode(&self) -> Vec<EncodedInteraction> {
vec![(self.to, self.value, Bytes(self.data.0.clone()))]
vec![(self.to, self.value, Bytes(self.data.clone()))]
}
}

Expand Down Expand Up @@ -269,7 +269,7 @@ mod tests {
estimated_gas: Default::default(),
},
to: shared::addr!("0000000000000000000000000000000000000000"),
data: web3::types::Bytes(hex::decode("00").unwrap()),
data: hex::decode("00").unwrap(),
value: U256::from_dec_str("0").unwrap(),
})
});
Expand Down Expand Up @@ -407,7 +407,7 @@ mod tests {
estimated_gas: Default::default(),
},
to: shared::addr!("0000000000000000000000000000000000000000"),
data: web3::types::Bytes(hex::decode("").unwrap()),
data: hex::decode("").unwrap(),
value: U256::from_dec_str("0").unwrap(),
})
});
Expand Down Expand Up @@ -483,7 +483,7 @@ mod tests {
estimated_gas: Default::default(),
},
to: shared::addr!("0000000000000000000000000000000000000000"),
data: web3::types::Bytes(vec![]),
data: vec![],
value: 0.into(),
})
});
Expand Down