Skip to content

Commit

Permalink
refactor: switch to hex formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
dignifiedquire committed Oct 25, 2024
1 parent 8f75005 commit 312e984
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 71 deletions.
7 changes: 3 additions & 4 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ iroh-net = { path = "./iroh-net" }
iroh-metrics = { path = "./iroh-metrics" }
iroh-test = { path = "./iroh-test" }
iroh-router = { path = "./iroh-router" }


iroh-gossip = { git = "https://github.com/n0-computer/iroh-gossip", branch = "refactor-switch-to-hex" }
iroh-docs = { git = "https://github.com/n0-computer/iroh-docs", branch = "refactor-switch-to-hex" }
6 changes: 3 additions & 3 deletions iroh-base/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ serde_json = "1.0.107"
serde_test = "1.0.176"

[features]
default = ["hash", "base32"]
hash = ["dep:blake3", "dep:data-encoding", "dep:postcard", "dep:derive_more", "base32"]
base32 = ["dep:data-encoding", "dep:postcard"]
default = ["hash", "ticket"]
hash = ["dep:blake3", "dep:postcard", "dep:derive_more", "dep:data-encoding"]
ticket = ["dep:postcard", "dep:data-encoding"]
redb = ["dep:redb"]
key = ["dep:ed25519-dalek", "dep:once_cell", "dep:rand", "dep:rand_core", "dep:ssh-key", "dep:ttl_cache", "dep:aead", "dep:crypto_box", "dep:zeroize", "dep:url", "dep:derive_more", "dep:getrandom"]
wasm = ["getrandom?/js"]
Expand Down
15 changes: 0 additions & 15 deletions iroh-base/src/base32.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
pub use data_encoding::{DecodeError, DecodeKind};
use hex::FromHexError;

/// Convert to a base32 string
pub fn fmt(bytes: impl AsRef<[u8]>) -> String {
let mut text = data_encoding::BASE32_NOPAD.encode(bytes.as_ref());
text.make_ascii_lowercase();
text
}

/// Convert to a base32 string and append out `out`
pub fn fmt_append(bytes: impl AsRef<[u8]>, out: &mut String) {
let start = out.len();
Expand All @@ -16,14 +9,6 @@ pub fn fmt_append(bytes: impl AsRef<[u8]>, out: &mut String) {
out[start..end].make_ascii_lowercase();
}

/// Convert to a base32 string limited to the first 10 bytes
pub fn fmt_short(bytes: impl AsRef<[u8]>) -> String {
let len = bytes.as_ref().len().min(10);
let mut text = data_encoding::BASE32_NOPAD.encode(&bytes.as_ref()[..len]);
text.make_ascii_lowercase();
text
}

/// Parse from a base32 string into a byte array
pub fn parse_array<const N: usize>(input: &str) -> Result<[u8; N], DecodeError> {
data_encoding::BASE32_NOPAD
Expand Down
24 changes: 8 additions & 16 deletions iroh-base/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{borrow::Borrow, fmt, str::FromStr};
use postcard::experimental::max_size::MaxSize;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};

use crate::base32::{self, parse_array_hex_or_base32, HexOrBase32ParseError};
use crate::base32::{parse_array_hex_or_base32, HexOrBase32ParseError};

/// Hash type used throughout.
#[derive(PartialEq, Eq, Copy, Clone, Hash)]
Expand Down Expand Up @@ -53,10 +53,11 @@ impl Hash {
self.0.to_hex().to_string()
}

/// Convert to a base32 string limited to the first 10 bytes for a friendly string
/// Convert to a hex string limited to the first 10 bytes for a friendly string
/// representation of the hash.
pub fn fmt_short(&self) -> String {
base32::fmt_short(self.as_bytes())
let raw = self.to_hex().to_string();
raw.chars().take(10).collect()
}
}

Expand Down Expand Up @@ -122,16 +123,7 @@ impl Ord for Hash {

impl fmt::Display for Hash {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// result will be 52 bytes
let mut res = [b'b'; 52];
// write the encoded bytes
data_encoding::BASE32_NOPAD.encode_mut(self.as_bytes(), &mut res);
// convert to string, this is guaranteed to succeed
let t = std::str::from_utf8_mut(res.as_mut()).unwrap();
// hack since data_encoding doesn't have BASE32LOWER_NOPAD as a const
t.make_ascii_lowercase();
// write the str, no allocations
f.write_str(t)
self.0.fmt(f)
}
}

Expand Down Expand Up @@ -510,7 +502,7 @@ mod tests {
assert_tokens(&hash.compact(), &tokens);

let tokens = vec![Token::String(
"5khrmpntq2bjexseshc6ldklwnig56gbj23yvbxjbdcwestheahq",
"ea8f163db38682925e4491c5e58d4bb3506ef8c14eb78a86e908c5624a67200f",
)];
assert_tokens(&hash.readable(), &tokens);
}
Expand All @@ -531,8 +523,8 @@ mod tests {
let ser = serde_json::to_string(&hash).unwrap();
let de = serde_json::from_str(&ser).unwrap();
assert_eq!(hash, de);
// 52 bytes of base32 + 2 quotes
assert_eq!(ser.len(), 54);
// 64 bytes of hex + 2 quotes
assert_eq!(ser.len(), 66);
}

#[test]
Expand Down
22 changes: 12 additions & 10 deletions iroh-base/src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,10 @@ impl PublicKey {
self.public().verify_strict(message, signature)
}

/// Convert to a base32 string limited to the first 10 bytes for a friendly string
/// Convert to a hex string limited to the first 10 bytes for a friendly string
/// representation of the key.
pub fn fmt_short(&self) -> String {
base32::fmt_short(self.as_bytes())
hex::encode(self.as_bytes()).chars().take(10).collect()
}
}

Expand Down Expand Up @@ -235,17 +235,13 @@ impl From<VerifyingKey> for PublicKey {

impl Debug for PublicKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "PublicKey({})", base32::fmt_short(self.as_bytes()))
write!(f, "PublicKey({})", self.fmt_short())
}
}

impl Display for PublicKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if f.alternate() {
write!(f, "{}", base32::fmt_short(self.as_bytes()))
} else {
write!(f, "{}", base32::fmt(self.as_bytes()))
}
write!(f, "{}", hex::encode(self.as_bytes()))
}
}

Expand Down Expand Up @@ -281,13 +277,13 @@ pub struct SecretKey {

impl Debug for SecretKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "SecretKey({})", base32::fmt_short(self.to_bytes()))
write!(f, "SecretKey({})", self.fmt_short())
}
}

impl Display for SecretKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", base32::fmt(self.to_bytes()))
write!(f, "{}", hex::encode(self.to_bytes()))
}
}

Expand Down Expand Up @@ -380,6 +376,12 @@ impl SecretKey {
secret.into()
}

/// Convert to a hex string limited to the first 10 bytes for a friendly string
/// representation of the key.
pub fn fmt_short(&self) -> String {
hex::encode(self.as_bytes()).chars().take(10).collect()
}

fn secret_crypto_box(&self) -> &crypto_box::SecretKey {
self.secret_crypto_box
.get_or_init(|| secret_ed_box(&self.secret))
Expand Down
9 changes: 4 additions & 5 deletions iroh-base/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//! Base types and utilities for Iroh
#![cfg_attr(iroh_docsrs, feature(doc_cfg))]

#[cfg(feature = "base32")]
#[cfg_attr(iroh_docsrs, doc(cfg(feature = "base32")))]
pub mod base32;
#[cfg(feature = "ticket")]
mod base32;
#[cfg(feature = "hash")]
#[cfg_attr(iroh_docsrs, doc(cfg(feature = "hash")))]
pub mod hash;
Expand All @@ -14,6 +13,6 @@ pub mod key;
#[cfg_attr(iroh_docsrs, doc(cfg(feature = "key")))]
pub mod node_addr;
pub mod rpc;
#[cfg(feature = "base32")]
#[cfg_attr(iroh_docsrs, doc(cfg(feature = "base32")))]
#[cfg(feature = "ticket")]
#[cfg_attr(iroh_docsrs, doc(cfg(feature = "ticket")))]
pub mod ticket;
5 changes: 5 additions & 0 deletions iroh-cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,3 +214,8 @@ impl Cli {
Ok(config)
}
}

/// Helper to fmt bytes as short hex.
pub(crate) fn fmt_short(bytes: &impl AsRef<[u8]>) -> String {
hex::encode(bytes.as_ref()).chars().take(10).collect()
}
9 changes: 4 additions & 5 deletions iroh-cli/src/commands/authors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ use clap::Parser;
use derive_more::FromStr;
use futures_lite::StreamExt;
use iroh::{
base::base32::fmt_short,
client::Iroh,
docs::{Author, AuthorId},
};

use crate::config::ConsoleEnv;
use crate::{commands::fmt_short, config::ConsoleEnv};

/// Commands to manage authors.
#[derive(Debug, Clone, Parser)]
Expand Down Expand Up @@ -46,7 +45,7 @@ impl AuthorCommands {
match self {
Self::Switch { author } => {
env.set_author(author)?;
println!("Active author is now {}", fmt_short(author.as_bytes()));
println!("Active author is now {}", fmt_short(&author.as_bytes()));
}
Self::List => {
let mut stream = iroh.authors().list().await?;
Expand Down Expand Up @@ -87,14 +86,14 @@ impl AuthorCommands {
println!("{}", author);
}
None => {
println!("No author found {}", fmt_short(author));
println!("No author found {}", fmt_short(&author));
}
},
Self::Import { author } => match Author::from_str(&author) {
Ok(author) => {
let id = author.id();
iroh.authors().import(author).await?;
println!("Imported {}", fmt_short(id));
println!("Imported {}", fmt_short(&id));
}
Err(err) => {
eprintln!("Invalid author key: {}", err);
Expand Down
4 changes: 2 additions & 2 deletions iroh-cli/src/commands/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
use anyhow::Result;
use clap::{Parser, Subcommand};
use colored::Colorize;
use iroh::{base::base32::fmt_short, client::Iroh};
use iroh::client::Iroh;
use rustyline::{error::ReadlineError, Config, DefaultEditor};
use tokio::sync::{mpsc, oneshot};

use crate::{
commands::rpc::RpcCommands,
commands::{fmt_short, rpc::RpcCommands},
config::{ConsoleEnv, ConsolePaths},
};

Expand Down
19 changes: 10 additions & 9 deletions iroh-cli/src/commands/docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use futures_buffered::BufferedStreamExt;
use futures_lite::{Stream, StreamExt};
use indicatif::{HumanBytes, HumanDuration, MultiProgress, ProgressBar, ProgressStyle};
use iroh::{
base::{base32::fmt_short, node_addr::AddrInfoOptions},
base::node_addr::AddrInfoOptions,
blobs::{provider::AddProgress, util::SetTagOption, Hash, Tag},
client::{
blobs::WrapOption,
Expand All @@ -31,6 +31,7 @@ use iroh::{
};
use tokio::io::AsyncReadExt;

use super::fmt_short;
use crate::config::ConsoleEnv;

/// The maximum length of content to display before truncating.
Expand Down Expand Up @@ -389,7 +390,7 @@ impl DocCommands {
println!("Deleted {removed} entries.");
println!(
"Inserted an empty entry for author {} with key {prefix}.",
fmt_short(author)
fmt_short(&author)
);
} else {
println!("Aborted.")
Expand Down Expand Up @@ -446,7 +447,7 @@ impl DocCommands {
Self::Leave { doc } => {
let doc = get_doc(iroh, env, doc).await?;
doc.leave().await?;
println!("Doc {} is now inactive", fmt_short(doc.id()));
println!("Doc {} is now inactive", fmt_short(&doc.id()));
}
Self::Import {
doc,
Expand Down Expand Up @@ -596,14 +597,14 @@ impl DocCommands {
Ok(details) => {
println!(
"synced peer {} ({origin}, received {}, sent {}",
fmt_short(event.peer),
fmt_short(&event.peer),
details.entries_received,
details.entries_sent
)
}
Err(err) => println!(
"failed to sync with peer {} ({origin}): {err}",
fmt_short(event.peer)
fmt_short(&event.peer)
),
}
}
Expand All @@ -625,14 +626,14 @@ impl DocCommands {
"Deleting a document will permanently remove the document secret key, all document entries, \n\
and all content blobs which are not referenced from other docs or tags."
);
let prompt = format!("Delete document {}?", fmt_short(doc.id()));
let prompt = format!("Delete document {}?", fmt_short(&doc.id()));
if Confirm::new()
.with_prompt(prompt)
.interact()
.unwrap_or(false)
{
iroh.docs().drop_doc(doc.id()).await?;
println!("Doc {} has been deleted.", fmt_short(doc.id()));
println!("Doc {} has been deleted.", fmt_short(&doc.id()));
} else {
println!("Aborted.")
}
Expand Down Expand Up @@ -739,7 +740,7 @@ async fn fmt_entry(doc: &Doc, entry: &Entry, mode: DisplayContentMode) -> String
let key = std::str::from_utf8(entry.key())
.unwrap_or("<bad key>")
.bold();
let author = fmt_short(entry.author());
let author = fmt_short(&entry.author());
let (Ok(content) | Err(content)) = fmt_content(doc, entry, mode).await;
let len = human_len(entry);
format!("@{author}: {key} = {content} ({len})")
Expand Down Expand Up @@ -908,7 +909,7 @@ impl ImportProgressBar {
add.set_position(0);
add.enable_steady_tick(Duration::from_millis(500));

let doc_id = fmt_short(doc_id.to_bytes());
let doc_id = fmt_short(&doc_id.to_bytes());
let import = mp.add(ProgressBar::new(0));
import.set_style(ProgressStyle::default_bar()
.template("{msg}\n{spinner:.green} [{bar:40.cyan/blue}] {pos}/{len} ({per_sec}, eta {eta})").unwrap()
Expand Down
4 changes: 2 additions & 2 deletions iroh/examples/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//! run this example from the project root:
//! $ cargo run --features=examples --example client
use indicatif::HumanBytes;
use iroh::{base::base32, client::docs::Entry, docs::store::Query, node::Node};
use iroh::{client::docs::Entry, docs::store::Query, node::Node};
use tokio_stream::StreamExt;

#[tokio::main]
Expand Down Expand Up @@ -37,7 +37,7 @@ fn fmt_entry(entry: &Entry) -> String {
let key = std::str::from_utf8(id.key()).unwrap_or("<bad key>");
let author = id.author().fmt_short();
let hash = entry.content_hash();
let hash = base32::fmt_short(hash.as_bytes());
let hash = hash.to_string();
let len = HumanBytes(entry.content_len());
format!("@{author}: {key} = {hash} ({len})",)
}

0 comments on commit 312e984

Please sign in to comment.