-
Notifications
You must be signed in to change notification settings - Fork 165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ticket): Ensure a ticket always has at least one address #892
Conversation
This makes it impossible to have a ticket with an empty address list. It makes the fields of the ticket private and also makes creating the ticket fallible. Both are probably good things for the public API and the latter e.g. allows us to add further checks like ensure the hash really exists.
src/provider/mod.rs
Outdated
} | ||
|
||
impl Ticket { | ||
fn new(hash: Hash, peer: PeerId, addrs: Vec<SocketAddr>, token: AuthToken) -> Result<Self> { | ||
ensure!(!addrs.is_empty(), "Invalid address list in ticket"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe more sth like, missing addresses?
tokio::spawn(async move { | ||
let (path, tmp_path) = if let Some(path) = path { | ||
let absolute = path.canonicalize()?; | ||
println!("Adding {} as {}...", path.display(), absolute.display()); | ||
(absolute, None) | ||
} else { | ||
// Store STDIN content into a temporary file | ||
let (file, path) = tempfile::NamedTempFile::new()?.into_parts(); | ||
let mut file = tokio::fs::File::from_std(file); | ||
let path_buf = path.to_path_buf(); | ||
// Copy from stdin to the file, until EOF | ||
tokio::io::copy(&mut tokio::io::stdin(), &mut file).await?; | ||
println!("Adding from stdin..."); | ||
// return the TempPath to keep it alive | ||
(path_buf, Some(path)) | ||
}; | ||
// tell the provider to add the data | ||
let stream = controller.server_streaming(ProvideRequest { path }).await?; | ||
let (hash, entries) = aggregate_add_response(stream).await?; | ||
print_add_response(hash, entries); | ||
let ticket = provider.ticket(hash)?; | ||
println!("All-in-one ticket: {ticket}"); | ||
anyhow::Ok(tmp_path) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this block is only indented, otherwise unchanged
This has the advantage that the provider itself can not construct the ticket directly and thus is forced to uphold the invariant that the address list must not be empty.
PTAL: I additionally moved the Ticket to it's own module. This ensures that the provider can not construct a ticket without upholding the invariant. Also the provider module is pretty huge by now, so splitting it up does no harm. |
This makes it impossible to have a ticket with an empty address list.
It makes the fields of the ticket private and also makes creating the
ticket fallible. Both are probably good things for the public API and
the latter e.g. allows us to add further checks like ensure the hash
really exists.