From 6f78922bb050e282dad37a014cc35721d63704a1 Mon Sep 17 00:00:00 2001 From: grumbach Date: Wed, 1 Jan 2025 02:42:19 +0900 Subject: [PATCH 1/3] feat: remove wasm --- .github/workflows/cross-platform.yml | 40 - Cargo.lock | 158 +--- ant-bootstrap/Cargo.toml | 3 - ant-bootstrap/src/contacts.rs | 8 - ant-evm/Cargo.toml | 3 - ant-evm/src/data_payments.rs | 3 - ant-networking/Cargo.toml | 23 +- ant-networking/src/bootstrap.rs | 9 +- ant-networking/src/cmd.rs | 2 +- ant-networking/src/driver.rs | 11 +- ant-networking/src/event/kad.rs | 5 +- ant-networking/src/event/swarm.rs | 2 +- ant-networking/src/lib.rs | 8 +- ant-networking/src/metrics/bad_node.rs | 2 +- ant-networking/src/metrics/mod.rs | 6 +- ant-networking/src/network_discovery.rs | 2 +- ant-networking/src/record_store.rs | 2 +- ant-networking/src/replication_fetcher.rs | 4 +- ant-networking/src/target_arch.rs | 29 - ant-networking/src/time.rs | 12 + .../src/{transport/other.rs => transport.rs} | 8 + ant-networking/src/transport/mod.rs | 5 - ant-networking/src/transport/wasm32.rs | 18 - ant-node/src/metrics.rs | 2 +- ant-node/src/node.rs | 2 +- autonomi/Cargo.toml | 14 - autonomi/README.md | 4 - autonomi/README_WASM.md | 95 -- autonomi/examples/metamask/index.html | 26 - autonomi/examples/metamask/index.js | 233 ----- autonomi/src/client/data/mod.rs | 2 +- autonomi/src/client/data/public.rs | 4 +- autonomi/src/client/external_signer.rs | 2 +- autonomi/src/client/files/archive.rs | 2 +- autonomi/src/client/files/archive_public.rs | 2 +- autonomi/src/client/files/fs_public.rs | 4 +- autonomi/src/client/mod.rs | 17 +- autonomi/src/client/rate_limiter.rs | 2 +- autonomi/src/client/wasm.rs | 868 ------------------ autonomi/tests/wasm.rs | 51 - evmlib/Cargo.toml | 4 - 41 files changed, 60 insertions(+), 1637 deletions(-) delete mode 100644 .github/workflows/cross-platform.yml delete mode 100644 ant-networking/src/target_arch.rs create mode 100644 ant-networking/src/time.rs rename ant-networking/src/{transport/other.rs => transport.rs} (61%) delete mode 100644 ant-networking/src/transport/mod.rs delete mode 100644 ant-networking/src/transport/wasm32.rs delete mode 100644 autonomi/README_WASM.md delete mode 100644 autonomi/examples/metamask/index.html delete mode 100644 autonomi/examples/metamask/index.js delete mode 100644 autonomi/src/client/wasm.rs delete mode 100644 autonomi/tests/wasm.rs diff --git a/.github/workflows/cross-platform.yml b/.github/workflows/cross-platform.yml deleted file mode 100644 index 7b268cba02..0000000000 --- a/.github/workflows/cross-platform.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Cross platform checks - -on: - # tests must run for a PR to be valid and pass merge queue muster - # on main, we want to know that all commits are passing at a glance, any deviation should help bisecting errors - # the merge run checks should show on master and enable this clear test/passing history - merge_group: - branches: [main] - pull_request: - branches: ["*"] - -env: - CARGO_INCREMENTAL: 0 # bookkeeping for incremental builds has overhead, not useful in CI. - -jobs: - - wasm: - if: "!startsWith(github.event.head_commit.message, 'chore(release):')" - name: wasm32-unknown-unknown builds - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Install Rust - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - - - name: Install wasm-pack - run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh - - - name: Build WASM package - # --dev to avoid optimisation - run: wasm-pack build --dev --target=web autonomi - timeout-minutes: 30 - - - name: Cargo check for WASM - # Allow clippy lints (these can be pedantic on WASM), but deny regular Rust warnings - run: cargo clippy --target=wasm32-unknown-unknown --package=autonomi --lib --tests -- --allow=clippy::all --deny=warnings - timeout-minutes: 30 diff --git a/Cargo.lock b/Cargo.lock index 8a18ba551c..39fb541eb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -432,7 +432,7 @@ dependencies = [ "tokio", "tracing", "url", - "wasmtimer 0.4.1", + "wasmtimer", ] [[package]] @@ -477,7 +477,7 @@ dependencies = [ "tower 0.5.2", "tracing", "url", - "wasmtimer 0.4.1", + "wasmtimer", ] [[package]] @@ -666,8 +666,7 @@ dependencies = [ "tower 0.5.2", "tracing", "url", - "wasm-bindgen-futures", - "wasmtimer 0.4.1", + "wasmtimer", ] [[package]] @@ -792,7 +791,6 @@ dependencies = [ "tracing", "tracing-subscriber", "url", - "wasmtimer 0.2.1", "wiremock", ] @@ -855,7 +853,6 @@ dependencies = [ "tiny-keccak", "tokio", "tracing", - "wasmtimer 0.2.1", "xor_name", ] @@ -915,7 +912,6 @@ dependencies = [ "custom_debug", "eyre", "futures", - "getrandom 0.2.15", "hex", "hkdf", "hyper 0.14.31", @@ -937,8 +933,6 @@ dependencies = [ "uuid", "void", "walkdir", - "wasm-bindgen-futures", - "wasmtimer 0.2.1", "xor_name", ] @@ -1587,14 +1581,10 @@ dependencies = [ "blstrs 0.7.1", "blsttc", "bytes", - "console_error_panic_hook", "const-hex", - "evmlib", "eyre", "futures", "hex", - "instant", - "js-sys", "libp2p", "pyo3", "rand 0.8.5", @@ -1602,18 +1592,13 @@ dependencies = [ "rmp-serde", "self_encryption", "serde", - "serde-wasm-bindgen", "sha2", "test-utils", "thiserror 1.0.69", "tokio", "tracing", "tracing-subscriber", - "tracing-web", "walkdir", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", "xor_name", ] @@ -2356,16 +2341,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - [[package]] name = "const-hex" version = "1.14.0" @@ -3201,7 +3176,6 @@ version = "0.1.6" dependencies = [ "alloy", "dirs-next", - "getrandom 0.2.15", "rand 0.8.5", "serde", "serde_with", @@ -3568,10 +3542,6 @@ name = "futures-timer" version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" -dependencies = [ - "gloo-timers", - "send_wrapper 0.4.0", -] [[package]] name = "futures-util" @@ -4195,18 +4165,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "group" version = "0.12.1" @@ -5047,9 +5005,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", ] [[package]] @@ -5236,7 +5191,6 @@ dependencies = [ "libp2p-tcp", "libp2p-upnp", "libp2p-websocket", - "libp2p-websocket-websys", "libp2p-yamux", "multiaddr", "pin-project", @@ -5590,7 +5544,6 @@ dependencies = [ "fnv", "futures", "futures-timer", - "getrandom 0.2.15", "libp2p-core", "libp2p-identity", "libp2p-swarm-derive", @@ -5602,7 +5555,6 @@ dependencies = [ "tokio", "tracing", "void", - "wasm-bindgen-futures", "web-time", ] @@ -5691,24 +5643,6 @@ dependencies = [ "webpki-roots 0.25.4", ] -[[package]] -name = "libp2p-websocket-websys" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38cf9b429dd07be52cd82c4c484b1694df4209210a7db3b9ffb00c7606e230c8" -dependencies = [ - "bytes", - "futures", - "js-sys", - "libp2p-core", - "parking_lot", - "send_wrapper 0.6.0", - "thiserror 1.0.69", - "tracing", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "libp2p-yamux" version = "0.46.0" @@ -5848,16 +5782,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "minicov" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27fe9f1cc3c22e1687f9446c2083c4c5fc7f0bcf1c7a86bdbded14985895b4b" -dependencies = [ - "cc", - "walkdir", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -8151,18 +8075,6 @@ dependencies = [ "pest", ] -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" - [[package]] name = "serde" version = "1.0.210" @@ -8172,17 +8084,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-wasm-bindgen" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - [[package]] name = "serde_derive" version = "1.0.210" @@ -9329,19 +9230,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "tracing-web" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e6a141feebd51f8d91ebfd785af50fca223c570b86852166caa3b141defe7c" -dependencies = [ - "js-sys", - "tracing-core", - "tracing-subscriber", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -9771,46 +9659,6 @@ version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" -[[package]] -name = "wasm-bindgen-test" -version = "0.3.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d44563646eb934577f2772656c7ad5e9c90fac78aa8013d776fcdaf24625d" -dependencies = [ - "js-sys", - "minicov", - "scoped-tls", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test-macro", -] - -[[package]] -name = "wasm-bindgen-test-macro" -version = "0.3.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54171416ce73aa0b9c377b51cc3cb542becee1cd678204812e8392e5b0e4a031" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.90", -] - -[[package]] -name = "wasmtimer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7ed9d8b15c7fb594d72bfb4b5a276f3d2029333cd93a932f376f5937f6f80ee" -dependencies = [ - "futures", - "js-sys", - "parking_lot", - "pin-utils", - "serde", - "slab", - "wasm-bindgen", -] - [[package]] name = "wasmtimer" version = "0.4.1" diff --git a/ant-bootstrap/Cargo.toml b/ant-bootstrap/Cargo.toml index b71fecaec0..a705c7623a 100644 --- a/ant-bootstrap/Cargo.toml +++ b/ant-bootstrap/Cargo.toml @@ -36,6 +36,3 @@ wiremock = "0.5" tokio = { version = "1.0", features = ["full", "test-util"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] } tempfile = "3.8.1" - -[target.'cfg(target_arch = "wasm32")'.dependencies] -wasmtimer = "0.2.0" diff --git a/ant-bootstrap/src/contacts.rs b/ant-bootstrap/src/contacts.rs index 61e5026991..0edbc25357 100644 --- a/ant-bootstrap/src/contacts.rs +++ b/ant-bootstrap/src/contacts.rs @@ -24,7 +24,6 @@ const MAINNET_CONTACTS: &[&str] = &[ ]; /// The client fetch timeout -#[cfg(not(target_arch = "wasm32"))] const FETCH_TIMEOUT_SECS: u64 = 30; /// Maximum number of endpoints to fetch at a time const MAX_CONCURRENT_FETCHES: usize = 3; @@ -51,13 +50,9 @@ impl ContactsFetcher { /// Create a new struct with the provided endpoints pub fn with_endpoints(endpoints: Vec) -> Result { - #[cfg(not(target_arch = "wasm32"))] let request_client = Client::builder() .timeout(Duration::from_secs(FETCH_TIMEOUT_SECS)) .build()?; - // Wasm does not have the timeout method yet. - #[cfg(target_arch = "wasm32")] - let request_client = Client::builder().build()?; Ok(Self { max_addrs: usize::MAX, @@ -219,10 +214,7 @@ impl ContactsFetcher { "Failed to get bootstrap addrs from URL, retrying {retries}/{MAX_RETRIES_ON_FETCH_FAILURE}" ); - #[cfg(not(target_arch = "wasm32"))] tokio::time::sleep(Duration::from_secs(1)).await; - #[cfg(target_arch = "wasm32")] - wasmtimer::tokio::sleep(Duration::from_secs(1)).await; }; Ok(bootstrap_addresses) diff --git a/ant-evm/Cargo.toml b/ant-evm/Cargo.toml index 446c5ec9a4..6c88635a3c 100644 --- a/ant-evm/Cargo.toml +++ b/ant-evm/Cargo.toml @@ -34,8 +34,5 @@ xor_name = "5.0.0" [dev-dependencies] tokio = { version = "1.32.0", features = ["macros", "rt"] } -[target.'cfg(target_arch = "wasm32")'.dependencies] -wasmtimer = { version = "0.2.0", features = ["serde"] } - [lints] workspace = true diff --git a/ant-evm/src/data_payments.rs b/ant-evm/src/data_payments.rs index 48f904f8d4..e1486384bb 100644 --- a/ant-evm/src/data_payments.rs +++ b/ant-evm/src/data_payments.rs @@ -14,10 +14,7 @@ use evmlib::{ }; use libp2p::{identity::PublicKey, PeerId}; use serde::{Deserialize, Serialize}; -#[cfg(not(target_arch = "wasm32"))] pub use std::time::SystemTime; -#[cfg(target_arch = "wasm32")] -pub use wasmtimer::std::SystemTime; use xor_name::XorName; /// The time in seconds that a quote is valid for diff --git a/ant-networking/Cargo.toml b/ant-networking/Cargo.toml index da438d95aa..b3d031691c 100644 --- a/ant-networking/Cargo.toml +++ b/ant-networking/Cargo.toml @@ -15,7 +15,6 @@ encrypt-records = [] local = ["libp2p/mdns"] loud = [] open-metrics = ["libp2p/metrics", "prometheus-client", "hyper", "sysinfo"] -# tcp is automatically enabled when compiling for wasm32 upnp = ["libp2p/upnp"] [dependencies] @@ -85,25 +84,5 @@ uuid = { version = "1.5.0", features = ["v4"] } [lints] workspace = true -# wasm build requirements [lib] -crate-type = ["cdylib", "rlib"] - -[target.'cfg(target_arch = "wasm32")'.dependencies] -getrandom = { version = "0.2.12", features = ["js"] } -libp2p = { version = "0.54.1", features = [ - "tokio", - "dns", - "kad", - "tcp", - "macros", - "request-response", - "cbor", - "identify", - "noise", - "yamux", - "websocket-websys", - "wasm-bindgen", -] } -wasmtimer = "0.2.0" -wasm-bindgen-futures = "0.4.40" +crate-type = ["cdylib", "rlib"] \ No newline at end of file diff --git a/ant-networking/src/bootstrap.rs b/ant-networking/src/bootstrap.rs index e6926f695e..ecdf71397c 100644 --- a/ant-networking/src/bootstrap.rs +++ b/ant-networking/src/bootstrap.rs @@ -10,7 +10,7 @@ use crate::{driver::PendingGetClosestType, SwarmDriver}; use rand::{rngs::OsRng, Rng}; use tokio::time::Duration; -use crate::target_arch::{interval, Instant, Interval}; +use crate::time::{interval, Instant, Interval}; /// The default interval at which NetworkDiscovery is triggered. /// The interval is increased as more peers are added to the routing table. @@ -108,7 +108,6 @@ impl ContinuousNetworkDiscover { /// Returns `true` if we should carry out the Kademlia Bootstrap process immediately. /// Also optionally returns the new interval for network discovery. - #[cfg_attr(target_arch = "wasm32", allow(clippy::unused_async))] pub(crate) async fn should_we_discover( &self, peers_in_rt: u32, @@ -138,10 +137,7 @@ impl ContinuousNetworkDiscover { "It has been {LAST_PEER_ADDED_TIME_LIMIT:?} since we last added a peer to RT. Slowing down the continuous network discovery process. Old interval: {current_interval:?}, New interval: {no_peer_added_slowdown_interval_duration:?}" ); - // `Interval` ticks immediately for Tokio, but not for `wasmtimer`, which is used for wasm32. - #[cfg_attr(target_arch = "wasm32", allow(unused_mut))] let mut new_interval = interval(no_peer_added_slowdown_interval_duration); - #[cfg(not(target_arch = "wasm32"))] new_interval.tick().await; return (should_network_discover, Some(new_interval)); @@ -154,10 +150,7 @@ impl ContinuousNetworkDiscover { let new_interval = if new_interval > current_interval { info!("More peers have been added to our RT!. Slowing down the continuous network discovery process. Old interval: {current_interval:?}, New interval: {new_interval:?}"); - // `Interval` ticks immediately for Tokio, but not for `wasmtimer`, which is used for wasm32. - #[cfg_attr(target_arch = "wasm32", allow(unused_mut))] let mut interval = interval(new_interval); - #[cfg(not(target_arch = "wasm32"))] interval.tick().await; Some(interval) diff --git a/ant-networking/src/cmd.rs b/ant-networking/src/cmd.rs index 345668c36e..66c91b612b 100644 --- a/ant-networking/src/cmd.rs +++ b/ant-networking/src/cmd.rs @@ -35,7 +35,7 @@ use std::{ use tokio::sync::oneshot; use xor_name::XorName; -use crate::target_arch::Instant; +use crate::time::Instant; const MAX_CONTINUOUS_HDD_WRITE_ERROR: usize = 5; diff --git a/ant-networking/src/driver.rs b/ant-networking/src/driver.rs index bb1637a099..0ee325f6d5 100644 --- a/ant-networking/src/driver.rs +++ b/ant-networking/src/driver.rs @@ -21,8 +21,8 @@ use crate::{ record_store_api::UnifiedRecordStore, relay_manager::RelayManager, replication_fetcher::ReplicationFetcher, - target_arch::Interval, - target_arch::{interval, spawn, Instant}, + time::Interval, + time::{interval, spawn, Instant}, transport, GetRecordError, Network, NodeIssue, CLOSE_GROUP_SIZE, }; #[cfg(feature = "open-metrics")] @@ -493,7 +493,6 @@ impl NetworkBuilder { let peer_id = PeerId::from(self.keypair.public()); // vdash metric (if modified please notify at https://github.com/happybeing/vdash/issues): - #[cfg(not(target_arch = "wasm32"))] info!( "Process (PID: {}) with PeerId: {peer_id}", std::process::id() @@ -689,12 +688,8 @@ impl NetworkBuilder { mdns, }; - #[cfg(not(target_arch = "wasm32"))] let swarm_config = libp2p::swarm::Config::with_tokio_executor() .with_idle_connection_timeout(CONNECTION_KEEP_ALIVE_TIMEOUT); - #[cfg(target_arch = "wasm32")] - let swarm_config = libp2p::swarm::Config::with_wasm_executor() - .with_idle_connection_timeout(CONNECTION_KEEP_ALIVE_TIMEOUT); let swarm = Swarm::new(transport, behaviour, peer_id, swarm_config); @@ -1075,9 +1070,7 @@ impl SwarmDriver { let new_duration = Duration::from_secs(std::cmp::min(scaled, max_cache_save_duration.as_secs())); info!("Scaling up the bootstrap cache save interval to {new_duration:?}"); - // `Interval` ticks immediately for Tokio, but not for `wasmtimer`, which is used for wasm32. *current_interval = interval(new_duration); - #[cfg(not(target_arch = "wasm32"))] current_interval.tick().await; trace!("Bootstrap cache synced in {:?}", start.elapsed()); diff --git a/ant-networking/src/event/kad.rs b/ant-networking/src/event/kad.rs index 5c83bf103c..6dcf286cdf 100644 --- a/ant-networking/src/event/kad.rs +++ b/ant-networking/src/event/kad.rs @@ -7,9 +7,8 @@ // permissions and limitations relating to use of the SAFE Network Software. use crate::{ - driver::PendingGetClosestType, get_graph_entry_from_record, get_quorum_value, - target_arch::Instant, GetRecordCfg, GetRecordError, NetworkError, Result, SwarmDriver, - CLOSE_GROUP_SIZE, + driver::PendingGetClosestType, get_graph_entry_from_record, get_quorum_value, time::Instant, + GetRecordCfg, GetRecordError, NetworkError, Result, SwarmDriver, CLOSE_GROUP_SIZE, }; use ant_protocol::{ storage::{try_serialize_record, GraphEntry, RecordKind}, diff --git a/ant-networking/src/event/swarm.rs b/ant-networking/src/event/swarm.rs index b37165bd50..d4385d0500 100644 --- a/ant-networking/src/event/swarm.rs +++ b/ant-networking/src/event/swarm.rs @@ -8,7 +8,7 @@ use crate::{ event::NodeEvent, multiaddr_get_ip, multiaddr_is_global, multiaddr_strip_p2p, - relay_manager::is_a_relayed_peer, target_arch::Instant, NetworkEvent, Result, SwarmDriver, + relay_manager::is_a_relayed_peer, time::Instant, NetworkEvent, Result, SwarmDriver, }; use ant_protocol::version::{IDENTIFY_NODE_VERSION_STR, IDENTIFY_PROTOCOL_STR}; #[cfg(feature = "local")] diff --git a/ant-networking/src/lib.rs b/ant-networking/src/lib.rs index 6bfe3031c3..dda9e1d8d3 100644 --- a/ant-networking/src/lib.rs +++ b/ant-networking/src/lib.rs @@ -26,7 +26,7 @@ mod record_store; mod record_store_api; mod relay_manager; mod replication_fetcher; -pub mod target_arch; +pub mod time; mod transport; use cmd::LocalSwarmCmd; @@ -45,7 +45,7 @@ pub use self::{ }; #[cfg(feature = "open-metrics")] pub use metrics::service::MetricsRegistries; -pub use target_arch::{interval, sleep, spawn, Instant, Interval}; +pub use time::{interval, sleep, spawn, Instant, Interval}; use self::{cmd::NetworkSwarmCmd, error::Result}; use ant_evm::{PaymentQuote, QuotingMetrics}; @@ -592,7 +592,7 @@ impl Network { match backoff.next() { Some(Some(duration)) => { - crate::target_arch::sleep(duration).await; + crate::time::sleep(duration).await; debug!("Getting record from network of {pretty_key:?} via backoff..."); } _ => break Err(err.into()), @@ -873,7 +873,7 @@ impl Network { match backoff.next() { Some(Some(duration)) => { - crate::target_arch::sleep(duration).await; + crate::time::sleep(duration).await; } _ => break Err(err), } diff --git a/ant-networking/src/metrics/bad_node.rs b/ant-networking/src/metrics/bad_node.rs index 4e85931126..311c0ca8aa 100644 --- a/ant-networking/src/metrics/bad_node.rs +++ b/ant-networking/src/metrics/bad_node.rs @@ -6,7 +6,7 @@ // KIND, either express or implied. Please review the Licences for the specific language governing // permissions and limitations relating to use of the SAFE Network Software. -use crate::target_arch::interval; +use crate::time::interval; use ant_protocol::CLOSE_GROUP_SIZE; use libp2p::PeerId; use prometheus_client::{ diff --git a/ant-networking/src/metrics/mod.rs b/ant-networking/src/metrics/mod.rs index ef9f636bcb..e07d64e10c 100644 --- a/ant-networking/src/metrics/mod.rs +++ b/ant-networking/src/metrics/mod.rs @@ -13,7 +13,7 @@ pub mod service; mod upnp; use crate::MetricsRegistries; -use crate::{log_markers::Marker, target_arch::sleep}; +use crate::{log_markers::Marker, time::sleep}; use bad_node::{BadNodeMetrics, BadNodeMetricsMsg, TimeFrame}; use libp2p::{ metrics::{Metrics as Libp2pMetrics, Recorder}, @@ -275,7 +275,7 @@ impl NetworkMetricsRecorder { let _ = self.shunned_count.inc(); let bad_nodes_notifier = self.bad_nodes_notifier.clone(); let flagged_by = *flagged_by; - crate::target_arch::spawn(async move { + crate::time::spawn(async move { if let Err(err) = bad_nodes_notifier .send(BadNodeMetricsMsg::ShunnedByPeer(flagged_by)) .await @@ -306,7 +306,7 @@ impl NetworkMetricsRecorder { pub(crate) fn record_change_in_close_group(&self, new_close_group: Vec) { let bad_nodes_notifier = self.bad_nodes_notifier.clone(); - crate::target_arch::spawn(async move { + crate::time::spawn(async move { if let Err(err) = bad_nodes_notifier .send(BadNodeMetricsMsg::CloseGroupUpdated(new_close_group)) .await diff --git a/ant-networking/src/network_discovery.rs b/ant-networking/src/network_discovery.rs index 838cf685c0..f00a75c2d8 100644 --- a/ant-networking/src/network_discovery.rs +++ b/ant-networking/src/network_discovery.rs @@ -6,7 +6,7 @@ // KIND, either express or implied. Please review the Licences for the specific language governing // permissions and limitations relating to use of the SAFE Network Software. -use crate::target_arch::Instant; +use crate::time::Instant; use ant_protocol::NetworkAddress; use libp2p::{kad::KBucketKey, PeerId}; use rand::{thread_rng, Rng}; diff --git a/ant-networking/src/record_store.rs b/ant-networking/src/record_store.rs index b4ab4ff6b3..9b1fccd052 100644 --- a/ant-networking/src/record_store.rs +++ b/ant-networking/src/record_store.rs @@ -10,7 +10,7 @@ use crate::cmd::LocalSwarmCmd; use crate::driver::MAX_PACKET_SIZE; use crate::send_local_swarm_cmd; -use crate::target_arch::{spawn, Instant}; +use crate::time::{spawn, Instant}; use crate::{event::NetworkEvent, log_markers::Marker}; use aes_gcm_siv::{ aead::{Aead, KeyInit}, diff --git a/ant-networking/src/replication_fetcher.rs b/ant-networking/src/replication_fetcher.rs index a009209451..360e2fbe6b 100644 --- a/ant-networking/src/replication_fetcher.rs +++ b/ant-networking/src/replication_fetcher.rs @@ -7,8 +7,8 @@ // permissions and limitations relating to use of the SAFE Network Software. #![allow(clippy::mutable_key_type)] -use crate::target_arch::spawn; -use crate::{event::NetworkEvent, target_arch::Instant}; +use crate::time::spawn; +use crate::{event::NetworkEvent, time::Instant}; use ant_evm::U256; use ant_protocol::{ convert_distance_to_u256, storage::RecordType, NetworkAddress, PrettyPrintRecordKey, diff --git a/ant-networking/src/target_arch.rs b/ant-networking/src/target_arch.rs deleted file mode 100644 index 680528496a..0000000000 --- a/ant-networking/src/target_arch.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2024 MaidSafe.net limited. -// -// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3. -// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed -// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. Please review the Licences for the specific language governing -// permissions and limitations relating to use of the SAFE Network Software. - -#[cfg(not(target_arch = "wasm32"))] -pub use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; -/// Wasm32 target arch does not support `time` or spawning via tokio -/// so we shim in alternatives here when building for that architecture -#[cfg(not(target_arch = "wasm32"))] -pub use tokio::{ - spawn, - time::{interval, sleep, timeout, Interval}, -}; - -#[cfg(target_arch = "wasm32")] -pub use std::time::Duration; - -#[cfg(target_arch = "wasm32")] -pub use wasmtimer::{ - std::{Instant, SystemTime, UNIX_EPOCH}, - tokio::{interval, sleep, timeout, Interval}, -}; - -#[cfg(target_arch = "wasm32")] -pub use wasm_bindgen_futures::spawn_local as spawn; diff --git a/ant-networking/src/time.rs b/ant-networking/src/time.rs new file mode 100644 index 0000000000..2bd0a9f043 --- /dev/null +++ b/ant-networking/src/time.rs @@ -0,0 +1,12 @@ +/// Copyright 2024 MaidSafe.net limited. +/// +/// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3. +/// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed +/// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +/// KIND, either express or implied. Please review the Licences for the specific language governing +/// permissions and limitations relating to use of the SAFE Network Software. +pub use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; +pub use tokio::{ + spawn, + time::{interval, sleep, timeout, Interval}, +}; diff --git a/ant-networking/src/transport/other.rs b/ant-networking/src/transport.rs similarity index 61% rename from ant-networking/src/transport/other.rs rename to ant-networking/src/transport.rs index 75bca5ed27..d452560301 100644 --- a/ant-networking/src/transport/other.rs +++ b/ant-networking/src/transport.rs @@ -1,3 +1,11 @@ +// Copyright 2024 MaidSafe.net limited. +// +// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3. +// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed +// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. Please review the Licences for the specific language governing +// permissions and limitations relating to use of the SAFE Network Software. + #[cfg(feature = "open-metrics")] use crate::MetricsRegistries; use libp2p::{ diff --git a/ant-networking/src/transport/mod.rs b/ant-networking/src/transport/mod.rs deleted file mode 100644 index 4f8b142993..0000000000 --- a/ant-networking/src/transport/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[cfg_attr(target_arch = "wasm32", path = "wasm32.rs")] -#[cfg_attr(not(target_arch = "wasm32"), path = "other.rs")] -pub(crate) mod mod_impl; - -pub(crate) use mod_impl::build_transport; diff --git a/ant-networking/src/transport/wasm32.rs b/ant-networking/src/transport/wasm32.rs deleted file mode 100644 index 5eb645063e..0000000000 --- a/ant-networking/src/transport/wasm32.rs +++ /dev/null @@ -1,18 +0,0 @@ -// wasm32 environments typically only support WebSockets (and WebRTC or WebTransport), so no plain UDP or TCP. - -use libp2p::{ - core::{muxing::StreamMuxerBox, transport, upgrade}, - identity::Keypair, - noise, websocket_websys, yamux, PeerId, Transport as _, -}; - -pub(crate) fn build_transport(keypair: &Keypair) -> transport::Boxed<(PeerId, StreamMuxerBox)> { - // We build a single transport here, WebSockets. - websocket_websys::Transport::default() - .upgrade(upgrade::Version::V1) - .authenticate( - noise::Config::new(keypair).expect("Signing libp2p-noise static DH keypair failed."), - ) - .multiplex(yamux::Config::default()) - .boxed() -} diff --git a/ant-node/src/metrics.rs b/ant-node/src/metrics.rs index 43bad46639..53c7641db1 100644 --- a/ant-node/src/metrics.rs +++ b/ant-node/src/metrics.rs @@ -7,7 +7,7 @@ // permissions and limitations relating to use of the SAFE Network Software. use crate::Marker; -use ant_networking::target_arch::Instant; +use ant_networking::time::Instant; #[cfg(feature = "open-metrics")] use ant_networking::MetricsRegistries; use prometheus_client::{ diff --git a/ant-node/src/node.rs b/ant-node/src/node.rs index 2515af6344..3877a31a18 100644 --- a/ant-node/src/node.rs +++ b/ant-node/src/node.rs @@ -17,7 +17,7 @@ use ant_evm::RewardsAddress; #[cfg(feature = "open-metrics")] use ant_networking::MetricsRegistries; use ant_networking::{ - target_arch::sleep, Instant, Network, NetworkBuilder, NetworkEvent, NodeIssue, SwarmDriver, + time::sleep, Instant, Network, NetworkBuilder, NetworkEvent, NodeIssue, SwarmDriver, }; use ant_protocol::{ convert_distance_to_u256, diff --git a/autonomi/Cargo.toml b/autonomi/Cargo.toml index e6936d12b4..57db0e6c6f 100644 --- a/autonomi/Cargo.toml +++ b/autonomi/Cargo.toml @@ -53,14 +53,11 @@ rayon = "1.8.0" rmp-serde = "1.1.1" self_encryption = "~0.30.0" serde = { version = "1.0.133", features = ["derive", "rc"] } -serde-wasm-bindgen = "0.6.5" sha2 = "0.10.6" thiserror = "1.0.23" tokio = { version = "1.35.0", features = ["sync"] } tracing = { version = "~0.1.26" } walkdir = "2.5.0" -wasm-bindgen = "0.2.93" -wasm-bindgen-futures = "0.4.43" xor_name = "5.0.0" [dev-dependencies] @@ -72,17 +69,6 @@ sha2 = "0.10.6" # Removing the version field is a workaround. test-utils = { path = "../test-utils" } tracing-subscriber = { version = "0.3", features = ["env-filter"] } -wasm-bindgen-test = "0.3.43" - -[target.'cfg(target_arch = "wasm32")'.dependencies] -console_error_panic_hook = "0.1.7" -evmlib = { path = "../evmlib", version = "0.1.6", features = ["wasm-bindgen"] } -# See https://github.com/sebcrozet/instant/blob/7bd13f51f5c930239fddc0476a837870fb239ed7/README.md#using-instant-for-a-wasm-platform-where-performancenow-is-not-available -instant = { version = "0.1", features = ["wasm-bindgen", "inaccurate"] } -js-sys = "0.3.70" -tracing-subscriber = { version = "0.3", features = ["env-filter"] } -tracing-web = "0.1.3" -xor_name = { version = "5.0.0", features = ["serialize-hex"] } [lints] workspace = true diff --git a/autonomi/README.md b/autonomi/README.md index d77c38a81b..72be58b39d 100644 --- a/autonomi/README.md +++ b/autonomi/README.md @@ -135,10 +135,6 @@ Deployer wallet private key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efca Genesis wallet balance: (tokens: 20000000000000000000000000, gas: 9998998011366954730202) ``` -# WASM - -For documentation on WASM, see [./README_WASM.md]. - # Python For documentation on the Python bindings, see [./README_PYTHON.md]. diff --git a/autonomi/README_WASM.md b/autonomi/README_WASM.md deleted file mode 100644 index 8c6478def7..0000000000 --- a/autonomi/README_WASM.md +++ /dev/null @@ -1,95 +0,0 @@ -# Autonomi JS API - -Note: the JS API is experimental and will be subject to change. - -The entry point for connecting to the network is {@link Client.connect}. - -This API is a wrapper around the Rust API, found here: https://docs.rs/autonomi/latest/autonomi. The Rust API contains more detailed documentation on concepts and some types. - -## Addresses - -For addresses (chunk, data, archives, etc) we're using hex-encoded strings containing a 256-bit XOR addresse. For example: `abcdefg012345678900000000000000000000000000000000000000000000000`. - -## Example - -Note: `getEvmNetwork` will use hardcoded EVM network values that should be set during compilation of this library. - -```javascript -import init, { Client, Wallet, getEvmNetwork } from 'autonomi'; - -let client = await new Client(["/ip4/127.0.0.1/tcp/36075/ws/p2p/12D3KooWALb...BhDAfJY"]); -console.log("connected"); - -let wallet = Wallet.new_from_private_key(getEvmNetwork, "your_private_key_here"); -console.log("wallet retrieved"); - -let data = new Uint8Array([1, 2, 3]); -let result = await client.put(data, wallet); -console.log("Data stored at:", result); - -let fetchedData = await client.get(result); -console.log("Data retrieved:", fetchedData); -``` - -## Funded wallet from custom local network - -```js -const evmNetwork = getEvmNetworkCustom("http://localhost:4343", "", ""); -const wallet = getFundedWalletWithCustomNetwork(evmNetwork, "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"); -``` - -# Developing - -## WebAssembly - -To run a WASM test - -- Install `wasm-pack` -- Make sure your Rust supports the `wasm32-unknown-unknown` target. (If you - have `rustup`: `rustup target add wasm32-unknown-unknown`.) -- Pass a bootstrap peer via `ANT_PEERS`. This *has* to be the websocket address, - e.g. `/ip4//tcp//ws/p2p/`. - - As well as the other environment variables needed for EVM payments (e.g. `RPC_URL`). -- Optionally specify the specific test, e.g. `-- put` to run `put()` in `wasm.rs` only. - -Example: - -```sh -ANT_PEERS=/ip4//tcp//ws/p2p/ wasm-pack test --release --firefox autonomi --features=files --test wasm -- put -``` - -### Test from JS in the browser - -`wasm-pack test` does not execute JavaScript, but runs mostly WebAssembly. Again make sure the environment variables are -set and build the JS package: - -```sh -wasm-pack build --dev --target web autonomi --features=vault -``` - -Then cd into `autonomi/tests-js`, and use `npm` to install and serve the test html file. - -``` -cd autonomi/tests-js -npm install -npm run serve -``` - -Then go to `http://127.0.0.1:8080/tests-js` in the browser. Here, enter a `ws` multiaddr of a local node and press ' -run'. - -## MetaMask example - -There is a MetaMask example for doing a simple put operation. - -Build the package with the `external-signer` feature (and again with the env variables) and run a webserver, e.g. with -Python: - -```sh -wasm-pack build --dev --target web autonomi --features=external-signer -python -m http.server --directory autonomi 8000 -``` - -Then visit `http://127.0.0.1:8000/examples/metamask` in your (modern) browser. - -Here, enter a `ws` multiaddr of a local node and press 'run'. diff --git a/autonomi/examples/metamask/index.html b/autonomi/examples/metamask/index.html deleted file mode 100644 index 128273acbc..0000000000 --- a/autonomi/examples/metamask/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/autonomi/examples/metamask/index.js b/autonomi/examples/metamask/index.js deleted file mode 100644 index 66bf524037..0000000000 --- a/autonomi/examples/metamask/index.js +++ /dev/null @@ -1,233 +0,0 @@ -import init, * as autonomi from '../../pkg/autonomi.js'; - -export async function externalSignerPrivateDataPutToVault(peerAddr) { - try { - // Check if MetaMask (window.ethereum) is available - if (typeof window.ethereum === 'undefined') { - throw new Error('MetaMask is not installed'); - } - - // Request account access from MetaMask - const accounts = await window.ethereum.request({method: 'eth_requestAccounts'}); - const sender = accounts[0]; // Get the first account - - // Setup API client - await init(); - - autonomi.logInit("autonomi=trace"); - - const client = await autonomi.Client.connect([peerAddr]); - - // Generate 1MB of random bytes in a Uint8Array - const data = new Uint8Array(1024 * 1024).map(() => Math.floor(Math.random() * 256)); - - // Encrypt the data to chunks - const [dataMapChunk, dataChunks, dataMapChunkAddress, dataChunkAddresses] = autonomi.encryptData(data); - - // Fetch quotes for the chunks - const [quotes, quotePayments, _freeChunks] = await client.getQuotes(dataChunkAddresses); - - // Pay for data chunks (not the data map) - const receipt = await executeQuotePayments(sender, quotes, quotePayments); - - // Wait for a few seconds to allow tx to confirm - await new Promise(resolve => setTimeout(resolve, 5000)); - - // Upload the data - const privateDataAccess = await client.putPrivateDataWithReceipt(data, receipt); - - // Create a private archive - const privateArchive = new autonomi.PrivateArchive(); - - // Add our data's data map chunk to the private archive - privateArchive.addFile("test", privateDataAccess, autonomi.createMetadata(data.length)); - - // Get the private archive's bytes - const privateArchiveBytes = privateArchive.bytes(); - - // Encrypt the private archive to chunks - const [paDataMapChunk, paDataChunks, paDataMapChunkAddress, paDataChunkAddresses] = autonomi.encryptData(privateArchiveBytes); - - // Fetch quotes for the private archive chunks - const [paQuotes, paQuotePayments, _paFreeChunks] = await client.getQuotes(paDataChunkAddresses); - - // Pay for the private archive chunks (not the data map) - const paReceipt = await executeQuotePayments(sender, paQuotes, paQuotePayments); - - // Wait for a few seconds to allow tx to confirm - await new Promise(resolve => setTimeout(resolve, 5000)); - - // Upload the private archive - const privateArchiveAccess = await client.putPrivateArchiveWithReceipt(privateArchive, paReceipt); - - // Generate a random vault key (should normally be derived from a constant signature) - const vaultKey = autonomi.genSecretKey(); - - // Fetch user data from vault (won't exist, so will be empty) - let userData; - - try { - userData = await client.getUserDataFromVault(vaultKey); - } catch (err) { - userData = new autonomi.UserData(); - } - - // Add archive to user data - userData.addPrivateFileArchive(privateArchiveAccess, "test-archive"); - - // Get or create a scratchpad for the user data - let scratchpad = await client.getOrCreateUserDataScratchpad(vaultKey); - - // Content address of the scratchpad - let scratchPadAddress = scratchpad.xorName(); - - // Fetch quotes for the scratchpad - const [spQuotes, spQuotePayments, _spFreeChunks] = await client.getQuotes(scratchPadAddress ? [scratchPadAddress] : []); - - // Pay for the private archive chunks (not the data map) - const spReceipt = await executeQuotePayments(sender, spQuotes, spQuotePayments); - - // Wait for a few seconds to allow tx to confirm - await new Promise(resolve => setTimeout(resolve, 5000)); - - // Update vault - await client.putUserDataToVaultWithReceipt(userData, spReceipt, vaultKey); - - // VERIFY UPLOADED DATA - - // Fetch user data - let fetchedUserData = await client.getUserDataFromVault(vaultKey); - - // Get the first key - let fetchedPrivateArchiveAccess = fetchedUserData.privateFileArchives().keys().next().value; - - // Get private archive - let fetchedPrivateArchive = await client.getPrivateArchive(fetchedPrivateArchiveAccess); - - // Select first file in private archive - let [fetchedFilePath, [fetchedPrivateFileAccess, fetchedFileMetadata]] = fetchedPrivateArchive.map().entries().next().value; - - console.log(fetchedFilePath); - console.log(fetchedPrivateFileAccess); - console.log(fetchedFileMetadata); - - // Fetch private file/data - let fetchedPrivateFile = await client.getPrivateData(fetchedPrivateFileAccess); - - // Compare to original data - console.log("Comparing fetched data to original data.."); - - if (fetchedPrivateFile.toString() === data.toString()) { - console.log("Data matches! Private file upload to vault was successful!"); - } else { - console.log("Data does not match!! Something went wrong..") - } - } catch (error) { - console.error("An error occurred:", error); - } -} - -// Helper function to send a transaction through MetaMask using Ethereum JSON-RPC -async function sendTransaction({from, to, data}) { - const transactionParams = { - from: from, // Sender address - to: to, // Destination address - data: data, // Calldata (transaction input) - }; - - try { - // Send the transaction via MetaMask and get the transaction hash - const txHash = await window.ethereum.request({ - method: 'eth_sendTransaction', - params: [transactionParams] - }); - - console.log(`Transaction sent with hash: ${txHash}`); - return txHash; // Return the transaction hash - - } catch (error) { - console.error("Failed to send transaction:", error); - throw error; - } -} - -async function waitForTransactionConfirmation(txHash) { - const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); - - // Poll for the transaction receipt - while (true) { - // Query the transaction receipt - const receipt = await window.ethereum.request({ - method: 'eth_getTransactionReceipt', - params: [txHash], - }); - - // If the receipt is found, the transaction has been mined - if (receipt !== null) { - // Check if the transaction was successful (status is '0x1') - if (receipt.status === '0x1') { - console.log('Transaction successful!', receipt); - return receipt; // Return the transaction receipt - } else { - console.log('Transaction failed!', receipt); - throw new Error('Transaction failed'); - } - } - - // Wait for 1 second before checking again - await delay(1000); - } -} - -const executeQuotePayments = async (sender, quotes, quotePayments) => { - // Get the EVM network - let evmNetwork = autonomi.getEvmNetwork(); - - // Form quotes payment calldata - const payForQuotesCalldata = autonomi.getPayForQuotesCalldata( - evmNetwork, - quotePayments - ); - - // Form approve to spend tokens calldata - const approveCalldata = autonomi.getApproveToSpendTokensCalldata( - evmNetwork, - payForQuotesCalldata.approve_spender, - payForQuotesCalldata.approve_amount - ); - - console.log("Sending approve transaction.."); - - // Approve to spend tokens - let hash = await sendTransaction({ - from: sender, - to: approveCalldata[1], - data: approveCalldata[0] - }); - - // Wait for approve tx to confirm - await waitForTransactionConfirmation(hash); - - let payments = {}; - - // Execute batched quote payment transactions - for (const [calldata, quoteHashes] of payForQuotesCalldata.batched_calldata_map) { - console.log("Sending batched data payment transaction.."); - - let hash = await sendTransaction({ - from: sender, - to: payForQuotesCalldata.to, - data: calldata - }); - - await waitForTransactionConfirmation(hash); - - // Record the transaction hashes for each quote - quoteHashes.forEach(quoteHash => { - payments[quoteHash] = hash; - }); - } - - // Generate receipt - return autonomi.getReceiptFromQuotesAndPayments(quotes, payments); -} \ No newline at end of file diff --git a/autonomi/src/client/data/mod.rs b/autonomi/src/client/data/mod.rs index d9de0f8a63..d336c60dfc 100644 --- a/autonomi/src/client/data/mod.rs +++ b/autonomi/src/client/data/mod.rs @@ -215,7 +215,7 @@ impl Client { data: Bytes, payment_option: PaymentOption, ) -> Result { - let now = ant_networking::target_arch::Instant::now(); + let now = ant_networking::time::Instant::now(); let (data_map_chunk, chunks) = encrypt(data)?; debug!("Encryption took: {:.2?}", now.elapsed()); diff --git a/autonomi/src/client/data/public.rs b/autonomi/src/client/data/public.rs index 9f758edde8..35d476be18 100644 --- a/autonomi/src/client/data/public.rs +++ b/autonomi/src/client/data/public.rs @@ -44,7 +44,7 @@ impl Client { data: Bytes, payment_option: PaymentOption, ) -> Result { - let now = ant_networking::target_arch::Instant::now(); + let now = ant_networking::time::Instant::now(); let (data_map_chunk, chunks) = encrypt(data)?; let data_map_addr = data_map_chunk.address(); debug!("Encryption took: {:.2?}", now.elapsed()); @@ -143,7 +143,7 @@ impl Client { /// Get the estimated cost of storing a piece of data. pub async fn data_cost(&self, data: Bytes) -> Result { - let now = ant_networking::target_arch::Instant::now(); + let now = ant_networking::time::Instant::now(); let (data_map_chunk, chunks) = encrypt(data)?; debug!("Encryption took: {:.2?}", now.elapsed()); diff --git a/autonomi/src/client/external_signer.rs b/autonomi/src/client/external_signer.rs index 30114712f3..4309dba99f 100644 --- a/autonomi/src/client/external_signer.rs +++ b/autonomi/src/client/external_signer.rs @@ -41,7 +41,7 @@ impl Client { /// /// Returns the data map chunk and file chunks. pub fn encrypt_data(data: Bytes) -> Result<(Chunk, Vec), PutError> { - let now = ant_networking::target_arch::Instant::now(); + let now = ant_networking::time::Instant::now(); let result = encrypt(data)?; debug!("Encryption took: {:.2?}", now.elapsed()); diff --git a/autonomi/src/client/files/archive.rs b/autonomi/src/client/files/archive.rs index 8aebc1df85..03a82d423a 100644 --- a/autonomi/src/client/files/archive.rs +++ b/autonomi/src/client/files/archive.rs @@ -11,7 +11,7 @@ use std::{ path::{Path, PathBuf}, }; -use ant_networking::target_arch::{Duration, SystemTime, UNIX_EPOCH}; +use ant_networking::time::{Duration, SystemTime, UNIX_EPOCH}; use crate::{ client::{ diff --git a/autonomi/src/client/files/archive_public.rs b/autonomi/src/client/files/archive_public.rs index f4b487747f..19f1756b8b 100644 --- a/autonomi/src/client/files/archive_public.rs +++ b/autonomi/src/client/files/archive_public.rs @@ -11,7 +11,7 @@ use std::{ path::{Path, PathBuf}, }; -use ant_networking::target_arch::{Duration, SystemTime, UNIX_EPOCH}; +use ant_networking::time::{Duration, SystemTime, UNIX_EPOCH}; use ant_evm::{AttoTokens, EvmWallet}; use bytes::Bytes; diff --git a/autonomi/src/client/files/fs_public.rs b/autonomi/src/client/files/fs_public.rs index a35cce82f2..60f13d0cb1 100644 --- a/autonomi/src/client/files/fs_public.rs +++ b/autonomi/src/client/files/fs_public.rs @@ -14,7 +14,7 @@ use crate::client::files::get_relative_file_path_from_abs_file_and_folder_path; use crate::client::utils::process_tasks_with_max_concurrency; use crate::client::Client; use ant_evm::EvmWallet; -use ant_networking::target_arch::{Duration, SystemTime}; +use ant_networking::time::{Duration, SystemTime}; use bytes::Bytes; use std::path::PathBuf; @@ -164,7 +164,7 @@ impl Client { // re-do encryption to get the correct map xorname here // this code needs refactor - let now = ant_networking::target_arch::Instant::now(); + let now = ant_networking::time::Instant::now(); let (data_map_chunk, _) = crate::self_encryption::encrypt(file_bytes)?; tracing::debug!("Encryption took: {:.2?}", now.elapsed()); let map_xor_name = *data_map_chunk.address().xorname(); diff --git a/autonomi/src/client/mod.rs b/autonomi/src/client/mod.rs index 9c8ae7b4b8..b6ddcfbbb9 100644 --- a/autonomi/src/client/mod.rs +++ b/autonomi/src/client/mod.rs @@ -28,9 +28,6 @@ pub mod registers; #[cfg_attr(docsrs, doc(cfg(feature = "vault")))] pub mod vault; -#[cfg(target_arch = "wasm32")] -pub mod wasm; - // private module with utility functions mod rate_limiter; mod utils; @@ -188,7 +185,7 @@ impl Client { let network_clone = network.clone(); let peers = peers.to_vec(); - let _handle = ant_networking::target_arch::spawn(async move { + let _handle = ant_networking::time::spawn(async move { for addr in peers { if let Err(err) = network_clone.dial(addr.clone()).await { error!("Failed to dial addr={addr} with err: {err:?}"); @@ -198,7 +195,7 @@ impl Client { // Wait until we have added a few peers to our routing table. let (sender, receiver) = futures::channel::oneshot::channel(); - ant_networking::target_arch::spawn(handle_event_receiver(event_receiver, sender)); + ant_networking::time::spawn(handle_event_receiver(event_receiver, sender)); receiver.await.expect("sender should not close")?; debug!("Enough peers were added to our routing table, initialization complete"); @@ -236,7 +233,7 @@ impl Client { // Spawn task to dial to the given peers let network_clone = network.clone(); let peers = peers.to_vec(); - let _handle = ant_networking::target_arch::spawn(async move { + let _handle = ant_networking::time::spawn(async move { for addr in peers { if let Err(err) = network_clone.dial(addr.clone()).await { error!("Failed to dial addr={addr} with err: {err:?}"); @@ -246,7 +243,7 @@ impl Client { }); let (sender, receiver) = futures::channel::oneshot::channel(); - ant_networking::target_arch::spawn(handle_event_receiver(event_receiver, sender)); + ant_networking::time::spawn(handle_event_receiver(event_receiver, sender)); receiver.await.expect("sender should not close")?; debug!("Client is connected to the network"); @@ -255,7 +252,7 @@ impl Client { // Seems the too many `initial dial`s could result in failure, // when startup quoting/upload tasks got started up immediatly. // Hence, put in a forced wait to allow `initial network discovery` to be completed. - ant_networking::target_arch::sleep(Duration::from_secs(5)).await; + ant_networking::time::sleep(Duration::from_secs(5)).await; Ok(Self { network, @@ -296,7 +293,7 @@ fn build_client_and_run_swarm(local: bool) -> (Network, mpsc::Receiver, diff --git a/autonomi/src/client/wasm.rs b/autonomi/src/client/wasm.rs deleted file mode 100644 index ce49ba83d2..0000000000 --- a/autonomi/src/client/wasm.rs +++ /dev/null @@ -1,868 +0,0 @@ -use super::address::{addr_to_str, str_to_addr}; -#[cfg(feature = "vault")] -use super::vault::UserData; -use crate::client::data::DataMapChunk; -use crate::client::payment::Receipt; -use ant_protocol::storage::Chunk; -use libp2p::Multiaddr; -use wasm_bindgen::prelude::*; - -/// The `Client` object allows interaction with the network to store and retrieve data. -/// -/// To connect to the network, see {@link Client.connect}. -/// -/// # Example -/// -/// ```js -/// let client = await Client.connect(["/ip4/127.0.0.1/tcp/36075/ws/p2p/12D3KooWALb...BhDAfJY"]); -/// const dataAddr = await client.putData(new Uint8Array([0, 1, 2, 3]), wallet); -/// -/// const archive = new Archive(); -/// archive.addFile("foo", dataAddr, createMetadata(4)); -/// -/// const archiveAddr = await client.putArchive(archive, wallet); -/// const archiveFetched = await client.getArchive(archiveAddr); -/// ``` -#[wasm_bindgen(js_name = Client)] -pub struct JsClient(super::Client); - -#[wasm_bindgen] -pub struct AttoTokens(ant_evm::AttoTokens); -#[wasm_bindgen] -impl AttoTokens { - #[wasm_bindgen(js_name = toString)] - pub fn to_string(&self) -> String { - self.0.to_string() - } -} - -#[wasm_bindgen(js_name = Chunk)] -pub struct JsChunk(Chunk); - -#[wasm_bindgen(js_class = Chunk)] -impl JsChunk { - /// Returns the bytes. - #[wasm_bindgen] - pub fn bytes(&self) -> Vec { - self.0.value.to_vec() - } - - /// Returns the XOR name. - #[wasm_bindgen] - pub fn xor_name(&self) -> String { - self.0.address.xorname().to_string() - } -} - -#[wasm_bindgen(js_class = Client)] -impl JsClient { - /// Connect to the network via the given peers. - /// - /// # Example - /// - /// ```js - /// let client = await Client.connect(["/ip4/127.0.0.1/tcp/36075/ws/p2p/12D3KooWALb...BhDAfJY"]); - /// ``` - #[wasm_bindgen] - pub async fn connect(peers: Vec) -> Result { - let peers = peers - .into_iter() - .map(|peer| peer.parse()) - .collect::, _>>()?; - - let client = super::Client::init_with_peers(peers).await?; - - Ok(JsClient(client)) - } - - /// Upload a chunk to the network. - /// - /// Returns the hex encoded address of the chunk. - /// - /// This is not yet implemented. - #[wasm_bindgen(js_name = putChunk)] - pub async fn put_chunk(&self, _data: Vec, _wallet: &JsWallet) -> Result { - async { unimplemented!() }.await - } - - /// Fetch the chunk from the network. - #[wasm_bindgen(js_name = getChunk)] - pub async fn get_chunk(&self, addr: String) -> Result, JsError> { - let addr = str_to_addr(&addr)?; - let chunk = self.0.chunk_get(addr).await?; - - Ok(chunk.value().to_vec()) - } - - /// Upload data to the network. - /// - /// Returns the hex encoded address of the data. - #[wasm_bindgen(js_name = putData)] - pub async fn put_data(&self, data: Vec, wallet: &JsWallet) -> Result { - let data = crate::Bytes::from(data); - let xorname = self.0.data_put_public(data, (&wallet.0).into()).await?; - - Ok(addr_to_str(xorname)) - } - - /// Upload private data to the network. - /// - /// Returns the `DataMapChunk` chunk of the data. - #[wasm_bindgen(js_name = putPrivateData)] - pub async fn put_private_data( - &self, - data: Vec, - wallet: &JsWallet, - ) -> Result { - let data = crate::Bytes::from(data); - let private_data_access = self.0.data_put(data, (&wallet.0).into()).await?; - let js_value = serde_wasm_bindgen::to_value(&private_data_access)?; - - Ok(js_value) - } - - /// Upload private data to the network. - /// Uses a `Receipt` as payment. - /// - /// Returns the `DataMapChunk` chunk of the data. - #[wasm_bindgen(js_name = putPrivateDataWithReceipt)] - pub async fn put_private_data_with_receipt( - &self, - data: Vec, - receipt: JsValue, - ) -> Result { - let data = crate::Bytes::from(data); - let receipt: Receipt = serde_wasm_bindgen::from_value(receipt)?; - let private_data_access = self.0.data_put(data, receipt.into()).await?; - let js_value = serde_wasm_bindgen::to_value(&private_data_access)?; - - Ok(js_value) - } - - /// Fetch the data from the network. - #[wasm_bindgen(js_name = getData)] - pub async fn get_data(&self, addr: String) -> Result, JsError> { - let addr = str_to_addr(&addr)?; - let data = self.0.data_get_public(addr).await?; - - Ok(data.to_vec()) - } - - /// Fetch the data from the network. - #[wasm_bindgen(js_name = getPrivateData)] - pub async fn get_private_data(&self, private_data_access: JsValue) -> Result, JsError> { - let private_data_access: DataMapChunk = - serde_wasm_bindgen::from_value(private_data_access)?; - let data = self.0.data_get(private_data_access).await?; - - Ok(data.to_vec()) - } - - /// Get the cost of uploading data to the network. - #[wasm_bindgen(js_name = getDataCost)] - pub async fn get_data_cost(&self, data: Vec) -> Result { - let data = crate::Bytes::from(data); - let cost = self.0.data_cost(data).await.map_err(JsError::from)?; - - Ok(AttoTokens(cost)) - } -} - -mod archive { - use super::*; - use crate::client::{ - address::str_to_addr, files::archive::Metadata, files::archive_public::PublicArchive, - }; - use std::path::PathBuf; - use wasm_bindgen::JsError; - - /// Structure mapping paths to data addresses. - #[wasm_bindgen(js_name = Archive)] - pub struct JsArchive(PublicArchive); - - /// Create new metadata with the current time as uploaded, created and modified. - /// - /// # Example - /// - /// ```js - /// const metadata = createMetadata(BigInt(3)); - /// const archive = new atnm.Archive(); - /// archive.addFile("foo", addr, metadata); - /// ``` - #[wasm_bindgen(js_name = createMetadata)] - pub fn create_metadata(size: u64) -> Result { - let metadata = Metadata::new_with_size(size); - Ok(serde_wasm_bindgen::to_value(&metadata)?) - } - - #[wasm_bindgen(js_class = Archive)] - impl JsArchive { - /// Create a new archive. - #[wasm_bindgen(constructor)] - pub fn new() -> Self { - Self(PublicArchive::new()) - } - - /// Add a new file to the archive. - #[wasm_bindgen(js_name = addFile)] - pub fn add_file( - &mut self, - path: String, - data_addr: String, - metadata: JsValue, - ) -> Result<(), JsError> { - let path = PathBuf::from(path); - let data_addr = str_to_addr(&data_addr)?; - let metadata: Metadata = serde_wasm_bindgen::from_value(metadata)?; - self.0.add_file(path, data_addr, metadata); - - Ok(()) - } - - #[wasm_bindgen(js_name = renameFile)] - pub fn rename_file(&mut self, old_path: String, new_path: String) -> Result<(), JsError> { - let old_path = PathBuf::from(old_path); - let new_path = PathBuf::from(new_path); - self.0.rename_file(&old_path, &new_path)?; - - Ok(()) - } - - #[wasm_bindgen] - pub fn map(&self) -> Result { - let files = serde_wasm_bindgen::to_value(self.0.map())?; - Ok(files) - } - - /// Serialize to bytes. - #[wasm_bindgen(js_name = bytes)] - pub fn into_bytes(&self) -> Result, JsError> { - let root_serialized = rmp_serde::to_vec(&self.0)?; - Ok(root_serialized) - } - } - - #[wasm_bindgen(js_class = Client)] - impl JsClient { - /// Fetch an archive from the network. - #[wasm_bindgen(js_name = getArchive)] - pub async fn get_archive(&self, addr: String) -> Result { - let addr = str_to_addr(&addr)?; - let archive = self.0.archive_get_public(addr).await?; - let archive = JsArchive(archive); - - Ok(archive) - } - - /// Upload an archive to the network. - /// - /// Returns the hex encoded address of the archive. - #[wasm_bindgen(js_name = putArchive)] - pub async fn put_archive( - &self, - archive: &JsArchive, - wallet: &JsWallet, - ) -> Result { - let addr = self.0.archive_put_public(&archive.0, &wallet.0).await?; - - Ok(addr_to_str(addr)) - } - } -} - -mod archive_private { - use super::*; - use crate::client::data::DataMapChunk; - use crate::client::files::archive::{Metadata, PrivateArchive, PrivateArchiveAccess}; - use crate::client::payment::Receipt; - use std::path::PathBuf; - use wasm_bindgen::{JsError, JsValue}; - - /// Structure mapping paths to data addresses. - #[wasm_bindgen(js_name = PrivateArchive)] - pub struct JsPrivateArchive(PrivateArchive); - - #[wasm_bindgen(js_class = PrivateArchive)] - impl JsPrivateArchive { - /// Create a new private archive. - #[wasm_bindgen(constructor)] - pub fn new() -> Self { - Self(PrivateArchive::new()) - } - - /// Add a new file to the private archive. - #[wasm_bindgen(js_name = addFile)] - pub fn add_file( - &mut self, - path: String, - data_map: JsValue, - metadata: JsValue, - ) -> Result<(), JsError> { - let path = PathBuf::from(path); - let data_map: DataMapChunk = serde_wasm_bindgen::from_value(data_map)?; - let metadata: Metadata = serde_wasm_bindgen::from_value(metadata)?; - self.0.add_file(path, data_map, metadata); - - Ok(()) - } - - #[wasm_bindgen] - pub fn map(&self) -> Result { - let files = serde_wasm_bindgen::to_value(self.0.map())?; - Ok(files) - } - - /// Serialize to bytes. - #[wasm_bindgen(js_name = bytes)] - pub fn into_bytes(&self) -> Result, JsError> { - let root_serialized = rmp_serde::to_vec(&self.0)?; - Ok(root_serialized) - } - } - - #[wasm_bindgen(js_class = Client)] - impl JsClient { - /// Fetch a private archive from the network. - #[wasm_bindgen(js_name = getPrivateArchive)] - pub async fn get_private_archive( - &self, - private_archive_access: JsValue, - ) -> Result { - let private_archive_access: PrivateArchiveAccess = - serde_wasm_bindgen::from_value(private_archive_access)?; - let archive = self.0.archive_get(private_archive_access).await?; - let archive = JsPrivateArchive(archive); - - Ok(archive) - } - - /// Upload a private archive to the network. - /// - /// Returns the `PrivateArchiveAccess` chunk of the archive. - #[wasm_bindgen(js_name = putPrivateArchive)] - pub async fn put_private_archive( - &self, - archive: &JsPrivateArchive, - wallet: &JsWallet, - ) -> Result { - let private_archive_access = self.0.archive_put(&archive.0, (&wallet.0).into()).await?; - - let js_value = serde_wasm_bindgen::to_value(&private_archive_access)?; - - Ok(js_value) - } - - /// Upload a private archive to the network. - /// Uses a `Receipt` as payment. - /// - /// Returns the `PrivateArchiveAccess` chunk of the archive. - #[wasm_bindgen(js_name = putPrivateArchiveWithReceipt)] - pub async fn put_private_archive_with_receipt( - &self, - archive: &JsPrivateArchive, - receipt: JsValue, - ) -> Result { - let receipt: Receipt = serde_wasm_bindgen::from_value(receipt)?; - - let private_archive_access = self.0.archive_put(&archive.0, receipt.into()).await?; - - let js_value = serde_wasm_bindgen::to_value(&private_archive_access)?; - - Ok(js_value) - } - } -} - -#[cfg(feature = "vault")] -mod vault { - use super::*; - use crate::client::address::addr_to_str; - use crate::client::files::archive::PrivateArchiveAccess; - use crate::client::payment::Receipt; - use crate::client::vault::key::blst_to_blsttc; - use crate::client::vault::key::derive_secret_key_from_seed; - use crate::client::vault::user_data::USER_DATA_VAULT_CONTENT_IDENTIFIER; - use crate::client::vault::VaultContentType; - use ant_protocol::storage::Scratchpad; - use wasm_bindgen::{JsError, JsValue}; - - /// Structure to keep track of uploaded archives, registers and other data. - #[wasm_bindgen(js_name = UserData)] - pub struct JsUserData(UserData); - - #[wasm_bindgen(js_class = UserData)] - impl JsUserData { - /// Create a new user data structure. - #[wasm_bindgen(constructor)] - pub fn new() -> Self { - Self(UserData::new()) - } - - /// Store an archive address in the user data with an optional name. - /// - /// # Example - /// - /// ```js - /// userData.addFileArchive(archiveAddr, "foo"); - /// ``` - #[wasm_bindgen(js_name = addFileArchive)] - pub fn add_file_archive( - &mut self, - archive: String, - name: Option, - ) -> Result<(), JsError> { - let archive = str_to_addr(&archive)?; - - let old_name = if let Some(ref name) = name { - self.0.add_file_archive_with_name(archive, name.clone()) - } else { - self.0.add_file_archive(archive) - }; - - if let Some(old_name) = old_name { - tracing::warn!( - "Changing name of archive `{archive}` from `{old_name:?}` to `{name:?}`" - ); - } - - Ok(()) - } - - /// Store a private archive data map in the user data with an optional name. - /// - /// # Example - /// - /// ```js - /// userData.addPrivateFileArchive(privateArchiveAccess, "foo"); - /// ``` - #[wasm_bindgen(js_name = addPrivateFileArchive)] - pub fn add_private_file_archive( - &mut self, - private_archive_access: JsValue, - name: Option, - ) -> Result<(), JsError> { - let private_archive_access: PrivateArchiveAccess = - serde_wasm_bindgen::from_value(private_archive_access)?; - - let old_name = if let Some(ref name) = name { - self.0 - .add_private_file_archive_with_name(private_archive_access, name.clone()) - } else { - self.0.add_private_file_archive(private_archive_access) - }; - - if let Some(old_name) = old_name { - tracing::warn!( - "Changing name of private archive from `{old_name:?}` to `{name:?}`" - ); - } - - Ok(()) - } - - #[wasm_bindgen(js_name = removeFileArchive)] - pub fn remove_file_archive(&mut self, archive: String) -> Result<(), JsError> { - let archive = str_to_addr(&archive)?; - self.0.remove_file_archive(archive); - - Ok(()) - } - - #[wasm_bindgen(js_name = removePrivateFileArchive)] - pub fn remove_private_file_archive( - &mut self, - private_archive_access: JsValue, - ) -> Result<(), JsError> { - let private_archive_access: PrivateArchiveAccess = - serde_wasm_bindgen::from_value(private_archive_access)?; - - self.0.remove_private_file_archive(private_archive_access); - - Ok(()) - } - - #[wasm_bindgen(js_name = fileArchives)] - pub fn file_archives(&self) -> Result { - let archives = serde_wasm_bindgen::to_value(&self.0.file_archives)?; - Ok(archives) - } - - #[wasm_bindgen(js_name = privateFileArchives)] - pub fn private_file_archives(&self) -> Result { - let archives = serde_wasm_bindgen::to_value(&self.0.private_file_archives)?; - Ok(archives) - } - } - - #[wasm_bindgen(js_name = Scratchpad)] - pub struct JsScratchpad(Scratchpad); - - #[wasm_bindgen(js_class = Scratchpad)] - impl JsScratchpad { - /// Returns a VEC with the XOR name. - #[wasm_bindgen(js_name = xorName)] - pub fn xor_name(&self) -> Option { - self.0 - .network_address() - .as_xorname() - .map(|xor_name| addr_to_str(xor_name)) - } - } - - #[wasm_bindgen(js_class = Client)] - impl JsClient { - /// Fetch the user data from the vault. - /// - /// # Example - /// - /// ```js - /// const secretKey = genSecretKey(); - /// const userData = await client.getUserDataFromVault(secretKey); - /// ``` - #[wasm_bindgen(js_name = getUserDataFromVault)] - pub async fn get_user_data_from_vault( - &self, - secret_key: &SecretKeyJs, - ) -> Result { - let user_data = self.0.get_user_data_from_vault(&secret_key.0).await?; - - Ok(JsUserData(user_data)) - } - - /// Put the user data to the vault. - /// - /// # Example - /// - /// ```js - /// const secretKey = genSecretKey(); - /// await client.putUserDataToVault(userData, wallet, secretKey); - /// ``` - #[wasm_bindgen(js_name = putUserDataToVault)] - pub async fn put_user_data_to_vault( - &self, - user_data: &JsUserData, - wallet: &JsWallet, - secret_key: &SecretKeyJs, - ) -> Result<(), JsError> { - self.0 - .put_user_data_to_vault(&secret_key.0, (&wallet.0).into(), user_data.0.clone()) - .await?; - - Ok(()) - } - - /// Put the user data to the vault. - /// - /// # Example - /// - /// ```js - /// const secretKey = genSecretKey(); - /// await client.putUserDataToVaultWithReceipt(userData, receipt, secretKey); - /// ``` - #[wasm_bindgen(js_name = putUserDataToVaultWithReceipt)] - pub async fn put_user_data_to_vault_with_receipt( - &self, - user_data: &JsUserData, - receipt: JsValue, - secret_key: &SecretKeyJs, - ) -> Result<(), JsError> { - let receipt: Receipt = serde_wasm_bindgen::from_value(receipt)?; - - self.0 - .put_user_data_to_vault(&secret_key.0, receipt.into(), user_data.0.clone()) - .await?; - - Ok(()) - } - - /// Returns an existing scratchpad or creates a new one if it does not exist. - #[wasm_bindgen(js_name = getOrCreateScratchpad)] - pub async fn get_or_create_scratchpad( - &self, - secret_key: &SecretKeyJs, - vault_content_type: JsValue, - ) -> Result { - let vault_content_type: VaultContentType = - serde_wasm_bindgen::from_value(vault_content_type)?; - - let result = self - .0 - .get_or_create_scratchpad(&secret_key.0, vault_content_type) - .await?; - - let js_value = serde_wasm_bindgen::to_value(&result)?; - - Ok(js_value) - } - - /// Returns an existing user data scratchpad or creates a new one if it does not exist. - #[wasm_bindgen(js_name = getOrCreateUserDataScratchpad)] - pub async fn get_or_create_user_data_scratchpad( - &self, - secret_key: &SecretKeyJs, - ) -> Result { - let vault_content_type = *USER_DATA_VAULT_CONTENT_IDENTIFIER; - - let (scratchpad, _is_new) = self - .0 - .get_or_create_scratchpad(&secret_key.0, vault_content_type) - .await?; - - let js_scratchpad = JsScratchpad(scratchpad); - - Ok(js_scratchpad) - } - } - - #[wasm_bindgen(js_name = vaultKeyFromSignature)] - pub fn vault_key_from_signature(signature: Vec) -> Result { - let blst_key = derive_secret_key_from_seed(&signature)?; - let vault_sk = blst_to_blsttc(&blst_key)?; - Ok(SecretKeyJs(vault_sk)) - } -} - -#[cfg(feature = "external-signer")] -mod external_signer { - use super::*; - use crate::client::address::str_to_addr; - use crate::client::external_signer::encrypt_data; - use crate::client::payment::Receipt; - use crate::receipt_from_quotes_and_payments; - use ant_evm::external_signer::{approve_to_spend_tokens_calldata, pay_for_quotes_calldata}; - use ant_evm::EvmNetwork; - use ant_evm::QuotePayment; - use ant_evm::{Amount, PaymentQuote}; - use ant_evm::{EvmAddress, QuoteHash, TxHash}; - use std::collections::{BTreeMap, HashMap}; - use wasm_bindgen::prelude::wasm_bindgen; - use wasm_bindgen::{JsError, JsValue}; - use xor_name::XorName; - - #[wasm_bindgen(js_class = Client)] - impl JsClient { - /// Get quotes for given chunk addresses. - /// - /// # Example - /// - /// ```js - /// const [quotes, quotePayments, free_chunks] = await client.getQuotes(chunkAddresses); - /// `` - #[wasm_bindgen(js_name = getQuotes)] - pub async fn get_quotes(&self, chunk_addresses: Vec) -> Result { - let mut xor_addresses: Vec = vec![]; - - for chunk_address_str in &chunk_addresses { - let xor_address = str_to_addr(chunk_address_str)?; - xor_addresses.push(xor_address); - } - - let result = self - .0 - .get_quotes_for_content_addresses(xor_addresses.into_iter()) - .await?; - - let js_value = serde_wasm_bindgen::to_value(&result)?; - - Ok(js_value) - } - - /// Upload data with a receipt. - /// - /// # Example - /// - /// ```js - /// const receipt = getReceiptFromQuotesAndPayments(quotes, payments); - /// const addr = await client.putDataWithReceipt(data, receipt); - /// ``` - #[wasm_bindgen(js_name = putDataWithReceipt)] - pub async fn put_data_with_receipt( - &self, - data: Vec, - receipt: JsValue, - ) -> Result { - let data = crate::Bytes::from(data); - let receipt: Receipt = serde_wasm_bindgen::from_value(receipt)?; - let xorname = self.0.data_put_public(data, receipt.into()).await?; - Ok(addr_to_str(xorname)) - } - } - - /// Encrypt data. - /// - /// # Example - /// - /// ```js - /// const [dataMapChunk, dataChunks, dataMapChunkAddress, dataChunkAddresses] = client.encryptData(data); - /// `` - #[wasm_bindgen(js_name = encryptData)] - pub fn encrypt(data: Vec) -> Result { - let data = crate::Bytes::from(data); - let result = encrypt_data(data)?; - let map_xor_name = *result.0.address().xorname(); - let mut xor_names = vec![]; - - for chunk in &result.1 { - xor_names.push(*chunk.name()); - } - - let result = (result.0, result.1, map_xor_name, xor_names); - let js_value = serde_wasm_bindgen::to_value(&result)?; - - Ok(js_value) - } - - /// Get the calldata for paying for quotes. - /// - /// # Example - /// - /// ```js - /// const [quotes, quotePayments, free_chunks] = await client.getQuotes(data); - /// const callData = getPayForQuotesCalldata(evmNetwork, quotePayments); - /// ``` - #[wasm_bindgen(js_name = getPayForQuotesCalldata)] - pub fn get_pay_for_quotes_calldata( - network: JsValue, - payments: JsValue, - ) -> Result { - let network: EvmNetwork = serde_wasm_bindgen::from_value(network)?; - let payments: Vec = serde_wasm_bindgen::from_value(payments)?; - let calldata = pay_for_quotes_calldata(&network, payments.into_iter())?; - let js_value = serde_wasm_bindgen::to_value(&calldata)?; - Ok(js_value) - } - - /// Form approve to spend tokens calldata. - #[wasm_bindgen(js_name = getApproveToSpendTokensCalldata)] - pub fn get_approve_to_spend_tokens_calldata( - network: JsValue, - spender: JsValue, - amount: JsValue, - ) -> Result { - let network: EvmNetwork = serde_wasm_bindgen::from_value(network)?; - let spender: EvmAddress = serde_wasm_bindgen::from_value(spender)?; - let amount: Amount = serde_wasm_bindgen::from_value(amount)?; - let calldata = approve_to_spend_tokens_calldata(&network, spender, amount); - let js_value = serde_wasm_bindgen::to_value(&calldata)?; - Ok(js_value) - } - - /// Generate payment proof. - #[wasm_bindgen(js_name = getReceiptFromQuotesAndPayments)] - pub fn get_receipt_from_quotes_and_payments( - quotes: JsValue, - payments: JsValue, - ) -> Result { - let quotes: HashMap = serde_wasm_bindgen::from_value(quotes)?; - let payments: BTreeMap = serde_wasm_bindgen::from_value(payments)?; - let receipt = receipt_from_quotes_and_payments("es, &payments); - let js_value = serde_wasm_bindgen::to_value(&receipt)?; - Ok(js_value) - } -} - -#[wasm_bindgen(js_name = SecretKey)] -pub struct SecretKeyJs(bls::SecretKey); - -/// # Example -/// -/// ```js -/// const secretKey = genSecretKey(); -/// await client.putUserDataToVault(userData, wallet, secretKey); -/// const userDataFetched = await client.getUserDataFromVault(secretKey); -/// ``` -#[wasm_bindgen(js_name = genSecretKey)] -pub fn gen_secret_key() -> SecretKeyJs { - let secret_key = bls::SecretKey::random(); - SecretKeyJs(secret_key) -} - -/// Get the current `EvmNetwork` that was set using environment variables that were used during the build process of this library. -#[wasm_bindgen(js_name = getEvmNetwork)] -pub fn evm_network() -> Result { - let evm_network = evmlib::utils::get_evm_network_from_env()?; - let js_value = serde_wasm_bindgen::to_value(&evm_network)?; - Ok(js_value) -} - -/// Create an `EvmNetwork` with custom values. -/// -/// # Example -/// -/// ```js -/// const [quotes, quotePayments, free_chunks] = await client.getQuotes(data); -/// const evmNetwork = getEvmNetworkCustom("http://localhost:4343", "", ""); -/// const payForQuotesCalldata = getPayForQuotesCalldata(evmNetwork, quotePayments); -/// ``` -#[wasm_bindgen(js_name = getEvmNetworkCustom)] -pub fn evm_network_custom( - rpc_url: String, - payment_token_address: String, - data_payments_address: String, -) -> Result { - let evm_network = - evmlib::utils::get_evm_network(&rpc_url, &payment_token_address, &data_payments_address); - let js_value = serde_wasm_bindgen::to_value(&evm_network)?; - Ok(js_value) -} - -#[wasm_bindgen(js_name = Wallet)] -pub struct JsWallet(evmlib::wallet::Wallet); - -/// Get a funded wallet for testing. This either uses a default private key or the `EVM_PRIVATE_KEY` -/// environment variable that was used during the build process of this library. -#[wasm_bindgen(js_name = getFundedWallet)] -pub fn funded_wallet() -> JsWallet { - let network = evmlib::utils::get_evm_network_from_env() - .expect("Failed to get EVM network from environment variables"); - if matches!(network, evmlib::Network::ArbitrumOne) { - panic!("You're trying to use ArbitrumOne network. Use a custom network for testing."); - } - // Default deployer wallet of the testnet. - const DEFAULT_WALLET_PRIVATE_KEY: &str = - "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; - - let private_key = std::env::var("SECRET_KEY").unwrap_or(DEFAULT_WALLET_PRIVATE_KEY.to_string()); - - let wallet = evmlib::wallet::Wallet::new_from_private_key(network, &private_key) - .expect("Invalid private key"); - - JsWallet(wallet) -} - -/// Get a funded wallet with a custom network. -#[wasm_bindgen(js_name = getFundedWalletWithCustomNetwork)] -pub fn funded_wallet_with_custom_network( - network: JsValue, - private_key: String, -) -> Result { - let network: evmlib::Network = serde_wasm_bindgen::from_value(network)?; - let wallet = evmlib::wallet::Wallet::new_from_private_key(network, &private_key)?; - Ok(JsWallet(wallet)) -} - -/// Enable tracing logging in the console. -/// -/// A level could be passed like `trace` or `warn`. Or set for a specific module/crate -/// with `ant-networking=trace,autonomi=info`. -/// -/// # Example -/// -/// ```js -/// logInit("ant-networking=warn,autonomi=trace"); -/// ``` -#[wasm_bindgen(js_name = logInit)] -pub fn log_init(directive: String) { - use tracing_subscriber::prelude::*; - - console_error_panic_hook::set_once(); - - let fmt_layer = tracing_subscriber::fmt::layer() - .with_ansi(false) // Only partially supported across browsers - .without_time() // std::time is not available in browsers - .with_writer(tracing_web::MakeWebConsoleWriter::new()); // write events to the console - tracing_subscriber::registry() - .with(fmt_layer) - .with(tracing_subscriber::EnvFilter::new(directive)) - .init(); -} diff --git a/autonomi/tests/wasm.rs b/autonomi/tests/wasm.rs deleted file mode 100644 index d0531c0999..0000000000 --- a/autonomi/tests/wasm.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2024 MaidSafe.net limited. -// -// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3. -// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed -// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. Please review the Licences for the specific language governing -// permissions and limitations relating to use of the SAFE Network Software. - -#![cfg(target_arch = "wasm32")] - -use std::time::Duration; - -use ant_networking::target_arch::sleep; -use autonomi::Client; -use test_utils::{evm::get_funded_wallet, gen_random_data}; -use wasm_bindgen_test::*; - -wasm_bindgen_test_configure!(run_in_browser); - -#[wasm_bindgen_test] -async fn put() -> Result<(), Box> { - enable_logging_wasm("ant-networking,autonomi,wasm"); - - let client = Client::init_local().await?; - let wallet = get_funded_wallet(); - let data = gen_random_data(1024 * 1024 * 10); - - let addr = client.data_put_public(data.clone(), wallet.into()).await?; - - sleep(Duration::from_secs(10)).await; - - let data_fetched = client.data_get_public(addr).await?; - assert_eq!(data, data_fetched, "data fetched should match data put"); - - Ok(()) -} - -fn enable_logging_wasm(directive: impl AsRef) { - use tracing_subscriber::prelude::*; - - console_error_panic_hook::set_once(); - - let fmt_layer = tracing_subscriber::fmt::layer() - .with_ansi(false) // Only partially supported across browsers - .without_time() // std::time is not available in browsers - .with_writer(tracing_web::MakeWebConsoleWriter::new()); // write events to the console - tracing_subscriber::registry() - .with(fmt_layer) - .with(tracing_subscriber::EnvFilter::new(directive)) - .init(); -} diff --git a/evmlib/Cargo.toml b/evmlib/Cargo.toml index a6b390814c..7c7ee7dbd4 100644 --- a/evmlib/Cargo.toml +++ b/evmlib/Cargo.toml @@ -9,7 +9,6 @@ repository = "https://github.com/maidsafe/safe_network" version = "0.1.6" [features] -wasm-bindgen = ["alloy/wasm-bindgen"] local = [] external-signer = [] @@ -23,8 +22,5 @@ tracing = { version = "~0.1.26" } tokio = "1.38.0" rand = "0.8.5" -[target.'cfg(target_arch = "wasm32")'.dependencies] -getrandom = { version = "0.2.12", features = ["js"] } - [lints] workspace = true From 6d57f276b731dce9ed4a13f477524ac1bcd7f5a2 Mon Sep 17 00:00:00 2001 From: grumbach Date: Thu, 2 Jan 2025 21:37:39 +0900 Subject: [PATCH 2/3] fix: remove encrypt-records dead flag from ci tests --- .github/workflows/merge.yml | 12 ++++++------ .github/workflows/nightly.yml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index cee96c0f9d..bc5d0d26e7 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -148,19 +148,19 @@ jobs: # This is most likely due to the setup and cocurrency issues of the tests. # As the `record_store` is used in a single thread style, get the test passing executed # and passing standalone is enough. - - name: Run network tests (with encrypt-records) + - name: Run network tests timeout-minutes: 25 - run: cargo test --release --package ant-networking --features="open-metrics, encrypt-records" -- --skip can_store_after_restart + run: cargo test --release --package ant-networking --features="open-metrics" -- --skip can_store_after_restart - - name: Run network tests (with encrypt-records) + - name: Run network tests timeout-minutes: 5 - run: cargo test --release --package ant-networking --features="open-metrics, encrypt-records" can_store_after_restart + run: cargo test --release --package ant-networking --features="open-metrics" can_store_after_restart - - name: Run network tests (without encrypt-records) + - name: Run network tests timeout-minutes: 25 run: cargo test --release --package ant-networking --features="open-metrics" -- --skip can_store_after_restart - - name: Run network tests (without encrypt-records) + - name: Run network tests timeout-minutes: 5 run: cargo test --release --package ant-networking --features="open-metrics" can_store_after_restart diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 8b4cc22cce..5c9553034d 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -262,7 +262,7 @@ jobs: - name: Run network tests timeout-minutes: 25 - run: cargo test --release --package ant-networking --features="open-metrics, encrypt-records" + run: cargo test --release --package ant-networking --features="open-metrics" - name: Run protocol tests timeout-minutes: 25 From 63ccf069e80e6c60b014bf697c6a0d2709e74cee Mon Sep 17 00:00:00 2001 From: grumbach Date: Fri, 3 Jan 2025 00:27:55 +0900 Subject: [PATCH 3/3] fix: wrong vault address paid for in vault payments --- ant-evm/src/data_payments.rs | 8 ++++++-- ant-protocol/src/storage/scratchpad.rs | 12 ++---------- autonomi/src/client/vault.rs | 2 +- autonomi/tests/external_signer.rs | 2 +- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/ant-evm/src/data_payments.rs b/ant-evm/src/data_payments.rs index e1486384bb..cc43f9598c 100644 --- a/ant-evm/src/data_payments.rs +++ b/ant-evm/src/data_payments.rs @@ -89,6 +89,9 @@ impl ProofOfPayment { pub fn verify_for(&self, peer_id: PeerId) -> bool { // make sure I am in the list of payees if !self.payees().contains(&peer_id) { + warn!("Payment does not contain node peer id"); + debug!("Payment contains peer ids: {:?}", self.payees()); + debug!("Node peer id: {:?}", peer_id); return false; } @@ -102,6 +105,7 @@ impl ProofOfPayment { } }; if !quote.check_is_signed_by_claimed_peer(peer_id) { + warn!("Payment is not signed by claimed peer"); return false; } } @@ -186,7 +190,7 @@ impl PaymentQuote { if let Ok(pub_key) = libp2p::identity::PublicKey::try_decode_protobuf(&self.pub_key) { Ok(PeerId::from(pub_key.clone())) } else { - error!("Cann't parse PublicKey from protobuf"); + error!("Can't parse PublicKey from protobuf"); Err(EvmError::InvalidQuotePublicKey) } } @@ -196,7 +200,7 @@ impl PaymentQuote { let pub_key = if let Ok(pub_key) = PublicKey::try_decode_protobuf(&self.pub_key) { pub_key } else { - error!("Cann't parse PublicKey from protobuf"); + error!("Can't parse PublicKey from protobuf"); return false; }; diff --git a/ant-protocol/src/storage/scratchpad.rs b/ant-protocol/src/storage/scratchpad.rs index 7a6416845e..9c40b4dbc5 100644 --- a/ant-protocol/src/storage/scratchpad.rs +++ b/ant-protocol/src/storage/scratchpad.rs @@ -131,16 +131,8 @@ impl Scratchpad { NetworkAddress::ScratchpadAddress(self.address) } - /// Returns a VEC with the XOR name. - pub fn to_xor_name_vec(&self) -> Vec { - [self.network_address()] - .iter() - .map(|f| XorName::from_content(f.as_bytes().as_ref())) - .collect::>() - } - - /// Returns the name. - pub fn name(&self) -> XorName { + /// Returns the xorname. + pub fn xorname(&self) -> XorName { self.address.xorname() } diff --git a/autonomi/src/client/vault.rs b/autonomi/src/client/vault.rs index f53875010f..462e2a4cb0 100644 --- a/autonomi/src/client/vault.rs +++ b/autonomi/src/client/vault.rs @@ -193,7 +193,7 @@ impl Client { let record = if is_new { let receipt = self - .pay_for_content_addrs(scratch.to_xor_name_vec().into_iter(), payment_option) + .pay_for_content_addrs(std::iter::once(scratch.xorname()), payment_option) .await .inspect_err(|err| { error!("Failed to pay for new vault at addr: {scratch_address:?} : {err}"); diff --git a/autonomi/tests/external_signer.rs b/autonomi/tests/external_signer.rs index 755a1cac8f..6430132d5d 100644 --- a/autonomi/tests/external_signer.rs +++ b/autonomi/tests/external_signer.rs @@ -147,7 +147,7 @@ async fn external_signer_put() -> eyre::Result<()> { assert!(is_new, "Scratchpad is not new"); let scratch_addresses = if is_new { - scratch.to_xor_name_vec() + vec![scratch.xorname()] } else { vec![] };