Skip to content

Commit

Permalink
Sync & Store methods updated (#193)
Browse files Browse the repository at this point in the history
* Added validate msg logic
* Added logic for validating msg data
* Added message storage
* Made raw block its own crate and impl to messages
* Updated raw block trait to improve cid return and remove multihash
* Made requested changes
* Updated RawBlock trait
* Init DB instance on chain store construction
* Fix naming convention
  • Loading branch information
dutterbutter authored Jan 28, 2020
1 parent f1eb515 commit 2514c40
Show file tree
Hide file tree
Showing 18 changed files with 227 additions and 68 deletions.
1 change: 1 addition & 0 deletions blockchain/blocks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ multihash = "0.9.3"
derive_builder = "0.9"
serde = { version = "1.0", features = ["derive"] }
encoding = { path = "../../encoding" }
raw_block = { path = "../raw_block" }
num-bigint = { git = "https://github.com/austinabell/num-bigint", rev = "f7084a9ed5a2b08d9bfb67790cb4ce9212193f31" }

[dev-dependencies]
Expand Down
10 changes: 8 additions & 2 deletions blockchain/blocks/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,21 @@ struct PoStProof {}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Block {
header: BlockHeader,
bls_messages: UnsignedMessage,
secp_messages: SignedMessage,
bls_messages: Vec<UnsignedMessage>,
secp_messages: Vec<SignedMessage>,
}

impl Block {
/// Returns reference to BlockHeader
pub fn to_header(&self) -> &BlockHeader {
&self.header
}
pub fn bls_msgs(&self) -> &Vec<UnsignedMessage> {
&self.bls_messages
}
pub fn secp_msgs(&self) -> &Vec<SignedMessage> {
&self.secp_messages
}
}

// TODO verify format or implement custom serialize/deserialize function (if necessary):
Expand Down
14 changes: 5 additions & 9 deletions blockchain/blocks/src/header.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0

use super::{EPostProof, RawBlock, Ticket, TipSetKeys, TxMeta};
use super::{EPostProof, Ticket, TipSetKeys, TxMeta};
use address::Address;
use cid::Cid;
use cid::{Cid, Error as CidError};
use clock::ChainEpoch;
use crypto::Signature;
use derive_builder::Builder;
use encoding::{Cbor, Error as EncodingError};
use multihash::Hash;
use num_bigint::BigUint;
use raw_block::RawBlock;
use serde::{Deserialize, Serialize};
use std::fmt;

Expand Down Expand Up @@ -119,12 +119,8 @@ impl RawBlock for BlockHeader {
self.marshal_cbor()
}
/// returns the content identifier of the block
fn cid(&self) -> Cid {
self.cid().clone()
}
/// returns the hash contained in the block CID
fn multihash(&self) -> Hash {
self.cid().prefix().mh_type
fn cid(&self) -> Result<Cid, CidError> {
Ok(self.cid().clone())
}
}

Expand Down
2 changes: 0 additions & 2 deletions blockchain/blocks/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
mod block;
mod errors;
mod header;
mod raw_block;
mod ticket;
mod tipset;

pub use block::*;
pub use errors::*;
pub use header::*;
pub use raw_block::*;
pub use ticket::*;
pub use tipset::*;
14 changes: 0 additions & 14 deletions blockchain/blocks/src/raw_block.rs

This file was deleted.

2 changes: 2 additions & 0 deletions blockchain/chain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ clock = { path = "../../node/clock" }
encoding = { path = "../../encoding" }
serde = { version = "1.0", features = ["derive"] }
num-bigint = { git = "https://github.com/austinabell/num-bigint", rev = "f7084a9ed5a2b08d9bfb67790cb4ce9212193f31" }
raw_block = { package = "raw_block", path = "../raw_block" }
message = { path = "../../vm/message" }

[dev-dependencies]
address = { path = "../../vm/address" }
Expand Down
60 changes: 50 additions & 10 deletions blockchain/chain/src/store/chain_store.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0

use super::{Error, TipIndex};
use blocks::{BlockHeader, RawBlock, Tipset};
use super::{Error, TipIndex, TipSetMetadata};
use blocks::{BlockHeader, Tipset};
use cid::Cid;
use db::{Error as DbError, Read, RocksDb as Blockstore, Write};
use encoding::from_slice;
use num_bigint::BigUint;
use raw_block::RawBlock;
use std::path::Path;

#[derive(Default)]
pub struct ChainStore {
/// Generic implementation of the datastore trait and structures
pub struct ChainStore<'a> {
// TODO add IPLD Store
// TODO add StateTreeLoader
// TODO add a pubsub channel that publishes an event every time the head changes.
Expand All @@ -21,15 +23,37 @@ pub struct ChainStore {
genesis: Cid,

// Tipset at the head of the best-known chain.
heaviest: Tipset,
heaviest: &'a Tipset,

// tip_index tracks tipsets by epoch/parentset for use by expected consensus.
_tip_index: TipIndex,
tip_index: TipIndex,
}

impl ChainStore {
/// TODO add constructor
impl<'a> ChainStore<'a> {
/// constructor
pub fn new(path: &Path, gen: Cid, heaviest: &'a Tipset) -> Result<Self, Error> {
let mut db = Blockstore::new(path.to_path_buf());
// initialize key-value store
db.open()?;

Ok(Self {
db,
tip_index: TipIndex::new(),
genesis: gen,
heaviest,
})
}
/// Sets tip_index tracker
pub fn set_tipset_tracker(&mut self, header: &BlockHeader) -> Result<(), Error> {
let ts: Tipset = Tipset::new(vec![header.clone()])?;
let meta = TipSetMetadata {
tipset_state_root: header.state_root().clone(),
tipset_receipts_root: header.message_receipts().clone(),
tipset: ts,
};
Ok(self.tip_index.put(&meta)?)
}
/// weight
pub fn weight(&self, _ts: &Tipset) -> Result<BigUint, Error> {
// TODO
Ok(BigUint::from(0 as u32))
Expand All @@ -52,8 +76,20 @@ impl ChainStore {
}
Ok(self.db.bulk_write(&keys, &raw_header_data)?)
}
/// Writes encoded message data to blockstore
pub fn put_messages<T: RawBlock>(&self, msgs: &[T]) -> Result<(), Error> {
for m in msgs {
let key = m.cid()?.key();
let value = &m.raw_data()?;
if self.db.exists(&key)? {
return Err(Error::KeyValueStore("Keys exist".to_string()));
}
self.db.write(&key, value)?
}
Ok(())
}
/// Returns genesis blockheader from blockstore
pub fn get_genesis(&self) -> Result<BlockHeader, Error> {
pub fn genesis(&self) -> Result<BlockHeader, Error> {
let bz = self.db.read(self.genesis.key())?;
match bz {
None => Err(Error::UndefinedKey(
Expand All @@ -63,7 +99,11 @@ impl ChainStore {
}
}
/// Returns heaviest tipset from blockstore
pub fn get_heaviest_tipset(&self) -> &Tipset {
pub fn heaviest_tipset(&self) -> &Tipset {
&self.heaviest
}
/// Returns key-value store instance
pub fn blockstore(&self) -> &Blockstore {
&self.db
}
}
35 changes: 22 additions & 13 deletions blockchain/chain/src/store/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

use blocks::Error as BlkErr;
use cid::Error as CidErr;
use db::Error as DbErr;
use encoding::{error::Error as SerdeErr, Error as EncErr};
use serde::Deserialize;
Expand All @@ -13,53 +14,61 @@ pub enum Error {
UndefinedKey(String),
/// Tipset contains no blocks
NoBlocks,
/// Keys are already written to store
KeyExists,
/// Error originating from key-value store
KVError(String),
KeyValueStore(String),
/// Error originating constructing blockchain structures
BlkError(String),
Blockchain(String),
/// Error originating from encoding arbitrary data
EncodingError(String),
Encoding(String),
/// Error originating from Cid creation
Cid(String),
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::UndefinedKey(msg) => write!(f, "Invalid key: {}", msg),
Error::NoBlocks => write!(f, "No blocks for tipset"),
Error::KeyExists => write!(f, "Keys already exist in store"),
Error::KVError(msg) => write!(f, "Error originating from Key-Value store: {}", msg),
Error::BlkError(msg) => write!(
Error::KeyValueStore(msg) => {
write!(f, "Error originating from Key-Value store: {}", msg)
}
Error::Blockchain(msg) => write!(
f,
"Error originating from construction of blockchain structures: {}",
msg
),
Error::EncodingError(msg) => write!(f, "Error originating from Encoding type: {}", msg),
Error::Encoding(msg) => write!(f, "Error originating from Encoding type: {}", msg),
Error::Cid(msg) => write!(f, "Error originating from from Cid creation: {}", msg),
}
}
}

impl From<DbErr> for Error {
fn from(e: DbErr) -> Error {
Error::KVError(e.to_string())
Error::KeyValueStore(e.to_string())
}
}

impl From<BlkErr> for Error {
fn from(e: BlkErr) -> Error {
Error::BlkError(e.to_string())
Error::Blockchain(e.to_string())
}
}

impl From<EncErr> for Error {
fn from(e: EncErr) -> Error {
Error::EncodingError(e.to_string())
Error::Encoding(e.to_string())
}
}

impl From<SerdeErr> for Error {
fn from(e: SerdeErr) -> Error {
Error::EncodingError(e.to_string())
Error::Encoding(e.to_string())
}
}

impl From<CidErr> for Error {
fn from(e: CidErr) -> Error {
Error::Cid(e.to_string())
}
}
6 changes: 3 additions & 3 deletions blockchain/chain/src/store/tip_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ use std::hash::{Hash, Hasher};
#[derive(Clone, PartialEq, Debug)]
pub struct TipSetMetadata {
/// Root of aggregate state after applying tipset
tipset_state_root: Cid,
pub tipset_state_root: Cid,

/// Receipts from all message contained within this tipset
tipset_receipts_root: Cid,
pub tipset_receipts_root: Cid,

/// The actual Tipset
tipset: Tipset,
pub tipset: Tipset,
}

/// Trait to allow metadata to be indexed by multiple types of structs
Expand Down
11 changes: 11 additions & 0 deletions blockchain/raw_block/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "raw_block"
version = "0.1.0"
authors = ["ChainSafe Systems <info@chainsafe.io>"]
edition = "2018"

[dependencies]
cid = { package = "ferret_cid", path = "../../ipld/cid" }
serde = { version = "1.0", features = ["derive"] }
encoding = { path = "../../encoding" }
multihash = "0.9.3"
6 changes: 6 additions & 0 deletions blockchain/raw_block/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0

mod raw_block;

pub use self::raw_block::*;
18 changes: 18 additions & 0 deletions blockchain/raw_block/src/raw_block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0

use cid::{Cid, Codec, Error, Version};
use encoding::{Cbor, Error as EncodingError};
use multihash::Multihash;

/// Used to extract required encoded data and cid for block and message storage
pub trait RawBlock: Cbor {
fn raw_data(&self) -> Result<Vec<u8>, EncodingError> {
self.marshal_cbor()
}
/// returns the content identifier of the block
fn cid(&self) -> Result<Cid, Error> {
let hash = Multihash::from_bytes(self.raw_data()?)?;
Ok(Cid::new(Codec::DagCBOR, Version::V1, hash))
}
}
6 changes: 6 additions & 0 deletions blockchain/sync_manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@ edition = "2018"
[dependencies]
address = { path = "../../vm/address" }
blocks = { path = "../blocks" }
db = { path = "../../node/db" }
encoding = { path = "../../encoding" }
libp2p = { git = "https://github.com/SigP/rust-libp2p", rev = "776d13ef046358964c7d64cda3295a3a3cb24743" }
cid = { package = "ferret_cid", path = "../../ipld/cid" }
chain = { path ="../chain" }
message = { path = "../../vm/message" }
raw_block = { package = "raw_block", path = "../raw_block" }
multihash = "0.9.3"

[dev-dependencies]
cid = { package = "ferret_cid", path = "../../ipld/cid" }
Expand Down
Loading

0 comments on commit 2514c40

Please sign in to comment.