CRC: create a trait to enforce multiple traits for signer event types

Signed-off-by: Jacinta Ferrant <jacinta@trustmachines.co>
This commit is contained in:
Jacinta Ferrant
2024-05-14 12:35:37 -07:00
parent 1decf3baca
commit 7af348d710
6 changed files with 31 additions and 25 deletions

View File

@@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
use std::fmt::Debug;
use std::io::{Read, Write};
use std::net::{SocketAddr, TcpListener, TcpStream};
use std::sync::atomic::{AtomicBool, Ordering};
@@ -53,6 +54,14 @@ use wsts::state_machine::signer;
use crate::http::{decode_http_body, decode_http_request};
use crate::EventError;
/// Define the trait for the event processor
pub trait SignerEventTrait<T: StacksMessageCodec + Clone + Debug + Send = Self>:
StacksMessageCodec + Clone + Debug + Send
{
}
impl<T: StacksMessageCodec + Clone + Debug + Send> SignerEventTrait for T {}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
/// BlockProposal sent to signers
pub struct BlockProposal {
@@ -86,7 +95,7 @@ impl StacksMessageCodec for BlockProposal {
/// Event enum for newly-arrived signer subscribed events
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum SignerEvent<T: StacksMessageCodec + Clone> {
pub enum SignerEvent<T: SignerEventTrait> {
/// A miner sent a message over .miners
/// The `Vec<T>` will contain any signer messages made by the miner.
/// The `StacksPublicKey` is the message sender's public key.
@@ -111,7 +120,7 @@ pub trait EventStopSignaler {
}
/// Trait to implement to handle signer specific events sent by the Stacks node
pub trait EventReceiver<T: StacksMessageCodec + Clone> {
pub trait EventReceiver<T: SignerEventTrait> {
/// The implementation of ST will ensure that a call to ST::send() will cause
/// the call to `is_stopped()` below to return true.
type ST: EventStopSignaler + Send + Sync;
@@ -164,7 +173,7 @@ pub trait EventReceiver<T: StacksMessageCodec + Clone> {
}
/// Event receiver for Signer events
pub struct SignerEventReceiver<T: StacksMessageCodec + Clone> {
pub struct SignerEventReceiver<T: SignerEventTrait> {
/// Address we bind to
local_addr: Option<SocketAddr>,
/// server socket that listens for HTTP POSTs from the node
@@ -177,7 +186,7 @@ pub struct SignerEventReceiver<T: StacksMessageCodec + Clone> {
is_mainnet: bool,
}
impl<T: StacksMessageCodec + Clone> SignerEventReceiver<T> {
impl<T: SignerEventTrait> SignerEventReceiver<T> {
/// Make a new Signer event receiver, and return both the receiver and the read end of a
/// channel into which node-received data can be obtained.
pub fn new(is_mainnet: bool) -> SignerEventReceiver<T> {
@@ -246,7 +255,7 @@ impl EventStopSignaler for SignerStopSignaler {
}
}
impl<T: StacksMessageCodec + Clone> EventReceiver<T> for SignerEventReceiver<T> {
impl<T: SignerEventTrait> EventReceiver<T> for SignerEventReceiver<T> {
type ST = SignerStopSignaler;
/// Start listening on the given socket address.
@@ -367,7 +376,7 @@ fn ack_dispatcher(request: HttpRequest) {
}
/// Process a stackerdb event from the node
fn process_stackerdb_event<T: StacksMessageCodec + Clone>(
fn process_stackerdb_event<T: SignerEventTrait>(
local_addr: Option<SocketAddr>,
mut request: HttpRequest,
) -> Result<SignerEvent<T>, EventError> {
@@ -405,7 +414,7 @@ fn process_stackerdb_event<T: StacksMessageCodec + Clone>(
Ok(signer_event)
}
impl<T: StacksMessageCodec + Clone> TryFrom<StackerDBChunksEvent> for SignerEvent<T> {
impl<T: SignerEventTrait> TryFrom<StackerDBChunksEvent> for SignerEvent<T> {
type Error = EventError;
fn try_from(event: StackerDBChunksEvent) -> Result<Self, Self::Error> {
@@ -448,7 +457,7 @@ impl<T: StacksMessageCodec + Clone> TryFrom<StackerDBChunksEvent> for SignerEven
}
/// Process a proposal response from the node
fn process_proposal_response<T: StacksMessageCodec + Clone>(
fn process_proposal_response<T: SignerEventTrait>(
mut request: HttpRequest,
) -> Result<SignerEvent<T>, EventError> {
debug!("Got proposal_response event");
@@ -476,7 +485,7 @@ fn process_proposal_response<T: StacksMessageCodec + Clone>(
}
/// Process a new burn block event from the node
fn process_new_burn_block_event<T: StacksMessageCodec + Clone>(
fn process_new_burn_block_event<T: SignerEventTrait>(
mut request: HttpRequest,
) -> Result<SignerEvent<T>, EventError> {
debug!("Got burn_block event");

View File

@@ -50,7 +50,7 @@ pub mod v1;
pub use crate::error::{EventError, RPCError};
pub use crate::events::{
BlockProposal, EventReceiver, EventStopSignaler, SignerEvent, SignerEventReceiver,
SignerStopSignaler,
SignerEventTrait, SignerStopSignaler,
};
pub use crate::runloop::{RunningSigner, Signer, SignerRunLoop};
pub use crate::session::{SignerSession, StackerDBSession};

View File

@@ -29,7 +29,7 @@ use stacks_common::deps_common::ctrlc as termination;
use stacks_common::deps_common::ctrlc::SignalId;
use crate::error::EventError;
use crate::events::{EventReceiver, EventStopSignaler, SignerEvent};
use crate::events::{EventReceiver, EventStopSignaler, SignerEvent, SignerEventTrait};
/// Some libcs, like musl, have a very small stack size.
/// Make sure it's big enough.
@@ -41,7 +41,7 @@ const STDERR: i32 = 2;
/// Trait describing the needful components of a top-level runloop.
/// This is where the signer business logic would go.
/// Implement this, and you get all the multithreaded setup for free.
pub trait SignerRunLoop<R: Send, CMD: Send, T: StacksMessageCodec + Send + Clone> {
pub trait SignerRunLoop<R: Send, CMD: Send, T: SignerEventTrait> {
/// Hint to set how long to wait for new events
fn set_event_timeout(&mut self, timeout: Duration);
/// Getter for the event poll timeout
@@ -108,7 +108,7 @@ pub struct Signer<CMD, R, SL, EV, T> {
}
/// The running signer implementation
pub struct RunningSigner<EV: EventReceiver<T>, R, T: StacksMessageCodec + Clone> {
pub struct RunningSigner<EV: EventReceiver<T>, R, T: SignerEventTrait> {
/// join handle for signer runloop
signer_join: JoinHandle<Option<R>>,
/// join handle for event receiver
@@ -117,7 +117,7 @@ pub struct RunningSigner<EV: EventReceiver<T>, R, T: StacksMessageCodec + Clone>
stop_signal: EV::ST,
}
impl<EV: EventReceiver<T>, R, T: StacksMessageCodec + Clone> RunningSigner<EV, R, T> {
impl<EV: EventReceiver<T>, R, T: SignerEventTrait> RunningSigner<EV, R, T> {
/// Stop the signer, and get the final state
pub fn stop(mut self) -> Option<R> {
// kill event receiver
@@ -213,7 +213,7 @@ impl<CMD, R, SL, EV, T> Signer<CMD, R, SL, EV, T> {
impl<
CMD: Send + 'static,
R: Send + 'static,
T: StacksMessageCodec + Clone + Send + 'static,
T: SignerEventTrait + 'static,
SL: SignerRunLoop<R, CMD, T> + Send + 'static,
EV: EventReceiver<T> + Send + 'static,
> Signer<CMD, R, SL, EV, T>

View File

@@ -37,19 +37,19 @@ use stacks_common::util::secp256k1::Secp256k1PrivateKey;
use stacks_common::util::sleep_ms;
use wsts::net::{DkgBegin, Packet};
use crate::events::SignerEvent;
use crate::events::{SignerEvent, SignerEventTrait};
use crate::v1::messages::SignerMessage;
use crate::{Signer, SignerEventReceiver, SignerRunLoop};
/// Simple runloop implementation. It receives `max_events` events and returns `events` from the
/// last call to `run_one_pass` as its final state.
struct SimpleRunLoop<T: StacksMessageCodec + Clone> {
struct SimpleRunLoop<T: SignerEventTrait> {
poll_timeout: Duration,
events: Vec<SignerEvent<T>>,
max_events: usize,
}
impl<T: StacksMessageCodec + Clone> SimpleRunLoop<T> {
impl<T: SignerEventTrait> SimpleRunLoop<T> {
pub fn new(max_events: usize) -> SimpleRunLoop<T> {
SimpleRunLoop {
poll_timeout: Duration::from_millis(100),
@@ -63,9 +63,7 @@ enum Command {
Empty,
}
impl<T: StacksMessageCodec + Send + Clone + Debug> SignerRunLoop<Vec<SignerEvent<T>>, Command, T>
for SimpleRunLoop<T>
{
impl<T: SignerEventTrait> SignerRunLoop<Vec<SignerEvent<T>>, Command, T> for SimpleRunLoop<T> {
fn set_event_timeout(&mut self, timeout: Duration) {
self.poll_timeout = timeout;
}