Skip to content

Commit

Permalink
Add a hash value to Inventory's Error variant
Browse files Browse the repository at this point in the history
While the hash value of the Error variant is meaningless, the variant
still conforms to all other Inventory messages and requires a 32
byte hash to be sent over the wire. This is how bitcoin core operates.

This patch adds the 32 byte array to the Error variant in order to make
its Encoding and Decoding paths symmetrical. This also allows a reader
to discard the 32 bytes when decoding a message. The hash is still not
exposed to the caller.

This was never a problem before because the top level RawNetworkPackage
pulls all the required bytes off a reader before decoding. But this is
not as easy to do with the v2 p2p network messages.
  • Loading branch information
nyonson committed Dec 19, 2024
1 parent ebe43b6 commit 72e97c6
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 7 deletions.
2 changes: 1 addition & 1 deletion bitcoin/src/p2p/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ mod test {
)]),
NetworkMessage::Inv(vec![Inventory::Block(hash([8u8; 32]).into())]),
NetworkMessage::GetData(vec![Inventory::Transaction(hash([45u8; 32]).into())]),
NetworkMessage::NotFound(vec![Inventory::Error]),
NetworkMessage::NotFound(vec![Inventory::Error([0u8; 32])]),
NetworkMessage::GetBlocks(GetBlocksMessage::new(
vec![hash([1u8; 32]).into(), hash([4u8; 32]).into()],
hash([5u8; 32]).into(),
Expand Down
13 changes: 7 additions & 6 deletions bitcoin/src/p2p/message_blockdata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ use crate::transaction::{Txid, Wtxid};
/// An inventory item.
#[derive(PartialEq, Eq, Clone, Debug, Copy, Hash, PartialOrd, Ord)]
pub enum Inventory {
/// Error --- these inventories can be ignored
Error,
/// Error --- these inventories can be ignored.
/// While a 32 byte hash is expected over the wire, the value is meaningless.
Error([u8; 32]),
/// Transaction
Transaction(Txid),
/// Block
Expand All @@ -42,10 +43,10 @@ pub enum Inventory {
impl Inventory {
/// Return the item value represented as a SHA256-d hash.
///
/// Returns [None] only for [Inventory::Error].
/// Returns [None] only for [Inventory::Error] who's hash value is meaningless.
pub fn network_hash(&self) -> Option<[u8; 32]> {
match self {
Inventory::Error => None,
Inventory::Error(_) => None,
Inventory::Transaction(t) => Some(t.to_byte_array()),
Inventory::Block(b) => Some(b.to_byte_array()),
Inventory::CompactBlock(b) => Some(b.to_byte_array()),
Expand All @@ -66,7 +67,7 @@ impl Encodable for Inventory {
};
}
Ok(match *self {
Inventory::Error => encode_inv!(0, [0; 32]),
Inventory::Error(_) => encode_inv!(0, [0; 32]),
Inventory::Transaction(ref t) => encode_inv!(1, t),
Inventory::Block(ref b) => encode_inv!(2, b),
Inventory::CompactBlock(ref b) => encode_inv!(4, b),
Expand All @@ -83,7 +84,7 @@ impl Decodable for Inventory {
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let inv_type: u32 = Decodable::consensus_decode(r)?;
Ok(match inv_type {
0 => Inventory::Error,
0 => Inventory::Error(Decodable::consensus_decode(r)?),
1 => Inventory::Transaction(Decodable::consensus_decode(r)?),
2 => Inventory::Block(Decodable::consensus_decode(r)?),
4 => Inventory::CompactBlock(Decodable::consensus_decode(r)?),
Expand Down

0 comments on commit 72e97c6

Please sign in to comment.