This repository has been archived by the owner on Jun 3, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a `chain::REGISTRY` (as a `lazy_static`) to tmkms, populated from the configuration file. Uses this registry when serializing keys to select the appropriate serialization format.
- Loading branch information
1 parent
fb2a825
commit ce31ad7
Showing
31 changed files
with
508 additions
and
229 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
use super::{Chain, Id}; | ||
use std::{collections::BTreeMap, sync::RwLockReadGuard}; | ||
|
||
/// Wrapper for a `RwLockReadGuard<'static, BTreeMap<Id, Chain>>`, allowing access to | ||
/// global information about particular Tendermint networks / "chains" | ||
pub struct Guard<'lock>(RwLockReadGuard<'lock, BTreeMap<Id, Chain>>); | ||
|
||
impl<'lock> From<RwLockReadGuard<'lock, BTreeMap<Id, Chain>>> for Guard<'lock> { | ||
fn from(guard: RwLockReadGuard<'lock, BTreeMap<Id, Chain>>) -> Guard<'lock> { | ||
Guard(guard) | ||
} | ||
} | ||
|
||
impl<'lock> Guard<'lock> { | ||
/// Get information about a particular chain ID (if registered) | ||
pub fn chain(&self, chain_id: Id) -> Option<&Chain> { | ||
self.0.get(&chain_id) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
//! Chain-specific key configuration | ||
use super::{Id, REGISTRY}; | ||
use tendermint::TendermintKey; | ||
|
||
/// Options for how keys for this chain are represented | ||
#[derive(Clone, Debug, Deserialize)] | ||
#[serde(tag = "type")] | ||
pub enum Format { | ||
/// Use the Bech32 serialization format with the given key prefixes | ||
#[serde(rename = "bech32")] | ||
Bech32 { | ||
/// Prefix to use for Account keys | ||
account_key_prefix: String, | ||
|
||
/// Prefix to use for Consensus keys | ||
consensus_key_prefix: String, | ||
}, | ||
|
||
/// Hex is a baseline representation | ||
#[serde(rename = "hex")] | ||
Hex, | ||
} | ||
|
||
impl Format { | ||
/// Serialize a `TendermintKey` according to chain-specific rules | ||
pub fn serialize(&self, public_key: TendermintKey) -> String { | ||
match self { | ||
Format::Bech32 { | ||
account_key_prefix, | ||
consensus_key_prefix, | ||
} => match public_key { | ||
TendermintKey::AccountKey(pk) => pk.to_bech32(account_key_prefix), | ||
TendermintKey::ConsensusKey(pk) => pk.to_bech32(consensus_key_prefix), | ||
}, | ||
Format::Hex => public_key.to_hex(), | ||
} | ||
} | ||
} | ||
|
||
/// Serialize a key according to chain-specific serialization rules | ||
pub fn serialize(chain_id: Id, public_key: TendermintKey) -> Option<String> { | ||
let registry = REGISTRY.get(); | ||
registry | ||
.chain(chain_id) | ||
.map(|chain| chain.key_format.serialize(public_key)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
//! Information about particular Tendermint blockchain networks | ||
mod guard; | ||
pub mod key; | ||
mod registry; | ||
|
||
pub use self::{guard::Guard, registry::REGISTRY}; | ||
use crate::config::chain::ChainConfig; | ||
pub use tendermint::chain::Id; | ||
|
||
/// Information about a particular Tendermint blockchain network | ||
pub struct Chain { | ||
/// ID of a particular chain | ||
pub id: Id, | ||
|
||
/// Key format configuration | ||
pub key_format: key::Format, | ||
} | ||
|
||
impl<'a> From<&ChainConfig> for Chain { | ||
fn from(config: &ChainConfig) -> Chain { | ||
Self { | ||
id: config.id, | ||
key_format: config.key_format.clone(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
//! Registry of information about known Tendermint blockchain networks | ||
use super::{Chain, Guard, Id}; | ||
use crate::error::{KmsError, KmsErrorKind::ConfigError}; | ||
use std::{collections::BTreeMap, sync::RwLock}; | ||
|
||
lazy_static! { | ||
pub static ref REGISTRY: Registry = Registry::default(); | ||
} | ||
|
||
/// Registry of blockchain networks known to the KMS | ||
// The `RwLock` is a bit of futureproofing as this data structure is for the | ||
// most part "immutable". New chains should be registered at boot time. | ||
// The only case in which this structure may change is in the event of | ||
// runtime configuration reloading, so the `RwLock` is included as | ||
// futureproofing for such a feature. | ||
// See: <https://github.com/tendermint/kms/issues/183> | ||
#[derive(Default)] | ||
pub struct Registry(RwLock<BTreeMap<Id, Chain>>); | ||
|
||
impl Registry { | ||
/// Acquire a read-only (concurrent) lock to the internal chain registry | ||
pub fn get(&self) -> Guard { | ||
// TODO(tarcieri): better handle `PoisonError` here? | ||
self.0.read().unwrap().into() | ||
} | ||
|
||
/// Register a chain with the registry | ||
pub fn register(&self, chain: Chain) -> Result<(), KmsError> { | ||
// TODO(tarcieri): better handle `PoisonError` here? | ||
let mut chain_map = self.0.write().unwrap(); | ||
|
||
let chain_id = chain.id; | ||
|
||
if chain_map.insert(chain_id, chain).is_none() { | ||
Ok(()) | ||
} else { | ||
// TODO(tarcieri): handle updating the set of registered chains | ||
fail!(ConfigError, "chain ID already registered: {}", chain_id); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.