From 33eba17c8aeda666b1974c568ba9920ff60f0a60 Mon Sep 17 00:00:00 2001 From: borngraced <51881311+borngraced@users.noreply.github.com> Date: Fri, 15 Jul 2022 13:59:35 +0100 Subject: [PATCH 1/4] fixed LBC block header deserializing bug --- mm2src/coins/utxo/rpc_clients.rs | 1 + mm2src/mm2_bitcoin/chain/src/block_header.rs | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/mm2src/coins/utxo/rpc_clients.rs b/mm2src/coins/utxo/rpc_clients.rs index fe9d5f819c..726282702a 100644 --- a/mm2src/coins/utxo/rpc_clients.rs +++ b/mm2src/coins/utxo/rpc_clients.rs @@ -1168,6 +1168,7 @@ impl ElectrumBlockHeaderV12 { version: self.version as u32, previous_header_hash: self.prev_block_hash.into(), merkle_root_hash: self.merkle_root.into(), + claim_trie_root: None, hash_final_sapling_root: None, time: self.timestamp as u32, bits: BlockHeaderBits::U32(self.bits as u32), diff --git a/mm2src/mm2_bitcoin/chain/src/block_header.rs b/mm2src/mm2_bitcoin/chain/src/block_header.rs index a3e92f6132..502fa448aa 100644 --- a/mm2src/mm2_bitcoin/chain/src/block_header.rs +++ b/mm2src/mm2_bitcoin/chain/src/block_header.rs @@ -43,6 +43,7 @@ const AUX_POW_VERSION_DOGE: u32 = 6422788; const AUX_POW_VERSION_SYS: u32 = 537919744; const MTP_POW_VERSION: u32 = 0x20001000u32; const PROG_POW_SWITCH_TIME: u32 = 1635228000; +// This header version is also uses for coins like LBC const QTUM_BLOCK_HEADER_VERSION: u32 = 536870912; // RVN const KAWPOW_VERSION: u32 = 805306368; @@ -92,6 +93,7 @@ pub struct BlockHeader { pub version: u32, pub previous_header_hash: H256, pub merkle_root_hash: H256, + pub claim_trie_root: Option, pub hash_final_sapling_root: Option, pub time: u32, pub bits: BlockHeaderBits, @@ -129,6 +131,9 @@ impl Serializable for BlockHeader { } s.append(&self.previous_header_hash); s.append(&self.merkle_root_hash); + if let Some(claim) = &self.claim_trie_root { + s.append(claim); + } match &self.hash_final_sapling_root { Some(h) => { s.append(h); @@ -197,6 +202,11 @@ impl Deserializable for BlockHeader { } let previous_header_hash = reader.read()?; let merkle_root_hash = reader.read()?; + let claim_trie_root = if version == QTUM_BLOCK_HEADER_VERSION { + Some(reader.read()?) + } else { + None + }; let hash_final_sapling_root = if version == 4 { Some(reader.read()?) } else { None }; let time = reader.read()?; let bits = if version == 4 { @@ -266,6 +276,7 @@ impl Deserializable for BlockHeader { version, previous_header_hash, merkle_root_hash, + claim_trie_root, hash_final_sapling_root, time, bits, @@ -316,6 +327,7 @@ mod tests { version: 1, previous_header_hash: [2; 32].into(), merkle_root_hash: [3; 32].into(), + claim_trie_root: None, hash_final_sapling_root: None, time: 4, bits: BlockHeaderBits::Compact(5.into()), @@ -361,6 +373,7 @@ mod tests { version: 1, previous_header_hash: [2; 32].into(), merkle_root_hash: [3; 32].into(), + claim_trie_root: None, hash_final_sapling_root: Default::default(), time: 4, bits: BlockHeaderBits::Compact(5.into()), @@ -393,6 +406,7 @@ mod tests { version: 4, previous_header_hash: "8e4e7283b71dd1572d220935db0a1654d1042e92378579f8abab67b143f93a02".into(), merkle_root_hash: "fa026610d2634b72ff729b9ea7850c0d2c25eeaf7a82878ca42a8e9912028863".into(), + claim_trie_root: None, hash_final_sapling_root: Some("a2d8a734eb73a4dc734072dbfd12406f1e7121bfe0e3d6c10922495c44e5cc1c".into()), time: 1583159441, bits: BlockHeaderBits::U32(486611429), From a59ce07513df492e889f347af48d3e2ae528a8d7 Mon Sep 17 00:00:00 2001 From: borngraced <51881311+borngraced@users.noreply.github.com> Date: Sun, 17 Jul 2022 12:51:35 +0100 Subject: [PATCH 2/4] fixed failing test && Improved Reader with coin_name for deserializing specific coins like LBC correctly --- mm2src/coins/utxo/rpc_clients.rs | 7 +++++-- mm2src/mm2_bitcoin/chain/src/block_header.rs | 11 ++++++++--- mm2src/mm2_bitcoin/serialization/src/reader.rs | 9 ++++++++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/mm2src/coins/utxo/rpc_clients.rs b/mm2src/coins/utxo/rpc_clients.rs index 726282702a..78a4d68402 100644 --- a/mm2src/coins/utxo/rpc_clients.rs +++ b/mm2src/coins/utxo/rpc_clients.rs @@ -1842,6 +1842,7 @@ impl ElectrumClient { blocks_limit_to_check: NonZeroU64, block_height: u64, ) -> UtxoRpcFut<(HashMap, Vec)> { + let coin_name = self.coin_name().to_string(); let (from, count) = { let from = if block_height < blocks_limit_to_check.get() { 0 @@ -1861,7 +1862,8 @@ impl ElectrumClient { let len = CompactInteger::from(headers.count); let mut serialized = serialize(&len).take(); serialized.extend(headers.hex.0.into_iter()); - let mut reader = Reader::new_with_coin_variant(serialized.as_slice(), CoinVariant::Standard); + let mut reader = + Reader::new_with_coin_params(serialized.as_slice(), CoinVariant::Standard, Some(coin_name)); let maybe_block_headers = reader.read_list::(); let block_headers = match maybe_block_headers { Ok(headers) => headers, @@ -2081,6 +2083,7 @@ impl UtxoRpcClientOps for ElectrumClient { count: NonZeroU64, coin_variant: CoinVariant, ) -> UtxoRpcFut { + let coin_name = self.coin_name().to_string(); let from = if starting_block <= count.get() { 0 } else { @@ -2096,7 +2099,7 @@ impl UtxoRpcClientOps for ElectrumClient { let len = CompactInteger::from(res.count); let mut serialized = serialize(&len).take(); serialized.extend(res.hex.0.into_iter()); - let mut reader = Reader::new_with_coin_variant(serialized.as_slice(), coin_variant); + let mut reader = Reader::new_with_coin_params(serialized.as_slice(), coin_variant, Some(coin_name)); let headers = reader.read_list::()?; let mut timestamps: Vec<_> = headers.into_iter().map(|block| block.time).collect(); // can unwrap because count is non zero diff --git a/mm2src/mm2_bitcoin/chain/src/block_header.rs b/mm2src/mm2_bitcoin/chain/src/block_header.rs index 502fa448aa..1fea2dda57 100644 --- a/mm2src/mm2_bitcoin/chain/src/block_header.rs +++ b/mm2src/mm2_bitcoin/chain/src/block_header.rs @@ -43,7 +43,7 @@ const AUX_POW_VERSION_DOGE: u32 = 6422788; const AUX_POW_VERSION_SYS: u32 = 537919744; const MTP_POW_VERSION: u32 = 0x20001000u32; const PROG_POW_SWITCH_TIME: u32 = 1635228000; -// This header version is also uses for coins like LBC +// This header version is also used for LBC coin. const QTUM_BLOCK_HEADER_VERSION: u32 = 536870912; // RVN const KAWPOW_VERSION: u32 = 805306368; @@ -93,6 +93,7 @@ pub struct BlockHeader { pub version: u32, pub previous_header_hash: H256, pub merkle_root_hash: H256, + /// https://github.com/lbryio/lbrycrd/blob/71fc94b1dea1c7818f84a09832ec3db736481e0f/src/primitives/block.h#L40 pub claim_trie_root: Option, pub hash_final_sapling_root: Option, pub time: u32, @@ -202,11 +203,15 @@ impl Deserializable for BlockHeader { } let previous_header_hash = reader.read()?; let merkle_root_hash = reader.read()?; - let claim_trie_root = if version == QTUM_BLOCK_HEADER_VERSION { + + // This is needed to deserialize coin like LBC correctly. + let claim_trie_root = if version == QTUM_BLOCK_HEADER_VERSION && *reader.coin_name() == Some("LBC".to_string()) + { Some(reader.read()?) } else { None }; + let hash_final_sapling_root = if version == 4 { Some(reader.read()?) } else { None }; let time = reader.read()?; let bits = if version == 4 { @@ -1976,7 +1981,7 @@ mod tests { 226, 1, 77, 51, 114, 115, 8, 152, 211, 49, 161, 62, 190, 80, 119, 154, 30, 193, 226, 46, 248, 169, 69, 226, 86, 134, 101, 238, 115, 14, 63, 174, 123, 30, 7, 123, 174, 60, 13, 100, 49, 23, 123, ]; - let mut reader = Reader::new_with_coin_variant(headers_bytes, CoinVariant::Qtum); + let mut reader = Reader::new_with_coin_params(headers_bytes, CoinVariant::Qtum, Some("QTUM".to_string())); let headers = reader.read_list::().unwrap(); for header in headers.iter() { assert_eq!(header.version, QTUM_BLOCK_HEADER_VERSION); diff --git a/mm2src/mm2_bitcoin/serialization/src/reader.rs b/mm2src/mm2_bitcoin/serialization/src/reader.rs index 26fe972531..66eaaeccab 100644 --- a/mm2src/mm2_bitcoin/serialization/src/reader.rs +++ b/mm2src/mm2_bitcoin/serialization/src/reader.rs @@ -65,6 +65,8 @@ pub struct Reader { buffer: T, peeked: Option, coin_variant: CoinVariant, + /// This field will be very important to deserializing specific coins correctly e.g `LBC` + coin_name: Option, } impl<'a> Reader<&'a [u8]> { @@ -74,15 +76,17 @@ impl<'a> Reader<&'a [u8]> { buffer, peeked: None, coin_variant: CoinVariant::Standard, + coin_name: None, } } /// Convenient way of creating for slice of bytes - pub fn new_with_coin_variant(buffer: &'a [u8], coin_variant: CoinVariant) -> Self { + pub fn new_with_coin_params(buffer: &'a [u8], coin_variant: CoinVariant, coin_name: Option) -> Self { Reader { buffer, peeked: None, coin_variant, + coin_name, } } } @@ -118,6 +122,7 @@ where buffer: read, peeked: None, coin_variant: CoinVariant::Standard, + coin_name: None, } } @@ -190,6 +195,8 @@ where } pub fn coin_variant(&self) -> &CoinVariant { &self.coin_variant } + + pub fn coin_name(&self) -> &Option { &self.coin_name } } /// Should be used to iterate over structures of the same type From 436a3352269f7efe609a376d945f1fc890dc787f Mon Sep 17 00:00:00 2001 From: borngraced <51881311+borngraced@users.noreply.github.com> Date: Mon, 18 Jul 2022 10:57:15 +0100 Subject: [PATCH 3/4] =?UTF-8?q?PR=20review=20fixes=20=F0=9F=94=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mm2src/coins/utxo/rpc_clients.rs | 11 ++- mm2src/coins/utxo/utxo_standard.rs | 7 +- mm2src/mm2_bitcoin/chain/src/block_header.rs | 74 ++++++++++++++++++- .../mm2_bitcoin/serialization/src/reader.rs | 11 +-- 4 files changed, 86 insertions(+), 17 deletions(-) diff --git a/mm2src/coins/utxo/rpc_clients.rs b/mm2src/coins/utxo/rpc_clients.rs index 78a4d68402..53e5468b54 100644 --- a/mm2src/coins/utxo/rpc_clients.rs +++ b/mm2src/coins/utxo/rpc_clients.rs @@ -1862,8 +1862,12 @@ impl ElectrumClient { let len = CompactInteger::from(headers.count); let mut serialized = serialize(&len).take(); serialized.extend(headers.hex.0.into_iter()); - let mut reader = - Reader::new_with_coin_params(serialized.as_slice(), CoinVariant::Standard, Some(coin_name)); + let coin_variant = if coin_name == "LBC" { + CoinVariant::LBC + } else { + CoinVariant::Standard + }; + let mut reader = Reader::new_with_coin_variant(serialized.as_slice(), coin_variant); let maybe_block_headers = reader.read_list::(); let block_headers = match maybe_block_headers { Ok(headers) => headers, @@ -2083,7 +2087,6 @@ impl UtxoRpcClientOps for ElectrumClient { count: NonZeroU64, coin_variant: CoinVariant, ) -> UtxoRpcFut { - let coin_name = self.coin_name().to_string(); let from = if starting_block <= count.get() { 0 } else { @@ -2099,7 +2102,7 @@ impl UtxoRpcClientOps for ElectrumClient { let len = CompactInteger::from(res.count); let mut serialized = serialize(&len).take(); serialized.extend(res.hex.0.into_iter()); - let mut reader = Reader::new_with_coin_params(serialized.as_slice(), coin_variant, Some(coin_name)); + let mut reader = Reader::new_with_coin_variant(serialized.as_slice(), coin_variant); let headers = reader.read_list::()?; let mut timestamps: Vec<_> = headers.into_iter().map(|block| block.time).collect(); // can unwrap because count is non zero diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index bc17d359a4..f89f331ed6 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -163,7 +163,12 @@ impl UtxoCommonOps for UtxoStandardCoin { } async fn get_current_mtp(&self) -> UtxoRpcResult { - utxo_common::get_current_mtp(&self.utxo_arc, CoinVariant::Standard).await + let coin_variant = if self.ticker() == "LBC" { + CoinVariant::LBC + } else { + CoinVariant::Standard + }; + utxo_common::get_current_mtp(&self.utxo_arc, coin_variant).await } fn is_unspent_mature(&self, output: &RpcTransaction) -> bool { diff --git a/mm2src/mm2_bitcoin/chain/src/block_header.rs b/mm2src/mm2_bitcoin/chain/src/block_header.rs index 1fea2dda57..6b8e5b6267 100644 --- a/mm2src/mm2_bitcoin/chain/src/block_header.rs +++ b/mm2src/mm2_bitcoin/chain/src/block_header.rs @@ -43,7 +43,7 @@ const AUX_POW_VERSION_DOGE: u32 = 6422788; const AUX_POW_VERSION_SYS: u32 = 537919744; const MTP_POW_VERSION: u32 = 0x20001000u32; const PROG_POW_SWITCH_TIME: u32 = 1635228000; -// This header version is also used for LBC coin. +const LBC_BLOCK_HEADER_VERSION: u32 = 536870912; const QTUM_BLOCK_HEADER_VERSION: u32 = 536870912; // RVN const KAWPOW_VERSION: u32 = 805306368; @@ -205,8 +205,7 @@ impl Deserializable for BlockHeader { let merkle_root_hash = reader.read()?; // This is needed to deserialize coin like LBC correctly. - let claim_trie_root = if version == QTUM_BLOCK_HEADER_VERSION && *reader.coin_name() == Some("LBC".to_string()) - { + let claim_trie_root = if version == LBC_BLOCK_HEADER_VERSION && reader.coin_variant().is_lbc() { Some(reader.read()?) } else { None @@ -326,6 +325,8 @@ mod tests { use hex::FromHex; use ser::{deserialize, serialize, serialize_list, CoinVariant, Error as ReaderError, Reader, Stream}; + use crate::block_header::LBC_BLOCK_HEADER_VERSION; + #[test] fn test_block_header_stream() { let block_header = BlockHeader { @@ -919,6 +920,71 @@ mod tests { assert_eq!(serialized.take(), headers_bytes); } + #[test] + fn test_lbc_block_herders_serde_11() { + let headers_bytes: &[u8] = &[ + 11, 0, 0, 0, 32, 4, 226, 205, 70, 162, 151, 56, 130, 229, 25, 56, 118, 91, 160, 178, 217, 85, 27, 1, 56, + 140, 20, 226, 40, 81, 171, 69, 77, 146, 40, 3, 245, 151, 115, 182, 25, 85, 159, 63, 6, 216, 43, 43, 130, + 111, 1, 126, 229, 53, 112, 195, 185, 7, 49, 80, 227, 104, 71, 129, 155, 14, 80, 229, 38, 102, 215, 134, 81, + 191, 250, 187, 217, 169, 93, 203, 220, 82, 217, 39, 221, 45, 2, 138, 18, 143, 248, 133, 15, 59, 140, 214, + 169, 65, 98, 208, 61, 46, 30, 213, 98, 213, 174, 0, 26, 75, 221, 59, 116, 0, 0, 0, 32, 196, 109, 14, 170, + 9, 36, 64, 47, 8, 64, 125, 180, 223, 157, 207, 10, 17, 147, 142, 204, 121, 184, 222, 20, 96, 107, 117, 222, + 175, 16, 105, 186, 108, 207, 33, 68, 226, 33, 122, 81, 173, 178, 158, 158, 8, 214, 102, 132, 57, 8, 233, + 138, 194, 133, 26, 124, 84, 0, 79, 31, 203, 142, 45, 232, 94, 218, 52, 2, 164, 160, 62, 236, 233, 187, 156, + 61, 122, 43, 214, 177, 87, 143, 144, 214, 64, 70, 168, 150, 210, 240, 78, 38, 204, 182, 2, 226, 137, 30, + 213, 98, 207, 195, 0, 26, 26, 210, 86, 33, 0, 0, 0, 32, 248, 242, 27, 4, 83, 243, 188, 89, 225, 120, 109, + 155, 92, 211, 112, 226, 110, 106, 117, 155, 244, 215, 210, 185, 63, 178, 180, 223, 137, 162, 58, 251, 107, + 190, 58, 159, 209, 134, 141, 129, 158, 66, 135, 230, 248, 146, 217, 232, 6, 92, 244, 181, 139, 203, 184, + 35, 35, 209, 240, 53, 56, 222, 63, 95, 180, 75, 178, 246, 193, 163, 175, 209, 16, 201, 188, 164, 245, 0, + 44, 216, 64, 8, 22, 170, 213, 238, 21, 240, 118, 16, 197, 201, 177, 29, 109, 91, 217, 30, 213, 98, 171, + 186, 0, 26, 3, 57, 180, 217, 0, 0, 0, 32, 107, 241, 118, 66, 209, 221, 160, 24, 69, 212, 76, 221, 81, 47, + 150, 6, 196, 22, 254, 107, 67, 96, 165, 129, 93, 87, 86, 253, 174, 166, 240, 6, 87, 49, 250, 185, 201, 18, + 49, 115, 222, 30, 154, 134, 214, 114, 183, 95, 87, 218, 116, 4, 176, 126, 196, 187, 210, 197, 142, 91, 129, + 175, 158, 88, 141, 159, 87, 247, 179, 75, 237, 84, 58, 216, 37, 210, 72, 167, 226, 154, 15, 69, 10, 254, + 149, 135, 74, 149, 110, 178, 91, 9, 134, 36, 137, 183, 57, 32, 213, 98, 182, 176, 0, 26, 184, 35, 19, 17, + 0, 0, 0, 32, 54, 175, 218, 241, 215, 229, 54, 226, 65, 178, 208, 185, 207, 176, 61, 171, 1, 203, 94, 53, + 30, 40, 188, 54, 70, 35, 33, 68, 234, 37, 203, 110, 248, 170, 156, 152, 52, 72, 42, 28, 248, 97, 9, 159, + 106, 83, 6, 68, 106, 134, 222, 38, 97, 227, 211, 181, 75, 36, 154, 182, 130, 133, 161, 8, 94, 210, 79, 13, + 155, 245, 191, 77, 157, 95, 40, 208, 220, 69, 190, 192, 248, 200, 39, 148, 177, 163, 88, 210, 23, 209, 106, + 200, 239, 23, 147, 3, 87, 32, 213, 98, 41, 206, 0, 26, 36, 6, 216, 89, 0, 0, 0, 32, 191, 206, 127, 113, + 217, 20, 89, 51, 103, 46, 155, 38, 64, 52, 51, 218, 35, 153, 161, 11, 24, 225, 116, 139, 117, 96, 245, 112, + 218, 168, 88, 99, 13, 117, 103, 10, 163, 133, 114, 186, 178, 138, 120, 22, 245, 23, 32, 108, 186, 238, 18, + 250, 254, 20, 236, 152, 247, 1, 229, 145, 249, 121, 29, 19, 64, 176, 250, 1, 212, 155, 54, 168, 176, 22, + 10, 174, 183, 38, 88, 77, 17, 174, 221, 73, 84, 133, 174, 149, 222, 93, 168, 85, 47, 122, 254, 142, 191, + 32, 213, 98, 139, 185, 0, 26, 11, 156, 81, 208, 0, 0, 0, 32, 185, 10, 134, 138, 197, 14, 90, 184, 108, 77, + 52, 169, 245, 158, 113, 196, 92, 63, 10, 42, 93, 138, 96, 146, 248, 103, 105, 107, 110, 92, 153, 32, 46, + 134, 91, 9, 151, 59, 17, 87, 145, 104, 83, 124, 153, 71, 154, 44, 254, 1, 16, 179, 214, 82, 219, 179, 57, + 94, 110, 85, 137, 231, 104, 113, 216, 65, 67, 201, 131, 14, 28, 55, 72, 31, 197, 88, 146, 130, 243, 56, + 173, 30, 153, 236, 36, 53, 220, 45, 18, 114, 217, 223, 59, 74, 60, 143, 214, 35, 213, 98, 91, 179, 0, 26, + 184, 79, 48, 125, 0, 0, 0, 32, 207, 9, 44, 157, 84, 2, 136, 174, 93, 198, 173, 105, 35, 141, 243, 6, 21, + 214, 24, 80, 113, 166, 149, 36, 207, 78, 157, 77, 195, 76, 118, 75, 93, 168, 103, 196, 147, 125, 5, 145, + 183, 30, 98, 150, 37, 135, 29, 3, 184, 160, 62, 61, 205, 109, 89, 124, 161, 161, 99, 166, 76, 198, 57, 104, + 21, 200, 173, 105, 181, 83, 152, 148, 115, 92, 215, 131, 108, 16, 121, 168, 25, 212, 150, 158, 205, 1, 128, + 106, 232, 31, 177, 216, 61, 70, 106, 149, 19, 36, 213, 98, 8, 13, 1, 26, 66, 126, 250, 117, 0, 0, 0, 32, + 14, 226, 195, 145, 216, 149, 97, 248, 36, 168, 95, 51, 163, 63, 36, 79, 144, 213, 195, 185, 88, 79, 179, + 68, 6, 166, 42, 176, 56, 129, 130, 158, 157, 158, 185, 82, 70, 100, 135, 53, 130, 252, 84, 56, 153, 183, 4, + 64, 167, 75, 237, 171, 159, 117, 76, 115, 169, 115, 131, 251, 119, 23, 3, 24, 159, 110, 115, 78, 6, 134, + 71, 167, 91, 187, 203, 252, 77, 121, 169, 201, 152, 67, 155, 21, 5, 19, 61, 136, 215, 31, 55, 173, 225, + 126, 138, 230, 51, 36, 213, 98, 77, 249, 0, 26, 153, 65, 133, 15, 0, 0, 0, 32, 98, 23, 129, 255, 228, 196, + 211, 128, 56, 58, 241, 153, 48, 139, 73, 26, 39, 169, 57, 4, 91, 179, 149, 36, 158, 254, 190, 185, 52, 110, + 160, 218, 227, 60, 248, 234, 204, 240, 216, 126, 70, 68, 180, 22, 122, 203, 103, 19, 177, 126, 226, 83, 44, + 83, 2, 36, 157, 164, 127, 241, 219, 47, 100, 53, 86, 216, 76, 242, 161, 117, 71, 214, 50, 154, 144, 42, + 180, 57, 145, 57, 95, 10, 18, 217, 161, 66, 70, 4, 116, 79, 24, 64, 71, 88, 47, 160, 77, 38, 213, 98, 8, + 226, 0, 26, 6, 75, 190, 72, 0, 0, 0, 32, 92, 201, 103, 9, 253, 13, 166, 231, 44, 6, 225, 162, 236, 10, 255, + 4, 42, 43, 196, 53, 83, 118, 220, 157, 231, 6, 104, 2, 111, 141, 219, 28, 162, 101, 33, 136, 243, 11, 130, + 200, 145, 88, 52, 186, 115, 44, 146, 231, 80, 158, 155, 182, 134, 156, 229, 247, 68, 55, 145, 249, 71, 225, + 115, 127, 165, 240, 245, 7, 151, 6, 193, 202, 139, 227, 48, 79, 12, 178, 233, 104, 176, 129, 136, 171, 201, + 184, 15, 6, 37, 118, 246, 130, 5, 177, 140, 190, 58, 38, 213, 98, 92, 42, 1, 26, 63, 91, 195, 195, + ]; + let mut reader = Reader::new_with_coin_variant(headers_bytes, CoinVariant::LBC); + let headers = reader.read_list::().unwrap(); + for header in headers.iter() { + assert_eq!(header.version, LBC_BLOCK_HEADER_VERSION); + } + let serialized = serialize_list(&headers); + assert_eq!(serialized.take(), headers_bytes); + } + #[test] fn test_verus_block_headers_serde_11() { let headers_bytes: &[u8] = &[ @@ -1981,7 +2047,7 @@ mod tests { 226, 1, 77, 51, 114, 115, 8, 152, 211, 49, 161, 62, 190, 80, 119, 154, 30, 193, 226, 46, 248, 169, 69, 226, 86, 134, 101, 238, 115, 14, 63, 174, 123, 30, 7, 123, 174, 60, 13, 100, 49, 23, 123, ]; - let mut reader = Reader::new_with_coin_params(headers_bytes, CoinVariant::Qtum, Some("QTUM".to_string())); + let mut reader = Reader::new_with_coin_variant(headers_bytes, CoinVariant::Qtum); let headers = reader.read_list::().unwrap(); for header in headers.iter() { assert_eq!(header.version, QTUM_BLOCK_HEADER_VERSION); diff --git a/mm2src/mm2_bitcoin/serialization/src/reader.rs b/mm2src/mm2_bitcoin/serialization/src/reader.rs index 66eaaeccab..73dfa47e54 100644 --- a/mm2src/mm2_bitcoin/serialization/src/reader.rs +++ b/mm2src/mm2_bitcoin/serialization/src/reader.rs @@ -51,12 +51,14 @@ pub trait Deserializable { #[derive(Debug)] pub enum CoinVariant { + LBC, Standard, Qtum, } impl CoinVariant { pub fn is_qtum(&self) -> bool { matches!(self, CoinVariant::Qtum) } + pub fn is_lbc(&self) -> bool { matches!(self, CoinVariant::LBC) } } /// Bitcoin structures reader. @@ -65,8 +67,6 @@ pub struct Reader { buffer: T, peeked: Option, coin_variant: CoinVariant, - /// This field will be very important to deserializing specific coins correctly e.g `LBC` - coin_name: Option, } impl<'a> Reader<&'a [u8]> { @@ -76,17 +76,15 @@ impl<'a> Reader<&'a [u8]> { buffer, peeked: None, coin_variant: CoinVariant::Standard, - coin_name: None, } } /// Convenient way of creating for slice of bytes - pub fn new_with_coin_params(buffer: &'a [u8], coin_variant: CoinVariant, coin_name: Option) -> Self { + pub fn new_with_coin_variant(buffer: &'a [u8], coin_variant: CoinVariant) -> Self { Reader { buffer, peeked: None, coin_variant, - coin_name, } } } @@ -122,7 +120,6 @@ where buffer: read, peeked: None, coin_variant: CoinVariant::Standard, - coin_name: None, } } @@ -195,8 +192,6 @@ where } pub fn coin_variant(&self) -> &CoinVariant { &self.coin_variant } - - pub fn coin_name(&self) -> &Option { &self.coin_name } } /// Should be used to iterate over structures of the same type From ad1f16448532ec66659ac201b64c04e301a7be5e Mon Sep 17 00:00:00 2001 From: borngraced <51881311+borngraced@users.noreply.github.com> Date: Tue, 19 Jul 2022 19:48:58 +0100 Subject: [PATCH 4/4] added coin_variant_by_ticker helper --- mm2src/coins/utxo/rpc_clients.rs | 12 ++++-------- mm2src/coins/utxo/utxo_standard.rs | 8 ++------ mm2src/mm2_bitcoin/chain/src/block_header.rs | 15 ++++++--------- mm2src/mm2_bitcoin/serialization/src/lib.rs | 3 ++- mm2src/mm2_bitcoin/serialization/src/reader.rs | 8 ++++++++ 5 files changed, 22 insertions(+), 24 deletions(-) diff --git a/mm2src/coins/utxo/rpc_clients.rs b/mm2src/coins/utxo/rpc_clients.rs index 53e5468b54..dac1d3712f 100644 --- a/mm2src/coins/utxo/rpc_clients.rs +++ b/mm2src/coins/utxo/rpc_clients.rs @@ -31,8 +31,8 @@ use mm2_number::{BigDecimal, BigInt, MmNumber}; #[cfg(test)] use mocktopus::macros::*; use rpc::v1::types::{Bytes as BytesJson, Transaction as RpcTransaction, H256 as H256Json}; use serde_json::{self as json, Value as Json}; -use serialization::{deserialize, serialize, serialize_with_flags, CoinVariant, CompactInteger, Reader, - SERIALIZE_TRANSACTION_WITNESS}; +use serialization::{coin_variant_by_ticker, deserialize, serialize, serialize_with_flags, CoinVariant, CompactInteger, + Reader, SERIALIZE_TRANSACTION_WITNESS}; use sha2::{Digest, Sha256}; use std::collections::hash_map::Entry; use std::collections::HashMap; @@ -1842,7 +1842,7 @@ impl ElectrumClient { blocks_limit_to_check: NonZeroU64, block_height: u64, ) -> UtxoRpcFut<(HashMap, Vec)> { - let coin_name = self.coin_name().to_string(); + let coin_name = self.coin_ticker.clone(); let (from, count) = { let from = if block_height < blocks_limit_to_check.get() { 0 @@ -1862,11 +1862,7 @@ impl ElectrumClient { let len = CompactInteger::from(headers.count); let mut serialized = serialize(&len).take(); serialized.extend(headers.hex.0.into_iter()); - let coin_variant = if coin_name == "LBC" { - CoinVariant::LBC - } else { - CoinVariant::Standard - }; + let coin_variant = coin_variant_by_ticker(&coin_name); let mut reader = Reader::new_with_coin_variant(serialized.as_slice(), coin_variant); let maybe_block_headers = reader.read_list::(); let block_headers = match maybe_block_headers { diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index f89f331ed6..b48f9bfe59 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -22,7 +22,7 @@ use crypto::trezor::utxo::TrezorUtxoCoin; use crypto::Bip44Chain; use futures::{FutureExt, TryFutureExt}; use mm2_number::MmNumber; -use serialization::CoinVariant; +use serialization::coin_variant_by_ticker; use utxo_signer::UtxoSignerOps; #[derive(Clone, Debug)] @@ -163,11 +163,7 @@ impl UtxoCommonOps for UtxoStandardCoin { } async fn get_current_mtp(&self) -> UtxoRpcResult { - let coin_variant = if self.ticker() == "LBC" { - CoinVariant::LBC - } else { - CoinVariant::Standard - }; + let coin_variant = coin_variant_by_ticker(self.ticker()); utxo_common::get_current_mtp(&self.utxo_arc, coin_variant).await } diff --git a/mm2src/mm2_bitcoin/chain/src/block_header.rs b/mm2src/mm2_bitcoin/chain/src/block_header.rs index 6b8e5b6267..611977d52e 100644 --- a/mm2src/mm2_bitcoin/chain/src/block_header.rs +++ b/mm2src/mm2_bitcoin/chain/src/block_header.rs @@ -43,8 +43,7 @@ const AUX_POW_VERSION_DOGE: u32 = 6422788; const AUX_POW_VERSION_SYS: u32 = 537919744; const MTP_POW_VERSION: u32 = 0x20001000u32; const PROG_POW_SWITCH_TIME: u32 = 1635228000; -const LBC_BLOCK_HEADER_VERSION: u32 = 536870912; -const QTUM_BLOCK_HEADER_VERSION: u32 = 536870912; +const BIP9_NO_SOFT_FORK_BLOCK_HEADER_VERSION: u32 = 536870912; // RVN const KAWPOW_VERSION: u32 = 805306368; @@ -205,7 +204,7 @@ impl Deserializable for BlockHeader { let merkle_root_hash = reader.read()?; // This is needed to deserialize coin like LBC correctly. - let claim_trie_root = if version == LBC_BLOCK_HEADER_VERSION && reader.coin_variant().is_lbc() { + let claim_trie_root = if version == BIP9_NO_SOFT_FORK_BLOCK_HEADER_VERSION && reader.coin_variant().is_lbc() { Some(reader.read()?) } else { None @@ -258,7 +257,7 @@ impl Deserializable for BlockHeader { }; let (hash_state_root, hash_utxo_root, prevout_stake, vch_block_sig_dlgt) = - if version == QTUM_BLOCK_HEADER_VERSION && reader.coin_variant().is_qtum() { + if version == BIP9_NO_SOFT_FORK_BLOCK_HEADER_VERSION && reader.coin_variant().is_qtum() { ( Some(reader.read()?), Some(reader.read()?), @@ -321,12 +320,10 @@ impl From<&'static str> for BlockHeader { #[cfg(test)] mod tests { use block_header::{BlockHeader, BlockHeaderBits, BlockHeaderNonce, AUX_POW_VERSION_DOGE, AUX_POW_VERSION_SYS, - KAWPOW_VERSION, MTP_POW_VERSION, PROG_POW_SWITCH_TIME, QTUM_BLOCK_HEADER_VERSION}; + BIP9_NO_SOFT_FORK_BLOCK_HEADER_VERSION, KAWPOW_VERSION, MTP_POW_VERSION, PROG_POW_SWITCH_TIME}; use hex::FromHex; use ser::{deserialize, serialize, serialize_list, CoinVariant, Error as ReaderError, Reader, Stream}; - use crate::block_header::LBC_BLOCK_HEADER_VERSION; - #[test] fn test_block_header_stream() { let block_header = BlockHeader { @@ -979,7 +976,7 @@ mod tests { let mut reader = Reader::new_with_coin_variant(headers_bytes, CoinVariant::LBC); let headers = reader.read_list::().unwrap(); for header in headers.iter() { - assert_eq!(header.version, LBC_BLOCK_HEADER_VERSION); + assert_eq!(header.version, BIP9_NO_SOFT_FORK_BLOCK_HEADER_VERSION); } let serialized = serialize_list(&headers); assert_eq!(serialized.take(), headers_bytes); @@ -2050,7 +2047,7 @@ mod tests { let mut reader = Reader::new_with_coin_variant(headers_bytes, CoinVariant::Qtum); let headers = reader.read_list::().unwrap(); for header in headers.iter() { - assert_eq!(header.version, QTUM_BLOCK_HEADER_VERSION); + assert_eq!(header.version, BIP9_NO_SOFT_FORK_BLOCK_HEADER_VERSION); } let serialized = serialize_list(&headers); assert_eq!(serialized.take(), headers_bytes); diff --git a/mm2src/mm2_bitcoin/serialization/src/lib.rs b/mm2src/mm2_bitcoin/serialization/src/lib.rs index 389c28f072..22e806516d 100644 --- a/mm2src/mm2_bitcoin/serialization/src/lib.rs +++ b/mm2src/mm2_bitcoin/serialization/src/lib.rs @@ -13,6 +13,7 @@ pub use primitives::{bytes, compact, hash}; pub use compact_integer::{parse_compact_int, CompactInteger}; pub use list::List; -pub use reader::{deserialize, deserialize_iterator, CoinVariant, Deserializable, Error, ReadIterator, Reader}; +pub use reader::{coin_variant_by_ticker, deserialize, deserialize_iterator, CoinVariant, Deserializable, Error, + ReadIterator, Reader}; pub use stream::{serialize, serialize_list, serialize_with_flags, serialized_list_size, serialized_list_size_with_flags, Serializable, Stream, SERIALIZE_TRANSACTION_WITNESS}; diff --git a/mm2src/mm2_bitcoin/serialization/src/reader.rs b/mm2src/mm2_bitcoin/serialization/src/reader.rs index 73dfa47e54..6b9045431d 100644 --- a/mm2src/mm2_bitcoin/serialization/src/reader.rs +++ b/mm2src/mm2_bitcoin/serialization/src/reader.rs @@ -58,9 +58,17 @@ pub enum CoinVariant { impl CoinVariant { pub fn is_qtum(&self) -> bool { matches!(self, CoinVariant::Qtum) } + pub fn is_lbc(&self) -> bool { matches!(self, CoinVariant::LBC) } } +pub fn coin_variant_by_ticker(ticker: &str) -> CoinVariant { + match ticker { + "LBC" => CoinVariant::LBC, + _ => CoinVariant::Standard, + } +} + /// Bitcoin structures reader. #[derive(Debug)] pub struct Reader {