clean up
This commit is contained in:
@@ -5,9 +5,7 @@ use std::time::{Duration, Instant};
|
||||
|
||||
use anyhow::{Error, anyhow, bail};
|
||||
use bitcoin_hashes::sha1::Hash as Sha1Hash;
|
||||
use gpui::{
|
||||
App, AppContext, AsyncApp, Context, Entity, EventEmitter, Global, Task, TaskExt, WeakEntity,
|
||||
};
|
||||
use gpui::{App, AppContext, AsyncApp, Context, Entity, EventEmitter, Global, Task, TaskExt};
|
||||
use nostr::event::IntoEventBuilder;
|
||||
use nostr::nips::nip19::Nip19Coordinate;
|
||||
use nostr_connect::prelude::*;
|
||||
@@ -194,7 +192,7 @@ impl Backend {
|
||||
this.set_signer(keys, cx);
|
||||
})?;
|
||||
} else if content.starts_with("bunker://") {
|
||||
let (base, keys) = extract_master_key(&content);
|
||||
let (base, keys) = extract_master_key(&content)?;
|
||||
let uri = NostrConnectUri::parse(base)?;
|
||||
let mut signer = NostrConnect::new(
|
||||
uri,
|
||||
@@ -463,7 +461,7 @@ impl Backend {
|
||||
let event = builder.finalize_async(&signer).await?;
|
||||
let output = client.send_event(&event).broadcast().await?;
|
||||
|
||||
if output.success.is_empty() && !output.failed.is_empty() {
|
||||
if output.success.is_empty() {
|
||||
let reasons = output
|
||||
.failed
|
||||
.values()
|
||||
@@ -539,7 +537,7 @@ impl Backend {
|
||||
folder.join(dir_name)
|
||||
};
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
cx.spawn(async move |_this, cx| {
|
||||
let work = cx.background_spawn({
|
||||
let destination = destination.clone();
|
||||
let name = name.clone();
|
||||
@@ -577,7 +575,6 @@ impl Backend {
|
||||
);
|
||||
|
||||
let event = announce_repository_and_push(
|
||||
&this,
|
||||
&client,
|
||||
&signer,
|
||||
announcement,
|
||||
@@ -643,7 +640,7 @@ impl Backend {
|
||||
let client = self.client.clone();
|
||||
let signer = self.signer.clone();
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
cx.spawn(async move |_this, cx| {
|
||||
let (mut state, euc) = cx
|
||||
.background_spawn({
|
||||
let path = path.clone();
|
||||
@@ -672,7 +669,6 @@ impl Backend {
|
||||
let ann = build_announcement(&repo_id, &name, &description, &owner, &servers, euc);
|
||||
|
||||
let event = announce_repository_and_push(
|
||||
&this,
|
||||
&client,
|
||||
&signer,
|
||||
ann,
|
||||
@@ -1155,11 +1151,15 @@ impl Backend {
|
||||
cx.background_spawn(async move {
|
||||
let builder = EventDeletionRequest::new().id(event.id);
|
||||
let deletion = builder.finalize_async(&signer).await?;
|
||||
client.send_event(&deletion).broadcast().await?;
|
||||
let output = client.send_event(&deletion).broadcast().await?;
|
||||
|
||||
Ok::<(), anyhow::Error>(())
|
||||
if output.success.is_empty() {
|
||||
bail!("deletion event not accepted by any relay");
|
||||
}
|
||||
|
||||
Ok::<(), Error>(())
|
||||
})
|
||||
.detach();
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1190,7 +1190,6 @@ fn build_announcement(
|
||||
// Announce the repository, then stage the state event and push.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn announce_repository_and_push(
|
||||
backend: &WeakEntity<Backend>,
|
||||
client: &Client,
|
||||
signer: &UniversalSigner,
|
||||
announcement: GitRepositoryAnnouncement,
|
||||
@@ -1204,13 +1203,15 @@ async fn announce_repository_and_push(
|
||||
push: impl Fn(&Path, &str, &str, &str) -> Result<(), Error> + Send + 'static,
|
||||
) -> Result<Event, Error> {
|
||||
for url in servers {
|
||||
client.add_relay(url).and_connect().await.ok();
|
||||
if let Err(e) = client.add_relay(url).and_connect().await {
|
||||
log::warn!("failed to connect grasp relay {url}: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
let event = announcement.finalize_async(signer).await?;
|
||||
let output = client.send_event(&event).broadcast().await?;
|
||||
|
||||
if output.success.is_empty() && !output.failed.is_empty() {
|
||||
if output.success.is_empty() {
|
||||
let reasons = output
|
||||
.failed
|
||||
.values()
|
||||
@@ -1252,17 +1253,34 @@ async fn announce_repository_and_push(
|
||||
|
||||
if outcome.accepted() == 0 {
|
||||
// Retract the announcement so the repository is not left announced without content.
|
||||
backend
|
||||
.update(cx, |backend, cx| {
|
||||
backend.retract_events(std::slice::from_ref(&event), cx);
|
||||
})
|
||||
.ok();
|
||||
let retracted = async {
|
||||
let deletion = EventDeletionRequest::new()
|
||||
.id(event.id)
|
||||
.finalize_async(signer)
|
||||
.await?;
|
||||
let output = client.send_event(&deletion).broadcast().await?;
|
||||
|
||||
return Err(anyhow!(
|
||||
"The repository was announced, but the push to every grasp server failed: {}. \
|
||||
The announcement has been retracted",
|
||||
outcome.failure_summary()
|
||||
));
|
||||
// Without relay acceptance the deletion request stays live.
|
||||
if output.success.is_empty() {
|
||||
bail!("deletion event not accepted by any relay");
|
||||
}
|
||||
|
||||
Ok::<(), Error>(())
|
||||
}
|
||||
.await;
|
||||
|
||||
return Err(match retracted {
|
||||
Ok(()) => anyhow!(
|
||||
"The repository was announced, but the push to every grasp server failed: {}. \
|
||||
The announcement has been retracted",
|
||||
outcome.failure_summary()
|
||||
),
|
||||
Err(e) => anyhow!(
|
||||
"The repository was announced, but the push to every grasp server failed: {}. \
|
||||
Retracting the announcement failed: {e}; delete the repository to clean it up",
|
||||
outcome.failure_summary()
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
// Fan the state out to the relays once a git server holds the objects.
|
||||
@@ -1313,15 +1331,13 @@ impl UpdateEvent {
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_master_key(credential: &str) -> (&str, Keys) {
|
||||
fn extract_master_key(credential: &str) -> Result<(&str, Keys), Error> {
|
||||
match credential.split_once("master=") {
|
||||
Some((base, nsec)) => {
|
||||
let keys = SecretKey::parse(nsec)
|
||||
.map(Keys::new)
|
||||
.unwrap_or_else(|_| Keys::generate());
|
||||
(base.trim_end_matches(['?', '&']), keys)
|
||||
let keys = Keys::new(SecretKey::parse(nsec)?);
|
||||
Ok((base.trim_end_matches(['?', '&']), keys))
|
||||
}
|
||||
None => (credential, Keys::generate()),
|
||||
None => Ok((credential, Keys::generate())),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user