Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 14 additions & 16 deletions conformance/src/txn_execute.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1397,25 +1397,23 @@ pub fn hashSlot(
var signature_count_bytes: [8]u8 = undefined;
std.mem.writeInt(u64, &signature_count_bytes, 0, .little);

const initial_hash =
if (feature_set.active(.remove_accounts_delta_hash, 0))
Hash.generateSha256(.{
Hash.ZEROES,
&signature_count_bytes,
blockhash,
})
else
Hash.generateSha256(.{
Hash.ZEROES,
try freeze.deltaMerkleHash(account_reader, allocator, 0),
&signature_count_bytes,
blockhash,
});
var hash = std.crypto.hash.sha2.Sha256.init(.{});
hash.update(&sig.core.Hash.ZEROES.data); // no parent lt hash, start with zeroes
if (!feature_set.active(.remove_accounts_delta_hash, 0)) {
const delta_hash = try freeze.deltaMerkleHash(account_reader, allocator, 0);
hash.update(&delta_hash.data);
}
hash.update(&signature_count_bytes);
hash.update(&blockhash.data);
const initial_hash = hash.finalResult();

return if (feature_set.active(.accounts_lt_hash, 0))
Hash.generateSha256(.{ initial_hash, sig.core.hash.LtHash.IDENTITY.constBytes() })
Hash.initMany(&.{
&initial_hash,
sig.core.hash.LtHash.IDENTITY.constBytes(),
})
else
initial_hash;
.{ .data = initial_hash };
}

const State = struct {
Expand Down
12 changes: 6 additions & 6 deletions src/consensus/optimistic_vote_verifier.zig
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,9 @@ test "OptimisticConfirmationVerifier.verifyForUnrootedOptimisticSlots: unrooted
);

// Hashes for slots 1,3,5
const h1 = Hash.generateSha256("1");
const h3 = Hash.generateSha256("3");
const h5 = Hash.generateSha256("5");
const h1 = Hash.init("1");
const h3 = Hash.init("3");
const h5 = Hash.init("5");

var verifier = OptimisticConfirmationVerifier.init(
sig.time.Instant.now(),
Expand Down Expand Up @@ -369,7 +369,7 @@ test "OptimisticConfirmationVerifier.verifyForUnrootedOptimisticSlots: unrooted
const unrooted = try verifier.verifyForUnrootedOptimisticSlots(
allocator,
&ledger_reader,
.{ .slot = 4, .hash = Hash.generateSha256("4"), .ancestors = &anc4 },
.{ .slot = 4, .hash = Hash.init("4"), .ancestors = &anc4 },
);
defer allocator.free(unrooted);
try std.testing.expectEqual(1, unrooted.len);
Expand All @@ -395,7 +395,7 @@ test "OptimisticConfirmationVerifier.verifyForUnrootedOptimisticSlots: unrooted
const unrooted = try verifier.verifyForUnrootedOptimisticSlots(
allocator,
&ledger_reader,
.{ .slot = 7, .hash = Hash.generateSha256("7"), .ancestors = &anc7 },
.{ .slot = 7, .hash = Hash.init("7"), .ancestors = &anc7 },
);
defer allocator.free(unrooted);
// Expect two entries (1 and 3), order by slot ascending due to set ordering
Expand Down Expand Up @@ -423,7 +423,7 @@ test "OptimisticConfirmationVerifier.verifyForUnrootedOptimisticSlots: unrooted
const unrooted = try verifier.verifyForUnrootedOptimisticSlots(
allocator,
&ledger_reader,
.{ .slot = 7, .hash = Hash.generateSha256("7"), .ancestors = &anc7 },
.{ .slot = 7, .hash = Hash.init("7"), .ancestors = &anc7 },
);
defer allocator.free(unrooted);
try std.testing.expectEqual(0, unrooted.len);
Expand Down
4 changes: 2 additions & 2 deletions src/consensus/vote_listener.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1601,14 +1601,14 @@ test "vote_parser.parseVoteTransaction" {
var prng = std.Random.DefaultPrng.init(42);
const random = prng.random();
try vote_parser.testParseVoteTransaction(null, random);
try vote_parser.testParseVoteTransaction(Hash.generateSha256(&[_]u8{42}), random);
try vote_parser.testParseVoteTransaction(Hash.init(&.{42}), random);
}

test "vote_parser.parseSanitizedVoteTransaction" {
var prng = std.Random.DefaultPrng.init(43);
const random = prng.random();
try vote_parser.testParseSanitizedVoteTransaction(null, random);
try vote_parser.testParseSanitizedVoteTransaction(Hash.generateSha256(&[_]u8{43}), random);
try vote_parser.testParseSanitizedVoteTransaction(Hash.init(&.{43}), random);
}

test verifyVoteTransaction {
Expand Down
6 changes: 3 additions & 3 deletions src/core/blockhash_queue.zig
Original file line number Diff line number Diff line change
Expand Up @@ -212,15 +212,15 @@ test "reject old last hash" {
defer queue.deinit(allocator);

for (0..102) |i| {
const last_hash_i = Hash.ZEROES.extendAndHash(&[_]u8{@intCast(i)});
const last_hash_i = Hash.ZEROES.extend(&[_]u8{@intCast(i)});
try queue.insertHash(allocator, last_hash_i, 0);
}

const hash_0 = Hash.ZEROES.extendAndHash(&[_]u8{@intCast(0)});
const hash_0 = Hash.ZEROES.extend(&[_]u8{@intCast(0)});
try std.testing.expect(!queue.isHashValidForAge(hash_0, max_age));
try std.testing.expect(!queue.isHashValidForAge(hash_0, 0));

const hash_1 = Hash.ZEROES.extendAndHash(&[_]u8{@intCast(1)});
const hash_1 = Hash.ZEROES.extend(&[_]u8{@intCast(1)});
try std.testing.expect(queue.isHashValidForAge(hash_1, max_age));
try std.testing.expect(!queue.isHashValidForAge(hash_1, 0));
}
Expand Down
25 changes: 12 additions & 13 deletions src/core/entry.zig
Original file line number Diff line number Diff line change
Expand Up @@ -110,20 +110,19 @@ pub fn verifyPoh(
if (entry.num_hashes == 0) continue;

for (1..entry.num_hashes) |_| {
current_hash = Hash.generateSha256(&current_hash.data);
current_hash = Hash.init(&current_hash.data);
}

if (entry.transactions.len > 0) {
const mixin =
try hashTransactions(allocator, optional.preallocated_nodes, entry.transactions);
current_hash = current_hash.extendAndHash(&mixin.data);
} else {
current_hash = Hash.generateSha256(&current_hash.data);
}

if (!current_hash.eql(entry.hash)) {
return false;
}
const mixin = try hashTransactions(
allocator,
optional.preallocated_nodes,
entry.transactions,
);
current_hash = current_hash.extend(&mixin.data);
} else current_hash = Hash.init(&current_hash.data);

if (!current_hash.eql(entry.hash)) return false;
}

return true;
Expand Down Expand Up @@ -159,7 +158,7 @@ pub fn hashTransactions(
try nodes.ensureTotalCapacity(allocator, capacity);

for (transactions) |tx| for (tx.signatures) |signature| {
const hash = Hash.generateSha256(.{ LEAF_PREFIX, &signature.data });
const hash = Hash.initMany(&.{ LEAF_PREFIX, &signature.data });
nodes.appendAssumeCapacity(hash);
};

Expand All @@ -177,7 +176,7 @@ pub fn hashTransactions(
// Duplicate last entry if the level length is odd
&nodes.items[prev_level_start + prev_level_idx];

const hash = Hash.generateSha256(.{ INTERMEDIATE_PREFIX, &lsib.data, &rsib.data });
const hash = Hash.initMany(&.{ INTERMEDIATE_PREFIX, &lsib.data, &rsib.data });
nodes.appendAssumeCapacity(hash);
}
prev_level_start = level_start;
Expand Down
61 changes: 20 additions & 41 deletions src/core/hash.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36,54 +36,33 @@ pub const Hash = extern struct {

pub const SIZE = 32;

pub const ZEROES: Hash = .{ .data = .{0} ** SIZE };

/// Hashes the input byte slice(s) using SHA 256.
///
/// If the passed-in type contains multiple byte slices, it will
/// iterate/recurse over them in order, updating the hasher for all of them
/// before finalizing at the end.
pub fn generateSha256(
/// May be a slice or array of bytes, or a slice, array, or tuple
/// containing slices or arrays of bytes nested with arbitrary depth.
///
/// for example:
/// - []const u8
/// - []const []const u8
/// - [2]u8
/// - *[13]u8
/// - struct { [128]u8, []const []const u8, struct { []const u8 }, ... }
data: anytype,
) Hash {
var hasher = Sha256.init(.{});
update(&hasher, data);
return .{ .data = hasher.finalResult() };
pub const ZEROES: Hash = .{ .data = @splat(0) };

/// Creates a `Hash` by applying SHA256 to the input `data` and using
/// the result of that as the output.
pub fn init(data: []const u8) Hash {
var out: [32]u8 = undefined;
Sha256.hash(data, &out, .{});
return .{ .data = out };
}

/// re-hashes the current hash with the mixed-in byte slice(s).
pub fn extendAndHash(self: Hash, data: anytype) Hash {
return generateSha256(.{ self.data, data });
/// Does the same thing as `init`, but updates the hash with each
/// input slice from the `data` list.
pub fn initMany(data: []const []const u8) Hash {
var new = Sha256.init(.{});
for (data) |d| new.update(d);
return .{ .data = new.finalResult() };
}

fn update(hasher: *Sha256, data: anytype) void {
const T = @TypeOf(data);

if (T == Hash or T == *const Hash or T == *Hash) {
hasher.update(&data.data);
} else if (@typeInfo(T) == .@"struct") {
inline for (data) |val| update(hasher, val);
} else if (std.meta.Elem(T) == u8) switch (@typeInfo(T)) {
.array => hasher.update(&data),
else => hasher.update(data),
} else {
for (data) |val| update(hasher, val);
}
/// re-hashes the current hash with the mixed-in byte slice(s).
pub fn extend(self: Hash, data: []const u8) Hash {
return .initMany(&.{ &self.data, data });
}

pub fn eql(self: Hash, other: Hash) bool {
const xx: @Vector(SIZE, u8) = self.data;
const yy: @Vector(SIZE, u8) = other.data;
return @reduce(.And, xx == yy);
const x: @Vector(SIZE, u8) = self.data;
const y: @Vector(SIZE, u8) = other.data;
return @reduce(.And, x == y);
}

pub fn order(self: *const Hash, other: *const Hash) std.math.Order {
Expand Down
10 changes: 5 additions & 5 deletions src/core/poh.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub const Poh = struct {
pub fn hash(self: *Poh, max_num_hashes: u64) bool {
const num_hashes = @min(self.remaining_hashes -| 1, max_num_hashes);
for (0..num_hashes) |_| {
self.latest_hash = self.latest_hash.extendAndHash(.{});
self.latest_hash = .init(&self.latest_hash.data);
}
self.num_hashes += num_hashes;
self.remaining_hashes -= num_hashes;
Expand Down Expand Up @@ -70,12 +70,12 @@ pub const Poh = struct {
return null; // needs a tick first
}

self.latest_hash = self.latest_hash.extendAndHash(mixin.data);
self.latest_hash = self.latest_hash.extend(&mixin.data);
const num_hashes = self.num_hashes + 1;
self.num_hashes = 0;
self.remaining_hashes -= 1;

return PohEntry{
return .{
.num_hashes = num_hashes,
.hash = self.latest_hash,
};
Expand All @@ -84,7 +84,7 @@ pub const Poh = struct {
/// Calculate the hash for a tick entry, without a mixin hash, and increment
/// the tick counter
pub fn tick(self: *Poh) ?PohEntry {
self.latest_hash = self.latest_hash.extendAndHash(.{});
self.latest_hash = .init(&self.latest_hash.data);
self.num_hashes += 1;
self.remaining_hashes -= 1;

Expand All @@ -98,7 +98,7 @@ pub const Poh = struct {
self.num_hashes = 0;
self.tick_count += 1;

return PohEntry{
return .{
.num_hashes = num_hashes,
.hash = self.latest_hash,
};
Expand Down
2 changes: 1 addition & 1 deletion src/core/shred.zig
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub const ShredVersion = struct {
var hash = genesis_hash;
if (maybe_hard_forks) |hard_forks| {
for (hard_forks.entries.items) |*hard_fork| {
hash = Hash.extendAndHash(
hash = Hash.extend(
hash,
std.mem.asBytes(hard_fork),
);
Expand Down
12 changes: 6 additions & 6 deletions src/gossip/fuzz_service.zig
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,9 @@ pub fn randomPullRequestWithContactInfo(
// add more random hashes
for (0..5) |_| {
const rand_value = try randomSignedGossipData(allocator, random, true);
var buf: [PACKET_DATA_SIZE]u8 = undefined;
const bytes = try bincode.writeToSlice(&buf, rand_value, bincode.Params.standard);
const value_hash = Hash.generateSha256(bytes);
var buffer: [PACKET_DATA_SIZE]u8 = undefined;
const bytes = try bincode.writeToSlice(&buffer, rand_value, bincode.Params.standard);
const value_hash = Hash.init(bytes);
filter.filter.add(&value_hash.data);
}
} else {
Expand All @@ -459,9 +459,9 @@ pub fn randomPullRequestWithContactInfo(

for (0..5) |_| {
const rand_value = try randomSignedGossipData(allocator, random, true);
var buf: [PACKET_DATA_SIZE]u8 = undefined;
const bytes = try bincode.writeToSlice(&buf, rand_value, bincode.Params.standard);
const value_hash = Hash.generateSha256(bytes);
var buffer: [PACKET_DATA_SIZE]u8 = undefined;
const bytes = try bincode.writeToSlice(&buffer, rand_value, bincode.Params.standard);
const value_hash = Hash.init(bytes);
filter_set.add(&value_hash);
}

Expand Down
4 changes: 2 additions & 2 deletions src/gossip/ping_pong.zig
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub const Pong = struct {

pub fn init(ping: *const Ping, keypair: *const KeyPair) !Pong {
const token_with_prefix = PING_PONG_HASH_PREFIX ++ ping.token;
const hash = Hash.generateSha256(token_with_prefix);
const hash = Hash.init(&token_with_prefix);
const signature = keypair.sign(&hash.data, null) catch return error.SignatureError;

return .{
Expand Down Expand Up @@ -172,7 +172,7 @@ pub const PingCache = struct {
var prng = DefaultPrng.init(0);
const ping = Ping.initRandom(prng.random(), keypair) catch return null;
var token_with_prefix = PING_PONG_HASH_PREFIX ++ ping.token;
const hash = Hash.generateSha256(token_with_prefix[0..]);
const hash = Hash.init(&token_with_prefix);
_ = self.pending_cache.put(hash, peer_and_addr);
_ = self.pings.put(peer_and_addr, now);
return ping;
Expand Down
2 changes: 1 addition & 1 deletion src/gossip/service.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1617,7 +1617,7 @@ pub const GossipService = struct {
const bytes = bincode.writeToSlice(&buf, gossip_value_ptr.*, bincode.Params.standard) catch {
continue;
};
const value_hash = Hash.generateSha256(bytes);
const value_hash = Hash.init(bytes);
try failed_pull_hashes.insert(value_hash, now);
gossip_value_ptr.deinit(self.gossip_data_allocator);
}
Expand Down
2 changes: 1 addition & 1 deletion src/gossip/table.zig
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ pub const GossipTable = struct {
pub fn insert(self: *Self, value: SignedGossipData, now: u64) !InsertResult {
var buf: [PACKET_DATA_SIZE]u8 = undefined;
const bytes = try bincode.writeToSlice(&buf, value, bincode.Params.standard);
const value_hash = Hash.generateSha256(bytes);
const value_hash = Hash.init(bytes);
const metadata = GossipMetadata{
.signature = value.signature,
.value_hash = value_hash,
Expand Down
1 change: 1 addition & 0 deletions src/ledger/database/hashmap.zig
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub fn SharedHashMapDB(comptime column_families: []const ColumnFamily) type {
transaction_lock: *RwLock,

const Self = @This();
pub const name: []const u8 = "SharedHashMapDB";

pub fn open(
allocator: Allocator,
Expand Down
7 changes: 4 additions & 3 deletions src/ledger/database/interface.zig
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub fn Database(comptime Impl: type) type {
impl: Impl,

const Self = @This();
pub const name: []const u8 = Impl.name;

pub fn open(
allocator: Allocator,
Expand Down Expand Up @@ -309,11 +310,11 @@ pub const BytesRef = struct {

/// Test cases that can be applied to any implementation of Database
pub fn testDatabase(comptime Impl: fn ([]const ColumnFamily) type) type {
assertIsDatabase(Impl(&.{}));
const T = Impl(&.{});
assertIsDatabase(T);

@setEvalBranchQuota(10_000);
const impl_id = sig.core.Hash.generateSha256(@typeName(Impl(&.{}))).base58String();
const test_dir = sig.TEST_STATE_DIR ++ "ledger/database/" ++ impl_id.buffer ++ "/";
const test_dir = sig.TEST_STATE_DIR ++ "ledger/database/" ++ T.name ++ "/";

const Value1 = struct { hello: u16 };
const Value2 = struct { world: u16 };
Expand Down
2 changes: 1 addition & 1 deletion src/ledger/database/rocksdb.zig
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ pub fn RocksDB(comptime column_families: []const ColumnFamily) type {
path: [:0]const u8,

const Self = @This();

const OpenError = Error || std.posix.MakeDirError || std.fs.Dir.StatFileError;
pub const name: []const u8 = "RocksDB";

pub fn open(
allocator: Allocator,
Expand Down
Loading