Skip to content

Commit 54d076d

Browse files
Ubuntuyewman
authored andcommitted
refactor(core): consolidate Cluster and ClusterType into single enum
- Merge sig.core.Cluster into ClusterType in genesis_config.zig - Move entrypoints and RPC URLs to ClusterType methods - Rename localnet to development to match Agave naming - Lift cluster config from gossip to top-level Cmd config - Fix duplicate rpc_client.deinit() call in cmd.zig
1 parent 8825886 commit 54d076d

File tree

9 files changed

+85
-112
lines changed

9 files changed

+85
-112
lines changed

src/accountsdb/db.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3305,7 +3305,7 @@ pub fn indexAndValidateAccountFile(
33053305
}
33063306

33073307
pub fn getAccountPerFileEstimateFromCluster(
3308-
cluster: sig.core.Cluster,
3308+
cluster: sig.core.ClusterType,
33093309
) error{NotImplementedYet}!u64 {
33103310
return switch (cluster) {
33113311
.testnet => 500,
@@ -4178,7 +4178,7 @@ pub const BenchmarkAccountsDBSnapshotLoad = struct {
41784178
use_disk: bool,
41794179
n_threads: u32,
41804180
name: []const u8,
4181-
cluster: sig.core.Cluster,
4181+
cluster: sig.core.ClusterType,
41824182
};
41834183

41844184
pub const inputs = [_]BenchInputs{.{

src/cmd.zig

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ pub fn main() !void {
209209
);
210210
current_config.genesis_file_path = params.genesis_file_path;
211211
params.accountsdb_base.apply(&current_config);
212-
current_config.gossip.cluster = params.gossip_cluster;
212+
current_config.cluster = params.gossip_cluster;
213213
params.geyser.apply(&current_config);
214214
current_config.geyser.pipe_path = try current_config.derivePathFromValidatorDir(
215215
gpa,
@@ -556,7 +556,7 @@ const Cmd = struct {
556556
cfg.gossip.host = args.host;
557557
cfg.gossip.port = args.port;
558558
cfg.gossip.entrypoints = args.entrypoints;
559-
cfg.gossip.cluster = args.network;
559+
cfg.cluster = args.network;
560560
}
561561
};
562562
const GossipArgumentsNode = struct {
@@ -1335,19 +1335,8 @@ fn ensureGenesis(
13351335
return try allocator.dupe(u8, provided_path);
13361336
}
13371337

1338-
// If genesis already exists in validator dir, use it
1339-
const existing_path = try std.fs.path.join(
1340-
allocator,
1341-
&.{ cfg.validator_dir, "genesis.bin" },
1342-
);
1343-
errdefer allocator.free(existing_path);
1344-
if (!std.meta.isError(std.fs.cwd().access(existing_path, .{}))) {
1345-
logger.info().logf("Using existing genesis file: {s}", .{existing_path});
1346-
return existing_path;
1347-
}
1348-
13491338
// Determine cluster for genesis
1350-
const cluster = try cfg.gossip.getCluster() orelse {
1339+
const cluster = try cfg.getCluster() orelse {
13511340
logger.err().log(
13521341
\\No genesis file path provided and no cluster specified.
13531342
\\Use --genesis-file-path or --cluster"
@@ -1357,12 +1346,7 @@ fn ensureGenesis(
13571346

13581347
// Otherwise, download genesis from network
13591348
logger.info().logf("Downloading genesis from {s} cluster...", .{@tagName(cluster)});
1360-
const cluster_url = switch (cluster) {
1361-
.mainnet => "https://api.mainnet-beta.solana.com",
1362-
.testnet => "https://api.testnet.solana.com",
1363-
.devnet => "https://api.devnet.solana.com",
1364-
.localnet => unreachable,
1365-
};
1349+
const cluster_url = cluster.getRpcUrl();
13661350
const genesis_path = downloadAndExtractGenesis(
13671351
allocator,
13681352
cluster_url,
@@ -2118,18 +2102,12 @@ fn printLeaderSchedule(allocator: std.mem.Allocator, cfg: config.Cmd) !void {
21182102

21192103
const leader_schedule //
21202104
= try getLeaderScheduleFromCli(allocator, cfg) orelse b: {
2121-
const cluster = try cfg.gossip.getCluster() orelse
2105+
const cluster_type = try cfg.getCluster() orelse
21222106
return error.ClusterNotProvided;
21232107

2124-
const cluster_type: ClusterType = switch (cluster) {
2125-
.mainnet => .MainnetBeta,
2126-
.devnet => .Devnet,
2127-
.testnet => .Testnet,
2128-
.localnet => .LocalHost,
2129-
};
2130-
21312108
var rpc_client = try sig.rpc.Client.init(allocator, cluster_type, .{});
21322109
defer rpc_client.deinit();
2110+
defer rpc_client.deinit();
21332111

21342112
const slot = blk: {
21352113
const response = try rpc_client.getSlot(.{});
@@ -2201,12 +2179,7 @@ fn testTransactionSenderService(
22012179
}
22022180

22032181
// define cluster of where to land transactions
2204-
const rpc_cluster: ClusterType = if (try cfg.gossip.getCluster()) |n| switch (n) {
2205-
.mainnet => .MainnetBeta,
2206-
.devnet => .Devnet,
2207-
.testnet => .Testnet,
2208-
.localnet => .LocalHost,
2209-
} else {
2182+
const rpc_cluster: ClusterType = try cfg.getCluster() orelse {
22102183
@panic("cluster option (-c) not provided");
22112184
};
22122185
app_base.logger.warn().logf(
@@ -2455,7 +2428,7 @@ const AppBase = struct {
24552428
const my_keypair = try sig.identity.getOrInit(allocator, .from(logger));
24562429
const my_pubkey = Pubkey.fromPublicKey(&my_keypair.public_key);
24572430

2458-
const entrypoints = try cfg.gossip.getEntrypointAddrs(allocator);
2431+
const entrypoints = try cfg.gossip.getEntrypointAddrs(try cfg.getCluster(), allocator);
24592432

24602433
const echo_data = try getShredAndIPFromEchoServer(.from(logger), entrypoints);
24612434

src/config.zig

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub const Cmd = struct {
1919
max_shreds: u64 = 5_000_000,
2020
leader_schedule_path: ?[]const u8 = null,
2121
genesis_file_path: ?[]const u8 = null,
22+
cluster: ?[]const u8 = null,
2223
// general config
2324
log_filters: sig.trace.Filters = .debug,
2425
log_file: ?[]const u8 = null,
@@ -32,20 +33,29 @@ pub const Cmd = struct {
3233
vote_account: ?[]const u8 = null,
3334
stop_at_slot: ?sig.core.Slot = null,
3435

35-
pub fn genesisFilePath(self: Cmd) error{UnknownCluster}!?[]const u8 {
36+
pub fn getCluster(self: Cmd) error{UnknownCluster}!?sig.core.ClusterType {
37+
return if (self.cluster) |cluster_str|
38+
std.meta.stringToEnum(sig.core.ClusterType, cluster_str) orelse error.UnknownCluster
39+
else
40+
null;
41+
}
42+
43+
pub fn genesisFilePath(self: Cmd) !?[]const u8 {
3644
if (self.genesis_file_path) |provided_path|
3745
return provided_path;
3846

39-
const local_path = if (try self.gossip.getCluster()) |n| switch (n) {
47+
const local_path = if (try self.getCluster()) |cluster| switch (cluster) {
4048
.mainnet => "data/genesis-files/mainnet_genesis.bin",
4149
.devnet => "data/genesis-files/devnet_genesis.bin",
4250
.testnet => "data/genesis-files/testnet_genesis.bin",
43-
.localnet => return error.MustProvideGenesisFileForLocalHost,
51+
.development => return null,
4452
} else return null;
4553

4654
std.fs.cwd().access(local_path, .{ .read = true }) catch {
4755
return null;
4856
};
57+
58+
return local_path;
4959
}
5060

5161
/// Derives a path relative to validator_dir if the param equals the default value.
@@ -140,7 +150,6 @@ pub const Gossip = struct {
140150
host: ?[]const u8 = null,
141151
port: u16 = 8001,
142152
entrypoints: []const []const u8 = &.{},
143-
cluster: ?[]const u8 = null,
144153
spy_node: bool = false,
145154
dump: bool = false,
146155
trusted_validators: []const []const u8 = &.{},
@@ -163,30 +172,23 @@ pub const Gossip = struct {
163172
};
164173
}
165174

166-
pub fn getCluster(self: Gossip) error{UnknownCluster}!?sig.core.Cluster {
167-
return if (self.cluster) |cluster_str|
168-
std.meta.stringToEnum(sig.core.Cluster, cluster_str) orelse
169-
error.UnknownCluster
170-
else
171-
null;
172-
}
173-
174175
pub fn getEntrypointAddrs(
175176
self: Gossip,
177+
cluster: ?sig.core.ClusterType,
176178
allocator: std.mem.Allocator,
177179
) ![]sig.net.SocketAddr {
178180
var entrypoint_set = std.AutoArrayHashMap(sig.net.SocketAddr, void).init(allocator);
179181
defer entrypoint_set.deinit();
180182

181-
// add cluster entrypoints
182-
if (try self.getCluster()) |cluster| {
183-
for (sig.gossip.getClusterEntrypoints(cluster)) |entrypoint| {
183+
// add cluster entrypoints (only for public clusters)
184+
if (cluster) |c| {
185+
for (c.getEntrypoints()) |entrypoint| {
184186
const socket_addr = try resolveSocketAddr(allocator, entrypoint);
185187
try entrypoint_set.put(socket_addr, {});
186188
}
187189
}
188190

189-
// add config entrypoints
191+
// add user-provided entrypoints
190192
for (self.entrypoints) |entrypoint| {
191193
const socket_addr = sig.net.SocketAddr.parse(entrypoint) catch brk: {
192194
break :brk try resolveSocketAddr(allocator, entrypoint);

src/core/genesis_config.zig

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -250,17 +250,50 @@ pub const Inflation = struct {
250250
}
251251
};
252252

253-
/// Analogous to [ClusterType](https://github.com/anza-xyz/agave/blob/cadba689cb44db93e9c625770cafd2fc0ae89e33/sdk/src/genesis_config.rs#L46)
253+
/// Analogous to [ClusterType](https://github.com/anza-xyz/solana-sdk/blob/a467058aabc453c7d749a4993c56df293d1d75c3/cluster-type/src/lib.rs#L19)
254254
/// Explicit numbers are added to ensure we don't mess up the order of the fields and break bincode reading.
255-
pub const ClusterType = union(enum(u8)) {
256-
Testnet = 0,
257-
MainnetBeta = 1,
258-
Devnet = 2,
259-
Development = 3,
260-
LocalHost,
261-
Custom: struct {
262-
url: []const u8,
263-
},
255+
pub const ClusterType = enum(u8) {
256+
testnet = 0,
257+
mainnet = 1,
258+
devnet = 2,
259+
development = 3,
260+
261+
/// Returns entrypoints for public clusters, null for development.
262+
/// For development, the caller must provide entrypoints manually.
263+
pub fn getEntrypoints(self: ClusterType) []const []const u8 {
264+
return switch (self) {
265+
.mainnet => &.{
266+
"entrypoint.mainnet-beta.solana.com:8001",
267+
"entrypoint2.mainnet-beta.solana.com:8001",
268+
"entrypoint3.mainnet-beta.solana.com:8001",
269+
"entrypoint4.mainnet-beta.solana.com:8001",
270+
"entrypoint5.mainnet-beta.solana.com:8001",
271+
},
272+
.testnet => &.{
273+
"entrypoint.testnet.solana.com:8001",
274+
"entrypoint2.testnet.solana.com:8001",
275+
"entrypoint3.testnet.solana.com:8001",
276+
},
277+
.devnet => &.{
278+
"entrypoint.devnet.solana.com:8001",
279+
"entrypoint2.devnet.solana.com:8001",
280+
"entrypoint3.devnet.solana.com:8001",
281+
"entrypoint4.devnet.solana.com:8001",
282+
"entrypoint5.devnet.solana.com:8001",
283+
},
284+
.development => @panic("TODO: should development require custom entrypoints?"),
285+
};
286+
}
287+
288+
/// Returns the RPC URL for this cluster.
289+
pub fn getRpcUrl(self: ClusterType) []const u8 {
290+
return switch (self) {
291+
.mainnet => "https://api.mainnet-beta.solana.com",
292+
.testnet => "https://api.testnet.solana.com",
293+
.devnet => "https://api.devnet.solana.com",
294+
.development => @panic("TODO: should development require custom rpc urls?"),
295+
};
296+
}
264297
};
265298

266299
/// Analogous to [GenesisConfig](https://github.com/anza-xyz/agave/blob/cadba689cb44db93e9c625770cafd2fc0ae89e33/sdk/src/genesis_config.rs#L93)
@@ -312,7 +345,7 @@ pub const GenesisConfig = struct {
312345
.fee_rate_governor = .DEFAULT,
313346
.rent = .INIT,
314347
.epoch_schedule = .INIT,
315-
.cluster_type = .Development,
348+
.cluster_type = .development,
316349
};
317350
}
318351

@@ -352,7 +385,7 @@ test "genesis_config deserialize development config" {
352385
const config = try GenesisConfig.init(allocator, genesis_path);
353386
defer config.deinit(allocator);
354387

355-
try std.testing.expectEqual(ClusterType.Development, config.cluster_type);
388+
try std.testing.expectEqual(ClusterType.development, config.cluster_type);
356389
}
357390

358391
test "genesis_config deserialize testnet config" {
@@ -362,7 +395,7 @@ test "genesis_config deserialize testnet config" {
362395
const config = try GenesisConfig.init(allocator, genesis_path);
363396
defer config.deinit(allocator);
364397

365-
try std.testing.expectEqual(ClusterType.Testnet, config.cluster_type);
398+
try std.testing.expectEqual(ClusterType.testnet, config.cluster_type);
366399
}
367400

368401
test "genesis_config deserialize devnet config" {
@@ -372,7 +405,7 @@ test "genesis_config deserialize devnet config" {
372405
const config = try GenesisConfig.init(allocator, genesis_path);
373406
defer config.deinit(allocator);
374407

375-
try std.testing.expectEqual(ClusterType.Devnet, config.cluster_type);
408+
try std.testing.expectEqual(ClusterType.devnet, config.cluster_type);
376409
}
377410

378411
test "genesis_config deserialize mainnet config" {
@@ -382,7 +415,7 @@ test "genesis_config deserialize mainnet config" {
382415
const config = try GenesisConfig.init(allocator, genesis_path);
383416
defer config.deinit(allocator);
384417

385-
try std.testing.expectEqual(ClusterType.MainnetBeta, config.cluster_type);
418+
try std.testing.expectEqual(ClusterType.mainnet, config.cluster_type);
386419
}
387420

388421
test "inflation" {

src/core/lib.zig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,3 @@ pub const Transaction = transaction.Transaction;
7777
pub const Epoch = time.Epoch;
7878
pub const Slot = time.Slot;
7979
pub const UnixTimestamp = time.UnixTimestamp;
80-
81-
pub const Cluster = enum { mainnet, testnet, devnet, localnet };

src/gossip/helpers.zig

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,28 @@ const sig = @import("../sig.zig");
33

44
const Pubkey = sig.core.Pubkey;
55
const ContactInfo = sig.gossip.ContactInfo;
6-
const Cluster = sig.core.Cluster;
6+
const ClusterType = sig.core.ClusterType;
77
const GossipService = sig.gossip.GossipService;
88
const SocketAddr = sig.net.SocketAddr;
99
const IpAddr = sig.net.IpAddr;
1010

1111
const resolveSocketAddr = sig.net.net.resolveSocketAddr;
1212
const getShredAndIPFromEchoServer = sig.net.echo.getShredAndIPFromEchoServer;
1313
const getWallclockMs = sig.time.getWallclockMs;
14-
const getClusterEntrypoints = sig.gossip.service.getClusterEntrypoints;
1514

1615
/// inits a gossip client with the minimum required configuration
1716
/// relying on the cluster to provide the entrypoints
1817
pub fn initGossipFromCluster(
1918
allocator: std.mem.Allocator,
2019
logger: sig.trace.Logger("gossip"),
21-
cluster: Cluster,
20+
cluster: ClusterType,
2221
my_port: u16,
2322
) !*GossipService {
2423
// gather entrypoints
2524
var entrypoints = std.ArrayList(SocketAddr).init(allocator);
2625
defer entrypoints.deinit();
2726

28-
const entrypoints_strs = getClusterEntrypoints(cluster);
27+
const entrypoints_strs = cluster.getEntrypoints();
2928
for (entrypoints_strs) |entrypoint_str| {
3029
const socket_addr = try resolveSocketAddr(allocator, entrypoint_str);
3130
try entrypoints.append(socket_addr);

src/gossip/lib.zig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,3 @@ pub const Ping = ping_pong.Ping;
2424
pub const Pong = ping_pong.Pong;
2525
pub const SocketTag = data.SocketTag;
2626
pub const PruneData = prune.PruneData;
27-
28-
pub const getClusterEntrypoints = service.getClusterEntrypoints;

src/gossip/service.zig

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,34 +2256,6 @@ pub fn chunkValuesIntoPacketIndexes(
22562256
return packet_indexs;
22572257
}
22582258

2259-
pub fn getClusterEntrypoints(cluster: sig.core.Cluster) []const []const u8 {
2260-
return switch (cluster) {
2261-
.mainnet => &.{
2262-
"entrypoint.mainnet-beta.solana.com:8001",
2263-
"entrypoint2.mainnet-beta.solana.com:8001",
2264-
"entrypoint3.mainnet-beta.solana.com:8001",
2265-
"entrypoint4.mainnet-beta.solana.com:8001",
2266-
"entrypoint5.mainnet-beta.solana.com:8001",
2267-
},
2268-
.testnet => &.{
2269-
"entrypoint.testnet.solana.com:8001",
2270-
"entrypoint2.testnet.solana.com:8001",
2271-
"entrypoint3.testnet.solana.com:8001",
2272-
},
2273-
.devnet => &.{
2274-
"entrypoint.devnet.solana.com:8001",
2275-
"entrypoint2.devnet.solana.com:8001",
2276-
"entrypoint3.devnet.solana.com:8001",
2277-
"entrypoint4.devnet.solana.com:8001",
2278-
"entrypoint5.devnet.solana.com:8001",
2279-
},
2280-
.localnet => &.{
2281-
"127.0.0.1:1024", // agave test-validator default
2282-
"127.0.0.1:8001", // sig validator default
2283-
},
2284-
};
2285-
}
2286-
22872259
test "general coverage" {
22882260
const allocator = std.testing.allocator;
22892261

0 commit comments

Comments
 (0)