From 243ce2395b63c45b7a3c5fe5dd7e117a42de41b2 Mon Sep 17 00:00:00 2001 From: xgreenx Date: Fri, 31 May 2024 21:16:27 +0200 Subject: [PATCH] - Use latest `fuel-core 0.27.0` and Rust SDK 0.63.0 - Removed caching of the coins from Rust SDK because it breaks the faucet if transaction is lost in the network. - Send dust coins to the user who claimed coins. --- Cargo.lock | 160 +++++++++++++++++++++++++++------------------- Cargo.toml | 20 +++--- src/config.rs | 13 ++-- src/constants.rs | 2 + src/lib.rs | 2 +- src/routes.rs | 54 ++++++++++------ tests/dispense.rs | 77 ++++++++++++---------- 7 files changed, 193 insertions(+), 135 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dfc117e..9971fa8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -808,6 +808,7 @@ dependencies = [ "encode_unicode", "lazy_static", "libc", + "unicode-width", "windows-sys 0.45.0", ] @@ -1557,9 +1558,9 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "fuel-abi-types" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2351bb0b743c23ac13ac2559756b3929502cd6e29091f2e5302fb9a1bdddaf35" +checksum = "e0e7e87f94417ff1a5d60e496906033c58bfe5367546621f131fe8cdabaa2671" dependencies = [ "itertools 0.10.5", "lazy_static", @@ -1574,9 +1575,9 @@ dependencies = [ [[package]] name = "fuel-asm" -version = "0.48.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20bc683784e35f3421aab3dc5a31a94c8ad80f1e9ec614ddddac930b4081cd92" +checksum = "db81c0bdf07b052d1c595b5ee71e20f0286ca3dc88c7ab3f775e08c8e055c34f" dependencies = [ "bitflags 2.4.1", "fuel-types", @@ -1586,9 +1587,9 @@ dependencies = [ [[package]] name = "fuel-core" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16acbaac42aceb26c704ed078314e7e7f9d1e20d6eaf147cada559e7e9f967ae" +checksum = "5ecef9aa6c04239c408e37613eb542f81cabb3a10a619b9c793312d38eed9e34" dependencies = [ "anyhow", "async-graphql", @@ -1614,6 +1615,7 @@ dependencies = [ "futures", "hex", "hyper", + "indicatif", "itertools 0.12.0", "rand", "serde", @@ -1622,7 +1624,6 @@ dependencies = [ "strum_macros 0.25.3", "thiserror", "tokio", - "tokio-rayon", "tokio-stream", "tokio-util", "tower-http 0.3.5", @@ -1632,12 +1633,13 @@ dependencies = [ [[package]] name = "fuel-core-chain-config" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23929afd8e279a463941ed18c8a23d9e29df4c3587ba19ad56c68f24c14484f5" +checksum = "16323762c4a5d58b11121580bee9f3a76ac7f655f95d727f957b05a9e35f477f" dependencies = [ "anyhow", "bech32", + "derivative", "fuel-core-storage", "fuel-core-types", "itertools 0.12.0", @@ -1651,9 +1653,9 @@ dependencies = [ [[package]] name = "fuel-core-client" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67d4a6c96cd1827d04361f8b76416273168efc9eb0951293b03bc18e52d409b6" +checksum = "f33af785942254f23e30a03a08a08ffb8eea645a87f06895e5d84f4205fc191a" dependencies = [ "anyhow", "cynic", @@ -1675,9 +1677,9 @@ dependencies = [ [[package]] name = "fuel-core-consensus-module" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b1d8ec2205453a563f9ac620867febb711c4ec7a930f063899f8c8673921417" +checksum = "85320bb1990ea54ad9fcda4c527c2e42651103c2332cb7ff0b51ecaa23b4c07a" dependencies = [ "anyhow", "fuel-core-chain-config", @@ -1688,9 +1690,9 @@ dependencies = [ [[package]] name = "fuel-core-database" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a87cc2351d5a3205d4a6673904bb3b876203540595e1746a1f466d5900b3c3e" +checksum = "d540b36b409d36ace39902509d55d0c758f9cfebc1bcbea07d7115b9923196c9" dependencies = [ "anyhow", "derive_more", @@ -1700,12 +1702,11 @@ dependencies = [ [[package]] name = "fuel-core-executor" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e159969d168d4b7cbaa9a55efb842604f0abe116d1baa0b0486c73f2261f63a" +checksum = "367ef0966c99cf1104035257023596256d61a3a5b58b8bac4dcb0bdc8e9b2459" dependencies = [ "anyhow", - "fuel-core-chain-config", "fuel-core-storage", "fuel-core-types", "hex", @@ -1716,13 +1717,12 @@ dependencies = [ [[package]] name = "fuel-core-importer" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b858caa4d262891964f55c09f86d6f93d368f7d9a073e5828e02616db88e014" +checksum = "4c7c89083930099a8dad11f5602d4bd935ff5db546ba600cbb9325f6b3bd78ac" dependencies = [ "anyhow", "derive_more", - "fuel-core-chain-config", "fuel-core-metrics", "fuel-core-storage", "fuel-core-types", @@ -1733,9 +1733,9 @@ dependencies = [ [[package]] name = "fuel-core-metrics" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003381d1f9f5def3685171b340c4bb56d3681897f3baa616aaf6cf7085013462" +checksum = "2a47f442a32f2e5917066bbf9be3d6fd5d85252a131f1b5fc2f2f0ee75008066" dependencies = [ "axum", "once_cell", @@ -1747,9 +1747,9 @@ dependencies = [ [[package]] name = "fuel-core-p2p" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c513afe591125230e3fd9f6cdf1add00a2aba3f11a19e9e77e020ec14b863b6e" +checksum = "5cc6a321f2b1df5be84444ee8b12b647313a5b92a2589d06489bb2b00dbdb2e1" dependencies = [ "anyhow", "async-trait", @@ -1779,9 +1779,9 @@ dependencies = [ [[package]] name = "fuel-core-poa" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8608758b49855f33c3e6a78917dada96265233096aae04628d6c1ff9fe6d3dca" +checksum = "1f6185f492f9ddb65228db0f250b3f6384637ebf76b72fc81b2efb629d887912" dependencies = [ "anyhow", "async-trait", @@ -1796,9 +1796,9 @@ dependencies = [ [[package]] name = "fuel-core-producer" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c662d29fafeeb686057f3ba1f2cd349e3c437c32d59ae4f6c61400cee26f27e7" +checksum = "efad4ce5bc2f4542e3838a4256158fdd7c537d73e359ba589a4ea86e5c8a2ee0" dependencies = [ "anyhow", "async-trait", @@ -1812,9 +1812,9 @@ dependencies = [ [[package]] name = "fuel-core-services" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca69ccc3a055e0a645c7e76e0623feec6945d4cf95b4131a3a1bf1ffc076d1bb" +checksum = "d35200489fdcdafbe5a6a3a39baad4da523e5c004db9a885056be0137ee35098" dependencies = [ "anyhow", "async-trait", @@ -1827,9 +1827,9 @@ dependencies = [ [[package]] name = "fuel-core-storage" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb47f4fabcec096b78137c782895a52aeed134f931256656511b10083cbd967" +checksum = "87f4e85b634f42fb53193da517b4a2efa8ac73031cdab653029a5b1d3725572d" dependencies = [ "anyhow", "derive_more", @@ -1851,18 +1851,18 @@ dependencies = [ [[package]] name = "fuel-core-txpool" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e62e3bf2e4ee38e248131293ad908d8ba82b7d02dff432f68bc49b252eda509" +checksum = "800ab382b81de3fa62858862acb25410fdba514fae9b3862065524ac25244678" dependencies = [ "anyhow", "async-trait", - "fuel-core-chain-config", "fuel-core-metrics", "fuel-core-services", "fuel-core-storage", "fuel-core-types", "futures", + "mockall", "parking_lot", "tokio", "tokio-rayon", @@ -1872,9 +1872,9 @@ dependencies = [ [[package]] name = "fuel-core-types" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385b3c9e9d51ca11e129ec1c713ffd2f4f2f2ad89c16b1808a4c661887a88bfb" +checksum = "ffe21004dd036f4c454666e339bd0fc3b037535bbc5510321db2565087edd4fc" dependencies = [ "anyhow", "bs58", @@ -1891,9 +1891,9 @@ dependencies = [ [[package]] name = "fuel-core-upgradable-executor" -version = "0.24.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123e31a87f925f6403cf960e04db1403c4093d0fbacb1a5a8333c2756b980a42" +checksum = "e7136365b6d48f78ea5ce6bbd3c3c79dece5777ec13a9b63ef4f56abeab6017e" dependencies = [ "fuel-core-executor", "fuel-core-storage", @@ -1902,9 +1902,9 @@ dependencies = [ [[package]] name = "fuel-crypto" -version = "0.48.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6112c726b5254cad831e61db36dcd0d83b28c50180ea22cb8815343fb162526" +checksum = "4ca73b3409086e772315625304cabd2eeec10e4bd1f8b8a99cc72e0aed755e5c" dependencies = [ "coins-bip32", "coins-bip39", @@ -1923,9 +1923,9 @@ dependencies = [ [[package]] name = "fuel-derive" -version = "0.48.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5896603b839f04f27e8bddbae2990dc799fb119f5e62973d6666b2ea1a4b036b" +checksum = "d8d6e66d1b68eb916640c12a1c6c40880e11fcf569359b04483d5e18237c5229" dependencies = [ "proc-macro2", "quote", @@ -1967,9 +1967,9 @@ dependencies = [ [[package]] name = "fuel-merkle" -version = "0.48.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8f75d97f6d43fbd15aa5ca0d594b33cc59ba5fd73ce42f4a10dfa9288a9a4a4" +checksum = "faa4b60ddfa51b64d02a1d71b0cf51488171d313b32ae3fb9f39f64ddd21791b" dependencies = [ "derive_more", "digest 0.10.7", @@ -1982,15 +1982,15 @@ dependencies = [ [[package]] name = "fuel-storage" -version = "0.48.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6899452bbf8b09d536b0adf98d6a28d1081ce38c3490fa2d8cc1dd47ba153351" +checksum = "beef5f12c40118e87ef6abf611c6bba5c88754e727fb825120ae7d0872123055" [[package]] name = "fuel-tx" -version = "0.48.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305c12d87f47d139505cbbaee1effa7750ce171c9a4362d212f4f7a651902121" +checksum = "fc95857e761db34a50967f53af7a74be08130d210bd985c5585f36bd753d346c" dependencies = [ "bitflags 2.4.1", "derivative", @@ -2001,6 +2001,7 @@ dependencies = [ "fuel-types", "hashbrown 0.14.3", "itertools 0.10.5", + "postcard", "rand", "serde", "serde_json", @@ -2010,9 +2011,9 @@ dependencies = [ [[package]] name = "fuel-types" -version = "0.48.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d92d34c6625f0c3b88463f01027e836ba561125f6ccfb1402d12743fc7b2c96" +checksum = "0af9f9d8c9eb3f4e644731c829ee7da5c3cae0886864731089627af25e336cea" dependencies = [ "fuel-derive", "hex", @@ -2022,9 +2023,9 @@ dependencies = [ [[package]] name = "fuel-vm" -version = "0.48.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06f02e86ebf357689e34412af34faf7f0d35a9b8b6ccb2ec42fd369559d6914" +checksum = "71df1a9ede5237febbc7864888f26365814327732ccd11002e9bddac1ce9a4e6" dependencies = [ "anyhow", "async-trait", @@ -2056,9 +2057,9 @@ dependencies = [ [[package]] name = "fuels-accounts" -version = "0.59.0" +version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b6dc7ec73fcbc104c87a3da8b4980626259ad3f2e42f7bc6fe41ec5d26b3c0" +checksum = "0e17d23b925d3d5e21dc5428330695c596db356d4adfc90eadecc2a490d7d5ce" dependencies = [ "async-trait", "chrono", @@ -2080,9 +2081,9 @@ dependencies = [ [[package]] name = "fuels-code-gen" -version = "0.59.0" +version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bceeab1b698cc0cb6ef84e37f7df6981180bf4f2ef808c1b0304e3b92d509c5" +checksum = "86a7a5b4811f5563bb5c2485efc7653ed6ce465c452a1182ae9062aa13dd19af" dependencies = [ "Inflector", "fuel-abi-types", @@ -2096,9 +2097,9 @@ dependencies = [ [[package]] name = "fuels-core" -version = "0.59.0" +version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "294e432031c758701ba54bca0c3ed11c19718d4918e800e1c928c0a536194760" +checksum = "9774ae9b35f808fa18b92d0478a3b0acbea41011409efa3117f972dfe528ae09" dependencies = [ "async-trait", "bech32", @@ -2107,6 +2108,7 @@ dependencies = [ "fuel-asm", "fuel-core-chain-config", "fuel-core-client", + "fuel-core-types", "fuel-crypto", "fuel-tx", "fuel-types", @@ -2114,24 +2116,23 @@ dependencies = [ "fuels-macros", "hex", "itertools 0.12.0", + "postcard", "serde", "serde_json", - "sha2 0.10.8", "thiserror", "uint", ] [[package]] name = "fuels-macros" -version = "0.59.0" +version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "223ab0dff7a6b0710eede62d381c61acce15d464e9cf5bd6848d5a9803b6671c" +checksum = "ba92a701fa86eed843db68d991807207b8b3d47099d49fb82467e8900f680e01" dependencies = [ "fuels-code-gen", "itertools 0.12.0", "proc-macro2", "quote", - "rand", "syn 2.0.39", ] @@ -2816,6 +2817,19 @@ dependencies = [ "serde", ] +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + [[package]] name = "inout" version = "0.1.3" @@ -3871,6 +3885,12 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "object" version = "0.32.1" @@ -4125,6 +4145,12 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + [[package]] name = "postcard" version = "1.0.8" @@ -5703,6 +5729,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" + [[package]] name = "unicode-xid" version = "0.2.4" diff --git a/Cargo.toml b/Cargo.toml index 0057f8b..ae249cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,11 +12,11 @@ description = "A token faucet for onboarding fuel users" [dependencies] anyhow = "1.0" axum = "0.5" -fuel-core-client = "0.24.3" -fuel-tx = "0.48.0" -fuel-types = "0.48.0" -fuels-accounts = { version = "0.59.0", features = ["coin-cache"] } -fuels-core = { version = "0.59.0" } +fuel-core-client = "0.27.0" +fuel-tx = "0.50.0" +fuel-types = "0.50.0" +fuels-accounts = { version = "0.63.0" } +fuels-core = { version = "0.63.0" } handlebars = "4.2" lazy_static = "1.4" memoize = "0.3.1" @@ -31,11 +31,11 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] } [dev-dependencies] -fuel-core = { version = "0.24.3", default-features = false, features = ["test-helpers"] } -fuel-core-txpool = "0.24.3" -fuel-crypto = "0.48.0" -fuel-tx = { version = "0.48.0", features = ["test-helpers"] } -fuel-types = { version = "0.48.0", features = ["random"] } +fuel-core = { version = "0.27.0", default-features = false, features = ["test-helpers"] } +fuel-core-txpool = "0.27.0" +fuel-crypto = "0.50.0" +fuel-tx = { version = "0.50.0", features = ["test-helpers"] } +fuel-types = { version = "0.50.0", features = ["random"] } futures = "0.3" insta = "1.14" rand = "0.8" diff --git a/src/config.rs b/src/config.rs index 697f08d..972dd57 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,8 +1,8 @@ use crate::constants::{ CAPTCHA_KEY, CAPTCHA_SECRET, DEFAULT_DISPENSE_INTERVAL, DEFAULT_FAUCET_DISPENSE_AMOUNT, - DEFAULT_NODE_URL, DEFAULT_PORT, DISPENSE_AMOUNT, DISPENSE_INTERVAL, FUEL_NODE_URL, - HUMAN_LOGGING, LOG_FILTER, PUBLIC_FUEL_NODE_URL, SERVICE_PORT, TIMEOUT_SECONDS, - WALLET_SECRET_KEY, + DEFAULT_NODE_URL, DEFAULT_NUMBER_OF_RETRIES, DEFAULT_PORT, DISPENSE_AMOUNT, DISPENSE_INTERVAL, + FUEL_NODE_URL, HUMAN_LOGGING, LOG_FILTER, NUMBER_OF_RETRIES, PUBLIC_FUEL_NODE_URL, + SERVICE_PORT, TIMEOUT_SECONDS, WALLET_SECRET_KEY, }; use secrecy::Secret; use std::env; @@ -18,6 +18,7 @@ pub struct Config { pub public_node_url: String, pub wallet_secret_key: Option>, pub dispense_amount: u64, + pub number_of_retries: u64, pub dispense_limit_interval: u64, pub timeout: u64, } @@ -42,12 +43,16 @@ impl Default for Config { .unwrap_or_else(|_| DEFAULT_FAUCET_DISPENSE_AMOUNT.to_string()) .parse::() .expect("expected a valid integer for DISPENSE_AMOUNT"), + number_of_retries: env::var(NUMBER_OF_RETRIES) + .unwrap_or_else(|_| DEFAULT_NUMBER_OF_RETRIES.to_string()) + .parse::() + .expect("expected a valid integer for NUMBER_OF_RETRIES"), dispense_limit_interval: env::var(DISPENSE_INTERVAL) .unwrap_or_else(|_| DEFAULT_DISPENSE_INTERVAL.to_string()) .parse::() .expect("expected a valid integer for DISPENSE_LIMIT_INTERVAL"), timeout: env::var(TIMEOUT_SECONDS) - .unwrap_or_else(|_| "30".to_string()) + .unwrap_or_else(|_| "10".to_string()) .parse::() .expect("expected a valid integer for TIMEOUT_SECONDS"), } diff --git a/src/constants.rs b/src/constants.rs index db8870e..8a53d93 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -9,9 +9,11 @@ pub const WALLET_SECRET_DEV_KEY: &str = pub const FUEL_NODE_URL: &str = "FUEL_NODE_URL"; pub const DEFAULT_NODE_URL: &str = "http://127.0.0.1:4000"; pub const DISPENSE_AMOUNT: &str = "DISPENSE_AMOUNT"; +pub const NUMBER_OF_RETRIES: &str = "NUMBER_OF_RETRIES"; pub const DISPENSE_INTERVAL: &str = "DISPENSE_LIMIT_INTERVAL"; pub const DEFAULT_DISPENSE_INTERVAL: u64 = 24 * 60 * 60; pub const DEFAULT_FAUCET_DISPENSE_AMOUNT: u64 = 10_000_000; +pub const DEFAULT_NUMBER_OF_RETRIES: u64 = 5; pub const SERVICE_PORT: &str = "PORT"; pub const DEFAULT_PORT: u16 = 3000; diff --git a/src/lib.rs b/src/lib.rs index 5e65fe8..1394df0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,6 @@ mod recaptcha; mod routes; pub use dispense_tracker::{Clock, StdTime}; -pub use routes::THE_BIGGEST_AMOUNT; #[derive(Debug, Copy, Clone)] pub struct CoinOutput { @@ -158,6 +157,7 @@ pub async fn start_server( .layer(TraceLayer::new_for_http()) .layer(Extension(Arc::new(wallet))) .layer(Extension(Arc::new(client))) + .layer(Extension(Arc::new(node_info.clone()))) .layer(Extension(Arc::new(tokio::sync::Mutex::new( FaucetState::new(&node_info.into()), )))) diff --git a/src/routes.rs b/src/routes.rs index 58b9b2a..bc18af3 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -7,6 +7,7 @@ use axum::{ Extension, Json, }; +use fuel_core_client::client::types::NodeInfo; use fuel_core_client::client::FuelClient; use fuel_tx::{Output, UtxoId}; use fuel_types::{Address, AssetId, Bytes32}; @@ -32,9 +33,6 @@ use std::{ }; use tracing::{error, info}; -// The amount to fetch the biggest input of the faucet. -pub const THE_BIGGEST_AMOUNT: u64 = u32::MAX as u64; - lazy_static::lazy_static! { static ref START_TIME: u64 = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64; } @@ -197,6 +195,7 @@ pub async fn dispense_tokens( Extension(wallet): Extension, Extension(state): Extension, Extension(config): Extension, + Extension(info_node): Extension>, Extension(client): Extension>, Extension(dispense_tracker): Extension, ) -> Result { @@ -252,9 +251,11 @@ pub async fn dispense_tokens( let base_asset_id = *provider.consensus_parameters().base_asset_id(); let mut tx_id = None; - for _ in 0..5 { + for _ in 0..config.number_of_retries { let mut guard = state.lock().await; - let inputs = if let Some(previous_coin_output) = &guard.last_output { + let amount = guard.last_output.as_ref().map_or(0, |o| o.amount); + let inputs = if amount > config.dispense_amount { + let previous_coin_output = guard.last_output.expect("Checked above"); let coin_type = CoinType::Coin(Coin { amount: previous_coin_output.amount, block_created: 0u32, @@ -266,17 +267,24 @@ pub async fn dispense_tokens( vec![Input::resource_signed(coin_type)] } else { - get_coins(&wallet, &base_asset_id, config.dispense_amount).await? + get_coins( + &wallet, + &base_asset_id, + // Double the target amount to cover also the fee + config.dispense_amount * info_node.max_depth * 2, + ) + .await? }; - let mut outputs = wallet.get_asset_outputs_for_amount( - &address.into(), - base_asset_id, - config.dispense_amount, - ); + let recipient_address: Address = address.into(); let faucet_address: Address = wallet.address().into(); - // Add an additional output to store the stable part of the fee change. - outputs.push(Output::coin(faucet_address, 0, base_asset_id)); + let outputs = vec![ + Output::coin(recipient_address, config.dispense_amount, base_asset_id), + // Sends the dust change to the user + Output::change(recipient_address, 0, base_asset_id), + // Add an additional output to store the stable part of the fee change. + Output::coin(faucet_address, 0, base_asset_id), + ]; let tip = guard.next_tip(); @@ -308,17 +316,21 @@ pub async fn dispense_tokens( StatusCode::INTERNAL_SERVER_ERROR, ) })? - .ok_or(error( - "Overflow during calculating `TransactionFee`".to_string(), - StatusCode::INTERNAL_SERVER_ERROR, - ))?; + .ok_or_else(|| { + error( + "Overflow during calculating `TransactionFee`".to_string(), + StatusCode::INTERNAL_SERVER_ERROR, + ) + })?; let available_balance = available_balance(&tx_builder.inputs, &base_asset_id); let stable_fee_change = available_balance .checked_sub(fee.max_fee().saturating_add(config.dispense_amount)) - .ok_or(error( - "Not enough asset to cover a max fee".to_string(), - StatusCode::INTERNAL_SERVER_ERROR, - ))?; + .ok_or_else(|| { + error( + "Not enough asset to cover a max fee".to_string(), + StatusCode::INTERNAL_SERVER_ERROR, + ) + })?; *tx_builder.outputs.last_mut().unwrap() = Output::coin(faucet_address, stable_fee_change, base_asset_id); diff --git a/tests/dispense.rs b/tests/dispense.rs index 9b56bd4..03ddb0e 100644 --- a/tests/dispense.rs +++ b/tests/dispense.rs @@ -8,13 +8,15 @@ use fuel_core_client::client::pagination::{PageDirection, PaginationRequest}; use fuel_crypto::SecretKey; use fuel_faucet::config::Config; use fuel_faucet::models::DispenseInfoResponse; -use fuel_faucet::{start_server, Clock, THE_BIGGEST_AMOUNT}; +use fuel_faucet::{start_server, Clock}; use fuel_tx::ConsensusParameters; use fuel_types::Address; use fuels_accounts::provider::Provider; use fuels_accounts::wallet::WalletUnlocked; use fuels_core::types::bech32::Bech32Address; use fuels_core::types::transaction::TransactionType; +use futures::stream::FuturesUnordered; +use futures::StreamExt; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; use secrecy::Secret; @@ -56,31 +58,21 @@ struct TestContext { clock: MockClock, } impl TestContext { - async fn new(mut rng: StdRng) -> Self { - let dispense_amount = rng.gen_range(1..10000u64); - let secret_key: SecretKey = SecretKey::random(&mut rng); + async fn new(rng: &mut StdRng) -> Self { + let dispense_amount = 2000000; + let secret_key: SecretKey = SecretKey::random(rng); let wallet = WalletUnlocked::new_from_private_key(secret_key, None); let base_asset_id = [1; 32].into(); let mut generator = CoinConfigGenerator::new(); - let mut coins: Vec<_> = (0..10000) - .map(|_| { - // dust - CoinConfig { - owner: wallet.address().into(), - amount: THE_BIGGEST_AMOUNT - 1, - asset_id: rng.gen(), - ..generator.generate() - } + let coins: Vec<_> = (0..10000) + .map(|_| CoinConfig { + owner: wallet.address().into(), + amount: dispense_amount - 1, + asset_id: base_asset_id, + ..generator.generate() }) .collect(); - // main coin - coins.push(CoinConfig { - owner: wallet.address().into(), - amount: 1 << 50, - asset_id: base_asset_id, - ..generator.generate() - }); let state_config = StateConfig { coins, @@ -88,8 +80,12 @@ impl TestContext { }; let mut consensus_parameters = ConsensusParameters::default(); - consensus_parameters - .set_fee_params(fuel_tx::FeeParameters::default().with_gas_price_factor(1)); + consensus_parameters.set_fee_params( + // Values from the testnet + fuel_tx::FeeParameters::default() + .with_gas_price_factor(92) + .with_gas_per_byte(63), + ); consensus_parameters.set_base_asset_id(base_asset_id); let chain_config = ChainConfig { @@ -99,15 +95,16 @@ impl TestContext { let snapshot_reader = SnapshotReader::new_in_memory(chain_config, state_config); - let config = NodeConfig { + let mut config = NodeConfig { block_production: Trigger::Interval { block_time: Duration::from_secs(3), }, utxo_validation: true, - static_gas_price: 1, + static_gas_price: 20, snapshot_reader, ..NodeConfig::local_node() }; + config.txpool.max_depth = 32; // start node let fuel_node = FuelService::new_node(config).await.unwrap(); @@ -123,6 +120,7 @@ impl TestContext { node_url: format!("http://{}", fuel_node.bound_address), wallet_secret_key: Some(Secret::new(format!("{secret_key:x}"))), dispense_amount, + number_of_retries: 1, ..Default::default() }; @@ -141,7 +139,7 @@ impl TestContext { #[tokio::test] async fn can_start_server() { - let context = TestContext::new(StdRng::seed_from_u64(42)).await; + let context = TestContext::new(&mut StdRng::seed_from_u64(42)).await; let addr = context.addr; let client = reqwest::Client::new(); @@ -193,11 +191,11 @@ async fn dispense_sends_coins_to_valid_address_non_hex() { } async fn _dispense_sends_coins_to_valid_address( - rng: StdRng, + mut rng: StdRng, recipient_address: Bech32Address, recipient_address_str: String, ) { - let context = TestContext::new(rng).await; + let context = TestContext::new(&mut rng).await; let addr = context.addr; let client = reqwest::Client::new(); @@ -223,7 +221,7 @@ async fn _dispense_sends_coins_to_valid_address( .map(|coin| coin.amount) .sum(); - assert_eq!(test_balance, context.faucet_config.dispense_amount); + assert!(test_balance >= context.faucet_config.dispense_amount); } fn generate_recipient_addresses(count: usize, rng: &mut StdRng) -> Vec { @@ -238,9 +236,10 @@ fn generate_recipient_addresses(count: usize, rng: &mut StdRng) -> Vec { #[tokio::test] async fn many_concurrent_requests() { let mut rng = StdRng::seed_from_u64(42); - const COUNT: usize = 30; + + const COUNT: usize = 128; let recipient_addresses_str = generate_recipient_addresses(COUNT, &mut rng); - let context = TestContext::new(rng).await; + let context = TestContext::new(&mut rng).await; let addr = context.addr; let mut queries = vec![]; @@ -258,16 +257,24 @@ async fn many_concurrent_requests() { .await }); } - let queries = futures::future::join_all(queries).await; - for query in queries { - query.expect("Query should be successful"); + let mut queries = FuturesUnordered::from_iter(queries); + let mut success = 0; + while let Some(query) = queries.next().await { + let response = query.expect("Query should be successful"); + assert_eq!( + response.status(), + reqwest::StatusCode::CREATED, + "{success}/{COUNT}: {:?}", + response.bytes().await + ); + success += 1; } let txs = context .provider .get_transactions(PaginationRequest { cursor: None, - results: 1000, + results: 500, direction: PageDirection::Forward, }) .await @@ -285,7 +292,7 @@ async fn dispense_once_per_day() { let mut rng = StdRng::seed_from_u64(42); let recipient_address: Address = rng.gen(); let recipient_address_str = format!("{}", &recipient_address); - let context = TestContext::new(rng).await; + let context = TestContext::new(&mut rng).await; let addr = context.addr; let dispense_interval = 24 * 60 * 60;