mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-19 21:41:02 +00:00
Upgrade to libp2p 0.15 (#4732)
* Fixes for libp2p 0.15 * More work * Update libp2p * Update to libp2p 0.15
This commit is contained in:
committed by
Gavin Wood
parent
ed3da9f903
commit
5c8743510e
Generated
+287
-211
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@ codec = { package = "parity-scale-codec", default-features = false, version = "1
|
|||||||
derive_more = "0.99.2"
|
derive_more = "0.99.2"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
futures-timer = "2.0"
|
futures-timer = "2.0"
|
||||||
libp2p = { version = "0.14.0-alpha.1", default-features = false, features = ["secp256k1", "libp2p-websocket"] }
|
libp2p = { version = "0.15.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] }
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
prost = "0.6.1"
|
prost = "0.6.1"
|
||||||
rand = "0.7.2"
|
rand = "0.7.2"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ futures01 = { package = "futures", version = "0.1.29" }
|
|||||||
futures = { version = "0.3.1", features = ["compat"] }
|
futures = { version = "0.3.1", features = ["compat"] }
|
||||||
futures-timer = "0.4.0"
|
futures-timer = "0.4.0"
|
||||||
lru = "0.1.2"
|
lru = "0.1.2"
|
||||||
libp2p = { version = "0.14.0-alpha.1", default-features = false, features = ["libp2p-websocket"] }
|
libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] }
|
||||||
sc-network = { version = "0.8", path = "../network" }
|
sc-network = { version = "0.8", path = "../network" }
|
||||||
parking_lot = "0.9.0"
|
parking_lot = "0.9.0"
|
||||||
sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" }
|
sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" }
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ linked_hash_set = "0.1.3"
|
|||||||
lru = "0.4.0"
|
lru = "0.4.0"
|
||||||
rustc-hex = "2.0.1"
|
rustc-hex = "2.0.1"
|
||||||
rand = "0.7.2"
|
rand = "0.7.2"
|
||||||
libp2p = { version = "0.14.0-alpha.1", default-features = false, features = ["libp2p-websocket"] }
|
libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] }
|
||||||
fork-tree = { version = "2.0.0", path = "../../utils/fork-tree" }
|
fork-tree = { version = "2.0.0", path = "../../utils/fork-tree" }
|
||||||
sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" }
|
sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" }
|
||||||
sc-client = { version = "0.8", path = "../" }
|
sc-client = { version = "0.8", path = "../" }
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ use libp2p::identity::{Keypair, ed25519};
|
|||||||
use libp2p::wasm_ext;
|
use libp2p::wasm_ext;
|
||||||
use libp2p::{PeerId, Multiaddr, multiaddr};
|
use libp2p::{PeerId, Multiaddr, multiaddr};
|
||||||
use core::{fmt, iter};
|
use core::{fmt, iter};
|
||||||
|
use std::{future::Future, pin::Pin};
|
||||||
use std::{error::Error, fs, io::{self, Write}, net::Ipv4Addr, path::{Path, PathBuf}, sync::Arc};
|
use std::{error::Error, fs, io::{self, Write}, net::Ipv4Addr, path::{Path, PathBuf}, sync::Arc};
|
||||||
use zeroize::Zeroize;
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
@@ -40,6 +41,10 @@ pub struct Params<B: BlockT, S, H: ExHashT> {
|
|||||||
/// Assigned roles for our node (full, light, ...).
|
/// Assigned roles for our node (full, light, ...).
|
||||||
pub roles: Roles,
|
pub roles: Roles,
|
||||||
|
|
||||||
|
/// How to spawn background tasks. If you pass `None`, then a threads pool will be used by
|
||||||
|
/// default.
|
||||||
|
pub executor: Option<Box<dyn Fn(Pin<Box<dyn Future<Output = ()> + Send>>) + Send>>,
|
||||||
|
|
||||||
/// Network layer configuration.
|
/// Network layer configuration.
|
||||||
pub network_config: NetworkConfiguration,
|
pub network_config: NetworkConfiguration,
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ impl<TSubstream> DiscoveryBehaviour<TSubstream> {
|
|||||||
allow_private_ipv4,
|
allow_private_ipv4,
|
||||||
#[cfg(not(target_os = "unknown"))]
|
#[cfg(not(target_os = "unknown"))]
|
||||||
mdns: if enable_mdns {
|
mdns: if enable_mdns {
|
||||||
match Mdns::new().await {
|
match Mdns::new() {
|
||||||
Ok(mdns) => Some(mdns).into(),
|
Ok(mdns) => Some(mdns).into(),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(target: "sub-libp2p", "Failed to initialize mDNS: {:?}", err);
|
warn!(target: "sub-libp2p", "Failed to initialize mDNS: {:?}", err);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use super::upgrade::{RegisteredProtocol, RegisteredProtocolEvent, RegisteredProt
|
|||||||
use bytes::BytesMut;
|
use bytes::BytesMut;
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use futures_timer::Delay;
|
use futures_timer::Delay;
|
||||||
use libp2p::core::{ConnectedPoint, PeerId, Endpoint};
|
use libp2p::core::{ConnectedPoint, Negotiated, PeerId, Endpoint};
|
||||||
use libp2p::core::upgrade::{InboundUpgrade, OutboundUpgrade};
|
use libp2p::core::upgrade::{InboundUpgrade, OutboundUpgrade};
|
||||||
use libp2p::swarm::{
|
use libp2p::swarm::{
|
||||||
ProtocolsHandler, ProtocolsHandlerEvent,
|
ProtocolsHandler, ProtocolsHandlerEvent,
|
||||||
@@ -159,7 +159,7 @@ enum ProtocolState<TSubstream> {
|
|||||||
/// Waiting for the behaviour to tell the handler whether it is enabled or disabled.
|
/// Waiting for the behaviour to tell the handler whether it is enabled or disabled.
|
||||||
Init {
|
Init {
|
||||||
/// List of substreams opened by the remote but that haven't been processed yet.
|
/// List of substreams opened by the remote but that haven't been processed yet.
|
||||||
substreams: SmallVec<[RegisteredProtocolSubstream<TSubstream>; 6]>,
|
substreams: SmallVec<[RegisteredProtocolSubstream<Negotiated<TSubstream>>; 6]>,
|
||||||
/// Deadline after which the initialization is abnormally long.
|
/// Deadline after which the initialization is abnormally long.
|
||||||
init_deadline: Delay,
|
init_deadline: Delay,
|
||||||
},
|
},
|
||||||
@@ -175,9 +175,9 @@ enum ProtocolState<TSubstream> {
|
|||||||
/// If we are in this state, we have sent a `CustomProtocolOpen` message to the outside.
|
/// If we are in this state, we have sent a `CustomProtocolOpen` message to the outside.
|
||||||
Normal {
|
Normal {
|
||||||
/// The substreams where bidirectional communications happen.
|
/// The substreams where bidirectional communications happen.
|
||||||
substreams: SmallVec<[RegisteredProtocolSubstream<TSubstream>; 4]>,
|
substreams: SmallVec<[RegisteredProtocolSubstream<Negotiated<TSubstream>>; 4]>,
|
||||||
/// Contains substreams which are being shut down.
|
/// Contains substreams which are being shut down.
|
||||||
shutdown: SmallVec<[RegisteredProtocolSubstream<TSubstream>; 4]>,
|
shutdown: SmallVec<[RegisteredProtocolSubstream<Negotiated<TSubstream>>; 4]>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// We are disabled. Contains substreams that are being closed.
|
/// We are disabled. Contains substreams that are being closed.
|
||||||
@@ -185,7 +185,7 @@ enum ProtocolState<TSubstream> {
|
|||||||
/// outside or we have never sent any `CustomProtocolOpen` in the first place.
|
/// outside or we have never sent any `CustomProtocolOpen` in the first place.
|
||||||
Disabled {
|
Disabled {
|
||||||
/// List of substreams to shut down.
|
/// List of substreams to shut down.
|
||||||
shutdown: SmallVec<[RegisteredProtocolSubstream<TSubstream>; 6]>,
|
shutdown: SmallVec<[RegisteredProtocolSubstream<Negotiated<TSubstream>>; 6]>,
|
||||||
|
|
||||||
/// If true, we should reactivate the handler after all the substreams in `shutdown` have
|
/// If true, we should reactivate the handler after all the substreams in `shutdown` have
|
||||||
/// been closed.
|
/// been closed.
|
||||||
@@ -466,7 +466,7 @@ where
|
|||||||
/// Called by `inject_fully_negotiated_inbound` and `inject_fully_negotiated_outbound`.
|
/// Called by `inject_fully_negotiated_inbound` and `inject_fully_negotiated_outbound`.
|
||||||
fn inject_fully_negotiated(
|
fn inject_fully_negotiated(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut substream: RegisteredProtocolSubstream<TSubstream>
|
mut substream: RegisteredProtocolSubstream<Negotiated<TSubstream>>
|
||||||
) {
|
) {
|
||||||
self.state = match mem::replace(&mut self.state, ProtocolState::Poisoned) {
|
self.state = match mem::replace(&mut self.state, ProtocolState::Poisoned) {
|
||||||
ProtocolState::Poisoned => {
|
ProtocolState::Poisoned => {
|
||||||
@@ -538,14 +538,14 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin {
|
|||||||
|
|
||||||
fn inject_fully_negotiated_inbound(
|
fn inject_fully_negotiated_inbound(
|
||||||
&mut self,
|
&mut self,
|
||||||
proto: <Self::InboundProtocol as InboundUpgrade<TSubstream>>::Output
|
proto: <Self::InboundProtocol as InboundUpgrade<Negotiated<TSubstream>>>::Output
|
||||||
) {
|
) {
|
||||||
self.inject_fully_negotiated(proto);
|
self.inject_fully_negotiated(proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_fully_negotiated_outbound(
|
fn inject_fully_negotiated_outbound(
|
||||||
&mut self,
|
&mut self,
|
||||||
proto: <Self::OutboundProtocol as OutboundUpgrade<TSubstream>>::Output,
|
proto: <Self::OutboundProtocol as OutboundUpgrade<Negotiated<TSubstream>>>::Output,
|
||||||
_: Self::OutboundOpenInfo
|
_: Self::OutboundOpenInfo
|
||||||
) {
|
) {
|
||||||
self.inject_fully_negotiated(proto);
|
self.inject_fully_negotiated(proto);
|
||||||
@@ -621,7 +621,7 @@ where
|
|||||||
/// Given a list of substreams, tries to shut them down. The substreams that have been successfully
|
/// Given a list of substreams, tries to shut them down. The substreams that have been successfully
|
||||||
/// shut down are removed from the list.
|
/// shut down are removed from the list.
|
||||||
fn shutdown_list<TSubstream>
|
fn shutdown_list<TSubstream>
|
||||||
(list: &mut SmallVec<impl smallvec::Array<Item = RegisteredProtocolSubstream<TSubstream>>>,
|
(list: &mut SmallVec<impl smallvec::Array<Item = RegisteredProtocolSubstream<Negotiated<TSubstream>>>>,
|
||||||
cx: &mut Context)
|
cx: &mut Context)
|
||||||
where TSubstream: AsyncRead + AsyncWrite + Unpin {
|
where TSubstream: AsyncRead + AsyncWrite + Unpin {
|
||||||
'outer: for n in (0..list.len()).rev() {
|
'outer: for n in (0..list.len()).rev() {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use crate::config::ProtocolId;
|
|||||||
use bytes::BytesMut;
|
use bytes::BytesMut;
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use futures_codec::Framed;
|
use futures_codec::Framed;
|
||||||
use libp2p::core::{Negotiated, Endpoint, UpgradeInfo, InboundUpgrade, OutboundUpgrade, upgrade::ProtocolName};
|
use libp2p::core::{Endpoint, UpgradeInfo, InboundUpgrade, OutboundUpgrade, upgrade::ProtocolName};
|
||||||
use std::{collections::VecDeque, io, pin::Pin, vec::IntoIter as VecIntoIter};
|
use std::{collections::VecDeque, io, pin::Pin, vec::IntoIter as VecIntoIter};
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use unsigned_varint::codec::UviBytes;
|
use unsigned_varint::codec::UviBytes;
|
||||||
@@ -82,7 +82,7 @@ pub struct RegisteredProtocolSubstream<TSubstream> {
|
|||||||
/// If true, we should call `poll_complete` on the inner sink.
|
/// If true, we should call `poll_complete` on the inner sink.
|
||||||
requires_poll_flush: bool,
|
requires_poll_flush: bool,
|
||||||
/// The underlying substream.
|
/// The underlying substream.
|
||||||
inner: stream::Fuse<Framed<Negotiated<TSubstream>, UviBytes<BytesMut>>>,
|
inner: stream::Fuse<Framed<TSubstream, UviBytes<BytesMut>>>,
|
||||||
/// Version of the protocol that was negotiated.
|
/// Version of the protocol that was negotiated.
|
||||||
protocol_version: u8,
|
protocol_version: u8,
|
||||||
/// If true, we have sent a "remote is clogged" event recently and shouldn't send another one
|
/// If true, we have sent a "remote is clogged" event recently and shouldn't send another one
|
||||||
@@ -250,7 +250,7 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin,
|
|||||||
|
|
||||||
fn upgrade_inbound(
|
fn upgrade_inbound(
|
||||||
self,
|
self,
|
||||||
socket: Negotiated<TSubstream>,
|
socket: TSubstream,
|
||||||
info: Self::Info,
|
info: Self::Info,
|
||||||
) -> Self::Future {
|
) -> Self::Future {
|
||||||
let framed = {
|
let framed = {
|
||||||
@@ -280,7 +280,7 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin,
|
|||||||
|
|
||||||
fn upgrade_outbound(
|
fn upgrade_outbound(
|
||||||
self,
|
self,
|
||||||
socket: Negotiated<TSubstream>,
|
socket: TSubstream,
|
||||||
info: Self::Info,
|
info: Self::Info,
|
||||||
) -> Self::Future {
|
) -> Self::Future {
|
||||||
let framed = Framed::new(socket, UviBytes::default());
|
let framed = Framed::new(socket, UviBytes::default());
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ use futures::{prelude::*, channel::mpsc};
|
|||||||
use log::{warn, error, info, trace};
|
use log::{warn, error, info, trace};
|
||||||
use libp2p::{PeerId, Multiaddr, kad::record};
|
use libp2p::{PeerId, Multiaddr, kad::record};
|
||||||
use libp2p::core::{transport::boxed::Boxed, muxing::StreamMuxerBox};
|
use libp2p::core::{transport::boxed::Boxed, muxing::StreamMuxerBox};
|
||||||
use libp2p::swarm::{NetworkBehaviour, SwarmEvent};
|
use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use sc_peerset::PeersetHandle;
|
use sc_peerset::PeersetHandle;
|
||||||
use sp_runtime::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId};
|
use sp_runtime::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId};
|
||||||
@@ -213,7 +213,7 @@ impl<B: BlockT + 'static, S: NetworkSpecialization<B>, H: ExHashT> NetworkWorker
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Build the swarm.
|
// Build the swarm.
|
||||||
let (mut swarm, bandwidth) = {
|
let (mut swarm, bandwidth): (Swarm::<B, S, H>, _) = {
|
||||||
let user_agent = format!(
|
let user_agent = format!(
|
||||||
"{} ({})",
|
"{} ({})",
|
||||||
params.network_config.client_version,
|
params.network_config.client_version,
|
||||||
@@ -241,7 +241,11 @@ impl<B: BlockT + 'static, S: NetworkSpecialization<B>, H: ExHashT> NetworkWorker
|
|||||||
};
|
};
|
||||||
transport::build_transport(local_identity, config_mem, config_wasm)
|
transport::build_transport(local_identity, config_mem, config_wasm)
|
||||||
};
|
};
|
||||||
(Swarm::<B, S, H>::new(transport, behaviour, local_peer_id.clone()), bandwidth)
|
let mut builder = SwarmBuilder::new(transport, behaviour, local_peer_id.clone());
|
||||||
|
if let Some(spawner) = params.executor {
|
||||||
|
builder = builder.executor_fn(spawner);
|
||||||
|
}
|
||||||
|
(builder.build(), bandwidth)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Listen on multiaddresses.
|
// Listen on multiaddresses.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ futures = "0.1.29"
|
|||||||
futures03 = { package = "futures", version = "0.3.1", features = ["compat"] }
|
futures03 = { package = "futures", version = "0.3.1", features = ["compat"] }
|
||||||
futures-timer = "0.4.0"
|
futures-timer = "0.4.0"
|
||||||
rand = "0.7.2"
|
rand = "0.7.2"
|
||||||
libp2p = { version = "0.14.0-alpha.1", default-features = false, features = ["libp2p-websocket"] }
|
libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] }
|
||||||
sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" }
|
sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" }
|
||||||
sc-client = { version = "0.8", path = "../../" }
|
sc-client = { version = "0.8", path = "../../" }
|
||||||
sc-client-api = { version = "2.0.0", path = "../../api" }
|
sc-client-api = { version = "2.0.0", path = "../../api" }
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ use sc_network::config::{NetworkConfiguration, TransportConfig, BoxFinalityProof
|
|||||||
use libp2p::PeerId;
|
use libp2p::PeerId;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use sp_core::H256;
|
use sp_core::H256;
|
||||||
use sc_network::{Context, ProtocolConfig};
|
use sc_network::ProtocolConfig;
|
||||||
use sp_runtime::generic::{BlockId, OpaqueDigestItemId};
|
use sp_runtime::generic::{BlockId, OpaqueDigestItemId};
|
||||||
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor};
|
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor};
|
||||||
use sp_runtime::Justification;
|
use sp_runtime::Justification;
|
||||||
@@ -613,6 +613,7 @@ pub trait TestNetFactory: Sized {
|
|||||||
|
|
||||||
let network = NetworkWorker::new(sc_network::config::Params {
|
let network = NetworkWorker::new(sc_network::config::Params {
|
||||||
roles: config.roles,
|
roles: config.roles,
|
||||||
|
executor: None,
|
||||||
network_config: NetworkConfiguration {
|
network_config: NetworkConfiguration {
|
||||||
listen_addresses: vec![listen_addr.clone()],
|
listen_addresses: vec![listen_addr.clone()],
|
||||||
transport: TransportConfig::MemoryOnly,
|
transport: TransportConfig::MemoryOnly,
|
||||||
@@ -688,6 +689,7 @@ pub trait TestNetFactory: Sized {
|
|||||||
|
|
||||||
let network = NetworkWorker::new(sc_network::config::Params {
|
let network = NetworkWorker::new(sc_network::config::Params {
|
||||||
roles: config.roles,
|
roles: config.roles,
|
||||||
|
executor: None,
|
||||||
network_config: NetworkConfiguration {
|
network_config: NetworkConfiguration {
|
||||||
listen_addresses: vec![listen_addr.clone()],
|
listen_addresses: vec![listen_addr.clone()],
|
||||||
transport: TransportConfig::MemoryOnly,
|
transport: TransportConfig::MemoryOnly,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
libp2p = { version = "0.14.0-alpha.1", default-features = false }
|
libp2p = { version = "0.15.0", default-features = false }
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
serde_json = "1.0.41"
|
serde_json = "1.0.41"
|
||||||
|
|
||||||
|
|||||||
@@ -837,6 +837,14 @@ ServiceBuilder<
|
|||||||
|
|
||||||
let network_params = sc_network::config::Params {
|
let network_params = sc_network::config::Params {
|
||||||
roles: config.roles,
|
roles: config.roles,
|
||||||
|
executor: {
|
||||||
|
let to_spawn_tx = to_spawn_tx.clone();
|
||||||
|
Some(Box::new(move |fut| {
|
||||||
|
if let Err(e) = to_spawn_tx.unbounded_send(fut) {
|
||||||
|
error!("Failed to spawn libp2p background task: {:?}", e);
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
},
|
||||||
network_config: config.network.clone(),
|
network_config: config.network.clone(),
|
||||||
chain: client.clone(),
|
chain: client.clone(),
|
||||||
finality_proof_provider,
|
finality_proof_provider,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ bytes = "0.5"
|
|||||||
parking_lot = "0.9.0"
|
parking_lot = "0.9.0"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
futures-timer = "2.0.0"
|
futures-timer = "2.0.0"
|
||||||
libp2p = { version = "0.14.0-alpha.1", default-features = false, features = ["libp2p-websocket"] }
|
libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] }
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
pin-project = "0.4.6"
|
pin-project = "0.4.6"
|
||||||
rand = "0.7.2"
|
rand = "0.7.2"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
derive_more = "0.99.2"
|
derive_more = "0.99.2"
|
||||||
libp2p = { version = "0.14.0-alpha.1", default-features = false }
|
libp2p = { version = "0.15.0", default-features = false }
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
sp-core = { path= "../../core" }
|
sp-core = { path= "../../core" }
|
||||||
sp-inherents = { version = "2.0.0", path = "../../inherents" }
|
sp-inherents = { version = "2.0.0", path = "../../inherents" }
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ edition = "2018"
|
|||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
futures01 = { package = "futures", version = "0.1.29" }
|
futures01 = { package = "futures", version = "0.1.29" }
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
libp2p = { version = "0.14.0-alpha.1", default-features = false }
|
libp2p = { version = "0.15.0", default-features = false }
|
||||||
console_error_panic_hook = "0.1.6"
|
console_error_panic_hook = "0.1.6"
|
||||||
console_log = "0.1.2"
|
console_log = "0.1.2"
|
||||||
js-sys = "0.3.34"
|
js-sys = "0.3.34"
|
||||||
|
|||||||
Reference in New Issue
Block a user