diff --git a/.gitignore b/.gitignore
index 443c90e76..197b77ae6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,3 +82,4 @@ spacedrive
.cargo/config.toml
.github/scripts/deps
.vite-inspect
+vite.config.ts.*
diff --git a/Cargo.lock b/Cargo.lock
index 6e67ccba5..72bbfc55d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -76,11 +76,23 @@ version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd"
dependencies = [
- "getrandom 0.2.11",
+ "getrandom 0.2.12",
"once_cell",
"version_check",
]
+[[package]]
+name = "ahash"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "version_check",
+ "zerocopy",
+]
+
[[package]]
name = "aho-corasick"
version = "0.7.20"
@@ -114,6 +126,12 @@ dependencies = [
"alloc-no-stdlib",
]
+[[package]]
+name = "allocator-api2"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
+
[[package]]
name = "android-tzdata"
version = "0.1.1"
@@ -369,9 +387,9 @@ dependencies = [
[[package]]
name = "async-trait"
-version = "0.1.75"
+version = "0.1.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98"
+checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
dependencies = [
"proc-macro2",
"quote",
@@ -945,9 +963,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64"
-version = "0.21.5"
+version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9"
+checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64-simd"
@@ -1197,7 +1215,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c"
dependencies = [
"memchr",
- "regex-automata 0.4.3",
+ "regex-automata 0.4.5",
"serde",
]
@@ -1389,7 +1407,7 @@ version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3431df59f28accaf4cb4eed4a9acc66bea3f3c3753aa6cdc2f024174ef232af7"
dependencies = [
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
]
[[package]]
@@ -1398,7 +1416,7 @@ version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03915af431787e6ffdcc74c645077518c6b6e01f80b761e0fbbfa288536311b3"
dependencies = [
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"target-lexicon",
]
@@ -1866,7 +1884,7 @@ dependencies = [
"phf 0.8.0",
"proc-macro2",
"quote",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"syn 1.0.109",
]
@@ -2506,7 +2524,7 @@ dependencies = [
"lebe",
"miniz_oxide",
"rayon-core",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"zune-inflate",
]
@@ -2759,9 +2777,9 @@ dependencies = [
[[package]]
name = "futures"
-version = "0.3.29"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335"
+checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
dependencies = [
"futures-channel",
"futures-core",
@@ -2775,8 +2793,7 @@ dependencies = [
[[package]]
name = "futures-bounded"
version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1e2774cc104e198ef3d3e1ff4ab40f86fa3245d6cb6a3a46174f21463cee173"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"futures-timer",
"futures-util",
@@ -2784,9 +2801,9 @@ dependencies = [
[[package]]
name = "futures-channel"
-version = "0.3.29"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"
+checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
dependencies = [
"futures-core",
"futures-sink",
@@ -2802,7 +2819,7 @@ dependencies = [
"futures-core",
"pin-project",
"slab",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
]
[[package]]
@@ -2813,9 +2830,9 @@ checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-executor"
-version = "0.3.29"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc"
+checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
dependencies = [
"futures-core",
"futures-task",
@@ -2825,9 +2842,9 @@ dependencies = [
[[package]]
name = "futures-io"
-version = "0.3.29"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
+checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-lite"
@@ -2867,9 +2884,9 @@ dependencies = [
[[package]]
name = "futures-macro"
-version = "0.3.29"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
+checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
@@ -2888,15 +2905,15 @@ dependencies = [
[[package]]
name = "futures-sink"
-version = "0.3.29"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
+checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
[[package]]
name = "futures-task"
-version = "0.3.29"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"
+checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
[[package]]
name = "futures-ticker"
@@ -2917,9 +2934,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
[[package]]
name = "futures-util"
-version = "0.3.29"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
+checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-channel",
"futures-core",
@@ -3050,9 +3067,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.11"
+version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
+checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
dependencies = [
"cfg-if",
"js-sys",
@@ -3133,7 +3150,7 @@ dependencies = [
"gobject-sys",
"libc",
"once_cell",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"thiserror",
]
@@ -3177,7 +3194,7 @@ dependencies = [
"aho-corasick 1.1.2",
"bstr",
"log",
- "regex-automata 0.4.3",
+ "regex-automata 0.4.5",
"regex-syntax 0.8.2",
"serde",
]
@@ -3299,13 +3316,19 @@ dependencies = [
"num-traits",
]
+[[package]]
+name = "hash_map_diff"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff9168f8bc101ee284e882004680c32a048cd8076bc4c134443ff0f5dd302610"
+
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
dependencies = [
- "ahash",
+ "ahash 0.7.7",
]
[[package]]
@@ -3314,7 +3337,7 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
dependencies = [
- "ahash",
+ "ahash 0.7.7",
]
[[package]]
@@ -3322,6 +3345,10 @@ name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
+dependencies = [
+ "ahash 0.8.8",
+ "allocator-api2",
+]
[[package]]
name = "hashlink"
@@ -3338,7 +3365,7 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270"
dependencies = [
- "base64 0.21.5",
+ "base64 0.21.7",
"bytes",
"headers-core",
"http",
@@ -3429,7 +3456,7 @@ dependencies = [
"parking_lot 0.12.1",
"rand 0.8.5",
"resolv-conf",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"thiserror",
"tokio",
"tracing",
@@ -3554,7 +3581,7 @@ source = "git+https://github.com/spacedriveapp/rspc.git?rev=f3347e2e8bfe3f37bfac
dependencies = [
"async-tungstenite",
"axum",
- "base64 0.21.5",
+ "base64 0.21.7",
"cookie",
"form_urlencoded",
"futures",
@@ -3713,9 +3740,9 @@ dependencies = [
[[package]]
name = "igd-next"
-version = "0.14.2"
+version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57e065e90a518ab5fedf79aa1e4b784e10f8e484a834f6bda85c42633a2cb7af"
+checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4"
dependencies = [
"async-trait",
"attohttpc",
@@ -3740,7 +3767,7 @@ dependencies = [
"globset",
"log",
"memchr",
- "regex-automata 0.4.3",
+ "regex-automata 0.4.5",
"same-file",
"walkdir",
"winapi-util",
@@ -4158,9 +4185,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
name = "libc"
-version = "0.2.151"
+version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
+checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libdbus-sys"
@@ -4225,14 +4252,13 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
[[package]]
name = "libp2p"
version = "0.53.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "681fb3f183edfbedd7a57d32ebe5dcdc0b9f94061185acf3c30249349cc6fc99"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"bytes",
"either",
"futures",
"futures-timer",
- "getrandom 0.2.11",
+ "getrandom 0.2.12",
"instant",
"libp2p-allow-block-list",
"libp2p-connection-limits",
@@ -4242,7 +4268,7 @@ dependencies = [
"libp2p-identity",
"libp2p-kad",
"libp2p-mdns",
- "libp2p-quic",
+ "libp2p-quic 0.10.2 (git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c)",
"libp2p-swarm",
"libp2p-tcp",
"libp2p-upnp",
@@ -4255,8 +4281,7 @@ dependencies = [
[[package]]
name = "libp2p-allow-block-list"
version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "107b238b794cb83ab53b74ad5dcf7cca3200899b72fe662840cfb52f5b0a32e6"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"libp2p-core",
"libp2p-identity",
@@ -4267,8 +4292,7 @@ dependencies = [
[[package]]
name = "libp2p-connection-limits"
version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7cd50a78ccfada14de94cbacd3ce4b0138157f376870f13d3a8422cd075b4fd"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"libp2p-core",
"libp2p-identity",
@@ -4279,8 +4303,7 @@ dependencies = [
[[package]]
name = "libp2p-core"
version = "0.41.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8130a8269e65a2554d55131c770bdf4bcd94d2b8d4efb24ca23699be65066c05"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"either",
"fnv",
@@ -4298,7 +4321,7 @@ dependencies = [
"rand 0.8.5",
"rw-stream-sink",
"serde",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"thiserror",
"tracing",
"unsigned-varint 0.8.0",
@@ -4308,8 +4331,7 @@ dependencies = [
[[package]]
name = "libp2p-dns"
version = "0.41.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d17cbcf7160ff35c3e8e560de4a068fe9d6cb777ea72840e48eb76ff9576c4b6"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"async-trait",
"futures",
@@ -4317,25 +4339,24 @@ dependencies = [
"libp2p-core",
"libp2p-identity",
"parking_lot 0.12.1",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"tracing",
]
[[package]]
name = "libp2p-gossipsub"
version = "0.46.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d665144a616dadebdc5fff186b1233488cdcd8bfb1223218ff084b6d052c94f7"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"asynchronous-codec",
- "base64 0.21.5",
+ "base64 0.21.7",
"byteorder",
"bytes",
"either",
"fnv",
"futures",
"futures-ticker",
- "getrandom 0.2.11",
+ "getrandom 0.2.12",
"hex_fmt",
"instant",
"libp2p-core",
@@ -4348,7 +4369,7 @@ dependencies = [
"regex",
"serde",
"sha2 0.10.8",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"tracing",
"void",
]
@@ -4374,9 +4395,8 @@ dependencies = [
[[package]]
name = "libp2p-kad"
-version = "0.45.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cc5767727d062c4eac74dd812c998f0e488008e82cce9c33b463d38423f9ad2"
+version = "0.45.4"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"arrayvec",
"asynchronous-codec",
@@ -4395,7 +4415,7 @@ dependencies = [
"rand 0.8.5",
"serde",
"sha2 0.10.8",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"thiserror",
"tracing",
"uint",
@@ -4405,8 +4425,7 @@ dependencies = [
[[package]]
name = "libp2p-mdns"
version = "0.45.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49007d9a339b3e1d7eeebc4d67c05dbf23d300b7d091193ec2d3f26802d7faf2"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"data-encoding",
"futures",
@@ -4416,7 +4435,7 @@ dependencies = [
"libp2p-identity",
"libp2p-swarm",
"rand 0.8.5",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"socket2 0.5.5",
"tokio",
"tracing",
@@ -4435,7 +4454,7 @@ dependencies = [
"if-watch",
"libp2p-core",
"libp2p-identity",
- "libp2p-tls",
+ "libp2p-tls 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.12.1",
"quinn",
"rand 0.8.5",
@@ -4447,11 +4466,47 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "libp2p-quic"
+version = "0.10.2"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
+dependencies = [
+ "bytes",
+ "futures",
+ "futures-timer",
+ "if-watch",
+ "libp2p-core",
+ "libp2p-identity",
+ "libp2p-tls 0.3.0 (git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c)",
+ "parking_lot 0.12.1",
+ "quinn",
+ "rand 0.8.5",
+ "ring 0.16.20",
+ "rustls",
+ "socket2 0.5.5",
+ "thiserror",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "libp2p-stream"
+version = "0.1.0-alpha"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
+dependencies = [
+ "futures",
+ "libp2p-core",
+ "libp2p-identity",
+ "libp2p-swarm",
+ "rand 0.8.5",
+ "tracing",
+ "void",
+]
+
[[package]]
name = "libp2p-swarm"
-version = "0.44.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e92532fc3c4fb292ae30c371815c9b10103718777726ea5497abc268a4761866"
+version = "0.44.2"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"either",
"fnv",
@@ -4460,10 +4515,11 @@ dependencies = [
"instant",
"libp2p-core",
"libp2p-identity",
+ "lru 0.12.2",
"multistream-select",
"once_cell",
"rand 0.8.5",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"tokio",
"tracing",
"void",
@@ -4472,8 +4528,7 @@ dependencies = [
[[package]]
name = "libp2p-tcp"
version = "0.41.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b2460fc2748919adff99ecbc1aab296e4579e41f374fb164149bd2c9e529d4c"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"futures",
"futures-timer",
@@ -4505,11 +4560,28 @@ dependencies = [
"yasna",
]
+[[package]]
+name = "libp2p-tls"
+version = "0.3.0"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
+dependencies = [
+ "futures",
+ "futures-rustls",
+ "libp2p-core",
+ "libp2p-identity",
+ "rcgen",
+ "ring 0.16.20",
+ "rustls",
+ "rustls-webpki",
+ "thiserror",
+ "x509-parser",
+ "yasna",
+]
+
[[package]]
name = "libp2p-upnp"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "963eb8a174f828f6a51927999a9ab5e45dfa9aa2aa5fed99aa65f79de6229464"
+version = "0.2.1"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"futures",
"futures-timer",
@@ -4620,6 +4692,15 @@ dependencies = [
"hashbrown 0.12.3",
]
+[[package]]
+name = "lru"
+version = "0.12.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db2c024b41519440580066ba82aab04092b333e09066a5eb86c7c4890df31f22"
+dependencies = [
+ "hashbrown 0.14.3",
+]
+
[[package]]
name = "lru-cache"
version = "0.1.2"
@@ -4807,7 +4888,7 @@ version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e52eb6380b6d2a10eb3434aec0885374490f5b82c8aaf5cd487a183c98be834"
dependencies = [
- "ahash",
+ "ahash 0.7.7",
"metrics-macros",
]
@@ -4817,7 +4898,7 @@ version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "142c53885123b68d94108295a09d4afe1a1388ed95b54d5dacd9a454753030f2"
dependencies = [
- "ahash",
+ "ahash 0.7.7",
"metrics-macros",
]
@@ -4914,7 +4995,7 @@ dependencies = [
"crossbeam-utils",
"dashmap",
"skeptic",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"tagptr",
"triomphe",
]
@@ -5016,15 +5097,14 @@ dependencies = [
[[package]]
name = "multistream-select"
version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea0df8e5eec2298a62b326ee4f0d7fe1a6b90a09dfcf9df37b38f947a8c42f19"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"bytes",
"futures",
- "log",
"pin-project",
- "smallvec 1.11.2",
- "unsigned-varint 0.7.2",
+ "smallvec 1.13.1",
+ "tracing",
+ "unsigned-varint 0.8.0",
]
[[package]]
@@ -5048,7 +5128,7 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
dependencies = [
- "getrandom 0.2.11",
+ "getrandom 0.2.12",
]
[[package]]
@@ -5198,7 +5278,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43"
dependencies = [
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
]
[[package]]
@@ -5225,6 +5305,12 @@ dependencies = [
"libc",
]
+[[package]]
+name = "no-std-compat"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df270209a7f04d62459240d890ecb792714d5db12c92937823574a09930276b4"
+
[[package]]
name = "nodrop"
version = "0.1.14"
@@ -5768,7 +5854,7 @@ dependencies = [
"instant",
"libc",
"redox_syscall 0.2.16",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"winapi",
]
@@ -5781,7 +5867,7 @@ dependencies = [
"cfg-if",
"libc",
"redox_syscall 0.4.1",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"windows-targets 0.48.5",
]
@@ -5859,7 +5945,7 @@ version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310"
dependencies = [
- "base64 0.21.5",
+ "base64 0.21.7",
"serde",
]
@@ -6066,18 +6152,18 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]]
name = "pin-project"
-version = "1.1.3"
+version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422"
+checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
-version = "1.1.3"
+version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
+checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690"
dependencies = [
"proc-macro2",
"quote",
@@ -6140,7 +6226,7 @@ version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5699cc8a63d1aa2b1ee8e12b9ad70ac790d65788cd36101fa37f87ea46c4cef"
dependencies = [
- "base64 0.21.5",
+ "base64 0.21.7",
"indexmap 2.2.1",
"line-wrap",
"quick-xml",
@@ -6446,9 +6532,9 @@ dependencies = [
[[package]]
name = "prometheus-client"
-version = "0.22.0"
+version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "510c4f1c9d81d556458f94c98f857748130ea9737bbd6053da497503b26ea63c"
+checksum = "6f87c10af16e0af74010d2a123d202e8363c04db5acfa91d8747f64a8524da3a"
dependencies = [
"dtoa",
"itoa 1.0.10",
@@ -6597,7 +6683,7 @@ dependencies = [
"futures",
"indexmap 1.9.3",
"itertools 0.10.5",
- "lru",
+ "lru 0.7.8",
"once_cell",
"opentelemetry",
"petgraph",
@@ -6653,8 +6739,7 @@ dependencies = [
[[package]]
name = "quick-protobuf-codec"
version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15a0580ab32b169745d7a39db2ba969226ca16738931be152a3209b409de2474"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"asynchronous-codec",
"bytes",
@@ -6833,7 +6918,7 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
- "getrandom 0.2.11",
+ "getrandom 0.2.12",
]
[[package]]
@@ -6946,20 +7031,20 @@ version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
dependencies = [
- "getrandom 0.2.11",
+ "getrandom 0.2.12",
"libredox",
"thiserror",
]
[[package]]
name = "regex"
-version = "1.10.2"
+version = "1.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
+checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
dependencies = [
"aho-corasick 1.1.2",
"memchr",
- "regex-automata 0.4.3",
+ "regex-automata 0.4.5",
"regex-syntax 0.8.2",
]
@@ -6974,9 +7059,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.3"
+version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
+checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
dependencies = [
"aho-corasick 1.1.2",
"memchr",
@@ -7034,7 +7119,7 @@ version = "0.11.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41"
dependencies = [
- "base64 0.21.5",
+ "base64 0.21.7",
"bytes",
"encoding_rs",
"futures-core",
@@ -7161,7 +7246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74"
dependencies = [
"cc",
- "getrandom 0.2.11",
+ "getrandom 0.2.12",
"libc",
"spin 0.9.8",
"untrusted 0.9.0",
@@ -7257,7 +7342,7 @@ dependencies = [
"hashlink",
"libsqlite3-sys",
"memchr",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
]
[[package]]
@@ -7347,7 +7432,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
- "base64 0.21.5",
+ "base64 0.21.7",
]
[[package]]
@@ -7374,7 +7459,7 @@ checksum = "71cd15fef9112a1f94ac64b58d1e4628192631ad6af4dc69997f995459c874e7"
dependencies = [
"bitflags 1.3.2",
"bytemuck",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"ttf-parser",
"unicode-bidi-mirroring",
"unicode-ccc",
@@ -7385,8 +7470,7 @@ dependencies = [
[[package]]
name = "rw-stream-sink"
version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8c9026ff5d2f23da5e45bbc283f156383001bfb09c4e44256d02c1a685fe9a1"
+source = "git+https://github.com/spacedriveapp/rust-libp2p.git?rev=a005656df7e82059a0eb2e333ebada4731d23f8c#a005656df7e82059a0eb2e333ebada4731d23f8c"
dependencies = [
"futures",
"pin-project",
@@ -7570,10 +7654,10 @@ dependencies = [
name = "sd-cloud-api"
version = "0.1.0"
dependencies = [
- "base64 0.21.5",
+ "base64 0.21.7",
"reqwest",
"rspc",
- "sd-p2p",
+ "sd-p2p2",
"serde",
"serde_json",
"specta",
@@ -7594,7 +7678,7 @@ dependencies = [
"aws-credential-types",
"aws-sdk-s3",
"axum",
- "base64 0.21.5",
+ "base64 0.21.7",
"base91",
"blake3",
"bytes",
@@ -7636,7 +7720,10 @@ dependencies = [
"sd-file-path-helper",
"sd-images",
"sd-media-metadata",
- "sd-p2p",
+ "sd-p2p-block",
+ "sd-p2p-proto",
+ "sd-p2p-tunnel",
+ "sd-p2p2",
"sd-prisma",
"sd-sync",
"sd-utils",
@@ -7891,24 +7978,58 @@ dependencies = [
]
[[package]]
-name = "sd-p2p"
+name = "sd-p2p-block"
version = "0.1.0"
dependencies = [
- "base64 0.21.5",
+ "sd-p2p-proto",
+ "sd-p2p2",
+ "thiserror",
+ "tokio",
+ "tracing",
+ "uuid",
+]
+
+[[package]]
+name = "sd-p2p-proto"
+version = "0.1.0"
+dependencies = [
+ "ed25519-dalek",
+ "thiserror",
+ "tokio",
+ "uuid",
+]
+
+[[package]]
+name = "sd-p2p-tunnel"
+version = "0.1.0"
+dependencies = [
+ "sd-p2p2",
+ "tokio",
+]
+
+[[package]]
+name = "sd-p2p2"
+version = "0.2.0"
+dependencies = [
+ "base64 0.21.7",
"base91",
"ed25519-dalek",
"flume 0.11.0",
"futures-core",
+ "hash_map_diff",
"if-watch",
"libp2p",
- "libp2p-quic",
+ "libp2p-quic 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-stream",
"mdns-sd",
"pin-project-lite",
"rand_core 0.6.4",
"serde",
"sha256",
"specta",
+ "stable-vec",
"streamunordered",
+ "sync_wrapper",
"thiserror",
"tokio",
"tokio-stream",
@@ -8050,7 +8171,7 @@ dependencies = [
"phf_codegen 0.8.0",
"precomputed-hash",
"servo_arc",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"thin-slice",
]
@@ -8171,7 +8292,7 @@ version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23"
dependencies = [
- "base64 0.21.5",
+ "base64 0.21.7",
"chrono",
"hex",
"indexmap 1.9.3",
@@ -8414,9 +8535,9 @@ dependencies = [
[[package]]
name = "smallvec"
-version = "1.11.2"
+version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
+checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]]
name = "socket2"
@@ -8643,6 +8764,15 @@ dependencies = [
"log",
]
+[[package]]
+name = "stable-vec"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80dfb7bb28f3d2fa50566793349d633b33f938543154be8071610ea9f590d8ca"
+dependencies = [
+ "no-std-compat",
+]
+
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
@@ -8761,7 +8891,7 @@ version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bbdb58577b6301f8d17ae2561f32002a5bae056d444e0f69e611e504a276204"
dependencies = [
- "base64 0.21.5",
+ "base64 0.21.7",
"serde",
"serde_json",
]
@@ -8971,7 +9101,7 @@ version = "1.5.3"
source = "git+https://github.com/spacedriveapp/tauri.git?rev=8409af71a83d631ff9d1cd876c441a57511a1cbd#8409af71a83d631ff9d1cd876c441a57511a1cbd"
dependencies = [
"anyhow",
- "base64 0.21.5",
+ "base64 0.21.7",
"bytes",
"cocoa",
"dirs-next",
@@ -9047,7 +9177,7 @@ name = "tauri-codegen"
version = "1.4.1"
source = "git+https://github.com/spacedriveapp/tauri.git?rev=8409af71a83d631ff9d1cd876c441a57511a1cbd#8409af71a83d631ff9d1cd876c441a57511a1cbd"
dependencies = [
- "base64 0.21.5",
+ "base64 0.21.7",
"brotli",
"ico",
"json-patch",
@@ -9271,18 +9401,18 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
[[package]]
name = "thiserror"
-version = "1.0.51"
+version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7"
+checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.51"
+version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df"
+checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
dependencies = [
"proc-macro2",
"quote",
@@ -9382,9 +9512,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.35.1"
+version = "1.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104"
+checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
dependencies = [
"backtrace",
"bytes",
@@ -9665,7 +9795,7 @@ dependencies = [
"once_cell",
"regex",
"sharded-slab",
- "smallvec 1.11.2",
+ "smallvec 1.13.1",
"thread_local",
"tracing",
"tracing-core",
@@ -9918,7 +10048,7 @@ version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97"
dependencies = [
- "base64 0.21.5",
+ "base64 0.21.7",
"log",
"once_cell",
"rustls",
@@ -9976,7 +10106,7 @@ version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c51daa774fe9ee5efcf7b4fec13019b8119cda764d9a8b5b06df02bb1445c656"
dependencies = [
- "base64 0.21.5",
+ "base64 0.21.7",
"log",
"pico-args",
"usvg-parser",
@@ -10058,7 +10188,7 @@ version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560"
dependencies = [
- "getrandom 0.2.11",
+ "getrandom 0.2.12",
"serde",
]
@@ -10993,6 +11123,26 @@ dependencies = [
"syn 1.0.109",
]
+[[package]]
+name = "zerocopy"
+version = "0.7.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.7.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.48",
+]
+
[[package]]
name = "zeroize"
version = "1.7.0"
diff --git a/Cargo.toml b/Cargo.toml
index 6a3396275..f54358834 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -57,7 +57,7 @@ base64 = "0.21.5"
blake3 = "1.5.0"
chrono = "0.4.31"
clap = "4.4.7"
-futures = "0.3.29"
+futures = "0.3.30"
futures-concurrency = "7.4.3"
hex = "0.4.3"
http = "0.2.9"
@@ -76,7 +76,7 @@ strum = "0.25"
strum_macros = "0.25"
tempfile = "3.8.1"
thiserror = "1.0.50"
-tokio = "1.34.0"
+tokio = "1.36.0"
tokio-stream = "0.1.14"
tokio-util = "0.7.10"
uhlc = "=0.5.2"
@@ -87,13 +87,19 @@ webp = "0.2.6"
# Proper IOS Support
if-watch = { git = "https://github.com/oscartbeaumont/if-watch.git", rev = "a92c17d3f85c1c6fb0afeeaf6c2b24d0b147e8c3" }
-# Beta features
+# We hack it to the high heavens
rspc = { git = "https://github.com/spacedriveapp/rspc.git", rev = "f3347e2e8bfe3f37bfacc437ca329fe71cdcb048" }
# `cursor_position` method
tauri = { git = "https://github.com/spacedriveapp/tauri.git", rev = "8409af71a83d631ff9d1cd876c441a57511a1cbd" }
tao = { git = "https://github.com/spacedriveapp/tao", rev = "7880adbc090402c44fbcf006669458fa82623403" }
+# Add `Control::open_stream_with_addrs`
+libp2p = { git = "https://github.com/spacedriveapp/rust-libp2p.git", rev = "a005656df7e82059a0eb2e333ebada4731d23f8c" }
+libp2p-core = { git = "https://github.com/spacedriveapp/rust-libp2p.git", rev = "a005656df7e82059a0eb2e333ebada4731d23f8c" }
+libp2p-swarm = { git = "https://github.com/spacedriveapp/rust-libp2p.git", rev = "a005656df7e82059a0eb2e333ebada4731d23f8c" }
+libp2p-stream = { git = "https://github.com/spacedriveapp/rust-libp2p.git", rev = "a005656df7e82059a0eb2e333ebada4731d23f8c" }
+
# Set the settings for build scripts and proc-macros.
[profile.dev.build-override]
opt-level = 3
diff --git a/apps/mobile/src/screens/settings/client/GeneralSettings.tsx b/apps/mobile/src/screens/settings/client/GeneralSettings.tsx
index 6cfce95cb..2e89489cd 100644
--- a/apps/mobile/src/screens/settings/client/GeneralSettings.tsx
+++ b/apps/mobile/src/screens/settings/client/GeneralSettings.tsx
@@ -37,8 +37,9 @@ const GeneralSettingsScreen = ({ navigation }: SettingsStackScreenProps<'General
{/* Node Name and Port */}
Node Name
- Node Port
-
+ {/* // TODO: Bring this back */}
+ {/* Node Port */}
+ {/* */}
{debugState.enabled && (
diff --git a/core/Cargo.toml b/core/Cargo.toml
index e59da6b17..b1ed15311 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -38,7 +38,10 @@ sd-images = { path = "../crates/images", features = [
"specta",
] }
sd-media-metadata = { path = "../crates/media-metadata" }
-sd-p2p = { path = "../crates/p2p", features = ["specta", "serde"] }
+sd-p2p2 = { path = "../crates/p2p2", features = ["specta"] }
+sd-p2p-block = { path = "../crates/p2p-block" }
+sd-p2p-proto = { path = "../crates/p2p-proto" }
+sd-p2p-tunnel = { path = "../crates/p2p-tunnel" }
sd-prisma = { path = "../crates/prisma" }
sd-ai = { path = "../crates/ai", optional = true }
sd-sync = { path = "../crates/sync" }
diff --git a/core/prisma/migrations/20240221044741_drop_node_peer_id/migration.sql b/core/prisma/migrations/20240221044741_drop_node_peer_id/migration.sql
new file mode 100644
index 000000000..deda288c5
--- /dev/null
+++ b/core/prisma/migrations/20240221044741_drop_node_peer_id/migration.sql
@@ -0,0 +1,33 @@
+/*
+ Warnings:
+
+ - You are about to drop the column `pub_id` on the `label` table. All the data in the column will be lost.
+ - You are about to drop the column `node_peer_id` on the `node` table. All the data in the column will be lost.
+
+*/
+-- RedefineTables
+PRAGMA foreign_keys=OFF;
+CREATE TABLE "new_label" (
+ "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "name" TEXT NOT NULL,
+ "date_created" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "date_modified" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
+);
+INSERT INTO "new_label" ("date_created", "date_modified", "id", "name") SELECT "date_created", "date_modified", "id", "name" FROM "label";
+DROP TABLE "label";
+ALTER TABLE "new_label" RENAME TO "label";
+CREATE UNIQUE INDEX "label_name_key" ON "label"("name");
+CREATE TABLE "new_node" (
+ "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "pub_id" BLOB NOT NULL,
+ "name" TEXT NOT NULL,
+ "platform" INTEGER NOT NULL,
+ "date_created" DATETIME NOT NULL,
+ "identity" BLOB
+);
+INSERT INTO "new_node" ("date_created", "id", "identity", "name", "platform", "pub_id") SELECT "date_created", "id", "identity", "name", "platform", "pub_id" FROM "node";
+DROP TABLE "node";
+ALTER TABLE "new_node" RENAME TO "node";
+CREATE UNIQUE INDEX "node_pub_id_key" ON "node"("pub_id");
+PRAGMA foreign_key_check;
+PRAGMA foreign_keys=ON;
diff --git a/core/prisma/schema.prisma b/core/prisma/schema.prisma
index 4052b7a35..73cc986de 100644
--- a/core/prisma/schema.prisma
+++ b/core/prisma/schema.prisma
@@ -43,7 +43,6 @@ model Node {
platform Int
date_created DateTime
identity Bytes? // TODO: Change to required field in future
- node_peer_id String? // TODO: Remove as part of - https://linear.app/spacedriveapp/issue/ENG-757/p2p-library-portability
@@map("node")
}
@@ -72,8 +71,8 @@ model Instance {
locations Location[]
- CRDTOperation CRDTOperation[]
- CloudCRDTOperation CloudCRDTOperation[]
+ CRDTOperation CRDTOperation[]
+ CloudCRDTOperation CloudCRDTOperation[]
@@map("instance")
}
@@ -360,11 +359,11 @@ model Label {
model LabelOnObject {
date_created DateTime @default(now())
- object_id Int
- object Object @relation(fields: [object_id], references: [id], onDelete: Restrict)
+ object_id Int
+ object Object @relation(fields: [object_id], references: [id], onDelete: Restrict)
- label_id Int
- label Label @relation(fields: [label_id], references: [id], onDelete: Restrict)
+ label_id Int
+ label Label @relation(fields: [label_id], references: [id], onDelete: Restrict)
@@id([label_id, object_id])
@@map("label_on_object")
diff --git a/core/src/api/libraries.rs b/core/src/api/libraries.rs
index f98f73b53..6f48b67c3 100644
--- a/core/src/api/libraries.rs
+++ b/core/src/api/libraries.rs
@@ -9,7 +9,7 @@ use crate::{
use futures::StreamExt;
use sd_cache::{Model, Normalise, NormalisedResult, NormalisedResults};
use sd_file_ext::kind::ObjectKind;
-use sd_p2p::spacetunnel::RemoteIdentity;
+use sd_p2p2::RemoteIdentity;
use sd_prisma::prisma::{indexer_rule, object, statistics};
use tokio_stream::wrappers::IntervalStream;
diff --git a/core/src/api/mod.rs b/core/src/api/mod.rs
index 32e452eb3..903a22641 100644
--- a/core/src/api/mod.rs
+++ b/core/src/api/mod.rs
@@ -2,14 +2,15 @@ use crate::{
invalidate_query,
job::JobProgressEvent,
node::{
- config::{NodeConfig, NodePreferences},
+ config::{NodeConfig, NodePreferences, P2PDiscoveryState, Port},
get_hardware_model_name, HardwareModel,
},
+ p2p::{into_listener2, Listener2},
Node,
};
use sd_cache::patch_typedef;
-use sd_p2p::P2PStatus;
+use sd_p2p2::RemoteIdentity;
use std::sync::{atomic::Ordering, Arc};
use itertools::Itertools;
@@ -93,8 +94,10 @@ pub struct SanitisedNodeConfig {
pub id: Uuid,
/// name is the display name of the current node. This is set by the user and is shown in the UI. // TODO: Length validation so it can fit in DNS record
pub name: String,
- pub p2p_enabled: bool,
- pub p2p_port: Option,
+ pub identity: RemoteIdentity,
+ pub p2p_ipv4_port: Port,
+ pub p2p_ipv6_port: Port,
+ pub p2p_discovery: P2PDiscoveryState,
pub features: Vec,
pub preferences: NodePreferences,
pub image_labeler_version: Option,
@@ -105,8 +108,10 @@ impl From for SanitisedNodeConfig {
Self {
id: value.id,
name: value.name,
- p2p_enabled: value.p2p.enabled,
- p2p_port: value.p2p.port,
+ identity: value.identity.to_remote_identity(),
+ p2p_ipv4_port: value.p2p_ipv4_port,
+ p2p_ipv6_port: value.p2p_ipv6_port,
+ p2p_discovery: value.p2p_discovery,
features: value.features,
preferences: value.preferences,
image_labeler_version: value.image_labeler_version,
@@ -119,7 +124,7 @@ struct NodeState {
#[serde(flatten)]
config: SanitisedNodeConfig,
data_path: String,
- p2p: P2PStatus,
+ listeners: Vec,
device_model: Option,
}
@@ -155,7 +160,7 @@ pub(crate) fn mount() -> Arc {
.to_str()
.expect("Found non-UTF-8 path")
.to_string(),
- p2p: node.p2p.manager.status(),
+ listeners: into_listener2(&node.p2p.p2p.listeners()),
device_model: Some(device_model),
})
})
diff --git a/core/src/api/nodes.rs b/core/src/api/nodes.rs
index 3b69306d0..92198323d 100644
--- a/core/src/api/nodes.rs
+++ b/core/src/api/nodes.rs
@@ -1,4 +1,7 @@
-use crate::{invalidate_query, util::MaybeUndefined};
+use crate::{
+ invalidate_query,
+ node::config::{P2PDiscoveryState, Port},
+};
use sd_prisma::prisma::{instance, location};
@@ -16,8 +19,9 @@ pub(crate) fn mount() -> AlphaRouter {
#[derive(Deserialize, Type)]
pub struct ChangeNodeNameArgs {
pub name: Option,
- pub p2p_port: MaybeUndefined,
- pub p2p_enabled: Option,
+ pub p2p_ipv4_port: Option,
+ pub p2p_ipv6_port: Option,
+ pub p2p_discovery: Option,
pub image_labeler_version: Option,
}
R.mutation(|node, args: ChangeNodeNameArgs| async move {
@@ -30,9 +34,6 @@ pub(crate) fn mount() -> AlphaRouter {
}
}
- let does_p2p_need_refresh =
- args.p2p_enabled.is_some() || args.p2p_port.is_defined();
-
#[cfg(feature = "ai")]
let mut new_model = None;
@@ -42,11 +43,15 @@ pub(crate) fn mount() -> AlphaRouter {
config.name = name;
}
- config.p2p.enabled = args.p2p_enabled.unwrap_or(config.p2p.enabled);
-
- if let Some(v) = args.p2p_port.into() {
- config.p2p.port = v;
- }
+ if let Some(port) = args.p2p_ipv4_port {
+ config.p2p_ipv4_port = port;
+ };
+ if let Some(port) = args.p2p_ipv6_port {
+ config.p2p_ipv6_port = port;
+ };
+ if let Some(v) = args.p2p_discovery {
+ config.p2p_discovery = v;
+ };
#[cfg(feature = "ai")]
if let Some(version) = args.image_labeler_version {
@@ -59,9 +64,9 @@ pub(crate) fn mount() -> AlphaRouter {
new_model = sd_ai::image_labeler::YoloV8::model(Some(&version))
.map_err(|e| {
error!(
- "Failed to crate image_detection model: '{}'; Error: {e:#?}",
- &version,
- );
+ "Failed to crate image_detection model: '{}'; Error: {e:#?}",
+ &version,
+ );
})
.ok();
if new_model.is_some() {
@@ -79,13 +84,8 @@ pub(crate) fn mount() -> AlphaRouter {
)
})?;
- // If a P2P config was modified reload it
- if does_p2p_need_refresh {
- node.p2p
- .manager
- .update_config(node.config.get().await.p2p.clone())
- .await;
- }
+ // This is a no-op if the config didn't change
+ node.p2p.on_node_config_change().await;
invalidate_query!(node; node, "nodeState");
diff --git a/core/src/api/p2p.rs b/core/src/api/p2p.rs
index ad994fc3e..b464fa57b 100644
--- a/core/src/api/p2p.rs
+++ b/core/src/api/p2p.rs
@@ -1,11 +1,12 @@
-use crate::p2p::{operations, P2PEvent};
+use crate::p2p::{operations, Header, P2PEvent, PeerMetadata};
-use sd_p2p::spacetunnel::RemoteIdentity;
+use sd_p2p2::RemoteIdentity;
use rspc::{alpha::AlphaRouter, ErrorCode};
use serde::Deserialize;
use specta::Type;
use std::path::PathBuf;
+use tokio::io::AsyncWriteExt;
use uuid::Uuid;
use super::{Ctx, R};
@@ -14,26 +15,21 @@ pub(crate) fn mount() -> AlphaRouter {
R.router()
.procedure("events", {
R.subscription(|node, _: ()| async move {
- let mut rx = node.p2p.subscribe();
+ let mut rx = node.p2p.events.subscribe();
let mut queued = Vec::new();
- // TODO: Don't block subscription start
- for peer in node.p2p.node.get_discovered() {
- queued.push(P2PEvent::DiscoveredPeer {
- identity: peer.identity,
- metadata: peer.metadata,
- });
- }
-
- // TODO: Don't block subscription start
- for identity in node.p2p.manager.get_connected_peers().await.map_err(|_| {
- rspc::Error::new(
- ErrorCode::InternalServerError,
- "todo: error getting connected peers".into(),
- )
- })? {
- queued.push(P2PEvent::ConnectedPeer { identity });
+ for (identity, peer, metadata) in
+ node.p2p.p2p.peers().iter().filter_map(|(i, p)| {
+ PeerMetadata::from_hashmap(&p.metadata())
+ .ok()
+ .map(|m| (i, p, m))
+ }) {
+ let identity = *identity;
+ match peer.is_connected() {
+ true => queued.push(P2PEvent::ConnectedPeer { identity }),
+ false => queued.push(P2PEvent::DiscoveredPeer { identity, metadata }),
+ }
}
Ok(async_stream::stream! {
@@ -48,10 +44,36 @@ pub(crate) fn mount() -> AlphaRouter {
})
})
.procedure("state", {
- R.query(|node, _: ()| async move {
- // TODO: This has a potentially invalid map key and Specta don't like that.
- // TODO: This will bypass that check and for an debug route that's fine.
- Ok(serde_json::to_value(node.p2p.state()).unwrap())
+ R.query(|node, _: ()| async move { Ok(node.p2p.state().await) })
+ })
+ .procedure("debugConnect", {
+ R.mutation(|node, identity: RemoteIdentity| async move {
+ let peer = { node.p2p.p2p.peers().get(&identity).cloned() };
+ let mut stream = peer
+ .ok_or(rspc::Error::new(
+ ErrorCode::InternalServerError,
+ "big man, offline".into(),
+ ))?
+ .new_stream()
+ .await
+ .map_err(|err| {
+ rspc::Error::new(
+ ErrorCode::InternalServerError,
+ format!("error in peer.new_stream: {:?}", err),
+ )
+ })?;
+
+ stream
+ .write_all(&Header::Ping.to_bytes())
+ .await
+ .map_err(|err| {
+ rspc::Error::new(
+ ErrorCode::InternalServerError,
+ format!("error sending ping header: {:?}", err),
+ )
+ })?;
+
+ Ok("connected")
})
})
.procedure("spacedrop", {
diff --git a/core/src/cloud/sync/receive.rs b/core/src/cloud/sync/receive.rs
index 5a7439c17..7ab1c16f4 100644
--- a/core/src/cloud/sync/receive.rs
+++ b/core/src/cloud/sync/receive.rs
@@ -3,7 +3,7 @@ use crate::library::{Libraries, Library};
use super::{err_break, err_return, CompressedCRDTOperations};
use sd_cloud_api::RequestConfigProvider;
use sd_core_sync::NTP64;
-use sd_p2p::spacetunnel::{IdentityOrRemoteIdentity, RemoteIdentity};
+use sd_p2p2::{IdentityOrRemoteIdentity, RemoteIdentity};
use sd_prisma::prisma::{cloud_crdt_operation, instance, PrismaClient, SortOrder};
use sd_sync::CRDTOperation;
use sd_utils::uuid_to_bytes;
diff --git a/core/src/custom_uri/mod.rs b/core/src/custom_uri/mod.rs
index 481980af3..19ef0607b 100644
--- a/core/src/custom_uri/mod.rs
+++ b/core/src/custom_uri/mod.rs
@@ -9,10 +9,8 @@ use crate::{
use sd_file_ext::text::is_text;
use sd_file_path_helper::{file_path_to_handle_custom_uri, IsolatedFilePathData};
-use sd_p2p::{
- spaceblock::Range,
- spacetunnel::{IdentityOrRemoteIdentity, RemoteIdentity},
-};
+use sd_p2p2::{IdentityOrRemoteIdentity, RemoteIdentity};
+use sd_p2p_block::Range;
use sd_prisma::prisma::{file_path, location};
use sd_utils::db::maybe_missing;
@@ -243,45 +241,43 @@ pub fn router(node: Arc) -> Router<()> {
}
// TODO: Support `Range` requests and `ETag` headers
- match state.node.p2p.get_library_service(&library.id) {
- Some(service) => {
- let stream = service
- .connect(state.node.p2p.manager.clone(), &identity)
- .await
- .map_err(|err| {
- not_found(format!(
- "Error connecting to {identity}: {err:?}"
- ))
- })?;
+ let stream = state
+ .node
+ .p2p
+ .get_instance(&library.id, identity)
+ .ok_or_else(|| {
+ not_found(format!("Error connecting to {identity}: no connection method available"))
+ })?
+ .new_stream()
+ .await
+ .map_err(|err| {
+ not_found(format!("Error connecting to {identity}: {err:?}"))
+ })?;
- let (tx, mut rx) =
- tokio::sync::mpsc::channel::>(150);
- // TODO: We only start a thread because of stupid `ManagerStreamAction2` and libp2p's `!Send/!Sync` bounds on a stream.
- tokio::spawn(async move {
- let Ok(()) = operations::request_file(
- stream,
- &library,
- file_path_pub_id,
- Range::Full,
- MpscToAsyncWrite::new(PollSender::new(tx)),
- )
- .await
- else {
- return;
- };
- });
+ let (tx, mut rx) = tokio::sync::mpsc::channel::>(150);
+ // TODO: We only start a thread because of stupid `ManagerStreamAction2` and libp2p's `!Send/!Sync` bounds on a stream.
+ tokio::spawn(async move {
+ let Ok(()) = operations::request_file(
+ stream,
+ &library,
+ file_path_pub_id,
+ Range::Full,
+ MpscToAsyncWrite::new(PollSender::new(tx)),
+ )
+ .await
+ else {
+ return;
+ };
+ });
- // TODO: Content Type
- Ok(InfallibleResponse::builder().status(StatusCode::OK).body(
- body::boxed(StreamBody::new(stream! {
- while let Some(item) = rx.recv().await {
- yield item;
- }
- })),
- ))
- }
- None => Ok(not_found(())),
- }
+ // TODO: Content Type
+ Ok(InfallibleResponse::builder().status(StatusCode::OK).body(
+ body::boxed(StreamBody::new(stream! {
+ while let Some(item) = rx.recv().await {
+ yield item;
+ }
+ })),
+ ))
}
}
},
diff --git a/core/src/lib.rs b/core/src/lib.rs
index 561cb3303..0b263ba39 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -114,7 +114,9 @@ impl Node {
let (jobs, jobs_actor) = job::Jobs::new();
let libraries = library::Libraries::new(data_dir.join("libraries")).await?;
- let (p2p, p2p_actor) = p2p::P2PManager::new(config.clone(), libraries.clone()).await?;
+ let (p2p, start_p2p) = p2p::P2PManager::new(config.clone(), libraries.clone())
+ .await
+ .map_err(NodeError::P2PManager)?;
let node =
Arc::new(Node {
data_dir: data_dir.to_path_buf(),
@@ -160,7 +162,7 @@ impl Node {
locations_actor.start(node.clone());
node.libraries.init(&node).await?;
jobs_actor.start(node.clone());
- p2p_actor.start(node.clone());
+ start_p2p(node.clone());
let router = api::mount();
@@ -188,7 +190,7 @@ impl Node {
std::env::set_var(
"RUST_LOG",
- format!("info,sd_core={level},sd_core::location::manager=info,sd_ai={level}"),
+ format!("info,sd_core={level},sd_p2p=debug,sd_core::location::manager=info,sd_ai={level}"),
);
}
@@ -325,7 +327,7 @@ pub enum NodeError {
#[error("failed to initialize location manager: {0}")]
LocationManager(#[from] LocationManagerError),
#[error("failed to initialize p2p manager: {0}")]
- P2PManager(#[from] sd_p2p::ManagerError),
+ P2PManager(String),
#[error("invalid platform integer: {0}")]
InvalidPlatformInt(u8),
#[cfg(debug_assertions)]
diff --git a/core/src/library/config.rs b/core/src/library/config.rs
index 8c267495e..4505cd3c5 100644
--- a/core/src/library/config.rs
+++ b/core/src/library/config.rs
@@ -3,7 +3,7 @@ use crate::{
util::version_manager::{Kind, ManagedVersion, VersionManager, VersionManagerError},
};
-use sd_p2p::spacetunnel::{Identity, IdentityOrRemoteIdentity};
+use sd_p2p2::{Identity, IdentityOrRemoteIdentity};
use sd_prisma::prisma::{file_path, indexer_rule, instance, location, node, PrismaClient};
use sd_utils::{db::maybe_missing, error::FileIOError};
@@ -163,12 +163,7 @@ impl LibraryConfig {
db.node()
.update_many(
vec![],
- vec![
- node::pub_id::set(node_config.id.as_bytes().to_vec()),
- node::node_peer_id::set(Some(
- node_config.keypair.peer_id().to_string(),
- )),
- ],
+ vec![node::pub_id::set(node_config.id.as_bytes().to_vec())],
)
.exec()
.await?;
diff --git a/core/src/library/library.rs b/core/src/library/library.rs
index c474aee2a..7eb9c489f 100644
--- a/core/src/library/library.rs
+++ b/core/src/library/library.rs
@@ -1,7 +1,7 @@
use crate::{api::CoreEvent, object::media::thumbnail::get_indexed_thumbnail_path, sync, Node};
use sd_file_path_helper::{file_path_to_full_path, IsolatedFilePathData};
-use sd_p2p::spacetunnel::Identity;
+use sd_p2p2::Identity;
use sd_prisma::prisma::{file_path, location, PrismaClient};
use sd_utils::{db::maybe_missing, error::FileIOError};
@@ -67,6 +67,7 @@ impl Debug for Library {
}
impl Library {
+ #[allow(clippy::too_many_arguments)]
pub async fn new(
id: Uuid,
config: LibraryConfig,
diff --git a/core/src/library/manager/error.rs b/core/src/library/manager/error.rs
index 3d00c5990..05775d244 100644
--- a/core/src/library/manager/error.rs
+++ b/core/src/library/manager/error.rs
@@ -3,7 +3,7 @@ use crate::{
location::{indexer, LocationManagerError},
};
-use sd_p2p::spacetunnel::IdentityOrRemoteIdentityErr;
+use sd_p2p2::IdentityOrRemoteIdentityErr;
use sd_utils::{
db::{self, MissingFieldError},
error::{FileIOError, NonUtf8PathError},
diff --git a/core/src/library/manager/mod.rs b/core/src/library/manager/mod.rs
index 8cd69ba5a..524579801 100644
--- a/core/src/library/manager/mod.rs
+++ b/core/src/library/manager/mod.rs
@@ -1,20 +1,19 @@
use crate::{
api::{utils::InvalidateOperationEvent, CoreEvent},
- invalidate_query,
+ cloud, invalidate_query,
location::{
indexer,
metadata::{LocationMetadataError, SpacedriveLocationMetadataFile},
},
node::Platform,
object::tag,
- p2p::{self},
- sync,
+ p2p, sync,
util::{mpscrr, MaybeUndefined},
Node,
};
use sd_core_sync::SyncMessage;
-use sd_p2p::spacetunnel::{Identity, IdentityOrRemoteIdentity};
+use sd_p2p2::{Identity, IdentityOrRemoteIdentity};
use sd_prisma::prisma::{crdt_operation, instance, location, SortOrder};
use sd_utils::{
db,
@@ -535,7 +534,7 @@ impl Libraries {
loop {
debug!("Syncing library with cloud!");
- if let Some(_) = library.config().await.cloud_id {
+ if library.config().await.cloud_id.is_some() {
if let Ok(lib) =
sd_cloud_api::library::get(node.cloud_api_config().await, library.id)
.await
@@ -575,7 +574,7 @@ impl Libraries {
}
}
- if &lib.name != &*library.config().await.name {
+ if lib.name != *library.config().await.name {
warn!("Library name on cloud is outdated. Updating...");
if let Err(err) = sd_cloud_api::library::update(
@@ -593,17 +592,16 @@ impl Libraries {
}
for instance in lib.instances {
- if let Err(err) =
- crate::cloud::sync::receive::create_instance(
- &library,
- &node.libraries,
- instance.uuid,
- instance.identity,
- instance.node_id,
- instance.node_name,
- instance.node_platform,
- )
- .await
+ if let Err(err) = cloud::sync::receive::create_instance(
+ &library,
+ &node.libraries,
+ instance.uuid,
+ instance.identity,
+ instance.node_id,
+ instance.node_name,
+ instance.node_platform,
+ )
+ .await
{
error!(
"Failed to create instance from cloud: {:#?}",
diff --git a/core/src/node/config.rs b/core/src/node/config.rs
index 379b90ab4..09d8340bd 100644
--- a/core/src/node/config.rs
+++ b/core/src/node/config.rs
@@ -4,7 +4,7 @@ use crate::{
util::version_manager::{Kind, ManagedVersion, VersionManager, VersionManagerError},
};
-use sd_p2p::{Keypair, ManagerConfig};
+use sd_p2p2::Identity;
use sd_utils::error::FileIOError;
use std::{
@@ -28,6 +28,29 @@ use uuid::Uuid;
/// NODE_STATE_CONFIG_NAME is the name of the file which stores the NodeState
pub const NODE_STATE_CONFIG_NAME: &str = "node_state.sdconfig";
+#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Type)]
+pub enum P2PDiscoveryState {
+ #[default]
+ Everyone,
+ ContactsOnly,
+ Disabled,
+}
+
+#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, Type)]
+#[serde(rename_all = "snake_case", untagged)]
+pub enum Port {
+ Disabled,
+ #[default]
+ Random,
+ Discrete(u16),
+}
+
+impl Port {
+ pub fn is_random(&self) -> bool {
+ matches!(self, Port::Random)
+ }
+}
+
/// NodeConfig is the configuration for a node. This is shared between all libraries and is stored in a JSON file on disk.
#[derive(Debug, Clone, Serialize, Deserialize)] // If you are adding `specta::Type` on this your probably about to leak the P2P private key
pub struct NodeConfig {
@@ -40,10 +63,15 @@ pub struct NodeConfig {
pub notifications: Vec,
/// The p2p identity keypair for this node. This is used to identify the node on the network.
/// This keypair does effectively nothing except for provide libp2p with a stable peer_id.
- pub keypair: Keypair,
+ #[serde(with = "identity_serde")]
+ pub identity: Identity,
/// P2P config
+ #[serde(default, skip_serializing_if = "Port::is_random")]
+ pub p2p_ipv4_port: Port,
+ #[serde(default, skip_serializing_if = "Port::is_random")]
+ pub p2p_ipv6_port: Port,
#[serde(default)]
- pub p2p: ManagerConfig,
+ pub p2p_discovery: P2PDiscoveryState,
/// Feature flags enabled on the node
#[serde(default)]
pub features: Vec,
@@ -60,6 +88,30 @@ pub struct NodeConfig {
version: NodeConfigVersion,
}
+mod identity_serde {
+ use sd_p2p2::Identity;
+ use serde::{Deserialize, Deserializer, Serialize, Serializer};
+
+ pub fn serialize(identity: &Identity, serializer: S) -> Result
+ where
+ S: Serializer,
+ {
+ to_string(identity).serialize(serializer)
+ }
+
+ pub fn deserialize<'de, D>(deserializer: D) -> Result
+ where
+ D: Deserializer<'de>,
+ {
+ let s = String::deserialize(deserializer)?;
+ Identity::from_bytes(&base91::slice_decode(s.as_bytes())).map_err(serde::de::Error::custom)
+ }
+
+ pub fn to_string(identity: &Identity) -> String {
+ String::from_utf8_lossy(&base91::slice_encode(&identity.to_bytes())).to_string()
+ }
+}
+
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq, Type)]
pub struct NodePreferences {
pub thumbnailer: ThumbnailerPreferences,
@@ -73,10 +125,11 @@ pub enum NodeConfigVersion {
V0 = 0,
V1 = 1,
V2 = 2,
+ V3 = 3,
}
impl ManagedVersion for NodeConfig {
- const LATEST_VERSION: NodeConfigVersion = NodeConfigVersion::V2;
+ const LATEST_VERSION: NodeConfigVersion = NodeConfigVersion::V3;
const KIND: Kind = Kind::Json("version");
type MigrationError = NodeConfigError;
@@ -99,9 +152,11 @@ impl ManagedVersion for NodeConfig {
Some(Self {
id: Uuid::new_v4(),
name,
- keypair: Keypair::generate(),
+ identity: Identity::default(),
+ p2p_ipv4_port: Port::Random,
+ p2p_ipv6_port: Port::Random,
+ p2p_discovery: P2PDiscoveryState::Everyone,
version: Self::LATEST_VERSION,
- p2p: ManagerConfig::default(),
features: vec![],
notifications: vec![],
auth_token: None,
@@ -173,6 +228,33 @@ impl NodeConfig {
.map_err(|e| FileIOError::from((path, e)))?;
}
+ (NodeConfigVersion::V2, NodeConfigVersion::V3) => {
+ let mut config: Map =
+ serde_json::from_slice(&fs::read(path).await.map_err(|e| {
+ FileIOError::from((
+ path,
+ e,
+ "Failed to read node config file for migration",
+ ))
+ })?)
+ .map_err(VersionManagerError::SerdeJson)?;
+
+ config.remove("keypair");
+ config.remove("p2p");
+
+ config.insert(
+ String::from("identity"),
+ json!(identity_serde::to_string(&Default::default())),
+ );
+
+ let a =
+ serde_json::to_vec(&config).map_err(VersionManagerError::SerdeJson)?;
+
+ fs::write(path, a)
+ .await
+ .map_err(|e| FileIOError::from((path, e)))?;
+ }
+
_ => {
error!("Node config version is not handled: {:?}", current);
return Err(VersionManagerError::UnexpectedMigration {
diff --git a/core/src/p2p/connect_hook.rs b/core/src/p2p/connect_hook.rs
new file mode 100644
index 000000000..f52812841
--- /dev/null
+++ b/core/src/p2p/connect_hook.rs
@@ -0,0 +1,26 @@
+// TODO: This is unused but will be used in the future.
+// use std::sync::Arc;
+
+// use sd_p2p2::{flume::bounded, HookEvent, P2P};
+
+// /// A P2P hook which listens for the availability of peers and connects with them.
+// pub struct ConnectHook {}
+
+// impl ConnectHook {
+// pub fn spawn(p2p: Arc) -> Self {
+// let (tx, rx) = bounded(15);
+// let _ = p2p.register_hook("sd-connect-hook", tx);
+
+// tokio::spawn(async move {
+// while let Ok(event) = rx.recv_async().await {
+// match event {
+// // TODO: Do the thing. For now we don't need this.
+// HookEvent::Shutdown { _guard } => break,
+// _ => continue,
+// }
+// }
+// });
+
+// Self {}
+// }
+// }
diff --git a/core/src/p2p/events.rs b/core/src/p2p/events.rs
new file mode 100644
index 000000000..30d71e757
--- /dev/null
+++ b/core/src/p2p/events.rs
@@ -0,0 +1,116 @@
+use std::sync::Arc;
+
+use sd_p2p2::{flume::bounded, HookEvent, RemoteIdentity, P2P};
+use serde::Serialize;
+use specta::Type;
+use tokio::sync::broadcast;
+use uuid::Uuid;
+
+use super::PeerMetadata;
+
+/// TODO: P2P event for the frontend
+#[derive(Debug, Clone, Serialize, Type)]
+#[serde(tag = "type")]
+pub enum P2PEvent {
+ DiscoveredPeer {
+ identity: RemoteIdentity,
+ metadata: PeerMetadata,
+ },
+ ExpiredPeer {
+ identity: RemoteIdentity,
+ },
+ ConnectedPeer {
+ identity: RemoteIdentity,
+ },
+ DisconnectedPeer {
+ identity: RemoteIdentity,
+ },
+ SpacedropRequest {
+ id: Uuid,
+ identity: RemoteIdentity,
+ peer_name: String,
+ files: Vec,
+ },
+ SpacedropProgress {
+ id: Uuid,
+ percent: u8,
+ },
+ SpacedropTimedout {
+ id: Uuid,
+ },
+ SpacedropRejected {
+ id: Uuid,
+ },
+}
+
+/// A P2P hook which listens for events and sends them over a channel which can be connected to the frontend.
+pub struct P2PEvents {
+ events: (broadcast::Sender, broadcast::Receiver),
+}
+
+impl P2PEvents {
+ pub fn spawn(p2p: Arc) -> Self {
+ let events = broadcast::channel(15);
+ let (tx, rx) = bounded(15);
+ let _ = p2p.register_hook("sd-frontend-events", tx);
+
+ let events_tx = events.0.clone();
+ tokio::spawn(async move {
+ while let Ok(event) = rx.recv_async().await {
+ let event = match event {
+ // We use `HookEvent::PeerUnavailable`/`HookEvent::PeerAvailable` over `HookEvent::PeerExpiredBy`/`HookEvent::PeerDiscoveredBy` so that having an active connection is treated as "discovered".
+ // It's possible to have an active connection without mDNS data (which is what Peer*By` are for)
+ HookEvent::PeerAvailable(peer) => {
+ let metadata = match PeerMetadata::from_hashmap(&peer.metadata()) {
+ Ok(metadata) => metadata,
+ Err(e) => {
+ println!(
+ "Invalid metadata for peer '{}': {:?}",
+ peer.identity(),
+ e
+ );
+ continue;
+ }
+ };
+
+ P2PEvent::DiscoveredPeer {
+ identity: peer.identity(),
+ metadata,
+ }
+ }
+ HookEvent::PeerUnavailable(identity) => P2PEvent::ExpiredPeer { identity },
+ HookEvent::PeerConnectedWith(_, peer) => P2PEvent::ConnectedPeer {
+ identity: peer.identity(),
+ },
+ HookEvent::PeerDisconnectedWith(_, identity) => {
+ let peers = p2p.peers();
+ let Some(peer) = peers.get(&identity) else {
+ continue;
+ };
+
+ if !peer.is_connected() {
+ P2PEvent::DisconnectedPeer { identity }
+ } else {
+ continue;
+ }
+ }
+ HookEvent::Shutdown { _guard } => break,
+ _ => continue,
+ };
+
+ let _ = events_tx.send(event);
+ }
+ });
+
+ Self { events }
+ }
+
+ pub fn subscribe(&self) -> broadcast::Receiver {
+ self.events.0.subscribe()
+ }
+
+ #[allow(clippy::result_large_err)]
+ pub fn send(&self, event: P2PEvent) -> Result> {
+ self.events.0.send(event)
+ }
+}
diff --git a/core/src/p2p/libraries.rs b/core/src/p2p/libraries.rs
index 7df5a94f4..77969e7d9 100644
--- a/core/src/p2p/libraries.rs
+++ b/core/src/p2p/libraries.rs
@@ -1,70 +1,31 @@
-#![allow(unused)] // TODO: Remove this
+use std::sync::Arc;
-use crate::library::{Libraries, Library, LibraryManagerEvent};
+use sd_p2p2::P2P;
+use tracing::error;
-use sd_p2p::{spacetunnel::IdentityOrRemoteIdentity, Service};
+use crate::library::{Libraries, LibraryManagerEvent};
-use std::{
- collections::HashMap,
- fmt,
- sync::{Arc, PoisonError, RwLock},
-};
-
-use tokio::sync::mpsc;
-use tracing::{error, warn};
-use uuid::Uuid;
-
-use super::{LibraryMetadata, P2PManager};
-
-pub struct LibraryServices {
- services: RwLock>>>,
- register_service_tx: mpsc::Sender>>,
-}
-
-impl fmt::Debug for LibraryServices {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("LibraryServices")
- .field(
- "services",
- &self
- .services
- .read()
- .unwrap_or_else(PoisonError::into_inner)
- .keys(),
- )
- .finish()
- }
-}
-
-impl LibraryServices {
- pub fn new(register_service_tx: mpsc::Sender>>) -> Self {
- Self {
- services: Default::default(),
- register_service_tx,
- }
- }
-
- pub(crate) async fn start(manager: Arc, libraries: Arc) {
+pub fn start(p2p: Arc, libraries: Arc) {
+ tokio::spawn(async move {
if let Err(err) = libraries
.rx
.clone()
.subscribe(|msg| {
- let manager = manager.clone();
+ let p2p = p2p.clone();
async move {
match msg {
LibraryManagerEvent::InstancesModified(library)
| LibraryManagerEvent::Load(library) => {
- manager
- .clone()
- .libraries
- .load_library(manager, &library)
- .await
+ p2p.metadata_mut().insert(
+ library.id.to_string(),
+ library.identity.to_remote_identity().to_string(),
+ );
}
- LibraryManagerEvent::Edit(library) => {
- manager.libraries.edit_library(&library).await
+ LibraryManagerEvent::Edit(_library) => {
+ // TODO: Send changes to all connected nodes or queue sending for when they are online!
}
LibraryManagerEvent::Delete(library) => {
- manager.libraries.delete_library(&library).await
+ p2p.metadata_mut().remove(&library.id.to_string());
}
}
}
@@ -73,87 +34,5 @@ impl LibraryServices {
{
error!("Core may become unstable! `LibraryServices::start` manager aborted with error: {err:?}");
}
- }
-
- pub fn get(&self, id: &Uuid) -> Option>> {
- self.services
- .read()
- .unwrap_or_else(PoisonError::into_inner)
- .get(id)
- .cloned()
- }
-
- pub fn libraries(&self) -> Vec<(Uuid, Arc>)> {
- self.services
- .read()
- .unwrap_or_else(PoisonError::into_inner)
- .iter()
- .map(|(k, v)| (*k, v.clone()))
- .collect::>()
- }
-
- pub(crate) async fn load_library(&self, manager: Arc, library: &Library) {
- let identities = match library.db.instance().find_many(vec![]).exec().await {
- Ok(library) => library
- .into_iter()
- .filter_map(
- // TODO: Error handling
- |i| match IdentityOrRemoteIdentity::from_bytes(&i.identity) {
- Err(err) => {
- warn!("error parsing identity: {err:?}");
- None
- }
- Ok(IdentityOrRemoteIdentity::Identity(_)) => None,
- Ok(IdentityOrRemoteIdentity::RemoteIdentity(identity)) => Some(identity),
- },
- )
- .collect(),
- Err(err) => {
- warn!("error loading library '{}': {err:?}", library.id);
- return;
- }
- };
-
- let mut inserted = false;
-
- let service = {
- let mut service = self
- .services
- .write()
- .unwrap_or_else(PoisonError::into_inner);
- let service = service.entry(library.id).or_insert_with(|| {
- inserted = true;
- Arc::new(
- Service::new(
- String::from_utf8_lossy(&base91::slice_encode(library.id.as_bytes())),
- manager.manager.clone(),
- )
- .expect("error creating service with duplicate service name"),
- )
- });
- service.add_known(identities);
- service.clone()
- };
-
- if inserted {
- service.update(LibraryMetadata {});
- if self.register_service_tx.send(service).await.is_err() {
- warn!("error sending on 'register_service_tx'. This indicates a bug!");
- }
- }
- }
-
- pub(crate) async fn edit_library(&self, _library: &Library) {
- // TODO: Send changes to all connected nodes!
- // TODO: Update mdns
- }
-
- pub(crate) async fn delete_library(&self, library: &Library) {
- drop(
- self.services
- .write()
- .unwrap_or_else(PoisonError::into_inner)
- .remove(&library.id),
- );
- }
+ });
}
diff --git a/core/src/p2p/library_metadata.rs b/core/src/p2p/library_metadata.rs
deleted file mode 100644
index 0a6e2b198..000000000
--- a/core/src/p2p/library_metadata.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use sd_p2p::Metadata;
-
-use std::collections::HashMap;
-
-use serde::{Deserialize, Serialize};
-use specta::Type;
-
-#[derive(Debug, Clone, Type, Serialize, Deserialize)]
-pub struct LibraryMetadata {}
-
-impl Metadata for LibraryMetadata {
- fn to_hashmap(self) -> HashMap {
- HashMap::with_capacity(0)
- }
-
- fn from_hashmap(_: &HashMap) -> Result
- where
- Self: Sized,
- {
- Ok(Self {})
- }
-}
diff --git a/core/src/p2p/manager.rs b/core/src/p2p/manager.rs
new file mode 100644
index 000000000..0e4daeae0
--- /dev/null
+++ b/core/src/p2p/manager.rs
@@ -0,0 +1,311 @@
+use crate::{
+ node::{
+ config::{self, P2PDiscoveryState, Port},
+ get_hardware_model_name, HardwareModel,
+ },
+ p2p::{libraries, operations, sync::SyncMessage, Header, OperatingSystem, SPACEDRIVE_APP_ID},
+ Node,
+};
+
+use sd_p2p2::{
+ flume::{bounded, Receiver},
+ Libp2pPeerId, Listener, Mdns, Peer, QuicTransport, RemoteIdentity, UnicastStream, P2P,
+};
+use sd_p2p_tunnel::Tunnel;
+use serde::Serialize;
+use serde_json::json;
+use specta::Type;
+use std::{
+ collections::{HashMap, HashSet},
+ net::SocketAddr,
+ sync::{atomic::AtomicBool, Arc, Mutex, PoisonError},
+};
+
+use tokio::sync::oneshot;
+use tracing::{error, info};
+use uuid::Uuid;
+
+use super::{P2PEvents, PeerMetadata};
+
+pub struct P2PManager {
+ pub(crate) p2p: Arc,
+ mdns: Mutex