From c3624dec307212ec2565ae5bc7d159ad7fbbd565 Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Thu, 31 Oct 2024 20:28:24 +0200 Subject: [PATCH 1/5] fix: qcommitment seqwit always false --- dash/src/blockdata/transaction/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dash/src/blockdata/transaction/mod.rs b/dash/src/blockdata/transaction/mod.rs index 400b72f83..a50f44ce7 100644 --- a/dash/src/blockdata/transaction/mod.rs +++ b/dash/src/blockdata/transaction/mod.rs @@ -653,6 +653,9 @@ impl Decodable for Transaction { if special_transaction_type == TransactionType::AssetUnlock { segwit = false; } + if special_transaction_type == TransactionType::QuorumCommitment { + segwit = false; + } if segwit { let segwit_flag = u8::consensus_decode_from_finite_reader(r)?; match segwit_flag { From ef77beefcbed438ebf082415b6139832c2c97310 Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Thu, 31 Oct 2024 20:32:47 +0200 Subject: [PATCH 2/5] fix: qcommitment quorumIndex field --- .../special_transaction/quorum_commitment.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs b/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs index 794d0d18e..1ecb83a24 100644 --- a/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs +++ b/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs @@ -33,6 +33,7 @@ pub struct QuorumFinalizationCommitment { pub version: u16, pub llmq_type: u8, pub quorum_hash: QuorumHash, + pub quorum_index: Option, pub signers: Vec, pub valid_members: Vec, pub quorum_public_key: BLSPublicKey, @@ -47,6 +48,9 @@ impl QuorumFinalizationCommitment { let mut size = 2 + 1 + 32 + 48 + 32 + 96 + 96; size += VarInt(self.signers.len() as u64).len() + self.signers.len(); size += VarInt(self.valid_members.len() as u64).len() + self.valid_members.len(); + if self.version == 2 || self.version == 4 { + size += 16; + } size } } @@ -57,6 +61,9 @@ impl Encodable for QuorumFinalizationCommitment { len += self.version.consensus_encode(w)?; len += self.llmq_type.consensus_encode(w)?; len += self.quorum_hash.consensus_encode(w)?; + if self.version == 2 || self.version == 4 { + len += self.quorum_index.unwrap().consensus_encode(w)?; + } len += self.signers.consensus_encode(w)?; len += self.valid_members.consensus_encode(w)?; len += self.quorum_public_key.consensus_encode(w)?; @@ -72,6 +79,7 @@ impl Decodable for QuorumFinalizationCommitment { let version = u16::consensus_decode(r)?; let llmq_type = u8::consensus_decode(r)?; let quorum_hash = QuorumHash::consensus_decode(r)?; + let quorum_index = if version == 2 || version == 4 { Some(i16::consensus_decode(r)?) } else { None }; let signers = Vec::::consensus_decode(r)?; let valid_members = Vec::::consensus_decode(r)?; let quorum_public_key = BLSPublicKey::consensus_decode(r)?; @@ -82,6 +90,7 @@ impl Decodable for QuorumFinalizationCommitment { version, llmq_type, quorum_hash, + quorum_index, signers, valid_members, quorum_public_key, @@ -151,6 +160,7 @@ mod tests { version: 0, llmq_type: 0, quorum_hash: QuorumHash::all_zeros(), + quorum_index: None, signers: vec![1, 2, 3, 4, 5], valid_members: vec![6, 7, 8, 9, 0], quorum_public_key: BLSPublicKey::from([0; 48]), From d4e5beabfcb258eeff9a187bcbd797eadf1e63aa Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Thu, 31 Oct 2024 21:36:15 +0200 Subject: [PATCH 3/5] fix: qcommitment signers validmembers bitsets --- .../special_transaction/quorum_commitment.rs | 59 +++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs b/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs index 1ecb83a24..6f5062668 100644 --- a/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs +++ b/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs @@ -17,6 +17,7 @@ //! It is defined in DIP6 [dip-0006.md](https://github.com/dashpay/dips/blob/master/dip-0006.md). //! +use std::io::{Read, Write}; use crate::bls_sig_utils::{BLSPublicKey, BLSSignature}; use crate::consensus::{Decodable, Encodable, encode}; use crate::hash_types::{QuorumHash, QuorumVVecHash}; @@ -80,8 +81,10 @@ impl Decodable for QuorumFinalizationCommitment { let llmq_type = u8::consensus_decode(r)?; let quorum_hash = QuorumHash::consensus_decode(r)?; let quorum_index = if version == 2 || version == 4 { Some(i16::consensus_decode(r)?) } else { None }; - let signers = Vec::::consensus_decode(r)?; - let valid_members = Vec::::consensus_decode(r)?; + let signers_count = read_compact_size(r)?; + let signers = read_fixed_bitset(r, signers_count as usize)?; + let valid_members_count = read_compact_size(r)?; + let valid_members = read_fixed_bitset(r, valid_members_count as usize)?; let quorum_public_key = BLSPublicKey::consensus_decode(r)?; let quorum_vvec_hash = QuorumVVecHash::consensus_decode(r)?; let quorum_sig = BLSSignature::consensus_decode(r)?; @@ -91,8 +94,8 @@ impl Decodable for QuorumFinalizationCommitment { llmq_type, quorum_hash, quorum_index, - signers, - valid_members, + signers: signers.iter().map(|&b| b as u8).collect(), + valid_members: valid_members.iter().map(|&b| b as u8).collect(), quorum_public_key, quorum_vvec_hash, quorum_sig, @@ -139,6 +142,54 @@ impl Decodable for QuorumCommitmentPayload { } } +fn read_compact_size(r: &mut R) -> io::Result { + let mut marker = [0u8; 1]; + r.read_exact(&mut marker)?; + match marker[0] { + 0xFD => { + // Read the next 2 bytes as a little-endian u16 + let mut buf = [0u8; 2]; + r.read_exact(&mut buf)?; + Ok(u16::from_le_bytes(buf) as u64) + } + 0xFE => { + // Read the next 4 bytes as a little-endian u32 + let mut buf = [0u8; 4]; + r.read_exact(&mut buf)?; + Ok(u32::from_le_bytes(buf) as u64) + } + 0xFF => { + // Read the next 8 bytes as a little-endian u64 + let mut buf = [0u8; 8]; + r.read_exact(&mut buf)?; + Ok(u64::from_le_bytes(buf)) + } + value => { + // For values less than 253, the value is stored directly in the marker byte + Ok(value as u64) + } + } +} + +fn read_fixed_bitset(r: &mut R, size: usize) -> std::io::Result> { + // Calculate the number of bytes needed + let num_bytes = (size + 7) / 8; + let mut bytes = vec![0u8; num_bytes]; + + // Read bytes from the reader + r.read_exact(&mut bytes)?; + + // Unpack bits into a vector of bools + let mut bits = Vec::with_capacity(size); + for p in 0..size { + let byte = bytes[p / 8]; + let bit = (byte >> (p % 8)) & 1; + bits.push(bit != 0); + } + + Ok(bits) +} + #[cfg(test)] mod tests { use hashes::Hash; From ca7ad39ca109bdcf2ddb97823b9fbc19a0354b36 Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Thu, 31 Oct 2024 21:55:51 +0200 Subject: [PATCH 4/5] correct size --- .../transaction/special_transaction/quorum_commitment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs b/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs index 6f5062668..e7dff2eaa 100644 --- a/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs +++ b/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs @@ -50,7 +50,7 @@ impl QuorumFinalizationCommitment { size += VarInt(self.signers.len() as u64).len() + self.signers.len(); size += VarInt(self.valid_members.len() as u64).len() + self.valid_members.len(); if self.version == 2 || self.version == 4 { - size += 16; + size += 2; } size } From 0db8960dbc07239196ca95980c9a441ad287bb3a Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Thu, 31 Oct 2024 22:02:11 +0200 Subject: [PATCH 5/5] do not unwrap --- .../transaction/special_transaction/quorum_commitment.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs b/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs index e7dff2eaa..16450ec84 100644 --- a/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs +++ b/dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs @@ -62,8 +62,10 @@ impl Encodable for QuorumFinalizationCommitment { len += self.version.consensus_encode(w)?; len += self.llmq_type.consensus_encode(w)?; len += self.quorum_hash.consensus_encode(w)?; - if self.version == 2 || self.version == 4 { - len += self.quorum_index.unwrap().consensus_encode(w)?; + if let Some(q_index) = self.quorum_index { + if self.version == 2 || self.version == 4 { + len += q_index.consensus_encode(w)?; + } } len += self.signers.consensus_encode(w)?; len += self.valid_members.consensus_encode(w)?;