Add special genesis state API endpoint

This commit is contained in:
Paul Hauner 2019-09-02 15:07:48 +10:00
parent 11a1505784
commit bfbe776712
No known key found for this signature in database
GPG Key ID: 5E2CFF9B75FA63DF
4 changed files with 49 additions and 3 deletions

View File

@ -101,6 +101,21 @@ pub fn get_block_root<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiR
Ok(success_response(Body::from(json))) Ok(success_response(Body::from(json)))
} }
/// HTTP handler to return a `BeaconState` at a given `root` or `slot`.
///
/// Will not return a state if the request slot is in the future. Will return states higher than
/// the current head by skipping slots.
pub fn get_genesis_state<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
let beacon_chain = req
.extensions()
.get::<Arc<BeaconChain<T>>>()
.ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".to_string()))?;
let (_root, state) = state_at_slot(&beacon_chain, Slot::new(0))?;
ResponseBuilder::new(&req).body(&state)
}
#[derive(Serialize, Encode)] #[derive(Serialize, Encode)]
#[serde(bound = "T: EthSpec")] #[serde(bound = "T: EthSpec")]
pub struct StateResponse<T: EthSpec> { pub struct StateResponse<T: EthSpec> {

View File

@ -147,6 +147,7 @@ pub fn start_server<T: BeaconChainTypes>(
beacon::get_latest_finalized_checkpoint::<T>(req) beacon::get_latest_finalized_checkpoint::<T>(req)
} }
(&Method::GET, "/beacon/state") => beacon::get_state::<T>(req), (&Method::GET, "/beacon/state") => beacon::get_state::<T>(req),
(&Method::GET, "/beacon/state/genesis") => beacon::get_genesis_state::<T>(req),
(&Method::GET, "/beacon/state_root") => beacon::get_state_root::<T>(req), (&Method::GET, "/beacon/state_root") => beacon::get_state_root::<T>(req),
//TODO: Add aggreggate/filtered state lookups here, e.g. /beacon/validators/balances //TODO: Add aggreggate/filtered state lookups here, e.g. /beacon/validators/balances

View File

@ -172,6 +172,31 @@ fn process_testnet_subcommand(
genesis_time, genesis_time,
}) })
} }
("file", Some(cli_args)) => {
let file = cli_args
.value_of("file")
.ok_or_else(|| "No filename specified")?
.parse::<PathBuf>()
.map_err(|e| format!("Unable to parse filename: {:?}", e))?;
let format = cli_args
.value_of("format")
.ok_or_else(|| "No file format specified")?;
let start_method = match format {
"yaml" => BeaconChainStartMethod::Yaml { file },
"ssz" => BeaconChainStartMethod::Ssz { file },
other => return Err(format!("Unknown genesis file format: {}", other)),
};
builder.set_beacon_chain_start_method(start_method)
}
(cmd, Some(_)) => {
return Err(format!(
"Invalid valid method specified: {}. See 'testnet --help'.",
cmd
))
}
_ => return Err("No testnet method specified. See 'testnet --help'.".into()), _ => return Err("No testnet method specified. See 'testnet --help'.".into()),
}; };

View File

@ -312,9 +312,14 @@ fn main() {
* *
* Start a new node, using a genesis state loaded from a YAML file * Start a new node, using a genesis state loaded from a YAML file
*/ */
.subcommand(SubCommand::with_name("yaml") .subcommand(SubCommand::with_name("file")
.about("Creates a new datadir where the genesis state is read from YAML. Will fail to parse \ .about("Creates a new datadir where the genesis state is read from YAML. May fail to parse \
a YAML state that was generated to a different spec than that specified by --spec.") a file that was generated to a different spec than that specified by --spec.")
.arg(Arg::with_name("format")
.value_name("FORMAT")
.required(true)
.possible_values(&["yaml", "ssz"])
.help("The encoding of the state in the file."))
.arg(Arg::with_name("file") .arg(Arg::with_name("file")
.value_name("YAML_FILE") .value_name("YAML_FILE")
.required(true) .required(true)