Skip to content

Commit

Permalink
Implement Wallet (#469)
Browse files Browse the repository at this point in the history
* initial wallet implementation

* implemented wallet except generating new private key

* license

* implemented private key generation and refactor

* reformatting code according to comments on pr

* changed keystore to be a trait and refactored

* cargo clippy

* fixed issues using rust stable 1.44

* fixed issues rust 1.44 issues

* added wallet tests

* added changes

* Update key_management/src/keystore.rs

Co-authored-by: Austin Abell <austinabell8@gmail.com>

Co-authored-by: Austin Abell <austinabell8@gmail.com>
  • Loading branch information
flodesi and austinabell authored Jun 10, 2020
1 parent 418c2fe commit 8d2a493
Show file tree
Hide file tree
Showing 7 changed files with 549 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ members = [
"utils/commcid",
"utils/json_utils",
"types",
"key_management",
]
13 changes: 13 additions & 0 deletions key_management/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "key_management"
version = "0.1.0"
authors = ["ChainSafe Systems <info@chainsafe.io>"]
edition = "2018"

[dependencies]
thiserror = "1.0"
address = { package = "forest_address", path = "../vm/address", version = "0.2" }
crypto = { package = "forest_crypto", path = "../crypto" }
bls-signatures = "0.6.0"
libsecp256k1 = "0.3.4"
rand = "0.7.3"
22 changes: 22 additions & 0 deletions key_management/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use thiserror::Error;

#[derive(Debug, PartialEq, Error)]
pub enum Error {
/// info that corresponds to key does not exist
#[error("Key info not found")]
KeyInfo,
/// Key already exists in keystore
#[error("Key already exists")]
KeyExists,
#[error("Key does not exist")]
KeyNotExists,
#[error("Key not found")]
NoKey,
#[error("{0}")]
Other(String),
#[error("Could not convert from KeyInfo to Key")]
KeyInfoConversion,
}
83 changes: 83 additions & 0 deletions key_management/src/keystore.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use super::errors::Error;
use crypto::SignatureType;
use std::collections::HashMap;

/// KeyInfo struct, this contains the type of key (stored as a string) and the private key.
/// note how the private key is stored as a byte vector
#[derive(Clone, PartialEq, Debug, Eq)]
pub struct KeyInfo {
key_type: SignatureType,
// Vec<u8> is used because The private keys for BLS and SECP256K1 are not of the same type
private_key: Vec<u8>,
}

impl KeyInfo {
/// Return a new KeyInfo given the key_type and private_key
pub fn new(key_type: SignatureType, private_key: Vec<u8>) -> Self {
KeyInfo {
key_type,
private_key,
}
}

/// Return a clone of the key_type
pub fn key_type(&self) -> &SignatureType {
&self.key_type
}

/// Return a clone of the private_key
pub fn private_key(&self) -> &Vec<u8> {
&self.private_key
}
}

/// KeyStore struct, this contains a HashMap that is a set of KeyInfos resolved by their Address
pub trait KeyStore {
/// Return all of the keys that are stored in the KeyStore
fn list(&self) -> Vec<String>;
/// Return Keyinfo that corresponds to a given key
fn get(&self, k: &str) -> Result<KeyInfo, Error>;
/// Save a key key_info pair to the KeyStore
fn put(&mut self, key: String, key_info: KeyInfo) -> Result<(), Error>;
/// Remove the Key and corresponding key_info from the KeyStore
fn remove(&mut self, key: String) -> Option<KeyInfo>;
}

#[derive(Default, Clone, PartialEq, Debug, Eq)]
pub struct MemKeyStore {
pub key_info: HashMap<String, KeyInfo>,
}

impl MemKeyStore {
/// Return a new empty KeyStore
pub fn new() -> Self {
MemKeyStore {
key_info: HashMap::new(),
}
}
}

impl KeyStore for MemKeyStore {
fn list(&self) -> Vec<String> {
self.key_info.iter().map(|(key, _)| key.clone()).collect()
}

fn get(&self, k: &str) -> Result<KeyInfo, Error> {
self.key_info.get(k).cloned().ok_or(Error::KeyInfo)
}

fn put(&mut self, key: String, key_info: KeyInfo) -> Result<(), Error> {
if self.key_info.contains_key(&key) {
return Err(Error::KeyExists);
}
self.key_info.insert(key, key_info);
Ok(())
}

fn remove(&mut self, key: String) -> Option<KeyInfo> {
self.key_info.remove(&key)
}
}
12 changes: 12 additions & 0 deletions key_management/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

mod errors;
mod keystore;
mod wallet;
mod wallet_helpers;

pub use errors::*;
pub use keystore::*;
pub use wallet::*;
pub use wallet_helpers::*;
Loading

0 comments on commit 8d2a493

Please sign in to comment.