Set Graffiti via CLI (#1320)

## Issue Addressed

Closes #1319 

## Proposed Changes

This issue:
1. Allows users to edit their Graffiti via the cli option `--graffiti`. If the graffiti is too long, lighthouse will not start and throw an error message. Otherwise, it will set the Graffiti to be the one provided by the user, right-padded with 0s.
2. Create a new `Graffiti` type and unify the code around it. With this type, everything is enforced at compile-time, and the code can be (I think...) panic-free! :)

## Additional info

Currently, only `&str` are supported, as this is the returned type by `.arg("graffiti")`.
Since this is user-input, I tried being as careful as I could. This is also why I created the `Graffiti` type, to make sure I could check as much as possible at compile time.
This commit is contained in:
pscott
2020-07-14 08:05:02 +00:00
parent 00c89c51c8
commit e164371083
10 changed files with 68 additions and 22 deletions

View File

@@ -1,5 +1,11 @@
use clap::{App, Arg};
// Default text included in blocks.
// Must be 32-bytes or will not build.
//
// |-------must be this long------|
const DEFAULT_GRAFFITI: &str = "sigp/lighthouse-0.1.2-prerelease";
pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
App::new("beacon_node")
.visible_aliases(&["b", "bn", "beacon"])
@@ -227,4 +233,16 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
.long("purge-db")
.help("If present, the chain database will be deleted. Use with caution.")
)
/*
* Misc.
*/
.arg(
Arg::with_name("graffiti")
.long("graffiti")
.help("Specify your custom graffiti to be included in blocks.")
.value_name("GRAFFITI")
.default_value(DEFAULT_GRAFFITI)
.takes_value(true)
)
}

View File

@@ -10,7 +10,7 @@ use std::fs;
use std::net::{IpAddr, Ipv4Addr, ToSocketAddrs};
use std::net::{TcpListener, UdpSocket};
use std::path::PathBuf;
use types::{ChainSpec, EthSpec};
use types::{ChainSpec, EthSpec, GRAFFITI_BYTES_LEN};
pub const BEACON_NODE_DIR: &str = "beacon";
pub const NETWORK_DIR: &str = "network";
@@ -343,6 +343,22 @@ pub fn get_config<E: EthSpec>(
client_config.genesis = ClientGenesis::DepositContract;
}
if let Some(graffiti) = cli_args.value_of("graffiti") {
let graffiti_bytes = graffiti.as_bytes();
if graffiti_bytes.len() > GRAFFITI_BYTES_LEN {
return Err(format!(
"Your graffiti is too long! {} bytes maximum!",
GRAFFITI_BYTES_LEN
));
} else {
// `client_config.graffiti` is initialized by default to be all 0.
// We simply copy the bytes from `graffiti_bytes` in there.
//
// Panic-free because `graffiti_bytes.len()` <= `GRAFFITI_BYTES_LEN`.
client_config.graffiti[..graffiti_bytes.len()].copy_from_slice(graffiti_bytes);
}
}
Ok(client_config)
}