Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ddorgan
polkadot
Commits
4cb0346c
Commit
4cb0346c
authored
Dec 03, 2019
by
Arkadiy Paronyan
Committed by
Gavin Wood
Dec 03, 2019
Browse files
Update for new peerset API (#644)
* Reputation changes require reason * Fixes * Bump version
parent
e0a7e280
Changes
23
Expand all
Hide whitespace changes
Inline
Side-by-side
Cargo.lock
View file @
4cb0346c
This diff is collapsed.
Click to expand it.
Cargo.toml
View file @
4cb0346c
...
...
@@ -4,7 +4,7 @@ path = "src/main.rs"
[package]
name
=
"polkadot"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
build
=
"build.rs"
edition
=
"2018"
...
...
availability-store/Cargo.toml
View file @
4cb0346c
[package]
name
=
"polkadot-availability-store"
description
=
"Persistent database for parachain data"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
edition
=
"2018"
...
...
cli/Cargo.toml
View file @
4cb0346c
[package]
name
=
"polkadot-cli"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
description
=
"Polkadot node implementation in Rust."
edition
=
"2018"
...
...
collator/Cargo.toml
View file @
4cb0346c
[package]
name
=
"polkadot-collator"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
description
=
"Collator node implementation"
edition
=
"2018"
...
...
erasure-coding/Cargo.toml
View file @
4cb0346c
[package]
name
=
"polkadot-erasure-coding"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
edition
=
"2018"
...
...
executor/Cargo.toml
View file @
4cb0346c
[package]
name
=
"polkadot-executor"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
description
=
"Polkadot node implementation in Rust."
edition
=
"2018"
...
...
network/Cargo.toml
View file @
4cb0346c
[package]
name
=
"polkadot-network"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
description
=
"Polkadot-specific networking protocol"
edition
=
"2018"
...
...
network/src/gossip.rs
View file @
4cb0346c
...
...
@@ -51,7 +51,7 @@
use
sp_runtime
::{
generic
::
BlockId
,
traits
::
ProvideRuntimeApi
};
use
sp_blockchain
::
Error
as
ClientError
;
use
sc_network
::{
config
::
Roles
,
PeerId
};
use
sc_network
::{
config
::
Roles
,
PeerId
,
ReputationChange
};
use
sc_network
::
consensus_gossip
::{
self
as
network_gossip
,
ValidationResult
as
GossipValidationResult
,
ValidatorContext
,
MessageIntent
,
ConsensusMessage
,
...
...
@@ -87,35 +87,39 @@ pub(crate) const MAX_CHAIN_HEADS: usize = 5;
pub
type
LeavesVec
=
ArrayVec
<
[
Hash
;
MAX_CHAIN_HEADS
]
>
;
mod
benefit
{
use
sc_network
::
ReputationChange
as
Rep
;
/// When a peer sends us a previously-unknown candidate statement.
pub
const
NEW_CANDIDATE
:
i32
=
100
;
pub
const
NEW_CANDIDATE
:
Rep
=
Rep
::
new
(
100
,
"Polkadot: New candidate"
)
;
/// When a peer sends us a previously-unknown attestation.
pub
const
NEW_ATTESTATION
:
i32
=
50
;
pub
const
NEW_ATTESTATION
:
Rep
=
Rep
::
new
(
50
,
"Polkadot: New attestation"
)
;
/// When a peer sends us a previously-unknown message packet.
pub
const
NEW_ICMP_MESSAGES
:
i32
=
50
;
pub
const
NEW_ICMP_MESSAGES
:
Rep
=
Rep
::
new
(
50
,
"Polkadot: New ICMP messages"
)
;
}
mod
cost
{
use
sc_network
::
ReputationChange
as
Rep
;
/// No cost. This will not be reported.
pub
const
NONE
:
Rep
=
Rep
::
new
(
0
,
""
);
/// A peer sent us an attestation and we don't know the candidate.
pub
const
ATTESTATION_NO_CANDIDATE
:
i32
=
-
100
;
pub
const
ATTESTATION_NO_CANDIDATE
:
Rep
=
Rep
::
new
(
-
100
,
"Polkadot: No candidate"
)
;
/// A peer sent us a statement we consider in the future.
pub
const
FUTURE_MESSAGE
:
i32
=
-
100
;
pub
const
FUTURE_MESSAGE
:
Rep
=
Rep
::
new
(
-
100
,
"Polkadot: Future message"
)
;
/// A peer sent us a statement from the past.
pub
const
PAST_MESSAGE
:
i32
=
-
30
;
pub
const
PAST_MESSAGE
:
Rep
=
Rep
::
new
(
-
30
,
"Polkadot: Past message"
)
;
/// A peer sent us a malformed message.
pub
const
MALFORMED_MESSAGE
:
i32
=
-
500
;
pub
const
MALFORMED_MESSAGE
:
Rep
=
Rep
::
new
(
-
500
,
"Polkadot: Malformed message"
)
;
/// A peer sent us a wrongly signed message.
pub
const
BAD_SIGNATURE
:
i32
=
-
500
;
pub
const
BAD_SIGNATURE
:
Rep
=
Rep
::
new
(
-
500
,
"Polkadot: Bad signature"
)
;
/// A peer sent us a bad neighbor packet.
pub
const
BAD_NEIGHBOR_PACKET
:
i32
=
-
300
;
pub
const
BAD_NEIGHBOR_PACKET
:
Rep
=
Rep
::
new
(
-
300
,
"Polkadot: Bad neighbor"
)
;
/// A peer sent us an ICMP queue we haven't advertised a need for.
pub
const
UNNEEDED_ICMP_MESSAGES
:
i32
=
-
100
;
pub
const
UNNEEDED_ICMP_MESSAGES
:
Rep
=
Rep
::
new
(
-
100
,
"Polkadot: Unexpected ICMP message"
)
;
/// A peer sent us an ICMP queue with a bad root.
pub
fn
icmp_messages_root_mismatch
(
n_messages
:
usize
)
->
i32
{
pub
fn
icmp_messages_root_mismatch
(
n_messages
:
usize
)
->
Rep
{
const
PER_MESSAGE
:
i32
=
-
150
;
(
0
..
n_messages
)
.map
(|
_
|
PER_MESSAGE
)
.sum
()
Rep
::
new
(
(
0
..
n_messages
)
.map
(|
_
|
PER_MESSAGE
)
.sum
()
,
"Polkadot: ICMP root mismatch"
)
}
}
...
...
@@ -288,8 +292,10 @@ pub fn register_validator<C: ChainContext + 'static>(
)
->
RegisteredMessageValidator
{
let
s
=
service
.clone
();
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cost_benefit
|
{
s
.report_peer
(
peer
.clone
(),
cost_benefit
);
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cost_benefit
:
ReputationChange
|
{
if
cost_benefit
.value
!=
0
{
s
.report_peer
(
peer
.clone
(),
cost_benefit
);
}
});
let
validator
=
Arc
::
new
(
MessageValidator
{
report_handle
,
...
...
@@ -355,7 +361,7 @@ impl RegisteredMessageValidator {
#[cfg(test)]
pub
(
crate
)
fn
new_test
<
C
:
ChainContext
+
'static
>
(
chain
:
C
,
report_handle
:
Box
<
dyn
Fn
(
&
PeerId
,
i32
)
+
Send
+
Sync
>
,
report_handle
:
Box
<
dyn
Fn
(
&
PeerId
,
ReputationChange
)
+
Send
+
Sync
>
,
)
->
Self
{
let
validator
=
Arc
::
new
(
MessageValidator
::
new_test
(
chain
,
report_handle
));
...
...
@@ -474,7 +480,7 @@ struct Inner<C: ?Sized> {
impl
<
C
:
?
Sized
+
ChainContext
>
Inner
<
C
>
{
fn
validate_neighbor_packet
(
&
mut
self
,
sender
:
&
PeerId
,
packet
:
NeighborPacket
)
->
(
GossipValidationResult
<
Hash
>
,
i32
,
Vec
<
Hash
>
)
->
(
GossipValidationResult
<
Hash
>
,
ReputationChange
,
Vec
<
Hash
>
)
{
let
chain_heads
=
packet
.chain_heads
;
if
chain_heads
.len
()
>
MAX_CHAIN_HEADS
{
...
...
@@ -494,7 +500,7 @@ impl<C: ?Sized + ChainContext> Inner<C> {
Vec
::
new
()
};
(
GossipValidationResult
::
Discard
,
0
,
new_topics
)
(
GossipValidationResult
::
Discard
,
cost
::
NONE
,
new_topics
)
}
}
...
...
@@ -514,7 +520,7 @@ impl<C: ?Sized + ChainContext> Inner<C> {
/// An unregistered message validator. Register this with `register_validator`.
pub
struct
MessageValidator
<
C
:
?
Sized
>
{
report_handle
:
Box
<
dyn
Fn
(
&
PeerId
,
i32
)
+
Send
+
Sync
>
,
report_handle
:
Box
<
dyn
Fn
(
&
PeerId
,
ReputationChange
)
+
Send
+
Sync
>
,
inner
:
RwLock
<
Inner
<
C
>>
,
}
...
...
@@ -522,7 +528,7 @@ impl<C: ChainContext + ?Sized> MessageValidator<C> {
#[cfg(test)]
fn
new_test
(
chain
:
C
,
report_handle
:
Box
<
dyn
Fn
(
&
PeerId
,
i32
)
+
Send
+
Sync
>
,
report_handle
:
Box
<
dyn
Fn
(
&
PeerId
,
ReputationChange
)
+
Send
+
Sync
>
,
)
->
Self
where
C
:
Sized
{
MessageValidator
{
report_handle
,
...
...
@@ -535,7 +541,7 @@ impl<C: ChainContext + ?Sized> MessageValidator<C> {
}
}
fn
report
(
&
self
,
who
:
&
PeerId
,
cost_benefit
:
i32
)
{
fn
report
(
&
self
,
who
:
&
PeerId
,
cost_benefit
:
ReputationChange
)
{
(
self
.report_handle
)(
who
,
cost_benefit
)
}
}
...
...
@@ -720,7 +726,7 @@ mod tests {
fn
message_allowed
()
{
let
(
tx
,
_rx
)
=
mpsc
::
channel
();
let
tx
=
Mutex
::
new
(
tx
);
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
i32
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
ReputationChange
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
validator
=
MessageValidator
::
new_test
(
TestChainContext
::
default
(),
report_handle
,
...
...
@@ -803,7 +809,7 @@ mod tests {
fn
too_many_chain_heads_is_report
()
{
let
(
tx
,
rx
)
=
mpsc
::
channel
();
let
tx
=
Mutex
::
new
(
tx
);
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
i32
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
ReputationChange
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
validator
=
MessageValidator
::
new_test
(
TestChainContext
::
default
(),
report_handle
,
...
...
@@ -845,7 +851,7 @@ mod tests {
fn
statement_only_sent_when_candidate_known
()
{
let
(
tx
,
_rx
)
=
mpsc
::
channel
();
let
tx
=
Mutex
::
new
(
tx
);
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
i32
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
ReputationChange
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
validator
=
MessageValidator
::
new_test
(
TestChainContext
::
default
(),
report_handle
,
...
...
@@ -922,7 +928,7 @@ mod tests {
fn
multicasts_icmp_queues_when_building_on_new_leaf
()
{
let
(
tx
,
_rx
)
=
mpsc
::
channel
();
let
tx
=
Mutex
::
new
(
tx
);
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
i32
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
ReputationChange
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
hash_a
=
[
1u8
;
32
]
.into
();
let
root_a
=
[
11u8
;
32
]
.into
();
...
...
@@ -1017,7 +1023,7 @@ mod tests {
fn
multicasts_icmp_queues_on_neighbor_update
()
{
let
(
tx
,
_rx
)
=
mpsc
::
channel
();
let
tx
=
Mutex
::
new
(
tx
);
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
i32
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
ReputationChange
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
hash_a
=
[
1u8
;
32
]
.into
();
let
root_a
=
[
11u8
;
32
]
.into
();
...
...
@@ -1128,7 +1134,7 @@ mod tests {
fn
accepts_needed_unknown_icmp_message_queue
()
{
let
(
tx
,
_rx
)
=
mpsc
::
channel
();
let
tx
=
Mutex
::
new
(
tx
);
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
i32
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
ReputationChange
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
hash_a
=
[
1u8
;
32
]
.into
();
let
root_a_messages
=
vec!
[
...
...
network/src/gossip/attestation.rs
View file @
4cb0346c
...
...
@@ -31,6 +31,7 @@
//! consider an infinite amount of attestations produced by a misbehaving validator.
use
sc_network
::
consensus_gossip
::{
ValidationResult
as
GossipValidationResult
};
use
sc_network
::
ReputationChange
;
use
polkadot_validation
::
GenericStatement
;
use
polkadot_primitives
::
Hash
;
...
...
@@ -39,7 +40,9 @@ use std::collections::{HashMap, HashSet};
use
log
::
warn
;
use
crate
::
router
::
attestation_topic
;
use
super
::{
cost
,
benefit
,
MAX_CHAIN_HEADS
,
LeavesVec
,
ChainContext
,
Known
,
MessageValidationData
,
GossipStatement
};
use
super
::{
cost
,
benefit
,
MAX_CHAIN_HEADS
,
LeavesVec
,
ChainContext
,
Known
,
MessageValidationData
,
GossipStatement
};
// knowledge about attestations on a single parent-hash.
#[derive(Default)]
...
...
@@ -170,7 +173,7 @@ impl View {
message
:
GossipStatement
,
chain
:
&
C
,
)
->
(
GossipValidationResult
<
Hash
>
,
i32
)
->
(
GossipValidationResult
<
Hash
>
,
ReputationChange
)
{
// message must reference one of our chain heads and
// if message is not a `Candidate` we should have the candidate available
...
...
@@ -184,8 +187,7 @@ impl View {
"Leaf block {} not considered live for attestation"
,
message
.relay_chain_leaf
,
);
0
cost
::
NONE
}
Some
(
Known
::
Old
)
=>
cost
::
PAST_MESSAGE
,
_
=>
cost
::
FUTURE_MESSAGE
,
...
...
network/src/gossip/message_routing.rs
View file @
4cb0346c
...
...
@@ -133,7 +133,7 @@ impl View {
/// Validate an incoming message queue against this view. If it is accepted
/// by our view of un-routed message queues, we will keep and re-propagate.
pub
fn
validate_queue_and_note_known
(
&
mut
self
,
messages
:
&
super
::
GossipParachainMessages
)
->
(
GossipValidationResult
<
Hash
>
,
i32
)
->
(
GossipValidationResult
<
Hash
>
,
sc_network
::
ReputationChange
)
{
let
ostensible_topic
=
queue_topic
(
messages
.queue_root
);
match
self
.expected_queues
.get_mut
(
&
ostensible_topic
)
{
...
...
network/src/lib.rs
View file @
4cb0346c
...
...
@@ -54,23 +54,26 @@ use crate::gossip::{POLKADOT_ENGINE_ID, GossipMessage};
mod
tests
;
mod
cost
{
pub
(
super
)
const
UNEXPECTED_MESSAGE
:
i32
=
-
200
;
pub
(
super
)
const
INVALID_FORMAT
:
i32
=
-
200
;
pub
(
super
)
const
UNKNOWN_PEER
:
i32
=
-
50
;
pub
(
super
)
const
COLLATOR_ALREADY_KNOWN
:
i32
=
-
100
;
pub
(
super
)
const
BAD_COLLATION
:
i32
=
-
1000
;
pub
(
super
)
const
BAD_POV_BLOCK
:
i32
=
-
1000
;
use
sc_network
::
ReputationChange
as
Rep
;
pub
(
super
)
const
UNEXPECTED_MESSAGE
:
Rep
=
Rep
::
new
(
-
200
,
"Polkadot: Unexpected message"
);
pub
(
super
)
const
UNEXPECTED_ROLE
:
Rep
=
Rep
::
new
(
-
200
,
"Polkadot: Unexpected role"
);
pub
(
super
)
const
INVALID_FORMAT
:
Rep
=
Rep
::
new
(
-
200
,
"Polkadot: Bad message"
);
pub
(
super
)
const
UNKNOWN_PEER
:
Rep
=
Rep
::
new
(
-
50
,
"Polkadot: Unknown peer"
);
pub
(
super
)
const
COLLATOR_ALREADY_KNOWN
:
Rep
=
Rep
::
new
(
-
100
,
"Polkadot: Known collator"
);
pub
(
super
)
const
BAD_COLLATION
:
Rep
=
Rep
::
new
(
-
1000
,
"Polkadot: Bad collation"
);
pub
(
super
)
const
BAD_POV_BLOCK
:
Rep
=
Rep
::
new
(
-
1000
,
"Polkadot: Bad POV block"
);
}
mod
benefit
{
pub
(
super
)
const
EXPECTED_MESSAGE
:
i32
=
20
;
pub
(
super
)
const
VALID_FORMAT
:
i32
=
20
;
pub
(
super
)
const
KNOWN_PEER
:
i32
=
5
;
pub
(
super
)
const
NEW_COLLATOR
:
i32
=
10
;
pub
(
super
)
const
GOOD_COLLATION
:
i32
=
100
;
pub
(
super
)
const
GOOD_POV_BLOCK
:
i32
=
100
;
use
sc_network
::
ReputationChange
as
Rep
;
pub
(
super
)
const
EXPECTED_MESSAGE
:
Rep
=
Rep
::
new
(
20
,
"Polkadot: Expected message"
);
pub
(
super
)
const
VALID_FORMAT
:
Rep
=
Rep
::
new
(
20
,
"Polkadot: Valid message format"
);
pub
(
super
)
const
KNOWN_PEER
:
Rep
=
Rep
::
new
(
5
,
"Polkadot: Known peer"
);
pub
(
super
)
const
NEW_COLLATOR
:
Rep
=
Rep
::
new
(
10
,
"Polkadot: New collator"
);
pub
(
super
)
const
GOOD_COLLATION
:
Rep
=
Rep
::
new
(
100
,
"Polkadot: Good collation"
);
pub
(
super
)
const
GOOD_POV_BLOCK
:
Rep
=
Rep
::
new
(
100
,
"Polkadot: Good POV block"
);
}
type
FullStatus
=
GenericFullStatus
<
Block
>
;
...
...
@@ -553,7 +556,7 @@ impl PolkadotProtocol {
debug!
(
target
:
"p_net"
,
"New collator role {:?} from {}"
,
role
,
who
);
if
info
.validator_keys
.as_slice
()
.is_empty
()
{
ctx
.report_peer
(
who
,
cost
::
UNEXPECTED_
MESSAG
E
)
;
ctx
.report_peer
(
who
,
cost
::
UNEXPECTED_
ROL
E
)
}
else
{
// update role for all saved session keys for this validator.
let
local_collations
=
&
mut
self
.local_collations
;
...
...
network/src/tests/mod.rs
View file @
4cb0346c
...
...
@@ -29,7 +29,7 @@ use polkadot_primitives::parachain::{
use
sp_core
::
crypto
::
UncheckedInto
;
use
codec
::
Encode
;
use
sc_network
::{
PeerId
,
Context
,
config
::
Roles
,
message
::
generic
::
ConsensusMessage
,
PeerId
,
Context
,
ReputationChange
,
config
::
Roles
,
message
::
generic
::
ConsensusMessage
,
specialization
::
NetworkSpecialization
,
};
...
...
@@ -46,8 +46,8 @@ struct TestContext {
}
impl
Context
<
Block
>
for
TestContext
{
fn
report_peer
(
&
mut
self
,
peer
:
PeerId
,
reputation
:
i32
)
{
let
reputation
=
self
.reputations
.get
(
&
peer
)
.map_or
(
reputation
,
|
v
|
v
+
reputation
);
fn
report_peer
(
&
mut
self
,
peer
:
PeerId
,
reputation
:
ReputationChange
)
{
let
reputation
=
self
.reputations
.get
(
&
peer
)
.map_or
(
reputation
.value
,
|
v
|
v
+
reputation
.value
);
self
.reputations
.insert
(
peer
.clone
(),
reputation
);
match
reputation
{
...
...
parachain/Cargo.toml
View file @
4cb0346c
[package]
name
=
"polkadot-parachain"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
description
=
"Types and utilities for creating and working with parachains"
edition
=
"2018"
...
...
primitives/Cargo.toml
View file @
4cb0346c
[package]
name
=
"polkadot-primitives"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
edition
=
"2018"
...
...
rpc/Cargo.toml
View file @
4cb0346c
[package]
name
=
"polkadot-rpc"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
edition
=
"2018"
...
...
runtime/Cargo.toml
View file @
4cb0346c
[package]
name
=
"polkadot-runtime"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
edition
=
"2018"
build
=
"build.rs"
...
...
runtime/src/lib.rs
View file @
4cb0346c
...
...
@@ -97,7 +97,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name
:
create_runtime_str!
(
"kusama"
),
impl_name
:
create_runtime_str!
(
"parity-kusama"
),
authoring_version
:
2
,
spec_version
:
102
4
,
spec_version
:
102
5
,
impl_version
:
0
,
apis
:
RUNTIME_API_VERSIONS
,
};
...
...
service/Cargo.toml
View file @
4cb0346c
[package]
name
=
"polkadot-service"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
edition
=
"2018"
...
...
statement-table/Cargo.toml
View file @
4cb0346c
[package]
name
=
"polkadot-statement-table"
version
=
"0.7.
3
"
version
=
"0.7.
4
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
edition
=
"2018"
...
...
Prev
1
2
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment