Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
parity
Mirrored projects
polkadot
Commits
2f5a915a
Commit
2f5a915a
authored
Mar 26, 2020
by
Cecile Tonglet
Browse files
Update from parent 'origin/master' (conflicts)
Commit:
710f4cae
Parent branch: origin/master Forked at:
77de8b91
parents
9d0facf3
710f4cae
Changes
15
Show whitespace changes
Inline
Side-by-side
Cargo.lock
View file @
2f5a915a
...
@@ -3956,6 +3956,7 @@ dependencies = [
...
@@ -3956,6 +3956,7 @@ dependencies = [
"sp-inherents 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
"sp-inherents 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
"sp-runtime 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
"sp-runtime 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
"sp-serializer 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
"sp-serializer 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
"sp-staking 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
"sp-std 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
"sp-std 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
"sp-trie 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
"sp-trie 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
"sp-version 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
"sp-version 2.0.0-alpha.5 (git+https://github.com/paritytech/substrate)",
...
...
network/src/legacy/gossip/attestation.rs
View file @
2f5a915a
...
@@ -131,9 +131,13 @@ impl View {
...
@@ -131,9 +131,13 @@ impl View {
///
///
/// This will be pruned later on a call to `prune_old_leaves`, when this leaf
/// This will be pruned later on a call to `prune_old_leaves`, when this leaf
/// is not a leaf anymore.
/// is not a leaf anymore.
pub
(
super
)
fn
new_local_leaf
(
&
mut
self
,
relay_chain_leaf
:
Hash
,
validation_data
:
MessageValidationData
)
{
pub
(
super
)
fn
new_local_leaf
(
&
mut
self
,
validation_data
:
MessageValidationData
,
)
{
let
relay_chain_leaf
=
validation_data
.signing_context.parent_hash
.clone
();
self
.leaf_work
.push
((
self
.leaf_work
.push
((
relay_chain_leaf
,
validation_data
.signing_context.parent_hash
.clone
()
,
LeafView
{
LeafView
{
validation_data
,
validation_data
,
knowledge
:
Default
::
default
(),
knowledge
:
Default
::
default
(),
...
@@ -207,7 +211,6 @@ impl View {
...
@@ -207,7 +211,6 @@ impl View {
// validate signature.
// validate signature.
let
res
=
view
.validation_data
.check_statement
(
let
res
=
view
.validation_data
.check_statement
(
&
message
.relay_chain_leaf
,
&
message
.signed_statement
,
&
message
.signed_statement
,
);
);
...
...
network/src/legacy/gossip/mod.rs
View file @
2f5a915a
...
@@ -60,7 +60,7 @@ use sc_network_gossip::{
...
@@ -60,7 +60,7 @@ use sc_network_gossip::{
use
polkadot_validation
::{
SignedStatement
};
use
polkadot_validation
::{
SignedStatement
};
use
polkadot_primitives
::{
Block
,
Hash
};
use
polkadot_primitives
::{
Block
,
Hash
};
use
polkadot_primitives
::
parachain
::{
use
polkadot_primitives
::
parachain
::{
ParachainHost
,
ValidatorId
,
ErasureChunk
as
PrimitiveChunk
ParachainHost
,
ValidatorId
,
ErasureChunk
as
PrimitiveChunk
,
SigningContext
,
};
};
use
polkadot_erasure_coding
::{
self
as
erasure
};
use
polkadot_erasure_coding
::{
self
as
erasure
};
use
codec
::{
Decode
,
Encode
};
use
codec
::{
Decode
,
Encode
};
...
@@ -377,13 +377,12 @@ impl RegisteredMessageValidator {
...
@@ -377,13 +377,12 @@ impl RegisteredMessageValidator {
/// relevant to this leaf.
/// relevant to this leaf.
pub
(
crate
)
fn
new_local_leaf
(
pub
(
crate
)
fn
new_local_leaf
(
&
self
,
&
self
,
relay_chain_leaf
:
Hash
,
validation
:
MessageValidationData
,
validation
:
MessageValidationData
,
)
->
NewLeafActions
{
)
->
NewLeafActions
{
// add an entry in attestation_view
// add an entry in attestation_view
// prune any entries from attestation_view which are no longer leaves
// prune any entries from attestation_view which are no longer leaves
let
mut
inner
=
self
.inner.inner
.write
();
let
mut
inner
=
self
.inner.inner
.write
();
inner
.attestation_view
.new_local_leaf
(
relay_chain_leaf
,
validation
);
inner
.attestation_view
.new_local_leaf
(
validation
);
let
mut
actions
=
Vec
::
new
();
let
mut
actions
=
Vec
::
new
();
...
@@ -460,11 +459,13 @@ impl GossipService for RegisteredMessageValidator {
...
@@ -460,11 +459,13 @@ impl GossipService for RegisteredMessageValidator {
pub
(
crate
)
struct
MessageValidationData
{
pub
(
crate
)
struct
MessageValidationData
{
/// The authorities' parachain validation keys at a block.
/// The authorities' parachain validation keys at a block.
pub
(
crate
)
authorities
:
Vec
<
ValidatorId
>
,
pub
(
crate
)
authorities
:
Vec
<
ValidatorId
>
,
/// The signing context.
pub
(
crate
)
signing_context
:
SigningContext
,
}
}
impl
MessageValidationData
{
impl
MessageValidationData
{
// check a statement's signature.
// check a statement's signature.
fn
check_statement
(
&
self
,
relay_chain_leaf
:
&
Hash
,
statement
:
&
SignedStatement
)
->
Result
<
(),
()
>
{
fn
check_statement
(
&
self
,
statement
:
&
SignedStatement
)
->
Result
<
(),
()
>
{
let
sender
=
match
self
.authorities
.get
(
statement
.sender
as
usize
)
{
let
sender
=
match
self
.authorities
.get
(
statement
.sender
as
usize
)
{
Some
(
val
)
=>
val
,
Some
(
val
)
=>
val
,
None
=>
return
Err
(()),
None
=>
return
Err
(()),
...
@@ -475,7 +476,7 @@ impl MessageValidationData {
...
@@ -475,7 +476,7 @@ impl MessageValidationData {
&
statement
.statement
,
&
statement
.statement
,
&
statement
.signature
,
&
statement
.signature
,
sender
.clone
(),
sender
.clone
(),
relay_chain_leaf
,
&
self
.signing_context
,
);
);
if
good
{
if
good
{
...
@@ -826,7 +827,9 @@ mod tests {
...
@@ -826,7 +827,9 @@ mod tests {
let
topic_c
=
attestation_topic
(
hash_c
);
let
topic_c
=
attestation_topic
(
hash_c
);
// topic_a is in all 3 views -> succeed
// topic_a is in all 3 views -> succeed
validator
.inner
.write
()
.attestation_view
.new_local_leaf
(
hash_a
,
MessageValidationData
::
default
());
let
mut
validation_data
=
MessageValidationData
::
default
();
validation_data
.signing_context.parent_hash
=
hash_a
;
validator
.inner
.write
()
.attestation_view
.new_local_leaf
(
validation_data
);
// topic_b is in the neighbor's view but not ours -> fail
// topic_b is in the neighbor's view but not ours -> fail
// topic_c is not in either -> fail
// topic_c is not in either -> fail
...
@@ -937,7 +940,9 @@ mod tests {
...
@@ -937,7 +940,9 @@ mod tests {
}
}
});
});
let
encoded
=
statement
.encode
();
let
encoded
=
statement
.encode
();
validator
.inner
.write
()
.attestation_view
.new_local_leaf
(
hash_a
,
MessageValidationData
::
default
());
let
mut
validation_data
=
MessageValidationData
::
default
();
validation_data
.signing_context.parent_hash
=
hash_a
;
validator
.inner
.write
()
.attestation_view
.new_local_leaf
(
validation_data
);
{
{
let
mut
message_allowed
=
validator
.message_allowed
();
let
mut
message_allowed
=
validator
.message_allowed
();
...
...
network/src/protocol/mod.rs
View file @
2f5a915a
...
@@ -162,7 +162,6 @@ impl NetworkServiceOps for PolkadotNetworkService {
...
@@ -162,7 +162,6 @@ impl NetworkServiceOps for PolkadotNetworkService {
trait
GossipOps
:
Clone
+
Send
+
crate
::
legacy
::
GossipService
+
'static
{
trait
GossipOps
:
Clone
+
Send
+
crate
::
legacy
::
GossipService
+
'static
{
fn
new_local_leaf
(
fn
new_local_leaf
(
&
self
,
&
self
,
relay_parent
:
Hash
,
validation_data
:
crate
::
legacy
::
gossip
::
MessageValidationData
,
validation_data
:
crate
::
legacy
::
gossip
::
MessageValidationData
,
)
->
crate
::
legacy
::
gossip
::
NewLeafActions
;
)
->
crate
::
legacy
::
gossip
::
NewLeafActions
;
...
@@ -177,10 +176,12 @@ trait GossipOps: Clone + Send + crate::legacy::GossipService + 'static {
...
@@ -177,10 +176,12 @@ trait GossipOps: Clone + Send + crate::legacy::GossipService + 'static {
impl
GossipOps
for
RegisteredMessageValidator
{
impl
GossipOps
for
RegisteredMessageValidator
{
fn
new_local_leaf
(
fn
new_local_leaf
(
&
self
,
&
self
,
relay_parent
:
Hash
,
validation_data
:
crate
::
legacy
::
gossip
::
MessageValidationData
,
validation_data
:
crate
::
legacy
::
gossip
::
MessageValidationData
,
)
->
crate
::
legacy
::
gossip
::
NewLeafActions
{
)
->
crate
::
legacy
::
gossip
::
NewLeafActions
{
RegisteredMessageValidator
::
new_local_leaf
(
self
,
relay_parent
,
validation_data
)
RegisteredMessageValidator
::
new_local_leaf
(
self
,
validation_data
,
)
}
}
fn
register_availability_store
(
fn
register_availability_store
(
...
@@ -804,7 +805,6 @@ impl<Api, Sp, Gossip> Worker<Api, Sp, Gossip> where
...
@@ -804,7 +805,6 @@ impl<Api, Sp, Gossip> Worker<Api, Sp, Gossip> where
authorities
:
Vec
<
ValidatorId
>
,
authorities
:
Vec
<
ValidatorId
>
,
)
{
)
{
// glue: let gossip know about our new local leaf.
// glue: let gossip know about our new local leaf.
let
relay_parent
=
table
.consensus_parent_hash
()
.clone
();
let
(
signal
,
exit
)
=
exit_future
::
signal
();
let
(
signal
,
exit
)
=
exit_future
::
signal
();
let
key
=
table
.session_key
();
let
key
=
table
.session_key
();
...
@@ -814,19 +814,20 @@ impl<Api, Sp, Gossip> Worker<Api, Sp, Gossip> where
...
@@ -814,19 +814,20 @@ impl<Api, Sp, Gossip> Worker<Api, Sp, Gossip> where
}
}
}
}
let
signing_context
=
table
.signing_context
()
.clone
();
let
relay_parent
=
signing_context
.parent_hash
.clone
();
let
new_leaf_actions
=
self
.gossip_handle
.new_local_leaf
(
let
new_leaf_actions
=
self
.gossip_handle
.new_local_leaf
(
relay_parent
,
crate
::
legacy
::
gossip
::
MessageValidationData
{
authorities
,
signing_context
},
crate
::
legacy
::
gossip
::
MessageValidationData
{
authorities
},
);
);
new_leaf_actions
.perform
(
&
self
.gossip_handle
);
new_leaf_actions
.perform
(
&
self
.gossip_handle
);
self
.protocol_handler.consensus_instances
.insert
(
self
.protocol_handler.consensus_instances
.insert
(
relay_parent
,
relay_parent
.clone
()
,
ConsensusNetworkingInstance
{
ConsensusNetworkingInstance
{
statement_table
:
table
.clone
(),
statement_table
:
table
.clone
(),
relay_parent
,
relay_parent
:
relay_parent
.clone
()
,
attestation_topic
:
crate
::
legacy
::
gossip
::
attestation_topic
(
relay_parent
),
attestation_topic
:
crate
::
legacy
::
gossip
::
attestation_topic
(
relay_parent
.clone
()
),
_drop_signal
:
signal
,
_drop_signal
:
signal
,
},
},
);
);
...
@@ -1324,7 +1325,7 @@ impl ParachainNetwork for Service {
...
@@ -1324,7 +1325,7 @@ impl ParachainNetwork for Service {
)
->
Self
::
BuildTableRouter
{
)
->
Self
::
BuildTableRouter
{
let
authorities
=
authorities
.to_vec
();
let
authorities
=
authorities
.to_vec
();
let
mut
sender
=
self
.sender
.clone
();
let
mut
sender
=
self
.sender
.clone
();
let
relay_parent
=
table
.
consensus_
parent_hash
()
.clone
();
let
relay_parent
=
table
.
signing_context
()
.
parent_hash
.clone
();
Box
::
pin
(
async
move
{
Box
::
pin
(
async
move
{
sender
.send
(
sender
.send
(
...
...
network/src/protocol/tests.rs
View file @
2f5a915a
...
@@ -20,7 +20,7 @@ use polkadot_primitives::{Block, Header, BlockId};
...
@@ -20,7 +20,7 @@ use polkadot_primitives::{Block, Header, BlockId};
use
polkadot_primitives
::
parachain
::{
use
polkadot_primitives
::
parachain
::{
Id
as
ParaId
,
Chain
,
DutyRoster
,
ParachainHost
,
ValidatorId
,
Id
as
ParaId
,
Chain
,
DutyRoster
,
ParachainHost
,
ValidatorId
,
Retriable
,
CollatorId
,
AbridgedCandidateReceipt
,
Retriable
,
CollatorId
,
AbridgedCandidateReceipt
,
GlobalValidationSchedule
,
LocalValidationData
,
ErasureChunk
,
GlobalValidationSchedule
,
LocalValidationData
,
ErasureChunk
,
SigningContext
,
};
};
use
polkadot_validation
::
SharedTable
;
use
polkadot_validation
::
SharedTable
;
...
@@ -114,7 +114,6 @@ impl crate::legacy::GossipService for MockGossip {
...
@@ -114,7 +114,6 @@ impl crate::legacy::GossipService for MockGossip {
impl
GossipOps
for
MockGossip
{
impl
GossipOps
for
MockGossip
{
fn
new_local_leaf
(
fn
new_local_leaf
(
&
self
,
&
self
,
_relay_parent
:
Hash
,
_validation_data
:
crate
::
legacy
::
gossip
::
MessageValidationData
,
_validation_data
:
crate
::
legacy
::
gossip
::
MessageValidationData
,
)
->
crate
::
legacy
::
gossip
::
NewLeafActions
{
)
->
crate
::
legacy
::
gossip
::
NewLeafActions
{
crate
::
legacy
::
gossip
::
NewLeafActions
::
new
()
crate
::
legacy
::
gossip
::
NewLeafActions
::
new
()
...
@@ -294,6 +293,22 @@ impl ParachainHost<Block> for RuntimeApi {
...
@@ -294,6 +293,22 @@ impl ParachainHost<Block> for RuntimeApi {
)
->
ClientResult
<
NativeOrEncoded
<
Option
<
Vec
<
AbridgedCandidateReceipt
>>>>
{
)
->
ClientResult
<
NativeOrEncoded
<
Option
<
Vec
<
AbridgedCandidateReceipt
>>>>
{
Ok
(
NativeOrEncoded
::
Native
(
Some
(
Vec
::
new
())))
Ok
(
NativeOrEncoded
::
Native
(
Some
(
Vec
::
new
())))
}
}
fn
ParachainHost_signing_context_runtime_api_impl
(
&
self
,
_at
:
&
BlockId
,
_
:
ExecutionContext
,
_
:
Option
<
()
>
,
_
:
Vec
<
u8
>
,
)
->
ClientResult
<
NativeOrEncoded
<
SigningContext
>>
{
Ok
(
NativeOrEncoded
::
Native
(
SigningContext
{
session_index
:
Default
::
default
(),
parent_hash
:
Default
::
default
(),
}
)
)
}
}
}
impl
super
::
Service
{
impl
super
::
Service
{
...
@@ -389,11 +404,15 @@ fn consensus_instances_cleaned_up() {
...
@@ -389,11 +404,15 @@ fn consensus_instances_cleaned_up() {
let
relay_parent
=
[
0
;
32
]
.into
();
let
relay_parent
=
[
0
;
32
]
.into
();
let
authorities
=
Vec
::
new
();
let
authorities
=
Vec
::
new
();
let
signing_context
=
SigningContext
{
session_index
:
Default
::
default
(),
parent_hash
:
relay_parent
,
};
let
table
=
Arc
::
new
(
SharedTable
::
new
(
let
table
=
Arc
::
new
(
SharedTable
::
new
(
Vec
::
new
(),
Vec
::
new
(),
HashMap
::
new
(),
HashMap
::
new
(),
None
,
None
,
relay_paren
t
,
signing_contex
t
,
AvailabilityStore
::
new_in_memory
(
service
.clone
()),
AvailabilityStore
::
new_in_memory
(
service
.clone
()),
None
,
None
,
));
));
...
...
primitives/Cargo.toml
View file @
2f5a915a
...
@@ -13,6 +13,7 @@ application-crypto = { package = "sp-application-crypto", git = "https://github.
...
@@ -13,6 +13,7 @@ application-crypto = { package = "sp-application-crypto", git = "https://github.
sp-api
=
{
git
=
"https://github.com/paritytech/substrate"
,
branch
=
"cecton-the-revenge-of-the-cli"
,
default-features
=
false
}
sp-api
=
{
git
=
"https://github.com/paritytech/substrate"
,
branch
=
"cecton-the-revenge-of-the-cli"
,
default-features
=
false
}
sp-version
=
{
git
=
"https://github.com/paritytech/substrate"
,
branch
=
"cecton-the-revenge-of-the-cli"
,
default-features
=
false
}
sp-version
=
{
git
=
"https://github.com/paritytech/substrate"
,
branch
=
"cecton-the-revenge-of-the-cli"
,
default-features
=
false
}
sp-std
=
{
package
=
"sp-std"
,
git
=
"https://github.com/paritytech/substrate"
,
branch
=
"cecton-the-revenge-of-the-cli"
,
default-features
=
false
}
sp-std
=
{
package
=
"sp-std"
,
git
=
"https://github.com/paritytech/substrate"
,
branch
=
"cecton-the-revenge-of-the-cli"
,
default-features
=
false
}
sp-staking
=
{
git
=
"https://github.com/paritytech/substrate"
,
branch
=
"cecton-the-revenge-of-the-cli"
,
default-features
=
false
}
runtime_primitives
=
{
package
=
"sp-runtime"
,
git
=
"https://github.com/paritytech/substrate"
,
branch
=
"cecton-the-revenge-of-the-cli"
,
default-features
=
false
}
runtime_primitives
=
{
package
=
"sp-runtime"
,
git
=
"https://github.com/paritytech/substrate"
,
branch
=
"cecton-the-revenge-of-the-cli"
,
default-features
=
false
}
polkadot-parachain
=
{
path
=
"../parachain"
,
default-features
=
false
}
polkadot-parachain
=
{
path
=
"../parachain"
,
default-features
=
false
}
trie
=
{
package
=
"sp-trie"
,
git
=
"https://github.com/paritytech/substrate"
,
branch
=
"cecton-the-revenge-of-the-cli"
,
default-features
=
false
}
trie
=
{
package
=
"sp-trie"
,
git
=
"https://github.com/paritytech/substrate"
,
branch
=
"cecton-the-revenge-of-the-cli"
,
default-features
=
false
}
...
@@ -33,6 +34,7 @@ std = [
...
@@ -33,6 +34,7 @@ std = [
"sp-api/std"
,
"sp-api/std"
,
"sp-std/std"
,
"sp-std/std"
,
"sp-version/std"
,
"sp-version/std"
,
"sp-staking/std"
,
"runtime_primitives/std"
,
"runtime_primitives/std"
,
"serde"
,
"serde"
,
"polkadot-parachain/std"
,
"polkadot-parachain/std"
,
...
...
primitives/src/parachain.rs
View file @
2f5a915a
...
@@ -608,6 +608,15 @@ pub enum ValidityAttestation {
...
@@ -608,6 +608,15 @@ pub enum ValidityAttestation {
Explicit
(
ValidatorSignature
),
Explicit
(
ValidatorSignature
),
}
}
/// A type returned by runtime with current session index and a parent hash.
#[derive(Clone,
Eq,
PartialEq,
Default,
Decode,
Encode,
RuntimeDebug)]
pub
struct
SigningContext
{
/// Current session index.
pub
session_index
:
sp_staking
::
SessionIndex
,
/// Hash of the parent.
pub
parent_hash
:
Hash
,
}
/// An attested candidate. This is submitted to the relay chain by a block author.
/// An attested candidate. This is submitted to the relay chain by a block author.
#[derive(Clone,
PartialEq,
Decode,
Encode,
RuntimeDebug)]
#[derive(Clone,
PartialEq,
Decode,
Encode,
RuntimeDebug)]
pub
struct
AttestedCandidate
{
pub
struct
AttestedCandidate
{
...
@@ -655,7 +664,7 @@ impl FeeSchedule {
...
@@ -655,7 +664,7 @@ impl FeeSchedule {
sp_api
::
decl_runtime_apis!
{
sp_api
::
decl_runtime_apis!
{
/// The API for querying the state of parachains on-chain.
/// The API for querying the state of parachains on-chain.
#[api_version(
2
)]
#[api_version(
3
)]
pub
trait
ParachainHost
{
pub
trait
ParachainHost
{
/// Get the current validators.
/// Get the current validators.
fn
validators
()
->
Vec
<
ValidatorId
>
;
fn
validators
()
->
Vec
<
ValidatorId
>
;
...
@@ -673,6 +682,8 @@ sp_api::decl_runtime_apis! {
...
@@ -673,6 +682,8 @@ sp_api::decl_runtime_apis! {
/// Extract the abridged head that was set in the extrinsics.
/// Extract the abridged head that was set in the extrinsics.
fn
get_heads
(
extrinsics
:
Vec
<<
Block
as
BlockT
>
::
Extrinsic
>
)
fn
get_heads
(
extrinsics
:
Vec
<<
Block
as
BlockT
>
::
Extrinsic
>
)
->
Option
<
Vec
<
AbridgedCandidateReceipt
>>
;
->
Option
<
Vec
<
AbridgedCandidateReceipt
>>
;
/// Get a `SigningContext` with current `SessionIndex` and parent hash.
fn
signing_context
()
->
SigningContext
;
}
}
}
}
...
...
runtime/common/src/parachains.rs
View file @
2f5a915a
...
@@ -44,7 +44,7 @@ use primitives::{
...
@@ -44,7 +44,7 @@ use primitives::{
UpwardMessage
,
ValidatorId
,
ActiveParas
,
CollatorId
,
Retriable
,
OmittedValidationData
,
UpwardMessage
,
ValidatorId
,
ActiveParas
,
CollatorId
,
Retriable
,
OmittedValidationData
,
CandidateReceipt
,
GlobalValidationSchedule
,
AbridgedCandidateReceipt
,
CandidateReceipt
,
GlobalValidationSchedule
,
AbridgedCandidateReceipt
,
LocalValidationData
,
ValidityAttestation
,
NEW_HEADS_IDENTIFIER
,
PARACHAIN_KEY_TYPE_ID
,
LocalValidationData
,
ValidityAttestation
,
NEW_HEADS_IDENTIFIER
,
PARACHAIN_KEY_TYPE_ID
,
ValidatorSignature
,
ValidatorSignature
,
SigningContext
,
},
},
};
};
use
frame_support
::{
use
frame_support
::{
...
@@ -121,7 +121,7 @@ pub struct ValidatorIdentities<T>(sp_std::marker::PhantomData<T>);
...
@@ -121,7 +121,7 @@ pub struct ValidatorIdentities<T>(sp_std::marker::PhantomData<T>);
/// `Hash` - a type of a hash used in the runtime.
/// `Hash` - a type of a hash used in the runtime.
#[derive(RuntimeDebug,
Encode,
Decode)]
#[derive(RuntimeDebug,
Encode,
Decode)]
#[derive(Clone,
Eq,
PartialEq)]
#[derive(Clone,
Eq,
PartialEq)]
pub
struct
DoubleVoteReport
<
Proof
,
Hash
>
{
pub
struct
DoubleVoteReport
<
Proof
>
{
/// Identity of the double-voter.
/// Identity of the double-voter.
pub
identity
:
ValidatorId
,
pub
identity
:
ValidatorId
,
/// First vote of the double-vote.
/// First vote of the double-vote.
...
@@ -130,11 +130,11 @@ pub struct DoubleVoteReport<Proof, Hash> {
...
@@ -130,11 +130,11 @@ pub struct DoubleVoteReport<Proof, Hash> {
pub
second
:
(
Statement
,
ValidatorSignature
),
pub
second
:
(
Statement
,
ValidatorSignature
),
/// Proof that the validator with `identity` id was actually a validator at `parent_hash`.
/// Proof that the validator with `identity` id was actually a validator at `parent_hash`.
pub
proof
:
Proof
,
pub
proof
:
Proof
,
///
P
arent hash of the
block
this offence was commited.
///
A `SigningContext` with a session and a p
arent hash of the
moment
this offence was commited.
pub
parent_hash
:
Hash
,
pub
signing_context
:
SigningContext
,
}
}
impl
<
Proof
:
Parameter
+
GetSessionNumber
,
Hash
:
AsRef
<
[
u8
]
>
>
DoubleVoteReport
<
Proof
,
Hash
>
{
impl
<
Proof
:
Parameter
+
GetSessionNumber
>
DoubleVoteReport
<
Proof
>
{
fn
verify
<
T
:
Trait
<
Proof
=
Proof
>>
(
fn
verify
<
T
:
Trait
<
Proof
=
Proof
>>
(
&
self
,
&
self
,
)
->
Result
<
(),
DoubleVoteValidityError
>
{
)
->
Result
<
(),
DoubleVoteValidityError
>
{
...
@@ -145,9 +145,21 @@ impl<Proof: Parameter + GetSessionNumber, Hash: AsRef<[u8]>> DoubleVoteReport<Pr
...
@@ -145,9 +145,21 @@ impl<Proof: Parameter + GetSessionNumber, Hash: AsRef<[u8]>> DoubleVoteReport<Pr
T
::
KeyOwnerProofSystem
::
check_proof
((
PARACHAIN_KEY_TYPE_ID
,
id
),
self
.proof
.clone
())
T
::
KeyOwnerProofSystem
::
check_proof
((
PARACHAIN_KEY_TYPE_ID
,
id
),
self
.proof
.clone
())
.ok_or
(
DoubleVoteValidityError
::
InvalidProof
)
?
;
.ok_or
(
DoubleVoteValidityError
::
InvalidProof
)
?
;
if
self
.proof
.session
()
!=
self
.signing_context.session_index
{
return
Err
(
DoubleVoteValidityError
::
InvalidReport
);
}
// Check signatures.
// Check signatures.
Self
::
verify_vote
(
&
first
,
&
self
.parent_hash
,
&
self
.identity
)
?
;
Self
::
verify_vote
(
Self
::
verify_vote
(
&
second
,
&
self
.parent_hash
,
&
self
.identity
)
?
;
&
first
,
&
self
.signing_context
,
&
self
.identity
,
)
?
;
Self
::
verify_vote
(
&
second
,
&
self
.signing_context
,
&
self
.identity
,
)
?
;
match
(
&
first
.0
,
&
second
.0
)
{
match
(
&
first
.0
,
&
second
.0
)
{
// If issuing a `Candidate` message on a parachain block, neither a `Valid` or
// If issuing a `Candidate` message on a parachain block, neither a `Valid` or
...
@@ -173,10 +185,10 @@ impl<Proof: Parameter + GetSessionNumber, Hash: AsRef<[u8]>> DoubleVoteReport<Pr
...
@@ -173,10 +185,10 @@ impl<Proof: Parameter + GetSessionNumber, Hash: AsRef<[u8]>> DoubleVoteReport<Pr
fn
verify_vote
(
fn
verify_vote
(
vote
:
&
(
Statement
,
ValidatorSignature
),
vote
:
&
(
Statement
,
ValidatorSignature
),
parent_hash
:
&
Hash
,
signing_context
:
&
SigningContext
,
authority
:
&
ValidatorId
,
authority
:
&
ValidatorId
,
)
->
Result
<
(),
DoubleVoteValidityError
>
{
)
->
Result
<
(),
DoubleVoteValidityError
>
{
let
payload
=
localized_payload
(
vote
.0
.clone
(),
parent_hash
);
let
payload
=
localized_payload
(
vote
.0
.clone
(),
signing_context
);
if
!
vote
.1
.verify
(
&
payload
[
..
],
authority
)
{
if
!
vote
.1
.verify
(
&
payload
[
..
],
authority
)
{
return
Err
(
DoubleVoteValidityError
::
InvalidSignature
);
return
Err
(
DoubleVoteValidityError
::
InvalidSignature
);
...
@@ -203,7 +215,7 @@ impl GetSessionNumber for session::historical::Proof {
...
@@ -203,7 +215,7 @@ impl GetSessionNumber for session::historical::Proof {
}
}
}
}
pub
trait
Trait
:
attestations
::
Trait
+
session
::
historical
::
Trait
+
staking
::
Trait
{
pub
trait
Trait
:
attestations
::
Trait
+
session
::
historical
::
Trait
{
/// The outer origin type.
/// The outer origin type.
type
Origin
:
From
<
Origin
>
+
From
<
system
::
RawOrigin
<
Self
::
AccountId
>>
;
type
Origin
:
From
<
Origin
>
+
From
<
system
::
RawOrigin
<
Self
::
AccountId
>>
;
...
@@ -253,6 +265,9 @@ pub trait Trait: attestations::Trait + session::historical::Trait + staking::Tra
...
@@ -253,6 +265,9 @@ pub trait Trait: attestations::Trait + session::historical::Trait + staking::Tra
Self
::
IdentificationTuple
,
Self
::
IdentificationTuple
,
DoubleVoteOffence
<
Self
::
IdentificationTuple
>
DoubleVoteOffence
<
Self
::
IdentificationTuple
>
>
;
>
;
/// A type that converts the opaque hash type to exact one.
type
BlockHashConversion
:
Convert
<
Self
::
Hash
,
primitives
::
Hash
>
;
}
}
/// Origin for the parachains module.
/// Origin for the parachains module.
...
@@ -332,18 +347,6 @@ decl_storage! {
...
@@ -332,18 +347,6 @@ decl_storage! {
///
///
/// `None` if not yet updated.
/// `None` if not yet updated.
pub
DidUpdate
:
Option
<
Vec
<
ParaId
>>
;
pub
DidUpdate
:
Option
<
Vec
<
ParaId
>>
;
/// The mapping from parent block hashes to session indexes.
///
/// Used for double vote report validation.
pub
ParentToSessionIndex
get
(
fn
session_at_block
):
map
hasher
(
twox_64_concat
)
T
::
Hash
=>
SessionIndex
;
/// The era that is active currently.
///
/// Changes with the `ActiveEra` from `staking`. Upon these changes `ParentToSessionIndex`
/// is pruned.
ActiveEra
get
(
fn
active_era
):
Option
<
staking
::
EraIndex
>
;
}
}
add_extra_genesis
{
add_extra_genesis
{
config
(
authorities
):
Vec
<
ValidatorId
>
;
config
(
authorities
):
Vec
<
ValidatorId
>
;
...
@@ -484,7 +487,6 @@ decl_module! {
...
@@ -484,7 +487,6 @@ decl_module! {
origin
,
origin
,
report
:
DoubleVoteReport
<
report
:
DoubleVoteReport
<
<
T
::
KeyOwnerProofSystem
as
KeyOwnerProofSystem
<
(
KeyTypeId
,
Vec
<
u8
>
)
>>
::
Proof
,
<
T
::
KeyOwnerProofSystem
as
KeyOwnerProofSystem
<
(
KeyTypeId
,
Vec
<
u8
>
)
>>
::
Proof
,
T
::
Hash
,
>
,
>
,
)
->
DispatchResult
{
)
->
DispatchResult
{
let
reporter
=
ensure_signed
(
origin
)
?
;
let
reporter
=
ensure_signed
(
origin
)
?
;
...
@@ -519,26 +521,6 @@ decl_module! {
...
@@ -519,26 +521,6 @@ decl_module! {
fn
on_initialize
()
->
Weight
{
fn
on_initialize
()
->
Weight
{
<
Self
as
Store
>
::
DidUpdate
::
kill
();
<
Self
as
Store
>
::
DidUpdate
::
kill
();
let
current_session
=
<
session
::
Module
<
T
>>
::
current_index
();
let
parent_hash
=
<
system
::
Module
<
T
>>
::
parent_hash
();
match
Self
::
active_era
()
{
Some
(
era
)
=>
{
if
let
Some
(
active_era
)
=
<
staking
::
Module
<
T
>>
::
current_era
()
{
if
era
!=
active_era
{
<
Self
as
Store
>
::
ActiveEra
::
put
(
active_era
);
<
ParentToSessionIndex
<
T
>>
::
remove_all
();
}
}
}
None
=>
{
if
let
Some
(
active_era
)
=
<
staking
::
Module
<
T
>>
::
current_era
()
{
<
Self
as
Store
>
::
ActiveEra
::
set
(
Some
(
active_era
));
}
}
}
<
ParentToSessionIndex
<
T
>>
::
insert
(
parent_hash
,
current_session
);
SimpleDispatchInfo
::
default
()
.weigh_data
(())
SimpleDispatchInfo
::
default
()
.weigh_data
(())
}
}
...
@@ -552,9 +534,12 @@ fn majority_of(list_len: usize) -> usize {
...
@@ -552,9 +534,12 @@ fn majority_of(list_len: usize) -> usize {
list_len
/
2
+
list_len
%
2
list_len
/
2
+
list_len
%
2
}
}
fn
localized_payload
<
H
:
AsRef
<
[
u8
]
>>
(
statement
:
Statement
,
parent_hash
:
H
)
->
Vec
<
u8
>
{
fn
localized_payload
(
statement
:
Statement
,
signing_context
:
&
SigningContext
,
)
->
Vec
<
u8
>
{
let
mut
encoded
=
statement
.encode
();
let
mut
encoded
=
statement
.encode
();
encoded
.extend
(
parent_hash
.as_ref
(
));
signing_context
.using_encoded
(|
s
|
encoded
.extend
(
s
));
encoded
encoded