From afda7c80b0d8cf3bcea45c34139f45b28557304d Mon Sep 17 00:00:00 2001 From: Erik Reppel Date: Mon, 25 Mar 2024 15:12:36 -0400 Subject: [PATCH 1/3] Clean up premint topics and declare them via config --- src/config.rs | 12 ++++++++++++ src/p2p.rs | 21 +++++++++++++++------ src/types.rs | 25 ++++++++++++++++++++++--- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/config.rs b/src/config.rs index 7980f50..03c4110 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,3 +1,4 @@ +use crate::types::PremintName; use envconfig::Envconfig; #[derive(Envconfig, Debug)] @@ -22,6 +23,10 @@ pub struct Config { #[envconfig(from = "PEER_LIMIT", default = "1000")] pub peer_limit: u64, + + // Comma separated list of default premint types to process + #[envconfig(from = "PREMINT_TYPES", default = "zora_premint_v2")] + premint_types: String, } impl Config { @@ -32,6 +37,13 @@ impl Config { "127.0.0.1".to_string() } } + + pub fn premint_types(&self) -> Vec { + self.premint_types + .split(",") + .map(|s| PremintName(s.to_string())) + .collect() + } } pub fn init() -> Config { diff --git a/src/p2p.rs b/src/p2p.rs index 1a2ec6a..4129f7d 100644 --- a/src/p2p.rs +++ b/src/p2p.rs @@ -1,6 +1,7 @@ use crate::config::Config; use crate::controller::{P2PEvent, SwarmCommand}; -use crate::types::{MintpoolNodeInfo, Premint, PremintTypes}; +use crate::types::{MintpoolNodeInfo, Premint, PremintName, PremintTypes}; +use alloy_primitives::private::derive_more::Display; use eyre::WrapErr; use libp2p::core::ConnectedPoint; use libp2p::futures::StreamExt; @@ -26,6 +27,7 @@ pub struct SwarmController { event_sender: tokio::sync::mpsc::Sender, max_peers: u64, local_mode: bool, + premint_names: Vec, } impl SwarmController { @@ -42,7 +44,8 @@ impl SwarmController { command_receiver, event_sender, max_peers: config.peer_limit, - local_mode: config.connect_external == false, + local_mode: !config.connect_external, + premint_names: config.premint_types(), } } @@ -90,15 +93,17 @@ impl SwarmController { } pub async fn run(&mut self, port: u64, listen_ip: String) -> eyre::Result<()> { - let registry_topic = gossipsub::IdentTopic::new("announce::premints"); - - let topic = gossipsub::IdentTopic::new("zora-1155-v1-mints"); - self.swarm.behaviour_mut().gossipsub.subscribe(&topic)?; + let registry_topic = announce_topic(); self.swarm .behaviour_mut() .gossipsub .subscribe(®istry_topic)?; + for premint_name in self.premint_names.iter() { + let topic = premint_name.msg_topic(); + self.swarm.behaviour_mut().gossipsub.subscribe(&topic)?; + } + self.swarm .listen_on(format!("/ip4/{listen_ip}/tcp/{port}").parse()?)?; @@ -406,3 +411,7 @@ pub struct NetworkState { pub gossipsub_peers: Vec, pub all_external_addresses: Vec, } + +fn announce_topic() -> gossipsub::IdentTopic { + gossipsub::IdentTopic::new("mintpool::announce") +} diff --git a/src/types.rs b/src/types.rs index 3c2c5fa..98ab4b2 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,9 +1,19 @@ +use alloy_primitives::private::derive_more::Display; use alloy_primitives::{Address, U256}; -use libp2p::{Multiaddr, PeerId}; +use libp2p::{gossipsub, Multiaddr, PeerId}; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use std::fmt::Debug; +#[derive(Debug, Display)] +pub struct PremintName(pub String); + +impl PremintName { + pub fn msg_topic(&self) -> gossipsub::IdentTopic { + gossipsub::IdentTopic::new(format!("mintpool::{:?}", self)) + } +} + #[derive(Debug)] pub struct MintpoolNodeInfo { pub peer_id: PeerId, @@ -23,6 +33,7 @@ pub struct PremintMetadata { pub trait Premint: Serialize + DeserializeOwned + Debug + Clone { fn metadata(&self) -> PremintMetadata; + fn kind_id() -> PremintName; } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] @@ -44,8 +55,8 @@ impl PremintTypes { } } -impl Premint for PremintTypes { - fn metadata(&self) -> PremintMetadata { +impl PremintTypes { + pub fn metadata(&self) -> PremintMetadata { match self { PremintTypes::Simple(p) => p.metadata(), PremintTypes::V2(p) => p.metadata(), @@ -73,6 +84,10 @@ impl Premint for SimplePremint { uri: self.media.clone(), } } + + fn kind_id() -> PremintName { + PremintName("simple".to_string()) + } } #[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq)] @@ -96,6 +111,10 @@ impl Premint for PremintV2Message { uri: self.premint.token_creation_config.token_uri.clone(), } } + + fn kind_id() -> PremintName { + PremintName("zora_premint_v2".to_string()) + } } #[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq)] From d2b75bdff7baaa2a5529d6e86eb52af8de6c0bf5 Mon Sep 17 00:00:00 2001 From: Erik Reppel Date: Mon, 25 Mar 2024 15:30:11 -0400 Subject: [PATCH 2/3] Fix tests --- src/config.rs | 43 ++++++++++++++++++++++++++++++++++++++++--- src/p2p.rs | 18 ++++++++++-------- src/storage.rs | 4 +++- src/types.rs | 7 ++++--- tests/p2p_test.rs | 1 + 5 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/config.rs b/src/config.rs index 03c4110..a9329cc 100644 --- a/src/config.rs +++ b/src/config.rs @@ -26,7 +26,7 @@ pub struct Config { // Comma separated list of default premint types to process #[envconfig(from = "PREMINT_TYPES", default = "zora_premint_v2")] - premint_types: String, + pub premint_types: String, } impl Config { @@ -38,9 +38,9 @@ impl Config { } } - pub fn premint_types(&self) -> Vec { + pub fn premint_names(&self) -> Vec { self.premint_types - .split(",") + .split(',') .map(|s| PremintName(s.to_string())) .collect() } @@ -49,3 +49,40 @@ impl Config { pub fn init() -> Config { Config::init_from_env().expect("Failed to load config") } + +#[cfg(test)] +mod test { + #[test] + fn test_premint_names() { + let config = super::Config { + seed: 0, + port: 7777, + connect_external: false, + db_url: None, + persist_state: false, + prune_minted_premints: false, + peer_limit: 1000, + premint_types: "simple,zora_premint_v2".to_string(), + }; + + let names = config.premint_names(); + assert_eq!(names.len(), 2); + assert_eq!(names[0].0, "simple"); + assert_eq!(names[1].0, "zora_premint_v2"); + + let config = super::Config { + seed: 0, + port: 7777, + connect_external: false, + db_url: None, + persist_state: false, + prune_minted_premints: false, + peer_limit: 1000, + premint_types: "zora_premint_v2".to_string(), + }; + + let names = config.premint_names(); + assert_eq!(names.len(), 1); + assert_eq!(names[0].0, "zora_premint_v2"); + } +} diff --git a/src/p2p.rs b/src/p2p.rs index 4129f7d..c178b3b 100644 --- a/src/p2p.rs +++ b/src/p2p.rs @@ -45,7 +45,7 @@ impl SwarmController { event_sender, max_peers: config.peer_limit, local_mode: !config.connect_external, - premint_names: config.premint_types(), + premint_names: config.premint_names(), } } @@ -93,20 +93,22 @@ impl SwarmController { } pub async fn run(&mut self, port: u64, listen_ip: String) -> eyre::Result<()> { + self.swarm + .listen_on(format!("/ip4/{listen_ip}/tcp/{port}").parse()?)?; + let registry_topic = announce_topic(); self.swarm .behaviour_mut() .gossipsub .subscribe(®istry_topic)?; + println!("{:?}", self.premint_names); + for premint_name in self.premint_names.iter() { let topic = premint_name.msg_topic(); self.swarm.behaviour_mut().gossipsub.subscribe(&topic)?; } - self.swarm - .listen_on(format!("/ip4/{listen_ip}/tcp/{port}").parse()?)?; - self.run_loop().await; Ok(()) } @@ -240,7 +242,7 @@ impl SwarmController { } fn broadcast_message(&mut self, message: PremintTypes) -> eyre::Result<()> { - let topic = gossipsub::IdentTopic::new("zora-1155-v1-mints"); + let topic = message.metadata().kind.msg_topic(); let msg = message.to_json().wrap_err("failed to serialize message")?; self.swarm @@ -262,7 +264,7 @@ impl SwarmController { } else { peer_id.to_string() }; - let registry_topic = gossipsub::IdentTopic::new("announce::premints"); + let registry_topic = announce_topic(); if let Err(err) = self .swarm @@ -275,8 +277,8 @@ impl SwarmController { } async fn handle_gossipsub_event(&mut self, event: gossipsub::Event) -> eyre::Result<()> { - tracing::info!("Gossipsub event: {:?}", event); - let registry_topic = gossipsub::IdentTopic::new("announce::premints"); + tracing::debug!("Gossipsub event: {:?}", event); + let registry_topic = announce_topic(); match event { gossipsub::Event::Message { message, .. } => { let msg = String::from_utf8_lossy(&message.data); diff --git a/src/storage.rs b/src/storage.rs index 6951d37..cbb3766 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -59,7 +59,7 @@ impl PremintStorage { VALUES (?, ?, ?, ?, ?, ?, ?) "#, metadata.id, - metadata.kind, + metadata.kind.0, signer, metadata.chain_id, collection_address, @@ -121,6 +121,7 @@ mod test { persist_state: false, prune_minted_premints: false, peer_limit: 1000, + premint_types: "simple".to_string(), }; let store = PremintStorage::new(&config).await; @@ -141,6 +142,7 @@ mod test { persist_state: false, prune_minted_premints: false, peer_limit: 1000, + premint_types: "simple".to_string(), }; let store = PremintStorage::new(&config).await; diff --git a/src/types.rs b/src/types.rs index 98ab4b2..3316872 100644 --- a/src/types.rs +++ b/src/types.rs @@ -3,6 +3,7 @@ use alloy_primitives::{Address, U256}; use libp2p::{gossipsub, Multiaddr, PeerId}; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; +use sqlx::{Decode, Encode}; use std::fmt::Debug; #[derive(Debug, Display)] @@ -23,7 +24,7 @@ pub struct MintpoolNodeInfo { #[derive(Debug)] pub struct PremintMetadata { pub id: String, - pub kind: String, + pub kind: PremintName, pub signer: Address, pub chain_id: i64, pub collection_address: Address, @@ -76,7 +77,7 @@ impl Premint for SimplePremint { fn metadata(&self) -> PremintMetadata { PremintMetadata { id: format!("{:?}:{:?}:{:?}", self.chain_id, self.sender, self.token_id), - kind: "simple".to_string(), + kind: Self::kind_id(), signer: self.sender, chain_id: self.chain_id as i64, collection_address: Address::default(), @@ -103,7 +104,7 @@ impl Premint for PremintV2Message { fn metadata(&self) -> PremintMetadata { PremintMetadata { id: self.premint.uid.to_string(), - kind: "zora_premint_v2".to_string(), + kind: Self::kind_id(), signer: self.collection.contract_admin, chain_id: self.chain_id as i64, collection_address: Address::default(), // TODO: source this diff --git a/tests/p2p_test.rs b/tests/p2p_test.rs index 448fc29..55e0469 100644 --- a/tests/p2p_test.rs +++ b/tests/p2p_test.rs @@ -135,6 +135,7 @@ mod build { persist_state: false, prune_minted_premints: false, peer_limit, + premint_types: "simple,zora_premint_v2".to_string(), }; let ctl = mintpool::run::start_swarm_and_controller(&config) From ea3b533aea789fa4c4ed4a6fadd277eb48822e78 Mon Sep 17 00:00:00 2001 From: Erik Reppel Date: Tue, 26 Mar 2024 12:57:06 -0400 Subject: [PATCH 3/3] Update p2p.rs --- src/p2p.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/p2p.rs b/src/p2p.rs index c178b3b..103a859 100644 --- a/src/p2p.rs +++ b/src/p2p.rs @@ -102,8 +102,6 @@ impl SwarmController { .gossipsub .subscribe(®istry_topic)?; - println!("{:?}", self.premint_names); - for premint_name in self.premint_names.iter() { let topic = premint_name.msg_topic(); self.swarm.behaviour_mut().gossipsub.subscribe(&topic)?;