From 8bb9960147466466692d1b4f7a8c9bb249723fa2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 12 Dec 2019 09:16:05 -0800 Subject: [PATCH] Use an initial height of 0 in default chain state (fixes #369) Now that `tendermint-rs` v0.11 is out, we can use a default chain height of zero for chains which are in the initial state. This bit us yesterday on the `cosmoshub-3` upgrade. --- src/chain/state.rs | 47 +++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/chain/state.rs b/src/chain/state.rs index f5c0677..116d58a 100644 --- a/src/chain/state.rs +++ b/src/chain/state.rs @@ -28,18 +28,13 @@ pub struct State { impl State { /// Load the state from the given path - pub fn load_state

(path: P) -> Result + pub fn load_state

(path: P) -> Result where P: AsRef, { - let mut lst = State { - consensus_state: consensus::State::default(), - state_file_path: path.as_ref().to_owned(), - }; - match fs::read_to_string(path.as_ref()) { - Ok(contents) => { - lst.consensus_state = serde_json::from_str(&contents).map_err(|e| { + Ok(state_json) => { + let consensus_state = serde_json::from_str(&state_json).map_err(|e| { err!( ParseError, "error parsing {}: {}", @@ -47,16 +42,16 @@ impl State { e ) })?; - Ok(lst) + + Ok(Self { + consensus_state, + state_file_path: path.as_ref().to_owned(), + }) } - Err(e) => { - if e.kind() == io::ErrorKind::NotFound { - lst.sync_to_disk()?; - Ok(lst) - } else { - Err(e.into()) - } + Err(e) if e.kind() == io::ErrorKind::NotFound => { + Self::write_initial_state(path.as_ref()) } + Err(e) => Err(Error::from(e)), } } @@ -163,8 +158,26 @@ impl State { Ok(()) } + /// Write the initial state to the given path on disk + fn write_initial_state(path: &Path) -> Result { + let mut consensus_state = consensus::State::default(); + + // TODO(tarcieri): correct upstream `tendermint-rs` default height to 0 + // Set the initial block height to 0 to indicate we've never signed a block + consensus_state.height = 0.into(); + + let initial_state = Self { + consensus_state, + state_file_path: path.to_owned(), + }; + + initial_state.sync_to_disk()?; + + Ok(initial_state) + } + /// Sync the current state to disk - fn sync_to_disk(&mut self) -> std::io::Result<()> { + fn sync_to_disk(&self) -> io::Result<()> { let json = serde_json::to_string(&self.consensus_state)?; AtomicFile::new(&self.state_file_path, OverwriteBehavior::AllowOverwrite)