Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ChainSync framework #243

Merged
merged 21 commits into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2b48ae3
Remove chain sync (old)
austinabell Feb 21, 2020
240ae86
rename sync_manager -> chain_sync
austinabell Feb 21, 2020
367ea00
Refactor types and update state_manager from cherry pick
austinabell Feb 21, 2020
a907976
Wip set up framework for syncing and persisting headers (broken durin…
austinabell Feb 23, 2020
905b412
Build out syncing and update function APIs
austinabell Feb 23, 2020
4310e54
Implement more header syncing logic and updated functions (broken dur…
austinabell Feb 24, 2020
8e9000f
Connected p2p and chain sync for requests (wow what a fun cherry-pick!)
austinabell Feb 26, 2020
7e661fb
Clean up changes
austinabell Feb 27, 2020
4b00f20
Implement conversion of tipset bundle to be cleaned up
austinabell Feb 27, 2020
b9818fe
Add bad blocks cache
austinabell Feb 27, 2020
e731d52
function to allow getting cids from TipSet
austinabell Feb 27, 2020
c5beef8
Add tests
austinabell Feb 27, 2020
ae68925
replace duplicate logic with generic function
austinabell Feb 27, 2020
c52daaf
remove comments and update a fn signature
austinabell Feb 27, 2020
6279152
Update genesis storage, fix address deserialization edge case
austinabell Feb 27, 2020
615ebd3
Change function signature and fix lint
austinabell Feb 27, 2020
9aad4eb
Remove resolved TODO
austinabell Feb 27, 2020
a95b640
Query for genesis in syncer constructor
austinabell Feb 27, 2020
d08022a
update TODO and future proof generics
austinabell Feb 27, 2020
f2d182f
remove main async tag
austinabell Feb 28, 2020
ae66d68
doczzz
austinabell Feb 28, 2020
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
.idea/
config.toml
.DS_STORE
.vscode
.vscode
/chain_db
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ members = [
"blockchain",
"blockchain/blocks",
"blockchain/chain",
"blockchain/chain_sync",
"blockchain/sync_manager",
"blockchain/state_manager",
"blockchain/chain_sync",
"vm",
"vm/actor",
"vm/address",
Expand Down
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ clean:
@cargo clean -p blockchain
@cargo clean -p forest_blocks
@cargo clean -p chain_sync
@cargo clean -p sync_manager
@cargo clean -p vm
@cargo clean -p forest_address
@cargo clean -p actor
Expand Down
2 changes: 1 addition & 1 deletion blockchain/blocks/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
/// .build_and_validate()
/// .unwrap();
/// ```
#[derive(Clone, Debug, PartialEq, Builder)]
#[derive(Clone, Debug, PartialEq, Builder, Default)]
#[builder(name = "BlockHeaderBuilder")]
pub struct BlockHeader {
// CHAIN LINKING
Expand Down
18 changes: 14 additions & 4 deletions blockchain/blocks/src/tipset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ pub struct TipSetKeys {
}

impl TipSetKeys {
/// constructor
pub fn new(cids: Vec<Cid>) -> Self {
Self { cids }
}

/// checks whether the set contains exactly the same CIDs as another.
fn equals(&self, key: &TipSetKeys) -> bool {
if self.cids.len() != key.cids.len() {
Expand All @@ -38,8 +38,9 @@ impl TipSetKeys {
}
true
}
/// Returns tipset keys
pub fn tipset_keys(&self) -> &[Cid] {

/// Returns tipset header cids
pub fn cids(&self) -> &[Cid] {
&self.cids
}
}
Expand All @@ -65,7 +66,7 @@ impl<'de> de::Deserialize<'de> for TipSetKeys {

/// An immutable set of blocks at the same height with the same parent set.
/// Blocks in a tipset are canonically ordered by ticket size.
#[derive(Clone, PartialEq, Debug, Default)]
#[derive(Clone, PartialEq, Debug)]
pub struct Tipset {
blocks: Vec<BlockHeader>,
key: TipSetKeys,
Expand Down Expand Up @@ -145,6 +146,10 @@ impl Tipset {
},
})
}
/// Returns epoch of the tipset
pub fn epoch(&self) -> &ChainEpoch {
&self.blocks[0].epoch()
}
/// Returns all blocks in tipset
pub fn blocks(&self) -> &[BlockHeader] {
&self.blocks
Expand Down Expand Up @@ -181,6 +186,10 @@ impl Tipset {
pub fn key(&self) -> &TipSetKeys {
&self.key
}
/// Returns slice of Cids for the current tipset
pub fn cids(&self) -> &[Cid] {
&self.key.cids()
}
/// Returns the CIDs of the parents of the blocks in the tipset
pub fn parents(&self) -> &TipSetKeys {
&self.blocks[0].parents()
Expand All @@ -196,6 +205,7 @@ impl Tipset {
}

/// FullTipSet is an expanded version of the TipSet that contains all the blocks and messages
#[derive(Debug, PartialEq, Clone)]
pub struct FullTipset {
blocks: Vec<Block>,
}
Expand Down
2 changes: 1 addition & 1 deletion blockchain/chain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ authors = ["ChainSafe Systems <info@chainsafe.io>"]
edition = "2018"

[dependencies]
forest_libp2p = { path = "../../node/forest_libp2p" }
blocks = { package = "forest_blocks", path = "../blocks" }
db = { path = "../../node/db" }
cid = { package = "forest_cid", path = "../../ipld/cid" }
Expand All @@ -14,6 +13,7 @@ encoding = { package = "forest_encoding", path = "../../encoding" }
serde = { version = "1.0", features = ["derive"] }
num-bigint = { path = "../../math/bigint", package = "forest_bigint" }
message = { package = "forest_message", path = "../../vm/message" }
ipld_blockstore = { path = "../../ipld/blockstore" }

[dev-dependencies]
address = { package = "forest_address", path = "../../vm/address" }
Expand Down
57 changes: 33 additions & 24 deletions blockchain/chain/src/store/chain_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,47 @@
// SPDX-License-Identifier: Apache-2.0, MIT

use super::{Error, TipIndex, TipSetMetadata};
use blocks::{BlockHeader, Tipset};
use blocks::{BlockHeader, TipSetKeys, Tipset};
use cid::Cid;
use db::{Error as DbError, Read, RocksDb as Blockstore, Write};
use db::Error as DbError;
use encoding::{de::DeserializeOwned, from_slice, Cbor};
use ipld_blockstore::BlockStore;
use message::{SignedMessage, UnsignedMessage};
use num_bigint::BigUint;
use std::path::Path;
use std::sync::Arc;

/// Generic implementation of the datastore trait and structures
pub struct ChainStore<'a> {
pub struct ChainStore<'db, DB> {
// TODO add IPLD Store
// TODO add StateTreeLoader
// TODO add a pubsub channel that publishes an event every time the head changes.

// key-value datastore
db: Blockstore,

// CID of the genesis block.
genesis: Cid,
db: &'db DB,

// Tipset at the head of the best-known chain.
heaviest: &'a Tipset,
// TODO revisit if this should be pointer to tipset on heap
heaviest: Arc<Tipset>,

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

impl<'a> ChainStore<'a> {
impl<'db, DB> ChainStore<'db, DB>
where
DB: BlockStore,
{
/// 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 {
pub fn new(db: &'db DB) -> Self {
// TODO pull heaviest tipset from data storage
let heaviest = Arc::new(Tipset::new(vec![BlockHeader::default()]).unwrap());
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()])?;
Expand All @@ -58,11 +58,13 @@ impl<'a> ChainStore<'a> {
// TODO
Ok(BigUint::from(0 as u32))
}

/// Writes genesis to blockstore
pub fn set_genesis(&self, header: BlockHeader) -> Result<(), DbError> {
let ts: Tipset = Tipset::new(vec![header])?;
Ok(self.persist_headers(&ts)?)
}

/// Writes encoded blockheader data to blockstore
pub fn persist_headers(&self, tip: &Tipset) -> Result<(), DbError> {
let mut raw_header_data = Vec::new();
Expand All @@ -76,6 +78,7 @@ impl<'a> ChainStore<'a> {
}
Ok(self.db.bulk_write(&keys, &raw_header_data)?)
}

/// Writes encoded message data to blockstore
pub fn put_messages<T: Cbor>(&self, msgs: &[T]) -> Result<(), Error> {
for m in msgs {
Expand All @@ -88,28 +91,33 @@ impl<'a> ChainStore<'a> {
}
Ok(())
}

/// Returns genesis blockheader from blockstore
pub fn genesis(&self) -> Result<BlockHeader, Error> {
let bz = self.db.read(self.genesis.key())?;
// TODO change data store for pulling genesis
let bz = self.db.read("gen_block")?;
austinabell marked this conversation as resolved.
Show resolved Hide resolved
match bz {
None => Err(Error::UndefinedKey(
"Genesis key does not exist".to_string(),
)),
Some(ref x) => from_slice(&x)?,
}
}

/// Returns heaviest tipset from blockstore
pub fn heaviest_tipset(&self) -> &Tipset {
&self.heaviest
pub fn heaviest_tipset(&self) -> Arc<Tipset> {
self.heaviest.clone()
}

/// Returns key-value store instance
pub fn blockstore(&self) -> &Blockstore {
pub fn blockstore(&self) -> &DB {
&self.db
}

/// Returns Tipset from key-value store from provided cids
pub fn tipset(&self, cids: &[Cid]) -> Result<Tipset, Error> {
pub fn tipset_from_keys(&self, tsk: &TipSetKeys) -> Result<Tipset, Error> {
let mut block_headers = Vec::new();
for c in cids {
for c in tsk.cids() {
let raw_header = self.db.read(c.key())?;
if let Some(x) = raw_header {
// decode raw header into BlockHeader
Expand Down Expand Up @@ -138,6 +146,7 @@ impl<'a> ChainStore<'a> {
let secp_msgs: Vec<SignedMessage> = self.messages_from_cids(Vec::new())?;
Ok((bls_msgs, secp_msgs))
}

/// Returns messages from key-value store
pub fn messages_from_cids<T>(&self, keys: Vec<&Cid>) -> Result<Vec<T>, Error>
where
Expand Down
20 changes: 19 additions & 1 deletion blockchain/chain_sync/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,23 @@ authors = ["ChainSafe Systems <info@chainsafe.io>"]
edition = "2018"

[dependencies]
libp2p = "0.15.0"
address = { package = "forest_address", path = "../../vm/address" }
amt = { package = "ipld_amt", path = "../../ipld/amt" }
blocks = { package = "forest_blocks", path = "../blocks" }
db = { path = "../../node/db" }
encoding = { package = "forest_encoding", path = "../../encoding" }
libp2p = "0.15.0"
cid = { package = "forest_cid", path = "../../ipld/cid" }
ipld_blockstore = { path = "../../ipld/blockstore" }
chain = { path = "../chain" }
message = { package = "forest_message", path = "../../vm/message" }
state_tree = { path = "../../vm/state_tree/" }
state_manager = { path = "../state_manager/" }
num-bigint = { path = "../../math/bigint", package = "forest_bigint" }
crypto = { path = "../../crypto" }
log = "0.4.8"
async-std = { version = "1.4.0", features = ["unstable"] }
forest_libp2p = { path = "../../node/forest_libp2p" }
pin-project = "0.4.8"
futures = "0.3.2"
lru = "0.4.3"
42 changes: 0 additions & 42 deletions blockchain/chain_sync/src/block_msg.rs

This file was deleted.

12 changes: 0 additions & 12 deletions blockchain/chain_sync/src/block_proposer.rs

This file was deleted.

Loading