separate evm structs, deserialisation functions and main logic

Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
This commit is contained in:
Uncle Stinky 2025-06-25 19:28:59 +03:00
parent 591cce1fb1
commit 47f7ae3847
Signed by: st1nky
GPG Key ID: 016064BD97603B40
4 changed files with 112 additions and 118 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "ghost-slow-clap"
version = "0.3.32"
version = "0.3.33"
description = "Applause protocol for the EVM bridge"
license.workspace = true
authors.workspace = true

View File

@ -0,0 +1,57 @@
use crate::{Deserialize, Deserializer, Vec, H256};
pub fn de_string_to_bytes<'de, D>(de: D) -> Result<Option<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
Ok(Some(s.as_bytes().to_vec()))
}
pub fn de_string_to_u64<'de, D>(de: D) -> Result<Option<u64>, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
let s = if s.starts_with("0x") { &s[2..] } else { &s };
Ok(u64::from_str_radix(s, 16).ok())
}
pub fn de_string_to_u64_pure<'de, D>(de: D) -> Result<u64, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
let s = if s.starts_with("0x") { &s[2..] } else { &s };
Ok(u64::from_str_radix(s, 16).unwrap_or_default())
}
pub fn de_string_to_h256<'de, D>(de: D) -> Result<Option<H256>, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
let start_index = if s.starts_with("0x") { 2 } else { 0 };
let h256: Vec<_> = (start_index..s.len())
.step_by(2)
.map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("valid u8 symbol; qed"))
.collect();
Ok(Some(H256::from_slice(&h256)))
}
pub fn de_string_to_vec_of_bytes<'de, D>(de: D) -> Result<Vec<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let strings: Vec<&str> = Deserialize::deserialize(de)?;
Ok(strings
.iter()
.map(|s| {
let start_index = if s.starts_with("0x") { 2 } else { 0 };
(start_index..s.len())
.step_by(2)
.map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("valid u8 symbol; qed"))
.collect::<Vec<u8>>()
})
.collect::<Vec<Vec<u8>>>())
}

View File

@ -0,0 +1,49 @@
use crate::{
deserialisations::{
de_string_to_bytes, de_string_to_h256, de_string_to_u64, de_string_to_u64_pure,
de_string_to_vec_of_bytes,
},
Decode, Deserialize, Encode, RuntimeDebug, Vec, H256,
};
const NUMBER_OF_TOPICS: usize = 3;
#[derive(RuntimeDebug, Clone, PartialEq, Deserialize, Encode, Decode)]
pub struct EvmResponse {
#[serde(default)]
id: Option<u32>,
#[serde(default, deserialize_with = "de_string_to_bytes")]
jsonrpc: Option<Vec<u8>>,
#[serde(default, deserialize_with = "de_string_to_bytes")]
pub error: Option<Vec<u8>>,
#[serde(default)]
pub result: Option<EvmResponseType>,
}
#[derive(RuntimeDebug, Clone, PartialEq, Deserialize, Encode, Decode)]
#[serde(untagged)]
pub enum EvmResponseType {
#[serde(deserialize_with = "de_string_to_u64_pure")]
BlockNumber(u64),
TransactionLogs(Vec<Log>),
}
#[derive(RuntimeDebug, Clone, Eq, PartialEq, Ord, PartialOrd, Deserialize, Encode, Decode)]
#[serde(rename_all = "camelCase")]
pub struct Log {
#[serde(default, deserialize_with = "de_string_to_h256")]
pub transaction_hash: Option<H256>,
#[serde(default, deserialize_with = "de_string_to_u64")]
pub block_number: Option<u64>,
#[serde(default, deserialize_with = "de_string_to_vec_of_bytes")]
pub topics: Vec<Vec<u8>>,
pub removed: bool,
}
impl Log {
pub fn is_sufficient(&self) -> bool {
self.transaction_hash.is_some()
&& self.block_number.is_some()
&& self.topics.len() == NUMBER_OF_TOPICS
}
}

View File

@ -48,6 +48,11 @@ mod benchmarking;
mod mock;
mod tests;
mod deserialisations;
mod evm_types;
use evm_types::{EvmResponse, EvmResponseType};
pub mod sr25519 {
mod app_sr25519 {
use sp_application_crypto::{app_crypto, sr25519, KeyTypeId};
@ -68,126 +73,9 @@ const DB_PREFIX: &[u8] = b"slow_clap::";
const FETCH_TIMEOUT_PERIOD: u64 = 3_000;
const LOCK_BLOCK_EXPIRATION: u64 = 10;
const NUMBER_OF_TOPICS: usize = 3;
pub type AuthIndex = u32;
#[derive(RuntimeDebug, Clone, PartialEq, Deserialize, Encode, Decode)]
struct EvmResponse {
#[serde(default)]
id: Option<u32>,
#[serde(default, deserialize_with = "de_string_to_bytes")]
jsonrpc: Option<Vec<u8>>,
#[serde(default, deserialize_with = "de_string_to_bytes")]
error: Option<Vec<u8>>,
#[serde(default)]
result: Option<EvmResponseType>,
}
#[derive(RuntimeDebug, Clone, PartialEq, Deserialize, Encode, Decode)]
#[serde(untagged)]
enum EvmResponseType {
#[serde(deserialize_with = "de_string_to_u64_pure")]
BlockNumber(u64),
TransactionLogs(Vec<Log>),
}
#[derive(RuntimeDebug, Clone, Eq, PartialEq, Ord, PartialOrd, Deserialize, Encode, Decode)]
#[serde(rename_all = "camelCase")]
struct Log {
#[serde(default, deserialize_with = "de_string_to_h256")]
transaction_hash: Option<H256>,
#[serde(default, deserialize_with = "de_string_to_u64")]
block_number: Option<u64>,
#[serde(default, deserialize_with = "de_string_to_vec_of_bytes")]
topics: Vec<Vec<u8>>,
#[serde(default, deserialize_with = "de_string_to_bytes")]
address: Option<Vec<u8>>,
#[serde(default, deserialize_with = "de_string_to_btree_map")]
data: BTreeMap<u128, u128>,
removed: bool,
}
impl Log {
fn is_sufficient(&self) -> bool {
self.transaction_hash.is_some()
&& self.block_number.is_some()
&& self.topics.len() == NUMBER_OF_TOPICS
}
}
pub fn de_string_to_bytes<'de, D>(de: D) -> Result<Option<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
Ok(Some(s.as_bytes().to_vec()))
}
pub fn de_string_to_u64<'de, D>(de: D) -> Result<Option<u64>, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
let s = if s.starts_with("0x") { &s[2..] } else { &s };
Ok(u64::from_str_radix(s, 16).ok())
}
pub fn de_string_to_u64_pure<'de, D>(de: D) -> Result<u64, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
let s = if s.starts_with("0x") { &s[2..] } else { &s };
Ok(u64::from_str_radix(s, 16).unwrap_or_default())
}
pub fn de_string_to_h256<'de, D>(de: D) -> Result<Option<H256>, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
let start_index = if s.starts_with("0x") { 2 } else { 0 };
let h256: Vec<_> = (start_index..s.len())
.step_by(2)
.map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("valid u8 symbol; qed"))
.collect();
Ok(Some(H256::from_slice(&h256)))
}
pub fn de_string_to_vec_of_bytes<'de, D>(de: D) -> Result<Vec<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let strings: Vec<&str> = Deserialize::deserialize(de)?;
Ok(strings
.iter()
.map(|s| {
let start_index = if s.starts_with("0x") { 2 } else { 0 };
(start_index..s.len())
.step_by(2)
.map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("valid u8 symbol; qed"))
.collect::<Vec<u8>>()
})
.collect::<Vec<Vec<u8>>>())
}
pub fn de_string_to_btree_map<'de, D>(de: D) -> Result<BTreeMap<u128, u128>, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
let start_index = if s.starts_with("0x") { 2 } else { 0 };
Ok(BTreeMap::from_iter((start_index..s.len()).step_by(64).map(
|i| {
(
u128::from_str_radix(&s[i..i + 32], 16).expect("valid u8 symbol; qed"),
u128::from_str_radix(&s[i + 32..i + 64], 16).expect("valid u8 symbol; qed"),
)
},
)))
}
#[derive(
RuntimeDebug, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo, MaxEncodedLen,
)]