Skip to content

Commit bd1e0fe

Browse files
committed
*: update, add genesis.rs
Signed-off-by: Gyuho Lee <[email protected]>
1 parent 082f7e8 commit bd1e0fe

File tree

9 files changed

+344
-16
lines changed

9 files changed

+344
-16
lines changed

Cargo.toml

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,14 @@ clap = { version = "3.1.8", features = ["cargo", "derive"] }
1919
env_logger = "0.9.0"
2020
log = "0.4.16"
2121
prost = "0.10.0"
22-
tokio = { version = "1.17.0", features = ["rt-multi-thread"] }
22+
prost-types = "0.10.0"
23+
serde = { version = "1.0.136", features = ["derive"] }
24+
serde_json = "1.0.79"
25+
serde_yaml = "0.8.23"
26+
tokio = { version = "1.17.0", features = ["fs", "rt-multi-thread"] }
27+
tokio-stream = { version = "0.1.8", features = ["net"] }
2328
tonic = "0.7.1"
29+
tonic-health = "0.6.0"
2430

2531
[build-dependencies]
2632
# ref. https://github.com/hyperium/tonic/tree/master/tonic-build

build.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,6 @@ fn main() {
33
tonic_build::configure()
44
.build_server(true)
55
.build_client(false)
6-
.compile(
7-
&[
8-
// e.g.,
9-
// git submodule add https://github.com/prometheus/client_model
10-
// git submodule update --remote
11-
"client_model/io/prometheus/client/metrics.proto",
12-
"proto/vm.proto",
13-
],
14-
&["client_model", "proto"],
15-
)
6+
.compile(&["proto/metrics.proto", "proto/vm.proto"], &["proto"])
167
.unwrap();
178
}

client_model

Submodule client_model deleted from 6dc836e

proto/metrics.proto

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// copied from https://github.com/prometheus/client_model/tree/master/io/prometheus/client
2+
3+
// Copyright 2013 Prometheus Team
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
syntax = "proto2";
17+
18+
package metrics;
19+
option java_package = "io.prometheus.client";
20+
option go_package = "github.com/prometheus/client_model/go;io_prometheus_client";
21+
22+
import "google/protobuf/timestamp.proto";
23+
24+
message LabelPair {
25+
optional string name = 1;
26+
optional string value = 2;
27+
}
28+
29+
enum MetricType {
30+
COUNTER = 0;
31+
GAUGE = 1;
32+
SUMMARY = 2;
33+
UNTYPED = 3;
34+
HISTOGRAM = 4;
35+
}
36+
37+
message Gauge {
38+
optional double value = 1;
39+
}
40+
41+
message Counter {
42+
optional double value = 1;
43+
optional Exemplar exemplar = 2;
44+
}
45+
46+
message Quantile {
47+
optional double quantile = 1;
48+
optional double value = 2;
49+
}
50+
51+
message Summary {
52+
optional uint64 sample_count = 1;
53+
optional double sample_sum = 2;
54+
repeated Quantile quantile = 3;
55+
}
56+
57+
message Untyped {
58+
optional double value = 1;
59+
}
60+
61+
message Histogram {
62+
optional uint64 sample_count = 1;
63+
optional double sample_sum = 2;
64+
repeated Bucket bucket = 3; // Ordered in increasing order of upper_bound, +Inf bucket is optional.
65+
}
66+
67+
message Bucket {
68+
optional uint64 cumulative_count = 1; // Cumulative in increasing order.
69+
optional double upper_bound = 2; // Inclusive.
70+
optional Exemplar exemplar = 3;
71+
}
72+
73+
message Exemplar {
74+
repeated LabelPair label = 1;
75+
optional double value = 2;
76+
optional google.protobuf.Timestamp timestamp = 3; // OpenMetrics-style.
77+
}
78+
79+
message Metric {
80+
repeated LabelPair label = 1;
81+
optional Gauge gauge = 2;
82+
optional Counter counter = 3;
83+
optional Summary summary = 4;
84+
optional Untyped untyped = 5;
85+
optional Histogram histogram = 7;
86+
optional int64 timestamp_ms = 6;
87+
}
88+
89+
message MetricFamily {
90+
optional string name = 1;
91+
optional string help = 2;
92+
optional MetricType type = 3;
93+
repeated Metric metric = 4;
94+
}

proto/vm.proto

+8-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@ syntax = "proto3";
55
package vm;
66

77
import "google/protobuf/empty.proto";
8-
import "io/prometheus/client/metrics.proto";
98

10-
option go_package = "github.com/ava-labs/avalanchego/proto/pb/vm";
9+
// THIS DOES NOT WORK:
10+
// git submodule add https://github.com/prometheus/client_model
11+
// git submodule update --remote
12+
//
13+
// original path converts to "super::io::prometheus::client::MetricFamily"
14+
// which is invalid in Rust
15+
import "metrics.proto";
1116

1217
service VM {
1318
rpc Initialize(InitializeRequest) returns (InitializeResponse);
@@ -248,5 +253,5 @@ message GetBlockIDAtHeightResponse {
248253
}
249254

250255
message GatherResponse {
251-
repeated io.prometheus.client.MetricFamily metric_families = 1;
256+
repeated metrics.MetricFamily metric_families = 1;
252257
}

src/bin/mini-kvvm-rs/main.rs

+58
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
use std::io;
2+
13
use clap::{crate_version, Arg, Command};
24
use log::info;
35

6+
use mini_kvvm_rs::genesis;
7+
48
pub const APP_NAME: &str = "mini-kvvm-rs";
59

610
fn main() {
@@ -19,6 +23,7 @@ fn main() {
1923
.allow_invalid_utf8(false)
2024
.default_value("info"),
2125
)
26+
.subcommands(vec![command_genesis()])
2227
.get_matches();
2328

2429
let log_level = matches.value_of("LOG_LEVEL").unwrap_or("info").to_string();
@@ -28,5 +33,58 @@ fn main() {
2833
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, log_level),
2934
);
3035

36+
if let Some(("genesis", sub_matches)) = matches.subcommand() {
37+
let author = sub_matches.value_of("AUTHOR").unwrap_or("");
38+
let msg = sub_matches.value_of("WELCOME_MESSAGE").unwrap_or("");
39+
let p = sub_matches.value_of("GENESIS_FILE_PATH").unwrap_or("");
40+
execute_genesis(author, msg, p).unwrap();
41+
return;
42+
}
43+
3144
info!("starting mini-kvvm-rs");
45+
// TODO
46+
}
47+
48+
pub fn command_genesis() -> Command<'static> {
49+
Command::new("genesis")
50+
.about("Generates the genesis file")
51+
.arg(
52+
Arg::new("AUTHOR")
53+
.long("author")
54+
.short('a')
55+
.help("author of the genesis")
56+
.required(true)
57+
.takes_value(true)
58+
.allow_invalid_utf8(false)
59+
.default_value("subnet creator"),
60+
)
61+
.arg(
62+
Arg::new("WELCOME_MESSAGE")
63+
.long("welcome-message")
64+
.short('m')
65+
.help("message field in genesis")
66+
.required(true)
67+
.takes_value(true)
68+
.allow_invalid_utf8(false)
69+
.default_value("hi"),
70+
)
71+
.arg(
72+
Arg::new("GENESIS_FILE_PATH")
73+
.long("genesis-file-path")
74+
.short('p')
75+
.help("file path to save genesis file")
76+
.required(true)
77+
.takes_value(true)
78+
.allow_invalid_utf8(false),
79+
)
80+
}
81+
82+
pub fn execute_genesis(author: &str, msg: &str, p: &str) -> io::Result<()> {
83+
let g = genesis::Genesis {
84+
author: String::from(author),
85+
welcome_message: String::from(msg),
86+
};
87+
g.sync(p)?;
88+
89+
Ok(())
3290
}

src/genesis.rs

+73-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,75 @@
1+
use std::{
2+
fmt,
3+
fs::{self, File},
4+
io::{self, Error, ErrorKind, Write},
5+
path::Path,
6+
};
7+
8+
use log::info;
9+
use serde::{Deserialize, Serialize};
10+
11+
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
112
pub struct Genesis {
2-
pub data: String,
13+
pub author: String,
14+
pub welcome_message: String,
15+
}
16+
17+
impl Default for Genesis {
18+
fn default() -> Self {
19+
Self::default()
20+
}
21+
}
22+
23+
impl Genesis {
24+
pub fn default() -> Self {
25+
Self {
26+
author: String::from("subnet creator"),
27+
welcome_message: String::from("Hello from Rust VM!"),
28+
}
29+
}
30+
31+
pub fn from_json<S>(d: S) -> io::Result<Self>
32+
where
33+
S: AsRef<[u8]>,
34+
{
35+
let resp: Self = match serde_json::from_slice(d.as_ref()) {
36+
Ok(p) => p,
37+
Err(e) => {
38+
return Err(Error::new(
39+
ErrorKind::Other,
40+
format!("failed to decode {}", e),
41+
));
42+
}
43+
};
44+
Ok(resp)
45+
}
46+
47+
pub fn sync(&self, file_path: &str) -> io::Result<()> {
48+
info!("syncing genesis to '{}'", file_path);
49+
let path = Path::new(file_path);
50+
let parent_dir = path.parent().unwrap();
51+
fs::create_dir_all(parent_dir)?;
52+
53+
let ret = serde_json::to_vec(&self);
54+
let d = match ret {
55+
Ok(d) => d,
56+
Err(e) => {
57+
return Err(Error::new(
58+
ErrorKind::Other,
59+
format!("failed to serialize genesis info to YAML {}", e),
60+
));
61+
}
62+
};
63+
let mut f = File::create(&file_path)?;
64+
f.write_all(&d)?;
65+
66+
Ok(())
67+
}
68+
}
69+
70+
impl fmt::Display for Genesis {
71+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72+
let s = serde_yaml::to_string(&self).unwrap();
73+
write!(f, "{}", s)
74+
}
375
}

src/lib.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
11
pub mod genesis;
2+
pub mod plugin;
3+
4+
pub mod vm {
5+
tonic::include_proto!("vm");
6+
}
7+
8+
pub mod metrics {
9+
tonic::include_proto!("metrics");
10+
}

0 commit comments

Comments
 (0)