forked from zig-bitcoin/btczee
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.zig
188 lines (161 loc) · 5.32 KB
/
main.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
//
// ___. __
// \_ |___/ |_ ____ ________ ____ ____
// | __ \ __\/ ___\\___ // __ \_/ __ \
// | \_\ \ | \ \___ / /\ ___/\ ___/
// |___ /__| \___ >_____ \\___ >\___ >
// \/ \/ \/ \/ \/
//
// Bitcoin Implementation in Zig
// =============================
//==== Imports ====//
const std = @import("std");
const Config = @import("config/config.zig").Config;
const Mempool = @import("core/mempool.zig").Mempool;
const Storage = @import("storage/storage.zig").Storage;
const P2P = @import("network/p2p.zig").P2P;
const RPC = @import("network/rpc.zig").RPC;
const Node = @import("node/node.zig").Node;
const ArgParser = @import("util/cmd/ArgParser.zig");
// We set this so that std.log knows not to log .debug level messages
// which libraries we import will use
pub const std_options: std.Options = .{
// Set the log level to info
.log_level = .info,
};
//==== Main Entry Point ====//
pub fn main() !void {
// Initialize the allocator
var gpa_state = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa_state.allocator();
defer _ = gpa_state.deinit();
// Parse command-line arguments
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
// Set up buffered stdout
var stdout_buffered = std.io.bufferedWriter(std.io.getStdOut().writer());
const stdout = stdout_buffered.writer();
// Run the main program logic
try mainFull(.{
.allocator = allocator,
.args = args[1..],
.stdout = stdout.any(),
});
// Flush the buffered stdout
return stdout_buffered.flush();
}
//==== Main Program Logic ====//
pub fn mainFull(options: struct {
allocator: std.mem.Allocator,
args: []const []const u8,
stdout: std.io.AnyWriter,
}) !void {
var program = Program{
.allocator = options.allocator,
.args = .{ .args = options.args },
.stdout = options.stdout,
};
return program.mainCommand();
}
//==== Program Structure ====//
const Program = @This();
allocator: std.mem.Allocator,
args: ArgParser,
stdout: std.io.AnyWriter,
//==== Usage Messages ====//
const main_usage =
\\Usage: btczee [command] [args]
\\
\\Commands:
\\ node <subcommand>
\\ wallet <subcommand>
\\ help Display this message
\\
;
const node_sub_usage =
\\Usage:
\\ btczee node [command] [args]
\\ btczee node [options] [ids]...
\\
\\Commands:
\\ help Display this message
\\
;
const wallet_sub_usage =
\\Usage:
\\ btczee wallet [command] [args]
\\
\\Commands:
\\ create Create a new wallet
\\ load Load an existing wallet
\\ help Display this message
\\
;
//==== Command Handlers ====//
// Main Command Handler
pub fn mainCommand(program: *Program) !void {
while (program.args.next()) {
if (program.args.flag(&.{"node"}))
return program.nodeSubCommand();
if (program.args.flag(&.{"wallet"}))
return program.walletSubCommand();
if (program.args.flag(&.{ "-h", "--help", "help" }))
return program.stdout.writeAll(main_usage);
if (program.args.positional()) |_| {
try std.io.getStdErr().writeAll(main_usage);
return error.InvalidArgument;
}
}
try std.io.getStdErr().writeAll(main_usage);
return error.InvalidArgument;
}
// Node Subcommand Handler
fn nodeSubCommand(program: *Program) !void {
if (program.args.next()) {
if (program.args.flag(&.{ "-h", "--help", "help" }))
return program.stdout.writeAll(node_sub_usage);
}
return program.runNodeCommand();
}
// Wallet Subcommand Handler
fn walletSubCommand(program: *Program) !void {
if (program.args.next()) {
if (program.args.flag(&.{"create"}))
return program.walletCreateCommand();
if (program.args.flag(&.{"load"}))
return program.walletLoadCommand();
if (program.args.flag(&.{ "-h", "--help", "help" }))
return program.stdout.writeAll(wallet_sub_usage);
}
try std.io.getStdErr().writeAll(wallet_sub_usage);
return error.InvalidArgument;
}
//==== Command Implementations ====//
// Node Command Implementation
fn runNodeCommand(program: *Program) !void {
// Load configuration
var config = try Config.load(program.allocator, "bitcoin.conf.example");
defer config.deinit();
// Initialize components
var mempool = try Mempool.init(program.allocator, &config);
defer mempool.deinit();
var storage = try Storage.init(&config);
defer storage.deinit();
var p2p = try P2P.init(program.allocator, &config);
defer p2p.deinit();
var rpc = try RPC.init(program.allocator, &config, &mempool, &storage);
defer rpc.deinit();
var node = try Node.init(program.allocator, &mempool, &storage, &p2p, &rpc);
defer node.deinit();
// Start the node
try node.start();
}
// Wallet Create Command Implementation
fn walletCreateCommand(program: *Program) !void {
return program.stdout.writeAll("Wallet creation not implemented yet\n");
}
// Wallet Load Command Implementation
fn walletLoadCommand(program: *Program) !void {
return program.stdout.writeAll("Wallet loading not implemented yet\n");
}
//==== End of File ====//