diff --git a/Cargo.lock b/Cargo.lock index ac36c5654..482c458be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,9 +67,9 @@ checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anyhow" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "arrayref" @@ -140,9 +140,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" -version = "0.7.7" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core", @@ -164,7 +164,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tokio", "tower 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -187,7 +187,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tower-layer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "tracing", @@ -277,9 +277,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7" +checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e" dependencies = [ "arrayref", "arrayvec", @@ -299,9 +299,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" +checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" dependencies = [ "borsh-derive", "cfg_aliases", @@ -309,16 +309,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" +checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", "syn", - "syn_derive", ] [[package]] @@ -329,9 +328,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" dependencies = [ "bytemuck_derive", ] @@ -370,9 +369,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.31" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" dependencies = [ "shlex", ] @@ -430,9 +429,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -440,9 +439,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstyle", "clap_lex", @@ -462,9 +461,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" [[package]] name = "const_format" @@ -494,9 +493,9 @@ checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "core-foundation" -version = "0.9.4" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" dependencies = [ "core-foundation-sys", "libc", @@ -510,9 +509,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -799,6 +798,43 @@ dependencies = [ name = "cuprate-constants" version = "0.1.0" +[[package]] +name = "cuprate-criterion-blockchain" +version = "0.0.0" +dependencies = [ + "criterion", + "cuprate-blockchain", + "cuprate-helper", + "cuprate-test-utils", + "cuprate-types", + "function_name", + "rand", + "serde_json", + "tempfile", +] + +[[package]] +name = "cuprate-criterion-cryptonight" +version = "0.0.0" +dependencies = [ + "criterion", + "cuprate-cryptonight", + "function_name", +] + +[[package]] +name = "cuprate-criterion-database" +version = "0.0.0" +dependencies = [ + "criterion", + "cuprate-blockchain", + "cuprate-database", + "cuprate-helper", + "function_name", + "rand", + "tempfile", +] + [[package]] name = "cuprate-criterion-example" version = "0.0.0" @@ -808,6 +844,19 @@ dependencies = [ "serde_json", ] +[[package]] +name = "cuprate-criterion-helper" +version = "0.0.0" +dependencies = [ + "criterion", + "cuprate-constants", + "cuprate-helper", + "cuprate-test-utils", + "function_name", + "monero-serai", + "serde_json", +] + [[package]] name = "cuprate-criterion-json-rpc" version = "0.0.0" @@ -818,6 +867,19 @@ dependencies = [ "serde_json", ] +[[package]] +name = "cuprate-criterion-rpc-types" +version = "0.0.0" +dependencies = [ + "criterion", + "cuprate-epee-encoding", + "cuprate-rpc-types", + "cuprate-test-utils", + "function_name", + "paste", + "serde_json", +] + [[package]] name = "cuprate-cryptonight" version = "0.1.0" @@ -1345,6 +1407,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "doxygen-rs" version = "0.4.2" @@ -1378,9 +1451,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "ff" @@ -1401,9 +1474,9 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "flate2" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -1584,9 +1657,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", "bytes", @@ -1622,9 +1695,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" @@ -1676,6 +1749,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -1739,9 +1818,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", @@ -1818,14 +1897,143 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", ] [[package]] @@ -1835,16 +2043,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.2", ] [[package]] name = "is-terminal" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" dependencies = [ - "hermit-abi", + "hermit-abi 0.4.0", "libc", "windows-sys 0.52.0", ] @@ -1860,9 +2068,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jh" @@ -1901,9 +2109,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.161" +version = "0.2.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" [[package]] name = "libm" @@ -1927,6 +2135,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lmdb-master-sys" version = "0.2.4" @@ -2018,7 +2232,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "wasi", "windows-sys 0.52.0", @@ -2220,9 +2434,9 @@ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "openssl-probe" @@ -2363,9 +2577,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "plotters" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -2376,15 +2590,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] @@ -2417,34 +2631,11 @@ dependencies = [ "toml_edit", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -2631,13 +2822,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.7", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -2652,9 +2843,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -2705,9 +2896,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.38" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -2718,9 +2909,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.16" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "log", "once_cell", @@ -2733,26 +2924,16 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" dependencies = [ "openssl-probe", - "rustls-pemfile", "rustls-pki-types", "schannel", "security-framework", ] -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "rustls-pki-types" version = "1.10.0" @@ -2805,9 +2986,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys 0.59.0", ] @@ -2820,9 +3001,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.11.1" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +checksum = "e1415a607e92bec364ea2cf9264646dcce0f91e6d65281bd6f2819cca3bf39c8" dependencies = [ "bitflags 2.6.0", "core-foundation", @@ -2833,9 +3014,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", @@ -2855,9 +3036,9 @@ checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" [[package]] name = "serde" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -2873,9 +3054,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -2884,9 +3065,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -3021,6 +3202,12 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "std-shims" version = "0.1.1" @@ -3060,27 +3247,15 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.86" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89275301d38033efb81a6e60e3497e734dfcc62571f2854bf4b16690398824c" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "sync_wrapper" version = "0.1.2" @@ -3089,9 +3264,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" [[package]] name = "synchronoise" @@ -3102,6 +3277,17 @@ dependencies = [ "crossbeam-queue", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tap" version = "1.0.1" @@ -3110,9 +3296,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -3123,18 +3309,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.66" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d171f59dbaa811dbbb1aee1e73db92ec2b122911a48e1390dfe327a821ddede" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.66" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b08be0f17bd307950653ce45db00cd31200d82b624b36e181337d9c7d92765b5" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", @@ -3158,35 +3344,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a693d0c8cf16973fac5a93fbe47b8c6452e7097d4fcac49f3d7a18e39c76e62e" [[package]] -name = "tinytemplate" -version = "1.2.1" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "serde", - "serde_json", + "displaydoc", + "zerovec", ] [[package]] -name = "tinyvec" -version = "1.8.0" +name = "tinytemplate" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" dependencies = [ - "tinyvec_macros", + "serde", + "serde_json", ] -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" -version = "1.41.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -3335,9 +3516,9 @@ source = "git+https://github.com/Cuprate/tower.git?rev=6c7faf0#6c7faf0e9dbc74aef [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -3347,9 +3528,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -3358,9 +3539,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -3413,26 +3594,11 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" -[[package]] -name = "unicode-bidi" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" - [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-xid" @@ -3466,15 +3632,27 @@ dependencies = [ [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "valuable" version = "0.1.0" @@ -3578,9 +3756,9 @@ checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -3588,9 +3766,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.6" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ "rustls-pki-types", ] @@ -3613,11 +3791,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3856,6 +4034,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wyz" version = "0.5.1" @@ -3871,6 +4061,30 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -3892,6 +4106,27 @@ dependencies = [ "syn", ] +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.1" @@ -3911,3 +4146,25 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 3cc3ab18d..613385cd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,11 @@ members = [ "benches/benchmark/example", "benches/criterion/example", "benches/criterion/cuprate-json-rpc", + "benches/criterion/cuprate-helper", + "benches/criterion/cuprate-database", + "benches/criterion/cuprate-cryptonight", + "benches/criterion/cuprate-rpc-types", + "benches/criterion/cuprate-blockchain", # Consensus "consensus", diff --git a/benches/benchmark/bin/Cargo.toml b/benches/benchmark/bin/Cargo.toml index 36d0b2c74..22f221618 100644 --- a/benches/benchmark/bin/Cargo.toml +++ b/benches/benchmark/bin/Cargo.toml @@ -40,4 +40,4 @@ tracing-subscriber = { workspace = true, features = ["fmt", "std", "env-filter"] [dev-dependencies] [lints] -workspace = true \ No newline at end of file +workspace = true diff --git a/benches/criterion/cuprate-blockchain/Cargo.toml b/benches/criterion/cuprate-blockchain/Cargo.toml new file mode 100644 index 000000000..585bf7e35 --- /dev/null +++ b/benches/criterion/cuprate-blockchain/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "cuprate-criterion-blockchain" +version = "0.0.0" +edition = "2021" +description = "Criterion benchmarking for cuprate-blockchain" +license = "MIT" +authors = ["hinto-janai"] +repository = "https://github.com/Cuprate/cuprate/tree/main/benches/criterion/cuprate-blockchain" +keywords = ["cuprate", "blockchain", "criterion", "benchmark"] + +[dependencies] +cuprate-blockchain = { workspace = true } +cuprate-test-utils = { workspace = true } +cuprate-types = { workspace = true, default-features = false } +cuprate-helper = { workspace = true, features = ["cast"] } + +criterion = { workspace = true } +function_name = { workspace = true } +serde_json = { workspace = true, features = ["default"] } +tempfile = { workspace = true } +rand = { workspace = true } + +[[bench]] +name = "main" +harness = false + +[lints] +workspace = true diff --git a/benches/criterion/cuprate-blockchain/benches/block.rs b/benches/criterion/cuprate-blockchain/benches/block.rs new file mode 100644 index 000000000..4a2bd885e --- /dev/null +++ b/benches/criterion/cuprate-blockchain/benches/block.rs @@ -0,0 +1,140 @@ +//! Benchmarks for [`block`] and [`alt_block`] functions. + +#![allow(unused_attributes, unused_crate_dependencies)] + +use std::{num::NonZeroU64, time::Instant}; + +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use cuprate_helper::cast::usize_to_u64; +use function_name::named; + +use cuprate_blockchain::{ + cuprate_database::{Env, EnvInner}, + ops::{alt_block, block}, + tables::OpenTables, +}; +use cuprate_test_utils::data::{BLOCK_V16_TX0, BLOCK_V1_TX2, BLOCK_V9_TX3}; +use cuprate_types::{AltBlockInformation, ChainId, VerifiedBlockInformation}; + +use cuprate_criterion_blockchain::generate_fake_blocks; + +criterion_group! { + name = benches; + config = Criterion::default(); + targets = + add_block_v1_tx2, + add_block_v9_tx3, + add_block_v16_tx0, + add_alt_block_v1_tx2, + add_alt_block_v9_tx3, + add_alt_block_v16_tx0, +} +criterion_main!(benches); + +/// Inner function for benchmarking [`block::add_block`]. +#[expect(clippy::significant_drop_tightening)] +fn add_block_inner(c: &mut Criterion, function_name: &str, block: &VerifiedBlockInformation) { + let env = cuprate_criterion_blockchain::TmpEnv::new(); + + c.bench_function(function_name, |b| { + // We use `iter_custom` because we need to generate an + // appropriate amount of blocks and only time the `add_block`. + b.iter_custom(|count| { + let blocks = black_box(generate_fake_blocks(block, count)); + + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let mut tables = env_inner.open_tables_mut(&tx_rw).unwrap(); + + let start = Instant::now(); + for block in &blocks { + let block = black_box(block); + black_box(block::add_block(block, &mut tables)).unwrap(); + } + start.elapsed() + }); + }); +} + +#[named] +fn add_block_v1_tx2(c: &mut Criterion) { + add_block_inner(c, function_name!(), &BLOCK_V1_TX2); +} + +#[named] +fn add_block_v9_tx3(c: &mut Criterion) { + add_block_inner(c, function_name!(), &BLOCK_V9_TX3); +} + +#[named] +fn add_block_v16_tx0(c: &mut Criterion) { + add_block_inner(c, function_name!(), &BLOCK_V16_TX0); +} + +/// Inner function for benchmarking [`alt_block::add_alt_block`]. +#[expect(clippy::significant_drop_tightening)] +fn add_alt_block_inner(c: &mut Criterion, function_name: &str, block: &VerifiedBlockInformation) { + let env = cuprate_criterion_blockchain::TmpEnv::new(); + + // We must have at least 1 block or else `add_alt_block` will panic. + { + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let mut tables = env_inner.open_tables_mut(&tx_rw).unwrap(); + + let mut block = BLOCK_V1_TX2.clone(); + block.height = 0; + + block::add_block(&block, &mut tables).unwrap(); + } + + c.bench_function(function_name, |b| { + // We use `iter_custom` because we need to generate an + // appropriate amount of blocks and only time the `add_block`. + b.iter_custom(|count| { + // Map the block to a fake alt block. + let blocks = generate_fake_blocks(block, count) + .into_iter() + .enumerate() + .map(|(i, b)| AltBlockInformation { + block: b.block, + block_blob: b.block_blob, + txs: b.txs, + block_hash: b.block_hash, + pow_hash: b.pow_hash, + height: b.height + 1, + weight: b.weight, + long_term_weight: b.long_term_weight, + cumulative_difficulty: b.cumulative_difficulty, + chain_id: ChainId(NonZeroU64::new(usize_to_u64(i) + 1).unwrap()), + }) + .collect::>(); + + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let mut tables = env_inner.open_tables_mut(&tx_rw).unwrap(); + + let start = Instant::now(); + for block in &blocks { + let block = black_box(block); + black_box(alt_block::add_alt_block(block, &mut tables)).unwrap(); + } + start.elapsed() + }); + }); +} + +#[named] +fn add_alt_block_v1_tx2(c: &mut Criterion) { + add_alt_block_inner(c, function_name!(), &BLOCK_V1_TX2); +} + +#[named] +fn add_alt_block_v9_tx3(c: &mut Criterion) { + add_alt_block_inner(c, function_name!(), &BLOCK_V9_TX3); +} + +#[named] +fn add_alt_block_v16_tx0(c: &mut Criterion) { + add_alt_block_inner(c, function_name!(), &BLOCK_V16_TX0); +} diff --git a/benches/criterion/cuprate-blockchain/benches/main.rs b/benches/criterion/cuprate-blockchain/benches/main.rs new file mode 100644 index 000000000..daa06c1da --- /dev/null +++ b/benches/criterion/cuprate-blockchain/benches/main.rs @@ -0,0 +1,7 @@ +#![allow(unused_crate_dependencies)] + +mod block; + +criterion::criterion_main! { + block::benches, +} diff --git a/benches/criterion/cuprate-blockchain/src/blocks.rs b/benches/criterion/cuprate-blockchain/src/blocks.rs new file mode 100644 index 000000000..a5629af40 --- /dev/null +++ b/benches/criterion/cuprate-blockchain/src/blocks.rs @@ -0,0 +1,36 @@ +use rand::Rng; + +use cuprate_helper::cast::u64_to_usize; +use cuprate_types::VerifiedBlockInformation; + +/// Generate fake [`VerifiedBlockInformation`]s. +/// +/// This function generates fake blocks, +/// cloning the `base` block `count` amount of times, +/// starting at height `0` and sequentially incrementing, +/// i.e. block height `{0,1,2,...}`. +/// +/// Each block has a random [`VerifiedBlockInformation::block_hash`]. +/// +/// # Hack +/// This is used for these benchmarks because +/// [`cuprate_blockchain::ops::block::add_block`] +/// asserts that blocks with non-sequential heights cannot be added. +/// To get around this, we manually edit the block heights. +/// +/// The hash must also be faked as +/// [`cuprate_blockchain::ops::blockchain::chain_height`] +/// which is used for an [`assert`] relies on the `hash -> height` table. +pub fn generate_fake_blocks( + base: &VerifiedBlockInformation, + count: u64, +) -> Vec { + (0..count) + .map(|height| { + let mut block = base.clone(); + block.height = u64_to_usize(height); + block.block_hash = rand::thread_rng().r#gen(); + block + }) + .collect() +} diff --git a/benches/criterion/cuprate-blockchain/src/lib.rs b/benches/criterion/cuprate-blockchain/src/lib.rs new file mode 100644 index 000000000..8687f45ed --- /dev/null +++ b/benches/criterion/cuprate-blockchain/src/lib.rs @@ -0,0 +1,7 @@ +#![allow(unused_crate_dependencies, reason = "used in benchmarks")] + +mod blocks; +mod tmp_env; + +pub use blocks::generate_fake_blocks; +pub use tmp_env::TmpEnv; diff --git a/benches/criterion/cuprate-blockchain/src/tmp_env.rs b/benches/criterion/cuprate-blockchain/src/tmp_env.rs new file mode 100644 index 000000000..147705db3 --- /dev/null +++ b/benches/criterion/cuprate-blockchain/src/tmp_env.rs @@ -0,0 +1,53 @@ +//! An [`Env`] inside a [`TempDir`]. + +use tempfile::TempDir; + +use cuprate_blockchain::{ + config::ReaderThreads, + cuprate_database::{config::ConfigBuilder, resize::PAGE_SIZE, ConcreteEnv, Env}, +}; + +/// A temporary in-memory [`Env`]. +/// +/// This is a [`ConcreteEnv`] that uses [`TempDir`] as the +/// backing file location - this is an in-memory file on Linux. +pub struct TmpEnv { + pub env: ConcreteEnv, + pub tempdir: TempDir, +} + +impl Default for TmpEnv { + fn default() -> Self { + Self::new() + } +} + +impl TmpEnv { + /// Create an `Env` in a temporary directory. + /// + /// The directory is automatically removed after the [`TempDir`] is dropped. + #[expect(clippy::missing_panics_doc)] + pub fn new() -> Self { + let tempdir = tempfile::tempdir().unwrap(); + let path = tempdir.path().to_path_buf().into(); + let db_config = ConfigBuilder::new(path).low_power().build(); + let reader_threads = ReaderThreads::One; + let config = cuprate_blockchain::config::Config { + db_config, + reader_threads, + }; + let env = cuprate_blockchain::open(config).unwrap(); + + // Resize to a very large map to prevent resize errors. + if ConcreteEnv::MANUAL_RESIZE { + // SAFETY: no write transactions exist yet. + unsafe { + env.env_inner() + .resize(PAGE_SIZE.get() * 1024 * 1024 * 1024) + .unwrap(); + } + } + + Self { env, tempdir } + } +} diff --git a/benches/criterion/cuprate-cryptonight/Cargo.toml b/benches/criterion/cuprate-cryptonight/Cargo.toml new file mode 100644 index 000000000..21e4d9251 --- /dev/null +++ b/benches/criterion/cuprate-cryptonight/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "cuprate-criterion-cryptonight" +version = "0.0.0" +edition = "2021" +description = "Criterion benchmarking for cuprate-cryptonight" +license = "MIT" +authors = ["hinto-janai"] +repository = "https://github.com/Cuprate/cuprate/tree/main/benches/criterion/cuprate-cryptonight" +keywords = ["cuprate", "cryptonight", "criterion", "benchmark"] + +[dependencies] +cuprate-cryptonight = { workspace = true } + +criterion = { workspace = true } +function_name = { workspace = true } + +[[bench]] +name = "main" +harness = false + +[lints] +workspace = true \ No newline at end of file diff --git a/benches/criterion/cuprate-cryptonight/benches/hash.rs b/benches/criterion/cuprate-cryptonight/benches/hash.rs new file mode 100644 index 000000000..13dd90697 --- /dev/null +++ b/benches/criterion/cuprate-cryptonight/benches/hash.rs @@ -0,0 +1,92 @@ +//! Benchmarks for [`Response`]. +#![allow(unused_attributes, unused_crate_dependencies, dropping_copy_types)] + +use std::time::Duration; + +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use function_name::named; + +use cuprate_cryptonight::{ + cryptonight_hash_r, cryptonight_hash_v0, cryptonight_hash_v1, cryptonight_hash_v2, +}; + +criterion_group! { + name = benches; + // Criterion suggests that higher measurement time is required for these hash functions. + config = Criterion::default().measurement_time(Duration::from_secs(8)); + targets = + r_8, r_64, r_512, r_4096, r_65536, + v0_8, v0_64, v0_512, v0_4096, v0_65536, + v1_8, v1_64, v1_512, v1_4096, v1_65536, + v2_8, v2_64, v2_512, v2_4096, v2_65536, +} + +criterion_main!(benches); + +/// Generate the benchmark functions for the cryptonight hash functions. +macro_rules! impl_hash_benchmark { + ($( + // The actual hash function. + $hash_fn:ident { + // Inside these braces: + // - The name of the benchmark function + // - The input(s) to the hash function for that benchmark function + $( + $fn_name:ident => ($($input:expr_2021),* $(,)?) + ),* $(,)? + } + )*) => { + $( + $( + #[named] + fn $fn_name(c: &mut Criterion) { + c.bench_function(function_name!(), |b| { + b.iter(|| { + drop( + black_box( + $hash_fn( + $(black_box($input)),* + ) + ) + ); + }); + }); + } + )* + )* + }; +} + +impl_hash_benchmark! { + cryptonight_hash_r { + r_8 => (&[3; 8], 500_000), + r_64 => (&[3; 64], 500_000), + r_512 => (&[3; 512], 500_000), + r_4096 => (&[3; 4096], 500_000), + r_65536 => (&[3; 65536], 500_000), + } + + cryptonight_hash_v0 { + v0_8 => (&[3; 8]), + v0_64 => (&[3; 64]), + v0_512 => (&[3; 512]), + v0_4096 => (&[3; 4096]), + v0_65536 => (&[3; 65536]), + } + + cryptonight_hash_v1 { + v1_8 => (&[3; 8]), + v1_64 => (&[3; 64]), + v1_512 => (&[3; 512]), + v1_4096 => (&[3; 4096]), + v1_65536 => (&[3; 65536]), + } + + cryptonight_hash_v2 { + v2_8 => (&[3; 8]), + v2_64 => (&[3; 64]), + v2_512 => (&[3; 512]), + v2_4096 => (&[3; 4096]), + v2_65536 => (&[3; 65536]), + } +} diff --git a/benches/criterion/cuprate-cryptonight/benches/main.rs b/benches/criterion/cuprate-cryptonight/benches/main.rs new file mode 100644 index 000000000..79ce94001 --- /dev/null +++ b/benches/criterion/cuprate-cryptonight/benches/main.rs @@ -0,0 +1,8 @@ +//! Benchmarks for `cuprate-cryptonight`. +#![allow(unused_crate_dependencies)] + +mod hash; + +criterion::criterion_main! { + hash::benches +} diff --git a/benches/criterion/cuprate-cryptonight/src/lib.rs b/benches/criterion/cuprate-cryptonight/src/lib.rs new file mode 100644 index 000000000..d8b24aedf --- /dev/null +++ b/benches/criterion/cuprate-cryptonight/src/lib.rs @@ -0,0 +1,2 @@ +//! Benchmark lib for `cuprate-cryptonight`. +#![allow(unused_crate_dependencies, reason = "used in benchmarks")] diff --git a/benches/criterion/cuprate-database/Cargo.toml b/benches/criterion/cuprate-database/Cargo.toml new file mode 100644 index 000000000..c8248537c --- /dev/null +++ b/benches/criterion/cuprate-database/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "cuprate-criterion-database" +version = "0.0.0" +edition = "2021" +description = "Criterion benchmarking for cuprate-database" +license = "MIT" +authors = ["hinto-janai"] +repository = "https://github.com/Cuprate/cuprate/tree/main/benches/criterion/cuprate-database" +keywords = ["cuprate", "database", "benchmark"] + +[features] +default = ["heed"] +heed = ["cuprate-database/heed", "cuprate-blockchain/heed"] +redb = ["cuprate-database/redb", "cuprate-blockchain/redb"] + +[dependencies] +# FIXME: +# Some crates/features that are unused here but +# needed in other crates are pulled in, see: +# - +# +# Remove: +# - rand +# - cuprate-blockchain/asynch +# - cuprate-blockchain/tx + +cuprate-database = { workspace = true } +cuprate-blockchain = { workspace = true } +cuprate-helper = { workspace = true, features = ["asynch", "fs", "thread", "tx"] } + +criterion = { workspace = true } +function_name = { workspace = true } +tempfile = { workspace = true } +rand = { workspace = true, features = ["std", "std_rng"] } + +[[bench]] +name = "main" +harness = false + +[lints] +workspace = true \ No newline at end of file diff --git a/benches/criterion/cuprate-database/README.md b/benches/criterion/cuprate-database/README.md new file mode 100644 index 000000000..6e8314f5a --- /dev/null +++ b/benches/criterion/cuprate-database/README.md @@ -0,0 +1,48 @@ +# `cuprate-database-benchmark` +This is a benchmarking suite that allows testing/benchmarking `cuprate-database` with [`criterion`](https://bheisler.github.io/criterion.rs/book/criterion_rs.html). + +For more information on `cargo bench` and `criterion`: +- https://doc.rust-lang.org/cargo/commands/cargo-bench.html +- https://bheisler.github.io/criterion.rs/book/criterion_rs.html + + +1. [Usage](#Usage) +1. [File Structure](#file-structure) + - [`src/`](#src) + - [`benches/`](#benches) + +# Usage +Ensure the system is as quiet as possible (no background tasks) before starting and during the benchmarks. + +To start all benchmarks, run: +```bash +cargo bench --package cuprate-database-benchmarks +``` + +# File Structure +A quick reference of the structure of the folders & files in `cuprate-database`. + +Note that `lib.rs/mod.rs` files are purely for re-exporting/visibility/lints, and contain no code. Each sub-directory has a corresponding `mod.rs`. + +## `src/` +The top-level `src/` files. + +The actual `cuprate-database-benchmark` library crate is just used as a helper for the benchmarks within `benches/`. + +| File | Purpose | +|---------------------|---------| +| `helper.rs` | Helper functions + +## `benches/` +The actual benchmarks. + +Each file represents some logical benchmark grouping. + +| File | Purpose | +|-----------------------|---------| +| `db.rs` | `trait Database{Ro,Rw,Iter}` benchmarks +| `db_multi_thread.rs` | Same as `db.rs` but multi-threaded +| `env.rs` | `trait {Env, EnvInner, TxR{o,w}, Tables[Mut]}` benchmarks +| `env_multi_thread.rs` | Same as `env.rs` but multi-threaded +| `service.rs` | `cuprate_database::service` benchmarks +| `storable.rs` | `trait Storable` benchmarks \ No newline at end of file diff --git a/benches/criterion/cuprate-database/benches/db.rs b/benches/criterion/cuprate-database/benches/db.rs new file mode 100644 index 000000000..e0d4945d1 --- /dev/null +++ b/benches/criterion/cuprate-database/benches/db.rs @@ -0,0 +1,444 @@ +//! Database operations. +//! +//! This module tests the functions from: +//! - [`cuprate_database::DatabaseRo`] +//! - [`cuprate_database::DatabaseRw`] +//! - [`cuprate_database::DatabaseIter`] + +#![allow(unused_crate_dependencies, unused_attributes)] +#![expect(clippy::significant_drop_tightening)] + +use std::time::Instant; + +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use function_name::named; + +use cuprate_blockchain::{ + tables::Outputs, + types::{Output, PreRctOutputId}, +}; +use cuprate_database::{DatabaseIter, DatabaseRo, DatabaseRw, Env, EnvInner}; + +use cuprate_criterion_database::{TmpEnv, KEY, VALUE}; + +criterion_group! { + name = benches; + config = Criterion::default(); + targets = + // `DatabaseRo` + ro_get, + ro_len, + ro_first, + ro_last, + ro_is_empty, + ro_contains, + + // `DatabaseRo` with a `TxRw` + rw_get, + rw_len, + rw_first, + rw_last, + rw_is_empty, + rw_contains, + + // `DatabaseIter` + get_range, + iter, + keys, + values, + + // `DatabaseRw` + put, + delete, + pop_first, + pop_last, + take, +} +criterion_main!(benches); + +//---------------------------------------------------------------------------------------------------- DatabaseRo +// Read-only table operations. +// This uses `TxRw + TablesMut` briefly to insert values, then +// uses `TxRo + Tables` for the actual operation. +// +// See further below for using `TxRw + TablesMut` on the same operations. + +/// [`DatabaseRo::get`] +#[named] +fn ro_get(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_ro = env_inner.tx_ro().unwrap(); + let table = env_inner.open_db_ro::(&tx_ro).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let _: Output = table.get(black_box(&KEY)).unwrap(); + }); + }); +} + +/// [`DatabaseRo::len`] +#[named] +fn ro_len(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_ro = env_inner.tx_ro().unwrap(); + let table = env_inner.open_db_ro::(&tx_ro).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + black_box(table.len()).unwrap(); + }); + }); +} + +/// [`DatabaseRo::first`] +#[named] +fn ro_first(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_ro = env_inner.tx_ro().unwrap(); + let table = env_inner.open_db_ro::(&tx_ro).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let (_, _): (PreRctOutputId, Output) = black_box(table.first()).unwrap(); + }); + }); +} + +/// [`DatabaseRo::last`] +#[named] +fn ro_last(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_ro = env_inner.tx_ro().unwrap(); + let table = env_inner.open_db_ro::(&tx_ro).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let (_, _): (PreRctOutputId, Output) = black_box(table.last()).unwrap(); + }); + }); +} + +/// [`DatabaseRo::is_empty`] +#[named] +fn ro_is_empty(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_ro = env_inner.tx_ro().unwrap(); + let table = env_inner.open_db_ro::(&tx_ro).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + black_box(table.is_empty()).unwrap(); + }); + }); +} + +/// [`DatabaseRo::contains`] +#[named] +fn ro_contains(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_ro = env_inner.tx_ro().unwrap(); + let table = env_inner.open_db_ro::(&tx_ro).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + table.contains(black_box(&KEY)).unwrap(); + }); + }); +} + +//---------------------------------------------------------------------------------------------------- DatabaseRo (TxRw) +// These are the same benchmarks as above, but it uses a +// `TxRw` and a `TablesMut` instead to ensure our read/write tables +// using read operations perform the same as normal read-only tables. + +/// [`DatabaseRw::get`] +#[named] +fn rw_get(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let _: Output = table.get(black_box(&KEY)).unwrap(); + }); + }); +} + +/// [`DatabaseRw::len`] +#[named] +fn rw_len(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + black_box(table.len()).unwrap(); + }); + }); +} + +/// [`DatabaseRw::first`] +#[named] +fn rw_first(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let (_, _): (PreRctOutputId, Output) = black_box(table.first()).unwrap(); + }); + }); +} + +/// [`DatabaseRw::last`] +#[named] +fn rw_last(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let (_, _): (PreRctOutputId, Output) = black_box(table.last()).unwrap(); + }); + }); +} + +/// [`DatabaseRw::is_empty`] +#[named] +fn rw_is_empty(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + black_box(table.is_empty()).unwrap(); + }); + }); +} + +/// [`DatabaseRw::contains`] +#[named] +fn rw_contains(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + table.contains(black_box(&KEY)).unwrap(); + }); + }); +} + +//---------------------------------------------------------------------------------------------------- DatabaseIter +/// [`DatabaseIter::get_range`] +#[named] +fn get_range(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value_100(); + let env_inner = env.env.env_inner(); + let tx_ro = env_inner.tx_ro().unwrap(); + let table = env_inner.open_db_ro::(&tx_ro).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let range = table.get_range(black_box(..)).unwrap(); + for result in range { + let _: Output = black_box(result.unwrap()); + } + }); + }); +} + +/// [`DatabaseIter::iter`] +#[named] +fn iter(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value_100(); + let env_inner = env.env.env_inner(); + let tx_ro = env_inner.tx_ro().unwrap(); + let table = env_inner.open_db_ro::(&tx_ro).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let iter = black_box(table.iter()).unwrap(); + for result in iter { + let _: (PreRctOutputId, Output) = black_box(result.unwrap()); + } + }); + }); +} + +/// [`DatabaseIter::keys`] +#[named] +fn keys(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value_100(); + let env_inner = env.env.env_inner(); + let tx_ro = env_inner.tx_ro().unwrap(); + let table = env_inner.open_db_ro::(&tx_ro).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let keys = black_box(table.keys()).unwrap(); + for result in keys { + let _: PreRctOutputId = black_box(result.unwrap()); + } + }); + }); +} + +/// [`DatabaseIter::values`] +#[named] +fn values(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value_100(); + let env_inner = env.env.env_inner(); + let tx_ro = env_inner.tx_ro().unwrap(); + let table = env_inner.open_db_ro::(&tx_ro).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let values = black_box(table.values()).unwrap(); + for result in values { + let _: Output = black_box(result.unwrap()); + } + }); + }); +} + +//---------------------------------------------------------------------------------------------------- DatabaseRw +/// [`DatabaseRw::put`] +#[named] +fn put(c: &mut Criterion) { + let env = TmpEnv::new(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let mut table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + let mut key = KEY; + + c.bench_function(function_name!(), |b| { + b.iter(|| { + table.put(black_box(&key), black_box(&VALUE)).unwrap(); + key.amount += 1; + }); + }); +} + +/// [`DatabaseRw::delete`] +#[named] +fn delete(c: &mut Criterion) { + let env = TmpEnv::new(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let mut table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + let mut key = KEY; + + c.bench_function(function_name!(), |b| { + b.iter_custom(|iters| { + for _ in 0..iters { + table.put(&key, &VALUE).unwrap(); + key.amount += 1; + } + + key = KEY; + + let start = Instant::now(); + for _ in 0..iters { + table.delete(&key).unwrap(); + key.amount += 1; + } + start.elapsed() + }); + }); +} + +/// [`DatabaseRw::pop_first`] +#[named] +fn pop_first(c: &mut Criterion) { + let env = TmpEnv::new(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let mut table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + let mut key = KEY; + + c.bench_function(function_name!(), |b| { + b.iter_custom(|iters| { + for _ in 0..iters { + table.put(&key, &VALUE).unwrap(); + key.amount += 1; + } + + key = KEY; + + let start = Instant::now(); + for _ in 0..iters { + table.pop_first().unwrap(); + key.amount += 1; + } + start.elapsed() + }); + }); +} + +/// [`DatabaseRw::pop_last`] +#[named] +fn pop_last(c: &mut Criterion) { + let env = TmpEnv::new(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let mut table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + let mut key = KEY; + + c.bench_function(function_name!(), |b| { + b.iter_custom(|iters| { + for _ in 0..iters { + table.put(&key, &VALUE).unwrap(); + key.amount += 1; + } + + key = KEY; + + let start = Instant::now(); + for _ in 0..iters { + table.pop_last().unwrap(); + key.amount += 1; + } + start.elapsed() + }); + }); +} + +/// [`DatabaseRw::take`] +#[named] +fn take(c: &mut Criterion) { + let env = TmpEnv::new(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let mut table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + table.put(&KEY, &VALUE).unwrap(); + let _: Output = black_box(table.take(&black_box(KEY)).unwrap()); + }); + }); +} diff --git a/benches/criterion/cuprate-database/benches/env.rs b/benches/criterion/cuprate-database/benches/env.rs new file mode 100644 index 000000000..e7213d061 --- /dev/null +++ b/benches/criterion/cuprate-database/benches/env.rs @@ -0,0 +1,183 @@ +//! [`Env`] benchmarks. + +#![allow(unused_crate_dependencies, unused_attributes)] +#![expect(clippy::significant_drop_tightening)] + +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use function_name::named; + +use cuprate_blockchain::tables::Outputs; +use cuprate_database::{ + resize::{ResizeAlgorithm, PAGE_SIZE}, + ConcreteEnv, Env, EnvInner, TxRo, TxRw, +}; + +use cuprate_criterion_database::TmpEnv; + +criterion_group! { + name = benches; + config = Criterion::default(); + targets = + // open, + env_inner, + tx_ro, + tx_rw, + open_db_ro, + open_db_rw, + create_db, + resize, + current_map_size, + disk_size_bytes, +} +criterion_main!(benches); + +// FIXME: This function is hard to time due to: +// - heed errors +// - "too many open files" errors +// +// /// [`Env::open`]. +// #[named] +// fn open(c: &mut Criterion) { +// c.bench_function(function_name!(), |b| { +// b.iter_custom(|_| { +// let tempdir = tempfile::tempdir().unwrap(); +// let config = ConfigBuilder::new(tempdir.path().to_path_buf().into()).build(); +// +// let now = std::time::Instant::now(); +// ConcreteEnv::open(config).unwrap(); +// let elapsed = now.elapsed(); +// +// tempdir.close().unwrap(); +// elapsed +// }); +// }); +// } + +/// [`Env::env_inner`]. +#[named] +fn env_inner(c: &mut Criterion) { + let env = TmpEnv::new(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + drop(black_box(env.env.env_inner())); + }); + }); +} + +/// [`EnvInner::tx_ro`]. +#[named] +fn tx_ro(c: &mut Criterion) { + let env = TmpEnv::new(); + let env_inner = env.env.env_inner(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let tx_ro = black_box(env_inner.tx_ro()).unwrap(); + TxRo::commit(black_box(tx_ro)).unwrap(); + }); + }); +} + +/// [`EnvInner::tx_rw`]. +#[named] +fn tx_rw(c: &mut Criterion) { + let env = TmpEnv::new(); + let env_inner = env.env.env_inner(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let tx_rw = black_box(env_inner.tx_rw()).unwrap(); + TxRw::commit(black_box(tx_rw)).unwrap(); + }); + }); +} + +/// [`EnvInner::open_db_ro`]. +#[named] +fn open_db_ro(c: &mut Criterion) { + // `with_key_value()` creates the `Outputs` + // table so the `open_db_ro` below doesn't panic. + let env = TmpEnv::new().with_key_value(); + let env_inner = env.env.env_inner(); + let tx_ro = env_inner.tx_ro().unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + env_inner.open_db_ro::(&tx_ro).unwrap(); + }); + }); +} + +/// [`EnvInner::open_db_rw`]. +#[named] +fn open_db_rw(c: &mut Criterion) { + let env = TmpEnv::new(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + env_inner.open_db_rw::(&tx_rw).unwrap(); + }); + }); +} + +/// [`EnvInner::create_db`]. +#[named] +fn create_db(c: &mut Criterion) { + let env = TmpEnv::new(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + env_inner.create_db::(&tx_rw).unwrap(); + }); + }); +} + +/// [`Env::resize`]. +#[named] +fn resize(c: &mut Criterion) { + let env = TmpEnv::new(); + + // Resize env.by the OS page size. + let resize = Some(ResizeAlgorithm::FixedBytes(*PAGE_SIZE)); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + // This test is only valid for `Env`'s that need to resize manually. + if ConcreteEnv::MANUAL_RESIZE { + env.env.resize_map(resize); + } + }); + }); +} + +/// [`Env::current_map_size`]. +#[named] +fn current_map_size(c: &mut Criterion) { + let env = TmpEnv::new(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + // This test is only valid for `Env`'s that need to resize manually. + if ConcreteEnv::MANUAL_RESIZE { + black_box(env.env.current_map_size()); + } + }); + }); +} + +/// [`Env::disk_size_bytes`]. +#[named] +fn disk_size_bytes(c: &mut Criterion) { + let env = TmpEnv::new(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + black_box(env.env.disk_size_bytes()).unwrap(); + }); + }); +} diff --git a/benches/criterion/cuprate-database/benches/main.rs b/benches/criterion/cuprate-database/benches/main.rs new file mode 100644 index 000000000..0dba9693c --- /dev/null +++ b/benches/criterion/cuprate-database/benches/main.rs @@ -0,0 +1,11 @@ +#![expect(unused_crate_dependencies)] + +mod db; +mod env; +mod storable; + +criterion::criterion_main! { + db::benches, + env::benches, + storable::benches, +} diff --git a/benches/criterion/cuprate-database/benches/storable.rs b/benches/criterion/cuprate-database/benches/storable.rs new file mode 100644 index 000000000..e2add7d33 --- /dev/null +++ b/benches/criterion/cuprate-database/benches/storable.rs @@ -0,0 +1,66 @@ +//! [`Storable`] benchmarks. + +#![allow(unused_crate_dependencies, unused_attributes)] + +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use function_name::named; + +use cuprate_blockchain::types::{Output, PreRctOutputId}; +use cuprate_database::Storable; + +use cuprate_criterion_database::{KEY, VALUE}; + +criterion_group! { + name = benches; + config = Criterion::default(); + targets = + pre_rct_output_id_as_bytes, + pre_rct_output_id_from_bytes, + output_as_bytes, + output_from_bytes +} +criterion_main!(benches); + +/// [`PreRctOutputId`] cast as bytes. +#[named] +fn pre_rct_output_id_as_bytes(c: &mut Criterion) { + c.bench_function(function_name!(), |b| { + b.iter(|| { + black_box(Storable::as_bytes(black_box(&KEY))); + }); + }); +} + +/// [`PreRctOutputId`] cast from bytes. +#[named] +fn pre_rct_output_id_from_bytes(c: &mut Criterion) { + let bytes = Storable::as_bytes(&KEY); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let _: PreRctOutputId = black_box(Storable::from_bytes(black_box(bytes))); + }); + }); +} + +/// [`Output`] cast as bytes. +#[named] +fn output_as_bytes(c: &mut Criterion) { + c.bench_function(function_name!(), |b| { + b.iter(|| { + black_box(Storable::as_bytes(black_box(&VALUE))); + }); + }); +} + +/// [`Output`] cast from bytes. +#[named] +fn output_from_bytes(c: &mut Criterion) { + let bytes = Storable::as_bytes(&VALUE); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + let _: Output = black_box(Storable::from_bytes(black_box(bytes))); + }); + }); +} diff --git a/benches/criterion/cuprate-database/src/constants.rs b/benches/criterion/cuprate-database/src/constants.rs new file mode 100644 index 000000000..bcb191930 --- /dev/null +++ b/benches/criterion/cuprate-database/src/constants.rs @@ -0,0 +1,17 @@ +//! General constants. + +use cuprate_blockchain::types::{Output, OutputFlags, PreRctOutputId}; + +/// The (1st) key. +pub const KEY: PreRctOutputId = PreRctOutputId { + amount: 1, + amount_index: 123, +}; + +/// The expected value. +pub const VALUE: Output = Output { + key: [35; 32], + height: 45_761_798, + output_flags: OutputFlags::empty(), + tx_idx: 2_353_487, +}; diff --git a/benches/criterion/cuprate-database/src/lib.rs b/benches/criterion/cuprate-database/src/lib.rs new file mode 100644 index 000000000..2c527dcd4 --- /dev/null +++ b/benches/criterion/cuprate-database/src/lib.rs @@ -0,0 +1,7 @@ +#![allow(unused_crate_dependencies, reason = "used in benchmarks")] + +mod constants; +mod tmp_env; + +pub use constants::{KEY, VALUE}; +pub use tmp_env::TmpEnv; diff --git a/benches/criterion/cuprate-database/src/tmp_env.rs b/benches/criterion/cuprate-database/src/tmp_env.rs new file mode 100644 index 000000000..1a05e66f6 --- /dev/null +++ b/benches/criterion/cuprate-database/src/tmp_env.rs @@ -0,0 +1,88 @@ +//! An [`Env`] inside a [`TempDir`]. + +use tempfile::TempDir; + +use cuprate_blockchain::tables::Outputs; +use cuprate_database::{ + config::ConfigBuilder, resize::PAGE_SIZE, ConcreteEnv, DatabaseRw, Env, EnvInner, TxRw, +}; + +use crate::constants::{KEY, VALUE}; + +/// A temporary in-memory [`Env`]. +/// +/// This is a [`ConcreteEnv`] that uses [`TempDir`] as the +/// backing file location - this is an in-memory file on Linux. +pub struct TmpEnv { + pub env: ConcreteEnv, + pub tempdir: TempDir, +} + +impl Default for TmpEnv { + fn default() -> Self { + Self::new() + } +} + +impl TmpEnv { + /// Create an `Env` in a temporary directory. + /// + /// The directory is automatically removed after the [`TempDir`] is dropped. + #[expect(clippy::missing_panics_doc)] + pub fn new() -> Self { + let tempdir = tempfile::tempdir().unwrap(); + let path = tempdir.path().to_path_buf().into(); + let config = ConfigBuilder::new(path).low_power().build(); + let env = ConcreteEnv::open(config).unwrap(); + + // Resize to a very large map to prevent resize errors. + if ConcreteEnv::MANUAL_RESIZE { + // SAFETY: no write transactions exist yet. + unsafe { + env.env_inner() + .resize(PAGE_SIZE.get() * 1024 * 1024 * 1024) + .unwrap(); + } + } + + Self { env, tempdir } + } + + /// Inserts [`KEY`] and [`VALUE`] inside the [`Outputs`] table. + #[must_use] + pub fn with_key_value(self) -> Self { + let env_inner = self.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let mut table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + table.put(&KEY, &VALUE).unwrap(); + drop(table); + tx_rw.commit().unwrap(); + + drop(env_inner); + self + } + + /// Inserts [`VALUE`] inside the [`Outputs`] table 100 times. + /// + /// The key is an incrementing [`KEY`], i.e. the keys are + /// `KEY + {0..99}`, each one has [`VALUE`] as the value. + #[must_use] + pub fn with_key_value_100(self) -> Self { + let env_inner = self.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + let mut table = env_inner.open_db_rw::(&tx_rw).unwrap(); + + let mut key = KEY; + for _ in 0..100 { + table.put(&key, &VALUE).unwrap(); + key.amount += 1; + } + + drop(table); + tx_rw.commit().unwrap(); + + drop(env_inner); + self + } +} diff --git a/benches/criterion/cuprate-helper/Cargo.toml b/benches/criterion/cuprate-helper/Cargo.toml new file mode 100644 index 000000000..93a669834 --- /dev/null +++ b/benches/criterion/cuprate-helper/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "cuprate-criterion-helper" +version = "0.0.0" +edition = "2021" +description = "Criterion benchmarks for cuprate-helper" +license = "MIT" +authors = ["hinto-janai"] +repository = "https://github.com/Cuprate/cuprate/tree/main/benches/criterion/example" +keywords = ["cuprate", "helper", "criterion", "benchmark"] + +[dependencies] +cuprate-constants = { workspace = true, features = ["block"] } +cuprate-helper = { workspace = true, features = ["cast", "map", "num", "tx"] } +cuprate-test-utils = { workspace = true } + +criterion = { workspace = true } +function_name = { workspace = true } +monero-serai = { workspace = true } +serde_json = { workspace = true, features = ["default"] } + +[[bench]] +name = "main" +harness = false + +[lints] +workspace = true \ No newline at end of file diff --git a/benches/criterion/cuprate-helper/benches/cast.rs b/benches/criterion/cuprate-helper/benches/cast.rs new file mode 100644 index 000000000..256f43d5c --- /dev/null +++ b/benches/criterion/cuprate-helper/benches/cast.rs @@ -0,0 +1,40 @@ +//! Benchmarks for `cuprate_helper::cast`. +#![allow(unused_attributes, unused_crate_dependencies)] + +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use function_name::named; + +use cuprate_helper::cast::{ + i32_to_isize, i64_to_isize, isize_to_i64, u32_to_usize, u64_to_usize, usize_to_u64, +}; + +criterion_group! { + name = benches; + config = Criterion::default(); + targets = integer, unsigned, +} +criterion_main!(benches); + +/// Benchmark integer casts. +#[named] +fn integer(c: &mut Criterion) { + c.bench_function(function_name!(), |b| { + b.iter(|| { + black_box(i32_to_isize(black_box(0))); + black_box(i64_to_isize(black_box(0))); + black_box(isize_to_i64(black_box(0))); + }); + }); +} + +/// Benchmark unsigned integer casts. +#[named] +fn unsigned(c: &mut Criterion) { + c.bench_function(function_name!(), |b| { + b.iter(|| { + black_box(u32_to_usize(black_box(0))); + black_box(u64_to_usize(black_box(0))); + black_box(usize_to_u64(black_box(0))); + }); + }); +} diff --git a/benches/criterion/cuprate-helper/benches/main.rs b/benches/criterion/cuprate-helper/benches/main.rs new file mode 100644 index 000000000..aa325357d --- /dev/null +++ b/benches/criterion/cuprate-helper/benches/main.rs @@ -0,0 +1,14 @@ +//! `cuprate_helper` benchmarks. +#![allow(unused_crate_dependencies)] + +mod cast; +mod map; +mod num; +mod tx; + +criterion::criterion_main! { + cast::benches, + map::benches, + num::benches, + tx::benches, +} diff --git a/benches/criterion/cuprate-helper/benches/map.rs b/benches/criterion/cuprate-helper/benches/map.rs new file mode 100644 index 000000000..7b2f34453 --- /dev/null +++ b/benches/criterion/cuprate-helper/benches/map.rs @@ -0,0 +1,70 @@ +//! Benchmarks for `cuprate_helper::cast`. +#![allow(unused_attributes, unused_crate_dependencies)] + +use criterion::black_box as b; +use criterion::{criterion_group, criterion_main, Criterion}; +use function_name::named; + +use cuprate_constants::block::MAX_BLOCK_HEIGHT; +use cuprate_helper::map; + +criterion_group! { + name = benches; + config = Criterion::default(); + targets = + combine_low_high_bits_to_u128, + split_u128_into_low_high_bits, + timelock_to_u64, + u64_to_timelock, +} +criterion_main!(benches); + +/// Benchmark [`curpate_helper::map::combine_low_high_bits_to_u128`]. +#[named] +fn combine_low_high_bits_to_u128(c: &mut Criterion) { + c.bench_function(function_name!(), |bench| { + bench.iter(|| { + b(map::combine_low_high_bits_to_u128(b(0), b(0))); + }); + }); +} + +/// Benchmark [`curpate_helper::map::split_u128_into_low_high_bits`]. +#[named] +fn split_u128_into_low_high_bits(c: &mut Criterion) { + c.bench_function(function_name!(), |bench| { + bench.iter(|| { + b(map::split_u128_into_low_high_bits(b(0))); + }); + }); +} + +/// Benchmark [`curpate_helper::map::timelock_to_u64`]. +#[named] +fn timelock_to_u64(c: &mut Criterion) { + c.bench_function(function_name!(), |bench| { + bench.iter(|| { + b(map::timelock_to_u64(b( + monero_serai::transaction::Timelock::None, + ))); + b(map::timelock_to_u64(b( + monero_serai::transaction::Timelock::Time(0), + ))); + b(map::timelock_to_u64(b( + monero_serai::transaction::Timelock::Block(0), + ))); + }); + }); +} + +/// Benchmark [`curpate_helper::map::u64_to_timelock`]. +#[named] +fn u64_to_timelock(c: &mut Criterion) { + c.bench_function(function_name!(), |bench| { + bench.iter(|| { + b(map::u64_to_timelock(b(0))); + b(map::u64_to_timelock(b(MAX_BLOCK_HEIGHT))); + b(map::u64_to_timelock(b(MAX_BLOCK_HEIGHT + 1))); + }); + }); +} diff --git a/benches/criterion/cuprate-helper/benches/num.rs b/benches/criterion/cuprate-helper/benches/num.rs new file mode 100644 index 000000000..070951411 --- /dev/null +++ b/benches/criterion/cuprate-helper/benches/num.rs @@ -0,0 +1,64 @@ +//! Benchmarks for `cuprate_helper::cast`. +#![allow(unused_attributes, unused_crate_dependencies)] + +use criterion::black_box as b; +use criterion::{criterion_group, criterion_main, Criterion}; +use function_name::named; + +use cuprate_helper::num; + +criterion_group! { + name = benches; + config = Criterion::default(); + targets = + cmp_float, + cmp_float_nan, + get_mid, + median, +} +criterion_main!(benches); + +/// Benchmark [`curpate_helper::num::cmp_float`]. +#[named] +fn cmp_float(c: &mut Criterion) { + c.bench_function(function_name!(), |bench| { + bench.iter(|| { + b(num::cmp_float(b(0.0), b(0.0))); + }); + }); +} + +/// Benchmark [`curpate_helper::num::cmp_float_nan`]. +#[named] +fn cmp_float_nan(c: &mut Criterion) { + c.bench_function(function_name!(), |bench| { + bench.iter(|| { + b(num::cmp_float_nan(b(0.0), b(0.0))); + }); + }); +} + +/// Benchmark [`curpate_helper::num::get_mid`]. +#[named] +fn get_mid(c: &mut Criterion) { + c.bench_function(function_name!(), |bench| { + bench.iter(|| { + b(num::get_mid(b(0_u8), b(0_u8))); + b(num::get_mid(b(1_i64), b(10_i64))); + b(num::get_mid(b(0.0_f32), b(0.0_f32))); + b(num::get_mid(b(0.0_f64), b(10.0_f64))); + }); + }); +} + +/// Benchmark [`curpate_helper::num::median`]. +#[named] +fn median(c: &mut Criterion) { + c.bench_function(function_name!(), |bench| { + bench.iter(|| { + b(num::median(b(vec![0_u8, 1, 2, 3, 4, 5]))); + b(num::median(b(vec![0.0_f32, 1.0, 2.0, 3.0, 4.0, 5.0]))); + b(num::median(b(vec![0_u64; 100]))); + }); + }); +} diff --git a/benches/criterion/cuprate-helper/benches/tx.rs b/benches/criterion/cuprate-helper/benches/tx.rs new file mode 100644 index 000000000..0b2dc2d0c --- /dev/null +++ b/benches/criterion/cuprate-helper/benches/tx.rs @@ -0,0 +1,28 @@ +//! Benchmarks for `cuprate_helper::cast`. +#![allow(unused_attributes, unused_crate_dependencies)] + +use criterion::black_box as b; +use criterion::{criterion_group, criterion_main, Criterion}; +use function_name::named; + +use cuprate_helper::tx; +use cuprate_test_utils::data::{TX_V1_SIG0, TX_V1_SIG2, TX_V2_RCT3}; + +criterion_group! { + name = benches; + config = Criterion::default(); + targets = tx_fee, +} +criterion_main!(benches); + +/// Benchmark [`curpate_helper::tx::tx_fee`]. +#[named] +fn tx_fee(c: &mut Criterion) { + c.bench_function(function_name!(), |bench| { + bench.iter(|| { + b(tx::tx_fee(b(&TX_V1_SIG0.tx))); + b(tx::tx_fee(b(&TX_V1_SIG2.tx))); + b(tx::tx_fee(b(&TX_V2_RCT3.tx))); + }); + }); +} diff --git a/benches/criterion/cuprate-helper/src/lib.rs b/benches/criterion/cuprate-helper/src/lib.rs new file mode 100644 index 000000000..5a529588c --- /dev/null +++ b/benches/criterion/cuprate-helper/src/lib.rs @@ -0,0 +1 @@ +#![allow(unused_crate_dependencies, reason = "used in benchmarks")] diff --git a/benches/criterion/cuprate-json-rpc/Cargo.toml b/benches/criterion/cuprate-json-rpc/Cargo.toml index a0cae64e6..b7bd1202f 100644 --- a/benches/criterion/cuprate-json-rpc/Cargo.toml +++ b/benches/criterion/cuprate-json-rpc/Cargo.toml @@ -20,4 +20,4 @@ name = "main" harness = false [lints] -workspace = true \ No newline at end of file +workspace = true diff --git a/benches/criterion/cuprate-rpc-types/Cargo.toml b/benches/criterion/cuprate-rpc-types/Cargo.toml new file mode 100644 index 000000000..21119605c --- /dev/null +++ b/benches/criterion/cuprate-rpc-types/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "cuprate-criterion-rpc-types" +version = "0.0.0" +edition = "2021" +description = "Criterion benchmarking for cuprate-rpc-types" +license = "MIT" +authors = ["hinto-janai"] +repository = "https://github.com/Cuprate/cuprate/tree/main/benches/criterion/cuprate-rpc-types" +keywords = ["cuprate", "rpc", "types", "criterion", "benchmark"] + +[dependencies] +cuprate-epee-encoding = { workspace = true } +cuprate-rpc-types = { workspace = true, features = ["serde", "epee"] } +cuprate-test-utils = { workspace = true } + +criterion = { workspace = true } +function_name = { workspace = true } +serde_json = { workspace = true, features = ["default"] } +paste = { workspace = true } + +[[bench]] +name = "main" +harness = false + +[lints] +workspace = true \ No newline at end of file diff --git a/benches/criterion/cuprate-rpc-types/benches/epee.rs b/benches/criterion/cuprate-rpc-types/benches/epee.rs new file mode 100644 index 000000000..7244eb8bf --- /dev/null +++ b/benches/criterion/cuprate-rpc-types/benches/epee.rs @@ -0,0 +1,74 @@ +//! This module contains benchmarks for any +//! +//! - non-trivial +//! - manual +//! - common +//! +//! type with a `epee` implementation. +//! +//! Types with the standard `epee` derive implementation are not included. + +#![allow(unused_attributes, unused_crate_dependencies)] + +use criterion::{black_box, criterion_group, criterion_main, BatchSize, Criterion}; +use function_name::named; + +use cuprate_epee_encoding::{from_bytes, to_bytes}; +use cuprate_rpc_types::bin::GetBlocksRequest; + +/// Create [`to_bytes`] and [`from_bytes`] benchmarks for `epee` types. +macro_rules! generate_epee_benchmarks { + ( + $( + $t:ty + ),* $(,)? + ) => { paste::paste! { + // Generate the benchmarking functions. + $( + #[named] + fn [](c: &mut Criterion) { + let bytes = to_bytes($t::default()).unwrap(); + + // `iter_batched()` is used so the `Default::default()` + // is not part of the timings. + c.bench_function(function_name!(), |b| { + b.iter_batched( + || bytes.clone(), + |mut bytes| drop(from_bytes::<$t, _>(black_box(&mut bytes)).unwrap()), + BatchSize::SmallInput, + ); + }); + } + + #[named] + fn [](c: &mut Criterion) { + let t = $t::default(); + + c.bench_function(function_name!(), |b| { + b.iter_batched( + || t.clone(), + |t| drop(to_bytes(black_box(t)).unwrap()), + BatchSize::SmallInput, + ); + }); + } + )* + + // Enable all the benchmark functions created in this macro. + criterion_group! { + name = benches; + config = Criterion::default(); + targets = + $( + [], + [], + )* + } + criterion_main!(benches); + }}; +} + +generate_epee_benchmarks! { + GetBlocksRequest, + // GetBlocksResponse // TODO: fix epee impl +} diff --git a/benches/criterion/cuprate-rpc-types/benches/main.rs b/benches/criterion/cuprate-rpc-types/benches/main.rs new file mode 100644 index 000000000..dedb44a13 --- /dev/null +++ b/benches/criterion/cuprate-rpc-types/benches/main.rs @@ -0,0 +1,10 @@ +//! Benchmarks for `cuprate-json-rpc`. +#![allow(unused_crate_dependencies)] + +mod epee; +mod serde; + +criterion::criterion_main! { + epee::benches, + serde::benches, +} diff --git a/benches/criterion/cuprate-rpc-types/benches/serde.rs b/benches/criterion/cuprate-rpc-types/benches/serde.rs new file mode 100644 index 000000000..2f6124862 --- /dev/null +++ b/benches/criterion/cuprate-rpc-types/benches/serde.rs @@ -0,0 +1,91 @@ +//! This module contains benchmarks for any +//! +//! - non-trivial +//! - manual +//! - common +//! +//! type with a `serde` implementation. +//! +//! Types with the standard `serde` derive implementation are not included. + +#![allow(unused_attributes, unused_crate_dependencies)] + +use criterion::{black_box, criterion_group, criterion_main, BatchSize, Criterion}; +use function_name::named; +use serde_json::{from_str, to_string}; + +use cuprate_rpc_types::{ + json::{ + CalcPowRequest, GetBlockHeadersRangeResponse, GetBlockResponse, GetBlockTemplateResponse, + GetConnectionsResponse, GetInfoResponse, GetLastBlockHeaderResponse, SyncInfoResponse, + }, + misc::TxEntry, +}; + +/// Generate [`from_str`] and [`to_string`] benchmarks for `serde` types. +macro_rules! generate_serde_benchmarks { + ( + $( + // The type to test => JSON of that type + $t:ty => $t_example:expr_2021 + ),* $(,)? + ) => { paste::paste! { + // Generate the benchmarking functions. + $( + #[named] + fn [](c: &mut Criterion) { + c.bench_function(function_name!(), |b| { + b.iter(|| { + drop(from_str::<$t>( + black_box($t_example) + ).unwrap()); + }); + }); + } + + #[named] + fn [](c: &mut Criterion) { + let t = $t::default(); + + c.bench_function(function_name!(), |b| { + b.iter_batched( + || t.clone(), + |t| drop(to_string(black_box(&t)).unwrap()), + BatchSize::SmallInput, + ); + }); + } + + )* + + // Enable all the benchmark functions created in this macro. + criterion_group! { + name = benches; + config = Criterion::default(); + targets = + $( + [], + [], + )* + } + criterion_main!(benches); + }}; +} + +// FIXME: these could be taken from `cuprate-test-utils::rpc::data::json` but +// those are wrapped in JSON-RPC, so we have to copy+paste the inner portion here. +generate_serde_benchmarks! { + // Custom serde types. + TxEntry => r#"{"as_hex":"","as_json":"","double_spend_seen":false,"prunable_as_hex":"","prunable_hash":"","pruned_as_hex":"","received_timestamp":0,"relayed":false,"tx_hash":"","in_pool":false}"#, + // Distribution => "TODO: enable after type is finalized" + + // Common types or heavy types (heap types, many fields, etc). + GetLastBlockHeaderResponse => r#"{"block_header":{"block_size":200419,"block_weight":200419,"cumulative_difficulty":366125734645190820,"cumulative_difficulty_top64":0,"depth":0,"difficulty":282052561854,"difficulty_top64":0,"hash":"57238217820195ac4c08637a144a885491da167899cf1d20e8e7ce0ae0a3434e","height":3195020,"long_term_weight":200419,"major_version":16,"miner_tx_hash":"7a42667237d4f79891bb407c49c712a9299fb87fce799833a7b633a3a9377dbd","minor_version":16,"nonce":1885649739,"num_txes":37,"orphan_status":false,"pow_hash":"","prev_hash":"22c72248ae9c5a2863c94735d710a3525c499f70707d1c2f395169bc5c8a0da3","reward":615702960000,"timestamp":1721245548,"wide_cumulative_difficulty":"0x514bd6a74a7d0a4","wide_difficulty":"0x41aba48bbe"},"credits":0,"status":"OK","top_hash":"","untrusted":false}"#, + CalcPowRequest => r#"{"major_version":14,"height":2286447,"block_blob":"0e0ed286da8006ecdc1aab3033cf1716c52f13f9d8ae0051615a2453643de94643b550d543becd0000000002abc78b0101ffefc68b0101fcfcf0d4b422025014bb4a1eade6622fd781cb1063381cad396efa69719b41aa28b4fce8c7ad4b5f019ce1dc670456b24a5e03c2d9058a2df10fec779e2579753b1847b74ee644f16b023c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051399a1bc46a846474f5b33db24eae173a26393b976054ee14f9feefe99925233802867097564c9db7a36af5bb5ed33ab46e63092bd8d32cef121608c3258edd55562812e21cc7e3ac73045745a72f7d74581d9a0849d6f30e8b2923171253e864f4e9ddea3acb5bc755f1c4a878130a70c26297540bc0b7a57affb6b35c1f03d8dbd54ece8457531f8cba15bb74516779c01193e212050423020e45aa2c15dcb","seed_hash":"d432f499205150873b2572b5f033c9c6e4b7c6f3394bd2dd93822cd7085e7307"}"#, + SyncInfoResponse => r#"{"credits":0,"height":3195157,"next_needed_pruning_seed":0,"overview":"[]","peers":[{"info":{"address":"142.93.128.65:44986","address_type":1,"avg_download":1,"avg_upload":1,"connection_id":"a5803c4c2dac49e7b201dccdef54c862","current_download":2,"current_upload":1,"height":3195157,"host":"142.93.128.65","incoming":true,"ip":"142.93.128.65","live_time":18,"local_ip":false,"localhost":false,"peer_id":"6830e9764d3e5687","port":"44986","pruning_seed":0,"recv_count":20340,"recv_idle_time":0,"rpc_credits_per_hash":0,"rpc_port":18089,"send_count":32235,"send_idle_time":6,"state":"normal","support_flags":1}},{"info":{"address":"4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion:18083","address_type":4,"avg_download":0,"avg_upload":0,"connection_id":"277f7c821bc546878c8bd29977e780f5","current_download":0,"current_upload":0,"height":3195157,"host":"4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion","incoming":false,"ip":"","live_time":2246,"local_ip":false,"localhost":false,"peer_id":"0000000000000001","port":"","pruning_seed":389,"recv_count":65164,"recv_idle_time":15,"rpc_credits_per_hash":0,"rpc_port":0,"send_count":99120,"send_idle_time":15,"state":"normal","support_flags":0}}],"status":"OK","target_height":0,"top_hash":"","untrusted":false}"#, + GetInfoResponse => r#"{"adjusted_time":1721245289,"alt_blocks_count":16,"block_size_limit":600000,"block_size_median":300000,"block_weight_limit":600000,"block_weight_median":300000,"bootstrap_daemon_address":"","busy_syncing":false,"credits":0,"cumulative_difficulty":366127702242611947,"cumulative_difficulty_top64":0,"database_size":235169075200,"difficulty":280716748706,"difficulty_top64":0,"free_space":30521749504,"grey_peerlist_size":4996,"height":3195028,"height_without_bootstrap":3195028,"incoming_connections_count":62,"mainnet":true,"nettype":"mainnet","offline":false,"outgoing_connections_count":1143,"restricted":false,"rpc_connections_count":1,"stagenet":false,"start_time":1720462427,"status":"OK","synchronized":true,"target":120,"target_height":0,"testnet":false,"top_block_hash":"bdf06d18ed1931a8ee62654e9b6478cc459bc7072628b8e36f4524d339552946","top_hash":"","tx_count":43205750,"tx_pool_size":12,"untrusted":false,"update_available":false,"version":"0.18.3.3-release","was_bootstrap_ever_used":false,"white_peerlist_size":1000,"wide_cumulative_difficulty":"0x514bf349299d2eb","wide_difficulty":"0x415c05a7a2"}"#, + GetBlockResponse => r#"{"blob":"1010c58bab9b06b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7807e07f502cef8a70101ff92f8a7010180e0a596bb1103d7cbf826b665d7a532c316982dc8dbc24f285cbc18bbcc27c7164cd9b3277a85d034019f629d8b36bd16a2bfce3ea80c31dc4d8762c67165aec21845494e32b7582fe00211000000297a787a000000000000000000000000","block_header":{"block_size":106,"block_weight":106,"cumulative_difficulty":236046001376524168,"cumulative_difficulty_top64":0,"depth":443517,"difficulty":313732272488,"difficulty_top64":0,"hash":"43bd1f2b6556dcafa413d8372974af59e4e8f37dbf74dc6b2a9b7212d0577428","height":2751506,"long_term_weight":176470,"major_version":16,"miner_tx_hash":"e49b854c5f339d7410a77f2a137281d8042a0ffc7ef9ab24cd670b67139b24cd","minor_version":16,"nonce":4110909056,"num_txes":0,"orphan_status":false,"pow_hash":"","prev_hash":"b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7","reward":600000000000,"timestamp":1667941829,"wide_cumulative_difficulty":"0x3469a966eb2f788","wide_difficulty":"0x490be69168"},"credits":0,"json":"{\n \"major_version\": 16, \n \"minor_version\": 16, \n \"timestamp\": 1667941829, \n \"prev_id\": \"b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7\", \n \"nonce\": 4110909056, \n \"miner_tx\": {\n \"version\": 2, \n \"unlock_time\": 2751566, \n \"vin\": [ {\n \"gen\": {\n \"height\": 2751506\n }\n }\n ], \n \"vout\": [ {\n \"amount\": 600000000000, \n \"target\": {\n \"tagged_key\": {\n \"key\": \"d7cbf826b665d7a532c316982dc8dbc24f285cbc18bbcc27c7164cd9b3277a85\", \n \"view_tag\": \"d0\"\n }\n }\n }\n ], \n \"extra\": [ 1, 159, 98, 157, 139, 54, 189, 22, 162, 191, 206, 62, 168, 12, 49, 220, 77, 135, 98, 198, 113, 101, 174, 194, 24, 69, 73, 78, 50, 183, 88, 47, 224, 2, 17, 0, 0, 0, 41, 122, 120, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n ], \n \"rct_signatures\": {\n \"type\": 0\n }\n }, \n \"tx_hashes\": [ ]\n}","miner_tx_hash":"e49b854c5f339d7410a77f2a137281d8042a0ffc7ef9ab24cd670b67139b24cd","status":"OK","top_hash":"","untrusted":false}"#, + GetConnectionsResponse => r#"{"connections":[{"address":"3evk3kezfjg44ma6tvesy7rbxwwpgpympj45xar5fo4qajrsmkoaqdqd.onion:18083","address_type":4,"avg_download":0,"avg_upload":0,"connection_id":"22ef856d0f1d44cc95e84fecfd065fe2","current_download":0,"current_upload":0,"height":3195026,"host":"3evk3kezfjg44ma6tvesy7rbxwwpgpympj45xar5fo4qajrsmkoaqdqd.onion","incoming":false,"ip":"","live_time":76651,"local_ip":false,"localhost":false,"peer_id":"0000000000000001","port":"","pruning_seed":0,"recv_count":240328,"recv_idle_time":34,"rpc_credits_per_hash":0,"rpc_port":0,"send_count":3406572,"send_idle_time":30,"state":"normal","support_flags":0},{"address":"4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion:18083","address_type":4,"avg_download":0,"avg_upload":0,"connection_id":"c7734e15936f485a86d2b0534f87e499","current_download":0,"current_upload":0,"height":3195024,"host":"4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion","incoming":false,"ip":"","live_time":76755,"local_ip":false,"localhost":false,"peer_id":"0000000000000001","port":"","pruning_seed":389,"recv_count":237657,"recv_idle_time":120,"rpc_credits_per_hash":0,"rpc_port":0,"send_count":3370566,"send_idle_time":120,"state":"normal","support_flags":0}],"status":"OK","untrusted":false}"#, + GetBlockTemplateResponse => r#"{"blockhashing_blob":"1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a00000000e0c20372be23d356347091025c5b5e8f2abf83ab618378565cce2b703491523401","blocktemplate_blob":"1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a0000000002c681c30101ff8a81c3010180e0a596bb11033b7eedf47baf878f3490cb20b696079c34bd017fe59b0d070e74d73ffabc4bb0e05f011decb630f3148d0163b3bd39690dde4078e4cfb69fecf020d6278a27bad10c58023c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":283305047039,"difficulty_top64":0,"expected_reward":600000000000,"height":3195018,"next_seed_hash":"","prev_hash":"9d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a","reserved_offset":131,"seed_hash":"e2aa0b7b55042cd48b02e395d78fa66a29815ccc1584e38db2d1f0e8485cd44f","seed_height":3194880,"status":"OK","untrusted":false,"wide_difficulty":"0x41f64bf3ff"}"#, + GetBlockHeadersRangeResponse => r#"{"credits":0,"headers":[{"block_size":301413,"block_weight":301413,"cumulative_difficulty":13185267971483472,"cumulative_difficulty_top64":0,"depth":1649024,"difficulty":134636057921,"difficulty_top64":0,"hash":"86d1d20a40cefcf3dd410ff6967e0491613b77bf73ea8f1bf2e335cf9cf7d57a","height":1545999,"long_term_weight":301413,"major_version":6,"miner_tx_hash":"9909c6f8a5267f043c3b2b079fb4eacc49ef9c1dee1c028eeb1a259b95e6e1d9","minor_version":6,"nonce":3246403956,"num_txes":20,"orphan_status":false,"pow_hash":"","prev_hash":"0ef6e948f77b8f8806621003f5de24b1bcbea150bc0e376835aea099674a5db5","reward":5025593029981,"timestamp":1523002893,"wide_cumulative_difficulty":"0x2ed7ee6db56750","wide_difficulty":"0x1f58ef3541"},{"block_size":13322,"block_weight":13322,"cumulative_difficulty":13185402687569710,"cumulative_difficulty_top64":0,"depth":1649023,"difficulty":134716086238,"difficulty_top64":0,"hash":"b408bf4cfcd7de13e7e370c84b8314c85b24f0ba4093ca1d6eeb30b35e34e91a","height":1546000,"long_term_weight":13322,"major_version":7,"miner_tx_hash":"7f749c7c64acb35ef427c7454c45e6688781fbead9bbf222cb12ad1a96a4e8f6","minor_version":7,"nonce":3737164176,"num_txes":1,"orphan_status":false,"pow_hash":"","prev_hash":"86d1d20a40cefcf3dd410ff6967e0491613b77bf73ea8f1bf2e335cf9cf7d57a","reward":4851952181070,"timestamp":1523002931,"wide_cumulative_difficulty":"0x2ed80dcb69bf2e","wide_difficulty":"0x1f5db457de"}],"status":"OK","top_hash":"","untrusted":false}"# +} diff --git a/benches/criterion/cuprate-rpc-types/src/lib.rs b/benches/criterion/cuprate-rpc-types/src/lib.rs new file mode 100644 index 000000000..5a529588c --- /dev/null +++ b/benches/criterion/cuprate-rpc-types/src/lib.rs @@ -0,0 +1 @@ +#![allow(unused_crate_dependencies, reason = "used in benchmarks")] diff --git a/storage/database/src/backend/heed/env.rs b/storage/database/src/backend/heed/env.rs index b603013bd..59c163377 100644 --- a/storage/database/src/backend/heed/env.rs +++ b/storage/database/src/backend/heed/env.rs @@ -78,11 +78,12 @@ impl Drop for ConcreteEnv { // TODO: use tracing. // - let result = self.env.read().unwrap().clear_stale_readers(); - match result { - Ok(n) => println!("LMDB stale readers cleared: {n}"), - Err(e) => println!("LMDB stale reader clear error: {e:?}"), - } + drop(self.env.read().unwrap().clear_stale_readers()); + // let result = self.env.read().unwrap().clear_stale_readers(); + // match result { + // Ok(n) => println!("LMDB stale readers cleared: {n}"), + // Err(e) => println!("LMDB stale reader clear error: {e:?}"), + // } } } diff --git a/typos.toml b/typos.toml index fbd66d099..c4537fa5f 100644 --- a/typos.toml +++ b/typos.toml @@ -16,7 +16,8 @@ extend-ignore-identifiers-re = [ # False positive files. extend-exclude = [ "/misc/gpg_keys/", - "cryptonight/", + "/cryptonight/", "/test-utils/src/rpc/data/json.rs", - "rpc/types/src/json.rs", + "/rpc/types/src/json.rs", + "/benches/criterion/cuprate-rpc-types/benches/serde.rs", ]