|
1 | 1 | use std::convert::Infallible;
|
2 | 2 | use std::net::Ipv4Addr;
|
3 | 3 | use std::path::PathBuf;
|
| 4 | +use std::process::exit; |
4 | 5 | use std::sync::atomic::{AtomicU64, Ordering};
|
5 | 6 |
|
6 | 7 | use anyhow::Result;
|
7 | 8 | use bytes::Bytes;
|
8 | 9 | use clap::Parser;
|
9 | 10 | use prost::Message;
|
10 | 11 | use quick_cache::sync::Cache;
|
| 12 | +use sailfish::types::RoundNumber; |
11 | 13 | use timeboost::config::CommitteeConfig;
|
12 | 14 | use timeboost::proto::block::Block;
|
13 | 15 | use timeboost::proto::forward::forward_api_server::{ForwardApi, ForwardApiServer};
|
@@ -36,7 +38,7 @@ struct Args {
|
36 | 38 | /// GRPC service that accepts inclusion lists and broadcasts them to clients.
|
37 | 39 | struct Service {
|
38 | 40 | next_block: AtomicU64,
|
39 |
| - cache: Cache<Bytes, u64>, |
| 41 | + cache: Cache<RoundNumber, (Bytes, u64)>, |
40 | 42 | output: broadcast::Sender<Block>,
|
41 | 43 | }
|
42 | 44 |
|
@@ -65,13 +67,21 @@ impl ForwardApi for Service {
|
65 | 67 | r: Request<InclusionList>,
|
66 | 68 | ) -> Result<Response<()>, Status> {
|
67 | 69 | let list = r.into_inner();
|
| 70 | + let round = RoundNumber::from(list.round); |
68 | 71 | let bytes = Bytes::from(list.encode_to_vec());
|
69 |
| - let bnum = self |
| 72 | + let (prev, bnum) = self |
70 | 73 | .cache
|
71 |
| - .get_or_insert_with(&bytes, || -> Result<u64, Infallible> { |
72 |
| - Ok(self.next_block.fetch_add(1, Ordering::Relaxed)) |
| 74 | + .get_or_insert_with(&round, || -> Result<_, Infallible> { |
| 75 | + Ok(( |
| 76 | + bytes.clone(), |
| 77 | + self.next_block.fetch_add(1, Ordering::Relaxed), |
| 78 | + )) |
73 | 79 | })
|
74 | 80 | .expect("infallible insert");
|
| 81 | + if bytes != prev { |
| 82 | + error!(%round, "inclusion list mismatch"); |
| 83 | + exit(1) |
| 84 | + } |
75 | 85 | let block = Block {
|
76 | 86 | number: bnum,
|
77 | 87 | round: list.round,
|
|
0 commit comments