-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adding StampNet first revision!! allows starting a public node, publi…
…shing an identity, and retrieving an identity from a p2p DHT. working great. also allows setting default StampNet nodes in config, in case you are a sociopath and want to run your own stamp network and not use mine =[. also moving towards setting up `stamp id import` to work with http URLs (ie stamp id import https://andrew.com/id.stamp) and also stamp://s0f-4x9aadf89d URLs which will basically just wrap `stamp net get`. really coming together
- Loading branch information
1 parent
2488dab
commit 0ea3abf
Showing
9 changed files
with
2,325 additions
and
107 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[package] | ||
name = "stamp-cli" | ||
version = "0.1.3" | ||
version = "0.1.4" | ||
authors = ["Andrew Danger Lyon <[email protected]>"] | ||
edition = "2018" | ||
|
||
|
@@ -21,6 +21,7 @@ serde_derive = "1.0" | |
sharks = "0.4" | ||
stamp-aux = { path = "../aux" } | ||
stamp-core = { path = "../core" } | ||
stamp-net = { path = "../net" } | ||
textwrap = { version = "0.13", features = ["terminal_size"] } | ||
tokio = { version = "1.34", features = ["io-std", "rt"] } | ||
tracing = { version = "0.1", features = ["log"] } | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
use crate::{commands::id::try_load_single_identity, config, db, util}; | ||
use anyhow::{anyhow, Result}; | ||
use stamp_aux::id::sign_with_optimal_key; | ||
use stamp_core::{ | ||
dag::Transaction, | ||
identity::IdentityID, | ||
util::{base64_decode, SerText, SerdeBinary, Timestamp}, | ||
}; | ||
use stamp_net::{ | ||
agent::{self, random_peer_key, Agent, DHTMode, Event, Quorum, RelayMode}, | ||
Multiaddr, | ||
}; | ||
use std::convert::TryFrom; | ||
use std::sync::Arc; | ||
use tokio::{ | ||
sync::{mpsc, oneshot, RwLock}, | ||
task, | ||
}; | ||
use tracing::log::{trace, warn}; | ||
|
||
async fn event_sink(mut events: mpsc::Receiver<Event>, tx_ident: mpsc::Sender<()>, min_idents: usize) -> stamp_net::error::Result<()> { | ||
let mut num_idents = 0; | ||
loop { | ||
match events.recv().await { | ||
Some(Event::Quit) => break, | ||
Some(Event::IdentifyRecv) => { | ||
num_idents += 1; | ||
if num_idents >= min_idents { | ||
let _ = tx_ident.try_send(()); | ||
} | ||
} | ||
Some(ev) => trace!("event_sink: {:?}", ev), | ||
_ => {} | ||
} | ||
} | ||
Ok(()) | ||
} | ||
|
||
pub fn get_stampnet_joinlist(join: Vec<Multiaddr>) -> Result<Vec<Multiaddr>> { | ||
if join.len() > 0 { | ||
return Ok(join); | ||
} | ||
let config = config::load()?; | ||
let join_list = match config.net { | ||
Some(net) => net.join_list.clone(), | ||
None => { | ||
vec![ | ||
"/dns/join01.stampid.net/tcp/5757".parse()?, | ||
"/dns/join02.stampid.net/tcp/5757".parse()?, | ||
] | ||
} | ||
}; | ||
Ok(join_list) | ||
} | ||
|
||
#[tokio::main(flavor = "current_thread")] | ||
pub async fn publish(id: &str, publish_transaction_file: Option<&str>, join: Vec<Multiaddr>) -> Result<()> { | ||
let hash_with = config::hash_algo(Some(&id)); | ||
let transactions = try_load_single_identity(id)?; | ||
let identity = util::build_identity(&transactions)?; | ||
let id_str = id_str!(identity.id())?; | ||
let signed_publish_transaction = if let Some(publish_transaction_file) = publish_transaction_file { | ||
let contents = util::load_file(publish_transaction_file)?; | ||
Transaction::deserialize_binary(&contents).or_else(|_| Transaction::deserialize_binary(&base64_decode(&contents)?))? | ||
} else { | ||
let master_key = | ||
util::passphrase_prompt(&format!("Your master passphrase for identity {}", IdentityID::short(&id_str)), identity.created())?; | ||
let now = Timestamp::now(); | ||
let transaction = transactions | ||
.publish(&hash_with, now) | ||
.map_err(|e| anyhow!("Error creating publish transaction: {:?}", e))?; | ||
sign_with_optimal_key(&identity, &master_key, transaction).map_err(|e| anyhow!("Error signing transaction: {:?}", e))? | ||
}; | ||
signed_publish_transaction.clone().validate_publish_transaction()?; | ||
|
||
let join = get_stampnet_joinlist(join)?; | ||
let join_len = join.len(); | ||
let bind: Multiaddr = "/ip4/127.0.0.1/tcp/0".parse()?; | ||
let peer_key = random_peer_key(); | ||
let peer_id = stamp_net::PeerId::from(peer_key.public()); | ||
let (agent, events) = Agent::new(peer_key, agent::memory_store(&peer_id), RelayMode::Client, DHTMode::Client).unwrap(); | ||
let agent = Arc::new(agent); | ||
let mut task_set = task::JoinSet::new(); | ||
let (tx_ident, mut rx_ident) = mpsc::channel::<()>(1); | ||
task_set.spawn(event_sink(events, tx_ident, join_len)); | ||
let agent2 = agent.clone(); | ||
task_set.spawn(async move { agent2.run(bind.clone(), join).await }); | ||
match rx_ident.recv().await { | ||
Some(_) => {} | ||
None => warn!("ident sender dropped"), | ||
} | ||
agent.dht_bootstrap().await?; | ||
let quorum = std::num::NonZeroUsize::new(std::cmp::max(join_len, 1)).ok_or(anyhow!("bad non-zero usize"))?; | ||
agent.publish_identity(signed_publish_transaction, Quorum::N(quorum)).await?; | ||
agent.quit().await?; | ||
while let Some(res) = task_set.join_next().await { | ||
res??; | ||
} | ||
Ok(()) | ||
} | ||
|
||
#[tokio::main(flavor = "current_thread")] | ||
pub async fn get(id: &str, join: Vec<Multiaddr>) -> Result<()> { | ||
let identity_id = IdentityID::try_from(id)?; | ||
let join = get_stampnet_joinlist(join)?; | ||
let join_len = join.len(); | ||
let bind: Multiaddr = "/ip4/127.0.0.1/tcp/0".parse()?; | ||
let peer_key = random_peer_key(); | ||
let peer_id = stamp_net::PeerId::from(peer_key.public()); | ||
let (agent, events) = Agent::new(peer_key, agent::memory_store(&peer_id), RelayMode::Client, DHTMode::Client).unwrap(); | ||
let agent = Arc::new(agent); | ||
let mut task_set = task::JoinSet::new(); | ||
let (tx_ident, mut rx_ident) = mpsc::channel::<()>(1); | ||
task_set.spawn(event_sink(events, tx_ident, join_len)); | ||
let agent2 = agent.clone(); | ||
task_set.spawn(async move { agent2.run(bind.clone(), join).await }); | ||
match rx_ident.recv().await { | ||
Some(_) => {} | ||
None => warn!("ident sender dropped"), | ||
} | ||
agent.dht_bootstrap().await?; | ||
let lookup_res = agent.lookup_identity(identity_id.clone()).await?; | ||
agent.quit().await?; | ||
while let Some(res) = task_set.join_next().await { | ||
res??; | ||
} | ||
|
||
let publish_transaction = lookup_res.ok_or_else(|| anyhow!("Identity {} not found", identity_id))?; | ||
let (transactions, identity) = publish_transaction.validate_publish_transaction()?; | ||
let exists = db::load_identity(identity.id())?; | ||
let identity = util::build_identity(&transactions)?; | ||
if exists.is_some() { | ||
if !util::yesno_prompt("The identity you're importing already exists locally. Overwrite? [y/N]", "n")? { | ||
return Ok(()); | ||
} | ||
} | ||
db::save_identity(transactions)?; | ||
println!("Imported identity {}", identity.id()); | ||
Ok(()) | ||
} | ||
|
||
#[tokio::main(flavor = "current_thread")] | ||
pub async fn node(bind: Multiaddr, join: Vec<Multiaddr>) -> Result<()> { | ||
let join = get_stampnet_joinlist(join)?; | ||
let peer_key = random_peer_key(); | ||
let peer_id = stamp_net::PeerId::from(peer_key.public()); | ||
let (agent, events) = Agent::new(peer_key, agent::memory_store(&peer_id), RelayMode::Server, DHTMode::Server).unwrap(); | ||
let agent = Arc::new(agent); | ||
let mut task_set = task::JoinSet::new(); | ||
let (tx_ident, mut rx_ident) = mpsc::channel::<()>(1); | ||
task_set.spawn(event_sink(events, tx_ident, 1)); | ||
let agent2 = agent.clone(); | ||
let bind2 = bind.clone(); | ||
task_set.spawn(async move { agent2.run(bind2.clone(), join).await }); | ||
match rx_ident.recv().await { | ||
Some(_) => {} | ||
None => warn!("ident sender dropped"), | ||
} | ||
agent.dht_bootstrap().await?; | ||
while let Some(res) = task_set.join_next().await { | ||
res??; | ||
} | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.