Basic Gossip Validator

This commit is contained in:
Luke Parker 2022-10-30 01:21:10 -04:00
parent f31c457c2c
commit 9a54317743
No known key found for this signature in database
GPG key ID: F9F1386DB1E119B6
5 changed files with 81 additions and 1 deletions

19
Cargo.lock generated
View file

@ -6878,6 +6878,24 @@ dependencies = [
"thiserror",
]
[[package]]
name = "sc-network-gossip"
version = "0.10.0-dev"
source = "git+https://github.com/serai-dex/substrate#176b4e8cfc110f339d88ebd414602bc3833da3c3"
dependencies = [
"ahash",
"futures",
"futures-timer",
"libp2p",
"log",
"lru 0.7.8",
"sc-network-common",
"sc-peerset",
"sp-runtime",
"substrate-prometheus-endpoint",
"tracing",
]
[[package]]
name = "sc-network-light"
version = "0.10.0-dev"
@ -7521,6 +7539,7 @@ dependencies = [
"sc-consensus",
"sc-executor",
"sc-network",
"sc-network-gossip",
"sc-service",
"sc-transaction-pool",
"serai-runtime",

View file

@ -36,6 +36,7 @@ sc-transaction-pool = { git = "https://github.com/serai-dex/substrate" }
sc-basic-authorship = { git = "https://github.com/serai-dex/substrate" }
sc-executor = { git = "https://github.com/serai-dex/substrate" }
sc-network = { git = "https://github.com/serai-dex/substrate" }
sc-network-gossip = { git = "https://github.com/serai-dex/substrate" }
sc-service = { git = "https://github.com/serai-dex/substrate" }
sc-client-api = { git = "https://github.com/serai-dex/substrate" }
sc-consensus = { git = "https://github.com/serai-dex/substrate" }

View file

@ -0,0 +1,43 @@
use std::sync::{Arc, RwLock};
use sp_core::{Decode, sr25519::Signature};
use sp_runtime::traits::{Hash, Header, Block};
use sc_network::PeerId;
use sc_network_gossip::{Validator, ValidatorContext, ValidationResult};
use tendermint_machine::{SignedMessage, ext::SignatureScheme};
#[derive(Clone)]
struct TendermintGossip<S: SignatureScheme<ValidatorId = u16, Signature = Signature>> {
number: Arc<RwLock<u64>>,
signature_scheme: Arc<S>,
}
impl<B: Block, S: SignatureScheme<ValidatorId = u16, Signature = Signature>> Validator<B>
for TendermintGossip<S>
{
fn validate(
&self,
_: &mut dyn ValidatorContext<B>,
_: &PeerId,
data: &[u8],
) -> ValidationResult<B::Hash> {
let msg = match SignedMessage::<u16, B, Signature>::decode(&mut &*data) {
Ok(msg) => msg,
Err(_) => return ValidationResult::Discard,
};
if msg.number().0 < *self.number.read().unwrap() {
return ValidationResult::Discard;
}
if !msg.verify_signature(&self.signature_scheme) {
return ValidationResult::Discard;
}
ValidationResult::ProcessAndKeep(<<B::Header as Header>::Hashing as Hash>::hash(
&[b"Tendermint Topic".as_ref(), &msg.number().0.to_le_bytes()].concat(),
))
}
}

View file

@ -20,6 +20,8 @@ mod verifier;
mod import_queue;
use import_queue::TendermintImportQueue;
mod gossip;
mod select_chain;
pub use select_chain::TendermintSelectChain;

View file

@ -81,6 +81,21 @@ pub struct SignedMessage<V: ValidatorId, B: Block, S: Signature> {
sig: S,
}
impl<V: ValidatorId, B: Block, S: Signature> SignedMessage<V, B, S> {
/// Number of the block this message is attempting to add to the chain.
pub fn number(&self) -> BlockNumber {
self.msg.number
}
#[must_use]
pub fn verify_signature<Scheme: SignatureScheme<ValidatorId = V, Signature = S>>(
&self,
signer: &Arc<Scheme>,
) -> bool {
signer.verify(self.msg.sender, &self.msg.encode(), &self.sig)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
enum TendermintError<V: ValidatorId> {
Malicious(V),
@ -302,7 +317,7 @@ impl<N: Network + 'static> TendermintMachine<N> {
loop {
match msg_recv.try_recv() {
Ok(msg) => {
if !machine.signer.verify(msg.msg.sender, &msg.msg.encode(), &msg.sig) {
if !msg.verify_signature(&machine.signer) {
continue;
}
machine.queue.push((false, msg.msg));