diff --git a/Cargo.lock b/Cargo.lock index dafe99b..4f514c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.24.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] @@ -66,9 +66,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7413bbf62c40b5db916ad5a1c382df1affe42080e148d69932bb7f0a12f32e" +checksum = "b17c19591d57add4f0c47922877a48aae1f47074e3433436545f8948353b3bbb" dependencies = [ "alloy-consensus", "alloy-contract", @@ -106,7 +106,7 @@ dependencies = [ "index-core", "itertools 0.14.0", "otc-custody", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "rand 0.9.2", "reqwest 0.11.27", "rust_decimal", @@ -124,9 +124,9 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.2.9" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8ff73a143281cb77c32006b04af9c047a6b8fe5860e85a88ad325328965355" +checksum = "bf01dd83a1ca5e4807d0ca0223c9615e211ce5db0a9fd1443c2778cacf89b546" dependencies = [ "alloy-primitives", "num_enum", @@ -135,9 +135,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7345077623aaa080fc06735ac13b8fa335125c8550f9c4f64135a5bf6f79967" +checksum = "6a0dd3ed764953a6b20458b2b7abbfdc93d20d14b38babe1a70fe631a443a9f1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -154,15 +154,16 @@ dependencies = [ "rand 0.8.5", "secp256k1", "serde", + "serde_json", "serde_with", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "alloy-consensus-any" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501f83565d28bdb9d6457dd3b5d646e19db37709d0f27608a26a1839052ddade" +checksum = "9556182afa73cddffa91e64a5aa9508d5e8c912b3a15f26998d2388a824d2c7b" dependencies = [ "alloy-consensus", "alloy-eips", @@ -174,9 +175,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c36bb4173892aeeba1c6b9e4eff923fa3fe8583f6d3e07afe1cbc5a96a853a" +checksum = "b19d7092c96defc3d132ee0d8969ca1b79ef512b5eda5c66e3065266b253adf2" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -192,14 +193,14 @@ dependencies = [ "futures", "futures-util", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "alloy-core" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe6c56d58fbfa9f0f6299376e8ce33091fc6494239466814c3f54b55743cb09" +checksum = "575053cea24ea8cb7e775e39d5c53c33b19cfd0ca1cf6c0fd653f3d8c682095f" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -210,9 +211,9 @@ dependencies = [ [[package]] name = "alloy-dyn-abi" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f56873f3cac7a2c63d8e98a4314b8311aa96adb1a0f82ae923eb2119809d2c" +checksum = "a6c2905bafc2df7ccd32ca3af13f0b0d82f2e2ff9dfbeb12196c0d978d5c0deb" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -234,7 +235,7 @@ dependencies = [ "alloy-rlp", "crc", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -258,14 +259,14 @@ dependencies = [ "alloy-rlp", "k256 0.13.4", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "alloy-eips" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c219a87fb386a75780ddbdbbced242477321887e426b0f946c05815ceabe5e09" +checksum = "305fa99b538ca7006b0c03cfed24ec6d82beda67aac857ef4714be24231d15e6" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -280,7 +281,7 @@ dependencies = [ "serde", "serde_with", "sha2 0.10.9", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -299,7 +300,7 @@ dependencies = [ "index-core", "itertools 0.14.0", "merkle-tree-rs", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "rand 0.9.2", "reqwest 0.11.27", "rust_decimal", @@ -317,9 +318,9 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dbf4c6b1b733ba0efaa6cc5f68786997a19ffcd88ff2ee2ba72fdd42594375e" +checksum = "a272533715aefc900f89d51db00c96e6fd4f517ea081a12fea482a352c8c815c" dependencies = [ "alloy-eips", "alloy-primitives", @@ -331,9 +332,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "125a1c373261b252e53e04d6e92c37d881833afc1315fceab53fd46045695640" +checksum = "a2acb6637a9c0e1cdf8971e0ced8f3fa34c04c5e9dccf6bb184f6a64fe0e37d8" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -343,16 +344,16 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "334555c323fa2bb98f1d4c242b62da9de8c715557a2ed680a76cefbcac19fefd" +checksum = "d91676d242c0ced99c0dd6d0096d7337babe9457cc43407d26aa6367fcf90553" dependencies = [ "alloy-primitives", "alloy-sol-types", "http 1.3.1", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", ] @@ -370,9 +371,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7ea377c9650203d7a7da9e8dee7f04906b49a9253f554b110edd7972e75ef34" +checksum = "77f82150116b30ba92f588b87f08fa97a46a1bd5ffc0d0597efdf0843d36bfda" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -391,14 +392,14 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "alloy-network-primitives" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f9ab9a9e92c49a357edaee2d35deea0a32ac8f313cfa37448f04e7e029c9d9" +checksum = "223612259a080160ce839a4e5df0125ca403a1d5e7206cc911cea54af5d769aa" dependencies = [ "alloy-consensus", "alloy-eips", @@ -409,18 +410,18 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc9485c56de23438127a731a6b4c87803d49faf1a7068dcd1d8768aca3a9edb9" +checksum = "5b77f7d5e60ad8ae6bd2200b8097919712a07a6db622a4b201e7ead6166f02e5" dependencies = [ "alloy-rlp", "bytes", "cfg-if", "const-hex", "derive_more 2.0.1", - "foldhash", - "hashbrown 0.15.5", - "indexmap 2.11.0", + "foldhash 0.2.0", + "hashbrown 0.16.0", + "indexmap 2.11.4", "itoa", "k256 0.13.4", "keccak-asm", @@ -436,9 +437,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a85361c88c16116defbd98053e3d267054d6b82729cdbef0236f7881590f924" +checksum = "f7283b81b6f136100b152e699171bc7ed8184a58802accbc91a7df4ebb944445" dependencies = [ "alloy-chains", "alloy-consensus", @@ -468,12 +469,12 @@ dependencies = [ "futures", "futures-utils-wasm", "lru", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "pin-project", "reqwest 0.12.23", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", "url", @@ -482,9 +483,9 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b1eda077b102b167effaf0c9d9109b1232948a6c7fcaff74abdb5deb562a17" +checksum = "eee7e3d343814ec0dfea69bd1820042a133a9d0b9ac5faf1e6eb133b43366315" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -492,7 +493,7 @@ dependencies = [ "auto_impl 1.3.0", "bimap", "futures", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "serde", "serde_json", "tokio", @@ -526,9 +527,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743fc964abb0106e454e9e8683fb0809fb32940270ef586a58e913531360b302" +checksum = "1154b12d470bef59951c62676e106f4ce5de73b987d86b9faa935acebb138ded" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -552,9 +553,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6445ccdc73c8a97e1794e9f0f91af52fb2bbf9ff004339a801b0293c3928abb" +checksum = "47ab76bf97648a1c6ad8fb00f0d594618942b5a9e008afbfb5c8a8fca800d574" dependencies = [ "alloy-primitives", "alloy-rpc-types-anvil", @@ -569,9 +570,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "242ff10318efd61c4b17ac8584df03a8db1e12146704c08b1b69d070cd4a1ebf" +checksum = "456cfc2c1677260edbd7ce3eddb7de419cb46de0e9826c43401f42b0286a779a" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -581,9 +582,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97372c51a14a804fb9c17010e3dd6c117f7866620b264e24b64d2259be44bcdf" +checksum = "23cc57ee0c1ac9fb14854195fc249494da7416591dc4a4d981ddfd5dd93b9bce" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -592,9 +593,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-debug" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a005a343cae9a0d4078d2f85a666493922d4bfb756229ea2a45a4bafd21cb9f1" +checksum = "4a0ac29dd005c33e3f7e09087accc80843315303685c3f7a1b888002cd27785b" dependencies = [ "alloy-primitives", "derive_more 2.0.1", @@ -604,9 +605,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e214c7667f88b2f7e48eb8428eeafcbf6faecda04175c5f4d13fdb2563333ac" +checksum = "1d9d173854879bcf26c7d71c1c3911972a3314df526f4349ffe488e676af577d" dependencies = [ "alloy-consensus", "alloy-eips", @@ -621,9 +622,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "672286c19528007df058bafd82c67e23247b4b3ebbc538cbddc705a82d8a930f" +checksum = "6d7d47bca1a2a1541e4404aa38b7e262bb4dffd9ac23b4f178729a4ddc5a5caa" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -637,28 +638,28 @@ dependencies = [ "serde", "serde_json", "serde_with", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "alloy-rpc-types-trace" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53c5ea8e10ca72889476343deb98c050da7b85e119a55a2a02a9791cb8242e4" +checksum = "c331c8e48665607682e8a9549a2347c13674d4fbcbdc342e7032834eba2424f4" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", "alloy-serde", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "alloy-rpc-types-txpool" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb1c7ee378e899353e05a0d9f5b73b5d57bdac257532c6acd98eaa6b093fe642" +checksum = "5e2f66afe1e76ca4485e593980056f061b2bdae2055486a062fca050ff111a52" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -668,9 +669,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aae653f049267ae7e040eab6c9b9a417064ca1a6cb21e3dd59b9f1131ef048f" +checksum = "6a8468f1a7f9ee3bae73c24eead0239abea720dbf7779384b9c7e20d51bfb6b0" dependencies = [ "alloy-primitives", "serde", @@ -679,9 +680,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97cedce202f848592b96f7e891503d3adb33739c4e76904da73574290141b93" +checksum = "33387c90b0a5021f45a5a77c2ce6c49b8f6980e66a318181468fb24cea771670" dependencies = [ "alloy-primitives", "async-trait", @@ -689,14 +690,14 @@ dependencies = [ "either", "elliptic-curve 0.13.8", "k256 0.13.4", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "alloy-signer-local" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83ae7d854db5b7cdd5b9ed7ad13d1e5e034cdd8be85ffef081f61dc6c9e18351" +checksum = "b55d9e795c85e36dcea08786d2e7ae9b73cb554b6bea6ac4c212def24e1b4d03" dependencies = [ "alloy-consensus", "alloy-network", @@ -705,14 +706,14 @@ dependencies = [ "async-trait", "k256 0.13.4", "rand 0.8.5", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "alloy-sol-macro" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20d867dcf42019d4779519a1ceb55eba8d7f3d0e4f0a89bcba82b8f9eb01e48" +checksum = "78c84c3637bee9b5c4a4d2b93360ee16553d299c3b932712353caf1cea76d0e6" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -724,15 +725,15 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b74e91b0b553c115d14bd0ed41898309356dc85d0e3d4b9014c4e7715e48c8ad" +checksum = "a882aa4e1790063362434b9b40d358942b188477ac1c44cfb8a52816ffc0cc17" dependencies = [ "alloy-json-abi", "alloy-sol-macro-input", "const-hex", "heck 0.5.0", - "indexmap 2.11.0", + "indexmap 2.11.4", "proc-macro-error2", "proc-macro2", "quote", @@ -743,9 +744,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84194d31220803f5f62d0a00f583fd3a062b36382e2bea446f1af96727754565" +checksum = "18e5772107f9bb265d8d8c86e0733937bb20d0857ea5425b1b6ddf51a9804042" dependencies = [ "alloy-json-abi", "const-hex", @@ -761,9 +762,9 @@ dependencies = [ [[package]] name = "alloy-sol-type-parser" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe8c27b3cf6b2bb8361904732f955bc7c05e00be5f469cec7e2280b6167f3ff0" +checksum = "e188b939aa4793edfaaa099cb1be4e620036a775b4bdf24fdc56f1cd6fd45890" dependencies = [ "serde", "winnow", @@ -771,9 +772,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5383d34ea00079e6dd89c652bcbdb764db160cef84e6250926961a0b2295d04" +checksum = "c3c8a9a909872097caffc05df134e5ef2253a1cdb56d3a9cf0052a042ac763f9" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -783,9 +784,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08b383bc903c927635e39e1dae7df2180877d93352d1abd389883665a598afc" +checksum = "702002659778d89a94cd4ff2044f6b505460df6c162e2f47d1857573845b0ace" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -794,10 +795,10 @@ dependencies = [ "derive_more 2.0.1", "futures", "futures-utils-wasm", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tower 0.5.2", "tracing", @@ -807,9 +808,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e58dee1f7763ef302074b645fc4f25440637c09a60e8de234b62993f06c0ae3" +checksum = "0d6bdc0830e5e8f08a4c70a4c791d400a86679c694a3b4b986caf26fad680438" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -822,9 +823,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ae5c6655e5cda1227f0c70b7686ecfb8af856771deebacad8dab9a7fbc51864" +checksum = "87ce41d99a32346f354725fe62eadd271cdbae45fe6b3cc40cb054e0bf763112" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -842,15 +843,15 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb2141958a1f13722cb20a2e01c130fb375209fa428849ae553c1518bc33a0d" +checksum = "686219dcef201655763bd3d4eabe42388d9368bfbf6f1c8016d14e739ec53aac" dependencies = [ "alloy-pubsub", "alloy-transport", "futures", "http 1.3.1", - "rustls 0.23.31", + "rustls 0.23.32", "serde_json", "tokio", "tokio-tungstenite 0.26.2", @@ -876,23 +877,17 @@ dependencies = [ [[package]] name = "alloy-tx-macros" -version = "1.0.27" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d14809f908822dbff0dc472c77ca4aa129ab12e22fd9bff2dd1ef54603e68e3d" +checksum = "7bf39928a5e70c9755d6811a2928131b53ba785ad37c8bf85c90175b5d43b818" dependencies = [ "alloy-primitives", - "darling 0.20.11", + "darling 0.21.3", "proc-macro2", "quote", "syn 2.0.106", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -904,9 +899,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -919,9 +914,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -991,9 +986,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "approx" @@ -1048,6 +1043,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +dependencies = [ + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "educe", + "itertools 0.13.0", + "num-bigint", + "num-traits", + "paste", + "zeroize", +] + [[package]] name = "ark-ff-asm" version = "0.3.0" @@ -1068,6 +1083,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.106", +] + [[package]] name = "ark-ff-macros" version = "0.3.0" @@ -1093,6 +1118,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "ark-serialize" version = "0.3.0" @@ -1114,6 +1152,18 @@ dependencies = [ "num-bigint", ] +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "num-bigint", +] + [[package]] name = "ark-std" version = "0.3.0" @@ -1134,6 +1184,16 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "ark-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + [[package]] name = "arrayvec" version = "0.7.6" @@ -1290,13 +1350,13 @@ dependencies = [ "eyre", "futures-util", "itertools 0.14.0", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "rand 0.9.2", "rust_decimal", "serde", "serde_json", "symm-core", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-util", "tracing", @@ -1324,9 +1384,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.75" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", @@ -1334,7 +1394,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] @@ -1418,7 +1478,7 @@ dependencies = [ "futures-util", "itertools 0.14.0", "market-data", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "rand 0.9.2", "rust_decimal", "serde", @@ -1439,14 +1499,14 @@ dependencies = [ "eyre", "futures-util", "itertools 0.14.0", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "rust_decimal", "safe-math", "serde", "serde_json", "symm-core", "test-case", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-util", "tracing", @@ -1480,7 +1540,7 @@ dependencies = [ "serde_json", "serde_repr", "sha2 0.10.9", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-native-tls", "tokio-stream", @@ -1551,7 +1611,7 @@ dependencies = [ "eyre", "futures-util", "itertools 0.14.0", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "rand 0.9.2", "rust_decimal", "serde", @@ -1625,9 +1685,9 @@ dependencies = [ [[package]] name = "blst" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fd49896f12ac9b6dcd7a5998466b9b58263a695a3dd1ecc1aaca2e12a90b080" +checksum = "dcdb4c7013139a150f9fc55d123186dbfaba0d912817466282c73ac49e71fb45" dependencies = [ "cc", "glob", @@ -1706,9 +1766,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.23.2" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" [[package]] name = "byteorder" @@ -1727,9 +1787,9 @@ dependencies = [ [[package]] name = "c-kzg" -version = "2.1.1" +version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7318cfa722931cb5fe0838b98d3ce5621e75f6a6408abc21721d80de9223f2e4" +checksum = "e00bf4b112b07b505472dbefd19e37e53307e2bfed5a79e0cc161d58ccd0e687" dependencies = [ "blst", "cc", @@ -1742,11 +1802,11 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.12" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0b03af37dad7a14518b7691d81acb0f8222604ad3d1b02f6b4bed5188c0cd5" +checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -1766,7 +1826,7 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.26", + "semver 1.0.27", "serde", "serde_json", "thiserror 1.0.69", @@ -1774,9 +1834,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.35" +version = "1.2.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "590f9024a68a8c40351881787f1934dc11afd69090f5edb6831464694d836ea3" +checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" dependencies = [ "find-msvc-tools", "shlex", @@ -1796,17 +1856,16 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -1821,9 +1880,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ "clap_builder", "clap_derive", @@ -1831,9 +1890,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", @@ -1924,15 +1983,14 @@ checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "const-hex" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dccd746bf9b1038c0507b7cec21eb2b11222db96a2902c96e8c185d6d20fb9c4" +checksum = "b6407bff74dea37e0fa3dc1c1c974e5d46405f0c987bf9997a0762adce71eda6" dependencies = [ "cfg-if", "cpufeatures", - "hex", "proptest", - "serde", + "serde_core", ] [[package]] @@ -1943,9 +2001,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_format" -version = "0.2.34" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" dependencies = [ "const_format_proc_macros", ] @@ -2184,12 +2242,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ - "darling_core 0.20.11", - "darling_macro 0.20.11", + "darling_core 0.21.3", + "darling_macro 0.21.3", ] [[package]] @@ -2208,14 +2266,15 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", + "serde", "strsim 0.11.1", "syn 2.0.106", ] @@ -2233,11 +2292,11 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ - "darling_core 0.20.11", + "darling_core 0.21.3", "quote", "syn 2.0.106", ] @@ -2253,7 +2312,7 @@ dependencies = [ "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.11", + "parking_lot_core 0.9.12", ] [[package]] @@ -2284,12 +2343,12 @@ dependencies = [ [[package]] name = "deranged" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" dependencies = [ "powerfmt", - "serde", + "serde_core", ] [[package]] @@ -2506,6 +2565,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "either" version = "1.15.0" @@ -2564,6 +2635,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum-ordinalize" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -2572,12 +2663,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2776,7 +2867,7 @@ dependencies = [ "ethers-core", "getrandom 0.2.16", "reqwest 0.11.27", - "semver 1.0.26", + "semver 1.0.27", "serde", "serde-aux", "serde_json", @@ -2891,7 +2982,7 @@ dependencies = [ "k256 0.13.4", "market-data", "otc-custody", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "rand 0.9.2", "reqwest 0.11.27", "rust_decimal", @@ -2976,9 +3067,9 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "find-msvc-tools" -version = "0.1.0" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e178e4fba8a2726903f6ba98a6d221e76f9c12c650d5dc0e6afdc50677b49650" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" [[package]] name = "fixed-hash" @@ -2994,9 +3085,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" dependencies = [ "crc32fast", "miniz_oxide", @@ -3014,6 +3105,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.3.2" @@ -3204,16 +3301,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", - "wasi 0.14.3+wasi-0.2.4", + "wasi 0.14.7+wasi-0.2.4", + "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "glob" @@ -3255,7 +3354,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.11.0", + "indexmap 2.11.4", "slab", "tokio", "tokio-util", @@ -3274,7 +3373,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.3.1", - "indexmap 2.11.0", + "indexmap 2.11.4", "slab", "tokio", "tokio-util", @@ -3304,7 +3403,16 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "foldhash 0.2.0", "serde", ] @@ -3340,9 +3448,6 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] [[package]] name = "hex-conservative" @@ -3500,11 +3605,12 @@ dependencies = [ "http 1.3.1", "hyper 1.7.0", "hyper-util", - "rustls 0.23.31", + "rustls 0.23.32", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.2", + "tokio-rustls 0.26.4", "tower-service", + "webpki-roots 1.0.3", ] [[package]] @@ -3538,9 +3644,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ "base64 0.22.1", "bytes", @@ -3564,9 +3670,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -3756,7 +3862,7 @@ dependencies = [ "intrusive-collections", "itertools 0.14.0", "opentelemetry", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "paste", "rust_decimal", "safe-math", @@ -3765,7 +3871,7 @@ dependencies = [ "string_cache", "symm-core", "test-case", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-util", "tracing", @@ -3818,7 +3924,7 @@ dependencies = [ "opentelemetry-semantic-conventions", "opentelemetry_sdk", "otc-custody", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "paste", "rand_core 0.6.4", "rust_decimal", @@ -3826,13 +3932,14 @@ dependencies = [ "safe-math", "serde", "serde_json", + "serde_with", "sha2 0.10.9", "statrs", "string_cache", "struple", "symm-core", "test-case", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-util", @@ -3874,13 +3981,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.0" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.16.0", "serde", + "serde_core", ] [[package]] @@ -3979,6 +4087,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.14.0" @@ -3996,9 +4113,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" dependencies = [ "once_cell", "wasm-bindgen", @@ -4059,9 +4176,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.175" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libm" @@ -4071,9 +4188,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "liquidity_tracker" @@ -4085,7 +4202,7 @@ dependencies = [ "eyre", "index-maker", "market-data", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "rust_decimal", "rust_decimal_macros", "safe-math", @@ -4105,19 +4222,18 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "lru" @@ -4128,6 +4244,12 @@ dependencies = [ "hashbrown 0.15.5", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "macro-string" version = "0.1.4" @@ -4147,7 +4269,7 @@ dependencies = [ "eyre", "futures-util", "itertools 0.14.0", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "rand 0.9.2", "rust_decimal", "serde", @@ -4185,9 +4307,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memoffset" @@ -4235,6 +4357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -4397,9 +4520,9 @@ dependencies = [ [[package]] name = "nybbles" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63cb50036b1ad148038105af40aaa70ff24d8a14fbc44ae5c914e1348533d12e" +checksum = "2c4b5ecbd0beec843101bffe848217f770e8b8da81d8355b7d6e226f2199b3dc" dependencies = [ "alloy-rlp", "cfg-if", @@ -4411,9 +4534,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] @@ -4495,9 +4618,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.5.2+3.5.2" +version = "300.5.3+3.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d270b79e2926f5150189d475bc7e9d2c69f9c4697b185fa917d5a32b792d21b4" +checksum = "dc6bad8cd0233b63971e232cc9c5e83039375b8586d2312f31fda85db8f888c2" dependencies = [ "cc", ] @@ -4525,7 +4648,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", ] @@ -4567,7 +4690,7 @@ dependencies = [ "opentelemetry_sdk", "prost", "reqwest 0.12.23", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", ] @@ -4602,7 +4725,7 @@ dependencies = [ "percent-encoding", "rand 0.9.2", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", ] @@ -4674,12 +4797,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", - "parking_lot_core 0.9.11", + "parking_lot_core 0.9.12", ] [[package]] @@ -4698,15 +4821,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.17", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] @@ -4746,12 +4869,11 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" dependencies = [ "memchr", - "thiserror 2.0.16", "ucd-trie", ] @@ -4878,11 +5000,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit", + "toml_edit 0.23.7", ] [[package]] @@ -4942,9 +5064,9 @@ dependencies = [ [[package]] name = "proptest" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f" +checksum = "2bb0be07becd10686a0bb407298fb425360a5c44a663774406340c59a22de4ce" dependencies = [ "bit-set", "bit-vec", @@ -5009,11 +5131,66 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls 0.23.32", + "socket2 0.6.0", + "thiserror 2.0.17", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "bytes", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash", + "rustls 0.23.32", + "rustls-pki-types", + "slab", + "thiserror 2.0.17", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.6.0", + "tracing", + "windows-sys 0.60.2", +] + [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -5140,27 +5317,27 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags 2.9.4", ] [[package]] name = "ref-cast" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", @@ -5169,9 +5346,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.2" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" dependencies = [ "aho-corasick", "memchr", @@ -5181,9 +5358,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" dependencies = [ "aho-corasick", "memchr", @@ -5287,6 +5464,8 @@ dependencies = [ "native-tls", "percent-encoding", "pin-project-lite", + "quinn", + "rustls 0.23.32", "rustls-pki-types", "serde", "serde_json", @@ -5294,6 +5473,7 @@ dependencies = [ "sync_wrapper 1.0.2", "tokio", "tokio-native-tls", + "tokio-rustls 0.26.4", "tower 0.5.2", "tower-http", "tower-service", @@ -5301,6 +5481,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots 1.0.3", ] [[package]] @@ -5414,13 +5595,14 @@ dependencies = [ [[package]] name = "ruint" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecb38f82477f20c5c3d62ef52d7c4e536e38ea9b73fb570a20c5cae0e14bcf6" +checksum = "a68df0380e5c9d20ce49534f292a36a7514ae21350726efe1865bdb1fa91d278" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", "ark-ff 0.4.2", + "ark-ff 0.5.0", "bytes", "fastrlp 0.3.1", "fastrlp 0.4.0", @@ -5434,7 +5616,7 @@ dependencies = [ "rand 0.9.2", "rlp", "ruint-macro", - "serde", + "serde_core", "valuable", "zeroize", ] @@ -5447,9 +5629,9 @@ checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rust_decimal" -version = "1.37.2" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b203a6425500a03e0919c42d3c47caca51e79f1132046626d2c8871c5092035d" +checksum = "c8975fc98059f365204d635119cf9c5a60ae67b841ed49b5422a9a7e56cdfac0" dependencies = [ "arrayvec", "borsh", @@ -5464,9 +5646,9 @@ dependencies = [ [[package]] name = "rust_decimal_macros" -version = "1.37.1" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6268b74858287e1a062271b988a0c534bf85bbeb567fe09331bf40ed78113d5" +checksum = "6dae310b657d2d686616e215c84c3119c675450d64c4b9f9e3467209191c3bcf" dependencies = [ "quote", "syn 2.0.106", @@ -5505,20 +5687,20 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.26", + "semver 1.0.27", ] [[package]] name = "rustix" -version = "1.0.8" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags 2.9.4", "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -5535,14 +5717,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.31" +version = "0.23.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.4", + "rustls-webpki 0.103.7", "subtle", "zeroize", ] @@ -5562,6 +5744,7 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ + "web-time", "zeroize", ] @@ -5577,9 +5760,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" dependencies = [ "ring", "rustls-pki-types", @@ -5594,9 +5777,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rusty-fork" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" dependencies = [ "fnv", "quick-error", @@ -5673,11 +5856,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -5803,9 +5986,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.14.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -5822,11 +6005,12 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" dependencies = [ "serde", + "serde_core", ] [[package]] @@ -5846,10 +6030,11 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] @@ -5874,11 +6059,20 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -5887,24 +6081,26 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] name = "serde_path_to_error" -version = "0.1.17" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" dependencies = [ "itoa", "serde", + "serde_core", ] [[package]] @@ -5941,19 +6137,18 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +checksum = "6093cd8c01b25262b84927e0f7151692158fab02d961e04c979d3903eba7ecc5" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.11.0", + "indexmap 2.11.4", "schemars 0.9.0", "schemars 1.0.4", - "serde", - "serde_derive", + "serde_core", "serde_json", "serde_with_macros", "time", @@ -5961,11 +6156,11 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +checksum = "a7e6c180db0816026a61afa1cff5344fb7ebded7e4d3062772179f2501481c27" dependencies = [ - "darling 0.20.11", + "darling 0.21.3", "proc-macro2", "quote", "syn 2.0.106", @@ -6092,6 +6287,12 @@ dependencies = [ "wide", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "simdutf8" version = "0.1.5" @@ -6139,6 +6340,31 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "solver_lambda" +version = "0.1.0" +dependencies = [ + "alloy", + "axum", + "axum-server", + "chrono", + "clap", + "crossbeam", + "eyre", + "hex", + "index-core", + "index-maker", + "itertools 0.14.0", + "parking_lot 0.12.5", + "rust_decimal", + "serde", + "serde_json", + "symm-core", + "tokio", + "tracing", + "tracing-subscriber", +] + [[package]] name = "spki" version = "0.6.0" @@ -6161,9 +6387,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "static_assertions" @@ -6191,7 +6417,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" dependencies = [ "new_debug_unreachable", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "phf_shared", "precomputed-hash", "serde", @@ -6297,7 +6523,7 @@ dependencies = [ "opentelemetry-otlp", "opentelemetry-semantic-conventions", "opentelemetry_sdk", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "paste", "rust_decimal", "safe-math", @@ -6305,7 +6531,7 @@ dependencies = [ "serde_json", "string_cache", "test-case", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-util", "tracing", @@ -6338,9 +6564,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0b198d366dbec045acfcd97295eb653a7a2b40e4dc764ef1e79aafcad439d3c" +checksum = "2375c17f6067adc651d8c2c51658019cef32edfff4a982adaf1d7fd1c039f08b" dependencies = [ "paste", "proc-macro2", @@ -6424,15 +6650,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.21.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", "getrandom 0.3.3", "once_cell", "rustix", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -6488,11 +6714,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.17", ] [[package]] @@ -6508,9 +6734,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -6537,11 +6763,12 @@ dependencies = [ [[package]] name = "time" -version = "0.3.43" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", + "itoa", "num-conv", "powerfmt", "serde", @@ -6610,7 +6837,7 @@ dependencies = [ "io-uring", "libc", "mio", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "pin-project-lite", "signal-hook-registry", "slab", @@ -6652,11 +6879,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.31", + "rustls 0.23.32", "tokio", ] @@ -6693,11 +6920,11 @@ dependencies = [ "futures-util", "log", "native-tls", - "rustls 0.23.31", + "rustls 0.23.32", "rustls-pki-types", "tokio", "tokio-native-tls", - "tokio-rustls 0.26.2", + "tokio-rustls 0.26.4", "tungstenite 0.26.2", "webpki-roots 0.26.11", ] @@ -6733,8 +6960,8 @@ checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", - "toml_datetime", - "toml_edit", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", ] [[package]] @@ -6746,20 +6973,50 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.11.0", + "indexmap 2.11.4", "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_write", "winnow", ] +[[package]] +name = "toml_edit" +version = "0.23.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" +dependencies = [ + "indexmap 2.11.4", + "toml_datetime 0.7.3", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +dependencies = [ + "winnow", +] + [[package]] name = "toml_write" version = "0.1.2" @@ -6976,7 +7233,7 @@ dependencies = [ "itertools 0.14.0", "market-data", "openssl", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "rust_decimal", "rust_decimal_macros", "safe-math", @@ -7025,18 +7282,18 @@ dependencies = [ "log", "native-tls", "rand 0.9.2", - "rustls 0.23.31", + "rustls 0.23.32", "rustls-pki-types", "sha1", - "thiserror 2.0.16", + "thiserror 2.0.17", "utf-8", ] [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ucd-trie" @@ -7070,9 +7327,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-segmentation" @@ -7198,30 +7455,40 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.3+wasi-0.2.4" +version = "0.14.7+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" dependencies = [ "bumpalo", "log", @@ -7233,9 +7500,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" dependencies = [ "cfg-if", "js-sys", @@ -7246,9 +7513,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7256,9 +7523,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", @@ -7269,9 +7536,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" dependencies = [ "unicode-ident", ] @@ -7299,7 +7566,7 @@ checksum = "1c598d6b99ea013e35844697fc4670d08339d5cda15588f193c6beedd12f644b" dependencies = [ "futures", "js-sys", - "parking_lot 0.12.4", + "parking_lot 0.12.5", "pin-utils", "slab", "wasm-bindgen", @@ -7307,9 +7574,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" dependencies = [ "js-sys", "wasm-bindgen", @@ -7337,14 +7604,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.2", + "webpki-roots 1.0.3", ] [[package]] name = "webpki-roots" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" dependencies = [ "rustls-pki-types", ] @@ -7361,9 +7628,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" [[package]] name = "winapi" @@ -7383,11 +7650,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -7398,22 +7665,22 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.61.2" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", ] [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -7422,9 +7689,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -7437,15 +7704,21 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-registry" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", ] [[package]] @@ -7454,7 +7727,16 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -7463,7 +7745,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -7499,7 +7790,16 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -7535,19 +7835,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -7564,9 +7864,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -7582,9 +7882,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -7600,9 +7900,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -7612,9 +7912,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -7630,9 +7930,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -7648,9 +7948,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -7666,9 +7966,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -7684,9 +7984,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" @@ -7709,9 +8009,9 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.45.0" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" @@ -7732,7 +8032,7 @@ dependencies = [ "pharos", "rustc_version 0.4.1", "send_wrapper", - "thiserror 2.0.16", + "thiserror 2.0.17", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -7773,18 +8073,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", @@ -7814,9 +8114,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "zeroize_derive", ] diff --git a/Cargo.toml b/Cargo.toml index 8551085..9d8f105 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ members = [ "apps/anvil_orchestrator", "apps/anvil_provisioner", "apps/index_deployer", + "apps/solver_lambda", "apps/tracker", "_deprecated/liquidity_tracker", "_deprecated/alloy-evm-connector", @@ -79,6 +80,7 @@ rust_decimal_macros = { workspace = true } safe-math = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } +serde_with = { workspace = true } sha2 = { workspace = true } statrs = { workspace = true } string_cache = { workspace = true } @@ -156,6 +158,7 @@ rust_decimal_macros = "1" safe-math = { path = "./proc-macros/safe-math" } serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.140" +serde_with = { version = "3.15.0", features = ["macros"] } sha2 = "0.10" statrs = "0.16" string_cache = "0.8.9" diff --git a/apps/solver_lambda/Cargo.toml b/apps/solver_lambda/Cargo.toml new file mode 100644 index 0000000..002ff1f --- /dev/null +++ b/apps/solver_lambda/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "solver_lambda" +version = "0.1.0" +edition = "2021" + +[dependencies] +alloy = { workspace = true } +axum = { workspace = true } +axum-server = { workspace = true } +chrono = { workspace = true } +clap = { workspace = true } +crossbeam = { workspace = true } +eyre = { workspace = true } +hex = { workspace = true } +index-core = { workspace = true } +index-maker = { workspace = true } +itertools = { workspace = true } +parking_lot = { workspace = true } +rust_decimal = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +symm-core = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } \ No newline at end of file diff --git a/apps/solver_lambda/example_data/1_input.json b/apps/solver_lambda/example_data/1_input.json new file mode 100644 index 0000000..073ca37 --- /dev/null +++ b/apps/solver_lambda/example_data/1_input.json @@ -0,0 +1,123 @@ +{ + "market_data_events": [ + { + "TopOfBook": { + "symbol": "BTCUSDC", + "sequence_number": 1, + "best_bid_price": "50000.0", + "best_ask_price": "50010.0", + "best_bid_quantity": "0.01", + "best_ask_quantity": "0.02" + } + }, + { + "TopOfBook": { + "symbol": "ETHUSDC", + "sequence_number": 1, + "best_bid_price": "5000.0", + "best_ask_price": "5010.0", + "best_bid_quantity": "0.05", + "best_ask_quantity": "0.09" + } + }, + { + "OrderBookSnapshot": { + "symbol": "BTCUSDC", + "sequence_number": 1, + "bid_updates": [ + { + "price": "50000.0", + "quantity": "0.01" + } + ], + "ask_updates": [ + { + "price": "50010.0", + "quantity": "0.02" + } + ] + } + }, + { + "OrderBookSnapshot": { + "symbol": "ETHUSDC", + "sequence_number": 1, + "bid_updates": [ + { + "price": "5000.0", + "quantity": "0.05" + } + ], + "ask_updates": [ + { + "price": "5010.0", + "quantity": "0.09" + } + ] + } + } + ], + "order_events": [], + "server_events": [ + { + "NewIndexOrder": { + "chain_id": 8453, + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "client_order_id": "C1", + "symbol": "SO2", + "side": "Buy", + "collateral_amount": "0.10", + "timestamp": "2025-10-09T13:28:00.000Z" + } + } + ], + "chain_events": [ + { + "Deposit": { + "chain_id": 8453, + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "seq_num": "0x1", + "amount": "0.10", + "timestamp": "2025-10-09T13:28:00.000Z" + } + } + ], + "router_events": [], + "state": { + "order_ids": [ + "O1", + "O2", + "O3", + "O4", + "O5", + "O6" + ], + "payment_ids": [ + "P1", + "P2" + ], + "batch_ids": [ + "B1", + "B2", + "B3" + ], + "indexes": [ + { + "symbol": "SO2", + "basket": [ + { + "pair": "BTCUSDC", + "weight": "0.5", + "quantity": "0.01" + }, + { + "pair": "ETHUSDC", + "weight": "0.5", + "quantity": "0.1" + } + ] + } + ] + }, + "timestamp": "2025-10-09T13:28:00.000Z" +} \ No newline at end of file diff --git a/apps/solver_lambda/example_data/1_output.json b/apps/solver_lambda/example_data/1_output.json new file mode 100644 index 0000000..b58d09a --- /dev/null +++ b/apps/solver_lambda/example_data/1_output.json @@ -0,0 +1,230 @@ +{ + "orders": [], + "server_responses": [ + { + "NewIndexOrderAck": { + "chain_id": 8453, + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "client_order_id": "C1", + "timestamp": "2025-10-09T13:28:00Z" + } + } + ], + "chain_commands": [ + { + "SolverWeightsSet": { + "symbol": "SO2", + "basket": [ + { + "pair": "BTCUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.01" + }, + { + "pair": "ETHUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.1" + } + ] + } + } + ], + "bridge_commands": [], + "state": { + "order_ids": [ + "O1", + "O2", + "O3", + "O4", + "O5", + "O6" + ], + "batch_ids": [ + "B1", + "B2", + "B3" + ], + "payment_ids": [ + "P2" + ], + "indexes": [ + { + "symbol": "SO2", + "basket": [ + { + "pair": "BTCUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.01" + }, + { + "pair": "ETHUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.1" + } + ] + } + ], + "index_orders": { + "index_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "SO2": { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "closed_updates": [], + "collateral_spent": "0", + "created_timestamp": "2025-10-09T13:28:00Z", + "engaged_collateral": null, + "engaged_side": null, + "engaged_updates": [], + "fees": "0", + "filled_quantity": "0", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "order_updates": [ + { + "client_order_id": "C1", + "collateral_spent": "0", + "engaged_collateral": null, + "filled_quantity": "0", + "original_collateral_amount": "0.1", + "remaining_collateral": "0.1", + "side": "Buy", + "timestamp": "2025-10-09T13:28:00Z", + "update_fee": "0" + } + ], + "remaining_collateral": "0.1", + "side": "Buy", + "symbol": "SO2" + } + } + ] + ] + }, + "invoices": { + "invoices": [] + }, + "collateral": { + "client_funds": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "side_cr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "open_lots": [ + { + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "payment_id": "P1", + "preauth_amount": "0", + "ready_amount": "0", + "seq_num": "0x1", + "spends": [], + "spent_amount": "0", + "unconfirmed_amount": "0.10" + } + ], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0.10" + }, + "side_dr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "open_lots": [], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0" + } + } + ] + ] + }, + "inventory": { + "positions": {} + }, + "batch": { + "batches": {}, + "carry_overs": [], + "engagements": {}, + "total_volley_size": "0" + }, + "orders": { + "orders": {} + }, + "solver": { + "client_orders": { + "client_notify_queue": [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ] + ], + "client_order_queues": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + [ + "C1" + ] + ] + ], + "client_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "C1" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "client_order_id": "C1", + "collateral_carried": "0", + "collateral_routed": "0", + "collateral_spent": "0", + "created_timestamp": "2025-10-09T13:28:00Z", + "engaged_collateral": "0", + "filled_quantity": "0", + "lots": [], + "payment_id": null, + "remaining_collateral": "0.1", + "side": "Buy", + "status": "Open", + "symbol": "SO2", + "timestamp": "2025-10-09T13:28:00Z" + } + ] + ], + "client_wait_period": [ + 5, + 0 + ] + }, + "ready_mints": [], + "ready_orders": [] + } + } +} \ No newline at end of file diff --git a/apps/solver_lambda/example_data/2_input.json b/apps/solver_lambda/example_data/2_input.json new file mode 100644 index 0000000..b56bf15 --- /dev/null +++ b/apps/solver_lambda/example_data/2_input.json @@ -0,0 +1,260 @@ +{ + "market_data_events": [ + { + "TopOfBook": { + "symbol": "BTCUSDC", + "sequence_number": 1, + "best_bid_price": "50000.0", + "best_ask_price": "50010.0", + "best_bid_quantity": "0.01", + "best_ask_quantity": "0.02" + } + }, + { + "TopOfBook": { + "symbol": "ETHUSDC", + "sequence_number": 1, + "best_bid_price": "5000.0", + "best_ask_price": "5010.0", + "best_bid_quantity": "0.05", + "best_ask_quantity": "0.09" + } + }, + { + "OrderBookSnapshot": { + "symbol": "BTCUSDC", + "sequence_number": 1, + "bid_updates": [ + { + "price": "50000.0", + "quantity": "0.01" + } + ], + "ask_updates": [ + { + "price": "50010.0", + "quantity": "0.02" + } + ] + } + }, + { + "OrderBookSnapshot": { + "symbol": "ETHUSDC", + "sequence_number": 1, + "bid_updates": [ + { + "price": "5000.0", + "quantity": "0.05" + } + ], + "ask_updates": [ + { + "price": "5010.0", + "quantity": "0.09" + } + ] + } + } + ], + "order_events": [], + "server_events": [], + "chain_events": [], + "router_events": [], + "timestamp": "2025-10-09T13:28:10.000Z", + "state": { + "order_ids": [ + "O1", + "O2", + "O3", + "O4", + "O5", + "O6" + ], + "batch_ids": [ + "B1", + "B2", + "B3" + ], + "payment_ids": [ + "P2" + ], + "indexes": [ + { + "symbol": "SO2", + "basket": [ + { + "pair": "BTCUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.01" + }, + { + "pair": "ETHUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.1" + } + ] + } + ], + "index_orders": { + "index_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "SO2": { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "closed_updates": [], + "collateral_spent": "0", + "created_timestamp": "2025-10-09T13:28:00Z", + "engaged_collateral": null, + "engaged_side": null, + "engaged_updates": [], + "fees": "0", + "filled_quantity": "0", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "order_updates": [ + { + "client_order_id": "C1", + "collateral_spent": "0", + "engaged_collateral": null, + "filled_quantity": "0", + "original_collateral_amount": "0.1", + "remaining_collateral": "0.1", + "side": "Buy", + "timestamp": "2025-10-09T13:28:00Z", + "update_fee": "0" + } + ], + "remaining_collateral": "0.1", + "side": "Buy", + "symbol": "SO2" + } + } + ] + ] + }, + "invoices": { + "invoices": [] + }, + "collateral": { + "client_funds": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "side_cr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "open_lots": [ + { + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "payment_id": "P1", + "preauth_amount": "0", + "ready_amount": "0", + "seq_num": "0x1", + "spends": [], + "spent_amount": "0", + "unconfirmed_amount": "0.10" + } + ], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0.10" + }, + "side_dr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "open_lots": [], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0" + } + } + ] + ] + }, + "inventory": { + "positions": {} + }, + "batch": { + "batches": {}, + "carry_overs": [], + "engagements": {}, + "total_volley_size": "0" + }, + "orders": { + "orders": {} + }, + "solver": { + "client_orders": { + "client_notify_queue": [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ] + ], + "client_order_queues": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + [ + "C1" + ] + ] + ], + "client_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "C1" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "client_order_id": "C1", + "collateral_carried": "0", + "collateral_routed": "0", + "collateral_spent": "0", + "created_timestamp": "2025-10-09T13:28:00Z", + "engaged_collateral": "0", + "filled_quantity": "0", + "lots": [], + "payment_id": null, + "remaining_collateral": "0.1", + "side": "Buy", + "status": "Open", + "symbol": "SO2", + "timestamp": "2025-10-09T13:28:00Z" + } + ] + ], + "client_wait_period": [ + 5, + 0 + ] + }, + "ready_mints": [], + "ready_orders": [] + } + } +} \ No newline at end of file diff --git a/apps/solver_lambda/example_data/2_output.json b/apps/solver_lambda/example_data/2_output.json new file mode 100644 index 0000000..80c222c --- /dev/null +++ b/apps/solver_lambda/example_data/2_output.json @@ -0,0 +1,230 @@ +{ + "orders": [], + "server_responses": [], + "chain_commands": [ + { + "SolverWeightsSet": { + "symbol": "SO2", + "basket": [ + { + "pair": "BTCUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.01" + }, + { + "pair": "ETHUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.1" + } + ] + } + } + ], + "bridge_commands": [ + { + "TransferFunds": { + "chain_id": 8453, + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "client_order_id": "C1", + "source": "Start:SO2:USDC", + "destination": "End:SO2:USDC", + "route_from": "Start:SO2:USDC", + "route_to": "End:SO2:USDC", + "amount": "0.1", + "cumulative_fee": "0" + } + } + ], + "state": { + "order_ids": [ + "O1", + "O2", + "O3", + "O4", + "O5", + "O6" + ], + "batch_ids": [ + "B1", + "B2", + "B3" + ], + "payment_ids": [ + "P2" + ], + "indexes": [ + { + "symbol": "SO2", + "basket": [ + { + "pair": "BTCUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.01" + }, + { + "pair": "ETHUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.1" + } + ] + } + ], + "index_orders": { + "index_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "SO2": { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "closed_updates": [], + "collateral_spent": "0", + "created_timestamp": "2025-10-09T13:28:00Z", + "engaged_collateral": null, + "engaged_side": null, + "engaged_updates": [], + "fees": "0", + "filled_quantity": "0", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "order_updates": [ + { + "client_order_id": "C1", + "collateral_spent": "0", + "engaged_collateral": null, + "filled_quantity": "0", + "original_collateral_amount": "0.1", + "remaining_collateral": "0.1", + "side": "Buy", + "timestamp": "2025-10-09T13:28:00Z", + "update_fee": "0" + } + ], + "remaining_collateral": "0.1", + "side": "Buy", + "symbol": "SO2" + } + } + ] + ] + }, + "invoices": { + "invoices": [] + }, + "collateral": { + "client_funds": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "side_cr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "open_lots": [ + { + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "payment_id": "P1", + "preauth_amount": "0", + "ready_amount": "0", + "seq_num": "0x1", + "spends": [], + "spent_amount": "0", + "unconfirmed_amount": "0.10" + } + ], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0.10" + }, + "side_dr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "open_lots": [], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0" + } + } + ] + ] + }, + "inventory": { + "positions": {} + }, + "batch": { + "batches": {}, + "carry_overs": [], + "engagements": {}, + "total_volley_size": "0" + }, + "orders": { + "orders": {} + }, + "solver": { + "client_orders": { + "client_notify_queue": [], + "client_order_queues": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + [ + "C1" + ] + ] + ], + "client_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "C1" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "client_order_id": "C1", + "collateral_carried": "0", + "collateral_routed": "0", + "collateral_spent": "0", + "created_timestamp": "2025-10-09T13:28:00Z", + "engaged_collateral": "0", + "filled_quantity": "0", + "lots": [], + "payment_id": null, + "remaining_collateral": "0.1", + "side": "Buy", + "status": "RouteCollateral", + "symbol": "SO2", + "timestamp": "2025-10-09T13:28:00Z" + } + ] + ], + "client_wait_period": [ + 5, + 0 + ] + }, + "ready_mints": [], + "ready_orders": [] + } + } +} \ No newline at end of file diff --git a/apps/solver_lambda/example_data/3_input.json b/apps/solver_lambda/example_data/3_input.json new file mode 100644 index 0000000..6d107ac --- /dev/null +++ b/apps/solver_lambda/example_data/3_input.json @@ -0,0 +1,271 @@ +{ + "market_data_events": [ + { + "TopOfBook": { + "symbol": "BTCUSDC", + "sequence_number": 1, + "best_bid_price": "50000.0", + "best_ask_price": "50010.0", + "best_bid_quantity": "0.01", + "best_ask_quantity": "0.02" + } + }, + { + "TopOfBook": { + "symbol": "ETHUSDC", + "sequence_number": 1, + "best_bid_price": "5000.0", + "best_ask_price": "5010.0", + "best_bid_quantity": "0.05", + "best_ask_quantity": "0.09" + } + }, + { + "OrderBookSnapshot": { + "symbol": "BTCUSDC", + "sequence_number": 1, + "bid_updates": [ + { + "price": "50000.0", + "quantity": "0.01" + } + ], + "ask_updates": [ + { + "price": "50010.0", + "quantity": "0.02" + } + ] + } + }, + { + "OrderBookSnapshot": { + "symbol": "ETHUSDC", + "sequence_number": 1, + "bid_updates": [ + { + "price": "5000.0", + "quantity": "0.05" + } + ], + "ask_updates": [ + { + "price": "5010.0", + "quantity": "0.09" + } + ] + } + } + ], + "order_events": [], + "server_events": [], + "chain_events": [], + "router_events": [ + { + "HopComplete": { + "chain_id": 8453, + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "client_order_id": "C1", + "timestamp": "2025-10-09T13:28:20.000Z", + "source": "Start:SO2:USDC", + "destination": "End:SO2:USDC", + "route_from": "Start:SO2:USDC", + "route_to": "End:SO2:USDC", + "amount": "0.10", + "fee": "0.00", + "status": "Success" + } + } + ], + "timestamp": "2025-10-09T13:28:20.000Z", + "state": { + "order_ids": [ + "O1", + "O2", + "O3", + "O4", + "O5", + "O6" + ], + "batch_ids": [ + "B1", + "B2", + "B3" + ], + "payment_ids": [ + "P2" + ], + "indexes": [ + { + "symbol": "SO2", + "basket": [ + { + "pair": "BTCUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.01" + }, + { + "pair": "ETHUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.1" + } + ] + } + ], + "index_orders": { + "index_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "SO2": { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "closed_updates": [], + "collateral_spent": "0", + "created_timestamp": "2025-10-09T13:28:00Z", + "engaged_collateral": null, + "engaged_side": null, + "engaged_updates": [], + "fees": "0", + "filled_quantity": "0", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "order_updates": [ + { + "client_order_id": "C1", + "collateral_spent": "0", + "engaged_collateral": null, + "filled_quantity": "0", + "original_collateral_amount": "0.1", + "remaining_collateral": "0.1", + "side": "Buy", + "timestamp": "2025-10-09T13:28:00Z", + "update_fee": "0" + } + ], + "remaining_collateral": "0.1", + "side": "Buy", + "symbol": "SO2" + } + } + ] + ] + }, + "invoices": { + "invoices": [] + }, + "collateral": { + "client_funds": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "side_cr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "open_lots": [ + { + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "payment_id": "P1", + "preauth_amount": "0", + "ready_amount": "0", + "seq_num": "0x1", + "spends": [], + "spent_amount": "0", + "unconfirmed_amount": "0.10" + } + ], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0.10" + }, + "side_dr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "open_lots": [], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0" + } + } + ] + ] + }, + "inventory": { + "positions": {} + }, + "batch": { + "batches": {}, + "carry_overs": [], + "engagements": {}, + "total_volley_size": "0" + }, + "orders": { + "orders": {} + }, + "solver": { + "client_orders": { + "client_notify_queue": [], + "client_order_queues": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + [ + "C1" + ] + ] + ], + "client_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "C1" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "client_order_id": "C1", + "collateral_carried": "0", + "collateral_routed": "0", + "collateral_spent": "0", + "created_timestamp": "2025-10-09T13:28:00Z", + "engaged_collateral": "0", + "filled_quantity": "0", + "lots": [], + "payment_id": null, + "remaining_collateral": "0.1", + "side": "Buy", + "status": "RouteCollateral", + "symbol": "SO2", + "timestamp": "2025-10-09T13:28:00Z" + } + ] + ], + "client_wait_period": [ + 5, + 0 + ] + }, + "ready_mints": [], + "ready_orders": [] + } + } +} \ No newline at end of file diff --git a/apps/solver_lambda/example_data/3_output.json b/apps/solver_lambda/example_data/3_output.json new file mode 100644 index 0000000..b5bd446 --- /dev/null +++ b/apps/solver_lambda/example_data/3_output.json @@ -0,0 +1,389 @@ +{ + "orders": [ + [ + "S1", + { + "order_id": "O2", + "batch_order_id": "B1", + "symbol": "BTCUSDC", + "side": "Buy", + "price": "50510.100", + "quantity": "0.0000989901029695051088792143", + "created_timestamp": "2025-10-09T13:28:20Z" + } + ], + [ + "S1", + { + "order_id": "O1", + "batch_order_id": "B1", + "symbol": "ETHUSDC", + "side": "Buy", + "price": "5060.100", + "quantity": "0.0009881227643722456077943124", + "created_timestamp": "2025-10-09T13:28:20Z" + } + ] + ], + "server_responses": [ + { + "IndexOrderFill": { + "chain_id": 8453, + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "client_order_id": "C1", + "filled_quantity": "0", + "collateral_spent": "0.00", + "collateral_remaining": "0.1", + "fill_rate": "0", + "status": "collateral ready", + "timestamp": "2025-10-09T13:28:20Z" + } + } + ], + "chain_commands": [ + { + "SolverWeightsSet": { + "symbol": "SO2", + "basket": [ + { + "pair": "BTCUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.01" + }, + { + "pair": "ETHUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.1" + } + ] + } + } + ], + "bridge_commands": [], + "state": { + "order_ids": [ + "O3", + "O4", + "O5", + "O6" + ], + "batch_ids": [ + "B2", + "B3" + ], + "payment_ids": [], + "indexes": [ + { + "symbol": "SO2", + "basket": [ + { + "pair": "BTCUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.01" + }, + { + "pair": "ETHUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.1" + } + ] + } + ], + "index_orders": { + "index_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "SO2": { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "closed_updates": [], + "collateral_spent": "0.00", + "created_timestamp": "2025-10-09T13:28:00Z", + "engaged_collateral": "0.1000000000000000000000000404", + "engaged_side": "Buy", + "engaged_updates": [ + { + "client_order_id": "C1", + "collateral_spent": "0.00", + "engaged_collateral": "0.1", + "filled_quantity": "0", + "original_collateral_amount": "0.1", + "remaining_collateral": "0.0", + "side": "Buy", + "timestamp": "2025-10-09T13:28:20Z", + "update_fee": "0.00" + } + ], + "fees": "0.00", + "filled_quantity": "0", + "last_update_timestamp": "2025-10-09T13:28:20Z", + "order_updates": [], + "remaining_collateral": "-0.0000000000000000000000000404", + "side": "Buy", + "symbol": "SO2" + } + } + ] + ] + }, + "invoices": { + "invoices": [] + }, + "collateral": { + "client_funds": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "side_cr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:20Z", + "open_lots": [ + { + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:20Z", + "payment_id": "P1", + "preauth_amount": "0.10", + "ready_amount": "0", + "seq_num": "0x1", + "spends": [ + { + "client_order_id": "C1", + "payment_id": "Charges", + "preauth_amount": "0", + "spent_amount": "0.00", + "timestamp": "2025-10-09T13:28:20Z" + }, + { + "client_order_id": "C1", + "payment_id": "P2", + "preauth_amount": "0.10", + "spent_amount": "0", + "timestamp": "2025-10-09T13:28:20Z" + } + ], + "spent_amount": "0.00", + "unconfirmed_amount": "0" + } + ], + "preauth_balance": "0.10", + "ready_balance": "0.00", + "spent_balance": "0.00", + "unconfirmed_balance": "0.00" + }, + "side_dr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "open_lots": [], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0" + } + } + ] + ] + }, + "inventory": { + "positions": {} + }, + "batch": { + "batches": { + "B1": { + "batch_order_id": "B1", + "fee": "0", + "filled_fraction": "0", + "filled_volley": "0", + "is_cancelled": false, + "last_update_timestamp": "2025-10-09T13:28:20Z", + "positions": [ + [ + [ + "BTCUSDC", + "Buy" + ], + { + "closed_lots": [], + "fee": "0", + "is_cancelled": false, + "last_update_timestamp": "2025-10-09T13:28:20Z", + "open_lots": [], + "order_quantity": "0.0000989901029695051088792143", + "position": "0", + "quantity_cancelled": "0", + "realized_value": "0", + "side": "Buy", + "symbol": "BTCUSDC", + "volley_size": "5.0000000000000000000000022144" + } + ], + [ + [ + "ETHUSDC", + "Buy" + ], + { + "closed_lots": [], + "fee": "0", + "is_cancelled": false, + "last_update_timestamp": "2025-10-09T13:28:20Z", + "open_lots": [], + "order_quantity": "0.0009881227643722456077943124", + "position": "0", + "quantity_cancelled": "0", + "realized_value": "0", + "side": "Buy", + "symbol": "ETHUSDC", + "volley_size": "5.0000000000000000000000001752" + } + ] + ], + "realized_value": "0", + "volley_size": "10.000000000000000000000002390" + } + }, + "carry_overs": [], + "engagements": { + "B1": { + "batch_order_id": "B1", + "engaged_buys": { + "asset_price_limits": { + "BTCUSDC": "50510.100", + "ETHUSDC": "5060.100" + }, + "asset_quantities": { + "BTCUSDC": "0.0000989901029695051088792143", + "ETHUSDC": "0.0009881227643722456077943124" + }, + "engaged_orders": [ + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "asset_contribution_fractions": { + "BTCUSDC": "1", + "ETHUSDC": "1" + }, + "asset_quantity_contributions": { + "BTCUSDC": "0.0000009870370236462347495698", + "ETHUSDC": "0.0000098703702364623474956979" + }, + "chain_id": 8453, + "client_order_id": "C1", + "engaged_collateral": "0.1000000000000000000000000404", + "engaged_price": "1011.11100", + "engaged_quantity": "0.0000987037023646234749569786", + "engaged_side": "Buy", + "filled_quantity": "0", + "new_engaged_collateral": "0.1000000000000000000000000404", + "symbol": "SO2" + } + ] + } + } + }, + "total_volley_size": "10.000000000000000000000002390" + }, + "orders": { + "orders": { + "O1": { + "order": { + "batch_order_id": "B1", + "created_timestamp": "2025-10-09T13:28:20Z", + "order_id": "O1", + "price": "5060.100", + "quantity": "0.0009881227643722456077943124", + "side": "Buy", + "symbol": "ETHUSDC" + }, + "session_id": "S1", + "status": { + "Sent": { + "order_quantity": "0.0009881227643722456077943124" + } + } + }, + "O2": { + "order": { + "batch_order_id": "B1", + "created_timestamp": "2025-10-09T13:28:20Z", + "order_id": "O2", + "price": "50510.100", + "quantity": "0.0000989901029695051088792143", + "side": "Buy", + "symbol": "BTCUSDC" + }, + "session_id": "S1", + "status": { + "Sent": { + "order_quantity": "0.0000989901029695051088792143" + } + } + } + } + }, + "solver": { + "client_orders": { + "client_notify_queue": [], + "client_order_queues": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + [ + "C1" + ] + ] + ], + "client_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "C1" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "client_order_id": "C1", + "collateral_carried": "0", + "collateral_routed": "0.10", + "collateral_spent": "0.00", + "created_timestamp": "2025-10-09T13:28:00Z", + "engaged_collateral": "0.1000000000000000000000000404", + "filled_quantity": "0", + "lots": [], + "payment_id": "P2", + "remaining_collateral": "0.0", + "side": "Buy", + "status": "Engaged", + "symbol": "SO2", + "timestamp": "2025-10-10T18:52:12.111660Z" + } + ] + ], + "client_wait_period": [ + 5, + 0 + ] + }, + "ready_mints": [], + "ready_orders": [] + } + } +} \ No newline at end of file diff --git a/apps/solver_lambda/example_data/4_input.json b/apps/solver_lambda/example_data/4_input.json new file mode 100644 index 0000000..f830c1a --- /dev/null +++ b/apps/solver_lambda/example_data/4_input.json @@ -0,0 +1,452 @@ +{ + "market_data_events": [ + { + "TopOfBook": { + "symbol": "BTCUSDC", + "sequence_number": 1, + "best_bid_price": "50000.0", + "best_ask_price": "50010.0", + "best_bid_quantity": "0.01", + "best_ask_quantity": "0.02" + } + }, + { + "TopOfBook": { + "symbol": "ETHUSDC", + "sequence_number": 1, + "best_bid_price": "5000.0", + "best_ask_price": "5010.0", + "best_bid_quantity": "0.05", + "best_ask_quantity": "0.09" + } + }, + { + "OrderBookSnapshot": { + "symbol": "BTCUSDC", + "sequence_number": 1, + "bid_updates": [ + { + "price": "50000.0", + "quantity": "0.01" + } + ], + "ask_updates": [ + { + "price": "50010.0", + "quantity": "0.02" + } + ] + } + }, + { + "OrderBookSnapshot": { + "symbol": "ETHUSDC", + "sequence_number": 1, + "bid_updates": [ + { + "price": "5000.0", + "quantity": "0.05" + } + ], + "ask_updates": [ + { + "price": "5010.0", + "quantity": "0.09" + } + ] + } + } + ], + "order_events": [ + { + "NewOrder": { + "order_id": "O1", + "symbol": "BTCUSDC", + "side": "Buy", + "price": "50510.100", + "quantity": "0.0000989901029695051088792143", + "timestamp": "2025-10-09T13:28:20Z" + } + }, + { + "NewOrder": { + "order_id": "O2", + "symbol": "ETHUSDC", + "side": "Buy", + "price": "5060.100", + "quantity": "0.0009881227643722456077943124", + "timestamp": "2025-10-09T13:28:20Z" + } + }, + { + "Fill": { + "order_id": "O1", + "lot_id": "O1-1", + "symbol": "BTCUSDC", + "side": "Buy", + "price": "50510.100", + "quantity": "0.0000989901029695051088792143", + "fee": "0.00", + "timestamp": "2025-10-09T13:28:20Z" + } + }, + { + "Fill": { + "order_id": "O2", + "lot_id": "O2-1", + "symbol": "ETHUSDC", + "side": "Buy", + "price": "5060.100", + "quantity": "0.0009881227643722456077943124", + "fee": "0.00", + "timestamp": "2025-10-09T13:28:20Z" + } + }, + { + "Cancel": { + "order_id": "O2", + "symbol": "BTCUSDC", + "side": "Buy", + "quantity": "0.0", + "timestamp": "2025-10-09T13:28:20Z" + } + }, + { + "Cancel": { + "order_id": "O2", + "symbol": "ETHUSDC", + "side": "Buy", + "quantity": "0.0", + "timestamp": "2025-10-09T13:28:20Z" + } + } + ], + "server_events": [], + "chain_events": [], + "router_events": [], + "timestamp": "2025-10-09T13:28:10.000Z", + "state": { + "order_ids": [ + "O3", + "O4", + "O5", + "O6" + ], + "batch_ids": [ + "B2", + "B3" + ], + "payment_ids": [], + "indexes": [ + { + "symbol": "SO2", + "basket": [ + { + "pair": "BTCUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.01" + }, + { + "pair": "ETHUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.1" + } + ] + } + ], + "index_orders": { + "index_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "SO2": { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "closed_updates": [], + "collateral_spent": "0.00", + "created_timestamp": "2025-10-09T13:28:00Z", + "engaged_collateral": "0.1000000000000000000000000404", + "engaged_side": "Buy", + "engaged_updates": [ + { + "client_order_id": "C1", + "collateral_spent": "0.00", + "engaged_collateral": "0.1", + "filled_quantity": "0", + "original_collateral_amount": "0.1", + "remaining_collateral": "0.0", + "side": "Buy", + "timestamp": "2025-10-09T13:28:20Z", + "update_fee": "0.00" + } + ], + "fees": "0.00", + "filled_quantity": "0", + "last_update_timestamp": "2025-10-09T13:28:20Z", + "order_updates": [], + "remaining_collateral": "-0.0000000000000000000000000404", + "side": "Buy", + "symbol": "SO2" + } + } + ] + ] + }, + "invoices": { + "invoices": [] + }, + "collateral": { + "client_funds": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "side_cr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:20Z", + "open_lots": [ + { + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:20Z", + "payment_id": "P1", + "preauth_amount": "0.10", + "ready_amount": "0", + "seq_num": "0x1", + "spends": [ + { + "client_order_id": "C1", + "payment_id": "Charges", + "preauth_amount": "0", + "spent_amount": "0.00", + "timestamp": "2025-10-09T13:28:20Z" + }, + { + "client_order_id": "C1", + "payment_id": "P2", + "preauth_amount": "0.10", + "spent_amount": "0", + "timestamp": "2025-10-09T13:28:20Z" + } + ], + "spent_amount": "0.00", + "unconfirmed_amount": "0" + } + ], + "preauth_balance": "0.10", + "ready_balance": "0.00", + "spent_balance": "0.00", + "unconfirmed_balance": "0.00" + }, + "side_dr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "open_lots": [], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0" + } + } + ] + ] + }, + "inventory": { + "positions": {} + }, + "batch": { + "batches": { + "B1": { + "batch_order_id": "B1", + "fee": "0", + "filled_fraction": "0", + "filled_volley": "0", + "is_cancelled": false, + "last_update_timestamp": "2025-10-09T13:28:20Z", + "positions": [ + [ + [ + "ETHUSDC", + "Buy" + ], + { + "closed_lots": [], + "fee": "0", + "is_cancelled": false, + "last_update_timestamp": "2025-10-09T13:28:20Z", + "open_lots": [], + "order_quantity": "0.0009881227643722456077943124", + "position": "0", + "quantity_cancelled": "0", + "realized_value": "0", + "side": "Buy", + "symbol": "ETHUSDC", + "volley_size": "5.0000000000000000000000001752" + } + ], + [ + [ + "BTCUSDC", + "Buy" + ], + { + "closed_lots": [], + "fee": "0", + "is_cancelled": false, + "last_update_timestamp": "2025-10-09T13:28:20Z", + "open_lots": [], + "order_quantity": "0.0000989901029695051088792143", + "position": "0", + "quantity_cancelled": "0", + "realized_value": "0", + "side": "Buy", + "symbol": "BTCUSDC", + "volley_size": "5.0000000000000000000000022144" + } + ] + ], + "realized_value": "0", + "volley_size": "10.000000000000000000000002390" + } + }, + "carry_overs": [], + "engagements": { + "B1": { + "batch_order_id": "B1", + "engaged_buys": { + "asset_price_limits": { + "BTCUSDC": "50510.100", + "ETHUSDC": "5060.100" + }, + "asset_quantities": { + "BTCUSDC": "0.0000989901029695051088792143", + "ETHUSDC": "0.0009881227643722456077943124" + }, + "engaged_orders": [ + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "asset_contribution_fractions": { + "BTCUSDC": "1", + "ETHUSDC": "1" + }, + "asset_quantity_contributions": { + "BTCUSDC": "0.0000009870370236462347495698", + "ETHUSDC": "0.0000098703702364623474956979" + }, + "chain_id": 8453, + "client_order_id": "C1", + "engaged_collateral": "0.1000000000000000000000000404", + "engaged_price": "1011.11100", + "engaged_quantity": "0.0000987037023646234749569786", + "engaged_side": "Buy", + "filled_quantity": "0", + "new_engaged_collateral": "0.1000000000000000000000000404", + "symbol": "SO2" + } + ] + } + } + }, + "total_volley_size": "10.000000000000000000000002390" + }, + "orders": { + "orders": { + "O1": { + "order": { + "batch_order_id": "B1", + "created_timestamp": "2025-10-09T13:28:20Z", + "order_id": "O1", + "price": "50510.100", + "quantity": "0.0000989901029695051088792143", + "side": "Buy", + "symbol": "BTCUSDC" + }, + "session_id": "S1", + "status": { + "Sent": { + "order_quantity": "0.0000989901029695051088792143" + } + } + }, + "O2": { + "order": { + "batch_order_id": "B1", + "created_timestamp": "2025-10-09T13:28:20Z", + "order_id": "O2", + "price": "5060.100", + "quantity": "0.0009881227643722456077943124", + "side": "Buy", + "symbol": "ETHUSDC" + }, + "session_id": "S1", + "status": { + "Sent": { + "order_quantity": "0.0009881227643722456077943124" + } + } + } + } + }, + "solver": { + "client_orders": { + "client_notify_queue": [], + "client_order_queues": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + [ + "C1" + ] + ] + ], + "client_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "C1" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "client_order_id": "C1", + "collateral_carried": "0", + "collateral_routed": "0.10", + "collateral_spent": "0.00", + "created_timestamp": "2025-10-09T13:28:00Z", + "engaged_collateral": "0.1000000000000000000000000404", + "filled_quantity": "0", + "lots": [], + "payment_id": "P2", + "remaining_collateral": "0.0", + "side": "Buy", + "status": "Engaged", + "symbol": "SO2", + "timestamp": "2025-10-10T18:47:14.387085Z" + } + ] + ], + "client_wait_period": [ + 5, + 0 + ] + }, + "ready_mints": [], + "ready_orders": [] + } + } +} \ No newline at end of file diff --git a/apps/solver_lambda/example_data/4_output.json b/apps/solver_lambda/example_data/4_output.json new file mode 100644 index 0000000..ebebf0f --- /dev/null +++ b/apps/solver_lambda/example_data/4_output.json @@ -0,0 +1,543 @@ +{ + "orders": [], + "server_responses": [ + { + "IndexOrderFill": { + "chain_id": 8453, + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "client_order_id": "C1", + "filled_quantity": "0.0000987037023646234749569786", + "collateral_spent": "0.0998003992015968063872264988", + "collateral_remaining": "0.0001996007984031936127735012", + "fill_rate": "0.9980039920159680638722645848", + "status": "mintable", + "timestamp": "2025-10-09T13:28:20Z" + } + }, + { + "IndexOrderFill": { + "chain_id": 8453, + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "client_order_id": "C1", + "filled_quantity": "0.0000989007157425967753061932", + "collateral_spent": "0.0999996015952127680766191012", + "collateral_remaining": "0.0000003984047872319233808988", + "fill_rate": "0.999996015952127680766190896", + "status": "fully mintable", + "timestamp": "2025-10-09T13:28:10Z" + } + }, + { + "MintInvoice": { + "chain_id": 8453, + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "client_order_id": "C1", + "mint_invoice": { + "client_order_id": "C1", + "payment_id": "P2", + "seq_num": "0x1", + "symbol": "SO2", + "filled_quantity": "0.0000989007157425967753061932", + "total_amount": "0.1", + "amount_paid": "0.10", + "amount_remaining": "0.0000003984047872319233808988", + "management_fee": "0.00", + "assets_value": "0.0999996015952127680766191011", + "exchange_fee": "0", + "fill_rate": "0.999996015952127680766191012", + "lots": [ + { + "lot_id": "O2-1", + "symbol": "ETH", + "price": "5060.100", + "original_quantity": "0.0009881227643722456077943124", + "remaining_quantity": "0.0009782326927979859302636930", + "original_fee": "0.00", + "assigned_quantity": "0.0000098900715742596775306194", + "assigned_fee": "0", + "created_timestamp": "2025-10-09T13:28:20Z", + "assigned_timestamp": "2025-10-09T13:28:20Z" + }, + { + "lot_id": "O1-1", + "symbol": "BTC", + "price": "50510.100", + "original_quantity": "0.0000989901029695051088792143", + "remaining_quantity": "0.0000980010958120791411261524", + "original_fee": "0.00", + "assigned_quantity": "0.0000009890071574259677530619", + "assigned_fee": "0", + "created_timestamp": "2025-10-09T13:28:20Z", + "assigned_timestamp": "2025-10-09T13:28:20Z" + } + ], + "position": { + "chain_id": 8453, + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "side_cr": { + "unconfirmed_balance": "0.00", + "ready_balance": "0.00", + "preauth_balance": "0.00", + "spent_balance": "0.10", + "open_lots": [], + "closed_lots": [ + { + "payment_id": "P1", + "seq_num": "0x1", + "unconfirmed_amount": "0", + "ready_amount": "0", + "preauth_amount": "0.00", + "spent_amount": "0.10", + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:10Z", + "spends": [ + { + "client_order_id": "C1", + "payment_id": "Charges", + "preauth_amount": "0", + "spent_amount": "0.00", + "timestamp": "2025-10-09T13:28:20Z" + }, + { + "client_order_id": "C1", + "payment_id": "P2", + "preauth_amount": "0", + "spent_amount": "0.10", + "timestamp": "2025-10-09T13:28:10Z" + } + ] + } + ], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:20Z" + }, + "side_dr": { + "unconfirmed_balance": "0", + "ready_balance": "0", + "preauth_balance": "0", + "spent_balance": "0", + "open_lots": [], + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z" + }, + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z" + }, + "timestamp": "2025-10-09T13:28:10Z" + }, + "timestamp": "2025-10-09T13:28:10Z" + } + } + ], + "chain_commands": [ + { + "SolverWeightsSet": { + "symbol": "SO2", + "basket": [ + { + "pair": "BTCUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.01" + }, + { + "pair": "ETHUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.1" + } + ] + } + }, + { + "MintIndex": { + "chain_id": 8453, + "symbol": "SO2", + "quantity": "0.0000989007157425967753061932", + "receipient": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "seq_num": "0x1", + "execution_price": "0.10", + "execution_time": "2025-10-09T13:28:10Z" + } + } + ], + "bridge_commands": [], + "state": { + "order_ids": [ + "O5", + "O6" + ], + "batch_ids": [ + "B3" + ], + "payment_ids": [], + "indexes": [ + { + "symbol": "SO2", + "basket": [ + { + "pair": "BTCUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.01" + }, + { + "pair": "ETHUSDC", + "listing": "", + "weight": "0.5", + "quantity": "0.1" + } + ] + } + ], + "index_orders": { + "index_orders": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + {} + ] + ] + }, + "invoices": { + "invoices": [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + { + "amount_paid": "0.10", + "amount_remaining": "0.0000003984047872319233808988", + "assets_value": "0.0999996015952127680766191011", + "client_order_id": "C1", + "exchange_fee": "0", + "fill_rate": "0.999996015952127680766191012", + "filled_quantity": "0.0000989007157425967753061932", + "lots": [ + { + "assigned_fee": "0", + "assigned_quantity": "0.0000098900715742596775306194", + "assigned_timestamp": "2025-10-09T13:28:20Z", + "created_timestamp": "2025-10-09T13:28:20Z", + "lot_id": "O2-1", + "original_fee": "0.00", + "original_quantity": "0.0009881227643722456077943124", + "price": "5060.100", + "remaining_quantity": "0.0009782326927979859302636930", + "symbol": "ETH" + }, + { + "assigned_fee": "0", + "assigned_quantity": "0.0000009890071574259677530619", + "assigned_timestamp": "2025-10-09T13:28:20Z", + "created_timestamp": "2025-10-09T13:28:20Z", + "lot_id": "O1-1", + "original_fee": "0.00", + "original_quantity": "0.0000989901029695051088792143", + "price": "50510.100", + "remaining_quantity": "0.0000980010958120791411261524", + "symbol": "BTC" + } + ], + "management_fee": "0.00", + "payment_id": "P2", + "position": { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "side_cr": { + "closed_lots": [ + { + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:10Z", + "payment_id": "P1", + "preauth_amount": "0.00", + "ready_amount": "0", + "seq_num": "0x1", + "spends": [ + { + "client_order_id": "C1", + "payment_id": "Charges", + "preauth_amount": "0", + "spent_amount": "0.00", + "timestamp": "2025-10-09T13:28:20Z" + }, + { + "client_order_id": "C1", + "payment_id": "P2", + "preauth_amount": "0", + "spent_amount": "0.10", + "timestamp": "2025-10-09T13:28:10Z" + } + ], + "spent_amount": "0.10", + "unconfirmed_amount": "0" + } + ], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:20Z", + "open_lots": [], + "preauth_balance": "0.00", + "ready_balance": "0.00", + "spent_balance": "0.10", + "unconfirmed_balance": "0.00" + }, + "side_dr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "open_lots": [], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0" + } + }, + "seq_num": "0x1", + "symbol": "SO2", + "timestamp": "2025-10-09T13:28:10Z", + "total_amount": "0.1" + } + ] + ] + }, + "collateral": { + "client_funds": [ + [ + [ + 8453, + "0xc0d3c9e530ca6d71469bb678e6592274154d9cad" + ], + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "side_cr": { + "closed_lots": [ + { + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:10Z", + "payment_id": "P1", + "preauth_amount": "0.00", + "ready_amount": "0", + "seq_num": "0x1", + "spends": [ + { + "client_order_id": "C1", + "payment_id": "Charges", + "preauth_amount": "0", + "spent_amount": "0.00", + "timestamp": "2025-10-09T13:28:20Z" + }, + { + "client_order_id": "C1", + "payment_id": "P2", + "preauth_amount": "0", + "spent_amount": "0.10", + "timestamp": "2025-10-09T13:28:10Z" + } + ], + "spent_amount": "0.10", + "unconfirmed_amount": "0" + } + ], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:20Z", + "open_lots": [], + "preauth_balance": "0.00", + "ready_balance": "0.00", + "spent_balance": "0.10", + "unconfirmed_balance": "0.00" + }, + "side_dr": { + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:00Z", + "last_update_timestamp": "2025-10-09T13:28:00Z", + "open_lots": [], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0" + } + } + ] + ] + }, + "inventory": { + "positions": { + "BTC": { + "balance": "0.0000989901029695051088792143", + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:20Z", + "last_update_timestamp": "2025-10-09T13:28:20Z", + "open_lots": [ + { + "created_timestamp": "2025-10-09T13:28:20Z", + "last_update_timestamp": "2025-10-09T13:28:20Z", + "lot_assignments": [ + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "assigned_fee": "0", + "assigned_quantity": "0.0000009890071574259677530619", + "assigned_timestamp": "2025-10-09T13:28:20Z", + "chain_id": 8453, + "client_order_id": "C1", + "seq_num": "0x1", + "side": "Buy" + } + ], + "lot_id": "O1-1", + "lot_transactions": [], + "original_batch_order_id": "B1", + "original_fee": "0.00", + "original_order_id": "O1", + "original_price": "50510.100", + "original_quantity": "0.0000989901029695051088792143", + "remaining_quantity": "0.0000989901029695051088792143" + } + ], + "side": "Buy", + "symbol": "BTC" + }, + "ETH": { + "balance": "0.0009881227643722456077943124", + "closed_lots": [], + "created_timestamp": "2025-10-09T13:28:20Z", + "last_update_timestamp": "2025-10-09T13:28:20Z", + "open_lots": [ + { + "created_timestamp": "2025-10-09T13:28:20Z", + "last_update_timestamp": "2025-10-09T13:28:20Z", + "lot_assignments": [ + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "assigned_fee": "0", + "assigned_quantity": "0.0000098900715742596775306194", + "assigned_timestamp": "2025-10-09T13:28:20Z", + "chain_id": 8453, + "client_order_id": "C1", + "seq_num": "0x1", + "side": "Buy" + } + ], + "lot_id": "O2-1", + "lot_transactions": [], + "original_batch_order_id": "B1", + "original_fee": "0.00", + "original_order_id": "O2", + "original_price": "5060.100", + "original_quantity": "0.0009881227643722456077943124", + "remaining_quantity": "0.0009881227643722456077943124" + } + ], + "side": "Buy", + "symbol": "ETH" + } + } + }, + "batch": { + "batches": {}, + "carry_overs": [ + [ + [ + "ETHUSDC", + "Buy" + ], + { + "carried_lots": [ + { + "closing_lot_id": null, + "fee": "0.00", + "lot_id": "O2-1", + "order_id": "O2", + "original_quantity": "0.0009881227643722456077943124", + "price": "5060.100", + "remaining_quantity": "0.0009782326927979859302636930", + "timestamp": "2025-10-09T13:28:20Z" + } + ], + "carried_position": "0.0009782326927979859302636930" + } + ], + [ + [ + "BTCUSDC", + "Buy" + ], + { + "carried_lots": [ + { + "closing_lot_id": null, + "fee": "0.00", + "lot_id": "O1-1", + "order_id": "O1", + "original_quantity": "0.0000989901029695051088792143", + "price": "50510.100", + "remaining_quantity": "0.0000980010958120791411261524", + "timestamp": "2025-10-09T13:28:20Z" + } + ], + "carried_position": "0.0000980010958120791411261524" + } + ] + ], + "engagements": {}, + "total_volley_size": "0.000000000000000000000000000" + }, + "orders": { + "orders": { + "O1": { + "order": { + "batch_order_id": "B1", + "created_timestamp": "2025-10-09T13:28:20Z", + "order_id": "O1", + "price": "50510.100", + "quantity": "0.0000989901029695051088792143", + "side": "Buy", + "symbol": "BTCUSDC" + }, + "session_id": "S1", + "status": { + "Cancelled": { + "quantity_remaining": "0" + } + } + }, + "O2": { + "order": { + "batch_order_id": "B1", + "created_timestamp": "2025-10-09T13:28:20Z", + "order_id": "O2", + "price": "5060.100", + "quantity": "0.0009881227643722456077943124", + "side": "Buy", + "symbol": "ETHUSDC" + }, + "session_id": "S1", + "status": { + "Cancelled": { + "quantity_remaining": "0" + } + } + } + } + }, + "solver": { + "client_orders": { + "client_notify_queue": [], + "client_order_queues": [], + "client_orders": [], + "client_wait_period": [ + 5, + 0 + ] + }, + "ready_mints": [], + "ready_orders": [] + } + } +} \ No newline at end of file diff --git a/apps/solver_lambda/src/lib.rs b/apps/solver_lambda/src/lib.rs new file mode 100644 index 0000000..a0b4fdb --- /dev/null +++ b/apps/solver_lambda/src/lib.rs @@ -0,0 +1,9 @@ +pub mod solver_input; +pub mod solver_output; +pub mod solver_output_chain_connector; +pub mod solver_output_collateral_bridge; +pub mod solver_output_order_sender; +pub mod solver_output_server; +pub mod solver_service; +pub mod solver_state; +pub mod solver_state_order_ids; diff --git a/apps/solver_lambda/src/main.rs b/apps/solver_lambda/src/main.rs new file mode 100644 index 0000000..8ff6e3e --- /dev/null +++ b/apps/solver_lambda/src/main.rs @@ -0,0 +1,56 @@ +use axum::{extract::State, http::StatusCode, routing::post, Json, Router}; +use clap::Parser; +use solver_lambda::{ + solver_input::SolverInput, solver_output::SolverOutput, solver_service::SolverService, +}; +use std::{net::SocketAddr, sync::Arc}; +use symm_core::{core::logging::log_init, init_log}; + +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +struct Cli { + #[arg(short, long)] + bind_address: Option, + + #[arg(long, short)] + config_path: Option, +} + +#[tokio::main] +async fn main() { + let cli = Cli::parse(); + + let address = cli.bind_address.unwrap_or(String::from("127.0.0.1:3099")); + let config_path = cli.config_path.unwrap_or("configs".into()); + + init_log!(); + + let service = Arc::new(SolverService::new(config_path)); + + let addr: SocketAddr = address.parse().expect(&format!( + "Server failed to start: Invalid address ({})", + address + )); + tracing::info!("Listening on {}", addr); + + let api_v1 = Router::new().route("/solver/tick", post(solver_tick)); + + let app = Router::new().nest("/api/v1", api_v1).with_state(service); + + if let Err(e) = axum_server::bind(addr).serve(app.into_make_service()).await { + tracing::warn!("Server failed to start: {}", e); + } +} + +async fn solver_tick( + State(service): State>, + Json(input): Json, +) -> Result, StatusCode> { + match service.solve(input).await { + Ok(output) => Ok(Json(output)), + Err(err) => { + tracing::warn!("Failed to handle request: {:?}", err); + Err(StatusCode::INTERNAL_SERVER_ERROR) + } + } +} diff --git a/apps/solver_lambda/src/solver_input.rs b/apps/solver_lambda/src/solver_input.rs new file mode 100644 index 0000000..c4340be --- /dev/null +++ b/apps/solver_lambda/src/solver_input.rs @@ -0,0 +1,24 @@ +use chrono::{DateTime, Utc}; +use index_core::{ + blockchain::chain_connector::ChainNotification, + collateral::collateral_router::CollateralRouterEvent, +}; +use index_maker::server::server::ServerEvent; +use serde::{Deserialize, Serialize}; +use symm_core::{ + market_data::market_data_connector::MarketDataEvent, + order_sender::order_connector::OrderConnectorNotification, +}; + +use crate::solver_state::SolverState; + +#[derive(Serialize, Deserialize)] +pub struct SolverInput { + pub market_data_events: Vec, + pub order_events: Vec, + pub server_events: Vec, + pub chain_events: Vec, + pub router_events: Vec, + pub state: SolverState, + pub timestamp: DateTime, +} diff --git a/apps/solver_lambda/src/solver_output.rs b/apps/solver_lambda/src/solver_output.rs new file mode 100644 index 0000000..a0ce55b --- /dev/null +++ b/apps/solver_lambda/src/solver_output.rs @@ -0,0 +1,71 @@ +use alloy::primitives::U256; +use chrono::{DateTime, Utc}; +use index_core::index::basket::Basket; +use index_maker::server::server::ServerResponse; +use serde::{Deserialize, Serialize}; +use std::sync::Arc; +use symm_core::{ + core::bits::{Address, Amount, ClientOrderId, SingleOrder, Symbol}, + order_sender::order_connector::SessionId, +}; + +use crate::solver_state::SolverState; + +#[derive(Serialize, Deserialize)] +pub enum ChainCommand { + PollOnce { + chain_id: u32, + address: Address, + symbol: Symbol, + }, + SolverWeightsSet { + symbol: Symbol, + basket: Arc, + }, + MintIndex { + chain_id: u32, + symbol: Symbol, + quantity: Amount, + receipient: Address, + seq_num: U256, + execution_price: Amount, + execution_time: DateTime, + }, + BurnIndex { + chain_id: u32, + symbol: Symbol, + quantity: Amount, + receipient: Address, + }, + Withdraw { + chain_id: u32, + receipient: Address, + amount: Amount, + execution_price: Amount, + execution_time: DateTime, + }, +} + +#[derive(Serialize, Deserialize)] +pub enum BridgeCommand { + TransferFunds { + chain_id: u32, + address: Address, + client_order_id: ClientOrderId, + source: Symbol, + destination: Symbol, + route_from: Symbol, + route_to: Symbol, + amount: Amount, + cumulative_fee: Amount, + }, +} + +#[derive(Serialize, Deserialize)] +pub struct SolverOutput { + pub orders: Vec<(SessionId, Arc)>, + pub server_responses: Vec, + pub chain_commands: Vec, + pub bridge_commands: Vec, + pub state: SolverState, +} diff --git a/apps/solver_lambda/src/solver_output_chain_connector.rs b/apps/solver_lambda/src/solver_output_chain_connector.rs new file mode 100644 index 0000000..a178538 --- /dev/null +++ b/apps/solver_lambda/src/solver_output_chain_connector.rs @@ -0,0 +1,95 @@ +use std::{collections::VecDeque, sync::Arc}; + +use chrono::{DateTime, Utc}; +use index_core::{ + blockchain::chain_connector::{ChainConnector, ChainNotification}, + index::basket::Basket, +}; +use parking_lot::RwLock; +use symm_core::core::{ + bits::{Address, Amount, Symbol}, + functional::{IntoObservableSingleVTable, NotificationHandlerOnce}, +}; + +use crate::solver_output::ChainCommand; + +pub struct SolverOutputChainConnector { + pub commands: RwLock>, +} + +impl SolverOutputChainConnector { + pub fn new() -> Self { + Self { + commands: RwLock::new(VecDeque::new()), + } + } +} + +impl ChainConnector for SolverOutputChainConnector { + fn poll_once(&self, chain_id: u32, address: Address, symbol: Symbol) { + self.commands.write().push_back(ChainCommand::PollOnce { + chain_id, + address, + symbol, + }); + } + + fn solver_weights_set(&self, symbol: Symbol, basket: Arc) { + self.commands + .write() + .push_back(ChainCommand::SolverWeightsSet { symbol, basket }); + } + + fn mint_index( + &self, + chain_id: u32, + symbol: Symbol, + quantity: Amount, + receipient: Address, + seq_num: alloy::primitives::U256, + execution_price: Amount, + execution_time: DateTime, + ) { + self.commands.write().push_back(ChainCommand::MintIndex { + chain_id, + symbol, + quantity, + receipient, + seq_num, + execution_price, + execution_time, + }); + } + + fn burn_index(&self, chain_id: u32, symbol: Symbol, quantity: Amount, receipient: Address) { + self.commands.write().push_back(ChainCommand::BurnIndex { + chain_id, + symbol, + quantity, + receipient, + }); + } + + fn withdraw( + &self, + chain_id: u32, + receipient: Address, + amount: Amount, + execution_price: Amount, + execution_time: DateTime, + ) { + self.commands.write().push_back(ChainCommand::Withdraw { + chain_id, + receipient, + amount, + execution_price, + execution_time, + }); + } +} + +impl IntoObservableSingleVTable for SolverOutputChainConnector { + fn set_observer(&mut self, _observer: Box>) { + unimplemented!() + } +} diff --git a/apps/solver_lambda/src/solver_output_collateral_bridge.rs b/apps/solver_lambda/src/solver_output_collateral_bridge.rs new file mode 100644 index 0000000..0118ba7 --- /dev/null +++ b/apps/solver_lambda/src/solver_output_collateral_bridge.rs @@ -0,0 +1,117 @@ +use std::{collections::VecDeque, sync::Arc}; + +use index_core::collateral::collateral_router::{ + CollateralBridge, CollateralDesignation, CollateralRouterEvent, +}; +use itertools::Itertools; +use parking_lot::RwLock; +use symm_core::core::{ + bits::{Address, Amount, ClientOrderId, Symbol}, + functional::{IntoObservableSingleVTableRef, NotificationHandlerOnce}, +}; + +use crate::solver_output::BridgeCommand; + +pub struct SolverOutputCollateralDesignation { + full_name: Symbol, + type_: Symbol, + name: Symbol, + collateral_symbol: Symbol, +} + +pub struct SolverOutputCollateralBridge { + pub source: Arc, + pub destination: Arc, + pub commands: RwLock>, +} + +impl SolverOutputCollateralDesignation { + pub fn new(full_name: &str) -> Self { + let (type_, name, collateral_symbol) = + full_name.split(':').map_into().collect_tuple().unwrap(); + + Self { + full_name: Symbol::from(full_name), + type_, + name, + collateral_symbol, + } + } +} + +impl CollateralDesignation for SolverOutputCollateralDesignation { + fn get_type(&self) -> Symbol { + self.type_.clone() + } + + fn get_name(&self) -> Symbol { + self.name.clone() + } + + fn get_collateral_symbol(&self) -> Symbol { + self.collateral_symbol.clone() + } + + fn get_full_name(&self) -> Symbol { + self.full_name.clone() + } + + fn get_balance(&self) -> Amount { + unimplemented!() + } +} + +impl SolverOutputCollateralBridge { + pub fn new( + source: Arc, + destination: Arc, + ) -> Self { + Self { + source, + destination, + commands: RwLock::new(VecDeque::new()), + } + } +} + +impl IntoObservableSingleVTableRef for SolverOutputCollateralBridge { + fn set_observer(&self, _observer: Box>) { + unimplemented!() + } +} + +impl CollateralBridge for SolverOutputCollateralBridge { + fn get_source(&self) -> Arc { + self.source.clone() + } + + fn get_destination(&self) -> Arc { + self.destination.clone() + } + + fn transfer_funds( + &self, + chain_id: u32, + address: Address, + client_order_id: ClientOrderId, + route_from: Symbol, + route_to: Symbol, + amount: Amount, + cumulative_fee: Amount, + ) -> eyre::Result<()> { + self.commands + .write() + .push_back(BridgeCommand::TransferFunds { + chain_id, + address, + client_order_id, + source: self.source.get_full_name(), + destination: self.destination.get_full_name(), + route_from, + route_to, + amount, + cumulative_fee, + }); + Ok(()) + } +} diff --git a/apps/solver_lambda/src/solver_output_order_sender.rs b/apps/solver_lambda/src/solver_output_order_sender.rs new file mode 100644 index 0000000..6835e80 --- /dev/null +++ b/apps/solver_lambda/src/solver_output_order_sender.rs @@ -0,0 +1,51 @@ +use std::{ + collections::{HashMap, VecDeque}, + sync::Arc, +}; + +use symm_core::{ + core::{ + bits::{Amount, SingleOrder, Symbol}, + functional::{ + IntoObservableSingleVTable, NotificationHandlerOnce, OneShotSingleObserver, + }, + }, + order_sender::order_connector::{OrderConnector, OrderConnectorNotification, SessionId}, +}; + +pub struct SolverOutputOrderSender { + pub orders: VecDeque<(SessionId, Arc)>, +} + +impl SolverOutputOrderSender { + pub fn new() -> Self { + Self { + orders: VecDeque::new(), + } + } +} + +impl OrderConnector for SolverOutputOrderSender { + fn send_order(&mut self, session_id: SessionId, order: &Arc) -> eyre::Result<()> { + let entry = (session_id, order.clone()); + self.orders.push_back(entry); + Ok(()) + } + + fn get_balances( + &self, + _session_id: SessionId, + _observer: OneShotSingleObserver>, + ) -> eyre::Result<()> { + Ok(()) + } +} + +impl IntoObservableSingleVTable for SolverOutputOrderSender { + fn set_observer( + &mut self, + _observer: Box>, + ) { + unimplemented!() + } +} diff --git a/apps/solver_lambda/src/solver_output_server.rs b/apps/solver_lambda/src/solver_output_server.rs new file mode 100644 index 0000000..693a00a --- /dev/null +++ b/apps/solver_lambda/src/solver_output_server.rs @@ -0,0 +1,35 @@ +use std::{collections::VecDeque, sync::Arc}; + +use index_maker::server::server::{Server, ServerEvent, ServerResponse}; +use symm_core::core::functional::{IntoObservableManyVTable, NotificationHandler}; + +pub struct SolverOutputServer { + pub responses: VecDeque, +} + +impl SolverOutputServer { + pub fn new() -> Self { + Self { + responses: VecDeque::new(), + } + } +} + +impl Server for SolverOutputServer { + fn respond_with(&mut self, response: ServerResponse) { + self.responses.push_back(response); + } + + fn initialize_shutdown(&mut self) { + unimplemented!() + } +} + +impl IntoObservableManyVTable> for SolverOutputServer { + fn add_observer( + &mut self, + _observer: Box>>, + ) { + unimplemented!() + } +} diff --git a/apps/solver_lambda/src/solver_service.rs b/apps/solver_lambda/src/solver_service.rs new file mode 100644 index 0000000..20f1a83 --- /dev/null +++ b/apps/solver_lambda/src/solver_service.rs @@ -0,0 +1,507 @@ +use std::{ + collections::VecDeque, + sync::{Arc, RwLock as ComponentLock}, +}; + +use chrono::TimeDelta; +use crossbeam::channel::unbounded; +use eyre::Context; +use index_core::{ + blockchain::chain_connector, + collateral::collateral_router::{CollateralBridge, CollateralRouter}, + index::basket_manager::BasketManager, +}; +use index_maker::{ + app::{ + basket_manager, batch_manager, collateral_manager, index_order_manager, + quote_request_manager, simple_router::SimpleBridge, + }, + collateral::collateral_manager::CollateralManager, + solver::{ + batch_manager::BatchManager, index_order_manager::IndexOrderManager, + index_quote_manager::QuoteRequestManager, mint_invoice_manager::MintInvoiceManager, + solver::Solver, solvers::simple_solver::SimpleSolver, + }, +}; +use itertools::Itertools; +use parking_lot::RwLock as AtomicLock; +use rust_decimal::dec; + +use symm_core::{ + core::{ + bits::Symbol, + functional::{IntoObservableSingle, IntoObservableSingleFun}, + persistence::{self, util::InMemoryPersistence, Persist, Persistence}, + }, + market_data::{ + market_data_connector::MarketDataEvent, + order_book::order_book_manager::{self, PricePointBookManager}, + price_tracker::{self, PriceTracker}, + }, + order_sender::{ + inventory_manager::{self, InventoryManager}, + order_connector::{OrderConnectorNotification, SessionId}, + order_tracker::{self, OrderTracker}, + }, +}; +use tracing::event; + +use crate::{ + solver_input::SolverInput, + solver_output::SolverOutput, + solver_output_chain_connector::SolverOutputChainConnector, + solver_output_collateral_bridge::{ + SolverOutputCollateralBridge, SolverOutputCollateralDesignation, + }, + solver_output_order_sender::SolverOutputOrderSender, + solver_output_server::SolverOutputServer, + solver_state::{IndexDefinition, SolverState}, + solver_state_order_ids::SolverStateOrderIdProvider, +}; + +pub struct SolverService { + pub config_path: String, +} + +impl SolverService { + pub fn new(config_path: String) -> Self { + Self { config_path } + } + + pub async fn solve(&self, input: SolverInput) -> eyre::Result { + // TODO: Load this configuration + + let price_threshold = dec!(0.01); + let max_levels = 5usize; + let fee_factor = dec!(1.002); + let max_order_volley_size = dec!(20.0); + let max_volley_size = dec!(500.0); + let min_asset_volley_size = dec!(5.0); + let asset_volley_step_size = dec!(0.1); + let max_total_volley_size = dec!(1000.0); + let min_total_volley_available = dec!(200.0); + + let fill_threshold = dec!(0.9999); + let mint_threshold = dec!(0.99); + let mint_wait_period = TimeDelta::seconds(10); + + let max_batch_size = 16usize; + let collateral_zero_threshold = dec!(0.000_001); + let assets_zero_threshold = dec!(0.000_000_000_000_000_001); + let order_expiry_after = chrono::Duration::minutes(30); + let client_order_wait_period = TimeDelta::seconds(5); + let client_quote_wait_period = TimeDelta::milliseconds(500); + + tracing::info!("Loading state..."); + + // + // Market data part + + let price_tracker = Arc::new(AtomicLock::new(PriceTracker::new())); + let order_book_manager = Arc::new(AtomicLock::new(PricePointBookManager::new( + assets_zero_threshold, + ))); + + // + // Order sending part + + let order_sender = Arc::new(AtomicLock::new(SolverOutputOrderSender::new())); + + let order_tracker = Arc::new(AtomicLock::new(OrderTracker::new( + order_sender.clone(), + assets_zero_threshold, + ))); + let order_tracker_persistence = InMemoryPersistence::new(); + if let Some(orders) = input.state.orders { + order_tracker_persistence.store_value(orders)?; + order_tracker.write().load_from(&order_tracker_persistence)?; + } + let (tracked_order_tx, tracked_order_rx) = unbounded(); + order_tracker + .write() + .get_single_observer_mut() + .set_observer_from(tracked_order_tx); + + let inventory_manager_persistence = Arc::new(InMemoryPersistence::new()); + if let Some(inventory_state) = input.state.inventory { + inventory_manager_persistence.store_value(inventory_state)?; + } + + let inventory_manager = Arc::new(AtomicLock::new(InventoryManager::new( + order_tracker.clone(), + inventory_manager_persistence.clone(), + assets_zero_threshold, + ))); + let (inventory_tx, inventory_rx) = unbounded(); + inventory_manager + .write() + .get_single_observer_mut() + .set_observer_from(inventory_tx); + + // + // Chain connector part + + let chain_connector = Arc::new(ComponentLock::new(SolverOutputChainConnector::new())); + + // + // Collateral manager part + let collateral_router = Arc::new(AtomicLock::new(CollateralRouter::new())); + let (collateral_router_tx, collateral_router_rx) = unbounded(); + collateral_router + .write() + .get_single_observer_mut() + .set_observer_from(collateral_router_tx); + + let collateral_persistence = Arc::new(InMemoryPersistence::new()); + if let Some(collateral_state) = input.state.collateral { + collateral_persistence.store_value(collateral_state)?; + } + + let collateral_manager = Arc::new(ComponentLock::new(CollateralManager::new( + collateral_router.clone(), + collateral_persistence.clone(), + collateral_zero_threshold, + ))); + let (collateral_tx, collateral_rx) = unbounded(); + collateral_manager + .write() + .map_err(|err| eyre::eyre!("Failed to access collateral manager{:?}", err))? + .get_single_observer_mut() + .set_observer_from(collateral_tx); + + // + // Server part + + let server = Arc::new(AtomicLock::new(SolverOutputServer::new())); + + // + // Quote request manager part + let quote_request_manager = + Arc::new(ComponentLock::new(QuoteRequestManager::new(server.clone()))); + + // + // Invoice manager part + let invoice_persistence = Arc::new(InMemoryPersistence::new()); + if let Some(invoice_state) = input.state.invoices { + invoice_persistence.store_value(invoice_state)?; + } + let invoice_manager = Arc::new(AtomicLock::new(MintInvoiceManager::new( + invoice_persistence.clone(), + ))); + + // + // Index order manager part + + let index_order_persistence = Arc::new(InMemoryPersistence::new()); + if let Some(index_orders_state) = input.state.index_orders { + index_order_persistence.store_value(index_orders_state)?; + } + let index_order_manager = Arc::new(ComponentLock::new(IndexOrderManager::new( + server.clone(), + invoice_manager, + index_order_persistence.clone(), + collateral_zero_threshold, + ))); + let (index_order_tx, index_order_rx) = unbounded(); + index_order_manager + .write() + .map_err(|err| eyre::eyre!("Failed to access index order manager{:?}", err))? + .get_single_observer_mut() + .set_observer_from(index_order_tx); + + // + // Solver part + + let order_id_provider = Arc::new(AtomicLock::new(SolverStateOrderIdProvider { + order_ids: VecDeque::from(input.state.order_ids), + batch_order_ids: VecDeque::from(input.state.batch_ids), + payment_ids: VecDeque::from(input.state.payment_ids), + })); + + let basket_manager = Arc::new(AtomicLock::new(BasketManager::new())); + let (basket_tx, basket_rx) = unbounded(); + basket_manager + .write() + .get_single_observer_mut() + .set_observer_from(basket_tx); + + for index_definition in input.state.indexes { + basket_manager + .write() + .set_basket(&index_definition.symbol, &index_definition.basket); + } + + let solver_strategy = Arc::new(SimpleSolver::new( + price_threshold, + max_levels, + fee_factor, + max_order_volley_size, + max_volley_size, + min_asset_volley_size, + asset_volley_step_size, + max_total_volley_size, + min_total_volley_available, + )); + + let batch_manager_persistence = Arc::new(InMemoryPersistence::new()); + if let Some(batch_state) = input.state.batch { + batch_manager_persistence.store_value(batch_state)?; + } + + let batch_manager = Arc::new(ComponentLock::new(BatchManager::new( + batch_manager_persistence.clone(), + max_batch_size, + assets_zero_threshold, + fill_threshold, + mint_threshold, + mint_wait_period, + ))); + let (batch_tx, batch_rx) = unbounded(); + batch_manager + .write() + .map_err(|err| eyre::eyre!("Failed to access batch manager{:?}", err))? + .get_single_observer_mut() + .set_observer_from(batch_tx); + + let solver_persistence = Arc::new(InMemoryPersistence::new()); + if let Some(solver_state) = input.state.solver { + solver_persistence.store_value(solver_state)?; + } + + let solver = { + let mut solver = Arc::new(Solver::new( + solver_strategy, + order_id_provider.clone(), + basket_manager.clone(), + price_tracker.clone(), + order_book_manager.clone(), + chain_connector.clone(), + batch_manager, + collateral_manager.clone(), + index_order_manager.clone(), + quote_request_manager, + inventory_manager.clone(), + solver_persistence.clone(), + max_batch_size, + collateral_zero_threshold, + order_expiry_after, + client_order_wait_period, + client_quote_wait_period, + )); + + if let Some(solver_mut) = Arc::get_mut(&mut solver) { + // This will load all the state from InMemoryPersistence + // that we created from input.state. + solver_mut.load()?; + } + + solver + }; + + // Flusher + + let flush_events = { + let solver = solver.clone(); + + move || -> eyre::Result { + let mut any_events = false; + loop { + crossbeam::select! { + recv(inventory_rx) -> res => { + res + .context("Failed to receive inventory event") + .and_then(|e| solver.handle_inventory_event(e))?; + } + recv(collateral_rx) -> res => { + res + .context("Failed to receive collateral event") + .and_then(|e| solver.handle_collateral_event(e))?; + } + recv(index_order_rx) -> res => { + res + .context("Failed to receive index order event") + .and_then(|e| solver.handle_index_order(e))?; + } + recv(basket_rx) -> res => { + res + .context("Failed to receive basket event") + .and_then(|e| solver.handle_basket_event(e))?; + } + recv(batch_rx) -> res => { + res + .context("Failed to receive batch event") + .and_then(|e| solver.handle_batch_event(e))?; + } + + recv(tracked_order_rx) -> res => { + res + .context("Failed to receive tracked order event") + .and_then(|e| inventory_manager.write().handle_fill_report(e))?; + } + + recv(collateral_router_rx) -> res => { + let e = res.context("Failed to receive collateral router event")?; + let mut c = collateral_manager.write() + .map_err(|err| eyre::eyre!("Failed to access collateral manager{:?}", err))?; + c.handle_collateral_transfer_event(e)?; + } + + default => { + return Ok(any_events) + } + } + any_events = true; + } + } + }; + + let next_step = { + let solver = solver.clone(); + + move || -> eyre::Result<()> { + loop { + // Poke solver + solver.solve(input.timestamp); + + // Flush all internal events + if !flush_events()? { + return Ok(()); + } + } + } + }; + + // TODO: Temporary routing filler + let bridge = Arc::new(SolverOutputCollateralBridge::new( + Arc::new(SolverOutputCollateralDesignation::new("Start:SO2:USDC")), + Arc::new(SolverOutputCollateralDesignation::new("End:SO2:USDC")), + )); + + let route_start = bridge.get_source().get_full_name(); + let route_end = bridge.get_destination().get_full_name(); + + collateral_router + .write() + .add_route(&[route_start.clone(), route_end.clone()])?; + + collateral_router + .write() + .add_bridge(bridge.clone() as Arc)?; + + collateral_router.write().add_chain_source( + 8453, + Symbol::from("SO2"), + route_start.clone(), + )?; + + collateral_router + .write() + .set_default_destination(route_end.clone())?; + + // Temporary session filler + { + order_tracker.write().handle_order_notification( + OrderConnectorNotification::SessionLogon { + session_id: SessionId::from("S1"), + timestamp: input.timestamp, + }, + )?; + } + + // + // Feed external events + + next_step()?; + + for event in input.market_data_events { + price_tracker.write().handle_market_data(&event); + order_book_manager.write().handle_market_data(&event); + } + + next_step()?; + + for event in input.server_events { + index_order_manager + .write() + .map_err(|e| eyre::eyre!("Failed to access index order manager: {:?}", e))? + .handle_server_message(&event)?; + } + + next_step()?; + + for event in input.chain_events { + solver.handle_chain_event(event)?; + } + + next_step()?; + + for event in input.router_events { + collateral_router + .read() + .handle_collateral_router_event(event)?; + } + + next_step()?; + + for event in input.order_events { + order_tracker.write().handle_order_notification(event)?; + } + + next_step()?; + + tracing::info!("Storing state..."); + + // This will store all the state into InMemoryPersistence + // that we then send back as output.state. + solver.store()?; + + let indexes = basket_manager + .read() + .get_baskets() + .iter() + .map(|(s, b)| IndexDefinition { + symbol: s.clone(), + basket: b.clone(), + }) + .collect_vec(); + + let order_ids = Vec::from_iter(order_id_provider.write().order_ids.drain(..)); + let batch_ids = Vec::from_iter(order_id_provider.write().batch_order_ids.drain(..)); + let payment_ids = Vec::from_iter(order_id_provider.write().payment_ids.drain(..)); + + let chain_commands = Vec::from_iter( + chain_connector + .write() + .map_err(|e| eyre::eyre!("Failed to access index order manager: {:?}", e))? + .commands + .write() + .drain(..), + ); + + let bridge_commands = Vec::from_iter(bridge.commands.write().drain(..)); + + order_tracker.read().store_into(&order_tracker_persistence)?; + + let output = SolverOutput { + orders: Vec::from_iter(order_sender.write().orders.drain(..)), + server_responses: Vec::from_iter(server.write().responses.drain(..)), + chain_commands, + bridge_commands, + state: SolverState { + order_ids, + batch_ids, + payment_ids, + indexes, + index_orders: index_order_persistence.load_value()?, + invoices: invoice_persistence.load_value()?, + collateral: collateral_persistence.load_value()?, + inventory: inventory_manager_persistence.load_value()?, + batch: batch_manager_persistence.load_value()?, + orders: order_tracker_persistence.load_value()?, + solver: solver_persistence.load_value()?, + }, + }; + + Ok(output) + } +} diff --git a/apps/solver_lambda/src/solver_state.rs b/apps/solver_lambda/src/solver_state.rs new file mode 100644 index 0000000..ff2b249 --- /dev/null +++ b/apps/solver_lambda/src/solver_state.rs @@ -0,0 +1,28 @@ +use std::sync::Arc; + +use index_core::index::basket::Basket; +use serde::{Deserialize, Serialize}; +use symm_core::core::bits::{BatchOrderId, OrderId, PaymentId, Symbol}; + +#[derive(Serialize, Deserialize)] +pub struct IndexDefinition { + pub symbol: Symbol, + pub basket: Arc, +} + +#[derive(Serialize, Deserialize)] +pub struct SolverState { + pub order_ids: Vec, + pub batch_ids: Vec, + pub payment_ids: Vec, + + pub indexes: Vec, + + pub index_orders: Option, + pub invoices: Option, + pub collateral: Option, + pub inventory: Option, + pub batch: Option, + pub orders: Option, + pub solver: Option, +} diff --git a/apps/solver_lambda/src/solver_state_order_ids.rs b/apps/solver_lambda/src/solver_state_order_ids.rs new file mode 100644 index 0000000..a02750a --- /dev/null +++ b/apps/solver_lambda/src/solver_state_order_ids.rs @@ -0,0 +1,28 @@ +use std::collections::VecDeque; + +use index_maker::solver::solver::OrderIdProvider; +use symm_core::core::bits::{BatchOrderId, OrderId, PaymentId}; + +pub struct SolverStateOrderIdProvider { + pub order_ids: VecDeque, + pub batch_order_ids: VecDeque, + pub payment_ids: VecDeque, +} + +impl OrderIdProvider for SolverStateOrderIdProvider { + fn next_order_id(&mut self) -> OrderId { + self.order_ids.pop_front().expect("No more Order Ids") + } + + fn next_batch_order_id(&mut self) -> BatchOrderId { + self.batch_order_ids + .pop_front() + .expect("No more BatchOrder Ids") + } + + fn next_payment_id(&mut self) -> PaymentId { + self.payment_ids + .pop_front() + .expect("No more PaymentIds Ids") + } +} diff --git a/libs/index-core/src/blockchain/chain_connector.rs b/libs/index-core/src/blockchain/chain_connector.rs index d2a6b25..3c29a0c 100644 --- a/libs/index-core/src/blockchain/chain_connector.rs +++ b/libs/index-core/src/blockchain/chain_connector.rs @@ -6,6 +6,7 @@ use chrono::{DateTime, Utc}; use derive_with_baggage::WithBaggage; use opentelemetry::propagation::Injector; +use serde::{Deserialize, Serialize}; use symm_core::core::telemetry::{TracingData, WithBaggage}; use symm_core::core::{ @@ -18,7 +19,7 @@ use crate::index::basket::{Basket, BasketDefinition}; /// call blockchain methods, receive blockchain events /// On-chain event -#[derive(WithBaggage)] +#[derive(Serialize, Deserialize, WithBaggage)] pub enum ChainNotification { CuratorWeightsSet(Symbol, BasketDefinition), // ...more Deposit { diff --git a/libs/index-core/src/collateral/collateral_router.rs b/libs/index-core/src/collateral/collateral_router.rs index 64782b8..c2082a4 100644 --- a/libs/index-core/src/collateral/collateral_router.rs +++ b/libs/index-core/src/collateral/collateral_router.rs @@ -7,6 +7,7 @@ use eyre::{eyre, OptionExt, Result}; use derive_with_baggage::WithBaggage; use opentelemetry::propagation::Injector; +use serde::{Deserialize, Serialize}; use symm_core::core::functional::IntoObservableSingleVTableRef; use symm_core::core::telemetry::{TracingData, WithBaggage}; @@ -15,7 +16,7 @@ use symm_core::core::{ functional::{IntoObservableSingle, PublishSingle, SingleObserver}, }; -#[derive(Debug)] +#[derive(Serialize, Deserialize, Debug)] pub enum CollateralRoutingStatus { Success, Failure { reason: String }, @@ -60,7 +61,7 @@ pub enum CollateralTransferEvent { }, } -#[derive(WithBaggage)] +#[derive(Serialize, Deserialize, WithBaggage)] pub enum CollateralRouterEvent { HopComplete { #[baggage] diff --git a/libs/index-core/src/index/basket.rs b/libs/index-core/src/index/basket.rs index 5191017..cef1d7c 100644 --- a/libs/index-core/src/index/basket.rs +++ b/libs/index-core/src/index/basket.rs @@ -2,7 +2,7 @@ use eyre::{eyre, Report, Result}; use itertools::Itertools; use rust_decimal::Decimal; use safe_math::safe; -use serde::{Deserialize, Deserializer, Serialize}; +use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize}; use std::{collections::HashMap, fmt::Display, sync::Arc}; use symm_core::{ @@ -36,6 +36,7 @@ impl AssetWeight { /// /// The struct is intended to be used for Read-Only purpose, and to make an update this /// struct needs to be burned, and new struct needs to be created. +#[derive(Serialize, Deserialize)] pub struct BasketDefinition { pub weights: Vec, } @@ -113,11 +114,25 @@ pub struct BasketAsset { /// /// The struct is intended to be used for Read-Only purpose, and to make an update this /// struct needs to be burned, and new struct needs to be created. -#[derive(Serialize)] pub struct Basket { pub basket_assets: Vec, } +impl Serialize for Basket { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut seq = serializer.serialize_seq(Some(self.basket_assets.len()))?; + + for asset in &self.basket_assets { + seq.serialize_element(asset)?; + } + + seq.end() + } +} + impl<'de> Deserialize<'de> for Basket { fn deserialize(deserializer: D) -> Result where diff --git a/libs/index-core/src/index/basket_manager.rs b/libs/index-core/src/index/basket_manager.rs index 43a9ec3..b4dbd11 100644 --- a/libs/index-core/src/index/basket_manager.rs +++ b/libs/index-core/src/index/basket_manager.rs @@ -47,6 +47,10 @@ impl BasketManager { .collect_vec() } + pub fn get_baskets(&self) -> &HashMap> { + &self.baskets + } + pub fn notify_baskets(&self) -> Result<()> { if self.observer.has_observer() { for (symbol, basket) in &self.baskets { diff --git a/libs/symm-core/src/core/bits.rs b/libs/symm-core/src/core/bits.rs index ec9dd09..1d2a9b9 100644 --- a/libs/symm-core/src/core/bits.rs +++ b/libs/symm-core/src/core/bits.rs @@ -20,7 +20,7 @@ pub enum PriceType { VolumeWeighted, } -#[derive(Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub struct LastPriceEntry { pub sequence_number: u64, pub best_bid_price: Option, @@ -57,7 +57,7 @@ impl LastPriceEntry { } } -#[derive(Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub struct PricePointEntry { pub price: Amount, pub quantity: Amount, @@ -116,7 +116,7 @@ impl FromStr for Side { } /// Single leg of a Batch Order -#[derive(Debug)] +#[derive(Serialize, Deserialize, Debug)] pub struct AssetOrder { /// An internal ID we assign to order pub order_id: OrderId, @@ -141,7 +141,7 @@ pub struct AssetOrder { /// quantites of Asset Orders are sent as Single Orders into -> Order Tracker, which /// then gets them send to exchange using Order Connector (-> Binance). /// -#[derive(Debug)] +#[derive(Serialize, Deserialize, Debug)] pub struct BatchOrder { /// An order ID from FIX message, one per IndexOrder pub batch_order_id: BatchOrderId, @@ -153,7 +153,7 @@ pub struct BatchOrder { pub created_timestamp: DateTime, } -#[derive(Debug)] +#[derive(Serialize, Deserialize, Debug)] pub struct SingleOrder { /// An internal ID we assign to order pub order_id: OrderId, diff --git a/libs/symm-core/src/market_data/market_data_connector.rs b/libs/symm-core/src/market_data/market_data_connector.rs index 3f75b6b..21354e3 100644 --- a/libs/symm-core/src/market_data/market_data_connector.rs +++ b/libs/symm-core/src/market_data/market_data_connector.rs @@ -1,7 +1,9 @@ use crate::core::bits::{Amount, PricePointEntry, Symbol}; use eyre::Result; +use serde::{Deserialize, Serialize}; /// abstract, connect to receive market data (live or mock) +#[derive(Serialize, Deserialize)] pub enum MarketDataEvent { TopOfBook { symbol: Symbol, diff --git a/libs/symm-core/src/order_sender/order_connector.rs b/libs/symm-core/src/order_sender/order_connector.rs index 2fdcc62..2befbf6 100644 --- a/libs/symm-core/src/order_sender/order_connector.rs +++ b/libs/symm-core/src/order_sender/order_connector.rs @@ -19,7 +19,7 @@ use opentelemetry::propagation::Injector; string_id!(SessionId); /// abstract, allow sending orders and cancels, receiving acks, naks, executions -#[derive(Debug, WithBaggage)] +#[derive(Serialize, Deserialize, Debug, WithBaggage)] pub enum OrderConnectorNotification { SessionLogon { #[baggage] diff --git a/libs/symm-core/src/order_sender/order_tracker.rs b/libs/symm-core/src/order_sender/order_tracker.rs index f7857c4..c9d00f2 100644 --- a/libs/symm-core/src/order_sender/order_tracker.rs +++ b/libs/symm-core/src/order_sender/order_tracker.rs @@ -1,9 +1,12 @@ use std::fmt::{self, write}; +use std::sync::atomic::Ordering; use std::sync::Arc; use chrono::{DateTime, Utc}; use eyre::{eyre, OptionExt, Result}; +use itertools::Itertools; use safe_math::safe; +use serde::{Deserialize, Serialize}; use std::collections::{hash_map::Entry, HashMap}; use crossbeam::atomic::AtomicCell; @@ -11,6 +14,7 @@ use parking_lot::RwLock; use crate::core::functional::{IntoObservableSingle, OneShotSingleObserver, PublishSingle}; +use crate::core::persistence::{Persist, Persistence}; use crate::core::telemetry::{TracingData, WithBaggage}; use derive_with_baggage::WithBaggage; use opentelemetry::propagation::Injector; @@ -113,7 +117,7 @@ pub enum OrderTrackerNotification { }, } -#[derive(Clone, Copy)] +#[derive(Serialize, Deserialize, Clone, Copy)] pub enum OrderStatus { Sent { order_quantity: Amount }, Live { quantity_remaining: Amount }, @@ -147,6 +151,31 @@ impl OrderEntry { } } +#[derive(Serialize, Deserialize)] +pub struct StoredOrderEntry { + pub session_id: SessionId, + pub order: Arc, + status: OrderStatus, +} + +impl StoredOrderEntry { + pub fn new(entry: &OrderEntry) -> Self { + Self { + session_id: entry.session_id.clone(), + order: entry.order.clone(), + status: entry.status.load(), + } + } + + pub fn to_live(self) -> OrderEntry { + OrderEntry { + session_id: self.session_id, + order: self.order, + status: AtomicCell::new(self.status), + } + } +} + pub struct OrderTracker { observer: SingleObserver, pub order_connector: Arc>, @@ -451,6 +480,39 @@ impl OrderTracker { Ok(()) } + + pub fn load_from(&mut self, persistence: &impl Persistence) -> Result<()> { + let Some(mut value) = persistence.load_value()? else { + return Ok(()); + }; + + if let Some(orders) = value.get_mut("orders") { + let orders: HashMap = serde_json::from_value(orders.take()) + .map_err(|err| eyre::eyre!("Failed to deserialised orders: {:?}", err))?; + + self.orders = orders + .into_iter() + .map(|(k, v)| (k, Arc::new(v.to_live()))) + .collect(); + } + + Ok(()) + } + + pub fn store_into(&self, persistence: &impl Persistence) -> Result<()> { + let orders: HashMap<_, _> = self + .orders + .iter() + .map(|(k, v)| (k.to_owned(), StoredOrderEntry::new(v))) + .collect(); + + let value = serde_json::json!({ + "orders": orders + }); + + persistence.store_value(value)?; + Ok(()) + } } impl IntoObservableSingle for OrderTracker { diff --git a/src/app/simple_router.rs b/src/app/simple_router.rs index 420e967..8ffb145 100644 --- a/src/app/simple_router.rs +++ b/src/app/simple_router.rs @@ -77,14 +77,14 @@ impl CollateralDesignation for SimpleDesignation { } } -struct SimpleBridge { +pub struct SimpleBridge { observer: RwLock>, source: Arc, destination: Arc, } impl SimpleBridge { - fn new(source: &str, symbol: &str, destination: &str) -> Self { + pub fn new(source: &str, symbol: &str, destination: &str) -> Self { Self { observer: RwLock::new(SingleObserver::new()), source: Arc::new(SimpleDesignation::new_with_symbol(source, symbol)), diff --git a/src/collateral/collateral_manager.rs b/src/collateral/collateral_manager.rs index 2970c64..36d6f47 100644 --- a/src/collateral/collateral_manager.rs +++ b/src/collateral/collateral_manager.rs @@ -82,7 +82,7 @@ pub enum CollateralEvent { }, } -pub trait CollateralManagerHost: SetSolverOrderStatus { +pub trait CollateralManagerHost { fn get_next_payment_id(&self) -> PaymentId; } @@ -176,38 +176,49 @@ impl CollateralManager { }); } - let failures = ready_to_route - .into_iter() - .filter_map(|request| { + let (successes, failures): (Vec<_>, Vec<_>) = ready_to_route + .iter() + .map(|request| { request.add_span_context_link(); - match self.router.read().transfer_collateral( - request.chain_id, - request.address, - request.client_order_id.clone(), - request.symbol.clone(), - request.side, - request.collateral_amount, - ) { - Ok(()) => None, - Err(err) => Some((err, request)), - } + self.router + .read() + .transfer_collateral( + request.chain_id, + request.address, + request.client_order_id.clone(), + request.symbol.clone(), + request.side, + request.collateral_amount, + ) + .map_err(|err| (err, request)) + .map(|_| request) }) - .collect_vec(); + .partition_result(); + + for request in successes { + self.observer + .publish_single(CollateralEvent::CollateralReady { + chain_id: request.chain_id, + address: request.address, + client_order_id: request.client_order_id.clone(), + timestamp, + collateral_amount: request.collateral_amount, + status: RoutingStatus::EnRoute, + }); + } if !failures.is_empty() { tracing::warn!( "Errors in processing: {}", failures .iter() - .map(|(err, request)| { - format!( - "\n in {} {} {}: {:?}", - request.chain_id, - request.address, - request.client_order_id.clone(), - err - ) - }) + .map(|(err, request)| format!( + "\n in {} {} {}: {:?}", + request.chain_id, + request.address, + request.client_order_id.clone(), + err + )) .join(", ") ); for (_, request) in failures { @@ -215,7 +226,7 @@ impl CollateralManager { .publish_single(CollateralEvent::CollateralReady { chain_id: request.chain_id, address: request.address, - client_order_id: request.client_order_id, + client_order_id: request.client_order_id.clone(), timestamp, collateral_amount: request.collateral_amount, status: RoutingStatus::NotReady, @@ -884,6 +895,12 @@ mod test { collateral_amount, ); } + RoutingStatus::EnRoute => { + tracing::info!( + "Collateral Ready Event {:0.5} EnRoute", + collateral_amount, + ); + } }, CollateralEvent::PreAuthResponse { status, .. } => match status { PreAuthStatus::Approved { .. } => { diff --git a/src/collateral/collateral_position.rs b/src/collateral/collateral_position.rs index d8335c8..b942658 100644 --- a/src/collateral/collateral_position.rs +++ b/src/collateral/collateral_position.rs @@ -19,6 +19,7 @@ pub enum RoutingStatus { Ready { fee: Amount }, NotReady, CheckLater, + EnRoute, } pub enum PreAuthStatus { diff --git a/src/lib.rs b/src/lib.rs index 40ae645..56e4aee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,6 +45,7 @@ pub mod server { pub mod solver { pub mod batch_manager; + pub mod batch_manager_serde; pub mod index_order; pub mod index_order_manager; pub mod index_quote; diff --git a/src/server/server.rs b/src/server/server.rs index 4595a97..003a302 100644 --- a/src/server/server.rs +++ b/src/server/server.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use chrono::{DateTime, Utc}; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use thiserror::Error; use derive_with_baggage::WithBaggage; @@ -15,7 +15,7 @@ use symm_core::core::{ use crate::solver::mint_invoice::MintInvoice; -#[derive(Serialize, WithBaggage)] +#[derive(Serialize, Deserialize, WithBaggage)] pub enum ServerEvent { NewIndexOrder { #[baggage] @@ -78,7 +78,7 @@ pub enum ServerEvent { CustodyToAccount, } -#[derive(Error, Debug)] +#[derive(Error, Debug, Serialize, Deserialize)] pub enum NewIndexOrderNakReason { #[error("Duplicate client order ID: {detail:?}")] DuplicateClientOrderId { detail: String }, @@ -90,7 +90,7 @@ pub enum NewIndexOrderNakReason { OtherReason { detail: String }, } -#[derive(Error, Debug)] +#[derive(Error, Debug, Serialize, Deserialize)] pub enum CancelIndexOrderNakReason { #[error("Index order not found: {detail:?}")] IndexOrderNotFound { detail: String }, @@ -98,7 +98,7 @@ pub enum CancelIndexOrderNakReason { OtherReason { detail: String }, } -#[derive(Error, Debug)] +#[derive(Error, Debug, Serialize, Deserialize)] pub enum NewIndexQuoteNakReason { #[error("Duplicate client quote ID: {detail:?}")] DuplicateIndexQuoteId { detail: String }, @@ -113,7 +113,7 @@ pub enum NewIndexQuoteNakReason { OtherReason { detail: String }, } -#[derive(Error, Debug)] +#[derive(Error, Debug, Serialize, Deserialize)] pub enum CancelIndexQuoteNakReason { #[error("Quote not found: {detail:?}")] IndexQuoteNotFound { detail: String }, @@ -125,7 +125,7 @@ pub enum CancelIndexQuoteNakReason { OtherReason { detail: String }, } -#[derive(Error, Debug)] +#[derive(Error, Debug, Serialize, Deserialize)] pub enum ServerError { // #[error("Sequence number out of order: {detail:?}")] // TODO: SequenceNumberOutOfOrder { detail: String }, //< example of known server errors @@ -135,7 +135,7 @@ pub enum ServerError { OtherReason { detail: String }, } -#[derive(Error, Debug)] +#[derive(Error, Debug, Serialize, Deserialize)] pub enum ServerResponseReason { #[error("{0:?}")] User(T), @@ -143,7 +143,7 @@ pub enum ServerResponseReason { Server(ServerError), } -#[derive(Error, Debug)] +#[derive(Error, Debug, Serialize, Deserialize)] pub enum NewQuoteRequestNakReason { #[error("Duplicate client quote ID: {detail:?}")] DuplicateClientQuoteId { detail: String }, @@ -155,7 +155,7 @@ pub enum NewQuoteRequestNakReason { OtherReason { detail: String }, } -#[derive(Error, Debug, WithBaggage)] +#[derive(Error, Debug, WithBaggage, Serialize, Deserialize)] pub enum ServerResponse { // ──────── Orders ──────── #[error("NewIndexOrder: ACK [{chain_id}:{address}] {client_order_id} {timestamp}")] diff --git a/src/solver/batch_manager.rs b/src/solver/batch_manager.rs index 39f5f4e..e91e4df 100644 --- a/src/solver/batch_manager.rs +++ b/src/solver/batch_manager.rs @@ -10,6 +10,7 @@ use parking_lot::{Mutex, RwLock}; use safe_math::safe; use serde::{Deserialize, Serialize}; use serde_json::json; +use serde_with::serde_as; use tracing::{info_span, span, Level}; use symm_core::{ @@ -26,6 +27,11 @@ use symm_core::{ order_sender::position::LotId, }; +use crate::solver::{ + batch_manager_serde::{StoredEngagedSolverOrders, StoredSolverOrderEngagement}, + solver::FetchSolverOrder, +}; + use super::{ index_order_manager::EngagedIndexOrder, solver::{ @@ -119,6 +125,7 @@ impl BatchAssetLot { /// positions in out inventory, for us to know what is our absolute position at /// any given moment. The BatchAssetPosition is different kind of position, in /// which we aggregate position over all lots for a batch created by Solver. +#[derive(Serialize, Deserialize)] struct BatchAssetPosition { /// Symbol of an asset symbol: Symbol, @@ -229,6 +236,8 @@ impl BatchAssetPosition { } } +#[serde_as] +#[derive(Serialize, Deserialize)] struct BatchOrderStatus { // ID of the batch order batch_order_id: BatchOrderId, @@ -236,6 +245,7 @@ struct BatchOrderStatus { /// Positions of individual assets in this batch /// Note: These aren't our absolute positions, these are only positions /// of assets acquired/disposed in this batch + #[serde_as(as = "Vec<(_, _)>")] positions: HashMap<(Symbol, Side), BatchAssetPosition>, /// Volley size (value of all orders in the batch) @@ -731,6 +741,7 @@ impl BatchManager { match index_order_write.status { SolverOrderStatus::Open | SolverOrderStatus::ManageCollateral + | SolverOrderStatus::RouteCollateral | SolverOrderStatus::Ready | SolverOrderStatus::Minted | SolverOrderStatus::InvalidSymbol @@ -1389,6 +1400,7 @@ impl BatchManager { } SolverOrderStatus::Open | SolverOrderStatus::ManageCollateral + | SolverOrderStatus::RouteCollateral | SolverOrderStatus::Ready | SolverOrderStatus::InvalidSymbol | SolverOrderStatus::InvalidOrder @@ -1415,30 +1427,104 @@ impl BatchManager { Ok(()) } -} -impl Persist for BatchManager { - fn load(&mut self) -> Result<()> { - if let Some(value) = self.persistence.load_value()? { - if let Some(carry_overs_value) = value.get("carry_overs") { - let loaded_carry_overs: Vec<((Symbol, Side), BatchCarryOver)> = - serde_json::from_value(carry_overs_value.clone()) - .map_err(|err| eyre!("Failed to deserialize carry_overs: {:?}", err))?; - *self.carry_overs.lock() = loaded_carry_overs.into_iter().collect(); - tracing::info!( - "Loaded {} carry-over positions from persistence", - self.carry_overs.lock().len() - ); - } + fn load_engagements( + &mut self, + engagements: serde_json::Value, + parent: &dyn FetchSolverOrder, + ) -> Result<()> { + let engagements: HashMap = + serde_json::from_value(engagements)?; + + let (engagements, failures): (HashMap<_, _>, Vec<_>) = engagements + .into_iter() + .map(|(k, v)| -> Result<(_, _)> { Ok((k, v.to_live(parent)?)) }) + .map_ok(|(k, v)| (k, Arc::new(RwLock::new(v)))) + .partition_result(); + + if !failures.is_empty() { + Err(eyre::eyre!( + "Failed to deserialise engagements: {:?}", + failures + ))?; + } + + self.engagements = engagements; + + Ok(()) + } + + pub fn load(&mut self, parent: &dyn FetchSolverOrder) -> Result<()> { + let Some(mut value) = self.persistence.load_value()? else { + return Ok(()); + }; + + if let Some(carry_overs) = value.get_mut("carry_overs") { + let carry_overs: Vec<((Symbol, Side), BatchCarryOver)> = + serde_json::from_value(carry_overs.take()) + .map_err(|err| eyre!("Failed to deserialize carry_overs: {:?}", err))?; + + *self.carry_overs.lock() = carry_overs.into_iter().collect(); + + tracing::info!( + "Loaded {} carry-over positions from persistence", + self.carry_overs.lock().len() + ); + } + + if let Some(batches) = value.get_mut("batches") { + let batches: HashMap = + serde_json::from_value(batches.take()) + .map_err(|err| eyre!("Failed to deserialize batches: {:?}", err))?; + + self.batches = batches + .into_iter() + .map(|(k, v)| (k, Arc::new(RwLock::new(v)))) + .collect(); } + + if let Some(engagements) = value.get_mut("engagements") { + self.load_engagements(engagements.take(), parent) + .map_err(|err| eyre!("Failed to deserialize engagements: {:?}", err))?; + } + + if let Some(total_volley_size) = value.get_mut("total_volley_size") { + *self.total_volley_size.write() = serde_json::from_value(total_volley_size.take()) + .map_err(|err| eyre!("Failed to deserialize total volley size: {:?}", err))?; + } + Ok(()) } - fn store(&self) -> Result<()> { - let carry_overs_for_serialization = self.carry_overs.lock().clone(); + pub fn store(&self) -> Result<()> { + let batches: HashMap<_, _> = self + .batches + .iter() + .map(|(k, v)| (k.to_string(), json!(&*v.read()))) + .collect(); + + let engagements: HashMap<_, _> = self + .engagements + .iter() + .map(|(k, v)| (k.to_string(), StoredEngagedSolverOrders::new(&v.read()))) + .collect(); + + let carry_overs = self + .carry_overs + .lock() + .iter() + .map(|(k, v)| (k.to_owned(), v.to_owned())) + .collect_vec(); + + let total_volley_size = *self.total_volley_size.read(); + let data = json!({ - "carry_overs": carry_overs_for_serialization.into_iter().collect_vec() + "batches": batches, + "engagements": engagements, + "carry_overs": carry_overs, + "total_volley_size": total_volley_size }); + self.persistence .store_value(data) .map_err(|err| eyre!("Failed to store BatchManager state: {:?}", err)) @@ -1486,7 +1572,7 @@ mod test { use index_core::index::basket::{AssetWeight, Basket, BasketDefinition}; - use crate::{app::timestamp_ids, solver::{ + use crate::solver::{ batch_manager::BatchEvent, index_order_manager::EngagedIndexOrder, solver::{ @@ -1495,7 +1581,7 @@ mod test { }, solver_order::solver_order::{SolverOrder, SolverOrderAssetLot, SolverOrderStatus}, solver_quote::{SolverQuote, SolverQuoteStatus}, - }}; + }; use super::{BatchAssetLot, BatchAssetPosition, BatchManager, BatchManagerHost}; diff --git a/src/solver/batch_manager_serde.rs b/src/solver/batch_manager_serde.rs new file mode 100644 index 0000000..683bafa --- /dev/null +++ b/src/solver/batch_manager_serde.rs @@ -0,0 +1,140 @@ +use std::{collections::HashMap, sync::Arc}; + +use alloy::rpc::types::trace::tracerequest::TraceCallRequest; +use eyre::OptionExt; +use index_core::index::basket::Basket; +use itertools::Itertools; +use serde::{Deserialize, Serialize}; +use symm_core::core::{ + bits::{Address, Amount, BatchOrderId, ClientOrderId, Side, Symbol}, + telemetry::TracingData, +}; + +use crate::solver::solver::{ + EngagedSolverOrders, EngagedSolverOrdersSide, FetchSolverOrder, SolverOrderEngagement, +}; + +#[derive(Serialize, Deserialize)] +pub struct StoredSolverOrderEngagement { + pub asset_contribution_fractions: HashMap, + pub asset_quantity_contributions: HashMap, + pub chain_id: u32, + pub address: Address, + pub client_order_id: ClientOrderId, + pub symbol: Symbol, + pub engaged_side: Side, + pub engaged_collateral: Amount, + pub new_engaged_collateral: Amount, + pub engaged_quantity: Amount, + pub engaged_price: Amount, + pub filled_quantity: Amount, +} + +#[derive(Serialize, Deserialize)] +pub struct StoredEngagedSolverOrdersSide { + pub asset_price_limits: HashMap, + pub asset_quantities: HashMap, + pub engaged_orders: Vec, +} + +#[derive(Serialize, Deserialize)] +pub struct StoredEngagedSolverOrders { + pub batch_order_id: BatchOrderId, + pub engaged_buys: StoredEngagedSolverOrdersSide, +} + +impl StoredSolverOrderEngagement { + pub fn new(engagement: &SolverOrderEngagement) -> Self { + Self { + asset_contribution_fractions: engagement.asset_contribution_fractions.clone(), + asset_quantity_contributions: engagement.asset_quantity_contributions.clone(), + chain_id: engagement.chain_id, + address: engagement.address, + client_order_id: engagement.client_order_id.clone(), + symbol: engagement.symbol.clone(), + engaged_side: engagement.engaged_side, + engaged_collateral: engagement.engaged_collateral, + new_engaged_collateral: engagement.new_engaged_collateral, + engaged_quantity: engagement.engaged_quantity, + engaged_price: engagement.engaged_price, + filled_quantity: engagement.filled_quantity, + } + } + + pub fn to_live(self, parent: &dyn FetchSolverOrder) -> eyre::Result { + let index_order = parent + .fetch_client_order(self.chain_id, &self.address, &self.client_order_id) + .ok_or_eyre("Failed to fetch index order")?; + + let basket = parent + .fetch_basket(&self.symbol) + .ok_or_eyre("Failed to fetch basket")?; + + Ok(SolverOrderEngagement { + index_order, + asset_contribution_fractions: self.asset_contribution_fractions, + asset_quantity_contributions: self.asset_quantity_contributions, + chain_id: self.chain_id, + address: self.address, + client_order_id: self.client_order_id, + symbol: self.symbol, + basket, + engaged_side: self.engaged_side, + engaged_collateral: self.engaged_collateral, + new_engaged_collateral: self.new_engaged_collateral, + engaged_quantity: self.engaged_quantity, + engaged_price: self.engaged_price, + filled_quantity: self.filled_quantity, + }) + } +} + +impl StoredEngagedSolverOrdersSide { + pub fn new(engaged: &EngagedSolverOrdersSide) -> Self { + Self { + asset_price_limits: engaged.asset_price_limits.clone(), + asset_quantities: engaged.asset_quantities.clone(), + engaged_orders: engaged + .engaged_orders + .iter() + .map(|v| StoredSolverOrderEngagement::new(v)) + .collect_vec(), + } + } + + pub fn to_live(self, parent: &dyn FetchSolverOrder) -> eyre::Result { + let (engaged_orders, failed): (Vec<_>, Vec<_>) = self + .engaged_orders + .into_iter() + .map(|x| x.to_live(parent)) + .partition_result(); + + if !failed.is_empty() { + Err(eyre::eyre!("Failed to load engaged orders: {:?}", failed))?; + } + + Ok(EngagedSolverOrdersSide { + asset_price_limits: self.asset_price_limits, + asset_quantities: self.asset_quantities, + engaged_orders, + }) + } +} + +impl StoredEngagedSolverOrders { + pub fn new(engagement: &EngagedSolverOrders) -> Self { + Self { + batch_order_id: engagement.batch_order_id.clone(), + engaged_buys: StoredEngagedSolverOrdersSide::new(&engagement.engaged_buys), + } + } + + pub fn to_live(self, parent: &dyn FetchSolverOrder) -> eyre::Result { + let engaged_buys = self.engaged_buys.to_live(parent)?; + Ok(EngagedSolverOrders { + batch_order_id: self.batch_order_id, + engaged_buys, + trace_data: TracingData::default(), + }) + } +} diff --git a/src/solver/solver.rs b/src/solver/solver.rs index 96f69fe..f303bad 100644 --- a/src/solver/solver.rs +++ b/src/solver/solver.rs @@ -1,6 +1,5 @@ use std::{ collections::{HashMap, VecDeque}, - isize, sync::{ atomic::{AtomicU8, Ordering}, Arc, RwLock as ComponentLock, @@ -163,6 +162,17 @@ pub trait SetSolverOrderStatus { fn set_quote_status(&self, order: &mut SolverQuote, status: SolverQuoteStatus); } +pub trait FetchSolverOrder { + fn fetch_client_order( + &self, + chain_id: u32, + address: &Address, + client_order_id: &ClientOrderId, + ) -> Option>>; + + fn fetch_basket(&self, symbol: &Symbol) -> Option>; +} + pub trait SolverStrategyHost: SetSolverOrderStatus { fn get_next_batch_order_id(&self) -> BatchOrderId; fn get_basket(&self, symbol: &Symbol) -> Option>; @@ -1014,6 +1024,14 @@ impl Solver { timestamp, )?; } + RoutingStatus::EnRoute => { + tracing::info!(%chain_id, %address, %collateral_amount, "🚚 CollateralReady EnRoute"); + + self.set_order_status( + &mut order.write(), + SolverOrderStatus::RouteCollateral, + ); + } RoutingStatus::CheckLater => { tracing::info!(%chain_id, %address, %collateral_amount, "⏱️ CollateralReady CheckLater"); @@ -1773,6 +1791,23 @@ impl SetSolverOrderStatus for Solver { } } +impl FetchSolverOrder for Solver { + fn fetch_client_order( + &self, + chain_id: u32, + address: &Address, + client_order_id: &ClientOrderId, + ) -> Option>> { + self.client_orders + .read() + .get_client_order(chain_id, *address, client_order_id.clone()) + } + + fn fetch_basket(&self, symbol: &Symbol) -> Option> { + self.basket_manager.read().get_basket(symbol).cloned() + } +} + impl SolverStrategyHost for Solver { fn get_next_batch_order_id(&self) -> BatchOrderId { self.order_id_provider.write().next_batch_order_id() @@ -1864,7 +1899,12 @@ impl CollateralManagerHost for Solver { impl Persist for Solver { fn load(&mut self) -> Result<()> { - // First load all dependent components + if let Some(value) = self.persistence.load_value()? { + self.load_solver_state(value)?; + } else { + tracing::info!("No persisted solver state found, starting with empty state"); + } + self.index_order_manager .write() .map_err(|err| eyre!("Failed to access index order manager: {:?}", err))? @@ -1875,19 +1915,12 @@ impl Persist for Solver { .map_err(|err| eyre!("Failed to access collateral manager: {:?}", err))? .load()?; + self.inventory_manager.write().load()?; + self.batch_manager .write() .map_err(|err| eyre!("Failed to access batch manager: {:?}", err))? - .load()?; - - self.inventory_manager.write().load()?; - - // Load solver-specific state - if let Some(value) = self.persistence.load_value()? { - self.load_solver_state(value)?; - } else { - tracing::info!("No persisted solver state found, starting with empty state"); - } + .load(self)?; Ok(()) } diff --git a/src/solver/solver_order/solver_order.rs b/src/solver/solver_order/solver_order.rs index 033c14f..839a662 100644 --- a/src/solver/solver_order/solver_order.rs +++ b/src/solver/solver_order/solver_order.rs @@ -26,6 +26,7 @@ use symm_core::{ pub enum SolverOrderStatus { Open, ManageCollateral, + RouteCollateral, Ready, Engaged, PartlyMintable, @@ -90,6 +91,7 @@ pub struct SolverOrder { pub lots: Vec, /// Telemetry data + #[serde(skip)] pub tracing_data: TracingData, }