Skip to content

Commit

Permalink
Feat/message/mempool (#106)
Browse files Browse the repository at this point in the history
Co-authored-by: Timothée Delabrouille <[email protected]>
  • Loading branch information
oxlime and tdelabro authored Sep 20, 2024
1 parent d070f88 commit 8561fcb
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 2 deletions.
12 changes: 11 additions & 1 deletion src/network/protocol/messages/lib.zig
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
const std = @import("std");
pub const VersionMessage = @import("version.zig").VersionMessage;
pub const VerackMessage = @import("verack.zig").VerackMessage;
pub const MempoolMessage = @import("mempool.zig").MempoolMessage;
pub const GetaddrMessage = @import("getaddr.zig").GetaddrMessage;

pub const MessageTypes = enum { Version, Verack, Getaddr };
pub const MessageTypes = enum {
Version,
Verack,
Mempool,
Getaddr,
};

pub const Message = union(MessageTypes) {
Version: VersionMessage,
Verack: VerackMessage,
Mempool: MempoolMessage,
Getaddr: GetaddrMessage,

pub fn deinit(self: Message, allocator: std.mem.Allocator) void {
switch (self) {
.Version => |m| m.deinit(allocator),
.Verack => {},
.Mempool => {},
.Getaddr => {},
}
}
pub fn checksum(self: Message) [4]u8 {
return switch (self) {
.Version => |m| m.checksum(),
.Verack => |m| m.checksum(),
.Mempool => |m| m.checksum(),
.Getaddr => |m| m.checksum(),
};
}
Expand All @@ -29,6 +38,7 @@ pub const Message = union(MessageTypes) {
return switch (self) {
.Version => |m| m.hintSerializedLen(),
.Verack => |m| m.hintSerializedLen(),
.Mempool => |m| m.hintSerializedLen(),
.Getaddr => |m| m.hintSerializedLen(),
};
}
Expand Down
57 changes: 57 additions & 0 deletions src/network/protocol/messages/mempool.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

const std = @import("std");
const native_endian = @import("builtin").target.cpu.arch.endian();
const protocol = @import("../lib.zig");

/// MempoolMessage represents the "mempool" message
///
/// https://developer.bitcoin.org/reference/p2p_networking.html#mempool
pub const MempoolMessage = struct {
// mempool message do not contain any payload, thus there is no field

pub inline fn name() *const [12]u8 {
return protocol.CommandNames.MEMPOOL ++ [_]u8{0} ** 5;
}

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 };
}

/// Serialize a message as bytes and return them.
pub fn serialize(self: *const MempoolMessage, allocator: std.mem.Allocator) ![]u8 {
_ = self;
_ = allocator;
return &.{};
}

pub fn deserializeReader(allocator: std.mem.Allocator, r: anytype) !MempoolMessage {
_ = allocator;
_ = r;
return MempoolMessage{};
}

pub fn hintSerializedLen(self: MempoolMessage) usize {
_ = self;
return 0;
}

};

// TESTS

test "ok_full_flow_MempoolMessage" {
const allocator = std.testing.allocator;

{
const msg = MempoolMessage{};

const payload = try msg.serialize(allocator);
defer allocator.free(payload);
const deserialized_msg = try MempoolMessage.deserializeReader(allocator, payload);
_ = deserialized_msg;

try std.testing.expect(payload.len == 0);
}
}
32 changes: 31 additions & 1 deletion src/network/wire/lib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ pub fn receiveMessage(allocator: std.mem.Allocator, r: anytype) !protocol.messag
const message: protocol.messages.Message = if (std.mem.eql(u8, &command, protocol.messages.VersionMessage.name()))
protocol.messages.Message{ .Version = try protocol.messages.VersionMessage.deserializeReader(allocator, r) }
else if (std.mem.eql(u8, &command, protocol.messages.VerackMessage.name()))
protocol.messages.Message{ .Verack = try protocol.messages.VerackMessage.deserializeReader(allocator, r) }
protocol.messages.Message{ .Verack = try protocol.messages.VerackMessage.deserializeReader(allocator, r)}
else if (std.mem.eql(u8, &command, protocol.messages.MempoolMessage.name()))
protocol.messages.Message{ .Mempool = try protocol.messages.MempoolMessage.deserializeReader(allocator, r)}
else if (std.mem.eql(u8, &command, protocol.messages.GetaddrMessage.name()))
protocol.messages.Message{ .Getaddr = try protocol.messages.GetaddrMessage.deserializeReader(allocator, r) }
else
Expand Down Expand Up @@ -135,6 +137,7 @@ test "ok_send_version_message" {
switch (received_message) {
.Version => |rm| try std.testing.expect(message.eql(&rm)),
.Verack => unreachable,
.Mempool => unreachable,
.Getaddr => unreachable,
}
}
Expand All @@ -160,6 +163,33 @@ test "ok_send_verack_message" {
switch (received_message) {
.Verack => {},
.Version => unreachable,
.Mempool => unreachable,
.Getaddr => unreachable,
}
}

test "ok_send_mempool_message" {
const ArrayList = std.ArrayList;
const test_allocator = std.testing.allocator;
const MempoolMessage = protocol.messages.MempoolMessage;

var list: std.ArrayListAligned(u8, null) = ArrayList(u8).init(test_allocator);
defer list.deinit();

const message = MempoolMessage{};

const writer = list.writer();
try sendMessage(test_allocator, writer, protocol.PROTOCOL_VERSION, protocol.BitcoinNetworkId.MAINNET, message);
var fbs: std.io.FixedBufferStream([]u8) = std.io.fixedBufferStream(list.items);
const reader = fbs.reader();

const received_message = try receiveMessage(test_allocator, reader);
defer received_message.deinit(test_allocator);

switch (received_message) {
.Mempool => {},
.Verack => unreachable,
.Version => unreachable,
.Getaddr => unreachable,
}
}
Expand Down

0 comments on commit 8561fcb

Please sign in to comment.