Skip to content

Commit

Permalink
chore: generic checksum impl (#145)
Browse files Browse the repository at this point in the history
  • Loading branch information
TropicalDog17 authored Oct 1, 2024
1 parent 3e2c745 commit 0e87d6b
Show file tree
Hide file tree
Showing 13 changed files with 42 additions and 75 deletions.
11 changes: 2 additions & 9 deletions src/network/protocol/messages/feefilter.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const std = @import("std");
const protocol = @import("../lib.zig");
const Sha256 = std.crypto.hash.sha2.Sha256;
const genericChecksum = @import("lib.zig").genericChecksum;

/// FeeFilterMessage represents the "feefilter" message
///
Expand All @@ -18,15 +19,7 @@ pub const FeeFilterMessage = struct {
///
/// Computed as `Sha256(Sha256(self.serialize()))[0..4]`
pub fn checksum(self: *const Self) [4]u8 {
var digest: [32]u8 = undefined;
var hasher = Sha256.init(.{});
const writer = hasher.writer();
self.serializeToWriter(writer) catch unreachable; // Sha256.write is infallible
hasher.final(&digest);

Sha256.hash(&digest, &digest, .{});

return digest[0..4].*;
return genericChecksum(self);
}

/// Serialize a message as bytes and write them to the buffer.
Expand Down
6 changes: 2 additions & 4 deletions src/network/protocol/messages/filteradd.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const std = @import("std");
const protocol = @import("../lib.zig");
const genericChecksum = @import("lib.zig").genericChecksum;

/// FilterAddMessage represents the "filteradd" message
///
Expand All @@ -15,10 +16,7 @@ pub const FilterAddMessage = struct {

/// Returns the message checksum
pub fn checksum(self: *const Self) [4]u8 {
var digest: [32]u8 = undefined;
std.crypto.hash.sha2.Sha256.hash(self.element, &digest, .{});
std.crypto.hash.sha2.Sha256.hash(&digest, &digest, .{});
return digest[0..4].*;
return genericChecksum(self);
}

/// Serialize the message as bytes and write them to the Writer.
Expand Down
4 changes: 2 additions & 2 deletions src/network/protocol/messages/filterclear.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const std = @import("std");
const protocol = @import("../lib.zig");
const default_checksum = @import("lib.zig").default_checksum;

/// FilterClear represents the "filterclear" message
///
Expand All @@ -13,8 +14,7 @@ pub const FilterClearMessage = struct {

pub fn checksum(self: FilterClearMessage) [4]u8 {
_ = self;
// If payload is empty, the checksum is always 0x5df6e0e2 (SHA256(SHA256("")))
return [4]u8{ 0x5d, 0xf6, 0xe0, 0xe2 };
return default_checksum;
}

/// Serialize a message as bytes and return them.
Expand Down
4 changes: 2 additions & 2 deletions src/network/protocol/messages/getaddr.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const std = @import("std");
const protocol = @import("../lib.zig");
const default_checksum = @import("lib.zig").default_checksum;

/// GetaddrMessage represents the "getaddr" message
///
Expand All @@ -13,8 +14,7 @@ pub const GetaddrMessage = struct {

pub fn checksum(self: GetaddrMessage) [4]u8 {
_ = self;
// If payload is empty, the checksum is always 0x5df6e0e2 (SHA256(SHA256("")))
return [4]u8{ 0x5d, 0xf6, 0xe0, 0xe2 };
return default_checksum;
}

/// Serialize a message as bytes and return them.
Expand Down
11 changes: 2 additions & 9 deletions src/network/protocol/messages/getblocks.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const std = @import("std");
const protocol = @import("../lib.zig");
const genericChecksum = @import("lib.zig").genericChecksum;

const Sha256 = std.crypto.hash.sha2.Sha256;

Expand All @@ -21,15 +22,7 @@ pub const GetblocksMessage = struct {
///
/// Computed as `Sha256(Sha256(self.serialize()))[0..4]`
pub fn checksum(self: *const GetblocksMessage) [4]u8 {
var digest: [32]u8 = undefined;
var hasher = Sha256.init(.{});
const writer = hasher.writer();
self.serializeToWriter(writer) catch unreachable; // Sha256.write is infaible
hasher.final(&digest);

Sha256.hash(&digest, &digest, .{});

return digest[0..4].*;
return genericChecksum(self);
}

/// Free the `header_hashes`
Expand Down
18 changes: 18 additions & 0 deletions src/network/protocol/messages/lib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub const FeeFilterMessage = @import("feefilter.zig").FeeFilterMessage;
pub const SendCmpctMessage = @import("sendcmpct.zig").SendCmpctMessage;
pub const FilterClearMessage = @import("filterclear.zig").FilterClearMessage;
pub const FilterAddMessage = @import("filteradd.zig").FilterAddMessage;
const Sha256 = std.crypto.hash.sha2.Sha256;
pub const NotFoundMessage = @import("notfound.zig").NotFoundMessage;
pub const SendHeadersMessage = @import("sendheaders.zig").SendHeadersMessage;

Expand Down Expand Up @@ -153,3 +154,20 @@ pub const Message = union(MessageTypes) {
};
}
};

pub const default_checksum: [4]u8 = [_]u8{ 0x5d, 0xf6, 0xe0, 0xe2 };

pub fn genericChecksum(m: anytype) [4]u8 {
comptime {
if (!std.meta.hasMethod(@TypeOf(m), "serializeToWriter")) @compileError("Expects m to have fn 'serializeToWriter'.");
}

var digest: [32]u8 = undefined;
var hasher = Sha256.init(.{});
m.serializeToWriter(hasher.writer()) catch unreachable;
hasher.final(&digest);

Sha256.hash(&digest, &digest, .{});

return digest[0..4].*;
}
4 changes: 2 additions & 2 deletions src/network/protocol/messages/mempool.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const std = @import("std");
const protocol = @import("../lib.zig");
const default_checksum = @import("lib.zig").default_checksum;

/// MempoolMessage represents the "mempool" message
///
Expand All @@ -13,8 +14,7 @@ pub const MempoolMessage = struct {

pub fn checksum(self: MempoolMessage) [4]u8 {
_ = self;
// If payload is empty, the checksum is always 0x5df6e0e2 (SHA256(SHA256("")))
return [4]u8{ 0x5d, 0xf6, 0xe0, 0xe2 };
return default_checksum;
}

/// Serialize a message as bytes and return them.
Expand Down
11 changes: 2 additions & 9 deletions src/network/protocol/messages/merkleblock.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const protocol = @import("../lib.zig");
const Sha256 = std.crypto.hash.sha2.Sha256;
const BlockHeader = @import("../../../types/BlockHeader.zig");
const CompactSizeUint = @import("bitcoin-primitives").types.CompatSizeUint;

const genericChecksum = @import("lib.zig").genericChecksum;
/// MerkleBlockMessage represents the "MerkleBlock" message
///
/// https://developer.bitcoin.org/reference/p2p_networking.html#merkleblock
Expand All @@ -22,14 +22,7 @@ pub const MerkleBlockMessage = struct {

/// Returns the message checksum
pub fn checksum(self: *const Self) [4]u8 {
var digest: [32]u8 = undefined;
var hasher = Sha256.init(.{});
self.serializeToWriter(hasher.writer()) catch unreachable;
hasher.final(&digest);

Sha256.hash(&digest, &digest, .{});

return digest[0..4].*;
return genericChecksum(self);
}

/// Free the allocated memory
Expand Down
11 changes: 2 additions & 9 deletions src/network/protocol/messages/ping.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const std = @import("std");
const protocol = @import("../lib.zig");
const Sha256 = std.crypto.hash.sha2.Sha256;
const genericChecksum = @import("lib.zig").genericChecksum;

/// PingMessage represents the "Ping" message
///
Expand All @@ -18,15 +19,7 @@ pub const PingMessage = struct {
///
/// Computed as `Sha256(Sha256(self.serialize()))[0..4]`
pub fn checksum(self: *const Self) [4]u8 {
var digest: [32]u8 = undefined;
var hasher = Sha256.init(.{});
const writer = hasher.writer();
self.serializeToWriter(writer) catch unreachable; // Sha256.write is infaible
hasher.final(&digest);

Sha256.hash(&digest, &digest, .{});

return digest[0..4].*;
return genericChecksum(self);
}

/// Serialize a message as bytes and write them to the buffer.
Expand Down
11 changes: 2 additions & 9 deletions src/network/protocol/messages/pong.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const std = @import("std");
const protocol = @import("../lib.zig");
const Sha256 = std.crypto.hash.sha2.Sha256;
const genericChecksum = @import("lib.zig").genericChecksum;

/// PongMessage represents the "Pong" message
///
Expand All @@ -18,15 +19,7 @@ pub const PongMessage = struct {
///
/// Computed as `Sha256(Sha256(self.serialize()))[0..4]`
pub fn checksum(self: *const Self) [4]u8 {
var digest: [32]u8 = undefined;
var hasher = Sha256.init(.{});
const writer = hasher.writer();
self.serializeToWriter(writer) catch unreachable; // Sha256.write is infaible
hasher.final(&digest);

Sha256.hash(&digest, &digest, .{});

return digest[0..4].*;
return genericChecksum(self);
}

/// Serialize a message as bytes and write them to the buffer.
Expand Down
11 changes: 2 additions & 9 deletions src/network/protocol/messages/sendcmpct.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const protocol = @import("../lib.zig");
const Sha256 = std.crypto.hash.sha2.Sha256;

const CompactSizeUint = @import("bitcoin-primitives").types.CompatSizeUint;
const genericChecksum = @import("lib.zig").genericChecksum;

/// SendCmpctMessage represents the "sendcmpct" message
///
Expand All @@ -20,15 +21,7 @@ pub const SendCmpctMessage = struct {
///
/// Computed as `Sha256(Sha256(self.serialize()))[0..4]`
pub fn checksum(self: *const SendCmpctMessage) [4]u8 {
var digest: [32]u8 = undefined;
var hasher = Sha256.init(.{});
const writer = hasher.writer();
self.serializeToWriter(writer) catch unreachable; // Sha256.write is infallible
hasher.final(&digest);

Sha256.hash(&digest, &digest, .{});

return digest[0..4].*;
return genericChecksum(self);
}
/// Serialize the message as bytes and write them to the Writer.
pub fn serializeToWriter(self: *const SendCmpctMessage, w: anytype) !void {
Expand Down
4 changes: 2 additions & 2 deletions src/network/protocol/messages/verack.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const std = @import("std");
const protocol = @import("../lib.zig");
const default_checksum = @import("lib.zig").default_checksum;

/// VerackMessage represents the "verack" message
///
Expand All @@ -13,8 +14,7 @@ pub const VerackMessage = struct {

pub fn checksum(self: VerackMessage) [4]u8 {
_ = self;
// If payload is empty, the checksum is always 0x5df6e0e2 (SHA256(SHA256("")))
return [4]u8{ 0x5d, 0xf6, 0xe0, 0xe2 };
return default_checksum;
}

/// Serialize a message as bytes and return them.
Expand Down
11 changes: 2 additions & 9 deletions src/network/protocol/messages/version.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const ServiceFlags = protocol.ServiceFlags;
const Sha256 = std.crypto.hash.sha2.Sha256;

const CompactSizeUint = @import("bitcoin-primitives").types.CompatSizeUint;
const genericChecksum = @import("lib.zig").genericChecksum;

/// VersionMessage represents the "version" message
///
Expand Down Expand Up @@ -35,15 +36,7 @@ pub const VersionMessage = struct {
///
/// Computed as `Sha256(Sha256(self.serialize()))[0..4]`
pub fn checksum(self: *const Self) [4]u8 {
var digest: [32]u8 = undefined;
var hasher = Sha256.init(.{});
const writer = hasher.writer();
self.serializeToWriter(writer) catch unreachable; // Sha256.write is infaible
hasher.final(&digest);

Sha256.hash(&digest, &digest, .{});

return digest[0..4].*;
return genericChecksum(self);
}

/// Free the `user_agent` if there is one
Expand Down

0 comments on commit 0e87d6b

Please sign in to comment.