Skip to content

Commit

Permalink
Implement clone for gossip data to allow for safe construction of mes…
Browse files Browse the repository at this point in the history
…sages without table lock
  • Loading branch information
yewman committed Jul 9, 2024
1 parent eb77c5c commit 24b8ac4
Show file tree
Hide file tree
Showing 5 changed files with 325 additions and 18 deletions.
10 changes: 10 additions & 0 deletions src/bloom/bit_set.zig
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ pub fn DynamicArrayBitSet(comptime MaskIntType: type) type {
return self.bit_length;
}

pub fn clone(self: Self, allocator: Allocator) error{OutOfMemory}!Self {
return .{
.num_masks = self.num_masks,
.last_pad_bits = self.last_pad_bits,
.last_item_mask = self.last_item_mask,
.bit_length = self.bit_length,
.masks = try allocator.dupe(MaskInt, self.masks),
};
}

/// Returns true if the bit at the specified index
/// is present in the set, false otherwise.
pub fn isSet(self: Self, index: usize) bool {
Expand Down
42 changes: 42 additions & 0 deletions src/core/transaction.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ pub const Transaction = struct {
};
}

pub fn clone(self: *const Transaction, allocator: std.mem.Allocator) error{OutOfMemory}!Transaction {
return .{
.signatures = try allocator.dupe(Signature, self.signatures),
.message = try self.message.clone(allocator),
};
}

pub fn deinit(self: *Transaction, allocator: std.mem.Allocator) void {
allocator.free(self.signatures);
self.message.deinit(allocator);
}

pub fn sanitize(self: *const Transaction) !void {
const num_required_sigs = self.message.header.num_required_signatures;
const num_signatures = self.signatures.len;
Expand Down Expand Up @@ -57,6 +69,23 @@ pub const Message = struct {
};
}

pub fn clone(self: *const Message, allocator: std.mem.Allocator) error{OutOfMemory}!Message {
const instructions = try allocator.alloc(CompiledInstruction, self.instructions.len);
for (instructions, 0..) |*ci, i| ci.* = try self.instructions[i].clone(allocator);
return .{
.header = self.header,
.account_keys = try allocator.dupe(Pubkey, self.account_keys),
.recent_blockhash = self.recent_blockhash,
.instructions = instructions,
};
}

pub fn deinit(self: *Message, allocator: std.mem.Allocator) void {
allocator.free(self.account_keys);
for (self.instructions) |*ci| ci.deinit(allocator);
allocator.free(self.instructions);
}

pub const MessageSanitizeError = error{
NotEnoughAccounts,
MissingWritableFeePayer,
Expand Down Expand Up @@ -118,6 +147,19 @@ pub const CompiledInstruction = struct {

pub const @"!bincode-config:accounts" = ShortVecConfig(u8);
pub const @"!bincode-config:data" = ShortVecConfig(u8);

pub fn clone(self: *const CompiledInstruction, allocator: std.mem.Allocator) error{OutOfMemory}!CompiledInstruction {
return .{
.program_id_index = self.program_id_index,
.accounts = try allocator.dupe(u8, self.accounts),
.data = try allocator.dupe(u8, self.data),
};
}

pub fn deinit(self: *CompiledInstruction, allocator: std.mem.Allocator) void {
allocator.free(self.accounts);
allocator.free(self.data);
}
};

test "core.transaction: tmp" {
Expand Down
Loading

0 comments on commit 24b8ac4

Please sign in to comment.