Skip to content

Commit d4e5bea

Browse files
committed
fix: qcommitment signers validmembers bitsets
1 parent ef77bee commit d4e5bea

File tree

1 file changed

+55
-4
lines changed

1 file changed

+55
-4
lines changed

dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
//! It is defined in DIP6 [dip-0006.md](https://github.com/dashpay/dips/blob/master/dip-0006.md).
1818
//!
1919
20+
use std::io::{Read, Write};
2021
use crate::bls_sig_utils::{BLSPublicKey, BLSSignature};
2122
use crate::consensus::{Decodable, Encodable, encode};
2223
use crate::hash_types::{QuorumHash, QuorumVVecHash};
@@ -80,8 +81,10 @@ impl Decodable for QuorumFinalizationCommitment {
8081
let llmq_type = u8::consensus_decode(r)?;
8182
let quorum_hash = QuorumHash::consensus_decode(r)?;
8283
let quorum_index = if version == 2 || version == 4 { Some(i16::consensus_decode(r)?) } else { None };
83-
let signers = Vec::<u8>::consensus_decode(r)?;
84-
let valid_members = Vec::<u8>::consensus_decode(r)?;
84+
let signers_count = read_compact_size(r)?;
85+
let signers = read_fixed_bitset(r, signers_count as usize)?;
86+
let valid_members_count = read_compact_size(r)?;
87+
let valid_members = read_fixed_bitset(r, valid_members_count as usize)?;
8588
let quorum_public_key = BLSPublicKey::consensus_decode(r)?;
8689
let quorum_vvec_hash = QuorumVVecHash::consensus_decode(r)?;
8790
let quorum_sig = BLSSignature::consensus_decode(r)?;
@@ -91,8 +94,8 @@ impl Decodable for QuorumFinalizationCommitment {
9194
llmq_type,
9295
quorum_hash,
9396
quorum_index,
94-
signers,
95-
valid_members,
97+
signers: signers.iter().map(|&b| b as u8).collect(),
98+
valid_members: valid_members.iter().map(|&b| b as u8).collect(),
9699
quorum_public_key,
97100
quorum_vvec_hash,
98101
quorum_sig,
@@ -139,6 +142,54 @@ impl Decodable for QuorumCommitmentPayload {
139142
}
140143
}
141144

145+
fn read_compact_size<R: Read + ?Sized>(r: &mut R) -> io::Result<u64> {
146+
let mut marker = [0u8; 1];
147+
r.read_exact(&mut marker)?;
148+
match marker[0] {
149+
0xFD => {
150+
// Read the next 2 bytes as a little-endian u16
151+
let mut buf = [0u8; 2];
152+
r.read_exact(&mut buf)?;
153+
Ok(u16::from_le_bytes(buf) as u64)
154+
}
155+
0xFE => {
156+
// Read the next 4 bytes as a little-endian u32
157+
let mut buf = [0u8; 4];
158+
r.read_exact(&mut buf)?;
159+
Ok(u32::from_le_bytes(buf) as u64)
160+
}
161+
0xFF => {
162+
// Read the next 8 bytes as a little-endian u64
163+
let mut buf = [0u8; 8];
164+
r.read_exact(&mut buf)?;
165+
Ok(u64::from_le_bytes(buf))
166+
}
167+
value => {
168+
// For values less than 253, the value is stored directly in the marker byte
169+
Ok(value as u64)
170+
}
171+
}
172+
}
173+
174+
fn read_fixed_bitset<R: Read + ?Sized>(r: &mut R, size: usize) -> std::io::Result<Vec<bool>> {
175+
// Calculate the number of bytes needed
176+
let num_bytes = (size + 7) / 8;
177+
let mut bytes = vec![0u8; num_bytes];
178+
179+
// Read bytes from the reader
180+
r.read_exact(&mut bytes)?;
181+
182+
// Unpack bits into a vector of bools
183+
let mut bits = Vec::with_capacity(size);
184+
for p in 0..size {
185+
let byte = bytes[p / 8];
186+
let bit = (byte >> (p % 8)) & 1;
187+
bits.push(bit != 0);
188+
}
189+
190+
Ok(bits)
191+
}
192+
142193
#[cfg(test)]
143194
mod tests {
144195
use hashes::Hash;

0 commit comments

Comments
 (0)