Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: CI

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Install latest nightly
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt
- name: Format code.
uses: actions-rs/cargo@v1
with:
command: fmt
- name: Build
uses: actions-rs/cargo@v1
with:
command: build
- name: Tests
uses: actions-rs/cargo@v1
with:
command: test
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/target
/test/*
Cargo.lock
21 changes: 21 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "libnode"
version = "0.1.0"
authors = ["luo4lu <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
kv-hal-sled = { git = "https://github.com/Yinet-project/kv-hal-sled" }
kv-hal = { git = "https://github.com/Yinet-project/kv-hal" }
rust-crypto = "0.2.36"
rand = "0.7.3"
async-trait = "0.1"
sled = "0.30.3"
tokio = { version = "0.2", features = ["full"] }

[dev-dependencies.cargo-husky]
version = "1"
default-features = false
features = ["precommit-hook", "run-cargo-fmt", "run-cargo-test", "run-cargo-clippy"]
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod node_information;
135 changes: 135 additions & 0 deletions src/node_information.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
use crypto::{digest::Digest, ed25519, ripemd160::Ripemd160, sha3::Sha3};
use kv_hal::kv::Storage;
use kv_hal_sled::SledStorage;
use std::convert::TryFrom;
//use sled;

pub struct NodeInfo {
seed: [u8; 32],
secret_key: [u8; 64],
public_key: [u8; 32],
node_id: [u8; 20],
}

impl NodeInfo {
pub async fn new(string: &str, key: &[u8]) -> Self {
let seed = NodeInfo::get_value(string, key).await;
if let Ok(seed) = seed {
if let Some(seed) = seed {
NodeInfo::init_node(&seed)
} else {
NodeInfo::rebuild_key()
}
} else {
NodeInfo::rebuild_key()
}
}

//get seed rand sum from kv-hal-sled trait in the get function
async fn get_value(string: &str, key: &[u8]) -> Result<Option<Vec<u8>>, sled::Error> {
let stor = SledStorage::new(string);
stor.get(key).await
}

//如果value存在初始化结构体
fn init_node(seed_s: &[u8]) -> Self {
//于rebuild_key接口功能类似,不产生随机种子而是根据入参计算秘钥,秘钥-》nodeid
let seed: [u8; 32] = TryFrom::try_from(seed_s).unwrap();
let (secret_key, public_key) = ed25519::keypair(&seed);
//两次hash let nodeID = ripemd160(sha3(public key));
//创建一个SHA3-256的对象
let mut hasher = Sha3::sha3_256();
//传入公钥
hasher.input(&public_key);
let mut hex: Vec<u8> = Vec::new();
hasher.result(&mut hex);

let mut ripemd = Ripemd160::new();
ripemd.input(&hex);
let mut node_id: [u8; 20] = [0; 20];
ripemd.result(&mut node_id);

Self {
seed,
secret_key,
public_key,
node_id,
}
}

//通过公钥私钥计算出NodeID
pub fn get_node(&self) -> [u8; 20] {
//获取nodeid,rebuild_key里面的算法获取
let mut hasher = Sha3::sha3_256();
//传入公钥
hasher.input(&self.public_key);
let mut hex: Vec<u8> = Vec::new();
hasher.result(&mut hex);

let mut ripemd = Ripemd160::new();
ripemd.input(&hex);
let mut node_id: [u8; 20] = [0; 20];
ripemd.result(&mut node_id);
assert_eq!(node_id, self.node_id);
node_id
}

//检查是否存在公钥私钥
pub fn check_key(&self) -> bool {
//由get_value获取的私钥计算出公钥与数据结构中存在的公秘钥比较
let (secret_key, public_key) = ed25519::keypair(&self.seed);
for (i, _) in secret_key.iter().enumerate() {
assert_eq!(secret_key[i], self.secret_key[i]);
}
assert_eq!(public_key, self.public_key);
if self.secret_key.len() != 64 && self.public_key.len() != 32 {
return false;
}
true
}

//如果value不存在生成新的公私钥
fn rebuild_key() -> Self {
let iter: [u8; 32] = [0; 32];
let mut seed: [u8; 32] = [0; 32];
for (i, _) in iter.iter().enumerate() {
seed[i] = rand::random::<u8>();
}
let (secret_key, public_key) = ed25519::keypair(&seed);
//两次hash let nodeID = ripemd160(sha3(public key));
//创建一个SHA3-256的对象
let mut hasher = Sha3::sha3_256();
//传入公钥
hasher.input(&public_key);
let mut hex: Vec<u8> = Vec::new();
hasher.result(&mut hex);

let mut ripemd = Ripemd160::new();
ripemd.input(&hex);
let mut node_id: [u8; 20] = [0; 20];
ripemd.result(&mut node_id);

Self {
seed,
secret_key,
public_key,
node_id,
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[tokio::test]
async fn test_node() {
let node_inf = NodeInfo::new("test/test.db", b"seed").await;

let value = node_inf.check_key();
assert_eq!(value, false || true);

let node = node_inf.get_node();
assert_eq!(node, node_inf.node_id);
}
}