I’m trying to make a connection to retrieve data via a safe XOR URL on my local baby fleming network. I’m integrating the sn_api connection code into actix web framework in a similar way to the file_upload.rs and from tracing through the code in general.
When using the CLI (0.26), safe cat works fine:
RUST_LOG=“sn_api=debug,sn_client=debug,qp2p=trace” safe cat safe://hy8oyeyxzoxhyg638zk3y593u5h191ykfugjxw1zzkzyy41d5w86ii5593o
Head of log:
[sn_api::api::app::safe_client] DEBUG 2021-05-15T17:41:53.427081838 [sn_api/src/api/app/safe_client.rs:62] Connecting to SAFE Network...
[sn_api::api::app::safe_client] DEBUG 2021-05-15T17:41:53.427156709 [sn_api/src/api/app/safe_client.rs:69] Client to be instantiated with specific pk?: None
[sn_api::api::app::safe_client] DEBUG 2021-05-15T17:41:53.427176350 [sn_api/src/api/app/safe_client.rs:73] Bootstrap contacts list set to: Some({127.0.0.1:45261})
[sn_client::client] INFO 2021-05-15T17:41:53.427338126 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/sn_client-0.54.9/src/client/mod.rs:89] Client started for new randomly created pk: PublicKey::Ed25519(f4b2d5d6553cec29f27034b3e6dd4cda525f5105fd7ddc9b61d4aa486f7ac5c6)
[sn_client::config_handler] WARN 2021-05-15T17:41:53.427393128 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/sn_client-0.54.9/src/config_handler.rs:73] Failed to open config file from '/home/paul/.safe/client/sn_client.config': No such file or directory (os error 2)
[sn_client::config_handler] DEBUG 2021-05-15T17:41:53.427434912 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/sn_client-0.54.9/src/config_handler.rs:50] Bootstrapping contacts overriden with: {127.0.0.1:45261}
[sn_client::connections] DEBUG 2021-05-15T17:41:53.427480584 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/sn_client-0.54.9/src/connections/mod.rs:61] QP2p config: Config { hard_coded_contacts: {127.0.0.1:45261}, local_port: None, local_ip: None, forward_port: true, external_port: None, external_ip: None, max_msg_size_allowed: None, idle_timeout_msec: None, keep_alive_interval_msec: None, bootstrap_cache_dir: Some("/home/paul/.safe/client"), upnp_lease_duration: None }
[qp2p::api] DEBUG 2021-05-15T17:41:53.427534642 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/qp2p-0.11.9/src/api.rs:69] Config passed in to qp2p: Some(Config { hard_coded_contacts: {127.0.0.1:45261}, local_port: None, local_ip: None, forward_port: true, external_port: None, external_ip: None, max_msg_size_allowed: None, idle_timeout_msec: None, keep_alive_interval_msec: None, bootstrap_cache_dir: Some("/home/paul/.safe/client"), upnp_lease_duration: None })
[qp2p::api] DEBUG 2021-05-15T17:41:53.427558907 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/qp2p-0.11.9/src/api.rs:338] Realizing local IP by connecting to contacts
[qp2p::api] DEBUG 2021-05-15T17:41:53.427632492 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/qp2p-0.11.9/src/api.rs:71] Config decided on after unwrap and IGD in to qp2p: Config { hard_coded_contacts: {127.0.0.1:45261}, local_port: None, local_ip: Some(127.0.0.1), forward_port: true, external_port: None, external_ip: None, max_msg_size_allowed: None, idle_timeout_msec: None, keep_alive_interval_msec: None, bootstrap_cache_dir: Some("/home/paul/.safe/client"), upnp_lease_duration: None }
[qp2p::api] TRACE 2021-05-15T17:41:53.428021424 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/qp2p-0.11.9/src/api.rs:101] Peers in bootstrap cache: [127.0.0.1:34365, 127.0.0.1:35343, 127.0.0.1:35373, 127.0.0.1:41000, 127.0.0.1:45261, 127.0.0.1:55683, 127.0.0.1:60847]
[qp2p::api] TRACE 2021-05-15T17:41:53.428194927 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/qp2p-0.11.9/src/api.rs:214] Creating a new endpoint
[qp2p::api] TRACE 2021-05-15T17:41:53.428294445 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/qp2p-0.11.9/src/api.rs:231] Bound endpoint to local address: 127.0.0.1:57753
[qp2p::api] TRACE 2021-05-15T17:41:53.428338864 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/qp2p-0.11.9/src/api.rs:253] Bootstrapping with nodes [127.0.0.1:60847, 127.0.0.1:55683, 127.0.0.1:45261, 127.0.0.1:41000, 127.0.0.1:35373, 127.0.0.1:35343, 127.0.0.1:34365, 127.0.0.1:45261]
[qp2p::endpoint] TRACE 2021-05-15T17:41:53.436478681 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/qp2p-0.11.9/src/endpoint.rs:425] Successfully created new connection to peer: 127.0.0.1:60847
[qp2p::endpoint] TRACE 2021-05-15T17:41:53.438038538 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/qp2p-0.11.9/src/endpoint.rs:447] Connection exists in the connection pool: 127.0.0.1:60847
[sn_client::connections::listeners] DEBUG 2021-05-15T17:41:53.442350632 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/sn_client-0.54.9/src/connections/listeners.rs:100] GetSectionResponse::Success!
[sn_client::connections::listeners] DEBUG 2021-05-15T17:41:53.442391762 [/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/sn_client-0.54.9/src/connections/listeners.rs:188] Connecting to new set of Elders: {127.0.0.1:34365: 4ce4a8(01001100).., 127.0.0.1:35343: aebfeb(10101110).., 127.0.0.1:35373: 16e1b5(00010110).., 127.0.0.1:41000: 20f3b4(00100000).., 127.0.0.1:45261: ada93a(10101101).., 127.0.0.1:55683: e824db(11101000).., 127.0.0.1:60847: ddfa8e(11011101)..}
…
The output is the data at the safe URL as expected.
However, the process seems to get stuck when integrating with actix:
[2021-05-15T16:42:16Z DEBUG sn_api::api::app::safe_client] Connecting to SAFE Network...
[2021-05-15T16:42:16Z DEBUG sn_api::api::app::safe_client] Client to be instantiated with specific pk?: None
[2021-05-15T16:42:16Z DEBUG sn_api::api::app::safe_client] Bootstrap contacts list set to: Some({127.0.0.1:45261})
[2021-05-15T16:42:16Z INFO sn_client::client] Client started for new randomly created pk: PublicKey::Ed25519(2d5d3fcbfb6dc35e25bca35ae329bb15d51b17f5f84d0b19bcf94b9a364e8d32)
[2021-05-15T16:42:16Z WARN sn_client::config_handler] Failed to open config file from '/home/paul/.safe/client/sn_client.config': No such file or directory (os error 2)
[2021-05-15T16:42:16Z DEBUG sn_client::config_handler] Bootstrapping contacts overriden with: {127.0.0.1:45261}
[2021-05-15T16:42:16Z DEBUG sn_client::connections] QP2p config: Config { hard_coded_contacts: {127.0.0.1:45261}, local_port: None, local_ip: None, forward_port: true, external_port: None, external_ip: None, max_msg_size_allowed: None, idle_timeout_msec: None, keep_alive_interval_msec: None, bootstrap_cache_dir: Some("/home/paul/.safe/client"), upnp_lease_duration: None }
[2021-05-15T16:42:16Z DEBUG qp2p::api] Config passed in to qp2p: Some(Config { hard_coded_contacts: {127.0.0.1:45261}, local_port: None, local_ip: None, forward_port: true, external_port: None, external_ip: None, max_msg_size_allowed: None, idle_timeout_msec: None, keep_alive_interval_msec: None, bootstrap_cache_dir: Some("/home/paul/.safe/client"), upnp_lease_duration: None })
[2021-05-15T16:42:16Z DEBUG qp2p::api] Realizing local IP by connecting to contacts
[2021-05-15T16:42:16Z DEBUG qp2p::api] Config decided on after unwrap and IGD in to qp2p: Config { hard_coded_contacts: {127.0.0.1:45261}, local_port: None, local_ip: Some(127.0.0.1), forward_port: true, external_port: None, external_ip: None, max_msg_size_allowed: None, idle_timeout_msec: None, keep_alive_interval_msec: None, bootstrap_cache_dir: Some("/home/paul/.safe/client"), upnp_lease_duration: None }
[2021-05-15T16:42:16Z TRACE qp2p::api] Peers in bootstrap cache: [127.0.0.1:34365, 127.0.0.1:35343, 127.0.0.1:35373, 127.0.0.1:41000, 127.0.0.1:45261, 127.0.0.1:55683, 127.0.0.1:60847]
[2021-05-15T16:42:16Z TRACE qp2p::api] Creating a new endpoint
[2021-05-15T16:42:16Z TRACE qp2p::api] Bound endpoint to local address: 127.0.0.1:37693
[2021-05-15T16:42:16Z TRACE qp2p::api] Bootstrapping with nodes [127.0.0.1:60847, 127.0.0.1:55683, 127.0.0.1:45261, 127.0.0.1:41000, 127.0.0.1:35373, 127.0.0.1:35343, 127.0.0.1:34365, 127.0.0.1:45261]
[2021-05-15T16:42:16Z TRACE qp2p::endpoint] Successfully created new connection to peer: 127.0.0.1:60847
[2021-05-15T16:42:16Z TRACE qp2p::endpoint] Connection exists in the connection pool: 127.0.0.1:60847
[2021-05-15T16:42:46Z TRACE qp2p::api] Bootstrapping with nodes [127.0.0.1:34365, 127.0.0.1:35343, 127.0.0.1:35373, 127.0.0.1:41000, 127.0.0.1:45261, 127.0.0.1:55683]
[2021-05-15T16:42:46Z TRACE qp2p::endpoint] Successfully created new connection to peer: 127.0.0.1:35343
[2021-05-15T16:43:16Z TRACE qp2p::api] Bootstrapping with nodes [127.0.0.1:34365, 127.0.0.1:35373, 127.0.0.1:41000, 127.0.0.1:45261, 127.0.0.1:55683]
[2021-05-15T16:43:16Z TRACE qp2p::endpoint] Successfully created new connection to peer: 127.0.0.1:34365
[2021-05-15T16:43:46Z TRACE qp2p::api] Bootstrapping with nodes [127.0.0.1:35373, 127.0.0.1:41000, 127.0.0.1:45261, 127.0.0.1:55683]
[2021-05-15T16:43:46Z TRACE qp2p::endpoint] Successfully created new connection to peer: 127.0.0.1:35373
[2021-05-15T16:44:16Z TRACE qp2p::api] Bootstrapping with nodes [127.0.0.1:41000, 127.0.0.1:45261, 127.0.0.1:55683]
[2021-05-15T16:44:16Z TRACE qp2p::endpoint] Successfully created new connection to peer: 127.0.0.1:41000
[2021-05-15T16:44:46Z TRACE qp2p::api] Bootstrapping with nodes [127.0.0.1:45261, 127.0.0.1:55683]
[2021-05-15T16:44:46Z TRACE qp2p::endpoint] Successfully created new connection to peer: 127.0.0.1:55683
[2021-05-15T16:45:16Z TRACE qp2p::api] Bootstrapping with nodes [127.0.0.1:45261]
[2021-05-15T16:45:16Z TRACE qp2p::endpoint] Successfully created new connection to peer: 127.0.0.1:45261
[2021-05-15T16:45:46Z TRACE qp2p::api] Bootstrapping with nodes []
[2021-05-15T16:45:46Z TRACE qp2p::api] Creating a new endpoint
[2021-05-15T16:45:46Z TRACE qp2p::api] Bound endpoint to local address: 127.0.0.1:59113
[2021-05-15T16:45:46Z TRACE qp2p::api] Bootstrapping with nodes [127.0.0.1:45261]
[2021-05-15T16:45:46Z TRACE qp2p::endpoint] Successfully created new connection to peer: 127.0.0.1:45261
[2021-05-15T16:45:46Z TRACE qp2p::endpoint] Connection exists in the connection pool: 127.0.0.1:45261
[2021-05-15T16:46:16Z TRACE qp2p::api] Bootstrapping with nodes []
[2021-05-15T16:46:16Z TRACE qp2p::api] Creating a new endpoint
[2021-05-15T16:46:16Z TRACE qp2p::api] Bound endpoint to local address: 127.0.0.1:49637
[2021-05-15T16:46:16Z TRACE qp2p::api] Bootstrapping with nodes [127.0.0.1:45261]
[2021-05-15T16:46:16Z TRACE qp2p::endpoint] Successfully created new connection to peer: 127.0.0.1:45261
[2021-05-15T16:46:16Z TRACE qp2p::endpoint] Connection exists in the connection pool: 127.0.0.1:45261
[2021-05-15T16:46:46Z TRACE qp2p::api] Bootstrapping with nodes []
thread 'actix-rt|system:0|arbiter:0' panicked at 'called `Result::unwrap()` on an `Err` value: ConnectionError("Failed to connect to the SAFE Network: QuicP2p(EmptyBootstrapNodesList)")', src/main.rs:63:98
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
The source code is as rough as you like. This is my first exploration into rust, so I’m just hacking it together until I can figure out how it ticks!
#[get("/xor/{xor}")]
async fn xor(info: web::Path<String>) -> impl Responder {
let info = info.into_inner();
//let url = ["safe://", xor].join();
let xorurl = format!("safe://{}", info);
println!("xor [{}], url [{}]", info, xorurl);
// The Safe instance is what will give us access to the API.
let mut safe = Safe::default();
let app_keypair = if let Ok((_, keypair)) = read_credentials() {
keypair
} else {
None
};
let found_app_keypair = app_keypair.is_some();
if !found_app_keypair {
info!("No credentials found for CLI, connecting with read-only access...");
}
// We assume there is a local network running which we can
// bootstrap to using 127.0.0.1:12000 contact address.
let mut bootstrap_contacts = BootstrapConfig::default();
bootstrap_contacts.insert("127.0.0.1:45261".parse().unwrap());
println!("bootstrap insert");
// Using our afe instance we connect to the network
let config_path = Path::new("/home/paul/.safe/client/sn_client.config");
safe.connect(app_keypair.clone(), Some(config_path), Some(bootstrap_contacts.clone())).await.unwrap();
println!("safe connected");
// Now we can simply fetch the file using `fetch` API,
// it will return not only thee content of the file
// but its metadata too so we can distinguish what has
// been fetched from the provided Safe-URL.
let mut url = SafeUrl::from_url(&xorurl).unwrap();
let fetched = safe.fetch(&url.to_string(), None).await;
if let Ok(SafeData::PublicBlob { data, .. }) = fetched {
let data = String::from_utf8(data).unwrap();
println!("Content retrieved:\n{}", data);
return HttpResponse::Ok().body(data);
} else {
println!("Failed to retrieve Blob, obtained: {:?}", fetched);
}
HttpResponse::BadRequest().body("failed")
}
I’ve added more and more to the above to make it identical as far as I can see from adding trace logs.
Dependencies are:
[dependencies]
actix-web = "4.0.0-beta.6"
sn_api = "0.26.0"
anyhow = "1.0.38"
log = "~0.4"
env_logger = "~0.8"
serde_json = "1.0.62"
dirs-next = "2.0.0"
I’ve not committed anything anywhere yet, but I can do so if it helps.
Any ideas as to why it is stalling? The node logs show activity for the CLI attempt, but nothing when I call via the above. It looks as if the nodes are just ignoring my requests.
It’s good to be playing around with this stuff. I’m working on a simple blogging app that can work on both safe and via a web gateway when needed. I wanted a wee project to get to grips with rust and to brush up my front end skills again!