mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
validatord: state storage moved from jsonfile to sled
This commit is contained in:
@@ -1,17 +1,21 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::{
|
||||
hash::{Hash, Hasher},
|
||||
io,
|
||||
};
|
||||
|
||||
use super::{metadata::Metadata, participant::Participant, tx::Tx};
|
||||
|
||||
use crate::{
|
||||
crypto::{keypair::PublicKey, schnorr::Signature},
|
||||
net,
|
||||
util::serial::{SerialDecodable, SerialEncodable},
|
||||
impl_vec, net,
|
||||
util::serial::{Decodable, Encodable, SerialDecodable, SerialEncodable, VarInt},
|
||||
Result,
|
||||
};
|
||||
|
||||
/// This struct represents a tuple of the form (st, sl, txs, metadata).
|
||||
/// Each blocks parent hash h may be computed simply as a hash of the parent block.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, SerialEncodable, SerialDecodable)]
|
||||
pub struct Block {
|
||||
/// Previous block hash
|
||||
pub st: String, // Change this to a proper hash type
|
||||
@@ -87,3 +91,5 @@ impl net::Message for BlockProposal {
|
||||
pub fn proposal_eq_block(proposal: &BlockProposal, block: &Block) -> bool {
|
||||
proposal.st == block.st && proposal.sl == block.sl && proposal.txs == block.txs
|
||||
}
|
||||
|
||||
impl_vec!(Block);
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
use std::{
|
||||
collections::hash_map::DefaultHasher,
|
||||
hash::{Hash, Hasher},
|
||||
io,
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::{
|
||||
impl_vec,
|
||||
util::serial::{Decodable, Encodable, SerialDecodable, SerialEncodable, VarInt},
|
||||
Result,
|
||||
};
|
||||
|
||||
use super::block::Block;
|
||||
|
||||
/// This struct represents a sequence of blocks starting with the genesis block.
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
#[derive(Debug, Clone, PartialEq, SerialEncodable, SerialDecodable)]
|
||||
pub struct Blockchain {
|
||||
pub blocks: Vec<Block>,
|
||||
}
|
||||
@@ -54,3 +59,5 @@ impl Blockchain {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl_vec!(Blockchain);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::io;
|
||||
use std::{collections::BTreeMap, io};
|
||||
|
||||
use crate::{
|
||||
impl_vec, net,
|
||||
@@ -30,4 +30,27 @@ impl net::Message for Participant {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for BTreeMap<u64, Participant> {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += VarInt(self.len() as u64).encode(&mut s)?;
|
||||
for c in self.iter() {
|
||||
len += c.1.encode(&mut s)?;
|
||||
}
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for BTreeMap<u64, Participant> {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
let len = VarInt::decode(&mut d)?.0;
|
||||
let mut ret = BTreeMap::new();
|
||||
for _ in 0..len {
|
||||
let participant: Participant = Decodable::decode(&mut d)?;
|
||||
ret.insert(participant.id, participant);
|
||||
}
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
||||
impl_vec!(Participant);
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use chrono::{NaiveDateTime, Utc};
|
||||
use log::{debug, error};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
collections::{hash_map::DefaultHasher, BTreeMap},
|
||||
hash::{Hash, Hasher},
|
||||
path::Path,
|
||||
sync::{Arc, RwLock},
|
||||
time::Duration,
|
||||
};
|
||||
@@ -14,8 +12,8 @@ use crate::{
|
||||
keypair::{PublicKey, SecretKey},
|
||||
schnorr::{SchnorrPublic, SchnorrSecret},
|
||||
},
|
||||
util::serial::Encodable,
|
||||
Result,
|
||||
util::serial::{deserialize, serialize, Encodable, SerialDecodable, SerialEncodable},
|
||||
Error, Result,
|
||||
};
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
@@ -24,11 +22,12 @@ use super::{
|
||||
blockchain::Blockchain,
|
||||
participant::Participant,
|
||||
tx::Tx,
|
||||
util::{get_current_time, load, save, Timestamp},
|
||||
util::Timestamp,
|
||||
vote::Vote,
|
||||
};
|
||||
|
||||
const DELTA: u64 = 60;
|
||||
const SLED_STATE_TREE: &[u8] = b"_state";
|
||||
|
||||
/// Atomic pointer to state.
|
||||
pub type StatePtr = Arc<RwLock<State>>;
|
||||
@@ -37,7 +36,7 @@ pub type StatePtr = Arc<RwLock<State>>;
|
||||
/// Each node is numbered and has a secret-public keys pair, to sign messages.
|
||||
/// Nodes hold a set of Blockchains(some of which are not notarized)
|
||||
/// and a set of unconfirmed pending transactions.
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(SerialEncodable, SerialDecodable)]
|
||||
pub struct State {
|
||||
pub id: u64,
|
||||
pub genesis_time: Timestamp,
|
||||
@@ -464,27 +463,34 @@ impl State {
|
||||
}
|
||||
|
||||
/// Util function to save the current node state to provided file path.
|
||||
pub fn save(&self, path: &Path) -> Result<()> {
|
||||
save::<Self>(path, self)
|
||||
pub fn save(&self, db: &sled::Db) -> Result<()> {
|
||||
let tree = db.open_tree(SLED_STATE_TREE).unwrap();
|
||||
let serialized = serialize(self);
|
||||
match tree.insert(self.id.to_ne_bytes(), serialized) {
|
||||
Err(_) => Err(Error::OperationFailed),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Util function to load current node state by the provided file path.
|
||||
// If file is not found, node state is reset.
|
||||
pub fn load_or_create(id: u64, path: &Path) -> Result<Self> {
|
||||
match load::<Self>(path) {
|
||||
Ok(state) => Ok(state),
|
||||
Err(_) => Self::reset(id, path),
|
||||
pub fn load_or_create(genesis: i64, id: u64, db: &sled::Db) -> Result<State> {
|
||||
let tree = db.open_tree(SLED_STATE_TREE).unwrap();
|
||||
if let Some(found) = tree.get(id.to_ne_bytes()).unwrap() {
|
||||
Ok(deserialize(&found).unwrap())
|
||||
} else {
|
||||
Self::reset(genesis, id, db)
|
||||
}
|
||||
}
|
||||
|
||||
/// Util function to load the current node state by the provided file path.
|
||||
pub fn load_current_state(id: u64, path: &Path) -> Result<StatePtr> {
|
||||
let state = Self::load_or_create(id, path)?;
|
||||
/// Util function to load the current node state by the provided folder path.
|
||||
pub fn load_current_state(genesis: i64, id: u64, db: &sled::Db) -> Result<StatePtr> {
|
||||
let state = Self::load_or_create(genesis, id, db)?;
|
||||
Ok(Arc::new(RwLock::new(state)))
|
||||
}
|
||||
|
||||
/// Util function to reset node state.
|
||||
pub fn reset(id: u64, path: &Path) -> Result<State> {
|
||||
pub fn reset(genesis: i64, id: u64, db: &sled::Db) -> Result<State> {
|
||||
// Genesis block is generated.
|
||||
let mut genesis_block = Block::new(
|
||||
String::from("⊥"),
|
||||
@@ -498,10 +504,10 @@ impl State {
|
||||
genesis_block.metadata.sm.notarized = true;
|
||||
genesis_block.metadata.sm.finalized = true;
|
||||
|
||||
let genesis_time = get_current_time();
|
||||
let genesis_time = Timestamp(genesis);
|
||||
|
||||
let state = Self::new(id, genesis_time, genesis_block);
|
||||
state.save(path)?;
|
||||
state.save(db)?;
|
||||
Ok(state)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,7 @@
|
||||
use std::{fs::File, io::BufReader, path::Path};
|
||||
|
||||
use chrono::{NaiveDateTime, Utc};
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
util::serial::{SerialDecodable, SerialEncodable},
|
||||
Result,
|
||||
};
|
||||
|
||||
/// Util function to load a structure saved as a JSON in the provided path file, using serde crate.
|
||||
pub fn load<T: DeserializeOwned>(path: &Path) -> Result<T> {
|
||||
let file = File::open(path)?;
|
||||
let reader = BufReader::new(file);
|
||||
|
||||
let value: T = serde_json::from_reader(reader)?;
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
/// Util function to save a structure as a JSON in the provided path file, using serde crate.
|
||||
pub fn save<T: Serialize>(path: &Path, value: &T) -> Result<()> {
|
||||
let file = File::create(path)?;
|
||||
serde_json::to_writer_pretty(file, value)?;
|
||||
Ok(())
|
||||
}
|
||||
use crate::util::serial::{SerialDecodable, SerialEncodable};
|
||||
|
||||
/// Util structure to represend chrono UTC timestamps.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, SerialDecodable, SerialEncodable)]
|
||||
|
||||
Reference in New Issue
Block a user