Skip to content

Commit e75dc6e

Browse files
committed
more work
1 parent faea29a commit e75dc6e

File tree

4 files changed

+282
-157
lines changed

4 files changed

+282
-157
lines changed

dash/src/blockdata/block.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -476,11 +476,11 @@ mod tests {
476476
"010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b0201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804ffff001d026e04ffffffff0100f2052a0100000043410446ef0102d1ec5240f0d061a4246c1bdef63fc3dbab7733052fbbf0ecd8f41fc26bf049ebb4f9527f374280259e7cfa99c48b0e3f39c51347a19a5819651503a5ac00000000010000000321f75f3139a013f50f315b23b0c9a2b6eac31e2bec98e5891c924664889942260000000049483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01ffffffff79cda0945903627c3da1f85fc95d0b8ee3e76ae0cfdc9a65d09744b1f8fc85430000000049483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501fffffffffe09f5fe3ffbf5ee97a54eb5e5069e9da6b4856ee86fc52938c2f979b0f38e82000000004847304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01ffffffff01009d966b01000000434104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac"
477477
);
478478

479-
let prevhash = hex!("85691f6a060e65346c281ed25b99dbd18c139053562ccd001d00000000000000");
480-
let merkle = hex!("377b6aa24658b7a0ae7b73f0673d047a291de5cbc06907038b288b2ebf491c2c");
479+
let prevhash = vec![14, 198, 132, 64, 91, 88, 179, 160, 240, 20, 76, 154, 146, 199, 212, 41, 101, 135, 186, 111, 199, 16, 65, 255, 242, 19, 10, 3, 138, 0, 0, 0];
480+
let merkle = vec![120, 226, 89, 180, 144, 207, 200, 168, 229, 14, 25, 51, 175, 222, 63, 119, 122, 71, 189, 172, 139, 97, 213, 4, 165, 27, 104, 222, 222, 42, 193, 129];
481481

482482
let work_bytes: [u8; 32] =
483-
hex!("000000000000000000000000000000000000000000000000050ec30af44bf25e")
483+
hex!("0000000000000000000000000000000000000000000000000000000000f7b6f1")
484484
.try_into()
485485
.unwrap();
486486
let work = Work::from_be_bytes(work_bytes);
@@ -493,16 +493,16 @@ mod tests {
493493
assert_eq!(serialize(&real_decode.header.prev_blockhash), prevhash);
494494
assert_eq!(real_decode.header.merkle_root, real_decode.compute_merkle_root().unwrap());
495495
assert_eq!(serialize(&real_decode.header.merkle_root), merkle);
496-
assert_eq!(real_decode.header.time, 1685447065);
497-
assert_eq!(real_decode.header.bits, CompactTarget::from_consensus(422747587));
498-
assert_eq!(real_decode.header.nonce, 2456102546);
496+
assert_eq!(real_decode.header.time, 1730283725);
497+
assert_eq!(real_decode.header.bits, CompactTarget::from_consensus(503384208));
498+
assert_eq!(real_decode.header.nonce, 394542);
499499
assert_eq!(real_decode.header.work(), work);
500500
assert_eq!(
501501
real_decode.header.validate_pow(real_decode.header.target()).unwrap(),
502502
real_decode.block_hash()
503503
);
504-
assert_eq!(real_decode.header.difficulty(), 84852220);
505-
assert_eq!(real_decode.header.difficulty_float(), 84852220.19239795);
504+
assert_eq!(real_decode.header.difficulty(), 0);
505+
assert_eq!(real_decode.header.difficulty_float(), 0.0037797675075301206);
506506
// [test] TODO: check the transaction data
507507

508508
assert_eq!(real_decode.size(), some_block.len());

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

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::hash_types::{MerkleRootMasternodeList, MerkleRootQuorums};
2323
use crate::io::{Error, ErrorKind};
2424
use crate::{VarInt, io};
2525
use crate::bls_sig_utils::BLSSignature;
26+
use crate::consensus::encode::{compact_size_len, read_compact_size, write_compact_size};
2627

2728
/// A Coinbase payload. This is contained as the payload of a coinbase special transaction.
2829
/// The Coinbase payload is described in DIP4.
@@ -43,15 +44,16 @@ pub struct CoinbasePayload {
4344
impl CoinbasePayload {
4445
/// The size of the payload in bytes.
4546
/// version(2) + height(4) + merkle_root_masternode_list(32) + merkle_root_quorums(32)
46-
/// in addition to the above, if version >= 3: asset_locked_amount(8) + best_cl_height(4) +
47-
/// best_cl_signature(VarInt(len) + len)
47+
/// in addition to the above, if version >= 3: asset_locked_amount(8) + best_cl_height(compact_size) +
48+
/// best_cl_signature(96)
4849
pub fn size(&self) -> usize {
4950
let mut size: usize = 2 + 4 + 32 + 32;
5051
if self.version >= 3 {
51-
size += 4 + 8;
52-
if let Some(sig) = &self.best_cl_signature {
53-
size += VarInt(sig.len() as u64).len() + sig.len()
52+
size += 96;
53+
if let Some(best_cl_height) = self.best_cl_height {
54+
size += compact_size_len(best_cl_height);
5455
}
56+
size += 8;
5557
}
5658
size
5759
}
@@ -66,7 +68,7 @@ impl Encodable for CoinbasePayload {
6668
len += self.merkle_root_quorums.consensus_encode(w)?;
6769
if self.version >= 3 {
6870
if let Some(best_cl_height) = self.best_cl_height {
69-
len += best_cl_height.consensus_encode(w)?;
71+
len += write_compact_size(w, best_cl_height)?;
7072
} else {
7173
return Err(Error::new(ErrorKind::InvalidInput, "best_cl_height is not set"));
7274
}
@@ -94,12 +96,7 @@ impl Decodable for CoinbasePayload {
9496
let merkle_root_masternode_list = MerkleRootMasternodeList::consensus_decode(r)?;
9597
let merkle_root_quorums = MerkleRootQuorums::consensus_decode(r)?;
9698
let best_cl_height = if version >= 3 {
97-
let value = u8::consensus_decode(r)?;
98-
match value {
99-
253 => Some(u16::consensus_decode(r)? as u32),
100-
254 => Some(u32::consensus_decode(r)?),
101-
_ => Some(value as u32)
102-
}
99+
Some(read_compact_size(r)?)
103100
} else { None };
104101
let best_cl_signature =
105102
if version >= 3 { Some(BLSSignature::consensus_decode(r)?) } else { None };
@@ -126,7 +123,7 @@ mod tests {
126123

127124
#[test]
128125
fn size() {
129-
let test_cases: &[(usize, u16)] = &[(70, 2), (179, 3)];
126+
let test_cases: &[(usize, u16)] = &[(70, 2), (177, 3)];
130127
for (want, version) in test_cases.iter() {
131128
let payload = CoinbasePayload {
132129
height: 1000,

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

Lines changed: 56 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::consensus::{Decodable, Encodable, encode};
2323
use crate::hash_types::{QuorumHash, QuorumVVecHash};
2424
use crate::prelude::*;
2525
use crate::{VarInt, io};
26+
use crate::consensus::encode::{compact_size_len, fixed_bitset_len, read_compact_size, read_fixed_bitset, write_compact_size, write_fixed_bitset};
2627

2728
/// A Quorum Finalization Commitment. It is described in the finalization section of DIP6:
2829
/// [dip-0006.md#6-finalization-phase](https://github.com/dashpay/dips/blob/master/dip-0006.md#6-finalization-phase)
@@ -35,8 +36,8 @@ pub struct QuorumFinalizationCommitment {
3536
pub llmq_type: u8,
3637
pub quorum_hash: QuorumHash,
3738
pub quorum_index: Option<i16>,
38-
pub signers: Vec<u8>,
39-
pub valid_members: Vec<u8>,
39+
pub signers: Vec<bool>,
40+
pub valid_members: Vec<bool>,
4041
pub quorum_public_key: BLSPublicKey,
4142
pub quorum_vvec_hash: QuorumVVecHash,
4243
pub quorum_sig: BLSSignature,
@@ -47,8 +48,10 @@ impl QuorumFinalizationCommitment {
4748
/// The size of the payload in bytes.
4849
pub fn size(&self) -> usize {
4950
let mut size = 2 + 1 + 32 + 48 + 32 + 96 + 96;
50-
size += VarInt(self.signers.len() as u64).len() + self.signers.len();
51-
size += VarInt(self.valid_members.len() as u64).len() + self.valid_members.len();
51+
size += compact_size_len(self.signers.len() as u32);
52+
size += fixed_bitset_len(self.signers.as_slice(), self.signers.len());
53+
size += compact_size_len(self.valid_members.len() as u32);
54+
size += fixed_bitset_len(self.valid_members.as_slice(), self.signers.len());
5255
if self.version == 2 || self.version == 4 {
5356
size += 2;
5457
}
@@ -67,8 +70,10 @@ impl Encodable for QuorumFinalizationCommitment {
6770
len += q_index.consensus_encode(w)?;
6871
}
6972
}
70-
len += self.signers.consensus_encode(w)?;
71-
len += self.valid_members.consensus_encode(w)?;
73+
len += write_compact_size(w, self.signers.len() as u32)?;
74+
len += write_fixed_bitset(w, self.signers.as_slice(), self.signers.iter().len())?;
75+
len += write_compact_size(w, self.valid_members.len() as u32)?;
76+
len += write_fixed_bitset(w, self.valid_members.as_slice(), self.valid_members.iter().len())?;
7277
len += self.quorum_public_key.consensus_encode(w)?;
7378
len += self.quorum_vvec_hash.consensus_encode(w)?;
7479
len += self.quorum_sig.consensus_encode(w)?;
@@ -96,8 +101,8 @@ impl Decodable for QuorumFinalizationCommitment {
96101
llmq_type,
97102
quorum_hash,
98103
quorum_index,
99-
signers: signers.iter().map(|&b| b as u8).collect(),
100-
valid_members: valid_members.iter().map(|&b| b as u8).collect(),
104+
signers,
105+
valid_members,
101106
quorum_public_key,
102107
quorum_vvec_hash,
103108
quorum_sig,
@@ -144,144 +149,60 @@ impl Decodable for QuorumCommitmentPayload {
144149
}
145150
}
146151

147-
fn read_compact_size<R: Read + ?Sized>(r: &mut R) -> io::Result<u32> {
148-
let mut marker = [0u8; 1];
149-
r.read_exact(&mut marker)?;
150-
match marker[0] {
151-
0xFD => {
152-
let mut buf = [0u8; 2];
153-
r.read_exact(&mut buf)?;
154-
Ok(u16::from_le_bytes(buf) as u32)
155-
}
156-
0xFE => {
157-
let mut buf = [0u8; 4];
158-
r.read_exact(&mut buf)?;
159-
Ok(u32::from_le_bytes(buf))
160-
}
161-
0xFF => {
162-
// Value is too large to fit in u32
163-
Err(io::Error::new(
164-
io::ErrorKind::InvalidData,
165-
"CompactSize value exceeds u32::MAX",
166-
))
167-
}
168-
value => Ok(value as u32),
169-
}
170-
}
171-
172-
fn write_compact_size<W: Write>(w: &mut W, value: u32) -> io::Result<usize> {
173-
let bytes_written = if value < 253 {
174-
// For values less than 253, write the value as a single byte.
175-
w.write_all(&[value as u8])?;
176-
1 // 1 byte written
177-
} else if value <= 0xFFFF {
178-
// For values from 253 to 65535, write 0xFD followed by the value as a little-endian u16.
179-
w.write_all(&[0xFDu8])?;
180-
w.write_all(&(value as u16).to_le_bytes())?;
181-
3 // 1 byte marker + 2 bytes for u16
182-
} else {
183-
// For values from 65536 to 0xFFFFFFFF, write 0xFE followed by the value as a little-endian u32.
184-
w.write_all(&[0xFEu8])?;
185-
w.write_all(&value.to_le_bytes())?;
186-
5 // 1 byte marker + 4 bytes for u32
187-
};
188-
Ok(bytes_written)
189-
}
190-
191-
fn read_fixed_bitset<R: Read + ?Sized>(r: &mut R, size: usize) -> std::io::Result<Vec<bool>> {
192-
// Calculate the number of bytes needed
193-
let num_bytes = (size + 7) / 8;
194-
let mut bytes = vec![0u8; num_bytes];
195-
196-
// Read bytes from the reader
197-
r.read_exact(&mut bytes)?;
198-
199-
// Unpack bits into a vector of bools
200-
let mut bits = Vec::with_capacity(size);
201-
for p in 0..size {
202-
let byte = bytes[p / 8];
203-
let bit = (byte >> (p % 8)) & 1;
204-
bits.push(bit != 0);
205-
}
206-
207-
Ok(bits)
208-
}
209-
210152
#[cfg(test)]
211153
mod tests {
212-
use std::io::Cursor;
213154
use hashes::Hash;
214155

215156
use crate::bls_sig_utils::{BLSPublicKey, BLSSignature};
216157
use crate::consensus::Encodable;
217158
use crate::hash_types::{QuorumHash, QuorumVVecHash};
218-
use crate::transaction::special_transaction::quorum_commitment::{read_compact_size, write_compact_size, QuorumCommitmentPayload, QuorumFinalizationCommitment};
159+
use crate::transaction::special_transaction::quorum_commitment::{QuorumCommitmentPayload, QuorumFinalizationCommitment};
219160

220161
#[test]
221162
fn size() {
222-
let want = 325;
223-
let payload = QuorumCommitmentPayload {
224-
version: 0,
225-
height: 0,
226-
finalization_commitment: QuorumFinalizationCommitment {
163+
{
164+
let want = 317;
165+
let payload = QuorumCommitmentPayload {
227166
version: 0,
228-
llmq_type: 0,
229-
quorum_hash: QuorumHash::all_zeros(),
230-
quorum_index: None,
231-
signers: vec![1, 2, 3, 4, 5],
232-
valid_members: vec![6, 7, 8, 9, 0],
233-
quorum_public_key: BLSPublicKey::from([0; 48]),
234-
quorum_vvec_hash: QuorumVVecHash::all_zeros(),
235-
quorum_sig: BLSSignature::from([0; 96]),
236-
sig: BLSSignature::from([0; 96]),
237-
},
238-
};
239-
let actual = payload.consensus_encode(&mut Vec::new()).unwrap();
240-
assert_eq!(payload.size(), want);
241-
assert_eq!(actual, want);
242-
}
243-
244-
#[test]
245-
fn test_compact_size_round_trip() {
246-
let test_values = vec![
247-
0u32,
248-
1,
249-
252,
250-
253,
251-
254,
252-
255,
253-
300,
254-
5000,
255-
65535,
256-
65536,
257-
70000,
258-
1_000_000,
259-
u32::MAX,
260-
];
261-
262-
for &value in &test_values {
263-
let mut buffer = Vec::new();
264-
// Write the value to the buffer
265-
let bytes_written = write_compact_size(&mut buffer, value).expect("Failed to write");
266-
// Read the value back from the buffer
267-
let mut cursor = Cursor::new(&buffer);
268-
let read_value = read_compact_size(&mut cursor).expect("Failed to read");
269-
270-
// Assert that the original value matches the deserialized value
271-
assert_eq!(
272-
value, read_value,
273-
"Deserialized value does not match original for value {}",
274-
value
275-
);
276-
277-
// Ensure that we've consumed all bytes (no extra bytes left)
278-
let position = cursor.position();
279-
assert_eq!(
280-
position as usize,
281-
buffer.len(),
282-
"Not all bytes were consumed for value {}",
283-
value
284-
);
167+
height: 0,
168+
finalization_commitment: QuorumFinalizationCommitment {
169+
version: 1,
170+
llmq_type: 0,
171+
quorum_hash: QuorumHash::all_zeros(),
172+
quorum_index: None,
173+
signers: vec![true, false, true, true, false],
174+
valid_members: vec![false, true, false, true],
175+
quorum_public_key: BLSPublicKey::from([0; 48]),
176+
quorum_vvec_hash: QuorumVVecHash::all_zeros(),
177+
quorum_sig: BLSSignature::from([0; 96]),
178+
sig: BLSSignature::from([0; 96]),
179+
},
180+
};
181+
let actual = payload.consensus_encode(&mut Vec::new()).unwrap();
182+
assert_eq!(payload.size(), want);
183+
assert_eq!(actual, want);
184+
}
185+
{
186+
let want = 319;
187+
let payload = QuorumCommitmentPayload {
188+
version: 0,
189+
height: 0,
190+
finalization_commitment: QuorumFinalizationCommitment {
191+
version: 2,
192+
llmq_type: 0,
193+
quorum_hash: QuorumHash::all_zeros(),
194+
quorum_index: Some(1),
195+
signers: vec![true, false, true, true, false, true, false],
196+
valid_members: vec![false, true, false, true, false, true],
197+
quorum_public_key: BLSPublicKey::from([0; 48]),
198+
quorum_vvec_hash: QuorumVVecHash::all_zeros(),
199+
quorum_sig: BLSSignature::from([0; 96]),
200+
sig: BLSSignature::from([0; 96]),
201+
},
202+
};
203+
let actual = payload.consensus_encode(&mut Vec::new()).unwrap();
204+
assert_eq!(payload.size(), want);
205+
assert_eq!(actual, want);
285206
}
286207
}
287208
}

0 commit comments

Comments
 (0)