feat(asb): Cache quotes (#288)

This commit is contained in:
Mohan 2025-04-17 16:22:30 +02:00 committed by GitHub
parent 8d4f714015
commit b3559421ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 245 additions and 96 deletions

View file

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- CI: Update Rust version to 1.80
- GUI: Update social media links
- ASB: Quotes are now cached (Time-to-live of 2 minutes) to avoid overloading the maker with requests in times of high demand
## [1.0.0-rc.13] - 2025-01-24

228
Cargo.lock generated
View file

@ -967,9 +967,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.6.0"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
dependencies = [
"serde",
]
@ -1251,7 +1251,7 @@ version = "0.18.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"cairo-sys-rs",
"glib",
"libc",
@ -1495,7 +1495,7 @@ version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f79398230a6e2c08f5c9760610eb6924b52aa9e7950a619602baba59dcbbdbb2"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"block",
"cocoa-foundation",
"core-foundation 0.10.0",
@ -1511,7 +1511,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14045fb83be07b5acf1c0884b2180461635b433455fa35d1cd6f17f1450679d"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"block",
"core-foundation 0.10.0",
"core-graphics-types 0.2.0",
@ -1627,6 +1627,15 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "convert_case"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "cookie"
version = "0.18.1"
@ -1691,7 +1700,7 @@ version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"core-foundation 0.10.0",
"core-graphics-types 0.2.0",
"foreign-types",
@ -1715,7 +1724,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"core-foundation 0.10.0",
"libc",
]
@ -1811,7 +1820,7 @@ version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"crossterm_winapi",
"parking_lot 0.12.3",
"rustix",
@ -2154,7 +2163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1b84d32b18d9a256d81e4fec2e4cfd0ab6dde5e5ff49be1713ae0adbd0060c2"
dependencies = [
"heck 0.5.0",
"indexmap 1.9.3",
"indexmap 2.7.0",
"itertools",
"proc-macro-crate 3.2.0",
"proc-macro2",
@ -2226,7 +2235,16 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05"
dependencies = [
"derive_more-impl",
"derive_more-impl 1.0.0",
]
[[package]]
name = "derive_more"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678"
dependencies = [
"derive_more-impl 2.0.1",
]
[[package]]
@ -2242,6 +2260,19 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "derive_more-impl"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
dependencies = [
"convert_case 0.7.1",
"proc-macro2",
"quote",
"syn 2.0.90",
"unicode-xid",
]
[[package]]
name = "dialoguer"
version = "0.11.0"
@ -2658,7 +2689,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [
"libc",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@ -2872,9 +2903,9 @@ dependencies = [
[[package]]
name = "fs-mistrust"
version = "0.8.2"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "050503efe568c5c90c13ef9b6a47fd5b657fb9605d6230a179aa190d004b65db"
checksum = "b28d81b7d2feb4197784e984a09c9799404a7793ed2352a54cb2aff98a31d48a"
dependencies = [
"derive_builder_fork_arti",
"dirs",
@ -3054,7 +3085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb"
dependencies = [
"futures-io",
"rustls 0.23.19",
"rustls 0.23.26",
"rustls-pki-types",
]
@ -3213,6 +3244,19 @@ dependencies = [
"x11",
]
[[package]]
name = "generator"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd"
dependencies = [
"cfg-if",
"libc",
"log",
"rustversion",
"windows 0.58.0",
]
[[package]]
name = "generic-array"
version = "0.14.7"
@ -3319,7 +3363,7 @@ version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"libc",
"libgit2-sys",
"log",
@ -3332,7 +3376,7 @@ version = "0.18.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"futures-channel",
"futures-core",
"futures-executor",
@ -3892,7 +3936,7 @@ dependencies = [
"http 1.1.0",
"hyper 1.5.1",
"hyper-util",
"rustls 0.23.19",
"rustls 0.23.26",
"rustls-pki-types",
"tokio",
"tokio-rustls 0.26.0",
@ -4579,7 +4623,7 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"serde",
"unicode-segmentation",
]
@ -5015,7 +5059,7 @@ dependencies = [
"quinn",
"rand 0.8.5",
"ring 0.17.8",
"rustls 0.23.19",
"rustls 0.23.26",
"socket2",
"thiserror 1.0.69",
"tokio",
@ -5153,7 +5197,7 @@ dependencies = [
"libp2p-identity",
"rcgen",
"ring 0.17.8",
"rustls 0.23.19",
"rustls 0.23.26",
"rustls-webpki 0.101.7",
"thiserror 1.0.69",
"x509-parser 0.16.0",
@ -5197,7 +5241,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"libc",
"redox_syscall 0.5.7",
]
@ -5259,6 +5303,19 @@ version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "loom"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca"
dependencies = [
"cfg-if",
"generator",
"scoped-tls",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "lru"
version = "0.12.5"
@ -5457,6 +5514,28 @@ dependencies = [
"tokio",
]
[[package]]
name = "moka"
version = "0.12.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926"
dependencies = [
"async-lock 3.4.0",
"crossbeam-channel",
"crossbeam-epoch",
"crossbeam-utils",
"event-listener 5.3.1",
"futures-util",
"loom",
"parking_lot 0.12.3",
"portable-atomic",
"rustc_version",
"smallvec",
"tagptr",
"thiserror 1.0.69",
"uuid",
]
[[package]]
name = "monero"
version = "0.12.0"
@ -5613,7 +5692,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"jni-sys",
"log",
"ndk-sys",
@ -5725,7 +5804,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"cfg-if",
"cfg_aliases",
"libc",
@ -5760,7 +5839,7 @@ version = "7.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c533b4c39709f9ba5005d8002048266593c1cfaf3c5f0739d5b8ab0c6c504009"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"filetime",
"inotify",
"kqueue",
@ -5774,9 +5853,9 @@ dependencies = [
[[package]]
name = "notify-types"
version = "1.0.0"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7393c226621f817964ffb3dc5704f9509e107a8b024b489cc2c1b217378785df"
checksum = "585d3cb5e12e01aed9e8a1f70d5c6b5e86fe2a6e48fc8cd0b3e0b8df6f6eb174"
dependencies = [
"instant",
]
@ -5937,7 +6016,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"block2",
"libc",
"objc2",
@ -5953,7 +6032,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-core-location",
@ -5977,7 +6056,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-foundation",
@ -6019,7 +6098,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"block2",
"libc",
"objc2",
@ -6043,7 +6122,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-foundation",
@ -6055,7 +6134,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-foundation",
@ -6078,7 +6157,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-cloud-kit",
@ -6110,7 +6189,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-core-location",
@ -6123,7 +6202,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68bc69301064cebefc6c4c90ce9cba69225239e4b8ff99d445a2b5563797da65"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-app-kit",
@ -6712,6 +6791,12 @@ dependencies = [
"universal-hash",
]
[[package]]
name = "portable-atomic"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
name = "postage"
version = "0.5.0"
@ -6876,7 +6961,7 @@ checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d"
dependencies = [
"bit-set",
"bit-vec",
"bitflags 2.6.0",
"bitflags 2.9.0",
"lazy_static",
"num-traits",
"rand 0.8.5",
@ -6991,7 +7076,7 @@ dependencies = [
"quinn-proto",
"quinn-udp",
"rustc-hash 2.1.0",
"rustls 0.23.19",
"rustls 0.23.26",
"socket2",
"thiserror 2.0.4",
"tokio",
@ -7009,7 +7094,7 @@ dependencies = [
"rand 0.8.5",
"ring 0.17.8",
"rustc-hash 2.1.0",
"rustls 0.23.19",
"rustls 0.23.26",
"rustls-pki-types",
"slab",
"thiserror 2.0.4",
@ -7029,7 +7114,7 @@ dependencies = [
"once_cell",
"socket2",
"tracing",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@ -7199,7 +7284,7 @@ version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
]
[[package]]
@ -7291,7 +7376,7 @@ dependencies = [
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls 0.23.19",
"rustls 0.23.26",
"rustls-pemfile 2.2.0",
"rustls-pki-types",
"serde",
@ -7442,7 +7527,7 @@ version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"fallible-iterator",
"fallible-streaming-iterator",
"hashlink",
@ -7525,7 +7610,7 @@ version = "0.38.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"errno",
"libc",
"linux-raw-sys",
@ -7571,15 +7656,15 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.23.19"
version = "0.23.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1"
checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0"
dependencies = [
"log",
"once_cell",
"ring 0.17.8",
"rustls-pki-types",
"rustls-webpki 0.102.8",
"rustls-webpki 0.103.1",
"subtle",
"zeroize",
]
@ -7628,9 +7713,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
version = "1.10.0"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b"
checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
dependencies = [
"web-time",
]
@ -7647,9 +7732,9 @@ dependencies = [
[[package]]
name = "rustls-webpki"
version = "0.102.8"
version = "0.103.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03"
dependencies = [
"ring 0.17.8",
"rustls-pki-types",
@ -7693,11 +7778,11 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "safelog"
version = "0.4.2"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5738eff432cfb1f861b0d7d2cfc7c3fabef53b8585840f16ce2eb980c782133b"
checksum = "fba05ad561772e139a16a49088b2d332f659ef49953d56e09cf0f726784e5fdd"
dependencies = [
"derive_more 1.0.0",
"derive_more 2.0.1",
"educe",
"either",
"fluid-let",
@ -7767,6 +7852,12 @@ dependencies = [
"syn 2.0.90",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -7910,7 +8001,7 @@ version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"core-foundation 0.9.4",
"core-foundation-sys",
"libc",
@ -8584,7 +8675,7 @@ dependencies = [
"once_cell",
"paste",
"percent-encoding",
"rustls 0.23.19",
"rustls 0.23.26",
"rustls-pemfile 2.2.0",
"serde",
"serde_json",
@ -8646,7 +8737,7 @@ checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a"
dependencies = [
"atoi",
"base64 0.22.1",
"bitflags 2.6.0",
"bitflags 2.9.0",
"byteorder",
"bytes",
"crc",
@ -8688,7 +8779,7 @@ checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8"
dependencies = [
"atoi",
"base64 0.22.1",
"bitflags 2.6.0",
"bitflags 2.9.0",
"byteorder",
"crc",
"dotenvy",
@ -8941,6 +9032,7 @@ dependencies = [
"libp2p",
"libp2p-community-tor",
"mockito",
"moka",
"monero",
"monero-harness",
"monero-rpc",
@ -9074,7 +9166,7 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"core-foundation 0.9.4",
"system-configuration-sys",
]
@ -9102,13 +9194,19 @@ dependencies = [
"version-compare",
]
[[package]]
name = "tagptr"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417"
[[package]]
name = "tao"
version = "0.30.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6682a07cf5bab0b8a2bd20d0a542917ab928b5edb75ebd4eda6b05cbaab872da"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"cocoa",
"core-foundation 0.10.0",
"core-graphics 0.24.0",
@ -9552,7 +9650,7 @@ dependencies = [
"fastrand",
"once_cell",
"rustix",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@ -9802,7 +9900,7 @@ version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
dependencies = [
"rustls 0.23.19",
"rustls 0.23.26",
"rustls-pki-types",
"tokio",
]
@ -10006,7 +10104,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d97937a95abe1325ef00ee2fa712fe73cc5bf59ef56c7f2ab7cc22ae7f385334"
dependencies = [
"amplify",
"bitflags 2.6.0",
"bitflags 2.9.0",
"bytes",
"caret",
"derive-deftly",
@ -10646,7 +10744,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66f6a0f1d0639ac75b9c1e1ca5f8e7a09f88cb0d4944a75bd0a58a33ecad0299"
dependencies = [
"async-trait",
"bitflags 2.6.0",
"bitflags 2.9.0",
"derive_more 1.0.0",
"digest 0.10.7",
"futures",
@ -10680,7 +10778,7 @@ checksum = "8b06ea3442a7918df190ad633d70c0da52b0e90a07c3439d4e3354f02448623e"
dependencies = [
"amplify",
"base64ct",
"bitflags 2.6.0",
"bitflags 2.9.0",
"cipher",
"derive_builder_fork_arti",
"derive_more 1.0.0",
@ -11868,7 +11966,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys 0.48.0",
"windows-sys 0.59.0",
]
[[package]]

View file

@ -43,6 +43,7 @@ jsonrpsee = { version = "0.16.2", features = [ "server" ] }
jsonrpsee-core = "0.16.2"
libp2p = { version = "0.53.2", features = [ "tcp", "yamux", "dns", "noise", "request-response", "ping", "rendezvous", "identify", "macros", "cbor", "json", "tokio", "serde", "rsa" ] }
libp2p-community-tor = { git = "https://github.com/umgefahren/libp2p-tor", branch = "main", features = [ "listen-onion-service" ] }
moka = { version = "0.12", features = [ "sync", "future" ] }
monero = { version = "0.12", features = [ "serde_support" ] }
monero-rpc = { path = "../monero-rpc" }
once_cell = "1.19"

View file

@ -16,6 +16,7 @@ use futures::stream::{FuturesUnordered, StreamExt};
use libp2p::request_response::{OutboundFailure, OutboundRequestId, ResponseChannel};
use libp2p::swarm::SwarmEvent;
use libp2p::{PeerId, Swarm};
use moka::future::Cache;
use rust_decimal::Decimal;
use std::collections::HashMap;
use std::convert::{Infallible, TryInto};
@ -25,6 +26,16 @@ use std::time::Duration;
use tokio::sync::{mpsc, oneshot};
use uuid::Uuid;
/// The time-to-live for quotes in the cache
const QUOTE_CACHE_TTL: Duration = Duration::from_secs(120);
/// The key for the quote cache
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct QuoteCacheKey {
min_buy: bitcoin::Amount,
max_buy: bitcoin::Amount,
}
#[allow(missing_debug_implementations)]
pub struct EventLoop<LR>
where
@ -40,6 +51,9 @@ where
max_buy: bitcoin::Amount,
external_redeem_address: Option<bitcoin::Address>,
/// Cache for quotes
quote_cache: Cache<QuoteCacheKey, Result<Arc<BidQuote>, Arc<anyhow::Error>>>,
swap_sender: mpsc::Sender<Swap>,
/// Stores where to send [`EncryptedSignature`]s to
@ -128,6 +142,8 @@ where
let (outgoing_transfer_proofs_sender, outgoing_transfer_proofs_requests) =
tokio::sync::mpsc::unbounded_channel();
let quote_cache = Cache::builder().time_to_live(QUOTE_CACHE_TTL).build();
let event_loop = EventLoop {
swarm,
env_config,
@ -139,6 +155,7 @@ where
min_buy,
max_buy,
external_redeem_address,
quote_cache,
recv_encrypted_signature: Default::default(),
inflight_encrypted_signatures: Default::default(),
outgoing_transfer_proofs_requests,
@ -232,16 +249,16 @@ where
tracing::warn!(%peer, "Ignoring spot price request: {}", error);
}
SwarmEvent::Behaviour(OutEvent::QuoteRequested { channel, peer }) => {
let quote = match self.make_quote(self.min_buy, self.max_buy).await {
Ok(quote) => quote,
Err(error) => {
tracing::warn!(%peer, "Failed to make quote: {:#}", error);
match self.make_quote_or_use_cached(self.min_buy, self.max_buy).await {
Ok(quote_arc) => {
if self.swarm.behaviour_mut().quote.send_response(channel, *quote_arc).is_err() {
tracing::debug!(%peer, "Failed to respond with quote");
}
}
Err(error_arc) => {
tracing::warn!(%peer, "Failed to make or retrieve quote: {:#}", error_arc);
continue;
}
};
if self.swarm.behaviour_mut().quote.send_response(channel, quote).is_err() {
tracing::debug!(%peer, "Failed to respond with quote");
}
}
SwarmEvent::Behaviour(OutEvent::TransferProofAcknowledged { peer, id }) => {
@ -462,66 +479,101 @@ where
}
}
/// Get a quote from the cache or calculate a new one by calling make_quote.
/// Returns the result wrapped in Arcs for consistent caching.
async fn make_quote_or_use_cached(
&mut self,
min_buy: bitcoin::Amount,
max_buy: bitcoin::Amount,
) -> Result<Arc<BidQuote>, Arc<anyhow::Error>> {
// We use the min and max buy amounts to create a unique key for the cache
// Although these values stay constant over the lifetime of an instance of the asb, this might change in the future
let key = QuoteCacheKey { min_buy, max_buy };
// Check if we have a cached quote
let maybe_cached_quote = self.quote_cache.get(&key).await;
if let Some(cached_quote_result) = maybe_cached_quote {
tracing::trace!("Got a request for a quote, using cached value.");
return cached_quote_result;
}
// We have a cache miss, so we compute a new quote
tracing::trace!("Got a request for a quote, computing new quote.");
let result = self.make_quote(self.min_buy, self.max_buy).await;
// Insert the computed quote into the cache
// Need to clone it as insert takes ownership
self.quote_cache.insert(key, result.clone()).await;
// Return the computed quote
result
}
/// Computes a quote and returns the result wrapped in Arcs.
async fn make_quote(
&mut self,
min_buy: bitcoin::Amount,
max_buy: bitcoin::Amount,
) -> Result<BidQuote> {
) -> Result<Arc<BidQuote>, Arc<anyhow::Error>> {
let ask_price = self
.latest_rate
.latest_rate()
.context("Failed to get latest rate")?
.map_err(|e| Arc::new(anyhow!(e).context("Failed to get latest rate")))?
.ask()
.context("Failed to compute asking price")?;
.map_err(|e| Arc::new(e.context("Failed to compute asking price")))?;
let balance = self.monero_wallet.get_balance().await?;
// use unlocked monero balance for quote
let balance = self
.monero_wallet
.get_balance()
.await
.map_err(|e| Arc::new(e.context("Failed to get Monero balance")))?;
let xmr_balance = Amount::from_piconero(balance.unlocked_balance);
let max_bitcoin_for_monero =
xmr_balance
.max_bitcoin_for_price(ask_price)
.ok_or_else(|| {
anyhow!(
Arc::new(anyhow!(
"Bitcoin price ({}) x Monero ({}) overflow",
ask_price,
xmr_balance
)
))
})?;
tracing::trace!(%ask_price, %xmr_balance, %max_bitcoin_for_monero, "Computed quote");
if min_buy > max_bitcoin_for_monero {
tracing::trace!(
"Your Monero balance is too low to initiate a swap, as your minimum swap amount is {}. You could at most swap {}",
min_buy, max_bitcoin_for_monero
);
"Your Monero balance is too low to initiate a swap, as your minimum swap amount is {}. You could at most swap {}",
min_buy, max_bitcoin_for_monero
);
return Ok(BidQuote {
return Ok(Arc::new(BidQuote {
price: ask_price,
min_quantity: bitcoin::Amount::ZERO,
max_quantity: bitcoin::Amount::ZERO,
});
}));
}
if max_buy > max_bitcoin_for_monero {
tracing::trace!(
"Your Monero balance is too low to initiate a swap with the maximum swap amount {} that you have specified in your config. You can at most swap {}",
max_buy, max_bitcoin_for_monero
);
return Ok(BidQuote {
"Your Monero balance is too low to initiate a swap with the maximum swap amount {} that you have specified in your config. You can at most swap {}",
max_buy, max_bitcoin_for_monero
);
return Ok(Arc::new(BidQuote {
price: ask_price,
min_quantity: min_buy,
max_quantity: max_bitcoin_for_monero,
});
}));
}
Ok(BidQuote {
Ok(Arc::new(BidQuote {
price: ask_price,
min_quantity: min_buy,
max_quantity: max_buy,
})
}))
}
async fn handle_execution_setup_done(
@ -546,9 +598,6 @@ where
swap_id,
};
// TODO: Consider adding separate components for start/resume of swaps
// swaps save peer id so we can resume
match self.db.insert_peer_id(swap_id, bob_peer_id).await {
Ok(_) => {
if let Err(error) = self.swap_sender.send(swap).await {