Skip to content

Commit

Permalink
Merge pull request #56 from chaintope/port_pr_35
Browse files Browse the repository at this point in the history
Add max block size xfield
  • Loading branch information
Yamaguchi authored Jun 14, 2024
2 parents 06215a4 + 59e3f0d commit d8a3ec7
Showing 1 changed file with 69 additions and 1 deletion.
70 changes: 69 additions & 1 deletion tapyrus/src/blockdata/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ impl Header {
let block = HeaderWithoutProof::from(self);
BlockSigHash::hash(&serialize(&block))
}

/// Return the max block size in this BlockHeader
pub fn max_block_size(&self) -> Option<u32> {
match self.xfield {
XField::MaxBlockSize(size) => Some(size),
_ => None,
}
}
}

impl_consensus_encoding!(
Expand Down Expand Up @@ -233,6 +241,8 @@ pub enum XField {
None,
/// Aggregate public key used to verify block proof.
AggregatePublicKey(PublicKey),
/// Max block size to change the block size limit.
MaxBlockSize(u32),
/// Unknown type
Unknown(u8, Vec<u8>),
}
Expand All @@ -243,14 +253,16 @@ impl XField {
match self {
XField::None => 0u8,
XField::AggregatePublicKey(_) => 1u8,
XField::MaxBlockSize(_) => 2u8,
XField::Unknown(x_type, _) => *x_type,
}
}
/// Return field size
pub fn size(&self) -> usize {
match self {
XField::None => 1,
XField::AggregatePublicKey(_) => 1 + 1 + 33,
XField::AggregatePublicKey(_) => 35, // 1 + 1 + 33
XField::MaxBlockSize(_) => 5, // 1 + 4
XField::Unknown(_, data) => 1 + VarInt::from(data.len()).size() + data.len(),
}
}
Expand Down Expand Up @@ -329,6 +341,10 @@ impl Decodable for XField {
.map_err(|_| encode::Error::ParseFailed("aggregate public key"))?;
Ok(XField::AggregatePublicKey(pk))
}
2 => {
let size: u32 = Decodable::consensus_decode(&mut d)?;
Ok(XField::MaxBlockSize(size))
}
_ => {
let data: Vec<u8> = Decodable::consensus_decode(&mut d)?;
Ok(XField::Unknown(x_type, data))
Expand All @@ -347,6 +363,10 @@ impl Encodable for XField {
let len = pk.to_bytes().consensus_encode(&mut s)?;
Ok(1 + len)
}
XField::MaxBlockSize(size) => {
let len = size.consensus_encode(&mut s)?;
Ok(1 + len)
}
XField::Unknown(_type, data) => {
let len = data.consensus_encode(&mut s)?;
Ok(1 + len)
Expand Down Expand Up @@ -765,6 +785,10 @@ mod tests {
.unwrap();
let decode: XField = deserialize(&xfield).unwrap();
serde_round_trip!(decode);

let xfield = Vec::from_hex("02000000ff").unwrap();
let decode: XField = deserialize(&xfield).unwrap();
serde_round_trip!(decode);
}

// Check testnet block 000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b
Expand Down Expand Up @@ -842,6 +866,50 @@ mod tests {
assert!(segwit_signal.is_signalling_soft_fork(1));
assert!(!segwit_signal.is_signalling_soft_fork(2));
}

#[test]
fn xfield_max_block_size_test() {
let bytes = Vec::from_hex("0200010000").unwrap();
let decode: XField = deserialize(&bytes).unwrap();
assert_eq!(serialize(&decode), bytes);

let maxblocksize:u32 = 0x100;
assert_eq!(decode, XField::MaxBlockSize(maxblocksize));
let xfield = XField::from_str("0200010000");
assert_eq!(xfield.unwrap(), XField::MaxBlockSize(maxblocksize));

// max u32
let max_size_bytes = Vec::from_hex("FFFFFFFF").unwrap();
let decoded_max:u32 = deserialize(&max_size_bytes).unwrap();
assert_eq!(XField::MaxBlockSize(u32::MAX).size(), 5);
assert_eq!(serialize(&decoded_max), max_size_bytes);

// zero
let zero_size_bytes = Vec::from_hex("00000000").unwrap();
let decoded_zero:u32 = deserialize(&zero_size_bytes).unwrap();
assert_eq!(XField::MaxBlockSize(0).size(), 5);
assert_eq!(serialize(&decoded_zero), zero_size_bytes);

// negative
let x:i32 = -1;
let hex_x = Vec::from_hex(&format!("{:08x}", x)).unwrap();
let decoded_x:u32 = deserialize(&hex_x).unwrap();
assert!(XField::from_str(&format!("{:08x}", decoded_x)).is_err());
assert!(XField::from_str(&format!("{:08x}", x)).is_err());

assert!(XField::from_str("pq").is_err());
assert!(XField::from_str("020001").is_err());
}

#[test]
#[should_panic]
fn xfield_max_block_size_panic_test() {
// larger than u32::MAX
let overflow_value:u64 = (u32::MAX as u64) + 1;
let overflow_bytes = Vec::from_hex(&format!("{:016x}", overflow_value)).unwrap();
assert!(deserialize::<u32>(&overflow_bytes).is_err());
assert!(XField::from_str(&format!("{:016x}", overflow_value)).is_err());
}
}

#[cfg(bench)]
Expand Down

0 comments on commit d8a3ec7

Please sign in to comment.