diff --git a/CHANGELOG.md b/CHANGELOG.md index 8267a01c499..03667651349 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added +- [2135](https://github.com/FuelLabs/fuel-core/pull/2135): Added metrics logging for number of blocks served over the p2p req/res protocol. +- [2155](https://github.com/FuelLabs/fuel-core/pull/2155): Added trait declaration for block committer data + + ## [Version 0.35.0] ### Added diff --git a/Cargo.lock b/Cargo.lock index 56845a7ce5a..aad1e663422 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -236,7 +236,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "synstructure", ] @@ -248,7 +248,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -358,7 +358,7 @@ dependencies = [ "fnv", "futures-util", "http 1.1.0", - "indexmap 2.4.0", + "indexmap 2.5.0", "mime", "multer", "num-traits", @@ -387,7 +387,7 @@ dependencies = [ "proc-macro2", "quote", "strum 0.26.3", - "syn 2.0.76", + "syn 2.0.77", "thiserror", ] @@ -410,7 +410,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69117c43c01d81a69890a9f5dd6235f2f027ca8d1ec62d6d3c5e01ca0edb4f2b" dependencies = [ "bytes", - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_json", ] @@ -565,7 +565,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -582,7 +582,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -667,7 +667,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -708,9 +708,9 @@ dependencies = [ [[package]] name = "aws-credential-types" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16838e6c9e12125face1c1eff1343c75e3ff540de98ff7ebd61874a89bcfeb9" +checksum = "60e8f6b615cb5fc60a98132268508ad104310f0cfb25a1c22eee76efdf9154da" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -720,14 +720,15 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f42c2d4218de4dcd890a109461e2f799a1a2ba3bcd2cde9af88360f5df9266c6" +checksum = "2424565416eef55906f9f8cece2072b6b6a76075e3ff81483ebe938a89a4c05f" dependencies = [ "aws-credential-types", "aws-sigv4", "aws-smithy-async", "aws-smithy-http", + "aws-smithy-runtime", "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", @@ -744,9 +745,9 @@ dependencies = [ [[package]] name = "aws-sdk-kms" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ebbbc319551583b9233a74b359ede7349102e779fc12371d2478e80b50d218" +checksum = "178910fefe72743b62b9c4670c14a038ebfdb265ff7feccf43827af6a8899e14" dependencies = [ "aws-credential-types", "aws-runtime", @@ -766,9 +767,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.39.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11822090cf501c316c6f75711d77b96fba30658e3867a7762e5e2f5d32d31e81" +checksum = "e5879bec6e74b648ce12f6085e7245417bc5f6d672781028384d2e494be3eb6d" dependencies = [ "aws-credential-types", "aws-runtime", @@ -788,9 +789,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a2a06ff89176123945d1bbe865603c4d7101bea216a550bb4d2e4e9ba74d74" +checksum = "4ef4cd9362f638c22a3b959fd8df292e7e47fdf170270f86246b97109b5f2f7d" dependencies = [ "aws-credential-types", "aws-runtime", @@ -810,9 +811,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.39.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20a91795850826a6f456f4a48eff1dfa59a0e69bdbf5b8c50518fd372106574" +checksum = "0b1e2735d2ab28b35ecbb5496c9d41857f52a0d6a0075bbf6a8af306045ea6f6" dependencies = [ "aws-credential-types", "aws-runtime", @@ -867,9 +868,9 @@ dependencies = [ [[package]] name = "aws-smithy-http" -version = "0.60.9" +version = "0.60.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9cd0ae3d97daa0a2bf377a4d8e8e1362cae590c4a1aad0d40058ebca18eb91e" +checksum = "01dbcb6e2588fd64cfb6d7529661b06466419e4c54ed1c62d6510d2d0350a728" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", @@ -906,9 +907,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.6.3" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0abbf454960d0db2ad12684a1640120e7557294b0ff8e2f11236290a1b293225" +checksum = "d1ce695746394772e7000b39fe073095db6d45a862d0767dd5ad0ac0d7f8eb87" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -950,9 +951,9 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.2.2" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cee7cadb433c781d3299b916fbf620fea813bf38f49db282fb6858141a05cc8" +checksum = "273dcdfd762fae3e1650b8024624e7cd50e484e37abdab73a7a706188ad34543" dependencies = [ "base64-simd", "bytes", @@ -1130,7 +1131,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1511,7 +1512,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1763,9 +1764,9 @@ dependencies = [ [[package]] name = "cpp_demangle" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8227005286ec39567949b33df9896bcadfa6051bccca2488129f108ca23119" +checksum = "96e58d342ad113c2b878f16d5d034c03be492ae460cdbc02b7f0f2284d310c7d" dependencies = [ "cfg-if", ] @@ -2105,7 +2106,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2193,7 +2194,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2215,7 +2216,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2308,7 +2309,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2424,7 +2425,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2584,7 +2585,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2604,7 +2605,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2759,7 +2760,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.76", + "syn 2.0.77", "toml 0.8.19", "walkdir", ] @@ -2777,7 +2778,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2803,7 +2804,7 @@ dependencies = [ "serde", "serde_json", "strum 0.26.3", - "syn 2.0.76", + "syn 2.0.77", "tempfile", "thiserror", "tiny-keccak", @@ -3795,7 +3796,7 @@ checksum = "3f49fdbfc1615d88d2849650afc2b0ac2fecd69661ebadd31a073d8416747764" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "synstructure", ] @@ -4009,7 +4010,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -4122,7 +4123,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" dependencies = [ "fallible-iterator", - "indexmap 2.4.0", + "indexmap 2.5.0", "stable_deref_trait", ] @@ -4183,7 +4184,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.4.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -4704,7 +4705,7 @@ dependencies = [ "autocfg", "impl-tools-lib", "proc-macro-error", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -4716,7 +4717,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -4749,9 +4750,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -5437,7 +5438,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6225,7 +6226,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6242,13 +6243,13 @@ checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" [[package]] name = "object" -version = "0.36.3" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "crc32fast", "hashbrown 0.14.5", - "indexmap 2.4.0", + "indexmap 2.5.0", "memchr", ] @@ -6523,7 +6524,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.4.0", + "indexmap 2.5.0", ] [[package]] @@ -6566,7 +6567,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6604,7 +6605,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6846,7 +6847,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ "proc-macro2", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6934,7 +6935,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -7906,7 +7907,7 @@ checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -7952,7 +7953,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_derive", "serde_json", @@ -7969,7 +7970,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -7978,7 +7979,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "itoa", "ryu", "serde", @@ -8299,7 +8300,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta-derive", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8310,7 +8311,7 @@ checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8363,7 +8364,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8376,7 +8377,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8441,9 +8442,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.76" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -8464,7 +8465,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8578,7 +8579,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8589,7 +8590,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "test-case-core", ] @@ -8626,7 +8627,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8652,7 +8653,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8772,9 +8773,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.3" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -8806,7 +8807,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8905,7 +8906,7 @@ version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", @@ -8993,7 +8994,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -9358,7 +9359,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "wasm-bindgen-shared", ] @@ -9392,7 +9393,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -9421,7 +9422,7 @@ dependencies = [ "ahash", "bitflags 2.6.0", "hashbrown 0.14.5", - "indexmap 2.4.0", + "indexmap 2.5.0", "semver", "serde", ] @@ -9449,7 +9450,7 @@ dependencies = [ "cc", "cfg-if", "hashbrown 0.14.5", - "indexmap 2.4.0", + "indexmap 2.5.0", "libc", "libm", "log", @@ -9517,7 +9518,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "wasmtime-component-util", "wasmtime-wit-bindgen", "wit-parser", @@ -9563,7 +9564,7 @@ dependencies = [ "cranelift-bitset", "cranelift-entity", "gimli 0.28.1", - "indexmap 2.4.0", + "indexmap 2.5.0", "log", "object", "postcard", @@ -9616,7 +9617,7 @@ checksum = "99c02af2e9dbeb427304d1a08787d70ed0dbfec1af2236616f84c9f1f03e7969" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -9627,7 +9628,7 @@ checksum = "75f528f8b8a2376a3dacaf497d960216dd466d324425361e1e00e26de0a7705c" dependencies = [ "anyhow", "heck 0.4.1", - "indexmap 2.4.0", + "indexmap 2.5.0", "wit-parser", ] @@ -9897,7 +9898,7 @@ checksum = "ceeb0424aa8679f3fcf2d6e3cfa381f3d6fa6179976a2c05a6249dd2bb426716" dependencies = [ "anyhow", "id-arena", - "indexmap 2.4.0", + "indexmap 2.5.0", "log", "semver", "serde", @@ -10057,7 +10058,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -10077,7 +10078,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] diff --git a/crates/fuel-core/src/service/sub_services/algorithm_updater.rs b/crates/fuel-core/src/service/sub_services/algorithm_updater.rs index 4cde01705fd..5482fac96a0 100644 --- a/crates/fuel-core/src/service/sub_services/algorithm_updater.rs +++ b/crates/fuel-core/src/service/sub_services/algorithm_updater.rs @@ -20,6 +20,7 @@ use fuel_core_gas_price_service::{ FuelL2BlockSource, GasPriceSettingsProvider, }, + fuel_da_source_adapter::FuelDaSource, Algorithm, AlgorithmUpdater, AlgorithmUpdaterV0, @@ -57,6 +58,7 @@ use fuel_core_types::{ type Updater = FuelGasPriceUpdater< FuelL2BlockSource, MetadataStorageAdapter, + FuelDaSource, >; pub struct InitializeTask { @@ -77,6 +79,7 @@ type Task = GasPriceService< FuelGasPriceUpdater< FuelL2BlockSource, MetadataStorageAdapter, + FuelDaSource, >, >; @@ -214,6 +217,7 @@ pub fn get_synced_gas_price_updater( default_metadata.into(), l2_block_source, metadata_storage, + FuelDaSource, ); Ok(updater) } else { @@ -231,6 +235,7 @@ pub fn get_synced_gas_price_updater( latest_block_height.into(), l2_block_source, metadata_storage, + FuelDaSource, config.min_gas_price, config.gas_price_change_percent, config.gas_price_threshold_percent, @@ -265,6 +270,9 @@ fn sync_metadata_storage_with_on_chain_storage( metadata_storage, )?; } + AlgorithmUpdater::V1(_) => { + todo!() // TODO(#2140) + } } Ok(()) } diff --git a/crates/fuel-gas-price-algorithm/gas-price-analysis/gas_prices.png b/crates/fuel-gas-price-algorithm/gas-price-analysis/gas_prices.png index 27e130cb0bc..dde9a368c50 100644 Binary files a/crates/fuel-gas-price-algorithm/gas-price-analysis/gas_prices.png and b/crates/fuel-gas-price-algorithm/gas-price-analysis/gas_prices.png differ diff --git a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/charts.rs b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/charts.rs index 7b49f33e537..1ec591e11fb 100644 --- a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/charts.rs +++ b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/charts.rs @@ -3,52 +3,52 @@ use super::*; pub fn draw_gas_prices( drawing_area: &DrawingArea, gas_prices: &[u64], - exec_gas_prices: &[u64], + _exec_gas_prices: &[u64], da_gas_prices: &[u64], title: &str, ) { - const GAS_PRICE_COLOR: RGBColor = BLACK; - const EXEC_GAS_PRICE_COLOR: RGBColor = RED; + // const GAS_PRICE_COLOR: RGBColor = BLACK; + // const EXEC_GAS_PRICE_COLOR: RGBColor = RED; const DA_GAS_PRICE_COLOR: RGBColor = BLUE; let min = 0; - let max = *gas_prices.iter().max().unwrap(); + let max = *da_gas_prices.iter().max().unwrap(); let mut chart = ChartBuilder::on(drawing_area) .caption(title, ("sans-serif", 50).into_font()) .margin(5) .x_label_area_size(40) - .y_label_area_size(60) - .right_y_label_area_size(40) + .y_label_area_size(100) + .right_y_label_area_size(100) .build_cartesian_2d(0..gas_prices.len(), min..max) .unwrap(); chart .configure_mesh() - .y_desc("Gas Price") + .y_desc("DA Gas Price") .x_desc("Block") .draw() .unwrap(); - chart - .draw_series(LineSeries::new( - gas_prices.iter().enumerate().map(|(x, y)| (x, *y)), - GAS_PRICE_COLOR, - )) - .unwrap() - .label("Gas Price") - .legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], GAS_PRICE_COLOR)); + // chart + // .draw_series(LineSeries::new( + // gas_prices.iter().enumerate().map(|(x, y)| (x, *y)), + // GAS_PRICE_COLOR, + // )) + // .unwrap() + // .label("Gas Price") + // .legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], GAS_PRICE_COLOR)); // Draw the exec gas prices - chart - .draw_series(LineSeries::new( - exec_gas_prices.iter().enumerate().map(|(x, y)| (x, *y)), - EXEC_GAS_PRICE_COLOR, - )) - .unwrap() - .label("Exec Gas Price") - .legend(|(x, y)| { - PathElement::new(vec![(x, y), (x + 20, y)], EXEC_GAS_PRICE_COLOR) - }); + // chart + // .draw_series(LineSeries::new( + // exec_gas_prices.iter().enumerate().map(|(x, y)| (x, *y)), + // EXEC_GAS_PRICE_COLOR, + // )) + // .unwrap() + // .label("Exec Gas Price") + // .legend(|(x, y)| { + // PathElement::new(vec![(x, y), (x + 20, y)], EXEC_GAS_PRICE_COLOR) + // }); // Draw the da gas prices chart @@ -82,8 +82,8 @@ pub fn draw_fullness( .caption(title, ("sans-serif", 50).into_font()) .margin(5) .x_label_area_size(40) - .y_label_area_size(60) - .right_y_label_area_size(40) + .y_label_area_size(100) + .right_y_label_area_size(100) .build_cartesian_2d(0..fullness.len(), min..max) .unwrap(); @@ -115,6 +115,70 @@ pub fn draw_fullness( .unwrap(); } +pub fn draw_bytes_and_cost_per_block( + drawing_area: &DrawingArea, + bytes_and_costs_per_block: &[(u64, u64)], + title: &str, +) { + const BYTES_PER_BLOCK_COLOR: RGBColor = BLACK; + let (bytes, costs): (Vec, Vec) = + bytes_and_costs_per_block.iter().cloned().unzip(); + + let min = 0; + let max_left = *bytes.iter().max().unwrap(); + let max_right = *costs.iter().max().unwrap(); + + let mut chart = ChartBuilder::on(drawing_area) + .caption(title, ("sans-serif", 50).into_font()) + .margin(5) + .x_label_area_size(40) + .y_label_area_size(100) + .right_y_label_area_size(100) + .build_cartesian_2d(0..bytes_and_costs_per_block.len(), min..max_left) + .unwrap() + .set_secondary_coord(0..bytes_and_costs_per_block.len(), min..max_right); + + chart + .configure_mesh() + .y_desc("Bytes Per Block") + .x_desc("Block") + .draw() + .unwrap(); + + chart + .configure_secondary_axes() + .y_desc("Cost Per Block") + .draw() + .unwrap(); + + chart + .draw_series(LineSeries::new( + bytes.iter().enumerate().map(|(x, y)| (x, *y)), + BYTES_PER_BLOCK_COLOR, + )) + .unwrap() + .label("Bytes Per Block") + .legend(|(x, y)| { + PathElement::new(vec![(x, y), (x + 20, y)], BYTES_PER_BLOCK_COLOR) + }); + + chart + .draw_secondary_series(LineSeries::new( + costs.iter().enumerate().map(|(x, y)| (x, *y)), + RED, + )) + .unwrap() + .label("Cost Per Block") + .legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], RED)); + + chart + .configure_series_labels() + .background_style(WHITE.mix(0.8)) + .border_style(BLACK) + .draw() + .unwrap(); +} + pub fn draw_profit( drawing_area: &DrawingArea, actual_profit: &[i64], @@ -125,18 +189,27 @@ pub fn draw_profit( const ACTUAL_PROFIT_COLOR: RGBColor = BLACK; const PROJECTED_PROFIT_COLOR: RGBColor = RED; const PESSIMISTIC_BLOCK_COST_COLOR: RGBColor = BLUE; - let min = *actual_profit.iter().min().unwrap(); - let max = *actual_profit.iter().max().unwrap(); - println!("min: {}, max: {}", min, max); + let min = *std::cmp::min( + actual_profit.iter().min().unwrap(), + projected_profit.iter().min().unwrap_or(&0), + ); + let max = *std::cmp::max( + actual_profit.iter().max().unwrap(), + projected_profit.iter().max().unwrap_or(&0), + ); let mut chart = ChartBuilder::on(drawing_area) .caption(title, ("sans-serif", 50).into_font()) .margin(5) .x_label_area_size(40) - .y_label_area_size(60) - .right_y_label_area_size(40) + .y_label_area_size(100) + .right_y_label_area_size(100) .build_cartesian_2d(0..actual_profit.len(), min..max) - .unwrap(); + .unwrap() + .set_secondary_coord( + 0..actual_profit.len(), + 0..*pessimistic_block_costs.iter().max().unwrap(), + ); chart .configure_mesh() @@ -145,6 +218,12 @@ pub fn draw_profit( .draw() .unwrap(); + chart + .configure_secondary_axes() + .y_desc("Pessimistic cost") + .draw() + .unwrap(); + chart .draw_series(LineSeries::new( actual_profit.iter().enumerate().map(|(x, y)| (x, *y)), @@ -169,11 +248,11 @@ pub fn draw_profit( // draw the block bytes chart - .draw_series(LineSeries::new( + .draw_secondary_series(LineSeries::new( pessimistic_block_costs .iter() .enumerate() - .map(|(x, y)| (x, *y as i64)), + .map(|(x, y)| (x, *y)), PESSIMISTIC_BLOCK_COST_COLOR, )) .unwrap() diff --git a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/main.rs b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/main.rs index f75360fe78c..02c67b93e43 100644 --- a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/main.rs +++ b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/main.rs @@ -9,6 +9,7 @@ use plotters::coord::Shift; use crate::{ charts::{ + draw_bytes_and_cost_per_block, draw_fullness, draw_gas_prices, draw_profit, @@ -25,22 +26,36 @@ mod simulation; mod charts; +pub fn pretty(input: u64) -> String { + input + .to_string() + .as_bytes() + .rchunks(3) + .rev() + .map(std::str::from_utf8) + .collect::, _>>() + .unwrap() + .join(",") // separator +} + fn main() { - let optimisation_iterations = 50_000; - let avg_window = 2; - let (best, (p_comp, d_comp, avg_window)) = - naive_optimisation(optimisation_iterations, avg_window); + let optimisation_iterations = 10_000; + let (best, (p_comp, d_comp)) = naive_optimisation(optimisation_iterations); let SimulationResults { gas_prices, exec_gas_prices, da_gas_prices, fullness, + bytes_and_costs, actual_profit, projected_profit, pessimistic_costs, } = best; - let plot_width = 640 * 2; + let max_actual_profit = pretty(*actual_profit.iter().max().unwrap() as u64); + println!("max_actual: {max_actual_profit}"); + + let plot_width = 640 * 2 * 2; let plot_height = 480 * 3; const FILE_PATH: &str = "gas_prices.png"; @@ -48,22 +63,23 @@ fn main() { let root = BitMapBackend::new(FILE_PATH, (plot_width, plot_height)).into_drawing_area(); root.fill(&WHITE).unwrap(); - let (upper, lower) = root.split_vertically(plot_height / 3); - let (middle, bottom) = lower.split_vertically(plot_height / 3); + let (window_one, lower) = root.split_vertically(plot_height / 4); + let (window_two, new_lower) = lower.split_vertically(plot_height / 4); + let (window_three, window_four) = new_lower.split_vertically(plot_height / 4); + + draw_fullness(&window_one, &fullness, "Fullness"); - draw_fullness(&upper, &fullness, "Fullness"); + draw_bytes_and_cost_per_block(&window_two, &bytes_and_costs, "Bytes Per Block"); draw_profit( - &middle, + &window_three, &actual_profit, &projected_profit, &pessimistic_costs, - &format!( - "Profit p_comp: {p_comp:?}, d_comp: {d_comp:?}, avg window: {avg_window:?}" - ), + &format!("Profit p_comp: {p_comp:?}, d_comp: {d_comp:?}"), ); draw_gas_prices( - &bottom, + &window_four, &gas_prices, &exec_gas_prices, &da_gas_prices, diff --git a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/optimisation.rs b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/optimisation.rs index 229939bd99a..273131b29d6 100644 --- a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/optimisation.rs +++ b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/optimisation.rs @@ -1,26 +1,26 @@ use super::*; -fn da_pid_factors(size: usize) -> Vec<(i64, i64)> { - let mut rng = StdRng::seed_from_u64(10902); - (0usize..size) - .map(|_| { - let p = rng.gen_range(1_000..100_000_000_000); - let d = rng.gen_range(1_000..100_000_000_000); - (p, d) - }) - .collect() +fn da_pid_factors(_size: usize) -> Vec<(i64, i64)> { + // let mut rng = StdRng::seed_from_u64(10902); + // (0usize..size) + // .map(|_| { + // let p = rng.gen_range(100_000..5_000_000); + // let d = rng.gen_range(100_000..5_000_000); + // (p, d) + // }) + // .collect() + // vec![(1_700_000, 50_000)] // Better on short term + vec![(1_700_000, 650_000)] // Safe } -pub fn naive_optimisation( - iterations: usize, - avg_window: u32, -) -> (SimulationResults, (i64, i64, u32)) { +pub fn naive_optimisation(iterations: usize) -> (SimulationResults, (i64, i64)) { da_pid_factors(iterations) .iter() - .map(|(p, d)| (run_simulation(*p, *d, avg_window), (*p, *d, avg_window))) + .map(|(p, d)| (run_simulation(*p, *d), (*p, *d))) .min_by_key(|(results, _)| { let SimulationResults { actual_profit, .. } = results; - actual_profit.iter().map(|p| p.abs()).sum::() + let err = actual_profit.iter().map(|p| p.abs()).sum::(); + err }) .unwrap() } diff --git a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/simulation.rs b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/simulation.rs index 5bb4070cb4a..5696fc26d28 100644 --- a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/simulation.rs +++ b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/simulation.rs @@ -3,30 +3,32 @@ use fuel_gas_price_algorithm::v1::{ AlgorithmUpdaterV1, RecordedBlock, }; +use std::{ + iter, + num::NonZeroU64, +}; pub struct SimulationResults { pub gas_prices: Vec, pub exec_gas_prices: Vec, pub da_gas_prices: Vec, pub fullness: Vec<(u64, u64)>, + pub bytes_and_costs: Vec<(u64, u64)>, pub actual_profit: Vec, pub projected_profit: Vec, pub pessimistic_costs: Vec, } -pub fn run_simulation( - da_p_component: i64, - da_d_component: i64, - avg_window: u32, -) -> SimulationResults { +pub fn run_simulation(da_p_component: i64, da_d_component: i64) -> SimulationResults { // simulation parameters - let size = 1_000; - let da_recording_rate = 10; + let size = 1000; + let da_recording_rate = 12; let capacity = 30_000_000; let gas_per_byte = 63; + let gas_price_factor = 100; let max_block_bytes = capacity / gas_per_byte; let fullness_and_bytes = fullness_and_bytes_per_block(size, capacity); - let da_cost_per_byte = arb_cost_per_byte(size as u32); + let da_cost_per_byte = arbitrary_cost_per_byte(size, da_recording_rate); let l2_blocks = fullness_and_bytes .iter() @@ -40,12 +42,12 @@ pub fn run_simulation( (vec![], vec![]), |(mut delayed, mut recorded), (index, ((_fullness, bytes), cost_per_byte))| { - let total_cost = bytes * cost_per_byte; + let total_cost = *bytes * cost_per_byte; let height = index as u32 + 1; let converted = RecordedBlock { height, block_bytes: *bytes, - block_cost: total_cost, + block_cost: total_cost as u64, }; delayed.push(converted); if delayed.len() == da_recording_rate { @@ -64,22 +66,23 @@ pub fn run_simulation( let mut updater = AlgorithmUpdaterV1 { min_exec_gas_price: 10, min_da_gas_price: 10, - new_exec_price: 800, - last_da_gas_price: 200, + new_exec_price: 10 * gas_price_factor, + last_da_gas_price: 5 * gas_price_factor, + da_gas_price_factor: NonZeroU64::new(gas_price_factor).unwrap(), l2_block_height: 0, l2_block_fullness_threshold_percent: 50, exec_gas_price_change_percent: 2, max_da_gas_price_change_percent: 10, total_da_rewards: 0, da_recorded_block_height: 0, - latest_da_cost_per_byte: 200, + latest_da_cost_per_byte: 50000, projected_total_da_cost: 0, latest_known_total_da_cost: 0, unrecorded_blocks: vec![], da_p_component, da_d_component, - profit_avg: 0, - avg_window, + last_profit: 0, + second_to_last_profit: 0, }; let mut gas_prices = vec![]; @@ -94,10 +97,12 @@ pub fn run_simulation( exec_gas_prices.push(updater.new_exec_price); let gas_price = updater.algorithm().calculate(max_block_bytes); gas_prices.push(gas_price); - // Update DA blocks - if let Some(da_blocks) = da_block { + // Update DA blocks on the occasion there is one + + if let Some(mut da_blocks) = da_block.clone() { let mut total_costs = updater.latest_known_total_da_cost; - for block in da_blocks { + for block in &mut da_blocks { + block.block_cost *= gas_price_factor; total_costs += block.block_cost; actual_costs.push(total_costs); } @@ -105,9 +110,14 @@ pub fn run_simulation( assert_eq!(total_costs, updater.projected_total_da_cost); assert_eq!(total_costs, updater.latest_known_total_da_cost); } - // Update L2 block updater - .update_l2_block_data(height, (*fullness, capacity), *bytes, gas_price) + .update_l2_block_data( + height, + *fullness, + capacity.try_into().unwrap(), + *bytes, + gas_price, + ) .unwrap(); da_gas_prices.push(updater.last_da_gas_price); pessimistic_costs.push(max_block_bytes * updater.latest_da_cost_per_byte); @@ -115,9 +125,16 @@ pub fn run_simulation( projected_cost_totals.push(updater.projected_total_da_cost); } - let fullness = fullness_and_bytes + let (fullness_without_capacity, bytes): (Vec<_>, Vec<_>) = + fullness_and_bytes.iter().cloned().unzip(); + let fullness = fullness_without_capacity + .iter() + .map(|&fullness| (fullness, capacity)) + .collect(); + let bytes_and_costs = bytes .iter() - .map(|(fullness, _)| (*fullness, capacity)) + .zip(da_cost_per_byte.iter()) + .map(|(bytes, cost_per_byte)| (*bytes, (*bytes * cost_per_byte) as u64)) .collect(); let actual_profit: Vec = actual_costs @@ -137,12 +154,14 @@ pub fn run_simulation( exec_gas_prices, da_gas_prices, fullness, + bytes_and_costs, actual_profit, projected_profit, pessimistic_costs, } } +// Naive Fourier series fn gen_noisy_signal(input: f64, components: &[f64]) -> f64 { components .iter() @@ -150,15 +169,6 @@ fn gen_noisy_signal(input: f64, components: &[f64]) -> f64 { / components.len() as f64 } -fn noisy_eth_price>(input: T) -> f64 -where - >::Error: core::fmt::Debug, -{ - const COMPONENTS: &[f64] = &[70.0, 130.0]; - let input = input.try_into().unwrap(); - gen_noisy_signal(input, COMPONENTS) -} - fn noisy_fullness>(input: T) -> f64 where >::Error: core::fmt::Debug, @@ -177,16 +187,17 @@ fn fullness_and_bytes_per_block(size: usize, capacity: u64) -> Vec<(u64, u64)> { .map(|val| val * capacity as f64) .collect(); + const ROUGH_GAS_TO_BYTE_RATIO: f64 = 0.01; let bytes_scale: Vec<_> = std::iter::repeat(()) .take(size) .map(|_| rng.gen_range(0.5..1.0)) - .map(|x| x * 4.0) + .map(|x| x * ROUGH_GAS_TO_BYTE_RATIO) .collect(); (0usize..size) .map(|val| val as f64) .map(noisy_fullness) - .map(|signal| (0.5 * signal + 0.5) * capacity as f64) + .map(|signal| (0.5 * signal + 0.5) * capacity as f64) // Scale and shift so it's between 0 and capacity .zip(fullness_noise) .map(|(fullness, noise)| fullness + noise) .map(|x| f64::min(x, capacity as f64)) @@ -196,14 +207,31 @@ fn fullness_and_bytes_per_block(size: usize, capacity: u64) -> Vec<(u64, u64)> { let bytes = fullness * bytes_scale; (fullness, bytes) }) - .map(|(fullness, bytes)| (fullness as u64, bytes as u64)) + .map(|(fullness, bytes)| (fullness as u64, std::cmp::max(bytes as u64, 1))) .collect() } -fn arb_cost_per_byte(size: u32) -> Vec { - (0u32..size) +fn noisy_eth_price>(input: T) -> f64 +where + >::Error: core::fmt::Debug, +{ + const COMPONENTS: &[f64] = &[3.0, 4.0]; + let input = input.try_into().unwrap(); + gen_noisy_signal(input, COMPONENTS) +} + +fn arbitrary_cost_per_byte(size: usize, update_period: usize) -> Vec { + let actual_size = size.div_ceil(update_period); + + const ROUGH_COST_AVG: f64 = 5.0; + + (0u32..actual_size as u32) .map(noisy_eth_price) - .map(|x| x * 100. + 110.) + .map(|x| x * ROUGH_COST_AVG + ROUGH_COST_AVG) // Sine wave is between -1 and 1, scale and shift .map(|x| x as u64) + .map(|x| std::cmp::max(x, 1)) + .map(|x| iter::repeat(x).take(update_period as usize)) + .flatten() + .take(size as usize) .collect() } diff --git a/crates/fuel-gas-price-algorithm/src/v1.rs b/crates/fuel-gas-price-algorithm/src/v1.rs index 4ea91c0c327..8c884633123 100644 --- a/crates/fuel-gas-price-algorithm/src/v1.rs +++ b/crates/fuel-gas-price-algorithm/src/v1.rs @@ -66,45 +66,30 @@ pub struct AlgorithmV1 { /// The D component of the PID control for the DA gas price da_d_factor: i64, /// The average profit over the last `avg_window` blocks - avg_profit: i64, - /// The number of blocks to consider when calculating the average profit - avg_window: u32, + last_profit: i64, + /// the previous profit + second_to_last_profit: i64, } impl AlgorithmV1 { - pub fn calculate(&self, block_bytes: u64) -> u64 { - let projected_profit_avg = self.calculate_avg_profit(block_bytes); - - let p = self.p(projected_profit_avg); - let d = self.d(projected_profit_avg); + pub fn calculate(&self, _block_bytes: u64) -> u64 { + let p = self.p(); + let d = self.d(); let da_change = self.change(p, d); self.assemble_price(da_change) } - fn calculate_avg_profit(&self, block_bytes: u64) -> i64 { - let extra_for_this_block = - block_bytes.saturating_mul(self.latest_da_cost_per_byte); - let pessimistic_cost = self.total_costs.saturating_add(extra_for_this_block); - let projected_profit = - (self.total_rewards as i64).saturating_sub(pessimistic_cost as i64); - projected_profit - .saturating_add( - self.avg_profit - .saturating_mul((self.avg_window as i64).saturating_sub(1)), - ) - .checked_div(self.avg_window as i64) - .unwrap_or(self.avg_profit) - } - - fn p(&self, projected_profit_avg: i64) -> i64 { - let checked_p = projected_profit_avg.checked_div(self.da_p_factor); + fn p(&self) -> i64 { + let checked_p = self.last_profit.checked_div(self.da_p_factor); + // If the profit is positive, we want to decrease the gas price checked_p.unwrap_or(0).saturating_mul(-1) } - fn d(&self, projected_profit_avg: i64) -> i64 { - let slope = projected_profit_avg.saturating_sub(self.avg_profit); + fn d(&self) -> i64 { + let slope = self.last_profit.saturating_sub(self.second_to_last_profit); let checked_d = slope.checked_div(self.da_d_factor); + // if the slope is positive, we want to decrease the gas price checked_d.unwrap_or(0).saturating_mul(-1) } @@ -142,12 +127,9 @@ impl AlgorithmV1 { /// to account for the worst case scenario when calculating the parameters of the algorithm. #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)] pub struct AlgorithmUpdaterV1 { + // Execution /// The gas price to cover the execution of the next block pub new_exec_price: u64, - /// The gas price for the DA portion of the last block. This can be used to calculate - /// the DA portion of the next block - pub last_da_gas_price: u64, - // Execution /// The lowest the algorithm allows the exec gas price to go pub min_exec_gas_price: u64, /// The Percentage the execution gas price will change in a single block, either increase or decrease @@ -159,6 +141,11 @@ pub struct AlgorithmUpdaterV1 { /// This is a percentage of the total capacity of the L2 block pub l2_block_fullness_threshold_percent: u64, // DA + /// The gas price for the DA portion of the last block. This can be used to calculate + /// the DA portion of the next block + pub last_da_gas_price: u64, + /// Scale factor for the DA gas price. + pub da_gas_price_factor: NonZeroU64, /// The lowest the algorithm allows the da gas price to go pub min_da_gas_price: u64, /// The maximum percentage that the DA portion of the gas price can change in a single block @@ -176,10 +163,10 @@ pub struct AlgorithmUpdaterV1 { pub da_p_component: i64, /// The D component of the PID control for the DA gas price pub da_d_component: i64, - /// The average profit over the last `avg_window` blocks - pub profit_avg: i64, - /// The number of blocks to consider when calculating the average profit - pub avg_window: u32, + /// The last profit + pub last_profit: i64, + /// The profit before last + pub second_to_last_profit: i64, /// The latest known cost per byte for recording blocks on the DA chain pub latest_da_cost_per_byte: u64, /// The unrecorded blocks that are used to calculate the projected cost of recording blocks @@ -230,29 +217,31 @@ impl AlgorithmUpdaterV1 { let last_exec_price = self.new_exec_price; let last_profit = (self.total_da_rewards as i64) .saturating_sub(self.projected_total_da_cost as i64); - self.update_profit_avg(last_profit); - let new_projected_da_cost = - block_bytes.saturating_mul(self.latest_da_cost_per_byte); + self.update_last_profit(last_profit); + #[allow(clippy::arithmetic_side_effects)] + // the `da_gas_price_factor` will never be `0` + let new_projected_da_cost = block_bytes + .saturating_mul(self.latest_da_cost_per_byte) + .saturating_div(self.da_gas_price_factor.into()); self.projected_total_da_cost = self .projected_total_da_cost .saturating_add(new_projected_da_cost); // implicitly deduce what our da gas price was for the l2 block self.last_da_gas_price = gas_price.saturating_sub(last_exec_price); self.update_exec_gas_price(used, capacity); - let da_reward = used.saturating_mul(self.last_da_gas_price); + #[allow(clippy::arithmetic_side_effects)] + // the `da_gas_price_factor` will never be `0` + let da_reward = used + .saturating_mul(self.last_da_gas_price) + .saturating_div(self.da_gas_price_factor.into()); self.total_da_rewards = self.total_da_rewards.saturating_add(da_reward); Ok(()) } } - fn update_profit_avg(&mut self, new_profit: i64) { - let old_avg = self.profit_avg; - let new_avg = old_avg - .saturating_mul((self.avg_window as i64).saturating_sub(1)) - .saturating_add(new_profit) - .checked_div(self.avg_window as i64) - .unwrap_or(old_avg); - self.profit_avg = new_avg; + fn update_last_profit(&mut self, new_profit: i64) { + self.second_to_last_profit = self.last_profit; + self.last_profit = new_profit; } fn update_exec_gas_price(&mut self, used: u64, capacity: NonZeroU64) { @@ -295,12 +284,17 @@ impl AlgorithmUpdaterV1 { got: height, }) } else { - let new_cost_per_byte = block_cost.checked_div(block_bytes).ok_or( - Error::CouldNotCalculateCostPerByte { + let new_cost_per_byte = block_cost + .checked_mul(self.da_gas_price_factor.into()) + .ok_or(Error::CouldNotCalculateCostPerByte { + bytes: block_bytes, + cost: block_cost, + })? + .checked_div(block_bytes) + .ok_or(Error::CouldNotCalculateCostPerByte { bytes: block_bytes, cost: block_cost, - }, - )?; + })?; self.da_recorded_block_height = height; let new_block_cost = self.latest_known_total_da_cost.saturating_add(block_cost); @@ -339,10 +333,10 @@ impl AlgorithmUpdaterV1 { latest_da_cost_per_byte: self.latest_da_cost_per_byte, total_rewards: self.total_da_rewards, total_costs: self.projected_total_da_cost, - avg_profit: self.profit_avg, + last_profit: self.last_profit, + second_to_last_profit: self.second_to_last_profit, da_p_factor: self.da_p_component, da_d_factor: self.da_d_component, - avg_window: self.avg_window, } } } diff --git a/crates/fuel-gas-price-algorithm/src/v1/tests.rs b/crates/fuel-gas-price-algorithm/src/v1/tests.rs index a3abf8f9ac4..49c1d25371b 100644 --- a/crates/fuel-gas-price-algorithm/src/v1/tests.rs +++ b/crates/fuel-gas-price-algorithm/src/v1/tests.rs @@ -34,8 +34,9 @@ pub struct UpdaterBuilder { project_total_cost: u64, latest_known_total_cost: u64, unrecorded_blocks: Vec, - profit_avg: i64, - avg_window: u32, + last_profit: i64, + second_to_last_profit: i64, + da_gas_price_factor: u64, } impl UpdaterBuilder { @@ -60,8 +61,9 @@ impl UpdaterBuilder { project_total_cost: 0, latest_known_total_cost: 0, unrecorded_blocks: vec![], - profit_avg: 0, - avg_window: 1, + last_profit: 0, + second_to_last_profit: 0, + da_gas_price_factor: 1, } } @@ -90,7 +92,7 @@ impl UpdaterBuilder { self } - fn with_max_change_percent(mut self, max_change_percent: u8) -> Self { + fn with_da_max_change_percent(mut self, max_change_percent: u8) -> Self { self.max_change_percent = max_change_percent; self } @@ -148,9 +150,9 @@ impl UpdaterBuilder { self } - fn with_profit_avg(mut self, profit_avg: i64, window: u32) -> Self { - self.profit_avg = profit_avg; - self.avg_window = window; + fn with_last_profit(mut self, last_profit: i64, last_last_profit: i64) -> Self { + self.last_profit = last_profit; + self.second_to_last_profit = last_last_profit; self } @@ -174,9 +176,13 @@ impl UpdaterBuilder { projected_total_da_cost: self.project_total_cost, latest_known_total_da_cost: self.latest_known_total_cost, unrecorded_blocks: self.unrecorded_blocks, - profit_avg: self.profit_avg, - avg_window: self.avg_window, + last_profit: self.last_profit, + second_to_last_profit: self.second_to_last_profit, min_da_gas_price: self.min_da_gas_price, + da_gas_price_factor: self + .da_gas_price_factor + .try_into() + .expect("Should never be non-zero"), } } } diff --git a/crates/fuel-gas-price-algorithm/src/v1/tests/algorithm_v1_tests.rs b/crates/fuel-gas-price-algorithm/src/v1/tests/algorithm_v1_tests.rs index e6ab76b2808..e559efd7d6e 100644 --- a/crates/fuel-gas-price-algorithm/src/v1/tests/algorithm_v1_tests.rs +++ b/crates/fuel-gas-price-algorithm/src/v1/tests/algorithm_v1_tests.rs @@ -39,8 +39,8 @@ fn calculate__negative_profit_increase_gas_price() { let da_p_component = 100; let da_d_component = 10; let block_bytes = 500; - let profit_avg = 100; - let avg_window = 10; + let last_profit = -100; + let last_last_profit = 0; let arb_value = 1000; let smaller_starting_reward = starting_cost + block_bytes * latest_gas_per_byte - arb_value; @@ -53,7 +53,7 @@ fn calculate__negative_profit_increase_gas_price() { .with_known_total_cost(starting_cost) .with_projected_total_cost(starting_cost) .with_da_cost_per_byte(latest_gas_per_byte) - .with_profit_avg(profit_avg, avg_window) + .with_last_profit(last_profit, last_last_profit) .build(); // when @@ -61,13 +61,8 @@ fn calculate__negative_profit_increase_gas_price() { let actual = algo.calculate(block_bytes); // then - let profit = smaller_starting_reward as i64 - - (starting_cost + block_bytes * latest_gas_per_byte) as i64; - let new_profit_avg = - (profit_avg * (avg_window as i64 - 1) + profit) / avg_window as i64; - - let da_p_comp = new_profit_avg / da_p_component; - let slope = new_profit_avg - profit_avg; + let da_p_comp = last_profit / da_p_component; + let slope = last_profit - last_last_profit; let da_d_comp = slope / da_d_component; let expected = starting_exec_gas_price as i64 + last_da_gas_price as i64 - da_p_comp - da_d_comp; @@ -84,8 +79,8 @@ fn calculate__positive_profit_decrease_gas_price() { let da_p_component = 100; let da_d_component = 10; let block_bytes = 500; - let profit_avg = 100; - let avg_window = 10; + let last_profit = 100; + let last_last_profit = 0; let arb_value = 1000; let larger_starting_reward = starting_cost + block_bytes * latest_gas_per_byte + arb_value; @@ -98,7 +93,9 @@ fn calculate__positive_profit_decrease_gas_price() { .with_known_total_cost(starting_cost) .with_projected_total_cost(starting_cost) .with_da_cost_per_byte(latest_gas_per_byte) - .with_profit_avg(profit_avg, avg_window) + .with_last_profit(last_profit, last_last_profit) + .with_da_max_change_percent(u8::MAX) + .with_exec_gas_price_change_percent(0) .build(); // when @@ -106,13 +103,8 @@ fn calculate__positive_profit_decrease_gas_price() { let actual = algo.calculate(block_bytes); // then - let profit = larger_starting_reward as i64 - - (starting_cost + block_bytes * latest_gas_per_byte) as i64; - let new_profit_avg = - (profit_avg * (avg_window as i64 - 1) + profit) / avg_window as i64; - - let da_p_comp = new_profit_avg / da_p_component; - let slope = new_profit_avg - profit_avg; + let da_p_comp = last_profit / da_p_component; + let slope = last_profit - last_last_profit; let da_d_comp = slope / da_d_component; let expected = starting_exec_gas_price as i64 + last_da_gas_price as i64 - da_p_comp - da_d_comp; @@ -129,8 +121,8 @@ fn calculate__price_does_not_decrease_more_than_max_percent() { let da_p_component = 100; let da_d_component = 10; let block_bytes = 500; - let profit_avg = 100; - let avg_window = 10; + let last_profit = 100000; // Large, positive profit to decrease da price + let last_last_profit = 0; let max_change_percent = 5; let arb_value = 1000; let larger_starting_reward = @@ -144,8 +136,8 @@ fn calculate__price_does_not_decrease_more_than_max_percent() { .with_known_total_cost(starting_cost) .with_projected_total_cost(starting_cost) .with_da_cost_per_byte(latest_gas_per_byte) - .with_profit_avg(profit_avg, avg_window) - .with_max_change_percent(max_change_percent) + .with_last_profit(last_profit, last_last_profit) + .with_da_max_change_percent(max_change_percent) .build(); // when @@ -159,19 +151,20 @@ fn calculate__price_does_not_decrease_more_than_max_percent() { assert_eq!(expected as u64, actual); } #[test] -fn calculate__price_does_not_increase_more_than_max_percent() { +fn calculate__da_price_does_not_increase_more_than_max_percent() { // given let starting_exec_gas_price = 100; let last_da_gas_price = 100; let starting_cost = 500; let latest_gas_per_byte = 10; - let da_p_component = 100; + let da_p_component = 1000; let da_d_component = 10; let block_bytes = 500; - let profit_avg = 100; - let avg_window = 10; + let last_profit = -1000000; // large, negative profit to increase da price + let last_last_profit = 0; let arb_value = 1000; - let max_change_percent = 5; + let max_da_change_percent = 5; + let max_exec_change_percent = 0; let smaller_starting_reward = starting_cost + block_bytes * latest_gas_per_byte - arb_value; let updater = UpdaterBuilder::new() @@ -183,8 +176,9 @@ fn calculate__price_does_not_increase_more_than_max_percent() { .with_known_total_cost(starting_cost) .with_projected_total_cost(starting_cost) .with_da_cost_per_byte(latest_gas_per_byte) - .with_profit_avg(profit_avg, avg_window) - .with_max_change_percent(max_change_percent) + .with_last_profit(last_profit, last_last_profit) + .with_da_max_change_percent(max_da_change_percent) + .with_exec_gas_price_change_percent(max_exec_change_percent) .build(); // when @@ -193,7 +187,7 @@ fn calculate__price_does_not_increase_more_than_max_percent() { // then let max_change = - (starting_exec_gas_price as f64 * max_change_percent as f64 / 100.0) as i64; + (last_da_gas_price as f64 * max_da_change_percent as f64 / 100.0) as i64; let expected = starting_exec_gas_price as i64 + last_da_gas_price as i64 + max_change; assert_eq!(expected as u64, actual); @@ -224,7 +218,7 @@ fn calculate__da_gas_price_never_drops_below_minimum() { .with_known_total_cost(starting_cost) .with_projected_total_cost(starting_cost) .with_da_cost_per_byte(latest_gas_per_byte) - .with_profit_avg(profit_avg, avg_window) + .with_last_profit(profit_avg, avg_window) .with_min_da_gas_price(min_da_gas_price) .build(); diff --git a/crates/fuel-gas-price-algorithm/src/v1/tests/update_l2_block_data_tests.rs b/crates/fuel-gas-price-algorithm/src/v1/tests/update_l2_block_data_tests.rs index 9a39e742718..7588554e1d5 100644 --- a/crates/fuel-gas-price-algorithm/src/v1/tests/update_l2_block_data_tests.rs +++ b/crates/fuel-gas-price-algorithm/src/v1/tests/update_l2_block_data_tests.rs @@ -254,14 +254,14 @@ fn update_l2_block_data__updates_last_da_gas_price() { } #[test] -fn update_l2_block_data__updates_profit_avg() { +fn update_l2_block_data__updates_last_and_last_last_profit() { // given - let starting_profit_avg = 200; - let avg_window = 10; + let last_last_profit = 0; let total_cost = 500; let total_rewards = 1000; + let last_profit = 200; let mut updater = UpdaterBuilder::new() - .with_profit_avg(starting_profit_avg, avg_window) + .with_last_profit(last_profit, last_last_profit) .with_total_rewards(total_rewards) .with_projected_total_cost(total_cost) .build(); @@ -278,9 +278,11 @@ fn update_l2_block_data__updates_profit_avg() { .unwrap(); // then - let last_profit = total_rewards as i64 - total_cost as i64; - let expected = - (starting_profit_avg * (avg_window as i64 - 1) + last_profit) / avg_window as i64; - let actual = updater.profit_avg; + let expected = last_profit; + let actual = updater.second_to_last_profit; + assert_eq!(actual, expected); + // and + let expected = total_rewards as i64 - total_cost as i64; + let actual = updater.last_profit; assert_eq!(actual, expected); } diff --git a/crates/metrics/src/p2p_metrics.rs b/crates/metrics/src/p2p_metrics.rs index b9123bed64b..a139cfb6ee3 100644 --- a/crates/metrics/src/p2p_metrics.rs +++ b/crates/metrics/src/p2p_metrics.rs @@ -1,16 +1,24 @@ use crate::global_registry; -use prometheus_client::metrics::counter::Counter; +use prometheus_client::metrics::{ + counter::Counter, + gauge::Gauge, +}; use std::sync::OnceLock; pub struct P2PMetrics { pub unique_peers: Counter, + pub blocks_requested: Gauge, } impl P2PMetrics { fn new() -> Self { let unique_peers = Counter::default(); + let blocks_requested = Gauge::default(); - let metrics = P2PMetrics { unique_peers }; + let metrics = P2PMetrics { + unique_peers, + blocks_requested, + }; let mut registry = global_registry().registry.lock(); registry.register( @@ -19,6 +27,12 @@ impl P2PMetrics { metrics.unique_peers.clone(), ); + registry.register( + "Blocks_Requested", + "A Gauge which keeps track of how many blocks were requested and served over the p2p req/res protocol", + metrics.blocks_requested.clone() + ); + metrics } } @@ -28,3 +42,11 @@ static P2P_METRICS: OnceLock = OnceLock::new(); pub fn p2p_metrics() -> &'static P2PMetrics { P2P_METRICS.get_or_init(P2PMetrics::new) } + +pub fn increment_unique_peers() { + p2p_metrics().unique_peers.inc(); +} + +pub fn set_blocks_requested(count: usize) { + p2p_metrics().blocks_requested.set(count as i64); +} diff --git a/crates/services/gas_price_service/src/fuel_gas_price_updater.rs b/crates/services/gas_price_service/src/fuel_gas_price_updater.rs index d3717916f92..69072e9033e 100644 --- a/crates/services/gas_price_service/src/fuel_gas_price_updater.rs +++ b/crates/services/gas_price_service/src/fuel_gas_price_updater.rs @@ -2,6 +2,8 @@ use crate::{ GasPriceAlgorithm, UpdateAlgorithm, }; +use anyhow::anyhow; +use core::num::NonZeroU64; use fuel_core_types::fuel_types::BlockHeight; pub use fuel_gas_price_algorithm::{ v0::{ @@ -14,48 +16,55 @@ pub use fuel_gas_price_algorithm::{ RecordedBlock, }, }; -use std::num::NonZeroU64; #[cfg(test)] mod tests; pub mod fuel_core_storage_adapter; +pub mod fuel_da_source_adapter; -pub struct FuelGasPriceUpdater { +pub struct FuelGasPriceUpdater { inner: AlgorithmUpdater, l2_block_source: L2, metadata_storage: Metadata, + #[allow(dead_code)] + da_source: DaSource, } #[derive(Debug, Clone, PartialEq)] pub enum AlgorithmUpdater { V0(AlgorithmUpdaterV0), + V1(AlgorithmUpdaterV1), } impl AlgorithmUpdater { pub fn algorithm(&self) -> Algorithm { match self { AlgorithmUpdater::V0(v0) => Algorithm::V0(v0.algorithm()), + AlgorithmUpdater::V1(v1) => Algorithm::V1(v1.algorithm()), } } pub fn l2_block_height(&self) -> BlockHeight { match self { AlgorithmUpdater::V0(v0) => v0.l2_block_height.into(), + AlgorithmUpdater::V1(v1) => v1.l2_block_height.into(), } } } -impl FuelGasPriceUpdater { +impl FuelGasPriceUpdater { pub fn new( inner: AlgorithmUpdater, l2_block_source: L2, metadata_storage: Metadata, + da_source: DaSource, ) -> Self { Self { inner, l2_block_source, metadata_storage, + da_source, } } } @@ -82,7 +91,7 @@ pub enum Error { CouldNotInitUpdater(anyhow::Error), } -pub type Result = std::result::Result; +pub type Result = core::result::Result; // Info required about the l2 block for the gas price algorithm #[derive(Debug, Clone, PartialEq)] @@ -104,6 +113,18 @@ pub trait L2BlockSource: Send + Sync { async fn get_l2_block(&mut self, height: BlockHeight) -> Result; } +#[derive(Debug, Default)] +pub struct DaCommitDetails { + pub l2_block_range: core::ops::Range, + pub blob_size_bytes: u32, + pub blob_cost_wei: u32, + pub partial_block_heights: Option<[u32; 2]>, +} + +pub trait DaCommitSource: Send + Sync { + fn get_da_commit_details(&mut self) -> Result>; +} + #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)] pub enum UpdaterMetadata { V0(V0Metadata), @@ -172,6 +193,9 @@ impl From for UpdaterMetadata { }; UpdaterMetadata::V0(metadata) } + AlgorithmUpdater::V1(_v1) => { + unimplemented!() // https://github.com/FuelLabs/fuel-core/issues/2140 + } } } } @@ -182,14 +206,16 @@ pub trait MetadataStorage: Send + Sync { fn set_metadata(&mut self, metadata: UpdaterMetadata) -> Result<()>; } -impl FuelGasPriceUpdater +impl FuelGasPriceUpdater where Metadata: MetadataStorage, + DaSource: DaCommitSource, { pub fn init( target_block_height: BlockHeight, l2_block_source: L2, metadata_storage: Metadata, + da_source: DaSource, min_exec_gas_price: u64, exec_gas_price_change_percent: u64, l2_block_fullness_threshold_percent: u64, @@ -216,16 +242,76 @@ where inner, l2_block_source, metadata_storage, + da_source, }; Ok(updater) } + + fn validate_block_gas_capacity( + &self, + block_gas_capacity: u64, + ) -> anyhow::Result { + NonZeroU64::new(block_gas_capacity) + .ok_or_else(|| anyhow!("Block gas capacity must be non-zero")) + } + + async fn set_metadata(&mut self) -> anyhow::Result<()> { + self.metadata_storage + .set_metadata(self.inner.clone().into()) + .map_err(|err| anyhow!(err)) + } + + async fn handle_normal_block( + &mut self, + height: u32, + gas_used: u64, + block_gas_capacity: u64, + ) -> anyhow::Result<()> { + let capacity = self.validate_block_gas_capacity(block_gas_capacity)?; + + match &mut self.inner { + AlgorithmUpdater::V0(updater) => { + updater.update_l2_block_data(height, gas_used, capacity)?; + } + AlgorithmUpdater::V1(_) => { + return Err(anyhow!("V1 of the gas price algo has not been enabled yet")) + // TODO(#2139): update the DA record data with data received from the source + // updater.update_da_record_data(vec![])?; + } + } + + self.set_metadata().await?; + Ok(()) + } + + async fn apply_block_info_to_gas_algorithm( + &mut self, + l2_block: BlockInfo, + ) -> anyhow::Result<()> { + match l2_block { + BlockInfo::GenesisBlock => { + self.set_metadata().await?; + } + BlockInfo::Block { + height, + gas_used, + block_gas_capacity, + } => { + self.handle_normal_block(height, gas_used, block_gas_capacity) + .await?; + } + } + Ok(()) + } } #[async_trait::async_trait] -impl UpdateAlgorithm for FuelGasPriceUpdater +impl UpdateAlgorithm + for FuelGasPriceUpdater where L2: L2BlockSource, Metadata: MetadataStorage + Send + Sync, + DaSource: DaCommitSource, { type Algorithm = Algorithm; @@ -240,25 +326,9 @@ where .await; tracing::info!("Received L2 block result: {:?}", l2_block_res); let l2_block = l2_block_res?; - let AlgorithmUpdater::V0(ref mut updater) = &mut self.inner; - match l2_block { - BlockInfo::GenesisBlock => { - self.metadata_storage - .set_metadata(self.inner.clone().into())?; - } - BlockInfo::Block { - height, - gas_used, - block_gas_capacity, - } => { - let capacity = NonZeroU64::new(block_gas_capacity).ok_or_else(|| { - anyhow::anyhow!("Block gas capacity must be non-zero") - })?; - updater.update_l2_block_data(height, gas_used, capacity)?; - self.metadata_storage - .set_metadata(self.inner.clone().into())?; - } - } + + self.apply_block_info_to_gas_algorithm(l2_block).await?; + Ok(self.inner.algorithm()) } } @@ -266,18 +336,21 @@ where #[derive(Debug, Clone, PartialEq)] pub enum Algorithm { V0(AlgorithmV0), + V1(AlgorithmV1), } impl GasPriceAlgorithm for Algorithm { fn next_gas_price(&self) -> u64 { match self { Algorithm::V0(v0) => v0.calculate(), + Algorithm::V1(v1) => v1.calculate(0), } } fn worst_case_gas_price(&self, height: BlockHeight) -> u64 { match self { Algorithm::V0(v0) => v0.worst_case(height.into()), + Algorithm::V1(v1) => v1.calculate(0), } } } diff --git a/crates/services/gas_price_service/src/fuel_gas_price_updater/fuel_da_source_adapter.rs b/crates/services/gas_price_service/src/fuel_gas_price_updater/fuel_da_source_adapter.rs new file mode 100644 index 00000000000..f9456643868 --- /dev/null +++ b/crates/services/gas_price_service/src/fuel_gas_price_updater/fuel_da_source_adapter.rs @@ -0,0 +1,16 @@ +use crate::fuel_gas_price_updater::{ + DaCommitDetails, + DaCommitSource, + Result as GasPriceUpdaterResult, +}; + +#[derive(Default, Clone)] +pub struct FuelDaSource; + +impl DaCommitSource for FuelDaSource { + fn get_da_commit_details( + &mut self, + ) -> GasPriceUpdaterResult> { + todo!() // TODO(#2139): pending research on how to get the data from the block committer + } +} diff --git a/crates/services/gas_price_service/src/fuel_gas_price_updater/tests.rs b/crates/services/gas_price_service/src/fuel_gas_price_updater/tests.rs index b922def6cec..3f64be6bebf 100644 --- a/crates/services/gas_price_service/src/fuel_gas_price_updater/tests.rs +++ b/crates/services/gas_price_service/src/fuel_gas_price_updater/tests.rs @@ -75,6 +75,30 @@ fn different_arb_metadata() -> UpdaterMetadata { }) } +#[derive(Default, Clone)] +struct FakeDaSource { + called: Arc>, +} + +impl FakeDaSource { + fn new() -> Self { + Self { + called: Arc::new(std::sync::Mutex::new(false)), + } + } + + fn was_called(&self) -> bool { + *self.called.lock().unwrap() + } +} + +impl DaCommitSource for FakeDaSource { + fn get_da_commit_details(&mut self) -> Result> { + *self.called.lock().unwrap() = true; + Ok(Some(DaCommitDetails::default())) + } +} + #[tokio::test] async fn next__fetches_l2_block() { // given @@ -90,10 +114,54 @@ async fn next__fetches_l2_block() { let metadata_storage = FakeMetadata::empty(); let starting_metadata = arb_metadata(); + let fake_da_source = FakeDaSource::new(); let mut updater = FuelGasPriceUpdater::new( starting_metadata.into(), l2_block_source, metadata_storage, + fake_da_source.clone(), + ); + + let start = updater.start(0.into()); + // when + let next = tokio::spawn(async move { updater.next().await }); + + l2_block_sender.send(l2_block).await.unwrap(); + let new = next.await.unwrap().unwrap(); + + // then + assert_ne!(start, new); + match start { + Algorithm::V0(_) => {} + Algorithm::V1(_) => { + assert!(fake_da_source.was_called()); + } + } +} + +#[tokio::test] +async fn next__new_l2_block_saves_old_metadata() { + // given + let l2_block = BlockInfo::Block { + height: 1, + gas_used: 60, + block_gas_capacity: 100, + }; + let (l2_block_sender, l2_block_receiver) = tokio::sync::mpsc::channel(1); + let l2_block_source = FakeL2BlockSource { + l2_block: l2_block_receiver, + }; + let metadata_inner = Arc::new(std::sync::Mutex::new(None)); + let metadata_storage = FakeMetadata { + inner: metadata_inner.clone(), + }; + + let starting_metadata = arb_metadata(); + let mut updater = FuelGasPriceUpdater::new( + starting_metadata.into(), + l2_block_source, + metadata_storage, + FakeDaSource::default(), ); let start = updater.start(0.into()); @@ -126,6 +194,7 @@ async fn init__if_exists_already_reload_old_values_with_overrides() { height, l2_block_source, metadata_storage, + FakeDaSource::default(), new_min_exec_gas_price, new_exec_gas_price_change_percent, new_l2_block_fullness_threshold_percent, @@ -158,6 +227,7 @@ async fn init__if_it_does_not_exist_fail() { height.into(), l2_block_source, metadata_storage, + FakeDaSource::default(), 0, 0, 0, @@ -166,48 +236,3 @@ async fn init__if_it_does_not_exist_fail() { // then assert!(matches!(res, Err(Error::CouldNotInitUpdater(_)))); } - -#[tokio::test] -async fn next__new_l2_block_saves_old_metadata() { - // given - let l2_block = BlockInfo::Block { - height: 1, - gas_used: 60, - block_gas_capacity: 100, - }; - let (l2_block_sender, l2_block_receiver) = tokio::sync::mpsc::channel(1); - let l2_block_source = FakeL2BlockSource { - l2_block: l2_block_receiver, - }; - let metadata_inner = Arc::new(std::sync::Mutex::new(None)); - let metadata_storage = FakeMetadata { - inner: metadata_inner.clone(), - }; - - let starting_metadata = arb_metadata(); - let mut updater = FuelGasPriceUpdater::new( - starting_metadata.clone().into(), - l2_block_source, - metadata_storage, - ); - - // when - let next = tokio::spawn(async move { updater.next().await }); - let actual = metadata_inner.lock().unwrap().clone(); - assert_eq!(None, actual); - l2_block_sender.send(l2_block.clone()).await.unwrap(); - let _ = next.await.unwrap().unwrap(); - - // then - let UpdaterMetadata::V0(old_inner) = starting_metadata; - let new_exec_price = old_inner.new_exec_price - + (old_inner.new_exec_price * old_inner.exec_gas_price_change_percent / 100); - let l2_block_height = old_inner.l2_block_height + 1; - let expected = UpdaterMetadata::V0(V0Metadata { - new_exec_price, - l2_block_height, - ..old_inner - }); - let actual = metadata_inner.lock().unwrap().clone().unwrap(); - assert_eq!(expected, actual); -} diff --git a/crates/services/p2p/src/p2p_service.rs b/crates/services/p2p/src/p2p_service.rs index 41ef9fb8109..e1afcad3a60 100644 --- a/crates/services/p2p/src/p2p_service.rs +++ b/crates/services/p2p/src/p2p_service.rs @@ -35,7 +35,7 @@ use crate::{ }, TryPeerId, }; -use fuel_core_metrics::p2p_metrics::p2p_metrics; +use fuel_core_metrics::p2p_metrics::increment_unique_peers; use fuel_core_types::{ fuel_types::BlockHeight, services::p2p::peer_reputation::AppScore, @@ -271,6 +271,15 @@ impl FuelP2PService { } } + pub fn update_metrics(&self, update_fn: T) + where + T: FnOnce(), + { + if self.metrics { + update_fn(); + } + } + #[cfg(feature = "test-helpers")] pub fn multiaddrs(&self) -> Vec { let local_peer = self.local_peer_id; @@ -644,9 +653,7 @@ impl FuelP2PService { fn handle_identify_event(&mut self, event: identify::Event) -> Option { match event { identify::Event::Received { peer_id, info } => { - if self.metrics { - p2p_metrics().unique_peers.inc(); - } + self.update_metrics(increment_unique_peers); let mut addresses = info.listen_addrs; let agent_version = info.agent_version; diff --git a/crates/services/p2p/src/service.rs b/crates/services/p2p/src/service.rs index f0b2be9f437..bf875289743 100644 --- a/crates/services/p2p/src/service.rs +++ b/crates/services/p2p/src/service.rs @@ -26,6 +26,7 @@ use crate::{ }, }; use anyhow::anyhow; +use fuel_core_metrics::p2p_metrics::set_blocks_requested; use fuel_core_services::{ stream::BoxStream, RunnableService, @@ -196,9 +197,20 @@ pub trait TaskP2PService: Send { ) -> anyhow::Result<()>; fn update_block_height(&mut self, height: BlockHeight) -> anyhow::Result<()>; + + fn update_metrics(&self, update_fn: T) + where + T: FnOnce(); } impl TaskP2PService for FuelP2PService { + fn update_metrics(&self, update_fn: T) + where + T: FnOnce(), + { + FuelP2PService::update_metrics(self, update_fn) + } + fn get_all_peer_info(&self) -> Vec<(&PeerId, &PeerInfo)> { self.peer_manager().get_all_peers().collect() } @@ -427,6 +439,13 @@ where V: AtomicView + 'static, V::LatestView: P2pDb, { + fn update_metrics(&self, update_fn: T) + where + T: FnOnce(), + { + self.p2p_service.update_metrics(update_fn) + } + fn process_request( &mut self, request_message: RequestMessage, @@ -464,8 +483,11 @@ where // If there are other types of data we send over p2p req/res protocol, then this needs // to be generalized let max_len = self.max_headers_per_request; + let range_len = range.len(); + + self.update_metrics(|| set_blocks_requested(range_len)); - if range.len() > max_len { + if range_len > max_len { tracing::error!( requested_length = range.len(), max_len, @@ -1031,6 +1053,13 @@ pub mod tests { } impl TaskP2PService for FakeP2PService { + fn update_metrics(&self, _: T) + where + T: FnOnce(), + { + unimplemented!() + } + fn get_all_peer_info(&self) -> Vec<(&PeerId, &PeerInfo)> { self.peer_info.iter().map(|tup| (&tup.0, &tup.1)).collect() }