diff --git a/Cargo.lock b/Cargo.lock index 42bf1986..ebf24e6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/substrate/tendermint/client/Cargo.toml b/substrate/tendermint/client/Cargo.toml index 37dde6d1..8e0a9e5a 100644 --- a/substrate/tendermint/client/Cargo.toml +++ b/substrate/tendermint/client/Cargo.toml @@ -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" } diff --git a/substrate/tendermint/client/src/gossip.rs b/substrate/tendermint/client/src/gossip.rs new file mode 100644 index 00000000..0c8cc438 --- /dev/null +++ b/substrate/tendermint/client/src/gossip.rs @@ -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> { + number: Arc>, + signature_scheme: Arc, +} + +impl> Validator + for TendermintGossip +{ + fn validate( + &self, + _: &mut dyn ValidatorContext, + _: &PeerId, + data: &[u8], + ) -> ValidationResult { + let msg = match SignedMessage::::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(<::Hashing as Hash>::hash( + &[b"Tendermint Topic".as_ref(), &msg.number().0.to_le_bytes()].concat(), + )) + } +} diff --git a/substrate/tendermint/client/src/lib.rs b/substrate/tendermint/client/src/lib.rs index 5c6413b4..e567c0cc 100644 --- a/substrate/tendermint/client/src/lib.rs +++ b/substrate/tendermint/client/src/lib.rs @@ -20,6 +20,8 @@ mod verifier; mod import_queue; use import_queue::TendermintImportQueue; +mod gossip; + mod select_chain; pub use select_chain::TendermintSelectChain; diff --git a/substrate/tendermint/machine/src/lib.rs b/substrate/tendermint/machine/src/lib.rs index 657b0370..a2134cd9 100644 --- a/substrate/tendermint/machine/src/lib.rs +++ b/substrate/tendermint/machine/src/lib.rs @@ -81,6 +81,21 @@ pub struct SignedMessage { sig: S, } +impl SignedMessage { + /// 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>( + &self, + signer: &Arc, + ) -> bool { + signer.verify(self.msg.sender, &self.msg.encode(), &self.sig) + } +} + #[derive(Clone, Copy, PartialEq, Eq, Debug)] enum TendermintError { Malicious(V), @@ -302,7 +317,7 @@ impl TendermintMachine { 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));