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

Storage chains: serve transactions over IPFS/bitswap #7963

Merged
13 commits merged into from
Feb 3, 2021
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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we name the method transaction.
Also wondering if we should comment the fact that in some case do not have result depending on node configuration (in previous pr column 'TRANSACTION' was only optionally use).

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),
}
cheme marked this conversation as resolved.
Show resolved Hide resolved
}

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 @@ -58,6 +61,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>>,
cheme marked this conversation as resolved.
Show resolved Hide resolved
/// Generic request-reponse protocols.
request_responses: request_responses::RequestResponsesBehaviour,

Expand Down Expand Up @@ -180,6 +185,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 @@ -194,6 +200,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 @@ -297,6 +304,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