Skip to content

Commit

Permalink
feat: alert system
Browse files Browse the repository at this point in the history
  • Loading branch information
jjyr committed May 23, 2019
1 parent 8b305de commit 797c677
Show file tree
Hide file tree
Showing 31 changed files with 1,276 additions and 19 deletions.
36 changes: 36 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ ckb-bin = { path = "ckb-bin" }

[workspace]
members = [
"util/alert-system",
"util/multisig",
"util/logger",
"util/hash",
"util/merkle-tree",
Expand Down
1 change: 1 addition & 0 deletions ckb-bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ ckb-pow = { path = "../pow" }
ckb-network = { path = "../network"}
ckb-rpc = { path = "../rpc"}
ckb-resource = { path = "../resource"}
ckb-alert-system = { path = "../util/alert-system" }
logger = { path = "../util/logger" }
numext-fixed-hash = { version = "0.1", features = ["support_rand", "support_heapsize", "support_serde"] }
numext-fixed-uint = { version = "0.1", features = ["support_rand", "support_heapsize", "support_serde"] }
Expand Down
14 changes: 14 additions & 0 deletions ckb-bin/src/subcommand/run.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::helper::{deadlock_detection, wait_for_exit};
use build_info::Version;
use ckb_alert_system::{alert_relayer::AlertRelayer, config::Config as AlertSystemConfig};
use ckb_app_config::{ExitCode, RunArgs};
use ckb_chain::chain::ChainService;
use ckb_db::RocksDB;
Expand Down Expand Up @@ -67,6 +68,10 @@ pub fn run(args: RunArgs, version: Version) -> Result<(), ExitCode> {
synchronizer.peers(),
);
let net_timer = NetTimeProtocol::default();
let alert_relayer = AlertRelayer::new(version.to_string(), AlertSystemConfig::default());

let alert_notifier = alert_relayer.notifier();
let alert_verifier = alert_relayer.verifier();

let synchronizer_clone = synchronizer.clone();
let protocols = vec![
Expand All @@ -91,6 +96,13 @@ pub fn run(args: RunArgs, version: Version) -> Result<(), ExitCode> {
move || Box::new(net_timer.clone()),
Arc::clone(&network_state),
),
CKBProtocol::new(
"alt".to_string(),
NetworkProtocol::ALERT.into(),
&["1".to_string()][..],
move || Box::new(alert_relayer.clone()),
Arc::clone(&network_state),
),
];
let network_controller = NetworkService::new(Arc::clone(&network_state), protocols)
.start(version, Some("NetworkService"))
Expand All @@ -103,6 +115,8 @@ pub fn run(args: RunArgs, version: Version) -> Result<(), ExitCode> {
synchronizer,
chain_controller,
block_assembler_controller,
alert_notifier,
alert_verifier,
);

wait_for_exit();
Expand Down
92 changes: 92 additions & 0 deletions core/src/alert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
use crate::Bytes;
use bincode::serialize;
use hash::blake2b_256;
use numext_fixed_hash::H256;
use serde_derive::{Deserialize, Serialize};

#[derive(Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
pub struct Alert {
pub id: u32,
// cancel id if cancel is greater than 0
pub cancel: u32,
// TODO use service flag to distinguish network
//network: String,
pub min_version: Option<String>,
pub max_version: Option<String>,
pub priority: u32,
pub notice_until: u64,
pub message: String,
pub signatures: Vec<Bytes>,
}

impl Alert {
pub fn hash(&self) -> H256 {
let alert = Self {
id: self.id,
cancel: self.cancel,
min_version: self.min_version.clone(),
max_version: self.max_version.clone(),
priority: self.priority,
notice_until: self.notice_until,
message: self.message.clone(),
signatures: Vec::new(),
};
blake2b_256(serialize(&alert).expect("serialize should not fail")).into()
}
}

#[derive(Default)]
pub struct AlertBuilder {
inner: Alert,
}

impl AlertBuilder {
pub fn alert(mut self, alert: Alert) -> Self {
self.inner = alert;
self
}

pub fn id(mut self, id: u32) -> Self {
self.inner.id = id;
self
}

pub fn cancel(mut self, cancel: u32) -> Self {
self.inner.cancel = cancel;
self
}

pub fn min_version(mut self, min_version: Option<String>) -> Self {
self.inner.min_version = min_version;
self
}

pub fn max_version(mut self, max_version: Option<String>) -> Self {
self.inner.max_version = max_version;
self
}

pub fn priority(mut self, priority: u32) -> Self {
self.inner.priority = priority;
self
}

pub fn signatures(mut self, signatures: Vec<Bytes>) -> Self {
self.inner.signatures.extend(signatures);
self
}

pub fn notice_until(mut self, notice_until: u64) -> Self {
self.inner.notice_until = notice_until;
self
}

pub fn message(mut self, message: String) -> Self {
self.inner.message = message;
self
}

pub fn build(self) -> Alert {
self.inner
}
}
1 change: 1 addition & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//!
//! This Library provides the essential types for building ckb.

pub mod alert;
pub mod block;
pub mod cell;
pub mod difficulty;
Expand Down
60 changes: 55 additions & 5 deletions protocol/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::protocol_generated::ckb::protocol::{
Block as FbsBlock, BlockBuilder, BlockProposalBuilder, BlockTransactionsBuilder,
Bytes as FbsBytes, BytesBuilder, CellInput as FbsCellInput, CellInputBuilder,
CellOutput as FbsCellOutput, CellOutputBuilder, CompactBlock, CompactBlockBuilder,
FilteredBlock, FilteredBlockBuilder, GetBlockProposalBuilder, GetBlockTransactionsBuilder,
GetBlocks as FbsGetBlocks, GetBlocksBuilder, GetHeaders as FbsGetHeaders, GetHeadersBuilder,
Alert as FbsAlert, AlertBuilder, AlertMessage, AlertMessageBuilder, Block as FbsBlock,
BlockBuilder, BlockProposalBuilder, BlockTransactionsBuilder, Bytes as FbsBytes, BytesBuilder,
CellInput as FbsCellInput, CellInputBuilder, CellOutput as FbsCellOutput, CellOutputBuilder,
CompactBlock, CompactBlockBuilder, FilteredBlock, FilteredBlockBuilder,
GetBlockProposalBuilder, GetBlockTransactionsBuilder, GetBlocks as FbsGetBlocks,
GetBlocksBuilder, GetHeaders as FbsGetHeaders, GetHeadersBuilder,
GetRelayTransaction as FbsGetRelayTransaction, GetRelayTransactionBuilder, Header as FbsHeader,
HeaderBuilder, Headers as FbsHeaders, HeadersBuilder, IndexTransactionBuilder,
MerkleProofBuilder, OutPoint as FbsOutPoint, OutPointBuilder,
Expand All @@ -16,6 +17,7 @@ use crate::protocol_generated::ckb::protocol::{
WitnessBuilder, H256 as FbsH256,
};
use crate::{short_transaction_id, short_transaction_id_keys};
use ckb_core::alert::Alert;
use ckb_core::block::Block;
use ckb_core::header::{BlockNumber, Header};
use ckb_core::script::Script;
Expand Down Expand Up @@ -712,6 +714,54 @@ impl<'a> TimeMessage<'a> {
}
}

impl<'a> FbsAlert<'a> {
pub fn build<'b>(fbb: &mut FlatBufferBuilder<'b>, alert: &Alert) -> WIPOffset<FbsAlert<'b>> {
let min_version = alert
.min_version
.as_ref()
.map(|min_ver| FbsBytes::build(fbb, min_ver.as_bytes()));
let max_version = alert
.max_version
.as_ref()
.map(|max_ver| FbsBytes::build(fbb, max_ver.as_bytes()));
let signatures = {
let signatures: Vec<_> = alert
.signatures
.iter()
.map(|sig| FbsBytes::build(fbb, sig))
.collect();
fbb.create_vector(&signatures)
};
let message = FbsBytes::build(fbb, alert.message.as_bytes());
let mut builder = AlertBuilder::new(fbb);
builder.add_id(alert.id);
builder.add_cancel(alert.cancel);
if let Some(min_version) = min_version {
builder.add_min_version(min_version);
}
if let Some(max_version) = max_version {
builder.add_max_version(max_version);
}
builder.add_priority(alert.priority);
builder.add_signatures(signatures);
builder.add_notice_until(alert.notice_until);
builder.add_message(message);
builder.finish()
}
}

impl<'a> AlertMessage<'a> {
pub fn build_alert<'b>(
fbb: &mut FlatBufferBuilder<'b>,
alert: &Alert,
) -> WIPOffset<AlertMessage<'b>> {
let fbs_alert = FbsAlert::build(fbb, alert);
let mut builder = AlertMessageBuilder::new(fbb);
builder.add_payload(fbs_alert);
builder.finish()
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
40 changes: 40 additions & 0 deletions protocol/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,3 +353,43 @@ impl<'a> TryFrom<ckb_protocol::IndexTransaction<'a>> for ckb_core::transaction::
})
}
}

impl<'a> TryFrom<ckb_protocol::Alert<'a>> for ckb_core::alert::Alert {
type Error = FailureError;

fn try_from(alert: ckb_protocol::Alert<'a>) -> Result<Self, Self::Error> {
let message = String::from_utf8(cast!(alert.message().and_then(|m| m.seq()))?.to_owned())?;
let min_version: Option<String> = match alert
.min_version()
.and_then(|m| m.seq().map(|s| String::from_utf8(s.to_vec())))
{
Some(min_version) => Some(min_version?),
None => None,
};
let max_version: Option<String> = match alert
.max_version()
.and_then(|m| m.seq().map(|s| String::from_utf8(s.to_vec())))
{
Some(max_version) => Some(max_version?),
None => None,
};
let signatures: Result<Vec<ckb_core::Bytes>, FailureError> =
FlatbuffersVectorIterator::new(cast!(alert.signatures())?)
.map(|s| {
cast!(s.seq())
.map(ckb_core::Bytes::from)
.map_err(Into::into)
})
.collect();
Ok(ckb_core::alert::AlertBuilder::default()
.id(alert.id())
.cancel(alert.cancel())
.min_version(min_version)
.max_version(max_version)
.priority(alert.priority())
.signatures(signatures?)
.notice_until(alert.notice_until())
.message(message)
.build())
}
}
16 changes: 16 additions & 0 deletions protocol/src/protocol.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,19 @@ table TimeMessage {
table Time {
timestamp: uint64;
}

table AlertMessage {
payload: Alert;
}

table Alert {
id: uint32;
cancel: uint32;
min_version: Bytes;
max_version: Bytes;
priority: uint32;
signatures: [Bytes];
notice_until: uint64;
message: Bytes;
}

Loading

0 comments on commit 797c677

Please sign in to comment.