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
b0c90ce6
Commit
b0c90ce6
authored
Apr 02, 2020
by
Cecile Tonglet
Browse files
Update from parent 'origin/master' (no conflict)
Commit:
639dfd67
Parent branch: origin/master Forked at:
77de8b91
parents
194a9d92
639dfd67
Changes
31
Expand all
Show whitespace changes
Inline
Side-by-side
Cargo.lock
View file @
b0c90ce6
This diff is collapsed.
Click to expand it.
Cargo.toml
View file @
b0c90ce6
...
@@ -4,7 +4,7 @@ path = "src/main.rs"
...
@@ -4,7 +4,7 @@ path = "src/main.rs"
[package]
[package]
name
=
"polkadot"
name
=
"polkadot"
version
=
"0.7.2
8
"
version
=
"0.7.2
9-pre1
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
authors
=
[
"Parity Technologies <admin@parity.io>"
]
build
=
"build.rs"
build
=
"build.rs"
edition
=
"2018"
edition
=
"2018"
...
...
availability-store/Cargo.toml
View file @
b0c90ce6
[package]
[package]
name
=
"polkadot-availability-store"
name
=
"polkadot-availability-store"
description
=
"Persistent database for parachain data"
description
=
"Persistent database for parachain data"
version
=
"0.7.2
8
"
version
=
"0.7.2
9-pre1
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
authors
=
[
"Parity Technologies <admin@parity.io>"
]
edition
=
"2018"
edition
=
"2018"
...
...
cli/Cargo.toml
View file @
b0c90ce6
[package]
[package]
name
=
"polkadot-cli"
name
=
"polkadot-cli"
version
=
"0.7.2
8
"
version
=
"0.7.2
9-pre1
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
authors
=
[
"Parity Technologies <admin@parity.io>"
]
description
=
"Polkadot Relay-chain Client Node"
description
=
"Polkadot Relay-chain Client Node"
edition
=
"2018"
edition
=
"2018"
...
...
collator/Cargo.toml
View file @
b0c90ce6
[package]
[package]
name
=
"polkadot-collator"
name
=
"polkadot-collator"
version
=
"0.7.2
8
"
version
=
"0.7.2
9-pre1
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
authors
=
[
"Parity Technologies <admin@parity.io>"
]
description
=
"Collator node implementation"
description
=
"Collator node implementation"
edition
=
"2018"
edition
=
"2018"
...
...
erasure-coding/Cargo.toml
View file @
b0c90ce6
[package]
[package]
name
=
"polkadot-erasure-coding"
name
=
"polkadot-erasure-coding"
version
=
"0.7.2
8
"
version
=
"0.7.2
9-pre1
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
authors
=
[
"Parity Technologies <admin@parity.io>"
]
edition
=
"2018"
edition
=
"2018"
...
...
network/Cargo.toml
View file @
b0c90ce6
[package]
[package]
name
=
"polkadot-network"
name
=
"polkadot-network"
version
=
"0.7.2
8
"
version
=
"0.7.2
9-pre1
"
authors
=
[
"Parity Technologies <admin@parity.io>"
]
authors
=
[
"Parity Technologies <admin@parity.io>"
]
description
=
"Polkadot-specific networking protocol"
description
=
"Polkadot-specific networking protocol"
edition
=
"2018"
edition
=
"2018"
...
...
network/src/legacy/gossip/attestation.rs
View file @
b0c90ce6
...
@@ -35,7 +35,7 @@ use sc_network::ReputationChange;
...
@@ -35,7 +35,7 @@ use sc_network::ReputationChange;
use
polkadot_validation
::
GenericStatement
;
use
polkadot_validation
::
GenericStatement
;
use
polkadot_primitives
::
Hash
;
use
polkadot_primitives
::
Hash
;
use
std
::
collections
::
{
HashMap
,
HashSet
}
;
use
std
::
collections
::
HashMap
;
use
log
::
warn
;
use
log
::
warn
;
...
@@ -44,22 +44,34 @@ use super::{
...
@@ -44,22 +44,34 @@ use super::{
ChainContext
,
Known
,
MessageValidationData
,
GossipStatement
,
ChainContext
,
Known
,
MessageValidationData
,
GossipStatement
,
};
};
/// Meta-data that we keep about a candidate in the `Knowledge`.
#[derive(Debug,
Clone)]
pub
(
super
)
struct
CandidateMeta
{
/// The hash of the pov-block data.
pub
(
super
)
pov_block_hash
:
Hash
,
}
// knowledge about attestations on a single parent-hash.
// knowledge about attestations on a single parent-hash.
#[derive(Default)]
#[derive(Default)]
pub
(
super
)
struct
Knowledge
{
pub
(
super
)
struct
Knowledge
{
candidates
:
Hash
Set
<
Hash
>
,
candidates
:
Hash
Map
<
Hash
,
CandidateMeta
>
,
}
}
impl
Knowledge
{
impl
Knowledge
{
// whether the peer is aware of a candidate with given hash.
// whether the peer is aware of a candidate with given hash.
fn
is_aware_of
(
&
self
,
candidate_hash
:
&
Hash
)
->
bool
{
fn
is_aware_of
(
&
self
,
candidate_hash
:
&
Hash
)
->
bool
{
self
.candidates
.contains
(
candidate_hash
)
self
.candidates
.contains_key
(
candidate_hash
)
}
// Get candidate meta data for a candidate by hash.
fn
candidate_meta
(
&
self
,
candidate_hash
:
&
Hash
)
->
Option
<&
CandidateMeta
>
{
self
.candidates
.get
(
candidate_hash
)
}
}
// note that the peer is aware of a candidate with given hash. this should
// note that the peer is aware of a candidate with given hash. this should
// be done after observing an incoming candidate message via gossip.
// be done after observing an incoming candidate message via gossip.
fn
note_aware
(
&
mut
self
,
candidate_hash
:
Hash
)
{
fn
note_aware
(
&
mut
self
,
candidate_hash
:
Hash
,
candidate_meta
:
CandidateMeta
)
{
self
.candidates
.insert
(
candidate_hash
);
self
.candidates
.insert
(
candidate_hash
,
candidate_meta
);
}
}
}
}
...
@@ -84,9 +96,14 @@ impl PeerData {
...
@@ -84,9 +96,14 @@ impl PeerData {
}
}
#[cfg(test)]
#[cfg(test)]
pub
(
super
)
fn
note_aware_under_leaf
(
&
mut
self
,
relay_chain_leaf
:
&
Hash
,
candidate_hash
:
Hash
)
{
pub
(
super
)
fn
note_aware_under_leaf
(
&
mut
self
,
relay_chain_leaf
:
&
Hash
,
candidate_hash
:
Hash
,
meta
:
CandidateMeta
,
)
{
if
let
Some
(
knowledge
)
=
self
.live
.get_mut
(
relay_chain_leaf
)
{
if
let
Some
(
knowledge
)
=
self
.live
.get_mut
(
relay_chain_leaf
)
{
knowledge
.note_aware
(
candidate_hash
);
knowledge
.note_aware
(
candidate_hash
,
meta
);
}
}
}
}
...
@@ -144,6 +161,7 @@ impl View {
...
@@ -144,6 +161,7 @@ impl View {
},
},
));
));
self
.topics
.insert
(
attestation_topic
(
relay_chain_leaf
),
relay_chain_leaf
);
self
.topics
.insert
(
attestation_topic
(
relay_chain_leaf
),
relay_chain_leaf
);
self
.topics
.insert
(
super
::
pov_block_topic
(
relay_chain_leaf
),
relay_chain_leaf
);
}
}
/// Prune old leaf-work that fails the leaf predicate.
/// Prune old leaf-work that fails the leaf predicate.
...
@@ -164,6 +182,17 @@ impl View {
...
@@ -164,6 +182,17 @@ impl View {
self
.topics
.get
(
topic
)
self
.topics
.get
(
topic
)
}
}
#[cfg(test)]
pub
(
super
)
fn
note_aware_under_leaf
(
&
mut
self
,
relay_chain_leaf
:
&
Hash
,
candidate_hash
:
Hash
,
meta
:
CandidateMeta
,
)
{
if
let
Some
(
view
)
=
self
.leaf_view_mut
(
relay_chain_leaf
)
{
view
.knowledge
.note_aware
(
candidate_hash
,
meta
);
}
}
/// Validate the signature on an attestation statement of some kind. Should be done before
/// Validate the signature on an attestation statement of some kind. Should be done before
/// any repropagation of that statement.
/// any repropagation of that statement.
...
@@ -225,15 +254,59 @@ impl View {
...
@@ -225,15 +254,59 @@ impl View {
}
}
}
}
/// Validate a pov-block message.
pub
(
super
)
fn
validate_pov_block_message
<
C
:
ChainContext
+
?
Sized
>
(
&
mut
self
,
message
:
&
super
::
GossipPoVBlock
,
chain
:
&
C
,
)
->
(
GossipValidationResult
<
Hash
>
,
ReputationChange
)
{
match
self
.leaf_view
(
&
message
.relay_chain_leaf
)
{
None
=>
{
let
cost
=
match
chain
.is_known
(
&
message
.relay_chain_leaf
)
{
Some
(
Known
::
Leaf
)
=>
{
warn!
(
target
:
"network"
,
"Leaf block {} not considered live for attestation"
,
message
.relay_chain_leaf
,
);
cost
::
NONE
}
Some
(
Known
::
Old
)
=>
cost
::
POV_BLOCK_UNWANTED
,
_
=>
cost
::
FUTURE_MESSAGE
,
};
(
GossipValidationResult
::
Discard
,
cost
)
}
Some
(
view
)
=>
{
// we only accept pov-blocks for candidates that we have
// and consider active.
match
view
.knowledge
.candidate_meta
(
&
message
.candidate_hash
)
{
None
=>
(
GossipValidationResult
::
Discard
,
cost
::
POV_BLOCK_UNWANTED
),
Some
(
meta
)
=>
{
// check that the pov-block hash is actually correct.
if
meta
.pov_block_hash
==
message
.pov_block
.hash
()
{
let
topic
=
super
::
pov_block_topic
(
message
.relay_chain_leaf
);
(
GossipValidationResult
::
ProcessAndKeep
(
topic
),
benefit
::
NEW_POV_BLOCK
)
}
else
{
(
GossipValidationResult
::
Discard
,
cost
::
POV_BLOCK_BAD_DATA
)
}
}
}
}
}
}
/// whether it's allowed to send a statement to a peer with given knowledge
/// whether it's allowed to send a statement to a peer with given knowledge
/// about the relay parent the statement refers to.
/// about the relay parent the statement refers to.
pub
(
super
)
fn
statement_allowed
(
pub
(
super
)
fn
statement_allowed
(
&
mut
self
,
&
mut
self
,
statement
:
&
GossipStatement
,
statement
:
&
GossipStatement
,
relay_chain_leaf
:
&
Hash
,
peer_knowledge
:
&
mut
Knowledge
,
peer_knowledge
:
&
mut
Knowledge
,
)
->
bool
{
)
->
bool
{
let
signed
=
&
statement
.signed_statement
;
let
signed
=
&
statement
.signed_statement
;
let
relay_chain_leaf
=
&
statement
.relay_chain_leaf
;
match
signed
.statement
{
match
signed
.statement
{
GenericStatement
::
Valid
(
ref
h
)
|
GenericStatement
::
Invalid
(
ref
h
)
=>
{
GenericStatement
::
Valid
(
ref
h
)
|
GenericStatement
::
Invalid
(
ref
h
)
=>
{
...
@@ -245,9 +318,10 @@ impl View {
...
@@ -245,9 +318,10 @@ impl View {
// if we are sending a `Candidate` message we should make sure that
// if we are sending a `Candidate` message we should make sure that
// attestation_view and their_view reflects that we know about the candidate.
// attestation_view and their_view reflects that we know about the candidate.
let
hash
=
c
.hash
();
let
hash
=
c
.hash
();
peer_knowledge
.note_aware
(
hash
);
let
meta
=
CandidateMeta
{
pov_block_hash
:
c
.pov_block_hash
};
peer_knowledge
.note_aware
(
hash
,
meta
.clone
());
if
let
Some
(
attestation_view
)
=
self
.leaf_view_mut
(
&
relay_chain_leaf
)
{
if
let
Some
(
attestation_view
)
=
self
.leaf_view_mut
(
&
relay_chain_leaf
)
{
attestation_view
.knowledge
.note_aware
(
hash
);
attestation_view
.knowledge
.note_aware
(
hash
,
meta
);
}
}
// at this point, the peer hasn't seen the message or the candidate
// at this point, the peer hasn't seen the message or the candidate
...
@@ -256,6 +330,15 @@ impl View {
...
@@ -256,6 +330,15 @@ impl View {
}
}
}
}
}
}
/// whether it's allowed to send a pov-block to a peer.
pub
(
super
)
fn
pov_block_allowed
(
&
mut
self
,
statement
:
&
super
::
GossipPoVBlock
,
peer_knowledge
:
&
mut
Knowledge
,
)
->
bool
{
peer_knowledge
.is_aware_of
(
&
statement
.candidate_hash
)
}
}
}
struct
LeafView
{
struct
LeafView
{
...
...
network/src/legacy/gossip/mod.rs
View file @
b0c90ce6
...
@@ -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
,
SigningContext
,
ParachainHost
,
ValidatorId
,
ErasureChunk
as
PrimitiveChunk
,
SigningContext
,
PoVBlock
,
};
};
use
polkadot_erasure_coding
::{
self
as
erasure
};
use
polkadot_erasure_coding
::{
self
as
erasure
};
use
codec
::{
Decode
,
Encode
};
use
codec
::{
Decode
,
Encode
};
...
@@ -95,6 +95,8 @@ mod benefit {
...
@@ -95,6 +95,8 @@ mod benefit {
pub
const
NEW_CANDIDATE
:
Rep
=
Rep
::
new
(
100
,
"Polkadot: New candidate"
);
pub
const
NEW_CANDIDATE
:
Rep
=
Rep
::
new
(
100
,
"Polkadot: New candidate"
);
/// When a peer sends us a previously-unknown attestation.
/// When a peer sends us a previously-unknown attestation.
pub
const
NEW_ATTESTATION
:
Rep
=
Rep
::
new
(
50
,
"Polkadot: New attestation"
);
pub
const
NEW_ATTESTATION
:
Rep
=
Rep
::
new
(
50
,
"Polkadot: New attestation"
);
/// When a peer sends us a previously-unknown pov-block
pub
const
NEW_POV_BLOCK
:
Rep
=
Rep
::
new
(
150
,
"Polkadot: New PoV block"
);
/// When a peer sends us a previously-unknown erasure chunk.
/// When a peer sends us a previously-unknown erasure chunk.
pub
const
NEW_ERASURE_CHUNK
:
Rep
=
Rep
::
new
(
10
,
"Polkadot: New erasure chunk"
);
pub
const
NEW_ERASURE_CHUNK
:
Rep
=
Rep
::
new
(
10
,
"Polkadot: New erasure chunk"
);
}
}
...
@@ -105,6 +107,10 @@ mod cost {
...
@@ -105,6 +107,10 @@ mod cost {
pub
const
NONE
:
Rep
=
Rep
::
new
(
0
,
""
);
pub
const
NONE
:
Rep
=
Rep
::
new
(
0
,
""
);
/// A peer sent us an attestation and we don't know the candidate.
/// A peer sent us an attestation and we don't know the candidate.
pub
const
ATTESTATION_NO_CANDIDATE
:
Rep
=
Rep
::
new
(
-
100
,
"Polkadot: No candidate"
);
pub
const
ATTESTATION_NO_CANDIDATE
:
Rep
=
Rep
::
new
(
-
100
,
"Polkadot: No candidate"
);
/// A peer sent us a pov-block and we don't know the candidate or the leaf.
pub
const
POV_BLOCK_UNWANTED
:
Rep
=
Rep
::
new
(
-
500
,
"Polkadot: No candidate"
);
/// A peer sent us a pov-block message with wrong data.
pub
const
POV_BLOCK_BAD_DATA
:
Rep
=
Rep
::
new
(
-
1000
,
"Polkadot: Bad PoV-block data"
);
/// A peer sent us a statement we consider in the future.
/// A peer sent us a statement we consider in the future.
pub
const
FUTURE_MESSAGE
:
Rep
=
Rep
::
new
(
-
100
,
"Polkadot: Future message"
);
pub
const
FUTURE_MESSAGE
:
Rep
=
Rep
::
new
(
-
100
,
"Polkadot: Future message"
);
/// A peer sent us a statement from the past.
/// A peer sent us a statement from the past.
...
@@ -135,6 +141,9 @@ pub enum GossipMessage {
...
@@ -135,6 +141,9 @@ pub enum GossipMessage {
/// A packet containing one of the erasure-coding chunks of one candidate.
/// A packet containing one of the erasure-coding chunks of one candidate.
#[codec(index
=
"3"
)]
#[codec(index
=
"3"
)]
ErasureChunk
(
ErasureChunkMessage
),
ErasureChunk
(
ErasureChunkMessage
),
/// A PoV-block.
#[codec(index
=
"255"
)]
PoVBlock
(
GossipPoVBlock
),
}
}
impl
From
<
NeighborPacket
>
for
GossipMessage
{
impl
From
<
NeighborPacket
>
for
GossipMessage
{
...
@@ -149,6 +158,12 @@ impl From<GossipStatement> for GossipMessage {
...
@@ -149,6 +158,12 @@ impl From<GossipStatement> for GossipMessage {
}
}
}
}
impl
From
<
GossipPoVBlock
>
for
GossipMessage
{
fn
from
(
pov
:
GossipPoVBlock
)
->
Self
{
GossipMessage
::
PoVBlock
(
pov
)
}
}
/// A gossip message containing a statement.
/// A gossip message containing a statement.
#[derive(Encode,
Decode,
Clone,
PartialEq)]
#[derive(Encode,
Decode,
Clone,
PartialEq)]
pub
struct
GossipStatement
{
pub
struct
GossipStatement
{
...
@@ -185,15 +200,18 @@ impl From<ErasureChunkMessage> for GossipMessage {
...
@@ -185,15 +200,18 @@ impl From<ErasureChunkMessage> for GossipMessage {
}
}
}
}
/// A packet of messages from one parachain to another.
/// A pov-block being gossipped. Should only be sent to peers aware of the candidate
///
/// referenced.
/// These are all the messages posted from one parachain to another during the
#[derive(Encode,
Decode,
Clone,
Debug,
PartialEq)]
/// execution of a single parachain block. Since this parachain block may have been
pub
struct
GossipPoVBlock
{
/// included in many forks of the relay chain, there is no relay-chain leaf parameter.
/// The block hash of the relay chain being referred to. In context, this should
#[derive(Encode,
Decode,
Clone,
PartialEq)]
/// be a leaf.
pub
struct
GossipParachainMessages
{
pub
relay_chain_leaf
:
Hash
,
/// The root of the message queue.
/// The hash of some candidate localized to the same relay-chain leaf, whose
pub
queue_root
:
Hash
,
/// pov-block is this block.
pub
candidate_hash
:
Hash
,
/// The pov-block itself.
pub
pov_block
:
PoVBlock
,
}
}
/// A versioned neighbor message.
/// A versioned neighbor message.
...
@@ -262,6 +280,14 @@ pub(crate) fn attestation_topic(parent_hash: Hash) -> Hash {
...
@@ -262,6 +280,14 @@ pub(crate) fn attestation_topic(parent_hash: Hash) -> Hash {
BlakeTwo256
::
hash
(
&
v
[
..
])
BlakeTwo256
::
hash
(
&
v
[
..
])
}
}
/// Compute the gossip topic for PoV blocks based on the given parent hash.
pub
(
crate
)
fn
pov_block_topic
(
parent_hash
:
Hash
)
->
Hash
{
let
mut
v
=
parent_hash
.as_ref
()
.to_vec
();
v
.extend
(
b"pov-blocks"
);
BlakeTwo256
::
hash
(
&
v
[
..
])
}
/// Register a gossip validator on the network service.
/// Register a gossip validator on the network service.
// NOTE: since RegisteredMessageValidator is meant to be a type-safe proof
// NOTE: since RegisteredMessageValidator is meant to be a type-safe proof
// that we've actually done the registration, this should be the only way
// that we've actually done the registration, this should be the only way
...
@@ -511,8 +537,9 @@ impl<C: ?Sized + ChainContext> Inner<C> {
...
@@ -511,8 +537,9 @@ impl<C: ?Sized + ChainContext> Inner<C> {
let
new_topics
=
if
let
Some
(
ref
mut
peer
)
=
self
.peers
.get_mut
(
sender
)
{
let
new_topics
=
if
let
Some
(
ref
mut
peer
)
=
self
.peers
.get_mut
(
sender
)
{
let
new_leaves
=
peer
.attestation
.update_leaves
(
&
chain_heads
);
let
new_leaves
=
peer
.attestation
.update_leaves
(
&
chain_heads
);
let
new_attestation_topics
=
new_leaves
.iter
()
.cloned
()
.map
(
attestation_topic
);
let
new_attestation_topics
=
new_leaves
.iter
()
.cloned
()
.map
(
attestation_topic
);
let
new_pov_block_topics
=
new_leaves
.iter
()
.cloned
()
.map
(
pov_block_topic
);
new_attestation_topics
.collect
()
new_attestation_topics
.
chain
(
new_pov_block_topics
)
.
collect
()
}
else
{
}
else
{
Vec
::
new
()
Vec
::
new
()
};
};
...
@@ -643,6 +670,19 @@ impl<C: ChainContext + ?Sized> sc_network_gossip::Validator<Block> for MessageVa
...
@@ -643,6 +670,19 @@ impl<C: ChainContext + ?Sized> sc_network_gossip::Validator<Block> for MessageVa
}
}
(
res
,
cb
)
(
res
,
cb
)
}
}
Ok
(
GossipMessage
::
PoVBlock
(
pov_block
))
=>
{
let
(
res
,
cb
)
=
{
let
mut
inner
=
self
.inner
.write
();
let
inner
=
&
mut
*
inner
;
inner
.attestation_view
.validate_pov_block_message
(
&
pov_block
,
&
inner
.chain
)
};
if
let
GossipValidationResult
::
ProcessAndKeep
(
ref
topic
)
=
res
{
context
.broadcast_message
(
topic
.clone
(),
data
.to_vec
(),
false
);
}
(
res
,
cb
)
}
Ok
(
GossipMessage
::
ErasureChunk
(
chunk
))
=>
{
Ok
(
GossipMessage
::
ErasureChunk
(
chunk
))
=>
{
self
.inner
.write
()
.validate_erasure_chunk_packet
(
chunk
)
self
.inner
.write
()
.validate_erasure_chunk_packet
(
chunk
)
}
}
...
@@ -688,9 +728,22 @@ impl<C: ChainContext + ?Sized> sc_network_gossip::Validator<Block> for MessageVa
...
@@ -688,9 +728,22 @@ impl<C: ChainContext + ?Sized> sc_network_gossip::Validator<Block> for MessageVa
.and_then
(|(
p
,
r
)|
p
.attestation
.knowledge_at_mut
(
&
r
)
.map
(|
k
|
(
k
,
r
)));
.and_then
(|(
p
,
r
)|
p
.attestation
.knowledge_at_mut
(
&
r
)
.map
(|
k
|
(
k
,
r
)));
peer_knowledge
.map_or
(
false
,
|(
knowledge
,
attestation_head
)|
{
peer_knowledge
.map_or
(
false
,
|(
knowledge
,
attestation_head
)|
{
attestation_view
.statement_allowed
(
statement
.relay_chain_leaf
==
attestation_head
&&
attestation_view
.statement_allowed
(
statement
,
statement
,
&
attestation_head
,
knowledge
,
)
})
}
Ok
(
GossipMessage
::
PoVBlock
(
ref
pov_block
))
=>
{
// to allow pov-blocks, we need peer knowledge.
let
peer_knowledge
=
peer
.and_then
(
move
|
p
|
attestation_head
.map
(|
r
|
(
p
,
r
)))
.and_then
(|(
p
,
r
)|
p
.attestation
.knowledge_at_mut
(
&
r
)
.map
(|
k
|
(
k
,
r
)));
peer_knowledge
.map_or
(
false
,
|(
knowledge
,
attestation_head
)|
{
pov_block
.relay_chain_leaf
==
attestation_head
&&
attestation_view
.pov_block_allowed
(
pov_block
,
knowledge
,
knowledge
,
)
)
})
})
...
@@ -707,7 +760,7 @@ mod tests {
...
@@ -707,7 +760,7 @@ mod tests {
use
sc_network_gossip
::
Validator
as
ValidatorT
;
use
sc_network_gossip
::
Validator
as
ValidatorT
;
use
std
::
sync
::
mpsc
;
use
std
::
sync
::
mpsc
;
use
parking_lot
::
Mutex
;
use
parking_lot
::
Mutex
;
use
polkadot_primitives
::
parachain
::
AbridgedCandidateReceipt
;
use
polkadot_primitives
::
parachain
::
{
AbridgedCandidateReceipt
,
BlockData
}
;
use
sp_core
::
sr25519
::
Signature
as
Sr25519Signature
;
use
sp_core
::
sr25519
::
Signature
as
Sr25519Signature
;
use
polkadot_validation
::
GenericStatement
;
use
polkadot_validation
::
GenericStatement
;
...
@@ -768,7 +821,7 @@ mod tests {
...
@@ -768,7 +821,7 @@ mod tests {
}
}
#[test]
#[test]
fn
message_allowed
()
{
fn
attestation_
message_allowed
()
{
let
(
tx
,
_rx
)
=
mpsc
::
channel
();
let
(
tx
,
_rx
)
=
mpsc
::
channel
();
let
tx
=
Mutex
::
new
(
tx
);
let
tx
=
Mutex
::
new
(
tx
);
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
ReputationChange
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
let
report_handle
=
Box
::
new
(
move
|
peer
:
&
PeerId
,
cb
:
ReputationChange
|
tx
.lock
()
.send
((
peer
.clone
(),
cb
))
.unwrap
());
...
@@ -806,6 +859,9 @@ mod tests {
...
@@ -806,6 +859,9 @@ mod tests {
vec!
[
vec!
[
ContextEvent
::
SendTopic
(
peer_a
.clone
(),
attestation_topic
(
hash_a
),
false
),
ContextEvent
::
SendTopic
(
peer_a
.clone
(),
attestation_topic
(
hash_a
),
false
),
ContextEvent
::
SendTopic
(
peer_a
.clone
(),
attestation_topic
(
hash_b
),
false
),
ContextEvent
::
SendTopic
(
peer_a
.clone
(),
attestation_topic
(
hash_b
),
false
),
ContextEvent
::
SendTopic
(
peer_a
.clone
(),
pov_block_topic
(
hash_a
),
false
),
ContextEvent
::
SendTopic
(
peer_a
.clone
(),
pov_block_topic
(
hash_b
),
false
),
],
],
);
);
...
@@ -908,6 +964,7 @@ mod tests {
...
@@ -908,6 +964,7 @@ mod tests {
chain_heads
:
vec!
[
hash_a
,
hash_b
],
chain_heads
:
vec!
[
hash_a
,
hash_b
],
})
.encode
();
})
.encode
();
{
let
res
=
validator
.validate
(
let
res
=
validator
.validate
(
&
mut
validator_context
,
&
mut
validator_context
,
&
peer_a
,
&
peer_a
,
...
@@ -923,23 +980,84 @@ mod tests {
...
@@ -923,23 +980,84 @@ mod tests {
vec!
[
vec!
[
ContextEvent
::
SendTopic
(
peer_a
.clone
(),
attestation_topic
(
hash_a
),
false
),
ContextEvent
::
SendTopic
(
peer_a
.clone
(),
attestation_topic
(
hash_a
),
false
),
ContextEvent
::
SendTopic
(
peer_a
.clone
(),
attestation_topic
(
hash_b
),
false
),
ContextEvent
::
SendTopic
(
peer_a
.clone
(),
attestation_topic
(
hash_b
),
false
),
ContextEvent
::
SendTopic
(
peer_a
.clone
(),
pov_block_topic
(
hash_a
),
false
),
ContextEvent
::
SendTopic
(
peer_a
.clone
(),
pov_block_topic
(
hash_b
),
false
),
],
],
);
);
validator_context
.clear
();
validator_context
.clear
();
}
let
topic_a
=
attestation_topic
(
hash_a
);
let
mut
validation_data
=
MessageValidationData
::
default
();
validation_data
.signing_context.parent_hash
=
hash_a
;
validator
.inner
.write
()
.attestation_view
.new_local_leaf
(
validation_data
);
}
#[test]
fn
pov_block_message_allowed
()
{
let
(
tx
,
_rx
)
=
mpsc
::
channel
();
let
tx
=
Mutex
::
new
(
tx
);
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
,
);
let
peer_a
=
PeerId
::
random
();
let
mut
validator_context
=
MockValidatorContext
::
default
();
validator
.new_peer
(
&
mut
validator_context
,
&
peer_a
,
Roles
::
FULL
);
assert!
(
validator_context
.events
.is_empty
());
validator_context
.clear
();
let
hash_a
=
[
1u8
;
32
]
.into
();
let
hash_b
=
[
2u8
;
32
]
.into
();
let
message
=
GossipMessage
::
from
(
NeighborPacket
{
chain_heads
:
vec!
[
hash_a
,
hash_b
],
})
.encode
();