Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Storage chains: serve transactions over IPFS/bitswap (#7963)
Browse files Browse the repository at this point in the history
* IPFS server for transactions

* Style

* Indent

* Log message

* CLI option

* Apply suggestions from code review

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>

* Style

* Style

* Minor fixes

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
  • Loading branch information
arkpar and tomaka authored Feb 3, 2021
1 parent 5a94966 commit 56c64cf
Show file tree
Hide file tree
Showing 19 changed files with 574 additions and 22 deletions.
79 changes: 79 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions client/api/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,17 @@ pub trait BlockBackend<Block: BlockT> {

/// Get block hash by number.
fn block_hash(&self, number: NumberFor<Block>) -> sp_blockchain::Result<Option<Block::Hash>>;

/// Get single extrinsic by hash.
fn extrinsic(
&self,
hash: &Block::Hash,
) -> sp_blockchain::Result<Option<<Block as BlockT>::Extrinsic>>;

/// Check if extrinsic exists.
fn have_extrinsic(&self, hash: &Block::Hash) -> sp_blockchain::Result<bool> {
Ok(self.extrinsic(hash)?.is_some())
}
}

/// Provide a list of potential uncle headers for a given block.
Expand Down
7 changes: 7 additions & 0 deletions client/api/src/in_mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,13 @@ impl<Block: BlockT> blockchain::Backend<Block> for Blockchain<Block> {
fn children(&self, _parent_hash: Block::Hash) -> sp_blockchain::Result<Vec<Block::Hash>> {
unimplemented!()
}

fn extrinsic(
&self,
_hash: &Block::Hash,
) -> sp_blockchain::Result<Option<<Block as BlockT>::Extrinsic>> {
unimplemented!("Not supported by the in-mem backend.")
}
}

impl<Block: BlockT> blockchain::ProvideCache<Block> for Blockchain<Block> {
Expand Down
5 changes: 5 additions & 0 deletions client/cli/src/params/network_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ pub struct NetworkParams {
/// security improvements.
#[structopt(long)]
pub kademlia_disjoint_query_paths: bool,

/// Join the IPFS network and serve transactions over bitswap protocol.
#[structopt(long)]
pub ipfs_server: bool,
}

impl NetworkParams {
Expand Down Expand Up @@ -181,6 +185,7 @@ impl NetworkParams {
allow_non_globals_in_dht,
kademlia_disjoint_query_paths: self.kademlia_disjoint_query_paths,
yamux_window_size: None,
ipfs_server: self.ipfs_server,
}
}
}
34 changes: 19 additions & 15 deletions client/db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,20 +448,6 @@ impl<Block: BlockT> BlockchainDb<Block> {
header.digest().log(DigestItem::as_changes_trie_root)
.cloned()))
}

fn extrinsic(&self, hash: &Block::Hash) -> ClientResult<Option<Block::Extrinsic>> {
match self.db.get(columns::TRANSACTION, hash.as_ref()) {
Some(ex) => {
match Decode::decode(&mut &ex[..]) {
Ok(ex) => Ok(Some(ex)),
Err(err) => Err(sp_blockchain::Error::Backend(
format!("Error decoding extrinsic {}: {}", hash, err)
)),
}
},
None => Ok(None),
}
}
}

impl<Block: BlockT> sc_client_api::blockchain::HeaderBackend<Block> for BlockchainDb<Block> {
Expand Down Expand Up @@ -532,7 +518,7 @@ impl<Block: BlockT> sc_client_api::blockchain::Backend<Block> for BlockchainDb<B
match Vec::<Block::Hash>::decode(&mut &body[..]) {
Ok(hashes) => {
let extrinsics: ClientResult<Vec<Block::Extrinsic>> = hashes.into_iter().map(
|h| self.extrinsic(&h) .and_then(|maybe_ex| maybe_ex.ok_or_else(
|h| self.extrinsic(&h).and_then(|maybe_ex| maybe_ex.ok_or_else(
|| sp_blockchain::Error::Backend(
format!("Missing transaction: {}", h))))
).collect();
Expand Down Expand Up @@ -576,6 +562,24 @@ impl<Block: BlockT> sc_client_api::blockchain::Backend<Block> for BlockchainDb<B
fn children(&self, parent_hash: Block::Hash) -> ClientResult<Vec<Block::Hash>> {
children::read_children(&*self.db, columns::META, meta_keys::CHILDREN_PREFIX, parent_hash)
}

fn extrinsic(&self, hash: &Block::Hash) -> ClientResult<Option<Block::Extrinsic>> {
match self.db.get(columns::TRANSACTION, hash.as_ref()) {
Some(ex) => {
match Decode::decode(&mut &ex[..]) {
Ok(ex) => Ok(Some(ex)),
Err(err) => Err(sp_blockchain::Error::Backend(
format!("Error decoding extrinsic {}: {}", hash, err)
)),
}
},
None => Ok(None),
}
}

fn have_extrinsic(&self, hash: &Block::Hash) -> ClientResult<bool> {
Ok(self.db.contains(columns::TRANSACTION, hash.as_ref()))
}
}

impl<Block: BlockT> sc_client_api::blockchain::ProvideCache<Block> for BlockchainDb<Block> {
Expand Down
8 changes: 7 additions & 1 deletion client/db/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,13 @@ pub fn read_meta<Block>(db: &dyn Database<DbHash>, col_header: u32) -> Result<
}
{
let hash = header.hash();
debug!("DB Opened blockchain db, fetched {} = {:?} ({})", desc, hash, header.number());
debug!(
target: "db",
"Opened blockchain db, fetched {} = {:?} ({})",
desc,
hash,
header.number()
);
Ok((hash, *header.number()))
} else {
Ok((genesis_hash.clone(), Zero::zero()))
Expand Down
7 changes: 7 additions & 0 deletions client/light/src/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ impl<S, Block> BlockchainBackend<Block> for Blockchain<S> where Block: BlockT, S
fn children(&self, _parent_hash: Block::Hash) -> ClientResult<Vec<Block::Hash>> {
Err(ClientError::NotAvailableOnLightClient)
}

fn extrinsic(
&self,
_hash: &Block::Hash,
) -> ClientResult<Option<<Block as BlockT>::Extrinsic>> {
Err(ClientError::NotAvailableOnLightClient)
}
}

impl<S: Storage<Block>, Block: BlockT> ProvideCache<Block> for Blockchain<S> {
Expand Down
1 change: 1 addition & 0 deletions client/network/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ async-trait = "0.1"
async-std = "1.6.5"
bitflags = "1.2.0"
bs58 = "0.4.0"
cid = "0.6.0"
bytes = "1"
codec = { package = "parity-scale-codec", version = "2.0.0", features = ["derive"] }
derive_more = "0.99.2"
Expand Down
3 changes: 2 additions & 1 deletion client/network/build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const PROTOS: &[&str] = &[
"src/schema/api.v1.proto",
"src/schema/light.v1.proto"
"src/schema/light.v1.proto",
"src/schema/bitswap.v1.2.0.proto",
];

fn main() {
Expand Down
16 changes: 15 additions & 1 deletion client/network/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

use crate::{
config::{ProtocolId, Role},
bitswap::Bitswap,
discovery::{DiscoveryBehaviour, DiscoveryConfig, DiscoveryOut},
protocol::{message::Roles, CustomMessageOutcome, NotificationsSink, Protocol},
peer_info, request_responses, light_client_requests,
Expand All @@ -30,7 +31,9 @@ use libp2p::NetworkBehaviour;
use libp2p::core::{Multiaddr, PeerId, PublicKey};
use libp2p::identify::IdentifyInfo;
use libp2p::kad::record;
use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters};
use libp2p::swarm::{
NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters, toggle::Toggle
};
use log::debug;
use prost::Message;
use sp_consensus::{BlockOrigin, import_queue::{IncomingBlock, Origin}};
Expand Down Expand Up @@ -59,6 +62,8 @@ pub struct Behaviour<B: BlockT, H: ExHashT> {
peer_info: peer_info::PeerInfoBehaviour,
/// Discovers nodes of the network.
discovery: DiscoveryBehaviour,
/// Bitswap server for blockchain data.
bitswap: Toggle<Bitswap<B>>,
/// Generic request-reponse protocols.
request_responses: request_responses::RequestResponsesBehaviour,

Expand Down Expand Up @@ -181,6 +186,7 @@ impl<B: BlockT, H: ExHashT> Behaviour<B, H> {
light_client_request_sender: light_client_requests::sender::LightClientRequestSender<B>,
disco_config: DiscoveryConfig,
block_request_protocol_config: request_responses::ProtocolConfig,
bitswap: Option<Bitswap<B>>,
light_client_request_protocol_config: request_responses::ProtocolConfig,
// All remaining request protocol configs.
mut request_response_protocols: Vec<request_responses::ProtocolConfig>,
Expand All @@ -195,6 +201,7 @@ impl<B: BlockT, H: ExHashT> Behaviour<B, H> {
substrate,
peer_info: peer_info::PeerInfoBehaviour::new(user_agent, local_public_key),
discovery: disco_config.finish(),
bitswap: bitswap.into(),
request_responses:
request_responses::RequestResponsesBehaviour::new(request_response_protocols.into_iter())?,
light_client_request_sender,
Expand Down Expand Up @@ -299,6 +306,13 @@ fn reported_roles_to_observed_role(local_role: &Role, remote: &PeerId, roles: Ro
}
}

impl<B: BlockT, H: ExHashT> NetworkBehaviourEventProcess<void::Void> for
Behaviour<B, H> {
fn inject_event(&mut self, event: void::Void) {
void::unreachable(event)
}
}

impl<B: BlockT, H: ExHashT> NetworkBehaviourEventProcess<CustomMessageOutcome<B>> for
Behaviour<B, H> {
fn inject_event(&mut self, event: CustomMessageOutcome<B>) {
Expand Down
Loading

0 comments on commit 56c64cf

Please sign in to comment.