From 1ab90a75943492f15fb54a39c25e26b0d5e7a9df Mon Sep 17 00:00:00 2001 From: jouzo <15011228+Jouzo@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:41:11 +0000 Subject: [PATCH 1/3] Parse leveldb entries --- lib/Cargo.lock | 10 ++++ lib/Cargo.toml | 1 + lib/ain-macros/src/lib.rs | 1 + lib/parser/Cargo.toml | 10 ++++ lib/parser/src/main.rs | 123 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 145 insertions(+) create mode 100644 lib/parser/Cargo.toml create mode 100644 lib/parser/src/main.rs diff --git a/lib/Cargo.lock b/lib/Cargo.lock index e55bb2d6a5..617f3a4410 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -3511,6 +3511,16 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "parser" +version = "0.1.0" +dependencies = [ + "ain-dftx", + "ain-macros", + "bitcoin", + "hex", +] + [[package]] name = "password-hash" version = "0.4.2" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 1c25deda6f..4a3c3aafea 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -2,6 +2,7 @@ members = [ "ain-*", "cli", + "parser" ] default-members = [ diff --git a/lib/ain-macros/src/lib.rs b/lib/ain-macros/src/lib.rs index 958c3a28c1..47f1da5be6 100644 --- a/lib/ain-macros/src/lib.rs +++ b/lib/ain-macros/src/lib.rs @@ -115,6 +115,7 @@ pub fn ocean_endpoint(_attr: TokenStream, item: TokenStream) -> TokenStream { TokenStream::from(expanded) } + #[proc_macro_derive(ConsensusEncoding)] pub fn consensus_encoding_derive(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); diff --git a/lib/parser/Cargo.toml b/lib/parser/Cargo.toml new file mode 100644 index 0000000000..3abd2054ad --- /dev/null +++ b/lib/parser/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "parser" +version = "0.1.0" +edition = "2021" + +[dependencies] +ain-macros.workspace = true +ain-dftx.workspace = true +bitcoin.workspace = true +hex.workspace = true diff --git a/lib/parser/src/main.rs b/lib/parser/src/main.rs new file mode 100644 index 0000000000..ae9050177f --- /dev/null +++ b/lib/parser/src/main.rs @@ -0,0 +1,123 @@ +use ain_macros::ConsensusEncoding; +use bitcoin::io; +use bitcoin::{consensus::Decodable, ScriptBuf}; +use std::io::BufRead; + +#[derive(Debug)] +pub struct RawDbEntry { + pub prefix: u8, + pub key: Vec, + pub value: Vec, +} + +impl RawDbEntry { + pub fn parse(input: &str) -> Result> { + let parts: Vec<&str> = input.split_whitespace().collect(); + if parts.len() != 3 { + return Err("Invalid input format: expected 3 space-separated parts".into()); + } + + let prefix = u8::from_str_radix(parts[0], 16)?; + + let key = hex::decode(parts[1])?; + let value = hex::decode(parts[2])?; + + Ok(RawDbEntry { prefix, key, value }) + } +} + +#[derive(ConsensusEncoding, Debug, Clone, PartialEq, Eq)] +pub struct BalanceKey { + pub owner: ScriptBuf, + pub token_id: u32, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct PrefixedData { + pub key: K, + pub value: V, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Prefix { + ByBalance(PrefixedData), + ByHeight(PrefixedData), + VMDomainTxEdge(PrefixedData<(u8, String), String>), + VMDomainBlockEdge(PrefixedData<(u8, String), String>), +} + +impl TryFrom for Prefix { + type Error = bitcoin::consensus::encode::Error; + + fn try_from(value: RawDbEntry) -> Result { + match value.prefix { + b'a' => Ok(Prefix::ByBalance(PrefixedData::try_from(value)?)), + b'b' => Ok(Prefix::ByHeight(PrefixedData::try_from(value)?)), + b'e' => Ok(Prefix::VMDomainTxEdge(PrefixedData::try_from(value)?)), + b'N' => Ok(Prefix::VMDomainBlockEdge(PrefixedData::try_from(value)?)), + _ => Err(bitcoin::consensus::encode::Error::ParseFailed( + "Unknown prefix", + )), + } + } +} + +impl TryFrom for PrefixedData +where + K: Decodable, + V: Decodable, +{ + type Error = bitcoin::consensus::encode::Error; + + fn try_from(value: RawDbEntry) -> Result { + let mut key_slice = value.key.as_slice(); + let mut value_slice = value.value.as_slice(); + + let key = K::consensus_decode(&mut key_slice)?; + let value = V::consensus_decode(&mut value_slice)?; + Ok(Self { key, value }) + } +} + +fn process_line(line: &str) -> Result<(), Box> { + let raw_entry = RawDbEntry::parse(line)?; + + match Prefix::try_from(raw_entry) { + Ok(entry) => println!("{entry:?}"), + Err(_) => {} + } + + Ok(()) +} + +fn main() -> Result<(), Box> { + let stdin = std::io::stdin(); + let reader = stdin.lock(); + + for line in reader.lines() { + let line = line?; + if !line.trim().is_empty() { + if let Err(e) = process_line(&line) { + eprintln!("Error processing line: {}", e); + } + } + } + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse() { + let input = "65 014031386566363362646661313837366264383735333933636363626133306430356465356238306261643161646536616131383931376261313939343532353163 4063343432376563623137373563333038346637313439383235313965616161323665636536643561653462303534626239393561326434666130346330353065"; + + let raw_entry = RawDbEntry::parse(input).unwrap(); + println!("raw_entry : {:?}", raw_entry); + let entry = Prefix::try_from(raw_entry).unwrap(); + + println!("entry : {:?}", entry); + } +} From f246353f9353d7531f42a2b6b4af76710088beed Mon Sep 17 00:00:00 2001 From: jouzo <15011228+Jouzo@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:52:54 +0000 Subject: [PATCH 2/3] Add VMDomainEdge --- lib/parser/src/main.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/parser/src/main.rs b/lib/parser/src/main.rs index ae9050177f..6e6b2b9572 100644 --- a/lib/parser/src/main.rs +++ b/lib/parser/src/main.rs @@ -38,12 +38,33 @@ pub struct PrefixedData { pub value: V, } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum VMDomainEdge { + DVMToEVM, + EVMToDVM, +} + +impl Decodable for VMDomainEdge { + fn consensus_decode( + reader: &mut R, + ) -> Result { + let edge = u8::consensus_decode(reader)?; + match edge { + 1 => Ok(Self::DVMToEVM), + 2 => Ok(Self::EVMToDVM), + _ => Err(bitcoin::consensus::encode::Error::ParseFailed( + "Unsupported VMDomainEdge", + )), + } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum Prefix { ByBalance(PrefixedData), ByHeight(PrefixedData), - VMDomainTxEdge(PrefixedData<(u8, String), String>), - VMDomainBlockEdge(PrefixedData<(u8, String), String>), + VMDomainTxEdge(PrefixedData<(VMDomainEdge, String), String>), + VMDomainBlockEdge(PrefixedData<(VMDomainEdge, String), String>), } impl TryFrom for Prefix { From e611a4f5769498f3a956849f39634ff4fc157d36 Mon Sep 17 00:00:00 2001 From: jouzo <15011228+Jouzo@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:51:02 +0000 Subject: [PATCH 3/3] Output as json --- lib/Cargo.lock | 3 +++ lib/ain-dftx/Cargo.toml | 1 + lib/ain-dftx/src/types/balance.rs | 1 + lib/ain-dftx/src/types/common.rs | 3 ++- lib/ain-dftx/src/types/price.rs | 6 +++--- lib/parser/Cargo.toml | 4 +++- lib/parser/src/main.rs | 30 +++++++++++++++++++++++------- 7 files changed, 36 insertions(+), 12 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 617f3a4410..1606660e17 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -128,6 +128,7 @@ dependencies = [ "bitflags 2.6.0", "hex", "lazy_static", + "serde", ] [[package]] @@ -3519,6 +3520,8 @@ dependencies = [ "ain-macros", "bitcoin", "hex", + "serde", + "serde_json", ] [[package]] diff --git a/lib/ain-dftx/Cargo.toml b/lib/ain-dftx/Cargo.toml index b0f0d4ee42..1a3cddcb52 100644 --- a/lib/ain-dftx/Cargo.toml +++ b/lib/ain-dftx/Cargo.toml @@ -11,3 +11,4 @@ bitcoin.workspace = true hex.workspace = true bitflags = "2.4.1" lazy_static.workspace = true +serde.workspace = true diff --git a/lib/ain-dftx/src/types/balance.rs b/lib/ain-dftx/src/types/balance.rs index 44f2ca22d0..20bddb5163 100644 --- a/lib/ain-dftx/src/types/balance.rs +++ b/lib/ain-dftx/src/types/balance.rs @@ -1,5 +1,6 @@ use ain_macros::ConsensusEncoding; use bitcoin::{io, ScriptBuf, VarInt}; +use serde::Serialize; use super::common::CompactVec; diff --git a/lib/ain-dftx/src/types/common.rs b/lib/ain-dftx/src/types/common.rs index 154f8835a8..0724ee387c 100644 --- a/lib/ain-dftx/src/types/common.rs +++ b/lib/ain-dftx/src/types/common.rs @@ -4,6 +4,7 @@ use bitcoin::{ consensus::{Decodable, Encodable}, io::{self, ErrorKind}, }; +use serde::Serialize; #[derive(Debug, PartialEq, Eq, Clone)] pub struct CompactVec(Vec); @@ -110,7 +111,7 @@ impl Decodable for RawBytes { /// In the rust-bitcoin library, variable-length integers are implemented as CompactSize. /// See [issue #1016](https://github.com/rust-bitcoin/rust-bitcoin/issues/1016) -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize)] pub struct VarInt(pub u64); impl Encodable for VarInt { diff --git a/lib/ain-dftx/src/types/price.rs b/lib/ain-dftx/src/types/price.rs index bba56a5f8a..b87972dbc4 100644 --- a/lib/ain-dftx/src/types/price.rs +++ b/lib/ain-dftx/src/types/price.rs @@ -1,7 +1,7 @@ +use super::common::CompactVec; use ain_macros::ConsensusEncoding; use bitcoin::io; - -use super::common::CompactVec; +use serde::Serialize; #[derive(ConsensusEncoding, Debug, PartialEq, Eq, Clone)] pub struct CurrencyPair { @@ -9,7 +9,7 @@ pub struct CurrencyPair { pub currency: String, } -#[derive(ConsensusEncoding, Debug, PartialEq, Eq, Clone)] +#[derive(ConsensusEncoding, Debug, PartialEq, Eq, Clone, Serialize)] pub struct TokenAmount { pub currency: String, pub amount: i64, diff --git a/lib/parser/Cargo.toml b/lib/parser/Cargo.toml index 3abd2054ad..cf49f40afd 100644 --- a/lib/parser/Cargo.toml +++ b/lib/parser/Cargo.toml @@ -6,5 +6,7 @@ edition = "2021" [dependencies] ain-macros.workspace = true ain-dftx.workspace = true -bitcoin.workspace = true +bitcoin = { workspace = true, features = ["serde"] } hex.workspace = true +serde_json.workspace = true +serde.workspace = true diff --git a/lib/parser/src/main.rs b/lib/parser/src/main.rs index 6e6b2b9572..72cff934c2 100644 --- a/lib/parser/src/main.rs +++ b/lib/parser/src/main.rs @@ -1,6 +1,10 @@ +use ain_dftx::balance::TokenBalanceVarInt; +use ain_dftx::common::VarInt; +use ain_dftx::price::TokenAmount; use ain_macros::ConsensusEncoding; -use bitcoin::io; use bitcoin::{consensus::Decodable, ScriptBuf}; +use bitcoin::{io, Txid}; +use serde::Serialize; use std::io::BufRead; #[derive(Debug)] @@ -26,19 +30,19 @@ impl RawDbEntry { } } -#[derive(ConsensusEncoding, Debug, Clone, PartialEq, Eq)] +#[derive(ConsensusEncoding, Debug, Clone, PartialEq, Eq, Serialize)] pub struct BalanceKey { pub owner: ScriptBuf, - pub token_id: u32, + pub token_id: VarInt, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize)] pub struct PrefixedData { pub key: K, pub value: V, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize)] pub enum VMDomainEdge { DVMToEVM, EVMToDVM, @@ -59,12 +63,24 @@ impl Decodable for VMDomainEdge { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize)] +struct UndoKey { + height: u32, + id: Txid, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize)] +struct Undo { + data: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize)] pub enum Prefix { ByBalance(PrefixedData), ByHeight(PrefixedData), VMDomainTxEdge(PrefixedData<(VMDomainEdge, String), String>), VMDomainBlockEdge(PrefixedData<(VMDomainEdge, String), String>), + Undo(PrefixedData), } impl TryFrom for Prefix { @@ -104,7 +120,7 @@ fn process_line(line: &str) -> Result<(), Box> { let raw_entry = RawDbEntry::parse(line)?; match Prefix::try_from(raw_entry) { - Ok(entry) => println!("{entry:?}"), + Ok(entry) => println!("{}", serde_json::to_string(&entry)?), Err(_) => {} }