diff --git a/Cargo.lock b/Cargo.lock index 84d7a2fc..f056eea2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,7 +39,7 @@ dependencies = [ "actix-web", "derive_more", "futures-util", - "log 0.4.20", + "log", "once_cell", "smallvec", ] @@ -54,7 +54,7 @@ dependencies = [ "actix-rt", "actix-service", "actix-utils", - "ahash 0.8.7", + "ahash 0.8.6", "base64 0.21.5", "bitflags 2.4.1", "brotli", @@ -69,10 +69,10 @@ dependencies = [ "httparse", "httpdate", "itoa", - "language-tags 0.3.2", + "language-tags", "local-channel", - "mime 0.3.17", - "percent-encoding 2.3.1", + "mime", + "percent-encoding", "pin-project-lite", "rand 0.8.5", "sha1", @@ -169,7 +169,7 @@ dependencies = [ "actix-service", "actix-utils", "actix-web-codegen", - "ahash 0.8.7", + "ahash 0.8.6", "bytes", "bytestring", "cfg-if", @@ -179,9 +179,9 @@ dependencies = [ "futures-core", "futures-util", "itoa", - "language-tags 0.3.2", - "log 0.4.20", - "mime 0.3.17", + "language-tags", + "log", + "mime", "once_cell", "pin-project-lite", "regex", @@ -190,8 +190,8 @@ dependencies = [ "serde_urlencoded", "smallvec", "socket2", - "time 0.3.31", - "url 2.5.0", + "time", + "url", ] [[package]] @@ -265,19 +265,19 @@ checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom 0.2.11", "once_cell", - "version_check 0.9.4", + "version_check", ] [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", "getrandom 0.2.11", "once_cell", - "version_check 0.9.4", + "version_check", "zerocopy", ] @@ -311,7 +311,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5f619f1d04f53621925ba8a2e633ba5a6081f2ae14758cbb67f38fd823e0a3e" dependencies = [ - "anchor-syn 0.29.0", + "anchor-syn", "proc-macro2", "quote", "syn 1.0.109", @@ -323,7 +323,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f2a3e1df4685f18d12a943a9f2a7456305401af21a07c9fe076ef9ecd6e400" dependencies = [ - "anchor-syn 0.29.0", + "anchor-syn", "bs58 0.5.0", "proc-macro2", "quote", @@ -336,7 +336,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9423945cb55627f0b30903288e78baf6f62c6c8ab28fb344b6b25f1ffee3dca7" dependencies = [ - "anchor-syn 0.29.0", + "anchor-syn", "quote", "syn 1.0.109", ] @@ -347,7 +347,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93ed12720033cc3c3bf3cfa293349c2275cd5ab99936e33dd4bf283aaad3e241" dependencies = [ - "anchor-syn 0.29.0", + "anchor-syn", "quote", "syn 1.0.109", ] @@ -358,7 +358,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eef4dc0371eba2d8c8b54794b0b0eb786a234a559b77593d6f80825b6d2c77a2" dependencies = [ - "anchor-syn 0.29.0", + "anchor-syn", "proc-macro2", "quote", "syn 1.0.109", @@ -370,7 +370,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b18c4f191331e078d4a6a080954d1576241c29c56638783322a18d308ab27e4f" dependencies = [ - "anchor-syn 0.29.0", + "anchor-syn", "quote", "syn 1.0.109", ] @@ -381,7 +381,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5de10d6e9620d3bcea56c56151cad83c5992f50d5960b3a9bebc4a50390ddc3c" dependencies = [ - "anchor-syn 0.29.0", + "anchor-syn", "quote", "syn 1.0.109", ] @@ -392,7 +392,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4e2e5be518ec6053d90a2a7f26843dbee607583c779e6c8395951b9739bdfbe" dependencies = [ - "anchor-syn 0.29.0", + "anchor-syn", "borsh-derive-internal 0.10.3", "proc-macro2", "quote", @@ -448,24 +448,6 @@ dependencies = [ "spl-token-2022 0.9.0", ] -[[package]] -name = "anchor-syn" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11cb31fe143aedb36fc41409ea072aa0b840cbea727e62eb2ff6e7b6cea036ff" -dependencies = [ - "anyhow", - "bs58 0.3.1", - "heck 0.3.3", - "proc-macro2", - "quote", - "serde", - "serde_json", - "sha2 0.9.9", - "syn 1.0.109", - "thiserror", -] - [[package]] name = "anchor-syn" version = "0.29.0" @@ -662,7 +644,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.31", + "time", ] [[package]] @@ -739,12 +721,6 @@ dependencies = [ "syn 2.0.47", ] -[[package]] -name = "async_once" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ce4f10ea3abcd6617873bae9f91d1c5332b4a778bd9ce34d0cd517474c1de82" - [[package]] name = "atty" version = "0.2.14" @@ -777,16 +753,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -dependencies = [ - "byteorder", - "safemem", -] - [[package]] name = "base64" version = "0.12.3" @@ -994,12 +960,6 @@ dependencies = [ "alloc-stdlib", ] -[[package]] -name = "bs58" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" - [[package]] name = "bs58" version = "0.4.0" @@ -1015,20 +975,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "bugsnag" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20015af8027d22db67e2c84f8b9f2c31b1efa0ec554d8b210c77acb7065d69bf" -dependencies = [ - "backtrace", - "hyper 0.10.16", - "serde", - "serde_derive", - "serde_json", - "sys-info", -] - [[package]] name = "bumpalo" version = "3.14.0" @@ -1045,16 +991,6 @@ dependencies = [ "serde", ] -[[package]] -name = "byte-unit" -version = "4.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c" -dependencies = [ - "serde", - "utf8-width", -] - [[package]] name = "bytemuck" version = "1.14.0" @@ -1252,52 +1188,6 @@ dependencies = [ "os_str_bytes", ] -[[package]] -name = "clockwork-anchor-gen" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7bb5c1101a261455e32d9017be20f2202eb4e09aae0497e30a20915f4ebc9a" -dependencies = [ - "clockwork-anchor-generate-cpi-crate", - "clockwork-anchor-generate-cpi-interface", -] - -[[package]] -name = "clockwork-anchor-generate-cpi-crate" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa2ea8df18090fea5be162c5ebe57569af47692fae626424160d14460d7ed95b" -dependencies = [ - "clockwork-anchor-idl", - "syn 1.0.109", -] - -[[package]] -name = "clockwork-anchor-generate-cpi-interface" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e601b4b0b6f2e78d8502996b900fce5811ecf1479f84a07e3fb80fcd38117e8" -dependencies = [ - "clockwork-anchor-idl", - "darling 0.14.4", - "syn 1.0.109", -] - -[[package]] -name = "clockwork-anchor-idl" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a949f478bf927b4d61cd0a1be78d9c6fd07361a25e327966b06d1cdc342ff839" -dependencies = [ - "anchor-syn 0.27.0", - "darling 0.14.4", - "heck 0.4.1", - "proc-macro2", - "quote", - "serde_json", - "syn 1.0.109", -] - [[package]] name = "clockwork-cli" version = "2.0.18" @@ -1322,14 +1212,10 @@ dependencies = [ "reqwest", "serde", "serde_json", - "serde_yaml", - "solana-account-decoder", - "solana-clap-utils", "solana-cli-config", "solana-client", "solana-sdk", "spl-associated-token-account 1.1.3", - "spl-memo 3.0.1", "spl-token 3.5.0", "tar", "termcolor", @@ -1342,7 +1228,6 @@ version = "2.0.18" dependencies = [ "chrono", "nom", - "once_cell", ] [[package]] @@ -1352,8 +1237,6 @@ dependencies = [ "anchor-lang", "anchor-spl", "clockwork-utils", - "toml_datetime", - "winnow", ] [[package]] @@ -1372,12 +1255,8 @@ dependencies = [ "actix-cors", "actix-web", "anchor-lang", - "bincode", - "byte-unit", "clockwork-relayer-api", "clockwork-webhook-program", - "curve25519-dalek", - "lazy_static", "rayon", "regex", "reqwest", @@ -1386,7 +1265,6 @@ dependencies = [ "solana-client", "solana-sdk", "solana-zk-token-sdk", - "tokio", ] [[package]] @@ -1403,10 +1281,7 @@ name = "clockwork-sdk" version = "2.0.18" dependencies = [ "anchor-lang", - "chrono", "clockwork-thread-program", - "nom", - "once_cell", ] [[package]] @@ -1417,21 +1292,11 @@ dependencies = [ "chrono", "clockwork-cron", "clockwork-network-program", - "clockwork-thread-program-v1", "clockwork-utils", "pyth-sdk-solana", - "static-pubkey", "version", ] -[[package]] -name = "clockwork-thread-program-v1" -version = "1.4.4" -dependencies = [ - "anchor-lang", - "clockwork-anchor-gen", -] - [[package]] name = "clockwork-utils" version = "2.0.18" @@ -1439,7 +1304,6 @@ dependencies = [ "anchor-lang", "base64 0.13.1", "serde", - "serde_json", "static-pubkey", ] @@ -1448,8 +1312,6 @@ name = "clockwork-webhook-program" version = "2.0.18" dependencies = [ "anchor-lang", - "clockwork-network-program", - "clockwork-utils", "serde", ] @@ -1459,10 +1321,7 @@ version = "2.0.18" dependencies = [ "anchor-lang", "async-trait", - "async_once", "bincode", - "bs58 0.4.0", - "bugsnag", "cargo_metadata", "chrono", "clockwork-cron", @@ -1470,18 +1329,13 @@ dependencies = [ "clockwork-plugin-utils", "clockwork-relayer-api", "clockwork-thread-program", - "clockwork-thread-program-v1", "clockwork-utils", "clockwork-webhook-program", "futures", - "lazy_static", - "log 0.4.20", - "prost", + "log", "pyth-sdk-solana", "reqwest", "rustc_version", - "serde", - "serde_json", "solana-account-decoder", "solana-client", "solana-geyser-plugin-interface", @@ -1489,9 +1343,7 @@ dependencies = [ "solana-program", "solana-quic-client", "solana-sdk", - "solana-transaction-status", "static-pubkey", - "thiserror", "tokio", ] @@ -1546,7 +1398,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" dependencies = [ - "log 0.4.20", + "log", "web-sys", ] @@ -1574,9 +1426,9 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ - "percent-encoding 2.3.1", - "time 0.3.31", - "version_check 0.9.4", + "percent-encoding", + "time", + "version_check", ] [[package]] @@ -1703,38 +1555,14 @@ dependencies = [ "zeroize", ] -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", -] - [[package]] name = "darling" version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", + "darling_core", + "darling_macro", ] [[package]] @@ -1751,24 +1579,13 @@ dependencies = [ "syn 2.0.47", ] -[[package]] -name = "darling_macro" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" -dependencies = [ - "darling_core 0.14.4", - "quote", - "syn 1.0.109", -] - [[package]] name = "darling_macro" version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ - "darling_core 0.20.3", + "darling_core", "quote", "syn 2.0.47", ] @@ -2034,7 +1851,7 @@ checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" dependencies = [ "atty", "humantime", - "log 0.4.20", + "log", "regex", "termcolor", ] @@ -2122,7 +1939,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "percent-encoding 2.3.1", + "percent-encoding", ] [[package]] @@ -2222,7 +2039,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "serde", "typenum", - "version_check 0.9.4", + "version_check", ] [[package]] @@ -2273,7 +2090,7 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7666983ed0dd8d21a6f6576ee00053ca0926fb281a5522577a4dbd0f1b54143" dependencies = [ - "log 0.4.20", + "log", "plain", "scroll", ] @@ -2327,7 +2144,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.7", + "ahash 0.8.6", ] [[package]] @@ -2451,25 +2268,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "hyper" -version = "0.10.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" -dependencies = [ - "base64 0.9.3", - "httparse", - "language-tags 0.2.2", - "log 0.3.9", - "mime 0.2.6", - "num_cpus", - "time 0.1.45", - "traitobject", - "typeable", - "unicase", - "url 1.7.2", -] - [[package]] name = "hyper" version = "0.14.28" @@ -2502,7 +2300,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http", - "hyper 0.14.28", + "hyper", "rustls", "tokio", "tokio-rustls", @@ -2515,7 +2313,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.28", + "hyper", "native-tls", "tokio", "tokio-native-tls", @@ -2550,17 +2348,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "idna" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "idna" version = "0.5.0" @@ -2584,7 +2371,7 @@ dependencies = [ "serde", "sized-chunks", "typenum", - "version_check 0.9.4", + "version_check", ] [[package]] @@ -2689,7 +2476,7 @@ dependencies = [ "futures", "futures-executor", "futures-util", - "log 0.4.20", + "log", "serde", "serde_derive", "serde_json", @@ -2704,12 +2491,6 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" - [[package]] name = "language-tags" version = "0.3.2" @@ -2832,27 +2613,12 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -dependencies = [ - "log 0.4.20", -] - [[package]] name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "memchr" version = "2.7.1" @@ -2898,15 +2664,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "mime" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -dependencies = [ - "log 0.3.9", -] - [[package]] name = "mime" version = "0.3.17" @@ -2935,7 +2692,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", - "log 0.4.20", + "log", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -2948,7 +2705,7 @@ checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ "lazy_static", "libc", - "log 0.4.20", + "log", "openssl", "openssl-probe", "openssl-sys", @@ -3306,12 +3063,6 @@ dependencies = [ "base64 0.13.1", ] -[[package]] -name = "percent-encoding" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" - [[package]] name = "percent-encoding" version = "2.3.1" @@ -3421,7 +3172,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "version_check 0.9.4", + "version_check", ] [[package]] @@ -3432,7 +3183,7 @@ checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", "quote", - "version_check 0.9.4", + "version_check", ] [[package]] @@ -3444,29 +3195,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prost" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "pyth-sdk" version = "0.8.0" @@ -3504,7 +3232,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" dependencies = [ - "percent-encoding 2.3.1", + "percent-encoding", ] [[package]] @@ -3683,7 +3411,7 @@ checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", "ring 0.16.20", - "time 0.3.31", + "time", "yasna", ] @@ -3751,16 +3479,16 @@ dependencies = [ "h2", "http", "http-body", - "hyper 0.14.28", + "hyper", "hyper-rustls", "hyper-tls", "ipnet", "js-sys", - "log 0.4.20", - "mime 0.3.17", + "log", + "mime", "native-tls", "once_cell", - "percent-encoding 2.3.1", + "percent-encoding", "pin-project-lite", "rustls", "rustls-pemfile", @@ -3773,7 +3501,7 @@ dependencies = [ "tokio-rustls", "tokio-util", "tower-service", - "url 2.5.0", + "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -3880,7 +3608,7 @@ version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ - "log 0.4.20", + "log", "ring 0.17.7", "rustls-webpki", "sct", @@ -3929,12 +3657,6 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" -[[package]] -name = "safemem" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" - [[package]] name = "schannel" version = "0.1.23" @@ -4115,7 +3837,7 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ - "darling 0.20.3", + "darling", "proc-macro2", "quote", "syn 2.0.47", @@ -4286,7 +4008,7 @@ dependencies = [ "thiserror", "tiny-bip39", "uriparse", - "url 2.5.0", + "url", ] [[package]] @@ -4302,7 +4024,7 @@ dependencies = [ "serde_yaml", "solana-clap-utils", "solana-sdk", - "url 2.5.0", + "url", ] [[package]] @@ -4318,7 +4040,7 @@ dependencies = [ "futures-util", "indexmap 2.1.0", "indicatif 0.17.7", - "log 0.4.20", + "log", "quinn", "rayon", "solana-connection-cache", @@ -4363,7 +4085,7 @@ dependencies = [ "crossbeam-channel", "futures-util", "indexmap 2.1.0", - "log 0.4.20", + "log", "rand 0.8.5", "rayon", "rcgen", @@ -4380,7 +4102,7 @@ version = "1.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e2c5e5dde22cac045d29675b3fefa84817e1f63b0b911d094c599e80c0c07d9" dependencies = [ - "ahash 0.8.7", + "ahash 0.8.6", "blake3", "block-buffer 0.10.4", "bs58 0.4.0", @@ -4391,7 +4113,7 @@ dependencies = [ "generic-array", "im", "lazy_static", - "log 0.4.20", + "log", "memmap2", "rustc_version", "serde", @@ -4422,7 +4144,7 @@ version = "1.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d910a096a3eac2546c4d654158c2fad8b88d5b733c1225d876de144a09fa262" dependencies = [ - "log 0.4.20", + "log", "solana-sdk", "solana-transaction-status", "thiserror", @@ -4436,7 +4158,7 @@ checksum = "d37a1b1a383a01039afbc6447a1712fb2a1a73a5ba8916762e693e8e492fabf3" dependencies = [ "env_logger", "lazy_static", - "log 0.4.20", + "log", ] [[package]] @@ -4445,7 +4167,7 @@ version = "1.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19831a93d760205f5c3e20d05a37b0e533caa1889e48041648ad0859e68ec336" dependencies = [ - "log 0.4.20", + "log", "solana-sdk", ] @@ -4458,7 +4180,7 @@ dependencies = [ "crossbeam-channel", "gethostname", "lazy_static", - "log 0.4.20", + "log", "reqwest", "solana-sdk", "thiserror", @@ -4473,7 +4195,7 @@ dependencies = [ "bincode", "clap 3.2.25", "crossbeam-channel", - "log 0.4.20", + "log", "nix", "rand 0.8.5", "serde", @@ -4483,7 +4205,7 @@ dependencies = [ "solana-sdk", "solana-version", "tokio", - "url 2.5.0", + "url", ] [[package]] @@ -4492,7 +4214,7 @@ version = "1.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdf5a429e018e8ba693f4c43f833192db421fe97b88dfaf97041aa258e4b191" dependencies = [ - "ahash 0.8.7", + "ahash 0.8.6", "bincode", "bv", "caps", @@ -4501,7 +4223,7 @@ dependencies = [ "fnv", "lazy_static", "libc", - "log 0.4.20", + "log", "nix", "rand 0.8.5", "rayon", @@ -4545,7 +4267,7 @@ dependencies = [ "libc", "libsecp256k1", "light-poseidon", - "log 0.4.20", + "log", "memoffset 0.9.0", "num-bigint 0.4.4", "num-derive 0.3.3", @@ -4581,7 +4303,7 @@ dependencies = [ "enum-iterator", "itertools", "libc", - "log 0.4.20", + "log", "num-derive 0.3.3", "num-traits", "percentage", @@ -4605,7 +4327,7 @@ checksum = "2c22290c0d296a6a250a8d5b680797f12138a81af9c403a6ce62bd3ddad307e6" dependencies = [ "crossbeam-channel", "futures-util", - "log 0.4.20", + "log", "reqwest", "semver", "serde", @@ -4619,7 +4341,7 @@ dependencies = [ "tokio-stream", "tokio-tungstenite", "tungstenite", - "url 2.5.0", + "url", ] [[package]] @@ -4633,7 +4355,7 @@ dependencies = [ "futures", "itertools", "lazy_static", - "log 0.4.20", + "log", "quinn", "quinn-proto", "rcgen", @@ -4667,7 +4389,7 @@ checksum = "fb9a96d1c001d07a0abb08e05b92ff6528b2d9239d03c57f99f738527839eb12" dependencies = [ "console", "dialoguer", - "log 0.4.20", + "log", "num-derive 0.3.3", "num-traits", "parking_lot", @@ -4689,7 +4411,7 @@ dependencies = [ "bincode", "bs58 0.4.0", "indicatif 0.17.7", - "log 0.4.20", + "log", "reqwest", "semver", "serde", @@ -4764,7 +4486,7 @@ dependencies = [ "js-sys", "lazy_static", "libsecp256k1", - "log 0.4.20", + "log", "memmap2", "num-derive 0.3.3", "num-traits", @@ -4826,7 +4548,7 @@ dependencies = [ "indexmap 2.1.0", "itertools", "libc", - "log 0.4.20", + "log", "nix", "pem", "percentage", @@ -4851,7 +4573,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54e782aabf9443a36d65e74d70ce732cc844707a5fec5a498bcbd81d3de7598c" dependencies = [ "bincode", - "log 0.4.20", + "log", "rayon", "solana-connection-cache", "solana-rpc-client", @@ -4870,7 +4592,7 @@ dependencies = [ "futures-util", "indexmap 2.1.0", "indicatif 0.17.7", - "log 0.4.20", + "log", "rayon", "solana-connection-cache", "solana-measure", @@ -4895,7 +4617,7 @@ dependencies = [ "borsh 0.10.3", "bs58 0.4.0", "lazy_static", - "log 0.4.20", + "log", "serde", "serde_derive", "serde_json", @@ -4929,7 +4651,7 @@ version = "1.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b32cc394aa7132ab7f270801b98bf47fa585ab93f1038e5be27e480d7b5b2dca" dependencies = [ - "log 0.4.20", + "log", "rustc_version", "semver", "serde", @@ -4946,7 +4668,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589cad4dccb4392e23f5ae4ccdd1f0aaa10f2823b264b27c4feb6382f40f4fd4" dependencies = [ "bincode", - "log 0.4.20", + "log", "num-derive 0.3.3", "num-traits", "rustc_version", @@ -5001,7 +4723,7 @@ dependencies = [ "goblin", "hash32", "libc", - "log 0.4.20", + "log", "rand 0.8.5", "rustc-demangle", "scroll", @@ -5412,16 +5134,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "sys-info" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58283a48c9212afcade2069f8bbf7ded6a7bdbf4888d2defba72244c8e5f423c" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "system-configuration" version = "0.5.1" @@ -5511,17 +5223,6 @@ dependencies = [ "syn 2.0.47", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "time" version = "0.3.31" @@ -5653,7 +5354,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", - "log 0.4.20", + "log", "rustls", "tokio", "tokio-rustls", @@ -5713,7 +5414,7 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "log 0.4.20", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -5739,12 +5440,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "traitobject" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" - [[package]] name = "try-lock" version = "0.2.5" @@ -5762,37 +5457,22 @@ dependencies = [ "data-encoding", "http", "httparse", - "log 0.4.20", + "log", "rand 0.8.5", "rustls", "sha1", "thiserror", - "url 2.5.0", + "url", "utf-8", "webpki-roots 0.24.0", ] -[[package]] -name = "typeable" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" - [[package]] name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "unicase" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -dependencies = [ - "version_check 0.1.5", -] - [[package]] name = "unicode-bidi" version = "0.3.14" @@ -5879,17 +5559,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "url" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -dependencies = [ - "idna 0.1.5", - "matches", - "percent-encoding 1.0.1", -] - [[package]] name = "url" version = "2.5.0" @@ -5897,8 +5566,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", - "idna 0.5.0", - "percent-encoding 2.3.1", + "idna", + "percent-encoding", ] [[package]] @@ -5907,12 +5576,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf8-width" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" - [[package]] name = "vcpkg" version = "0.2.15" @@ -5931,12 +5594,6 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a449064fee414fcc201356a3e6c1510f6c8829ed28bb06b91c54ebe208ce065" -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" - [[package]] name = "version_check" version = "0.9.4" @@ -5964,12 +5621,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -5993,7 +5644,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", - "log 0.4.20", + "log", "once_cell", "proc-macro2", "quote", @@ -6339,7 +5990,7 @@ dependencies = [ "oid-registry", "rusticata-macros", "thiserror", - "time 0.3.31", + "time", ] [[package]] @@ -6359,7 +6010,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.31", + "time", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 27366532..69bcced9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,3 +3,10 @@ members = ["cli", "cron", "plugin", "programs/*", "relayer", "sdk", "utils"] [profile.release] overflow-checks = true +lto = "fat" +codegen-units = 1 + +[profile.release.build-override] +opt-level = 3 +incremental = false +codegen-units = 1 diff --git a/cli/Cargo.toml b/cli/Cargo.toml index cd387943..acb7d986 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -37,14 +37,10 @@ indicatif = "0.16" reqwest = "0.11.14" serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.79" -serde_yaml = "0.9.4" -solana-account-decoder = "=1.17.14" solana-client = "=1.17.14" -solana-clap-utils = "=1.17.14" solana-cli-config = "=1.17.14" solana-sdk = "=1.17.14" spl-associated-token-account = "1.1.1" -spl-memo = "3.0.1" spl-token = "~3.5.0" tar = "0.4" thiserror = "1.0.30" diff --git a/cli/build.rs b/cli/build.rs index 2895d9d8..42311482 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -2,7 +2,7 @@ use std::process::Command; fn main() { let output = Command::new("git") - .args(&["rev-parse", "HEAD"]) + .args(["rev-parse", "HEAD"]) .output() .expect("unable to get git commit hash"); let commit_hash = String::from_utf8(output.stdout).unwrap(); diff --git a/cli/src/client.rs b/cli/src/client.rs index 6075781a..23d52699 100644 --- a/cli/src/client.rs +++ b/cli/src/client.rs @@ -1,8 +1,7 @@ use anchor_lang::{prelude::Clock, AccountDeserialize}; use clockwork_utils::ProgramLogsDeserializable; use solana_client::{ - client_error, rpc_client::RpcClient, - rpc_response::RpcSimulateTransactionResult, + client_error, rpc_client::RpcClient, rpc_response::RpcSimulateTransactionResult, }; use solana_sdk::{ commitment_config::CommitmentConfig, @@ -21,7 +20,6 @@ use std::{ }; use thiserror::Error; - #[derive(Debug, Error)] pub enum ClientError { #[error(transparent)] @@ -135,7 +133,6 @@ impl Client { } } - impl Debug for Client { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "RPC client payer {}", self.payer_pubkey()) @@ -155,4 +152,3 @@ impl DerefMut for Client { &mut self.client } } - diff --git a/cli/src/config.rs b/cli/src/config.rs index e16c7eed..29d86ab8 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -2,12 +2,7 @@ use { crate::deps::ToTagVersion, clap::crate_version, solana_sdk::commitment_config::CommitmentConfig, - std::{ - env, - fs, - path::PathBuf, - time::Duration, - }, + std::{env, fs, path::PathBuf, time::Duration}, }; pub const DEFAULT_RPC_TIMEOUT_SECONDS: Duration = Duration::from_secs(30); @@ -82,7 +77,7 @@ impl CliConfig { } pub fn active_runtime(&self, filename: &str) -> String { - if self.dev == true { + if self.dev { if filename.contains("solana") { self.active_runtime_dir().join(filename).to_string() } else if filename.contains("program") { @@ -103,9 +98,7 @@ impl CliConfig { path.extend(["test-ledger", "validator-keypair.json"]); path }) - .expect(&format!( - "Unable to find location of validator-keypair.json" - )) + .unwrap_or_else(|_| panic!("Unable to find location of validator-keypair.json")) .to_string() } @@ -114,7 +107,7 @@ impl CliConfig { } pub fn geyser_lib(&self) -> String { - if self.dev == true && env::consts::OS.to_lowercase().contains("mac") { + if self.dev && env::consts::OS.to_lowercase().contains("mac") { self.active_runtime("libclockwork_plugin.dylib") } else { // in the release process, we always rename dylib to so anyway @@ -146,8 +139,8 @@ impl CliConfig { String::from_utf8(output.stdout) .expect("Unable to get output from cargo -vV") .split('\n') - .find(|line| line.trim_start().to_lowercase().starts_with(&host_prefix)) - .map(|line| line.trim_start_matches(&host_prefix).trim()) + .find(|line| line.trim_start().to_lowercase().starts_with(host_prefix)) + .map(|line| line.trim_start_matches(host_prefix).trim()) .expect("Unable to detect target 'host' from cargo -vV") .to_owned() } diff --git a/cli/src/deps.rs b/cli/src/deps.rs index e0b3d169..94078214 100644 --- a/cli/src/deps.rs +++ b/cli/src/deps.rs @@ -1,31 +1,15 @@ use { super::*, - anyhow::{ - Context, - Result, - }, + anyhow::{Context, Result}, bzip2::read::BzDecoder, clap::crate_version, - indicatif::{ - ProgressBar, - ProgressStyle, - }, - reqwest::{ - blocking::get, - Url, - }, + indicatif::{ProgressBar, ProgressStyle}, + reqwest::{blocking::get, Url}, std::{ ffi::OsStr, - fs::{ - self, - copy, - File, - }, - io::{self,}, - path::{ - Path, - PathBuf, - }, + fs::{self, copy, File}, + io::{self}, + path::{Path, PathBuf}, }, tar::Archive, }; @@ -44,7 +28,7 @@ pub fn download_deps( let active_runtime = &runtime_dir.join(&clockwork_tag); download_and_extract( - &active_runtime, + active_runtime, &solana_archive.unwrap_or(CliConfig::solana_release_url(&solana_tag)), &active_runtime.join(CliConfig::solana_release_archive()), config::SOLANA_DEPS, @@ -52,7 +36,7 @@ pub fn download_deps( )?; if !dev { download_and_extract( - &active_runtime, + active_runtime, &clockwork_archive.unwrap_or(CliConfig::clockwork_release_url(&clockwork_tag)), &active_runtime.join(CliConfig::clockwork_release_archive()), config::CLOCKWORK_DEPS, @@ -83,8 +67,8 @@ pub fn download_and_extract( // create runtime dir if necessary fs::create_dir_all(runtime_dir) .context(format!("Unable to create dirs for {:#?}", runtime_dir))?; - download_file(src_url, &dest_path)?; - extract_archive(&dest_path, runtime_dir, files_to_extract)?; + download_file(src_url, dest_path)?; + extract_archive(dest_path, runtime_dir, files_to_extract)?; println!(); Ok(()) } @@ -108,7 +92,7 @@ fn download_file(url: &str, dest: &Path) -> Result<()> { let mut source = pb.wrap_read(response); let mut dest = - File::create(&dest).context(format!("Failed to create file {:#?}", dest))?; + File::create(dest).context(format!("Failed to create file {dest:#?}"))?; io::copy(&mut source, &mut dest)?; pb.finish_with_message("Download complete."); } @@ -130,7 +114,7 @@ fn extract_archive( files_to_extract: &[&str], ) -> Result<()> { let file = - File::open(&archive_path).context(format!("Failed to open file {:#?}", archive_path))?; + File::open(archive_path).context(format!("Failed to open file {:#?}", archive_path))?; let target_file_names: Vec<&OsStr> = files_to_extract.iter().map(OsStr::new).collect(); let mut archive = Archive::new(BzDecoder::new(file)); @@ -174,7 +158,7 @@ pub trait ToTagVersion { impl ToTagVersion for String { fn to_tag_version(&self) -> String { - if !self.starts_with("v") { + if !self.starts_with('v') { format!("v{}", self) } else { self.to_owned() diff --git a/cli/src/errors.rs b/cli/src/errors.rs index 87a2a426..dd599714 100644 --- a/cli/src/errors.rs +++ b/cli/src/errors.rs @@ -22,7 +22,9 @@ pub enum CliError { InvalidAddress, #[error("Program file does not exist")] InvalidProgramFile, - #[error("No default signer found in {0}, \ - run `solana-keygen new`, or `solana config set —keypair `")] + #[error( + "No default signer found in {0}, \ + run `solana-keygen new`, or `solana config set —keypair `" + )] KeypairNotFound(String), } diff --git a/cli/src/main.rs b/cli/src/main.rs index 6b109c7e..e9736f87 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -8,10 +8,7 @@ mod print; mod processor; use { - crate::{ - config::CliConfig, - print::print_style, - }, + crate::{config::CliConfig, print::print_style}, cli::app, errors::CliError, processor::process, diff --git a/cli/src/parser.rs b/cli/src/parser.rs index 65344d65..79c83d41 100644 --- a/cli/src/parser.rs +++ b/cli/src/parser.rs @@ -308,18 +308,18 @@ fn parse_instruction_file( } fn parse_keypair_file(arg: &str, matches: &ArgMatches) -> Result { - Ok(read_keypair_file(parse_string(arg, matches)?) - .map_err(|_err| CliError::BadParameter(arg.into()))?) + read_keypair_file(parse_string(arg, matches)?) + .map_err(|_err| CliError::BadParameter(arg.into())) } fn parse_http_method(arg: &str, matches: &ArgMatches) -> Result { - Ok(HttpMethod::from_str(parse_string(arg, matches)?.as_str()) - .map_err(|_err| CliError::BadParameter(arg.into()))?) + HttpMethod::from_str(parse_string(arg, matches)?.as_str()) + .map_err(|_err| CliError::BadParameter(arg.into())) } fn parse_pubkey(arg: &str, matches: &ArgMatches) -> Result { - Ok(Pubkey::from_str(parse_string(arg, matches)?.as_str()) - .map_err(|_err| CliError::BadParameter(arg.into()))?) + Pubkey::from_str(parse_string(arg, matches)?.as_str()) + .map_err(|_err| CliError::BadParameter(arg.into())) } fn parse_string(arg: &str, matches: &ArgMatches) -> Result { @@ -330,24 +330,21 @@ fn parse_string(arg: &str, matches: &ArgMatches) -> Result { } pub fn _parse_i64(arg: &str, matches: &ArgMatches) -> Result { - Ok(parse_string(arg, matches)? + parse_string(arg, matches)? .parse::() .map_err(|_err| CliError::BadParameter(arg.into())) - .unwrap()) } pub fn parse_u64(arg: &str, matches: &ArgMatches) -> Result { - Ok(parse_string(arg, matches)? + parse_string(arg, matches)? .parse::() .map_err(|_err| CliError::BadParameter(arg.into())) - .unwrap()) } pub fn parse_usize(arg: &str, matches: &ArgMatches) -> Result { - Ok(parse_string(arg, matches)? + parse_string(arg, matches)? .parse::() .map_err(|_err| CliError::BadParameter(arg.into())) - .unwrap()) } // Json parsers diff --git a/cli/src/print.rs b/cli/src/print.rs index 709ce871..6443b265 100644 --- a/cli/src/print.rs +++ b/cli/src/print.rs @@ -1,17 +1,8 @@ #![allow(dead_code)] use { - std::{ - fmt::Display, - io::Write, - }, - termcolor::{ - Color, - ColorChoice, - ColorSpec, - StandardStream, - WriteColor, - }, + std::{fmt::Display, io::Write}, + termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}, }; #[macro_export] diff --git a/cli/src/processor/config.rs b/cli/src/processor/config.rs index 6e983ef7..7d6b90cd 100644 --- a/cli/src/processor/config.rs +++ b/cli/src/processor/config.rs @@ -1,8 +1,6 @@ use anchor_lang::{ - solana_program::{ - instruction::Instruction, pubkey::Pubkey, - }, - InstructionData, ToAccountMetas + solana_program::{instruction::Instruction, pubkey::Pubkey}, + InstructionData, ToAccountMetas, }; use clockwork_network_program::state::{Config, ConfigSettings}; @@ -41,7 +39,8 @@ pub fn set( accounts: clockwork_network_program::accounts::ConfigUpdate { admin: client.payer_pubkey(), config: Config::pubkey(), - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::ConfigUpdate { settings }.data(), }; client.send_and_confirm(&[ix], &[client.payer()]).unwrap(); diff --git a/cli/src/processor/crontab.rs b/cli/src/processor/crontab.rs index c9e2888b..54d18d40 100644 --- a/cli/src/processor/crontab.rs +++ b/cli/src/processor/crontab.rs @@ -9,7 +9,7 @@ pub fn get(client: &Client, schedule: String) -> Result<(), CliError> { let schedule = Schedule::from_str(schedule.as_str()).unwrap(); let mut i = 0; - for t in schedule.after(&DateTime::::from_utc( + for t in schedule.after(&DateTime::::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(clock.unix_timestamp, 0).unwrap(), Utc, )) { diff --git a/cli/src/processor/delegation.rs b/cli/src/processor/delegation.rs index a2c80359..1d1e33d6 100644 --- a/cli/src/processor/delegation.rs +++ b/cli/src/processor/delegation.rs @@ -1,8 +1,6 @@ use anchor_lang::{ - solana_program::{ - instruction::Instruction, system_program, sysvar - }, - InstructionData, AccountDeserialize, ToAccountMetas + solana_program::{instruction::Instruction, system_program}, + AccountDeserialize, InstructionData, ToAccountMetas, }; use clockwork_network_program::state::{Config, Delegation, Worker}; use spl_associated_token_account::get_associated_token_address; @@ -37,11 +35,11 @@ pub fn create(client: &Client, worker_id: u64) -> Result<(), CliError> { delegation: delegation_pubkey, delegation_tokens: get_associated_token_address(&delegation_pubkey, &config.mint), mint: config.mint, - rent: sysvar::rent::ID, system_program: system_program::ID, token_program: anchor_spl::token::ID, worker: worker_pubkey, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::DelegationCreate {}.data(), }; client.send_and_confirm(&[ix], &[client.payer()]).unwrap(); @@ -76,8 +74,9 @@ pub fn deposit( config: Config::pubkey(), delegation: delegation_pubkey, delegation_tokens: get_associated_token_address(&delegation_pubkey, &config.mint), - token_program: anchor_spl::token::ID, - }.to_account_metas(Some(false)), + token_program: anchor_spl::token::ID, + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::DelegationDeposit { amount }.data(), }; client.send_and_confirm(&[ix], &[client.payer()]).unwrap(); @@ -112,8 +111,9 @@ pub fn withdraw( config: Config::pubkey(), delegation: delegation_pubkey, delegation_tokens: get_associated_token_address(&delegation_pubkey, &config.mint), - token_program: anchor_spl::token::ID, - }.to_account_metas(Some(false)), + token_program: anchor_spl::token::ID, + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::DelegationWithdraw { amount }.data(), }; client.send_and_confirm(&[ix], &[client.payer()]).unwrap(); diff --git a/cli/src/processor/explorer.rs b/cli/src/processor/explorer.rs index 213320c9..1e7085bd 100644 --- a/cli/src/processor/explorer.rs +++ b/cli/src/processor/explorer.rs @@ -1,15 +1,13 @@ -use { - crate::errors::CliError, - crate::config::CliConfig, - clockwork_utils::explorer::Explorer, -}; +use {crate::config::CliConfig, crate::errors::CliError, clockwork_utils::explorer::Explorer}; -pub fn thread_url(thread: T, config: CliConfig) -> Result<(), - CliError> { - println!("thread: {}", explorer(config).thread_url(thread, clockwork_thread_program::ID)); +pub fn thread_url(thread: T, config: CliConfig) -> Result<(), CliError> { + println!( + "thread: {}", + explorer(config).thread_url(thread, clockwork_thread_program::ID) + ); Ok(()) } fn explorer(config: CliConfig) -> Explorer { - Explorer::from(config.json_rpc_url) + Explorer::from(config.json_rpc_url) } diff --git a/cli/src/processor/initialize.rs b/cli/src/processor/initialize.rs index db30c0ec..d6b8566d 100644 --- a/cli/src/processor/initialize.rs +++ b/cli/src/processor/initialize.rs @@ -1,9 +1,5 @@ use anchor_lang::{ - solana_program::{ - instruction::Instruction, - pubkey::Pubkey, - system_program, - }, + solana_program::{instruction::Instruction, pubkey::Pubkey, system_program}, InstructionData, ToAccountMetas, }; use clockwork_network_program::state::{Config, Pool, Registry, Snapshot}; @@ -22,7 +18,8 @@ pub fn initialize(client: &Client, mint: Pubkey) -> Result<(), CliError> { registry: Registry::pubkey(), snapshot: Snapshot::pubkey(0), system_program: system_program::ID, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::Initialize {}.data(), }; let ix_b = Instruction { @@ -34,7 +31,8 @@ pub fn initialize(client: &Client, mint: Pubkey) -> Result<(), CliError> { pool: Pool::pubkey(0), registry: Registry::pubkey(), system_program: system_program::ID, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::PoolCreate {}.data(), }; diff --git a/cli/src/processor/localnet.rs b/cli/src/processor/localnet.rs index 767c911e..3b5f404a 100644 --- a/cli/src/processor/localnet.rs +++ b/cli/src/processor/localnet.rs @@ -1,22 +1,14 @@ #[allow(deprecated)] use { crate::{ - client::Client, - config::CliConfig, - deps, - errors::CliError, - parser::ProgramInfo, - print::print_style, - print_status - }, - anyhow::{ - Context, - Result, + client::Client, config::CliConfig, deps, errors::CliError, parser::ProgramInfo, + print::print_style, print_status, }, anchor_lang::{ solana_program::{instruction::Instruction, system_program}, - InstructionData, ToAccountMetas + InstructionData, ToAccountMetas, }, + anyhow::{Context, Result}, clap::crate_version, clockwork_network_program::state::{Config, ConfigSettings, Registry}, clockwork_thread_program::state::{Thread, Trigger}, @@ -24,29 +16,16 @@ use { native_token::LAMPORTS_PER_SOL, program_pack::Pack, pubkey::Pubkey, - signature::{ - read_keypair_file, - Keypair, - Signer, - }, + signature::{read_keypair_file, Keypair, Signer}, system_instruction, }, - spl_associated_token_account::{ - create_associated_token_account, - get_associated_token_address, - }, + spl_associated_token_account::{create_associated_token_account, get_associated_token_address}, spl_token::{ - instruction::{ - initialize_mint, - mint_to, - }, + instruction::{initialize_mint, mint_to}, state::Mint, }, std::fs, - std::process::{ - Child, - Command, - }, + std::process::{Child, Command}, }; pub fn start( @@ -178,7 +157,8 @@ fn create_threads(client: &Client, mint_pubkey: Pubkey) -> Result<()> { config: Config::pubkey(), registry: Registry::pubkey(), thread: epoch_thread_pubkey, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::DistributeFeesJob {}.data(), }; let ix_a2 = Instruction { @@ -187,7 +167,8 @@ fn create_threads(client: &Client, mint_pubkey: Pubkey) -> Result<()> { config: Config::pubkey(), registry: Registry::pubkey(), thread: epoch_thread_pubkey, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::ProcessUnstakesJob {}.data(), }; let ix_a3 = Instruction { @@ -196,7 +177,8 @@ fn create_threads(client: &Client, mint_pubkey: Pubkey) -> Result<()> { config: Config::pubkey(), registry: Registry::pubkey(), thread: epoch_thread_pubkey, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::StakeDelegationsJob {}.data(), }; let ix_a4 = Instruction { @@ -205,7 +187,8 @@ fn create_threads(client: &Client, mint_pubkey: Pubkey) -> Result<()> { config: Config::pubkey(), registry: Registry::pubkey(), thread: epoch_thread_pubkey, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::TakeSnapshotJob {}.data(), }; let ix_a5 = Instruction { @@ -214,7 +197,8 @@ fn create_threads(client: &Client, mint_pubkey: Pubkey) -> Result<()> { config: Config::pubkey(), registry: Registry::pubkey(), thread: epoch_thread_pubkey, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::IncrementEpoch {}.data(), }; let ix_a6 = Instruction { @@ -223,7 +207,8 @@ fn create_threads(client: &Client, mint_pubkey: Pubkey) -> Result<()> { config: Config::pubkey(), registry: Registry::pubkey(), thread: epoch_thread_pubkey, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::DeleteSnapshotJob {}.data(), }; let ix_a = Instruction { @@ -233,7 +218,8 @@ fn create_threads(client: &Client, mint_pubkey: Pubkey) -> Result<()> { payer: client.payer_pubkey(), system_program: system_program::ID, thread: epoch_thread_pubkey, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_thread_program::instruction::ThreadCreate { amount: LAMPORTS_PER_SOL, id: epoch_thread_id.into(), @@ -261,8 +247,9 @@ fn create_threads(client: &Client, mint_pubkey: Pubkey) -> Result<()> { accounts: clockwork_network_program::accounts::RegistryNonceHash { config: Config::pubkey(), registry: Registry::pubkey(), - thread: hasher_thread_pubkey, - }.to_account_metas(Some(false)), + thread: hasher_thread_pubkey, + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::RegistryNonceHash {}.data(), }; let ix_b = Instruction { @@ -272,13 +259,12 @@ fn create_threads(client: &Client, mint_pubkey: Pubkey) -> Result<()> { payer: client.payer_pubkey(), system_program: system_program::ID, thread: hasher_thread_pubkey, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_thread_program::instruction::ThreadCreate { amount: LAMPORTS_PER_SOL, id: hasher_thread_id.into(), - instructions: vec![ - registry_hash_ix.into(), - ], + instructions: vec![registry_hash_ix.into()], trigger: Trigger::Cron { schedule: "*/15 * * * * * *".into(), skippable: true, @@ -298,19 +284,20 @@ fn create_threads(client: &Client, mint_pubkey: Pubkey) -> Result<()> { program_id: clockwork_network_program::ID, accounts: clockwork_network_program::accounts::ConfigUpdate { admin: client.payer_pubkey(), - config: Config::pubkey() - }.to_account_metas(Some(false)), + config: Config::pubkey(), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::ConfigUpdate { settings }.data(), }; client - .send_and_confirm(&vec![ix_a], &[client.payer()]) + .send_and_confirm(&[ix_a], &[client.payer()]) .context(format!( "Failed to create thread: {} or update config", epoch_thread_id, ))?; client - .send_and_confirm(&vec![ix_b, ix_c], &[client.payer()]) + .send_and_confirm(&[ix_b, ix_c], &[client.payer()]) .context(format!("Failed to create thread: {}", hasher_thread_id))?; Ok(()) @@ -326,7 +313,7 @@ fn create_geyser_plugin_config(config: &CliConfig) -> Result<()> { let content = serde_json::to_string_pretty(&geyser_config) .context("Unable to serialize PluginConfig to json")?; let path = &config.geyser_config(); - fs::write(&path, content).context(format!("Unable to serialize PluginConfig to {}", path))?; + fs::write(path, content).context(format!("Unable to serialize PluginConfig to {}", path))?; Ok(()) } @@ -351,7 +338,7 @@ fn start_test_validator( let mut process = cmd .spawn() .context(format!("solana-test-validator command: {:#?}", cmd))?; -print_status!("Running", "Clockwork Validator {}\n", crate_version!()); + print_status!("Running", "Clockwork Validator {}\n", crate_version!()); // Wait for the validator to become healthy let ms_wait = 10_000; @@ -413,12 +400,12 @@ impl TestValidatorHelpers for Command { let filename = format!("clockwork_{}_program.so", program_name); self.arg("--bpf-program") .arg(program_id.to_string()) - .arg(config.active_runtime(filename.as_str()).to_owned()) + .arg(config.active_runtime(filename.as_str())) } fn geyser_plugin_config(&mut self, config: &CliConfig) -> &mut Command { self.arg("--geyser-plugin-config") - .arg(config.geyser_config().to_owned()) + .arg(config.geyser_config()) } fn network_url(&mut self, url: Option) -> &mut Command { diff --git a/cli/src/processor/mod.rs b/cli/src/processor/mod.rs index 5c42ce57..68f01ac2 100644 --- a/cli/src/processor/mod.rs +++ b/cli/src/processor/mod.rs @@ -16,10 +16,7 @@ use clap::ArgMatches; use solana_sdk::signature::read_keypair_file; use crate::{ - client::Client, - cli::CliCommand, - config::CliConfig, - errors::CliError, + cli::CliCommand, client::Client, config::CliConfig, errors::CliError, processor::thread::parse_pubkey_from_id_or_address, }; @@ -27,13 +24,10 @@ pub fn process(matches: &ArgMatches) -> Result<(), CliError> { // Parse command and config let command = CliCommand::try_from(matches)?; - match command { - // Set solana config if using localnet command - CliCommand::Localnet { .. } => { - // TODO Verify the Solana CLI version is compatable with this build. - set_solana_config().map_err(|err| CliError::FailedLocalnet(err.to_string()))? - } - _ => {} + // Set solana config if using localnet command + if let CliCommand::Localnet { .. } = command { + // TODO Verify the Solana CLI version is compatable with this build. + set_solana_config().map_err(|err| CliError::FailedLocalnet(err.to_string()))? } let mut config = CliConfig::load(); @@ -136,7 +130,7 @@ pub fn process(matches: &ArgMatches) -> Result<(), CliError> { fn set_solana_config() -> Result<()> { let mut process = std::process::Command::new("solana") - .args(&["config", "set", "--url", "l"]) + .args(["config", "set", "--url", "l"]) .spawn() .expect("Failed to set solana config"); process.wait()?; diff --git a/cli/src/processor/pool.rs b/cli/src/processor/pool.rs index 8da7c4a0..466fc189 100644 --- a/cli/src/processor/pool.rs +++ b/cli/src/processor/pool.rs @@ -1,10 +1,8 @@ use anchor_lang::{ - solana_program::{ - instruction::Instruction, system_program, - }, - InstructionData, ToAccountMetas + solana_program::{instruction::Instruction, system_program}, + InstructionData, ToAccountMetas, }; -use clockwork_network_program::state::{Config, Pool, Registry, PoolSettings}; +use clockwork_network_program::state::{Config, Pool, PoolSettings, Registry}; use crate::{client::Client, errors::CliError}; @@ -45,7 +43,8 @@ pub fn update(client: &Client, id: u64, size: usize) -> Result<(), CliError> { payer: client.payer_pubkey(), pool: pool_pubkey, system_program: system_program::ID, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::PoolUpdate { settings }.data(), }; client.send_and_confirm(&[ix], &[client.payer()]).unwrap(); diff --git a/cli/src/processor/registry.rs b/cli/src/processor/registry.rs index bf6a99e4..124ef75f 100644 --- a/cli/src/processor/registry.rs +++ b/cli/src/processor/registry.rs @@ -1,7 +1,4 @@ -use anchor_lang::{ - solana_program::instruction::Instruction, - InstructionData, ToAccountMetas -}; +use anchor_lang::{solana_program::instruction::Instruction, InstructionData, ToAccountMetas}; use clockwork_network_program::state::{Config, Registry, Snapshot}; use crate::{client::Client, errors::CliError}; @@ -28,8 +25,9 @@ pub fn unlock(client: &Client) -> Result<(), CliError> { accounts: clockwork_network_program::accounts::RegistryUnlock { admin: client.payer_pubkey(), config: Config::pubkey(), - registry: Registry::pubkey() - }.to_account_metas(Some(false)), + registry: Registry::pubkey(), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::RegistryUnlock {}.data(), }; client.send_and_confirm(&[ix], &[client.payer()]).unwrap(); diff --git a/cli/src/processor/thread.rs b/cli/src/processor/thread.rs index d7aca69e..55b14ad5 100644 --- a/cli/src/processor/thread.rs +++ b/cli/src/processor/thread.rs @@ -1,8 +1,10 @@ use anchor_lang::{ solana_program::{instruction::Instruction, system_program}, - InstructionData, AccountDeserialize, ToAccountMetas + AccountDeserialize, InstructionData, ToAccountMetas, +}; +use clockwork_thread_program::state::{ + SerializableInstruction, Thread, ThreadSettings, Trigger, VersionedThread, }; -use clockwork_thread_program::state::{SerializableInstruction, Thread, ThreadSettings, Trigger, VersionedThread}; use clockwork_utils::CrateInfo; use solana_sdk::pubkey::Pubkey; @@ -13,7 +15,8 @@ pub fn crate_info(client: &Client) -> Result<(), CliError> { program_id: clockwork_thread_program::ID, accounts: clockwork_thread_program::accounts::GetCrateInfo { system_program: system_program::ID, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_thread_program::instruction::GetCrateInfo {}.data(), }; let crate_info: CrateInfo = client.get_return_data(ix).unwrap(); @@ -34,8 +37,9 @@ pub fn create( authority: client.payer_pubkey(), payer: client.payer_pubkey(), system_program: system_program::ID, - thread: thread_pubkey - }.to_account_metas(Some(false)), + thread: thread_pubkey, + } + .to_account_metas(Some(false)), data: clockwork_thread_program::instruction::ThreadCreate { amount: 0, id: id.into_bytes(), @@ -57,7 +61,8 @@ pub fn delete(client: &Client, id: String) -> Result<(), CliError> { authority: client.payer_pubkey(), close_to: client.payer_pubkey(), thread: thread_pubkey, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_thread_program::instruction::ThreadDelete {}.data(), }; client.send_and_confirm(&[ix], &[client.payer()]).unwrap(); @@ -78,7 +83,8 @@ pub fn pause(client: &Client, id: String) -> Result<(), CliError> { accounts: clockwork_thread_program::accounts::ThreadPause { authority: client.payer_pubkey(), thread: thread_pubkey, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_thread_program::instruction::ThreadPause {}.data(), }; client.send_and_confirm(&[ix], &[client.payer()]).unwrap(); @@ -92,8 +98,9 @@ pub fn resume(client: &Client, id: String) -> Result<(), CliError> { program_id: clockwork_thread_program::ID, accounts: clockwork_thread_program::accounts::ThreadResume { authority: client.payer_pubkey(), - thread: thread_pubkey - }.to_account_metas(Some(false)), + thread: thread_pubkey, + } + .to_account_metas(Some(false)), data: clockwork_thread_program::instruction::ThreadResume {}.data(), }; client.send_and_confirm(&[ix], &[client.payer()]).unwrap(); @@ -107,8 +114,9 @@ pub fn reset(client: &Client, id: String) -> Result<(), CliError> { program_id: clockwork_thread_program::ID, accounts: clockwork_thread_program::accounts::ThreadReset { authority: client.payer_pubkey(), - thread: thread_pubkey - }.to_account_metas(Some(false)), + thread: thread_pubkey, + } + .to_account_metas(Some(false)), data: clockwork_thread_program::instruction::ThreadReset {}.data(), }; client.send_and_confirm(&[ix], &[client.payer()]).unwrap(); @@ -123,14 +131,10 @@ pub fn update( schedule: Option, ) -> Result<(), CliError> { let thread_pubkey = Thread::pubkey(client.payer_pubkey(), id.into_bytes()); - let trigger = if let Some(schedule) = schedule { - Some(Trigger::Cron { - schedule, - skippable: true, - }) - } else { - None - }; + let trigger = schedule.map(|schedule| Trigger::Cron { + schedule, + skippable: true, + }); let settings = ThreadSettings { fee: None, instructions: None, @@ -143,8 +147,9 @@ pub fn update( accounts: clockwork_thread_program::accounts::ThreadUpdate { authority: client.payer_pubkey(), system_program: system_program::ID, - thread: thread_pubkey - }.to_account_metas(Some(false)), + thread: thread_pubkey, + } + .to_account_metas(Some(false)), data: clockwork_thread_program::instruction::ThreadUpdate { settings }.data(), }; client.send_and_confirm(&[ix], &[client.payer()]).unwrap(); diff --git a/cli/src/processor/worker.rs b/cli/src/processor/worker.rs index 3b2db1e9..0f4f85bf 100644 --- a/cli/src/processor/worker.rs +++ b/cli/src/processor/worker.rs @@ -1,9 +1,6 @@ use anchor_lang::{ - solana_program::{ - instruction::Instruction, - system_program, sysvar, - }, - AccountDeserialize, InstructionData, ToAccountMetas + solana_program::{instruction::Instruction, system_program}, + AccountDeserialize, InstructionData, ToAccountMetas, }; use anchor_spl::{associated_token, associated_token::get_associated_token_address, token}; use clockwork_network_program::state::{ @@ -101,13 +98,13 @@ pub fn create(client: &Client, signatory: Keypair, silent: bool) -> Result<(), C penalty: Penalty::pubkey(worker_pubkey), mint: config.mint, registry: Registry::pubkey(), - rent: sysvar::rent::ID, signatory: signatory.pubkey(), system_program: system_program::ID, token_program: token::ID, worker: worker_pubkey, worker_tokens: get_associated_token_address(&worker_pubkey, &config.mint), - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::WorkerCreate {}.data(), }; client @@ -137,7 +134,8 @@ pub fn update(client: &Client, id: u64, signatory: Option) -> Result<() authority: client.payer_pubkey(), system_program: system_program::ID, worker: worker_pubkey, - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::WorkerUpdate { settings }.data(), }; client.send_and_confirm(&[ix], &[client.payer()]).unwrap(); diff --git a/cron/Cargo.toml b/cron/Cargo.toml index 39b56329..6f2eabe5 100644 --- a/cron/Cargo.toml +++ b/cron/Cargo.toml @@ -16,5 +16,3 @@ name = "clockwork_cron" [dependencies] chrono = { version = "0.4.19", default-features = false, features = ["alloc"] } nom = "~7" -once_cell = "1.5.2" - diff --git a/cron/src/parsing.rs b/cron/src/parsing.rs index d2ea84fe..c5db4afb 100644 --- a/cron/src/parsing.rs +++ b/cron/src/parsing.rs @@ -10,10 +10,10 @@ use std::convert::TryFrom; use std::str::{self, FromStr}; use crate::error::{Error, ErrorKind}; -use crate::schedule::{ScheduleFields, Schedule}; +use crate::ordinal::*; +use crate::schedule::{Schedule, ScheduleFields}; use crate::specifier::*; use crate::time_unit::*; -use crate::ordinal::*; impl FromStr for Schedule { type Err = Error; @@ -52,10 +52,12 @@ where T: TimeUnitField, { fn from_field(field: Field) -> Result { - if field.specifiers.len() == 1 && - field.specifiers.get(0).unwrap() == &RootSpecifier::from(Specifier::All) - { return Ok(T::all()); } - let mut ordinals = OrdinalSet::new(); + if field.specifiers.len() == 1 + && field.specifiers.get(0).unwrap() == &RootSpecifier::from(Specifier::All) + { + return Ok(T::all()); + } + let mut ordinals = OrdinalSet::new(); for specifier in field.specifiers { let specifier_ordinals: OrdinalSet = T::ordinals_from_root_specifier(&specifier)?; for ordinal in specifier_ordinals { @@ -255,7 +257,15 @@ fn longhand(i: &str) -> IResult<&str, ScheduleFields> { let months = map_res(field, Months::from_field); let days_of_week = map_res(field_with_any, DaysOfWeek::from_field); let years = opt(map_res(field, Years::from_field)); - let fields = tuple((seconds, minutes, hours, days_of_month, months, days_of_week, years)); + let fields = tuple(( + seconds, + minutes, + hours, + days_of_month, + months, + days_of_week, + years, + )); map( terminated(fields, eof), diff --git a/cron/src/queries.rs b/cron/src/queries.rs index 7ffc13d5..0249c380 100644 --- a/cron/src/queries.rs +++ b/cron/src/queries.rs @@ -198,4 +198,4 @@ where pub fn reset_second(&mut self) { self.first_second = false; } -} \ No newline at end of file +} diff --git a/cron/src/schedule.rs b/cron/src/schedule.rs index 846d878c..6c2189a6 100644 --- a/cron/src/schedule.rs +++ b/cron/src/schedule.rs @@ -83,8 +83,8 @@ impl Schedule { let second_range = (Included(second_start), Included(Seconds::inclusive_max())); - for second in - self.fields.seconds.ordinals().range(second_range).cloned() + if let Some(second) = + self.fields.seconds.ordinals().range(second_range).next() { let timezone = after.timezone(); let candidate = timezone @@ -94,7 +94,7 @@ impl Schedule { day_of_month, hour, minute, - second, + *second, ) .unwrap(); if !self @@ -210,13 +210,15 @@ impl Schedule { let second_range = (Included(Seconds::inclusive_min()), Included(second_start)); - for second in self + //TODO Rework it + if let Some(second) = self .fields .seconds .ordinals() .range(second_range) .rev() .cloned() + .next() { let timezone = before.timezone(); let candidate = timezone diff --git a/cron/src/specifier.rs b/cron/src/specifier.rs index 4aca7914..e21fbff5 100644 --- a/cron/src/specifier.rs +++ b/cron/src/specifier.rs @@ -26,4 +26,4 @@ impl From for RootSpecifier { fn from(specifier: Specifier) -> Self { Self::Specifier(specifier) } -} \ No newline at end of file +} diff --git a/cron/src/time_unit/mod.rs b/cron/src/time_unit/mod.rs index 460a2298..444121c7 100644 --- a/cron/src/time_unit/mod.rs +++ b/cron/src/time_unit/mod.rs @@ -163,7 +163,7 @@ where //println!("ordinals_from_specifier for {} => {:?}", Self::name(), specifier); match *specifier { All => Ok(Self::supported_ordinals().clone()), - Point(ordinal) => Ok((&[ordinal]).iter().cloned().collect()), + Point(ordinal) => Ok(OrdinalSet::from([ordinal])), Range(start, end) => { match (Self::validate_ordinal(start), Self::validate_ordinal(end)) { (Ok(start), Ok(end)) if start <= end => Ok((start..end + 1).collect()), @@ -207,14 +207,13 @@ where specifier => Self::ordinals_from_specifier(specifier)?, }; if *step == 0 { - return Err(ErrorKind::Expression(format!("step cannot be 0")).into()); + return Err(ErrorKind::Expression("step cannot be 0".to_string()).into()); } base_set.into_iter().step_by(*step as usize).collect() } - RootSpecifier::NamedPoint(ref name) => (&[Self::ordinal_from_name(name)?]) - .iter() - .cloned() - .collect::(), + RootSpecifier::NamedPoint(ref name) => { + OrdinalSet::from([Self::ordinal_from_name(name)?]) + } }; Ok(ordinals) } diff --git a/cron/tests/lib.rs b/cron/tests/lib.rs index c37f3ce6..4e1f9120 100644 --- a/cron/tests/lib.rs +++ b/cron/tests/lib.rs @@ -38,46 +38,58 @@ mod tests { fn test_yearly() { let expression = "@yearly"; let schedule = Schedule::from_str(expression).expect("Failed to parse @yearly."); - let starting_date = Utc.ymd(2017, 6, 15).and_hms(14, 29, 36); + let starting_date = Utc.with_ymd_and_hms(2017, 6, 15, 14, 29, 36).unwrap(); let mut events = schedule.after(&starting_date); - assert_eq!(Utc.ymd(2018, 1, 1).and_hms(0, 0, 0), events.next().unwrap()); - assert_eq!(Utc.ymd(2019, 1, 1).and_hms(0, 0, 0), events.next().unwrap()); - assert_eq!(Utc.ymd(2020, 1, 1).and_hms(0, 0, 0), events.next().unwrap()); + assert_eq!( + Utc.with_ymd_and_hms(2018, 1, 1, 0, 0, 0).unwrap(), + events.next().unwrap() + ); + assert_eq!( + Utc.with_ymd_and_hms(2019, 1, 1, 0, 0, 0).unwrap(), + events.next().unwrap() + ); + assert_eq!( + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(), + events.next().unwrap() + ); } #[test] fn test_monthly() { let expression = "@monthly"; let schedule = Schedule::from_str(expression).expect("Failed to parse @monthly."); - let starting_date = Utc.ymd(2017, 10, 15).and_hms(14, 29, 36); + let starting_date = Utc.with_ymd_and_hms(2017, 10, 15, 14, 29, 36).unwrap(); let mut events = schedule.after(&starting_date); assert_eq!( - Utc.ymd(2017, 11, 1).and_hms(0, 0, 0), + Utc.with_ymd_and_hms(2017, 11, 1, 0, 0, 0).unwrap(), events.next().unwrap() ); assert_eq!( - Utc.ymd(2017, 12, 1).and_hms(0, 0, 0), + Utc.with_ymd_and_hms(2017, 12, 1, 0, 0, 0).unwrap(), + events.next().unwrap() + ); + assert_eq!( + Utc.with_ymd_and_hms(2018, 1, 1, 0, 0, 0).unwrap(), events.next().unwrap() ); - assert_eq!(Utc.ymd(2018, 1, 1).and_hms(0, 0, 0), events.next().unwrap()); } #[test] fn test_day() { let expression = "0 0 0 * * FRI"; let schedule = Schedule::from_str(expression).expect("Failed to parse @yearly."); - let starting_date = Utc.ymd(2023, 3, 1).and_hms(14, 29, 36); + let starting_date = Utc.with_ymd_and_hms(2023, 3, 1, 14, 29, 36).unwrap(); let mut events = schedule.after(&starting_date); assert_eq!( - Utc.ymd(2023, 03, 03).and_hms(0, 0, 0), + Utc.with_ymd_and_hms(2023, 03, 03, 0, 0, 0).unwrap(), events.next().unwrap() ); assert_eq!( - Utc.ymd(2023, 03, 10).and_hms(0, 0, 0), + Utc.with_ymd_and_hms(2023, 03, 10, 0, 0, 0).unwrap(), events.next().unwrap() ); assert_eq!( - Utc.ymd(2023, 03, 17).and_hms(0, 0, 0), + Utc.with_ymd_and_hms(2023, 03, 17, 0, 0, 0).unwrap(), events.next().unwrap() ); } @@ -86,49 +98,58 @@ mod tests { fn test_weekly() { let expression = "@weekly"; let schedule = Schedule::from_str(expression).expect("Failed to parse @weekly."); - let starting_date = Utc.ymd(2016, 12, 23).and_hms(14, 29, 36); + let starting_date = Utc.with_ymd_and_hms(2016, 12, 23, 14, 29, 36).unwrap(); let mut events = schedule.after(&starting_date); assert_eq!( - Utc.ymd(2016, 12, 25).and_hms(0, 0, 0), + Utc.with_ymd_and_hms(2016, 12, 25, 0, 0, 0).unwrap(), + events.next().unwrap() + ); + assert_eq!( + Utc.with_ymd_and_hms(2017, 1, 1, 0, 0, 0).unwrap(), + events.next().unwrap() + ); + assert_eq!( + Utc.with_ymd_and_hms(2017, 1, 8, 0, 0, 0).unwrap(), events.next().unwrap() ); - assert_eq!(Utc.ymd(2017, 1, 1).and_hms(0, 0, 0), events.next().unwrap()); - assert_eq!(Utc.ymd(2017, 1, 8).and_hms(0, 0, 0), events.next().unwrap()); } #[test] fn test_daily() { let expression = "@daily"; let schedule = Schedule::from_str(expression).expect("Failed to parse @daily."); - let starting_date = Utc.ymd(2016, 12, 29).and_hms(14, 29, 36); + let starting_date = Utc.with_ymd_and_hms(2016, 12, 29, 14, 29, 36).unwrap(); let mut events = schedule.after(&starting_date); assert_eq!( - Utc.ymd(2016, 12, 30).and_hms(0, 0, 0), + Utc.with_ymd_and_hms(2016, 12, 30, 0, 0, 0).unwrap(), + events.next().unwrap() + ); + assert_eq!( + Utc.with_ymd_and_hms(2016, 12, 31, 0, 0, 0).unwrap(), events.next().unwrap() ); assert_eq!( - Utc.ymd(2016, 12, 31).and_hms(0, 0, 0), + Utc.with_ymd_and_hms(2017, 1, 1, 0, 0, 0).unwrap(), events.next().unwrap() ); - assert_eq!(Utc.ymd(2017, 1, 1).and_hms(0, 0, 0), events.next().unwrap()); } #[test] fn test_hourly() { let expression = "@hourly"; let schedule = Schedule::from_str(expression).expect("Failed to parse @hourly."); - let starting_date = Utc.ymd(2017, 2, 25).and_hms(22, 29, 36); + let starting_date = Utc.with_ymd_and_hms(2017, 2, 25, 22, 29, 36).unwrap(); let mut events = schedule.after(&starting_date); assert_eq!( - Utc.ymd(2017, 2, 25).and_hms(23, 0, 0), + Utc.with_ymd_and_hms(2017, 2, 25, 23, 0, 0).unwrap(), events.next().unwrap() ); assert_eq!( - Utc.ymd(2017, 2, 26).and_hms(0, 0, 0), + Utc.with_ymd_and_hms(2017, 2, 26, 0, 0, 0).unwrap(), events.next().unwrap() ); assert_eq!( - Utc.ymd(2017, 2, 26).and_hms(1, 0, 0), + Utc.with_ymd_and_hms(2017, 2, 26, 1, 0, 0).unwrap(), events.next().unwrap() ); } @@ -137,39 +158,45 @@ mod tests { fn test_step_schedule() { let expression = "0/20 0/5 0 1 1 * *"; let schedule = Schedule::from_str(expression).expect("Failed to parse expression."); - let starting_date = Utc.ymd(2017, 6, 15).and_hms(14, 29, 36); + let starting_date = Utc.with_ymd_and_hms(2017, 6, 15, 14, 29, 36).unwrap(); let mut events = schedule.after(&starting_date); - assert_eq!(Utc.ymd(2018, 1, 1).and_hms(0, 0, 0), events.next().unwrap()); assert_eq!( - Utc.ymd(2018, 1, 1).and_hms(0, 0, 20), + Utc.with_ymd_and_hms(2018, 1, 1, 0, 0, 0).unwrap(), events.next().unwrap() ); assert_eq!( - Utc.ymd(2018, 1, 1).and_hms(0, 0, 40), + Utc.with_ymd_and_hms(2018, 1, 1, 0, 0, 20).unwrap(), + events.next().unwrap() + ); + assert_eq!( + Utc.with_ymd_and_hms(2018, 1, 1, 0, 0, 40).unwrap(), events.next().unwrap() ); - assert_eq!(Utc.ymd(2018, 1, 1).and_hms(0, 5, 0), events.next().unwrap()); assert_eq!( - Utc.ymd(2018, 1, 1).and_hms(0, 5, 20), + Utc.with_ymd_and_hms(2018, 1, 1, 0, 5, 0).unwrap(), + events.next().unwrap() + ); + assert_eq!( + Utc.with_ymd_and_hms(2018, 1, 1, 0, 5, 20).unwrap(), events.next().unwrap() ); assert_eq!( - Utc.ymd(2018, 1, 1).and_hms(0, 5, 40), + Utc.with_ymd_and_hms(2018, 1, 1, 0, 5, 40).unwrap(), events.next().unwrap() ); assert_eq!( - Utc.ymd(2018, 1, 1).and_hms(0, 10, 0), + Utc.with_ymd_and_hms(2018, 1, 1, 0, 10, 0).unwrap(), events.next().unwrap() ); assert_eq!( - Utc.ymd(2018, 1, 1).and_hms(0, 10, 20), + Utc.with_ymd_and_hms(2018, 1, 1, 0, 10, 20).unwrap(), events.next().unwrap() ); assert_eq!( - Utc.ymd(2018, 1, 1).and_hms(0, 10, 40), + Utc.with_ymd_and_hms(2018, 1, 1, 0, 10, 40).unwrap(), events.next().unwrap() ); } @@ -177,11 +204,17 @@ mod tests { #[test] fn test_first_ordinals_not_in_set_1() { let schedule = "0 0/10 * * * * *".parse::().unwrap(); - let start_time_1 = NaiveDate::from_ymd(2017, 10, 24).and_hms(0, 0, 59); + let start_time_1 = NaiveDate::from_ymd_opt(2017, 10, 24) + .unwrap() + .and_hms_opt(0, 0, 59) + .unwrap(); let start_time_1 = Utc.from_utc_datetime(&start_time_1); let next_time_1 = schedule.after(&start_time_1).next().unwrap(); - let start_time_2 = NaiveDate::from_ymd(2017, 10, 24).and_hms(0, 1, 0); + let start_time_2 = NaiveDate::from_ymd_opt(2017, 10, 24) + .unwrap() + .and_hms_opt(0, 1, 0) + .unwrap(); let start_time_2 = Utc.from_utc_datetime(&start_time_2); let next_time_2 = schedule.after(&start_time_2).next().unwrap(); assert_eq!(next_time_1, next_time_2); @@ -190,7 +223,10 @@ mod tests { #[test] fn test_first_ordinals_not_in_set_2() { let schedule_1 = "00 00 23 * * * *".parse::().unwrap(); - let start_time = NaiveDate::from_ymd(2018, 11, 15).and_hms(22, 30, 00); + let start_time = NaiveDate::from_ymd_opt(2018, 11, 15) + .unwrap() + .and_hms_opt(22, 30, 00) + .unwrap(); let start_time = Utc.from_utc_datetime(&start_time); let next_time_1 = schedule_1.after(&start_time).next().unwrap(); diff --git a/plugin/Cargo.toml b/plugin/Cargo.toml index 163a5086..24b1e6e6 100644 --- a/plugin/Cargo.toml +++ b/plugin/Cargo.toml @@ -20,27 +20,19 @@ name = "clockwork_plugin" [dependencies] anchor-lang = "0.29.0" -async_once = "0.2.6" async-trait = "0.1.64" bincode = "1.3.3" -bs58 = "0.4.0" -bugsnag = "0.2.1" chrono = { version = "0.4.19", default-features = false, features = ["alloc"] } clockwork-cron = { path = "../cron", version = "=2.0.18" } clockwork-network-program = { path = "../programs/network", version = "=2.0.18" } clockwork-plugin-utils = { path = "utils", version = "=2.0.18" } clockwork-relayer-api = { path = "../relayer/api", version = "=2.0.18" } clockwork-thread-program = { package = "clockwork-thread-program", path = "../programs/thread", version = "=2.0.18" } -clockwork-thread-program-v1 = { package = "clockwork-thread-program-v1", path = "../programs/thread/v1", version = "=1.4.4" } clockwork-webhook-program = { path = "../programs/webhook", version = "=2.0.18" } clockwork-utils = { path = "../utils", version = "=2.0.18" } -lazy_static = "1.4.0" log = "0.4" -prost = "0.10.0" pyth-sdk-solana = "0.9.0" reqwest = "0.11.11" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" solana-account-decoder = "=1.17.14" solana-client = "=1.17.14" solana-quic-client = "=1.17.14" @@ -48,8 +40,6 @@ solana-geyser-plugin-interface = "=1.17.14" solana-logger = "=1.17.14" solana-program = "=1.17.14" solana-sdk = "=1.17.14" -solana-transaction-status = "=1.17.14" -thiserror = "1.0.30" tokio = "1.18.4" futures = "0.3.26" static-pubkey = "1.0.3" diff --git a/plugin/build.rs b/plugin/build.rs index 66f395ff..176b4353 100644 --- a/plugin/build.rs +++ b/plugin/build.rs @@ -17,7 +17,7 @@ fn main() { println!("cargo:rustc-env=RUSTC_VERSION={:#?}", rustc_v,); let output = Command::new("git") - .args(&["rev-parse", "HEAD"]) + .args(["rev-parse", "HEAD"]) .output() .expect("unable to get git commit hash"); let commit_hash = String::from_utf8(output.stdout).unwrap(); diff --git a/plugin/src/builders/pool_rotation.rs b/plugin/src/builders/pool_rotation.rs index 85c2f504..f4a8ac6a 100644 --- a/plugin/src/builders/pool_rotation.rs +++ b/plugin/src/builders/pool_rotation.rs @@ -1,9 +1,6 @@ use std::sync::Arc; -use anchor_lang::{ - solana_program::instruction::Instruction, - InstructionData, ToAccountMetas -}; +use anchor_lang::{solana_program::instruction::Instruction, InstructionData, ToAccountMetas}; use clockwork_network_program::state::{Config, Pool, Registry, Snapshot, SnapshotFrame, Worker}; use log::info; use solana_client::nonblocking::rpc_client::RpcClient; @@ -76,12 +73,13 @@ pub async fn build_pool_rotation_tx<'a>( snapshot: snapshot_pubkey, snapshot_frame: SnapshotFrame::pubkey(snapshot_pubkey, worker_id), worker: Worker::pubkey(worker_id), - }.to_account_metas(Some(false)), + } + .to_account_metas(Some(false)), data: clockwork_network_program::instruction::PoolRotate {}.data(), }; // Build and sign tx. let mut tx = Transaction::new_with_payer(&[ix.clone()], Some(&keypair.pubkey())); tx.sign(&[keypair], client.get_latest_blockhash().await.unwrap()); - return Some(tx); + Some(tx) } diff --git a/plugin/src/builders/thread_exec.rs b/plugin/src/builders/thread_exec.rs index e0ac02df..09189c6b 100644 --- a/plugin/src/builders/thread_exec.rs +++ b/plugin/src/builders/thread_exec.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use anchor_lang::{InstructionData, ToAccountMetas}; -use clockwork_thread_program::state::{VersionedThread, Trigger}; use clockwork_network_program::state::Worker; +use clockwork_thread_program::state::{Trigger, VersionedThread}; use clockwork_utils::thread::PAYER_PUBKEY; use log::info; use solana_account_decoder::UiAccountEncoding; @@ -101,25 +101,19 @@ pub async fn build_thread_exec_tx( { // If there was a simulation error, stop packing and exit now. Err(err) => { - match err.kind { - solana_client::client_error::ClientErrorKind::RpcError(rpc_err) => { - match rpc_err { - solana_client::rpc_request::RpcError::RpcResponseError { - code, - message: _, - data: _, - } => { - if code.eq(&JSON_RPC_SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED) { - return Err(GeyserPluginError::Custom( - format!("RPC client has not reached min context slot") - .into(), - )); - } - } - _ => {} - } + if let solana_client::client_error::ClientErrorKind::RpcError( + solana_client::rpc_request::RpcError::RpcResponseError { + code, + message: _, + data: _, + }, + ) = err.kind + { + if code.eq(&JSON_RPC_SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED) { + return Err(GeyserPluginError::Custom( + "RPC client has not reached min context slot".into(), + )); } - _ => {} } break; } @@ -222,16 +216,6 @@ fn build_kickoff_ix( // Build the instruction. let mut kickoff_ix = match thread { VersionedThread::V1(_) => Instruction { - program_id: clockwork_thread_program_v1::ID, - accounts: clockwork_thread_program_v1::accounts::ThreadKickoff { - signatory: signatory_pubkey, - thread: thread_pubkey, - worker: worker_pubkey, - } - .to_account_metas(Some(false)), - data: clockwork_thread_program_v1::instruction::ThreadKickoff {}.data(), - }, - VersionedThread::V2(_) => Instruction { program_id: clockwork_thread_program::ID, accounts: clockwork_thread_program::accounts::ThreadKickoff { signatory: signatory_pubkey, @@ -278,19 +262,6 @@ fn build_exec_ix( // Build the instruction. let mut exec_ix = match thread { VersionedThread::V1(_) => Instruction { - program_id: clockwork_thread_program_v1::ID, - accounts: clockwork_thread_program_v1::accounts::ThreadExec { - fee: clockwork_network_program::state::Fee::pubkey(worker_pubkey), - penalty: clockwork_network_program::state::Penalty::pubkey(worker_pubkey), - pool: clockwork_network_program::state::Pool::pubkey(0), - signatory: signatory_pubkey, - thread: thread_pubkey, - worker: worker_pubkey, - } - .to_account_metas(Some(true)), - data: clockwork_thread_program_v1::instruction::ThreadExec {}.data(), - }, - VersionedThread::V2(_) => Instruction { program_id: clockwork_thread_program::ID, accounts: clockwork_thread_program::accounts::ThreadExec { fee: clockwork_network_program::state::Fee::pubkey(worker_pubkey), diff --git a/plugin/src/events.rs b/plugin/src/events.rs index 7c8278fe..d1657677 100644 --- a/plugin/src/events.rs +++ b/plugin/src/events.rs @@ -1,7 +1,6 @@ use anchor_lang::{prelude::AccountInfo, AccountDeserialize, Discriminator}; use bincode::deserialize; -use clockwork_thread_program::state::{Thread as ThreadV2, VersionedThread}; -use clockwork_thread_program_v1::state::Thread as ThreadV1; +use clockwork_thread_program::state::{Thread, VersionedThread}; use clockwork_webhook_program::state::Webhook; use pyth_sdk_solana::{load_price_feed_from_account_info, PriceFeed}; use solana_geyser_plugin_interface::geyser_plugin_interface::{ @@ -10,7 +9,7 @@ use solana_geyser_plugin_interface::geyser_plugin_interface::{ use solana_program::{clock::Clock, pubkey::Pubkey, sysvar}; use static_pubkey::static_pubkey; -static PYTH_ORACLE_PROGRAM_ID_MAINNET: Pubkey = +static PYTH_ORACLE_PROGRAM_ID_MAINNET: Pubkey = static_pubkey!("FsJ3A3u2vn5cTVofAjvy6y5kwABJAqYWpe4975bi2epH"); static PYTH_ORACLE_PROGRAM_ID_DEVNET: Pubkey = static_pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"); @@ -41,29 +40,13 @@ impl TryFrom<&mut ReplicaAccountInfo<'_>> for AccountUpdateEvent { }); } - // If the account belongs to the thread v1 program, parse it. - if owner_pubkey.eq(&clockwork_thread_program_v1::ID) && account_info.data.len() > 8 { - let d = &account_info.data[..8]; - if d.eq(&ThreadV1::discriminator()) { - return Ok(AccountUpdateEvent::Thread { - thread: VersionedThread::V1( - ThreadV1::try_deserialize(&mut account_info.data).map_err(|_| { - GeyserPluginError::AccountsUpdateError { - msg: "Failed to parse Clockwork thread v1 account".into(), - } - })?, - ), - }); - } - } - // If the account belongs to the thread v2 program, parse it. if owner_pubkey.eq(&clockwork_thread_program::ID) && account_info.data.len() > 8 { let d = &account_info.data[..8]; - if d.eq(&ThreadV2::discriminator()) { + if d.eq(&Thread::discriminator()) { return Ok(AccountUpdateEvent::Thread { - thread: VersionedThread::V2( - ThreadV2::try_deserialize(&mut account_info.data).map_err(|_| { + thread: VersionedThread::V1( + Thread::try_deserialize(&mut account_info.data).map_err(|_| { GeyserPluginError::AccountsUpdateError { msg: "Failed to parse Clockwork thread v2 account".into(), } diff --git a/plugin/src/executors/mod.rs b/plugin/src/executors/mod.rs index f47c3464..3ddedfb4 100644 --- a/plugin/src/executors/mod.rs +++ b/plugin/src/executors/mod.rs @@ -131,9 +131,9 @@ impl AccountGet for RpcClient { async fn get(&self, pubkey: &Pubkey) -> ClientResult { let data = self.get_account_data(pubkey).await?; T::try_deserialize(&mut data.as_slice()).map_err(|_| { - ClientError::from(ClientErrorKind::Custom(format!( - "Failed to deserialize account data" - ))) + ClientError::from(ClientErrorKind::Custom( + "Failed to deserialize account data".to_string(), + )) }) } } diff --git a/plugin/src/executors/tx.rs b/plugin/src/executors/tx.rs index eac8e2bc..6f0d540c 100644 --- a/plugin/src/executors/tx.rs +++ b/plugin/src/executors/tx.rs @@ -257,15 +257,11 @@ impl TxExecutor { .checked_add(ROTATION_CONFIRMATION_PERIOD) .unwrap() { - if let Ok(sig_status) = client + if let Ok(Some(status)) = client .get_signature_status(&rotation_history.signature) .await { - if let Some(status) = sig_status { - status.is_err() - } else { - true - } + status.is_err() } else { true } @@ -324,14 +320,14 @@ impl TxExecutor { r_executable_threads .iter() .filter(|(_pubkey, metadata)| slot > metadata.due_slot + THREAD_TIMEOUT_WINDOW) - .filter(|(_pubkey, metadata)| slot >= exponential_backoff_threshold(*metadata)) + .filter(|(_pubkey, metadata)| slot >= exponential_backoff_threshold(metadata)) .map(|(pubkey, metadata)| (*pubkey, metadata.due_slot)) .collect::>() } else { // This worker is in the pool. Get pubkeys executable threads. r_executable_threads .iter() - .filter(|(_pubkey, metadata)| slot >= exponential_backoff_threshold(*metadata)) + .filter(|(_pubkey, metadata)| slot >= exponential_backoff_threshold(metadata)) .map(|(pubkey, metadata)| (*pubkey, metadata.due_slot)) .collect::>() }; @@ -490,7 +486,11 @@ impl TxExecutor { let r_transaction_history = self.transaction_history.read().await; if let Some(metadata) = r_transaction_history.get(&thread_pubkey) { if metadata.signature.eq(&tx.signatures[0]) && metadata.sent_slot.le(&slot) { - return Err(GeyserPluginError::Custom(format!("Transaction signature is a duplicate of a previously submitted transaction").into())); + return Err(GeyserPluginError::Custom( + "Transaction signature is a duplicate of a previously submitted transaction" + .to_string() + .into(), + )); } } drop(r_transaction_history); @@ -554,13 +554,12 @@ async fn get_tpu_client() -> TpuClient *mut dyn GeyserPlugin { - let plugin: Box = Box::new(ClockworkPlugin::default()); + let plugin: Box = Box::::default(); Box::into_raw(plugin) } diff --git a/plugin/src/observers/mod.rs b/plugin/src/observers/mod.rs index 525d2d56..7bc9ce41 100644 --- a/plugin/src/observers/mod.rs +++ b/plugin/src/observers/mod.rs @@ -6,6 +6,7 @@ use std::{fmt::Debug, sync::Arc}; use thread::ThreadObserver; use webhook::WebhookObserver; +#[derive(Default)] pub struct Observers { pub thread: Arc, pub webhook: Arc, @@ -13,10 +14,7 @@ pub struct Observers { impl Observers { pub fn new() -> Self { - Observers { - thread: Arc::new(ThreadObserver::new()), - webhook: Arc::new(WebhookObserver::new()), - } + Self::default() } } diff --git a/plugin/src/observers/thread.rs b/plugin/src/observers/thread.rs index be8114c1..b0e62b38 100644 --- a/plugin/src/observers/thread.rs +++ b/plugin/src/observers/thread.rs @@ -7,7 +7,7 @@ use std::{ use chrono::{DateTime, NaiveDateTime, Utc}; use clockwork_cron::Schedule; -use clockwork_thread_program::state::{Trigger, TriggerContext, Equality, VersionedThread}; +use clockwork_thread_program::state::{Equality, Trigger, TriggerContext, VersionedThread}; use log::info; use pyth_sdk_solana::PriceFeed; use solana_geyser_plugin_interface::geyser_plugin_interface::{ @@ -16,6 +16,7 @@ use solana_geyser_plugin_interface::geyser_plugin_interface::{ use solana_program::{clock::Clock, pubkey::Pubkey}; use tokio::sync::RwLock; +#[derive(Default)] pub struct ThreadObserver { // Map from slot numbers to the sysvar clock data for that slot. pub clocks: RwLock>, @@ -56,17 +57,7 @@ pub struct PythThread { impl ThreadObserver { pub fn new() -> Self { - Self { - clocks: RwLock::new(HashMap::new()), - current_epoch: AtomicU64::new(0), - account_threads: RwLock::new(HashMap::new()), - cron_threads: RwLock::new(HashMap::new()), - now_threads: RwLock::new(HashSet::new()), - slot_threads: RwLock::new(HashMap::new()), - epoch_threads: RwLock::new(HashMap::new()), - pyth_threads: RwLock::new(HashMap::new()), - updated_accounts: RwLock::new(HashSet::new()), - } + Self::default() } pub async fn process_slot(self: Arc, slot: u64) -> PluginResult> { @@ -99,7 +90,7 @@ impl ThreadObserver { let r_account_threads = self.account_threads.read().await; let mut w_updated_accounts = self.updated_accounts.write().await; w_updated_accounts.iter().for_each(|account_pubkey| { - if let Some(thread_pubkeys) = r_account_threads.get(&account_pubkey) { + if let Some(thread_pubkeys) = r_account_threads.get(account_pubkey) { thread_pubkeys.iter().for_each(|pubkey| { executable_threads.insert(*pubkey); }); @@ -250,7 +241,7 @@ impl ThreadObserver { drop(w_account_threads); // Threads with account triggers might be immediately executable, - // Thus, we should attempt to execute these threads right away without for an account update. + // Thus, we should attempt to execute these threads right away without for an account update. let mut w_now_threads = self.now_threads.write().await; w_now_threads.insert(thread_pubkey); drop(w_now_threads); @@ -381,7 +372,7 @@ fn next_moment(after: i64, schedule: String) -> Option { match Schedule::from_str(&schedule) { Err(_) => None, Ok(schedule) => schedule - .next_after(&DateTime::::from_utc( + .next_after(&DateTime::::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(after, 0).unwrap(), Utc, )) diff --git a/plugin/src/observers/webhook.rs b/plugin/src/observers/webhook.rs index e9a5bb04..c2ba2c15 100644 --- a/plugin/src/observers/webhook.rs +++ b/plugin/src/observers/webhook.rs @@ -5,6 +5,7 @@ use solana_geyser_plugin_interface::geyser_plugin_interface::Result as PluginRes use solana_program::pubkey::Pubkey; use tokio::sync::RwLock; +#[derive(Default)] pub struct WebhookObserver { // The set of webhook that can be processed. pub webhooks: RwLock>, @@ -12,9 +13,7 @@ pub struct WebhookObserver { impl WebhookObserver { pub fn new() -> Self { - Self { - webhooks: RwLock::new(HashSet::new()), - } + Self::default() } pub async fn observe_webhook( diff --git a/plugin/src/plugin.rs b/plugin/src/plugin.rs index 5c74a311..24fdcdb7 100644 --- a/plugin/src/plugin.rs +++ b/plugin/src/plugin.rs @@ -161,15 +161,12 @@ impl GeyserPlugin for ClockworkPlugin { status: SlotStatus, ) -> PluginResult<()> { self.inner.clone().spawn(|inner| async move { - match status { - SlotStatus::Processed => { - inner - .executors - .clone() - .process_slot(inner.observers.clone(), slot, inner.runtime.clone()) - .await?; - } - _ => (), + if let SlotStatus::Processed = status { + inner + .executors + .clone() + .process_slot(inner.observers.clone(), slot, inner.runtime.clone()) + .await?; } Ok(()) }); diff --git a/plugin/src/pool_position.rs b/plugin/src/pool_position.rs index 5cfc50fd..1519aa72 100644 --- a/plugin/src/pool_position.rs +++ b/plugin/src/pool_position.rs @@ -1,16 +1,7 @@ use {solana_program::pubkey::Pubkey, std::fmt::Debug}; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct PoolPosition { pub current_position: Option, pub workers: Vec, } - -impl Default for PoolPosition { - fn default() -> Self { - PoolPosition { - current_position: None, - workers: vec![], - } - } -} diff --git a/plugin/utils/src/config.rs b/plugin/utils/src/config.rs index cde571a4..1236ffcb 100644 --- a/plugin/utils/src/config.rs +++ b/plugin/utils/src/config.rs @@ -1,8 +1,5 @@ use { - serde::{ - Serialize, - Deserialize - }, + serde::{Deserialize, Serialize}, solana_geyser_plugin_interface::geyser_plugin_interface::{ GeyserPluginError, Result as PluginResult, }, diff --git a/programs/network/Cargo.toml b/programs/network/Cargo.toml index 497d5089..9ec9011a 100644 --- a/programs/network/Cargo.toml +++ b/programs/network/Cargo.toml @@ -25,5 +25,3 @@ default = [] anchor-lang = "0.29.0" anchor-spl = { features = ["mint", "token"], version = "0.29.0" } clockwork-utils = { path = "../../utils", version = "=2.0.18" } -winnow = "=0.4.1" -toml_datetime = "=0.6.1" diff --git a/programs/network/src/constants.rs b/programs/network/src/constants.rs new file mode 100644 index 00000000..02627362 --- /dev/null +++ b/programs/network/src/constants.rs @@ -0,0 +1,37 @@ +use anchor_lang::prelude::*; + +#[constant] +pub const SEED_CONFIG: &[u8] = b"config"; + +#[constant] +pub const SEED_DELEGATION: &[u8] = b"delegation"; + +#[constant] +pub const SEED_FEE: &[u8] = b"fee"; + +#[constant] +pub const SEED_EPOCH: &[u8] = b"epoch"; + +#[constant] +pub const SEED_PENALTY: &[u8] = b"penalty"; + +#[constant] +pub const SEED_SNAPSHOT_ENTRY: &[u8] = b"snapshot_entry"; + +#[constant] +pub const SEED_SNAPSHOT_FRAME: &[u8] = b"snapshot_frame"; + +#[constant] +pub const SEED_REGISTRY: &[u8] = b"registry"; + +#[constant] +pub const SEED_WORKER: &[u8] = b"worker"; + +#[constant] +pub const SEED_POOL: &[u8] = b"pool"; + +#[constant] +pub const SEED_SNAPSHOT: &[u8] = b"snapshot"; + +#[constant] +pub const SEED_UNSTAKE: &[u8] = b"unstake"; diff --git a/programs/network/src/instructions/config_update.rs b/programs/network/src/instructions/config_update.rs index 5ea257f3..1177b4de 100644 --- a/programs/network/src/instructions/config_update.rs +++ b/programs/network/src/instructions/config_update.rs @@ -1,15 +1,17 @@ -use {crate::state::*, anchor_lang::prelude::*}; +use { + crate::{constants::*, state::*}, + anchor_lang::prelude::*, +}; #[derive(Accounts)] #[instruction(settings: ConfigSettings)] pub struct ConfigUpdate<'info> { - #[account(mut)] pub admin: Signer<'info>, #[account( - mut, + mut, seeds = [SEED_CONFIG], - bump, + bump, has_one = admin )] pub config: Account<'info, Config>, diff --git a/programs/network/src/instructions/delegation_claim.rs b/programs/network/src/instructions/delegation_claim.rs index f2d2448c..737f3d33 100644 --- a/programs/network/src/instructions/delegation_claim.rs +++ b/programs/network/src/instructions/delegation_claim.rs @@ -1,9 +1,11 @@ -use {crate::state::*, anchor_lang::prelude::*}; +use { + crate::{constants::*, state::*}, + anchor_lang::prelude::*, +}; #[derive(Accounts)] #[instruction(amount: u64)] pub struct DelegationClaim<'info> { - #[account()] pub authority: Signer<'info>, #[account(mut)] @@ -28,7 +30,7 @@ pub fn handler(ctx: Context, amount: u64) -> Result<()> { let delegation = &mut ctx.accounts.delegation; // Decrement the delegation's claimable balance. - delegation.yield_balance = delegation.yield_balance.checked_sub(amount).unwrap(); + delegation.yield_balance -= amount; // Transfer commission to the worker. delegation.sub_lamports(amount)?; diff --git a/programs/network/src/instructions/delegation_create.rs b/programs/network/src/instructions/delegation_create.rs index 98dc8ea2..c9b5d351 100644 --- a/programs/network/src/instructions/delegation_create.rs +++ b/programs/network/src/instructions/delegation_create.rs @@ -1,21 +1,14 @@ use { - crate::state::*, - anchor_lang::{ - prelude::*, - solana_program::{system_program, sysvar}, - }, + crate::{constants::*, state::*}, + anchor_lang::prelude::*, anchor_spl::{ associated_token::AssociatedToken, token::{Mint, Token, TokenAccount}, }, - std::mem::size_of, }; #[derive(Accounts)] pub struct DelegationCreate<'info> { - #[account(address = anchor_spl::associated_token::ID)] - pub associated_token_program: Program<'info, AssociatedToken>, - #[account(mut)] pub authority: Signer<'info>, @@ -31,7 +24,7 @@ pub struct DelegationCreate<'info> { ], bump, payer = authority, - space = 8 + size_of::(), + space = 8 + Delegation::INIT_SPACE, )] pub delegation: Account<'info, Delegation>, @@ -46,15 +39,6 @@ pub struct DelegationCreate<'info> { #[account(address = config.mint)] pub mint: Account<'info, Mint>, - #[account(address = sysvar::rent::ID)] - pub rent: Sysvar<'info, Rent>, - - #[account(address = system_program::ID)] - pub system_program: Program<'info, System>, - - #[account(address = anchor_spl::token::ID)] - pub token_program: Program<'info, Token>, - #[account( mut, seeds = [ @@ -64,6 +48,12 @@ pub struct DelegationCreate<'info> { bump )] pub worker: Account<'info, Worker>, + + pub token_program: Program<'info, Token>, + + pub associated_token_program: Program<'info, AssociatedToken>, + + pub system_program: Program<'info, System>, } pub fn handler(ctx: Context) -> Result<()> { @@ -76,7 +66,7 @@ pub fn handler(ctx: Context) -> Result<()> { delegation.init(authority.key(), worker.total_delegations, worker.key())?; // Increment the worker's total delegations counter. - worker.total_delegations = worker.total_delegations.checked_add(1).unwrap(); + worker.total_delegations += 1; Ok(()) } diff --git a/programs/network/src/instructions/delegation_deposit.rs b/programs/network/src/instructions/delegation_deposit.rs index 2451fecf..6fee0015 100644 --- a/programs/network/src/instructions/delegation_deposit.rs +++ b/programs/network/src/instructions/delegation_deposit.rs @@ -1,5 +1,5 @@ use { - crate::state::*, + crate::{constants::*, state::*}, anchor_lang::prelude::*, anchor_spl::token::{transfer, Token, TokenAccount, Transfer}, }; @@ -39,7 +39,6 @@ pub struct DelegationDeposit<'info> { )] pub delegation_tokens: Account<'info, TokenAccount>, - #[account(address = anchor_spl::token::ID)] pub token_program: Program<'info, Token>, } diff --git a/programs/network/src/instructions/delegation_withdraw.rs b/programs/network/src/instructions/delegation_withdraw.rs index 38d22e7b..48f5af1b 100644 --- a/programs/network/src/instructions/delegation_withdraw.rs +++ b/programs/network/src/instructions/delegation_withdraw.rs @@ -1,5 +1,5 @@ use { - crate::state::*, + crate::{constants::*, state::*}, anchor_lang::prelude::*, anchor_spl::token::{transfer, Token, TokenAccount, Transfer}, }; @@ -39,7 +39,6 @@ pub struct DelegationWithdraw<'info> { )] pub delegation_tokens: Account<'info, TokenAccount>, - #[account(address = anchor_spl::token::ID)] pub token_program: Program<'info, Token>, } diff --git a/programs/network/src/instructions/fee_collect.rs b/programs/network/src/instructions/fee_collect.rs index 1fb0b6fd..92e5f1a6 100644 --- a/programs/network/src/instructions/fee_collect.rs +++ b/programs/network/src/instructions/fee_collect.rs @@ -16,7 +16,6 @@ pub struct FeeCollect<'info> { )] pub fee: Account<'info, Fee>, - #[account()] pub signer: Signer<'info>, } @@ -26,15 +25,15 @@ pub fn handler(ctx: Context, amount: u64, penalty: bool) -> Result<( // Increment the collected fee counter. if penalty { - fee.penalty_balance = fee.penalty_balance.checked_add(amount).unwrap(); + fee.penalty_balance += amount; } else { - fee.collected_balance = fee.collected_balance.checked_add(amount).unwrap(); + fee.collected_balance += amount; } // Verify there are enough lamports to distribute at the end of the epoch. let lamport_balance = fee.get_lamports(); - let data_len = 8 + fee.try_to_vec()?.len(); - let min_rent_balance = Rent::get().unwrap().minimum_balance(data_len); + let data_len = 8 + Fee::INIT_SPACE; + let min_rent_balance = Rent::get()?.minimum_balance(data_len); msg!( "Fee collection! lamports: {} collected: {} penalty: {} rent: {}", @@ -45,12 +44,7 @@ pub fn handler(ctx: Context, amount: u64, penalty: bool) -> Result<( ); require!( - fee.collected_balance - .checked_add(fee.penalty_balance) - .unwrap() - .checked_add(min_rent_balance) - .unwrap() - .ge(&lamport_balance), + (fee.collected_balance + fee.penalty_balance + min_rent_balance) >= lamport_balance ClockworkError::InsufficientFeeBalance ); diff --git a/programs/network/src/instructions/initialize.rs b/programs/network/src/instructions/initialize.rs index 6dd1c936..31fbdb4e 100644 --- a/programs/network/src/instructions/initialize.rs +++ b/programs/network/src/instructions/initialize.rs @@ -1,8 +1,7 @@ use { - crate::state::*, - anchor_lang::{prelude::*, solana_program::system_program}, + crate::{constants::*, state::*}, + anchor_lang::prelude::*, anchor_spl::token::Mint, - std::mem::size_of, }; #[derive(Accounts)] @@ -15,11 +14,10 @@ pub struct Initialize<'info> { seeds = [SEED_CONFIG], bump, payer = admin, - space = 8 + size_of::(), + space = 8 + Config::INIT_SPACE, )] pub config: Account<'info, Config>, - #[account()] pub mint: Account<'info, Mint>, #[account( @@ -27,7 +25,7 @@ pub struct Initialize<'info> { seeds = [SEED_REGISTRY], bump, payer = admin, - space = 8 + size_of::(), + space = 8 + Registry::INIT_SPACE, )] pub registry: Account<'info, Registry>, @@ -35,15 +33,14 @@ pub struct Initialize<'info> { init, seeds = [ SEED_SNAPSHOT, - (0 as u64).to_be_bytes().as_ref(), + 0_u64.to_be_bytes().as_ref(), ], bump, payer = admin, - space = 8 + size_of::(), + space = 8 + Snapshot::INIT_SPACE, )] pub snapshot: Account<'info, Snapshot>, - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, } diff --git a/programs/network/src/instructions/penalty_claim.rs b/programs/network/src/instructions/penalty_claim.rs index d5a84512..8fad79a9 100644 --- a/programs/network/src/instructions/penalty_claim.rs +++ b/programs/network/src/instructions/penalty_claim.rs @@ -1,11 +1,11 @@ use { - crate::{errors::*, state::*}, + crate::{constants::*, errors::*, state::*}, anchor_lang::prelude::*, }; #[derive(Accounts)] pub struct PenaltyClaim<'info> { - #[account(mut, address = config.admin)] + #[account(address = config.admin)] pub admin: Signer<'info>, #[account(address = Config::pubkey())] @@ -31,26 +31,18 @@ pub fn handler(ctx: Context) -> Result<()> { let pay_to = &mut ctx.accounts.pay_to; // Calculate how many lamports are - let lamport_balance = penalty.to_account_info().lamports(); - let data_len = 8 + penalty.try_to_vec()?.len(); - let min_rent_balance = Rent::get().unwrap().minimum_balance(data_len); - let claimable_balance = lamport_balance.checked_sub(min_rent_balance).unwrap(); + let lamport_balance = penalty.get_lamports(); + let data_len = 8 + Penalty::INIT_SPACE; + let min_rent_balance = Rent::get()?.minimum_balance(data_len); + let claimable_balance = lamport_balance - min_rent_balance; require!( - claimable_balance.gt(&0), + claimable_balance > 0, ClockworkError::InsufficientPenaltyBalance ); // Pay reimbursment for base transaction fee - **penalty.to_account_info().try_borrow_mut_lamports()? = penalty - .to_account_info() - .lamports() - .checked_sub(claimable_balance) - .unwrap(); - **pay_to.to_account_info().try_borrow_mut_lamports()? = pay_to - .to_account_info() - .lamports() - .checked_add(claimable_balance) - .unwrap(); + penalty.sub_lamports(claimable_balance)?; + pay_to.add_lamports(claimable_balance)?; Ok(()) } diff --git a/programs/network/src/instructions/pool_create.rs b/programs/network/src/instructions/pool_create.rs index 7a7cc3e2..8e564835 100644 --- a/programs/network/src/instructions/pool_create.rs +++ b/programs/network/src/instructions/pool_create.rs @@ -1,6 +1,6 @@ use { - crate::{errors::*, state::*}, - anchor_lang::{prelude::*, solana_program::system_program}, + crate::{constants::*, errors::*, state::*}, + anchor_lang::prelude::*, std::mem::size_of, }; @@ -10,7 +10,7 @@ pub struct PoolCreate<'info> { pub admin: Signer<'info>, #[account( - address = Config::pubkey(), + address = Config::pubkey(), has_one = admin )] pub config: Account<'info, Config>, @@ -38,7 +38,6 @@ pub struct PoolCreate<'info> { )] pub registry: Box>, - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, } @@ -51,7 +50,7 @@ pub fn handler(ctx: Context) -> Result<()> { pool.init(registry.total_pools)?; // Increment the registry's pool counter. - registry.total_pools = registry.total_pools.checked_add(1).unwrap(); + registry.total_pools += 1; Ok(()) } diff --git a/programs/network/src/instructions/pool_rotate.rs b/programs/network/src/instructions/pool_rotate.rs index 95a67b81..2b4dccbf 100644 --- a/programs/network/src/instructions/pool_rotate.rs +++ b/programs/network/src/instructions/pool_rotate.rs @@ -1,5 +1,5 @@ use { - crate::{errors::*, state::*}, + crate::{constants::*, errors::*, state::*}, anchor_lang::prelude::*, }; @@ -31,7 +31,7 @@ pub struct PoolRotate<'info> { #[account( address = snapshot.pubkey(), - constraint = snapshot.id.eq(®istry.current_epoch) + constraint = snapshot.id == registry.current_epoch )] pub snapshot: Account<'info, Snapshot>, @@ -59,8 +59,8 @@ pub fn handler(ctx: Context) -> Result<()> { // Verify the pool has excess space or the worker can rotate in at this time. require!( - pool.workers.len().lt(&pool.size) - || is_rotation_window_open(®istry, &snapshot, &snapshot_frame).unwrap(), + pool.workers.len() < pool.size + || is_rotation_window_open(registry, snapshot, snapshot_frame).unwrap(), ClockworkError::PoolFull ); @@ -85,10 +85,6 @@ fn is_rotation_window_open( match registry.nonce.checked_rem(snapshot.total_stake) { None => Ok(false), Some(sample) => Ok(sample >= snapshot_frame.stake_offset - && sample - < snapshot_frame - .stake_offset - .checked_add(snapshot_frame.stake_amount) - .unwrap()), + && sample < snapshot_frame.stake_offset + snapshot_frame.stake_amount), } } diff --git a/programs/network/src/instructions/pool_update.rs b/programs/network/src/instructions/pool_update.rs index 03d41c61..7a8a132f 100644 --- a/programs/network/src/instructions/pool_update.rs +++ b/programs/network/src/instructions/pool_update.rs @@ -2,20 +2,19 @@ use { crate::state::*, anchor_lang::{ prelude::*, - solana_program::system_program, system_program::{transfer, Transfer}, }, + clockwork_utils::account::AccountInfoExt, std::mem::size_of, }; #[derive(Accounts)] #[instruction(settings: PoolSettings)] pub struct PoolUpdate<'info> { - #[account()] pub admin: Signer<'info>, #[account( - address = Config::pubkey(), + address = Config::pubkey(), has_one = admin )] pub config: Account<'info, Config>, @@ -26,7 +25,6 @@ pub struct PoolUpdate<'info> { #[account(mut, address = pool.pubkey())] pub pool: Account<'info, Pool>, - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, } @@ -41,11 +39,11 @@ pub fn handler(ctx: Context, settings: PoolSettings) -> Result<()> { // Reallocate memory for the pool account let data_len = 8 + size_of::() + settings.size.checked_mul(size_of::()).unwrap(); - pool.to_account_info().realloc(data_len, false)?; + pool.realloc(data_len, false)?; // If lamports are required to maintain rent-exemption, pay them - let minimum_rent = Rent::get().unwrap().minimum_balance(data_len); - if minimum_rent > pool.to_account_info().lamports() { + let minimum_rent = Rent::get()?.minimum_balance(data_len); + if minimum_rent > pool.get_lamports() { transfer( CpiContext::new( system_program.to_account_info(), @@ -54,9 +52,7 @@ pub fn handler(ctx: Context, settings: PoolSettings) -> Result<()> { to: pool.to_account_info(), }, ), - minimum_rent - .checked_sub(pool.to_account_info().lamports()) - .unwrap(), + minimum_rent - pool.get_lamports(), )?; } diff --git a/programs/network/src/instructions/registry_nonce_hash.rs b/programs/network/src/instructions/registry_nonce_hash.rs index c29224bb..2bfdd289 100644 --- a/programs/network/src/instructions/registry_nonce_hash.rs +++ b/programs/network/src/instructions/registry_nonce_hash.rs @@ -1,6 +1,9 @@ use clockwork_utils::thread::ThreadResponse; -use {crate::state::*, anchor_lang::prelude::*}; +use { + crate::{constants::*, state::*}, + anchor_lang::prelude::*, +}; #[derive(Accounts)] pub struct RegistryNonceHash<'info> { diff --git a/programs/network/src/instructions/registry_unlock.rs b/programs/network/src/instructions/registry_unlock.rs index 6c8ffba2..f7de49ef 100644 --- a/programs/network/src/instructions/registry_unlock.rs +++ b/programs/network/src/instructions/registry_unlock.rs @@ -1,8 +1,10 @@ -use {crate::state::*, anchor_lang::prelude::*}; +use { + crate::{constants::*, state::*}, + anchor_lang::prelude::*, +}; #[derive(Accounts)] pub struct RegistryUnlock<'info> { - #[account(mut)] pub admin: Signer<'info>, #[account(seeds = [SEED_CONFIG], bump, has_one = admin)] diff --git a/programs/network/src/instructions/unstake_create.rs b/programs/network/src/instructions/unstake_create.rs index 86e8e399..ae51c8a9 100644 --- a/programs/network/src/instructions/unstake_create.rs +++ b/programs/network/src/instructions/unstake_create.rs @@ -1,7 +1,6 @@ use { - crate::{errors::*, state::*}, - anchor_lang::{prelude::*, solana_program::system_program}, - std::mem::size_of + crate::{constants::*, errors::*, state::*}, + anchor_lang::prelude::*, }; #[derive(Accounts)] @@ -25,12 +24,11 @@ pub struct UnstakeCreate<'info> { #[account( mut, seeds = [SEED_REGISTRY], - bump, + bump, constraint = !registry.locked @ ClockworkError::RegistryLocked )] pub registry: Account<'info, Registry>, - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, #[account( @@ -41,7 +39,7 @@ pub struct UnstakeCreate<'info> { ], bump, payer = authority, - space = 8 + size_of::(), + space = 8 + Unstake::INIT_SPACE, )] pub unstake: Account<'info, Unstake>, @@ -58,13 +56,22 @@ pub fn handler(ctx: Context, amount: u64) -> Result<()> { let worker = &ctx.accounts.worker; // Validate the request is valid. - require!(amount.le(&delegation.stake_amount), ClockworkError::InvalidUnstakeAmount); + require!( + amount <= delegation.stake_amount, + ClockworkError::InvalidUnstakeAmount + ); // Initialize the unstake account. - unstake.init(amount, authority.key(), delegation.key(), registry.total_unstakes, worker.key())?; + unstake.init( + amount, + authority.key(), + delegation.key(), + registry.total_unstakes, + worker.key(), + )?; // Increment the registry's unstake counter. - registry.total_unstakes = registry.total_unstakes.checked_add(1).unwrap(); + registry.total_unstakes += 1; Ok(()) } diff --git a/programs/network/src/instructions/worker_claim.rs b/programs/network/src/instructions/worker_claim.rs index 6045378f..65529453 100644 --- a/programs/network/src/instructions/worker_claim.rs +++ b/programs/network/src/instructions/worker_claim.rs @@ -1,9 +1,11 @@ -use {crate::state::*, anchor_lang::prelude::*}; +use { + crate::{constants::*, state::*}, + anchor_lang::prelude::*, +}; #[derive(Accounts)] #[instruction(amount: u64)] pub struct WorkerClaim<'info> { - #[account()] pub authority: Signer<'info>, #[account(mut)] @@ -27,19 +29,11 @@ pub fn handler(ctx: Context, amount: u64) -> Result<()> { let worker = &mut ctx.accounts.worker; // Decrement the worker's commission balance. - worker.commission_balance = worker.commission_balance.checked_sub(amount).unwrap(); + worker.commission_balance -= amount; // Transfer commission to the worker. - **worker.to_account_info().try_borrow_mut_lamports()? = worker - .to_account_info() - .lamports() - .checked_sub(amount) - .unwrap(); - **pay_to.to_account_info().try_borrow_mut_lamports()? = pay_to - .to_account_info() - .lamports() - .checked_add(amount) - .unwrap(); + worker.sub_lamports(amount)?; + pay_to.add_lamports(amount)?; Ok(()) } diff --git a/programs/network/src/instructions/worker_create.rs b/programs/network/src/instructions/worker_create.rs index 6b095fb0..7630ed13 100644 --- a/programs/network/src/instructions/worker_create.rs +++ b/programs/network/src/instructions/worker_create.rs @@ -1,27 +1,21 @@ use { - crate::{errors::*, state::*}, - anchor_lang::{ - prelude::*, - solana_program::{system_program, sysvar}, - }, + crate::{constants::*, errors::*, state::*}, + anchor_lang::prelude::*, anchor_spl::{ associated_token::AssociatedToken, token::{Mint, Token, TokenAccount}, }, - std::mem::size_of, }; - #[derive(Accounts)] pub struct WorkerCreate<'info> { - #[account(address = anchor_spl::associated_token::ID)] pub associated_token_program: Program<'info, AssociatedToken>, #[account(mut)] pub authority: Signer<'info>, #[account(address = Config::pubkey())] - pub config: Box>, + pub config: Account<'info, Config>, #[account( init, @@ -31,7 +25,7 @@ pub struct WorkerCreate<'info> { ], bump, payer = authority, - space = 8 + size_of::(), + space = 8 + Fee::INIT_SPACE, )] pub fee: Account<'info, Fee>, @@ -43,7 +37,7 @@ pub struct WorkerCreate<'info> { ], bump, payer = authority, - space = 8 + size_of::(), + space = 8 + Penalty::INIT_SPACE, )] pub penalty: Account<'info, Penalty>, @@ -51,23 +45,18 @@ pub struct WorkerCreate<'info> { pub mint: Account<'info, Mint>, #[account( - mut, + mut, seeds = [SEED_REGISTRY], bump, constraint = !registry.locked @ ClockworkError::RegistryLocked )] pub registry: Account<'info, Registry>, - #[account(address = sysvar::rent::ID)] - pub rent: Sysvar<'info, Rent>, - - #[account(constraint = signatory.key().ne(&authority.key()) @ ClockworkError::InvalidSignatory)] + #[account(constraint = signatory.key() != authority.key() @ ClockworkError::InvalidSignatory)] pub signatory: Signer<'info>, - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, - #[account(address = anchor_spl::token::ID)] pub token_program: Program<'info, Token>, #[account( @@ -78,7 +67,7 @@ pub struct WorkerCreate<'info> { ], bump, payer = authority, - space = 8 + size_of::(), + space = 8 + Worker::INIT_SPACE, )] pub worker: Account<'info, Worker>, @@ -89,7 +78,6 @@ pub struct WorkerCreate<'info> { associated_token::mint = mint, )] pub worker_tokens: Account<'info, TokenAccount>, - } pub fn handler(ctx: Context) -> Result<()> { @@ -107,7 +95,7 @@ pub fn handler(ctx: Context) -> Result<()> { penalty.init(worker.key())?; // Update the registry's worker counter. - registry.total_workers = registry.total_workers.checked_add(1).unwrap(); + registry.total_workers += 1; Ok(()) } diff --git a/programs/network/src/instructions/worker_update.rs b/programs/network/src/instructions/worker_update.rs index d7f19c12..fdfa2374 100644 --- a/programs/network/src/instructions/worker_update.rs +++ b/programs/network/src/instructions/worker_update.rs @@ -1,8 +1,7 @@ use { - crate::state::*, + crate::{constants::*, state::*}, anchor_lang::{ prelude::*, - solana_program::system_program, system_program::{transfer, Transfer}, }, }; @@ -13,7 +12,6 @@ pub struct WorkerUpdate<'info> { #[account(mut)] pub authority: Signer<'info>, - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, #[account( @@ -37,13 +35,11 @@ pub fn handler(ctx: Context, settings: WorkerSettings) -> Result<( // Update the worker worker.update(settings)?; - // Realloc memory for the worker account - let data_len = 8 + worker.try_to_vec()?.len(); - worker.to_account_info().realloc(data_len, false)?; - // If lamports are required to maintain rent-exemption, pay them - let minimum_rent = Rent::get().unwrap().minimum_balance(data_len); - if minimum_rent > worker.to_account_info().lamports() { + let data_len = 8 + Worker::INIT_SPACE; + let minimum_rent = Rent::get()?.minimum_balance(data_len); + let worker_lamports = worker.get_lamports(); + if minimum_rent > worker_lamports { transfer( CpiContext::new( system_program.to_account_info(), @@ -52,9 +48,7 @@ pub fn handler(ctx: Context, settings: WorkerSettings) -> Result<( to: worker.to_account_info(), }, ), - minimum_rent - .checked_sub(worker.to_account_info().lamports()) - .unwrap(), + minimum_rent - worker_lamports, )?; } diff --git a/programs/network/src/jobs/delete_snapshot/job.rs b/programs/network/src/jobs/delete_snapshot/job.rs index 3374a4da..64bd6612 100644 --- a/programs/network/src/jobs/delete_snapshot/job.rs +++ b/programs/network/src/jobs/delete_snapshot/job.rs @@ -30,7 +30,7 @@ pub fn handler(ctx: Context) -> Result { accounts: crate::accounts::DeleteSnapshotProcessSnapshot { config: config.key(), registry: registry.key(), - snapshot: Snapshot::pubkey(registry.current_epoch.checked_sub(1).unwrap()), + snapshot: Snapshot::pubkey(registry.current_epoch - 1), thread: thread.key(), } .to_account_metas(Some(true)), diff --git a/programs/network/src/jobs/delete_snapshot/process_entry.rs b/programs/network/src/jobs/delete_snapshot/process_entry.rs index dd8f2abe..87d02094 100644 --- a/programs/network/src/jobs/delete_snapshot/process_entry.rs +++ b/programs/network/src/jobs/delete_snapshot/process_entry.rs @@ -1,7 +1,7 @@ -use anchor_lang::{prelude::*, InstructionData, solana_program::instruction::Instruction}; +use anchor_lang::{prelude::*, solana_program::instruction::Instruction, InstructionData}; use clockwork_utils::thread::ThreadResponse; -use crate::state::*; +use crate::{constants::*, state::*}; #[derive(Accounts)] pub struct DeleteSnapshotProcessEntry<'info> { @@ -21,7 +21,7 @@ pub struct DeleteSnapshotProcessEntry<'info> { snapshot.id.to_be_bytes().as_ref(), ], bump, - constraint = snapshot.id.lt(®istry.current_epoch) + constraint = snapshot.id < registry.current_epoch )] pub snapshot: Account<'info, Snapshot>, @@ -50,7 +50,7 @@ pub struct DeleteSnapshotProcessEntry<'info> { pub snapshot_frame: Account<'info, SnapshotFrame>, #[account( - mut, + mut, address = config.epoch_thread )] pub thread: Signer<'info>, @@ -66,71 +66,71 @@ pub fn handler(ctx: Context) -> Result { @@ -21,7 +21,7 @@ pub struct DeleteSnapshotProcessFrame<'info> { snapshot.id.to_be_bytes().as_ref(), ], bump, - constraint = snapshot.id.lt(®istry.current_epoch) + constraint = snapshot.id < registry.current_epoch )] pub snapshot: Account<'info, Snapshot>, @@ -38,7 +38,7 @@ pub struct DeleteSnapshotProcessFrame<'info> { pub snapshot_frame: Account<'info, SnapshotFrame>, #[account( - mut, + mut, address = config.epoch_thread )] pub thread: Signer<'info>, @@ -53,30 +53,21 @@ pub fn handler(ctx: Context) -> Result 0 { // This frame has entries. Delete the entries. Some( Instruction { @@ -88,11 +79,13 @@ pub fn handler(ctx: Context) -> Result) -> Result { @@ -21,12 +21,12 @@ pub struct DeleteSnapshotProcessSnapshot<'info> { snapshot.id.to_be_bytes().as_ref(), ], bump, - constraint = snapshot.id.lt(®istry.current_epoch) + constraint = snapshot.id < registry.current_epoch )] pub snapshot: Account<'info, Snapshot>, #[account( - mut, + mut, address = config.epoch_thread )] pub thread: Signer<'info>, @@ -40,18 +40,14 @@ pub fn handler(ctx: Context) -> Result 0 { // There are frames in this snapshot. Delete them. Some( Instruction { @@ -62,14 +58,20 @@ pub fn handler(ctx: Context) -> Result { diff --git a/programs/network/src/jobs/distribute_fees/process_entry.rs b/programs/network/src/jobs/distribute_fees/process_entry.rs index a5e50b4d..cd05507b 100644 --- a/programs/network/src/jobs/distribute_fees/process_entry.rs +++ b/programs/network/src/jobs/distribute_fees/process_entry.rs @@ -1,7 +1,7 @@ use anchor_lang::{prelude::*, solana_program::instruction::Instruction, InstructionData}; use clockwork_utils::thread::ThreadResponse; -use crate::state::*; +use crate::{constants::*, state::*}; #[derive(Accounts)] pub struct DistributeFeesProcessEntry<'info> { @@ -16,7 +16,7 @@ pub struct DistributeFeesProcessEntry<'info> { delegation.id.to_be_bytes().as_ref(), ], bump, - constraint = delegation.id.eq(&snapshot_entry.id), + constraint = delegation.id == snapshot_entry.id, has_one = worker, )] pub delegation: Account<'info, Delegation>, @@ -37,7 +37,7 @@ pub struct DistributeFeesProcessEntry<'info> { #[account( address = snapshot.pubkey(), - constraint = registry.current_epoch.eq(®istry.current_epoch) + constraint = snapshot.id == registry.current_epoch )] pub snapshot: Account<'info, Snapshot>, @@ -74,48 +74,25 @@ pub fn handler(ctx: Context) -> Result 0 { + fee.distributable_balance * snapshot_entry.stake_amount / snapshot_frame.stake_amount } else { 0 }; // Transfer yield to the worker. - **fee.to_account_info().try_borrow_mut_lamports()? = fee - .to_account_info() - .lamports() - .checked_sub(distribution_balance) - .unwrap(); - **delegation.to_account_info().try_borrow_mut_lamports()? = delegation - .to_account_info() - .lamports() - .checked_add(distribution_balance) - .unwrap(); + fee.sub_lamports(distribution_balance)?; + delegation.add_lamports(distribution_balance)?; // Increment the delegation's yield balance. - delegation.yield_balance = delegation - .yield_balance - .checked_add(distribution_balance) - .unwrap(); + delegation.yield_balance += distribution_balance; // Build the next instruction for the thread. - let dynamic_instruction = if snapshot_entry - .id - .checked_add(1) - .unwrap() - .lt(&snapshot_frame.total_entries) - { + let dynamic_instruction = if (snapshot_entry.id + 1) < snapshot_frame.total_entries { // This frame has more entries. Move on to the next one. - let next_delegation_pubkey = - Delegation::pubkey(worker.key(), delegation.id.checked_add(1).unwrap()); - let next_snapshot_entry_pubkey = SnapshotEntry::pubkey( - snapshot_frame.key(), - snapshot_entry.id.checked_add(1).unwrap(), - ); + let next_delegation_pubkey = Delegation::pubkey(worker.key(), delegation.id + 1); + let next_snapshot_entry_pubkey = + SnapshotEntry::pubkey(snapshot_frame.key(), snapshot_entry.id + 1); Some( Instruction { program_id: crate::ID, @@ -135,16 +112,11 @@ pub fn handler(ctx: Context) -> Result { @@ -24,7 +24,7 @@ pub struct DistributeFeesProcessFrame<'info> { #[account( address = snapshot.pubkey(), - constraint = snapshot.id.eq(®istry.current_epoch) + constraint = snapshot.id == registry.current_epoch )] pub snapshot: Account<'info, Snapshot>, @@ -53,41 +53,26 @@ pub fn handler(ctx: Context) -> Result 0 { // This snapshot frame has entries. Distribute fees to the delegations associated with the entries. let delegation_pubkey = Delegation::pubkey(worker.key(), 0); let snapshot_entry_pubkey = SnapshotEntry::pubkey(snapshot_frame.key(), 0); @@ -110,16 +95,11 @@ pub fn handler(ctx: Context) -> Result { #[account( address = snapshot.pubkey(), - constraint = snapshot.id.eq(®istry.current_epoch) + constraint = snapshot.id == registry.current_epoch )] pub snapshot: Account<'info, Snapshot>, @@ -46,7 +46,7 @@ pub fn handler(ctx: Context) -> Result 0 { Some( Instruction { program_id: crate::ID, diff --git a/programs/network/src/jobs/increment_epoch/job.rs b/programs/network/src/jobs/increment_epoch/job.rs index 782af661..135161cf 100644 --- a/programs/network/src/jobs/increment_epoch/job.rs +++ b/programs/network/src/jobs/increment_epoch/job.rs @@ -1,7 +1,7 @@ use anchor_lang::prelude::*; use clockwork_utils::thread::ThreadResponse; -use crate::state::*; +use crate::{constants::*, state::*}; #[derive(Accounts)] pub struct EpochCutover<'info> { @@ -21,7 +21,7 @@ pub struct EpochCutover<'info> { pub fn handler(ctx: Context) -> Result { let registry = &mut ctx.accounts.registry; - registry.current_epoch = registry.current_epoch.checked_add(1).unwrap(); + registry.current_epoch += 1; registry.locked = false; Ok(ThreadResponse { diff --git a/programs/network/src/jobs/process_unstakes/job.rs b/programs/network/src/jobs/process_unstakes/job.rs index 00d9ca51..52e82ebd 100644 --- a/programs/network/src/jobs/process_unstakes/job.rs +++ b/programs/network/src/jobs/process_unstakes/job.rs @@ -26,7 +26,7 @@ pub fn handler(ctx: Context) -> Result { // Return next instruction for thread. Ok(ThreadResponse { - dynamic_instruction: if registry.total_unstakes.gt(&0) { + dynamic_instruction: if registry.total_unstakes > 0 { Some( Instruction { program_id: crate::ID, diff --git a/programs/network/src/jobs/process_unstakes/unstake_preprocess.rs b/programs/network/src/jobs/process_unstakes/unstake_preprocess.rs index c418f2d2..08e20d34 100644 --- a/programs/network/src/jobs/process_unstakes/unstake_preprocess.rs +++ b/programs/network/src/jobs/process_unstakes/unstake_preprocess.rs @@ -36,7 +36,10 @@ pub fn handler(ctx: Context) -> Result { program_id: crate::ID, accounts: crate::accounts::UnstakeProcess { authority: unstake.authority, - authority_tokens: get_associated_token_address(&unstake.authority, &config.mint), + authority_tokens: get_associated_token_address( + &unstake.authority, + &config.mint, + ), config: config.key(), delegation: unstake.delegation, registry: registry.key(), diff --git a/programs/network/src/jobs/process_unstakes/unstake_process.rs b/programs/network/src/jobs/process_unstakes/unstake_process.rs index fc28be27..8c9d790f 100644 --- a/programs/network/src/jobs/process_unstakes/unstake_process.rs +++ b/programs/network/src/jobs/process_unstakes/unstake_process.rs @@ -2,11 +2,10 @@ use anchor_lang::{prelude::*, solana_program::instruction::Instruction, Instruct use anchor_spl::token::{transfer, Token, TokenAccount, Transfer}; use clockwork_utils::thread::ThreadResponse; -use crate::{errors::*, state::*}; +use crate::{constants::*, errors::*, state::*}; #[derive(Accounts)] pub struct UnstakeProcess<'info> { - #[account()] pub authority: SystemAccount<'info>, #[account( @@ -14,10 +13,10 @@ pub struct UnstakeProcess<'info> { associated_token::authority = delegation.authority, associated_token::mint = config.mint, )] - pub authority_tokens: Box>, + pub authority_tokens: Account<'info, TokenAccount>, #[account(address = Config::pubkey())] - pub config: Box>, + pub config: Account<'info, Config>, #[account( mut, @@ -30,19 +29,18 @@ pub struct UnstakeProcess<'info> { has_one = authority, has_one = worker, )] - pub delegation: Box>, + pub delegation: Account<'info, Delegation>, #[account( mut, seeds = [SEED_REGISTRY], bump, )] - pub registry: Box>, + pub registry: Account<'info, Registry>, #[account(address = config.epoch_thread)] pub thread: Signer<'info>, - #[account(address = anchor_spl::token::ID)] pub token_program: Program<'info, Token>, #[account( @@ -55,7 +53,7 @@ pub struct UnstakeProcess<'info> { has_one = authority, has_one = delegation )] - pub unstake: Box>, + pub unstake: Account<'info, Unstake>, #[account(address = worker.pubkey())] pub worker: Account<'info, Worker>, @@ -65,7 +63,7 @@ pub struct UnstakeProcess<'info> { associated_token::authority = worker, associated_token::mint = config.mint, )] - pub worker_tokens: Box>, + pub worker_tokens: Account<'info, TokenAccount>, } pub fn handler(ctx: Context) -> Result { @@ -83,7 +81,7 @@ pub fn handler(ctx: Context) -> Result { // Verify the unstake amount is valid. require!( - unstake.amount.le(&delegation.stake_amount), + unstake.amount <= delegation.stake_amount, ClockworkError::InvalidUnstakeAmount ); @@ -102,39 +100,21 @@ pub fn handler(ctx: Context) -> Result { )?; // Decrement the delegations locked stake balacne by the requested unstake amount. - delegation.stake_amount = delegation.stake_amount.checked_sub(unstake.amount).unwrap(); + delegation.stake_amount -= unstake.amount; // Close the unstake account by transfering all lamports to the authority. - let balance = unstake.to_account_info().lamports(); - **unstake.to_account_info().try_borrow_mut_lamports()? = unstake - .to_account_info() - .lamports() - .checked_sub(balance) - .unwrap(); - **authority.to_account_info().try_borrow_mut_lamports()? = authority - .to_account_info() - .lamports() - .checked_add(balance) - .unwrap(); + let balance = unstake.get_lamports(); + unstake.sub_lamports(balance)?; + authority.add_lamports(balance)?; // If this is the last unstake, then reset the registry's unstake counter. - if unstake - .id - .checked_add(1) - .unwrap() - .eq(®istry.total_unstakes) - { + if (unstake.id + 1) == registry.total_unstakes { registry.total_unstakes = 0; } // Build next instruction for the thread. - let dynamic_instruction = if unstake - .id - .checked_add(1) - .unwrap() - .lt(®istry.total_unstakes) - { - let next_unstake_pubkey = Unstake::pubkey(unstake.id.checked_add(1).unwrap()); + let dynamic_instruction = if (unstake.id + 1) < registry.total_unstakes { + let next_unstake_pubkey = Unstake::pubkey(unstake.id + 1); Some( Instruction { program_id: crate::ID, diff --git a/programs/network/src/jobs/stake_delegations/job.rs b/programs/network/src/jobs/stake_delegations/job.rs index 2c9ea585..484f841d 100644 --- a/programs/network/src/jobs/stake_delegations/job.rs +++ b/programs/network/src/jobs/stake_delegations/job.rs @@ -24,7 +24,7 @@ pub fn handler(ctx: Context) -> Result { let thread = &ctx.accounts.thread; Ok(ThreadResponse { - dynamic_instruction: if registry.total_workers.gt(&0) { + dynamic_instruction: if registry.total_workers > 0 { Some( Instruction { program_id: crate::ID, diff --git a/programs/network/src/jobs/stake_delegations/process_delegation.rs b/programs/network/src/jobs/stake_delegations/process_delegation.rs index 4ebc0c15..4846eba9 100644 --- a/programs/network/src/jobs/stake_delegations/process_delegation.rs +++ b/programs/network/src/jobs/stake_delegations/process_delegation.rs @@ -5,7 +5,7 @@ use anchor_spl::{ }; use clockwork_utils::thread::ThreadResponse; -use crate::state::*; +use crate::{constants::*, state::*}; #[derive(Accounts)] pub struct StakeDelegationsProcessDelegation<'info> { @@ -40,7 +40,6 @@ pub struct StakeDelegationsProcessDelegation<'info> { #[account(address = config.epoch_thread)] pub thread: Signer<'info>, - #[account(address = anchor_spl::token::ID)] pub token_program: Program<'info, Token>, #[account(address = worker.pubkey())] @@ -87,18 +86,12 @@ pub fn handler(ctx: Context) -> Result) -> Result) -> Result) -> Result 0 { // This worker has delegations. Stake their deposits. let delegation_pubkey = Delegation::pubkey(worker.key(), 0); Some( @@ -54,12 +54,7 @@ pub fn handler(ctx: Context) -> Result) -> Result { @@ -17,7 +11,7 @@ pub struct TakeSnapshotCreateEntry<'info> { #[account( address = delegation.pubkey(), - constraint = delegation.id.eq(&snapshot_frame.total_entries), + constraint = delegation.id == snapshot_frame.total_entries, has_one = worker, )] pub delegation: Box>, @@ -33,7 +27,7 @@ pub struct TakeSnapshotCreateEntry<'info> { #[account( address = snapshot.pubkey(), - constraint = registry.current_epoch.checked_add(1).unwrap().eq(&snapshot.id) + constraint = (registry.current_epoch + 1) == snapshot.id )] pub snapshot: Box>, @@ -46,7 +40,7 @@ pub struct TakeSnapshotCreateEntry<'info> { ], bump, payer = payer, - space = 8 + size_of::(), + space = 8 + SnapshotEntry::INIT_SPACE, )] pub snapshot_entry: Account<'info, SnapshotEntry>, @@ -59,11 +53,10 @@ pub struct TakeSnapshotCreateEntry<'info> { ], bump, has_one = snapshot, - constraint = snapshot_frame.id.checked_add(1).unwrap().eq(&snapshot.total_frames), + constraint = (snapshot_frame.id + 1) == snapshot.total_frames, )] pub snapshot_frame: Box>, - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, #[account(address = config.epoch_thread)] @@ -71,7 +64,7 @@ pub struct TakeSnapshotCreateEntry<'info> { #[account( address = worker.pubkey(), - constraint = worker.id.eq(&snapshot_frame.id), + constraint = worker.id == snapshot_frame.id, )] pub worker: Box>, } @@ -97,17 +90,14 @@ pub fn handler(ctx: Context) -> Result )?; // Update the snapshot frame. - snapshot_frame.total_entries = snapshot_frame.total_entries.checked_add(1).unwrap(); + snapshot_frame.total_entries += 1; // Build the next instruction for the thread. - let dynamic_instruction = if snapshot_frame.total_entries.lt(&worker.total_delegations) { + let dynamic_instruction = if snapshot_frame.total_entries < worker.total_delegations { // Create a snapshot entry for the next delegation. - let next_delegation_pubkey = - Delegation::pubkey(worker.pubkey(), delegation.id.checked_add(1).unwrap()); - let next_snapshot_entry_pubkey = SnapshotEntry::pubkey( - snapshot_frame.key(), - snapshot_entry.id.checked_add(1).unwrap(), - ); + let next_delegation_pubkey = Delegation::pubkey(worker.pubkey(), delegation.id + 1); + let next_snapshot_entry_pubkey = + SnapshotEntry::pubkey(snapshot_frame.key(), snapshot_entry.id + 1); Some( Instruction { program_id: crate::ID, @@ -128,11 +118,11 @@ pub fn handler(ctx: Context) -> Result } .into(), ) - } else if snapshot.total_frames.lt(®istry.total_workers) { + } else if snapshot.total_frames < registry.total_workers { // This frame has captured all its entries. Create a frame for the next worker. let next_snapshot_frame_pubkey = - SnapshotFrame::pubkey(snapshot.key(), snapshot_frame.id.checked_add(1).unwrap()); - let next_worker_pubkey = Worker::pubkey(worker.id.checked_add(1).unwrap()); + SnapshotFrame::pubkey(snapshot.key(), snapshot_frame.id + 1); + let next_worker_pubkey = Worker::pubkey(worker.id + 1); Some( Instruction { program_id: crate::ID, diff --git a/programs/network/src/jobs/take_snapshot/create_frame.rs b/programs/network/src/jobs/take_snapshot/create_frame.rs index 7e95bbb6..ef4046b2 100644 --- a/programs/network/src/jobs/take_snapshot/create_frame.rs +++ b/programs/network/src/jobs/take_snapshot/create_frame.rs @@ -1,13 +1,8 @@ -use anchor_lang::{ - prelude::*, - solana_program::{instruction::Instruction, system_program}, - InstructionData, -}; +use anchor_lang::{prelude::*, solana_program::instruction::Instruction, InstructionData}; use anchor_spl::{associated_token::get_associated_token_address, token::TokenAccount}; use clockwork_utils::thread::{ThreadResponse, PAYER_PUBKEY}; -use std::mem::size_of; -use crate::state::*; +use crate::{constants::*, state::*}; #[derive(Accounts)] pub struct TakeSnapshotCreateFrame<'info> { @@ -30,7 +25,7 @@ pub struct TakeSnapshotCreateFrame<'info> { snapshot.id.to_be_bytes().as_ref(), ], bump, - constraint = registry.current_epoch.checked_add(1).unwrap().eq(&snapshot.id), + constraint = (registry.current_epoch + 1) == snapshot.id, constraint = snapshot.total_frames < registry.total_workers, )] pub snapshot: Account<'info, Snapshot>, @@ -44,11 +39,10 @@ pub struct TakeSnapshotCreateFrame<'info> { ], bump, payer = payer, - space = 8 + size_of::(), + space = 8 + SnapshotFrame::INIT_SPACE, )] pub snapshot_frame: Account<'info, SnapshotFrame>, - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, #[account(address = config.epoch_thread)] @@ -56,7 +50,7 @@ pub struct TakeSnapshotCreateFrame<'info> { #[account( address = worker.pubkey(), - constraint = worker.id.eq(&snapshot.total_frames), + constraint = worker.id == snapshot.total_frames, )] pub worker: Account<'info, Worker>, @@ -88,14 +82,11 @@ pub fn handler(ctx: Context) -> Result )?; // Update snapshot total workers. - snapshot.total_stake = snapshot - .total_stake - .checked_add(worker_stake.amount) - .unwrap(); - snapshot.total_frames = snapshot.total_frames.checked_add(1).unwrap(); + snapshot.total_stake += worker_stake.amount; + snapshot.total_frames += 1; // Build the next instruction for the thread. - let dynamic_instruction = if worker.total_delegations.gt(&0) { + let dynamic_instruction = if worker.total_delegations > 0 { // This worker has delegations. Create a snapshot entry for each delegation associated with this worker. let zeroth_delegation_pubkey = Delegation::pubkey(worker.pubkey(), 0); let zeroth_snapshot_entry_pubkey = SnapshotEntry::pubkey(snapshot_frame.key(), 0); @@ -122,8 +113,8 @@ pub fn handler(ctx: Context) -> Result } else if snapshot.total_frames.lt(®istry.total_workers) { // This worker has no delegations. Create a snapshot frame for the next worker. let next_snapshot_frame_pubkey = - SnapshotFrame::pubkey(snapshot.key(), snapshot_frame.id.checked_add(1).unwrap()); - let next_worker_pubkey = Worker::pubkey(worker.id.checked_add(1).unwrap()); + SnapshotFrame::pubkey(snapshot.key(), snapshot_frame.id + 1); + let next_worker_pubkey = Worker::pubkey(worker.id + 1); Some( Instruction { program_id: crate::ID, diff --git a/programs/network/src/jobs/take_snapshot/create_snapshot.rs b/programs/network/src/jobs/take_snapshot/create_snapshot.rs index a98cacdc..ab89be83 100644 --- a/programs/network/src/jobs/take_snapshot/create_snapshot.rs +++ b/programs/network/src/jobs/take_snapshot/create_snapshot.rs @@ -1,14 +1,8 @@ -use std::mem::size_of; - -use anchor_lang::{ - prelude::*, - solana_program::{instruction::Instruction, system_program}, - InstructionData, -}; +use anchor_lang::{prelude::*, solana_program::instruction::Instruction, InstructionData}; use anchor_spl::associated_token::get_associated_token_address; use clockwork_utils::thread::{ThreadResponse, PAYER_PUBKEY}; -use crate::state::*; +use crate::{constants::*, state::*}; #[derive(Accounts)] pub struct TakeSnapshotCreateSnapshot<'info> { @@ -28,15 +22,14 @@ pub struct TakeSnapshotCreateSnapshot<'info> { init, seeds = [ SEED_SNAPSHOT, - registry.current_epoch.checked_add(1).unwrap().to_be_bytes().as_ref(), + (registry.current_epoch + 1).to_be_bytes().as_ref(), ], bump, - space = 8 + size_of::(), + space = 8 + Snapshot::INIT_SPACE, payer = payer )] pub snapshot: Account<'info, Snapshot>, - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, #[account(address = config.epoch_thread)] @@ -52,10 +45,10 @@ pub fn handler(ctx: Context) -> Result 0 { // The registry has workers. Create a snapshot frame for the zeroth worker. let snapshot_frame_pubkey = SnapshotFrame::pubkey(snapshot.key(), 0); let worker_pubkey = Worker::pubkey(0); diff --git a/programs/network/src/jobs/take_snapshot/job.rs b/programs/network/src/jobs/take_snapshot/job.rs index faaebbaa..d5cf21c4 100644 --- a/programs/network/src/jobs/take_snapshot/job.rs +++ b/programs/network/src/jobs/take_snapshot/job.rs @@ -36,7 +36,7 @@ pub fn handler(ctx: Context) -> Result { config: config.key(), payer: PAYER_PUBKEY, registry: registry.key(), - snapshot: Snapshot::pubkey(registry.current_epoch.checked_add(1).unwrap()), + snapshot: Snapshot::pubkey(registry.current_epoch + 1), system_program: system_program::ID, thread: thread.key(), } diff --git a/programs/network/src/lib.rs b/programs/network/src/lib.rs index 4a58af68..4869edc0 100644 --- a/programs/network/src/lib.rs +++ b/programs/network/src/lib.rs @@ -3,6 +3,7 @@ //! the amount of stake delgated to them. It also provides accounts for workers to collect fees //! and distribute those fees to delegators. +pub mod constants; pub mod errors; pub mod state; diff --git a/programs/network/src/state/config.rs b/programs/network/src/state/config.rs index 4777cc39..9bffa135 100644 --- a/programs/network/src/state/config.rs +++ b/programs/network/src/state/config.rs @@ -1,13 +1,13 @@ use anchor_lang::{prelude::*, AnchorDeserialize}; -pub const SEED_CONFIG: &[u8] = b"config"; +use crate::constants::SEED_CONFIG; /** * Config */ #[account] -#[derive(Debug)] +#[derive(Debug, InitSpace)] pub struct Config { pub admin: Pubkey, pub epoch_thread: Pubkey, diff --git a/programs/network/src/state/delegation.rs b/programs/network/src/state/delegation.rs index e6a76dfa..55c98c69 100644 --- a/programs/network/src/state/delegation.rs +++ b/programs/network/src/state/delegation.rs @@ -1,10 +1,10 @@ use anchor_lang::{prelude::*, AnchorDeserialize}; -pub const SEED_DELEGATION: &[u8] = b"delegation"; +use crate::constants::SEED_DELEGATION; /// An account to manage a token holder's stake delegation with a particiular a worker. #[account] -#[derive(Debug)] +#[derive(Debug, InitSpace)] pub struct Delegation { /// The authority of this delegation account. pub authority: Pubkey, diff --git a/programs/network/src/state/epoch.rs b/programs/network/src/state/epoch.rs deleted file mode 100644 index a2590110..00000000 --- a/programs/network/src/state/epoch.rs +++ /dev/null @@ -1,44 +0,0 @@ -use anchor_lang::{prelude::*, AnchorDeserialize}; - -use super::Snapshot; - -pub const SEED_EPOCH: &[u8] = b"epoch"; - -/** - * Epoch - */ - -#[account] -#[derive(Debug)] -pub struct Epoch { - pub id: u64, - pub snapshot: Pubkey, -} - -impl Epoch { - pub fn pubkey(id: u64) -> Pubkey { - Pubkey::find_program_address(&[SEED_EPOCH, id.to_be_bytes().as_ref()], &crate::ID).0 - } -} - -/** - * EpochAccount - */ - -pub trait EpochAccount { - fn pubkey(&self) -> Pubkey; - - fn init(&mut self, id: u64) -> Result<()>; -} - -impl EpochAccount for Account<'_, Epoch> { - fn pubkey(&self) -> Pubkey { - Epoch::pubkey(self.id) - } - - fn init(&mut self, id: u64) -> Result<()> { - self.id = id; - self.snapshot = Snapshot::pubkey(self.pubkey()); - Ok(()) - } -} diff --git a/programs/network/src/state/fee.rs b/programs/network/src/state/fee.rs index efe184d5..61789250 100644 --- a/programs/network/src/state/fee.rs +++ b/programs/network/src/state/fee.rs @@ -1,10 +1,10 @@ use anchor_lang::{prelude::*, AnchorDeserialize}; -pub const SEED_FEE: &[u8] = b"fee"; +use crate::constants::SEED_FEE; /// Escrows the lamport balance owed to a particular worker. #[account] -#[derive(Debug)] +#[derive(Debug, InitSpace)] pub struct Fee { /// The number of lamports that are distributable for this epoch period. pub distributable_balance: u64, diff --git a/programs/network/src/state/penalty.rs b/programs/network/src/state/penalty.rs index 4c9d7b70..aaef21ab 100644 --- a/programs/network/src/state/penalty.rs +++ b/programs/network/src/state/penalty.rs @@ -1,10 +1,10 @@ use anchor_lang::{prelude::*, AnchorDeserialize}; -pub const SEED_PENALTY: &[u8] = b"penalty"; +use crate::constants::SEED_PENALTY; /// Escrows the lamport balance owed to a particular worker. #[account] -#[derive(Debug)] +#[derive(Debug, InitSpace)] pub struct Penalty { /// The worker who was penalized. pub worker: Pubkey, diff --git a/programs/network/src/state/pool.rs b/programs/network/src/state/pool.rs index 2d43d0ac..bfe767b5 100644 --- a/programs/network/src/state/pool.rs +++ b/programs/network/src/state/pool.rs @@ -2,7 +2,7 @@ use std::collections::VecDeque; use anchor_lang::{prelude::*, AnchorDeserialize}; -pub const SEED_POOL: &[u8] = b"pool"; +use crate::constants::SEED_POOL; const DEFAULT_POOL_SIZE: usize = 1; @@ -24,6 +24,10 @@ impl Pool { } } +impl Space for Pool { + const INIT_SPACE: usize = 8 + DEFAULT_POOL_SIZE + 32; +} + /** * PoolSettings */ diff --git a/programs/network/src/state/registry.rs b/programs/network/src/state/registry.rs index f0d2c362..74a52c72 100644 --- a/programs/network/src/state/registry.rs +++ b/programs/network/src/state/registry.rs @@ -5,12 +5,12 @@ use std::{ use anchor_lang::{prelude::*, AnchorDeserialize}; -pub const SEED_REGISTRY: &[u8] = b"registry"; +use crate::constants::SEED_REGISTRY; /// Registry #[account] -#[derive(Debug)] +#[derive(Debug, InitSpace)] pub struct Registry { pub current_epoch: u64, pub locked: bool, @@ -46,7 +46,7 @@ impl RegistryAccount for Account<'_, Registry> { fn hash_nonce(&mut self) -> Result<()> { let mut hasher = DefaultHasher::new(); - Clock::get().unwrap().slot.hash(&mut hasher); + Clock::get()?.slot.hash(&mut hasher); self.nonce.hash(&mut hasher); self.nonce = hasher.finish(); Ok(()) diff --git a/programs/network/src/state/snapshot.rs b/programs/network/src/state/snapshot.rs index 3c2ba3a5..dfeaf40e 100644 --- a/programs/network/src/state/snapshot.rs +++ b/programs/network/src/state/snapshot.rs @@ -1,10 +1,10 @@ use anchor_lang::{prelude::*, AnchorDeserialize}; -pub const SEED_SNAPSHOT: &[u8] = b"snapshot"; +use crate::constants::SEED_SNAPSHOT; /// Snapshot #[account] -#[derive(Debug)] +#[derive(Debug, InitSpace)] pub struct Snapshot { pub id: u64, pub total_frames: u64, diff --git a/programs/network/src/state/snapshot_entry.rs b/programs/network/src/state/snapshot_entry.rs index bccc077b..8be790c1 100644 --- a/programs/network/src/state/snapshot_entry.rs +++ b/programs/network/src/state/snapshot_entry.rs @@ -1,13 +1,13 @@ use anchor_lang::{prelude::*, AnchorDeserialize}; -pub const SEED_SNAPSHOT_ENTRY: &[u8] = b"snapshot_entry"; +use crate::constants::SEED_SNAPSHOT_ENTRY; /** * SnapshotEntry */ #[account] -#[derive(Debug)] +#[derive(Debug, InitSpace)] pub struct SnapshotEntry { pub delegation: Pubkey, pub id: u64, diff --git a/programs/network/src/state/snapshot_frame.rs b/programs/network/src/state/snapshot_frame.rs index dc2af981..c4c1944d 100644 --- a/programs/network/src/state/snapshot_frame.rs +++ b/programs/network/src/state/snapshot_frame.rs @@ -1,12 +1,12 @@ use anchor_lang::{prelude::*, AnchorDeserialize}; -pub const SEED_SNAPSHOT_FRAME: &[u8] = b"snapshot_frame"; +use crate::constants::SEED_SNAPSHOT_FRAME; /** * SnapshotFrame */ #[account] -#[derive(Debug)] +#[derive(Debug, InitSpace)] pub struct SnapshotFrame { pub id: u64, pub snapshot: Pubkey, diff --git a/programs/network/src/state/unstake.rs b/programs/network/src/state/unstake.rs index ad06439b..c11da5ce 100644 --- a/programs/network/src/state/unstake.rs +++ b/programs/network/src/state/unstake.rs @@ -1,10 +1,10 @@ use anchor_lang::{prelude::*, AnchorDeserialize}; -pub const SEED_UNSTAKE: &[u8] = b"unstake"; +use crate::constants::SEED_UNSTAKE; /// Unstake #[account] -#[derive(Debug)] +#[derive(Debug, InitSpace)] pub struct Unstake { pub amount: u64, pub authority: Pubkey, diff --git a/programs/network/src/state/worker.rs b/programs/network/src/state/worker.rs index 945e25fe..69f6183c 100644 --- a/programs/network/src/state/worker.rs +++ b/programs/network/src/state/worker.rs @@ -1,12 +1,10 @@ use anchor_lang::{prelude::*, AnchorDeserialize}; -use crate::errors::*; - -pub const SEED_WORKER: &[u8] = b"worker"; +use crate::{constants::SEED_WORKER, errors::*}; /// Worker #[account] -#[derive(Debug)] +#[derive(Debug, InitSpace)] pub struct Worker { /// The worker's authority (owner). pub authority: Pubkey, @@ -61,7 +59,7 @@ impl WorkerAccount for Account<'_, Worker> { fn update(&mut self, settings: WorkerSettings) -> Result<()> { require!( - settings.commission_rate.ge(&0) && settings.commission_rate.le(&100), + settings.commission_rate > 0 && settings.commission_rate <= 100, ClockworkError::InvalidCommissionRate ); self.commission_rate = settings.commission_rate; diff --git a/programs/thread/Cargo.toml b/programs/thread/Cargo.toml index 1b1e035b..795fb979 100644 --- a/programs/thread/Cargo.toml +++ b/programs/thread/Cargo.toml @@ -28,8 +28,6 @@ clockwork-cron = { path = "../../cron", version = "=2.0.18" } clockwork-network-program = { path = "../network", features = [ "cpi", ], version = "=2.0.18" } -clockwork-thread-program-v1 = { path = "v1", version = "=1.4.4" } clockwork-utils = { path = "../../utils", version = "=2.0.18" } pyth-sdk-solana = "0.9.0" -static-pubkey = "1.0.3" version = "3.0.0" diff --git a/programs/thread/src/constants.rs b/programs/thread/src/constants.rs new file mode 100644 index 00000000..4c5c6384 --- /dev/null +++ b/programs/thread/src/constants.rs @@ -0,0 +1,20 @@ +use anchor_lang::prelude::*; + +#[constant] +pub const SEED_THREAD: &[u8] = b"thread"; + +/// The minimum exec fee that may be set on a thread. +#[constant] +pub const THREAD_MINIMUM_FEE: u64 = 1000; + +/// Static space for next_instruction field. +#[constant] +pub const NEXT_INSTRUCTION_SIZE: usize = 1232; + +/// The ID of the pool workers must be a member of to collect fees. +#[constant] +pub const POOL_ID: u64 = 0; + +/// The number of lamports to reimburse the worker with after they've submitted a transaction's worth of exec instructions. +#[constant] +pub const TRANSACTION_BASE_FEE_REIMBURSEMENT: u64 = 5_000; diff --git a/programs/thread/src/instructions/get_crate_info.rs b/programs/thread/src/instructions/get_crate_info.rs index d3b66abf..73f0c6e2 100644 --- a/programs/thread/src/instructions/get_crate_info.rs +++ b/programs/thread/src/instructions/get_crate_info.rs @@ -1,14 +1,10 @@ -use { - anchor_lang::{prelude::*, system_program}, - clockwork_utils::CrateInfo, -}; +use {anchor_lang::prelude::*, clockwork_utils::CrateInfo}; /// Accounts required for the `get_crate_info` instruction. /// We are not using system program actually /// But anchor does not support empty structs: https://github.com/coral-xyz/anchor/pull/1659 #[derive(Accounts)] pub struct GetCrateInfo<'info> { - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, } @@ -19,7 +15,7 @@ pub fn handler(_ctx: Context) -> Result { ); let blob = ""; let info = CrateInfo { - spec: spec.into(), + spec, blob: blob.into(), }; msg!("{}", info); diff --git a/programs/thread/src/instructions/thread_create.rs b/programs/thread/src/instructions/thread_create.rs index 41408a06..b0a1d377 100644 --- a/programs/thread/src/instructions/thread_create.rs +++ b/programs/thread/src/instructions/thread_create.rs @@ -2,30 +2,24 @@ use std::mem::size_of; use anchor_lang::{ prelude::*, - solana_program::system_program, - system_program::{transfer, Transfer} + system_program::{transfer, Transfer}, }; -use clockwork_utils::thread::{Trigger, SerializableInstruction}; +use clockwork_utils::thread::{SerializableInstruction, Trigger}; -use crate::state::*; - -/// The minimum exec fee that may be set on a thread. -const MINIMUM_FEE: u64 = 1000; +use crate::{constants::*, state::*}; /// Accounts required by the `thread_create` instruction. #[derive(Accounts)] #[instruction(amount: u64, id: Vec, instructions: Vec, trigger: Trigger)] pub struct ThreadCreate<'info> { /// The authority (owner) of the thread. - #[account()] pub authority: Signer<'info>, - /// The payer for account initializations. + /// The payer for account initializations. #[account(mut)] pub payer: Signer<'info>, /// The Solana system program. - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, /// The thread to be created. @@ -38,11 +32,11 @@ pub struct ThreadCreate<'info> { ], bump, payer= payer, - space = vec![ - 8, - size_of::(), + space = [ + 8, + size_of::(), id.len(), - instructions.try_to_vec()?.len(), + instructions.try_to_vec()?.len(), trigger.try_to_vec()?.len(), NEXT_INSTRUCTION_SIZE, ].iter().sum() @@ -50,7 +44,13 @@ pub struct ThreadCreate<'info> { pub thread: Account<'info, Thread>, } -pub fn handler(ctx: Context, amount: u64, id: Vec, instructions: Vec, trigger: Trigger) -> Result<()> { +pub fn handler( + ctx: Context, + amount: u64, + id: Vec, + instructions: Vec, + trigger: Trigger, +) -> Result<()> { // Get accounts let authority = &ctx.accounts.authority; let payer = &ctx.accounts.payer; @@ -61,9 +61,9 @@ pub fn handler(ctx: Context, amount: u64, id: Vec, instruction let bump = ctx.bumps.thread; thread.authority = authority.key(); thread.bump = bump; - thread.created_at = Clock::get().unwrap().into(); + thread.created_at = Clock::get()?.into(); thread.exec_context = None; - thread.fee = MINIMUM_FEE; + thread.fee = THREAD_MINIMUM_FEE; thread.id = id; thread.instructions = instructions; thread.name = String::new(); @@ -81,7 +81,7 @@ pub fn handler(ctx: Context, amount: u64, id: Vec, instruction to: thread.to_account_info(), }, ), - amount + amount, )?; Ok(()) diff --git a/programs/thread/src/instructions/thread_delete.rs b/programs/thread/src/instructions/thread_delete.rs index 04da66fa..ff38a186 100644 --- a/programs/thread/src/instructions/thread_delete.rs +++ b/programs/thread/src/instructions/thread_delete.rs @@ -1,4 +1,7 @@ -use {crate::state::*, anchor_lang::prelude::*}; +use { + crate::{constants::*, state::*}, + anchor_lang::prelude::*, +}; /// Accounts required by the `thread_delete` instruction. #[derive(Accounts)] @@ -30,17 +33,9 @@ pub fn handler(ctx: Context) -> Result<()> { let thread = &ctx.accounts.thread; let close_to = &ctx.accounts.close_to; - let thread_lamports = thread.to_account_info().lamports(); - **thread.to_account_info().try_borrow_mut_lamports()? = thread - .to_account_info() - .lamports() - .checked_sub(thread_lamports) - .unwrap(); - **close_to.to_account_info().try_borrow_mut_lamports()? = close_to - .to_account_info() - .lamports() - .checked_add(thread_lamports) - .unwrap(); + let thread_lamports = thread.get_lamports(); + thread.sub_lamports(thread_lamports)?; + close_to.add_lamports(thread_lamports)?; Ok(()) } diff --git a/programs/thread/src/instructions/thread_exec.rs b/programs/thread/src/instructions/thread_exec.rs index 8c1ee4db..bc29b4e6 100644 --- a/programs/thread/src/instructions/thread_exec.rs +++ b/programs/thread/src/instructions/thread_exec.rs @@ -9,13 +9,7 @@ use anchor_lang::{ use clockwork_network_program::state::{Fee, Pool, Worker, WorkerAccount}; use clockwork_utils::thread::{SerializableInstruction, ThreadResponse, PAYER_PUBKEY}; -use crate::{errors::ClockworkError, state::*}; - -/// The ID of the pool workers must be a member of to collect fees. -const POOL_ID: u64 = 0; - -/// The number of lamports to reimburse the worker with after they've submitted a transaction's worth of exec instructions. -pub const TRANSACTION_BASE_FEE_REIMBURSEMENT: u64 = 5_000; +use crate::{constants::*, errors::ClockworkError, state::*}; /// Accounts required by the `thread_exec` instruction. #[derive(Accounts)] @@ -24,7 +18,7 @@ pub struct ThreadExec<'info> { #[account( mut, seeds = [ - clockwork_network_program::state::SEED_FEE, + clockwork_network_program::constants::SEED_FEE, worker.key().as_ref(), ], bump, @@ -154,7 +148,7 @@ pub fn handler(ctx: Context) -> Result<()> { if next_instruction.is_none() { if let Some(ix) = thread.instructions.get((exec_index + 1) as usize) { next_instruction = Some(ix.clone()); - exec_index = exec_index + 1; + exec_index += 1; } } @@ -182,12 +176,7 @@ pub fn handler(ctx: Context) -> Result<()> { thread.exec_context = Some(ExecContext { exec_index, execs_since_slot: if clock.slot == thread.exec_context.unwrap().last_exec_at { - thread - .exec_context - .unwrap() - .execs_since_slot - .checked_add(1) - .unwrap() + thread.exec_context.unwrap().execs_since_slot + 1 } else { 1 }, @@ -200,35 +189,17 @@ pub fn handler(ctx: Context) -> Result<()> { let mut signatory_reimbursement = signatory_lamports_pre.saturating_sub(signatory_lamports_post); if should_reimburse_transaction { - signatory_reimbursement = signatory_reimbursement - .checked_add(TRANSACTION_BASE_FEE_REIMBURSEMENT) - .unwrap(); + signatory_reimbursement += TRANSACTION_BASE_FEE_REIMBURSEMENT; } - if signatory_reimbursement.gt(&0) { - **thread.to_account_info().try_borrow_mut_lamports()? = thread - .to_account_info() - .lamports() - .checked_sub(signatory_reimbursement) - .unwrap(); - **signatory.to_account_info().try_borrow_mut_lamports()? = signatory - .to_account_info() - .lamports() - .checked_add(signatory_reimbursement) - .unwrap(); + if signatory_reimbursement > 0 { + thread.sub_lamports(signatory_reimbursement)?; + signatory.add_lamports(signatory_reimbursement)?; } // If the worker is in the pool, debit from the thread account and payout to the worker's fee account. if pool.clone().into_inner().workers.contains(&worker.key()) { - **thread.to_account_info().try_borrow_mut_lamports()? = thread - .to_account_info() - .lamports() - .checked_sub(thread.fee) - .unwrap(); - **fee.to_account_info().try_borrow_mut_lamports()? = fee - .to_account_info() - .lamports() - .checked_add(thread.fee) - .unwrap(); + thread.sub_lamports(thread.fee)?; + fee.add_lamports(thread.fee)?; } Ok(()) diff --git a/programs/thread/src/instructions/thread_instruction_add.rs b/programs/thread/src/instructions/thread_instruction_add.rs index ac666e91..7280b44d 100644 --- a/programs/thread/src/instructions/thread_instruction_add.rs +++ b/programs/thread/src/instructions/thread_instruction_add.rs @@ -1,10 +1,10 @@ use anchor_lang::{ prelude::*, - solana_program::system_program, system_program::{transfer, Transfer}, }; +use clockwork_utils::account::AccountInfoExt; -use crate::state::*; +use crate::{constants::*, state::*}; /// Accounts required by the `thread_instruction_add` instruction. #[derive(Accounts)] @@ -14,8 +14,7 @@ pub struct ThreadInstructionAdd<'info> { #[account(mut)] pub authority: Signer<'info>, - /// The Solana system program - #[account(address = system_program::ID)] + /// The Solana system program. pub system_program: Program<'info, System>, /// The thread to be paused. @@ -45,12 +44,13 @@ pub fn handler( thread.instructions.push(instruction); // Reallocate mem for the thread account. - thread.realloc()?; + thread.realloc_account()?; // If lamports are required to maintain rent-exemption, pay them. - let data_len = thread.to_account_info().data_len(); - let minimum_rent = Rent::get().unwrap().minimum_balance(data_len); - if minimum_rent > thread.to_account_info().lamports() { + let data_len = thread.data_len(); + let minimum_rent = Rent::get()?.minimum_balance(data_len); + let thread_lamports = thread.get_lamports(); + if minimum_rent > thread_lamports { transfer( CpiContext::new( system_program.to_account_info(), @@ -59,9 +59,7 @@ pub fn handler( to: thread.to_account_info(), }, ), - minimum_rent - .checked_sub(thread.to_account_info().lamports()) - .unwrap(), + minimum_rent - thread_lamports, )?; } diff --git a/programs/thread/src/instructions/thread_instruction_remove.rs b/programs/thread/src/instructions/thread_instruction_remove.rs index 9a618811..37dfd409 100644 --- a/programs/thread/src/instructions/thread_instruction_remove.rs +++ b/programs/thread/src/instructions/thread_instruction_remove.rs @@ -1,11 +1,13 @@ -use {crate::state::*, anchor_lang::prelude::*}; +use { + crate::{constants::*, state::*}, + anchor_lang::prelude::*, +}; /// Accounts required by the `thread_instruction_remove` instruction. #[derive(Accounts)] #[instruction(index: u64)] pub struct ThreadInstructionRemove<'info> { /// The authority (owner) of the thread. - #[account()] pub authority: Signer<'info>, /// The thread to be edited. diff --git a/programs/thread/src/instructions/thread_kickoff.rs b/programs/thread/src/instructions/thread_kickoff.rs index 2c94e0c3..f6132b73 100644 --- a/programs/thread/src/instructions/thread_kickoff.rs +++ b/programs/thread/src/instructions/thread_kickoff.rs @@ -11,9 +11,7 @@ use clockwork_network_program::state::{Worker, WorkerAccount}; use clockwork_utils::thread::Trigger; use pyth_sdk_solana::load_price_feed_from_account_info; -use crate::{errors::*, state::*}; - -use super::TRANSACTION_BASE_FEE_REIMBURSEMENT; +use crate::{constants::*, errors::*, state::*}; /// Accounts required by the `thread_kickoff` instruction. #[derive(Accounts)] @@ -45,7 +43,7 @@ pub fn handler(ctx: Context) -> Result<()> { // Get accounts. let signatory = &mut ctx.accounts.signatory; let thread = &mut ctx.accounts.thread; - let clock = Clock::get().unwrap(); + let clock = Clock::get()?; match thread.trigger.clone() { Trigger::Account { @@ -67,9 +65,9 @@ pub fn handler(ctx: Context) -> Result<()> { // Begin computing the data hash of this account. let mut hasher = DefaultHasher::new(); - let data = &account_info.try_borrow_data().unwrap(); + let data = &account_info.try_borrow_data()?; let offset = offset as usize; - let range_end = offset.checked_add(size as usize).unwrap() as usize; + let range_end = offset + size as usize; if data.len().gt(&range_end) { data[offset..range_end].hash(&mut hasher); } else { @@ -108,7 +106,7 @@ pub fn handler(ctx: Context) -> Result<()> { skippable, } => { // Get the reference timestamp for calculating the thread's scheduled target timestamp. - let reference_timestamp = match thread.exec_context.clone() { + let reference_timestamp = match thread.exec_context { None => thread.created_at.unix_timestamp, Some(exec_context) => match exec_context.trigger_context { TriggerContext::Cron { started_at } => started_at, @@ -257,19 +255,11 @@ pub fn handler(ctx: Context) -> Result<()> { } // Realloc the thread account - thread.realloc()?; + thread.realloc_account()?; // Reimburse signatory for transaction fee. - **thread.to_account_info().try_borrow_mut_lamports()? = thread - .to_account_info() - .lamports() - .checked_sub(TRANSACTION_BASE_FEE_REIMBURSEMENT) - .unwrap(); - **signatory.to_account_info().try_borrow_mut_lamports()? = signatory - .to_account_info() - .lamports() - .checked_add(TRANSACTION_BASE_FEE_REIMBURSEMENT) - .unwrap(); + thread.sub_lamports(TRANSACTION_BASE_FEE_REIMBURSEMENT)?; + signatory.add_lamports(TRANSACTION_BASE_FEE_REIMBURSEMENT)?; Ok(()) } @@ -277,7 +267,7 @@ pub fn handler(ctx: Context) -> Result<()> { fn next_timestamp(after: i64, schedule: String) -> Option { Schedule::from_str(&schedule) .unwrap() - .next_after(&DateTime::::from_utc( + .next_after(&DateTime::::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(after, 0).unwrap(), Utc, )) diff --git a/programs/thread/src/instructions/thread_pause.rs b/programs/thread/src/instructions/thread_pause.rs index 10acb487..052946ef 100644 --- a/programs/thread/src/instructions/thread_pause.rs +++ b/programs/thread/src/instructions/thread_pause.rs @@ -1,10 +1,12 @@ -use {crate::state::*, anchor_lang::prelude::*}; +use { + crate::{constants::*, state::*}, + anchor_lang::prelude::*, +}; /// Accounts required by the `thread_delete` instruction. #[derive(Accounts)] pub struct ThreadPause<'info> { /// The authority (owner) of the thread. - #[account()] pub authority: Signer<'info>, /// The thread to be paused. diff --git a/programs/thread/src/instructions/thread_reset.rs b/programs/thread/src/instructions/thread_reset.rs index 4467831a..d28a949b 100644 --- a/programs/thread/src/instructions/thread_reset.rs +++ b/programs/thread/src/instructions/thread_reset.rs @@ -1,10 +1,12 @@ -use {crate::state::*, anchor_lang::prelude::*}; +use { + crate::{constants::*, state::*}, + anchor_lang::prelude::*, +}; /// Accounts required by the `thread_reset` instruction. #[derive(Accounts)] pub struct ThreadReset<'info> { /// The authority (owner) of the thread. - #[account()] pub authority: Signer<'info>, /// The thread to be paused. @@ -28,7 +30,7 @@ pub fn handler(ctx: Context) -> Result<()> { // Full reset the thread state. thread.next_instruction = None; thread.exec_context = None; - thread.created_at = Clock::get().unwrap().into(); + thread.created_at = Clock::get()?.into(); Ok(()) } diff --git a/programs/thread/src/instructions/thread_resume.rs b/programs/thread/src/instructions/thread_resume.rs index da0c31ae..3ce45dd1 100644 --- a/programs/thread/src/instructions/thread_resume.rs +++ b/programs/thread/src/instructions/thread_resume.rs @@ -1,10 +1,12 @@ -use {crate::state::*, anchor_lang::prelude::*}; +use { + crate::{constants::*, state::*}, + anchor_lang::prelude::*, +}; /// Accounts required by the `thread_resume` instruction. #[derive(Accounts)] pub struct ThreadResume<'info> { /// The authority (owner) of the thread. - #[account()] pub authority: Signer<'info>, /// The thread to be resumed. @@ -29,23 +31,15 @@ pub fn handler(ctx: Context) -> Result<()> { thread.paused = false; // Update the exec context - match thread.exec_context { - None => {} - Some(exec_context) => { - match exec_context.trigger_context { - TriggerContext::Cron { started_at: _ } => { - // Jump ahead to the current timestamp - thread.exec_context = Some(ExecContext { - trigger_context: TriggerContext::Cron { - started_at: Clock::get().unwrap().unix_timestamp, - }, - ..exec_context - }); - } - _ => { - // Nothing to do. - } - } + if let Some(exec_context) = thread.exec_context { + if let TriggerContext::Cron { started_at: _ } = exec_context.trigger_context { + // Jump ahead to the current timestamp + thread.exec_context = Some(ExecContext { + trigger_context: TriggerContext::Cron { + started_at: Clock::get()?.unix_timestamp, + }, + ..exec_context + }); } } diff --git a/programs/thread/src/instructions/thread_update.rs b/programs/thread/src/instructions/thread_update.rs index 1ba57dca..5a8b26e3 100644 --- a/programs/thread/src/instructions/thread_update.rs +++ b/programs/thread/src/instructions/thread_update.rs @@ -1,10 +1,10 @@ -use crate::{errors::ClockworkError, state::*}; +use crate::{constants::*, errors::ClockworkError, state::*}; use anchor_lang::{ prelude::*, - solana_program::system_program, system_program::{transfer, Transfer}, }; +use clockwork_utils::account::AccountInfoExt; /// Accounts required by the `thread_update` instruction. #[derive(Accounts)] @@ -15,7 +15,6 @@ pub struct ThreadUpdate<'info> { pub authority: Signer<'info>, /// The Solana system program - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, /// The thread to be updated. @@ -80,12 +79,13 @@ pub fn handler(ctx: Context, settings: ThreadSettings) -> Result<( } // Reallocate mem for the thread account - thread.realloc()?; + thread.realloc_account()?; // If lamports are required to maintain rent-exemption, pay them - let data_len = thread.to_account_info().data_len(); - let minimum_rent = Rent::get().unwrap().minimum_balance(data_len); - if minimum_rent > thread.to_account_info().lamports() { + let data_len = thread.data_len(); + let minimum_rent = Rent::get()?.minimum_balance(data_len); + let thread_lamports = thread.get_lamports(); + if minimum_rent > thread_lamports { transfer( CpiContext::new( system_program.to_account_info(), @@ -94,9 +94,7 @@ pub fn handler(ctx: Context, settings: ThreadSettings) -> Result<( to: thread.to_account_info(), }, ), - minimum_rent - .checked_sub(thread.to_account_info().lamports()) - .unwrap(), + minimum_rent - thread_lamports, )?; } diff --git a/programs/thread/src/instructions/thread_withdraw.rs b/programs/thread/src/instructions/thread_withdraw.rs index c798ac37..283313b8 100644 --- a/programs/thread/src/instructions/thread_withdraw.rs +++ b/programs/thread/src/instructions/thread_withdraw.rs @@ -1,5 +1,5 @@ use { - crate::{errors::*, state::*}, + crate::{constants::*, errors::*, state::*}, anchor_lang::prelude::*, }; @@ -8,7 +8,6 @@ use { #[instruction(amount: u64)] pub struct ThreadWithdraw<'info> { /// The authority (owner) of the thread. - #[account()] pub authority: Signer<'info>, /// The account to withdraw lamports to. @@ -36,28 +35,17 @@ pub fn handler(ctx: Context, amount: u64) -> Result<()> { // Calculate the minimum rent threshold let data_len = 8 + thread.try_to_vec()?.len(); - let minimum_rent = Rent::get().unwrap().minimum_balance(data_len); - let post_balance = thread - .to_account_info() - .lamports() - .checked_sub(amount) - .unwrap(); + let minimum_rent = Rent::get()?.minimum_balance(data_len); + let post_balance = thread.get_lamports() - amount; + require!( - post_balance.gt(&minimum_rent), + post_balance > minimum_rent, ClockworkError::WithdrawalTooLarge ); // Withdraw balance from thread to the pay_to account - **thread.to_account_info().try_borrow_mut_lamports()? = thread - .to_account_info() - .lamports() - .checked_sub(amount) - .unwrap(); - **pay_to.to_account_info().try_borrow_mut_lamports()? = pay_to - .to_account_info() - .lamports() - .checked_add(amount) - .unwrap(); + thread.sub_lamports(amount)?; + pay_to.add_lamports(amount)?; Ok(()) } diff --git a/programs/thread/src/lib.rs b/programs/thread/src/lib.rs index 3eb47de9..74c02f9b 100644 --- a/programs/thread/src/lib.rs +++ b/programs/thread/src/lib.rs @@ -4,6 +4,7 @@ #[macro_use] extern crate version; +pub mod constants; pub mod errors; pub mod state; diff --git a/programs/thread/src/state/thread.rs b/programs/thread/src/state/thread.rs index d01f7b12..b4075ee1 100644 --- a/programs/thread/src/state/thread.rs +++ b/programs/thread/src/state/thread.rs @@ -1,16 +1,17 @@ use std::mem::size_of; use anchor_lang::{prelude::*, AnchorDeserialize, AnchorSerialize}; -use clockwork_utils::thread::{ClockData, SerializableInstruction, Trigger}; +use clockwork_utils::{ + account::AccountInfoExt, + thread::{ClockData, SerializableInstruction, Trigger}, +}; pub use clockwork_utils::thread::Equality; -pub const SEED_THREAD: &[u8] = b"thread"; - -/// Static space for next_instruction field. -pub const NEXT_INSTRUCTION_SIZE: usize = 1232; +use crate::constants::{NEXT_INSTRUCTION_SIZE, SEED_THREAD}; /// Tracks the current state of a transaction thread on Solana. +// TODO Wait for the next version of Anchor to implement InitSpace macro #[account] #[derive(Debug)] pub struct Thread { @@ -65,7 +66,7 @@ pub trait ThreadAccount { fn pubkey(&self) -> Pubkey; /// Allocate more memory for the account. - fn realloc(&mut self) -> Result<()>; + fn realloc_account(&mut self) -> Result<()>; } impl ThreadAccount for Account<'_, Thread> { @@ -73,9 +74,9 @@ impl ThreadAccount for Account<'_, Thread> { Thread::pubkey(self.authority, self.id.clone()) } - fn realloc(&mut self) -> Result<()> { + fn realloc_account(&mut self) -> Result<()> { // Realloc memory for the thread account - let data_len = vec![ + let data_len = [ 8, size_of::(), self.id.len(), @@ -85,13 +86,13 @@ impl ThreadAccount for Account<'_, Thread> { ] .iter() .sum(); - self.to_account_info().realloc(data_len, false)?; + self.realloc(data_len, false)?; Ok(()) } } /// The execution context of a particular transaction thread. -#[derive(AnchorDeserialize, AnchorSerialize, Clone, Copy, Debug, PartialEq, Eq)] +#[derive(AnchorDeserialize, AnchorSerialize, InitSpace, Clone, Copy, Debug, PartialEq, Eq)] pub struct ExecContext { /// Index of the next instruction to be executed. pub exec_index: u64, @@ -111,7 +112,7 @@ pub struct ExecContext { } /// The event which allowed a particular transaction thread to be triggered. -#[derive(AnchorDeserialize, AnchorSerialize, Clone, Copy, Debug, PartialEq, Eq)] +#[derive(AnchorDeserialize, AnchorSerialize, InitSpace, Clone, Copy, Debug, PartialEq, Eq)] pub enum TriggerContext { /// A running hash of the observed account data. Account { diff --git a/programs/thread/src/state/versioned_thread.rs b/programs/thread/src/state/versioned_thread.rs index 70419192..167fc0e5 100644 --- a/programs/thread/src/state/versioned_thread.rs +++ b/programs/thread/src/state/versioned_thread.rs @@ -1,136 +1,69 @@ +use crate::{ClockData, ExecContext, SerializableInstruction, Thread, Trigger}; use anchor_lang::{prelude::*, AccountDeserialize}; -use clockwork_thread_program_v1::{ - state::Thread as ThreadV1, - typedefs::{Trigger as TriggerV1, TriggerContext as TriggerContextV1}, -}; -use clockwork_utils::thread::SerializableAccount; - -use crate::{ - ClockData, ExecContext, SerializableInstruction, Thread as ThreadV2, Trigger, TriggerContext, -}; #[derive(Clone, Debug, PartialEq)] pub enum VersionedThread { - V1(ThreadV1), - V2(ThreadV2), + V1(Thread), } impl VersionedThread { pub fn authority(&self) -> Pubkey { match self { Self::V1(t) => t.authority, - Self::V2(t) => t.authority, } } pub fn created_at(&self) -> ClockData { match self { - Self::V1(t) => ClockData { - slot: t.created_at.slot, - epoch: t.created_at.epoch, - unix_timestamp: t.created_at.unix_timestamp, - }, - Self::V2(t) => t.created_at.clone(), + Self::V1(t) => t.created_at.clone(), } } pub fn exec_context(&self) -> Option { match self { - Self::V1(t) => t.exec_context.map(|e| ExecContext { - exec_index: 0, - execs_since_reimbursement: e.execs_since_reimbursement, - execs_since_slot: e.execs_since_slot, - last_exec_at: e.last_exec_at, - trigger_context: unsafe { - std::mem::transmute::(e.trigger_context) - }, - }), - Self::V2(t) => t.exec_context, + Self::V1(t) => t.exec_context, } } pub fn id(&self) -> Vec { match self { - Self::V1(t) => t.id.as_bytes().to_vec(), - Self::V2(t) => t.id.clone(), + Self::V1(t) => t.id.clone(), } } pub fn next_instruction(&self) -> Option { match self { - Self::V1(t) => match &t.next_instruction { - None => None, - Some(ix) => Some(SerializableInstruction { - program_id: ix.program_id, - accounts: ix - .accounts - .iter() - .map(|a| unsafe { - std::mem::transmute_copy::< - clockwork_thread_program_v1::typedefs::AccountMetaData, - SerializableAccount, - >(a) - }) - .collect::>(), - data: ix.data.clone(), - }), - }, - Self::V2(t) => t.next_instruction.clone(), + Self::V1(t) => t.next_instruction.clone(), } } pub fn paused(&self) -> bool { match self { Self::V1(t) => t.paused, - Self::V2(t) => t.paused, } } pub fn program_id(&self) -> Pubkey { match self { - Self::V1(_) => clockwork_thread_program_v1::ID, - Self::V2(_) => crate::ID, + Self::V1(_) => crate::ID, } } pub fn pubkey(&self) -> Pubkey { match self { - Self::V1(_) => { - ThreadV1::pubkey(self.authority(), String::from_utf8(self.id()).unwrap()) - } - Self::V2(_) => ThreadV2::pubkey(self.authority(), self.id()), + Self::V1(_) => Thread::pubkey(self.authority(), self.id()), } } pub fn rate_limit(&self) -> u64 { match self { Self::V1(t) => t.rate_limit, - Self::V2(t) => t.rate_limit, } } pub fn trigger(&self) -> Trigger { match self { - Self::V1(t) => match &t.trigger { - TriggerV1::Account { - address, - offset, - size, - } => Trigger::Account { - address: *address, - offset: *offset as u64, - size: *size as u64, - }, - TriggerV1::Cron { - schedule, - skippable, - } => Trigger::Cron { - schedule: schedule.clone(), - skippable: *skippable, - }, - TriggerV1::Immediate => Trigger::Now, - }, - Self::V2(t) => t.trigger.clone(), + Self::V1(t) => t.trigger.clone(), } } } @@ -143,10 +76,7 @@ impl AccountDeserialize for VersionedThread { fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { // Try first to deserialize into ThreadV2. // If this fails, try to deserialize into ThreadV1. - match ThreadV2::try_deserialize(buf) { - Err(_err) => Ok(VersionedThread::V1(ThreadV1::try_deserialize(buf)?)), - Ok(t) => Ok(VersionedThread::V2(t)), - } + Ok(VersionedThread::V1(Thread::try_deserialize(buf)?)) } } diff --git a/programs/thread/v1/Cargo.toml b/programs/thread/v1/Cargo.toml deleted file mode 100644 index 223f9de0..00000000 --- a/programs/thread/v1/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "clockwork-thread-program-v1" -version = "1.4.4" -edition = "2021" -readme = "./README.md" -description = "Clockwork thread program v1" -license = "AGPL-3.0-or-later" - -[lib] -crate-type = ["cdylib", "lib"] -name = "clockwork_thread_program_v1" - -[features] -default = ["cpi"] -no-entrypoint = [] -no-idl = [] -no-log-ix-name = [] -cpi = ["no-entrypoint"] - -[dependencies] -anchor-lang = "0.29.0" -clockwork-anchor-gen = { version = "0.3.2", features = [ - "compat-program-result", -] } diff --git a/programs/thread/v1/README.md b/programs/thread/v1/README.md deleted file mode 100644 index ffbd3ea5..00000000 --- a/programs/thread/v1/README.md +++ /dev/null @@ -1 +0,0 @@ -# Clockwork Thread Program v1 diff --git a/programs/thread/v1/idl.json b/programs/thread/v1/idl.json deleted file mode 100644 index 692130f0..00000000 --- a/programs/thread/v1/idl.json +++ /dev/null @@ -1,834 +0,0 @@ -{ - "version": "1.4.4", - "name": "thread_program", - "docs": [ - "Program for creating transaction threads on Solana." - ], - "instructions": [ - { - "name": "getCrateInfo", - "docs": [ - "Return the crate information via `sol_set_return_data/sol_get_return_data`" - ], - "accounts": [ - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } - ], - "args": [], - "returns": { - "defined": "CrateInfo" - } - }, - { - "name": "threadExec", - "docs": [ - "Executes the next instruction on thread." - ], - "accounts": [ - { - "name": "fee", - "isMut": true, - "isSigner": false, - "docs": [ - "The worker's fee account." - ] - }, - { - "name": "penalty", - "isMut": true, - "isSigner": false, - "docs": [ - "The worker's penalty account." - ] - }, - { - "name": "pool", - "isMut": false, - "isSigner": false, - "docs": [ - "The active worker pool." - ] - }, - { - "name": "signatory", - "isMut": true, - "isSigner": true, - "docs": [ - "The signatory." - ] - }, - { - "name": "thread", - "isMut": true, - "isSigner": false, - "docs": [ - "The thread to execute." - ] - }, - { - "name": "worker", - "isMut": false, - "isSigner": false, - "docs": [ - "The worker." - ] - } - ], - "args": [] - }, - { - "name": "threadCreate", - "docs": [ - "Creates a new transaction thread." - ], - "accounts": [ - { - "name": "authority", - "isMut": false, - "isSigner": true, - "docs": [ - "The authority (owner) of the thread." - ] - }, - { - "name": "payer", - "isMut": true, - "isSigner": true, - "docs": [ - "The payer for account initializations." - ] - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false, - "docs": [ - "The Solana system program." - ] - }, - { - "name": "thread", - "isMut": true, - "isSigner": false, - "docs": [ - "The thread to be created." - ] - } - ], - "args": [ - { - "name": "id", - "type": "string" - }, - { - "name": "kickoffInstruction", - "type": { - "defined": "InstructionData" - } - }, - { - "name": "trigger", - "type": { - "defined": "Trigger" - } - } - ] - }, - { - "name": "threadDelete", - "docs": [ - "Closes an existing thread account and returns the lamports to the owner." - ], - "accounts": [ - { - "name": "authority", - "isMut": false, - "isSigner": true, - "docs": [ - "The authority (owner) of the thread." - ] - }, - { - "name": "closeTo", - "isMut": true, - "isSigner": false, - "docs": [ - "The address to return the data rent lamports to." - ] - }, - { - "name": "thread", - "isMut": true, - "isSigner": false, - "docs": [ - "The thread to be delete." - ] - } - ], - "args": [] - }, - { - "name": "threadKickoff", - "docs": [ - "Kicks off a thread if its trigger condition is active." - ], - "accounts": [ - { - "name": "signatory", - "isMut": true, - "isSigner": true, - "docs": [ - "The signatory." - ] - }, - { - "name": "thread", - "isMut": true, - "isSigner": false, - "docs": [ - "The thread to kickoff." - ] - }, - { - "name": "worker", - "isMut": false, - "isSigner": false, - "docs": [ - "The worker." - ] - } - ], - "args": [] - }, - { - "name": "threadPause", - "docs": [ - "Pauses an active thread." - ], - "accounts": [ - { - "name": "authority", - "isMut": false, - "isSigner": true, - "docs": [ - "The authority (owner) of the thread." - ] - }, - { - "name": "thread", - "isMut": true, - "isSigner": false, - "docs": [ - "The thread to be paused." - ] - } - ], - "args": [] - }, - { - "name": "threadResume", - "docs": [ - "Resumes a paused thread." - ], - "accounts": [ - { - "name": "authority", - "isMut": false, - "isSigner": true, - "docs": [ - "The authority (owner) of the thread." - ] - }, - { - "name": "thread", - "isMut": true, - "isSigner": false, - "docs": [ - "The thread to be resumed." - ] - } - ], - "args": [] - }, - { - "name": "threadStop", - "docs": [ - "Resumes a paused thread." - ], - "accounts": [ - { - "name": "authority", - "isMut": false, - "isSigner": true, - "docs": [ - "The authority (owner) of the thread." - ] - }, - { - "name": "thread", - "isMut": true, - "isSigner": false, - "docs": [ - "The thread to be paused." - ] - } - ], - "args": [] - }, - { - "name": "threadUpdate", - "docs": [ - "Allows an owner to update the mutable properties of a thread." - ], - "accounts": [ - { - "name": "authority", - "isMut": true, - "isSigner": true, - "docs": [ - "The authority (owner) of the thread." - ] - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false, - "docs": [ - "The Solana system program" - ] - }, - { - "name": "thread", - "isMut": true, - "isSigner": false, - "docs": [ - "The thread to be updated." - ] - } - ], - "args": [ - { - "name": "settings", - "type": { - "defined": "ThreadSettings" - } - } - ] - }, - { - "name": "threadWithdraw", - "docs": [ - "Allows an owner to withdraw from a thread's lamport balance." - ], - "accounts": [ - { - "name": "authority", - "isMut": false, - "isSigner": true, - "docs": [ - "The authority (owner) of the thread." - ] - }, - { - "name": "payTo", - "isMut": true, - "isSigner": false, - "docs": [ - "The account to withdraw lamports to." - ] - }, - { - "name": "thread", - "isMut": true, - "isSigner": false, - "docs": [ - "The thread to be." - ] - } - ], - "args": [ - { - "name": "amount", - "type": "u64" - } - ] - } - ], - "accounts": [ - { - "name": "Thread", - "docs": [ - "Tracks the current state of a transaction thread on Solana." - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "authority", - "docs": [ - "The owner of this thread." - ], - "type": "publicKey" - }, - { - "name": "createdAt", - "docs": [ - "The cluster clock at the moment the thread was created." - ], - "type": { - "defined": "ClockData" - } - }, - { - "name": "execContext", - "docs": [ - "The context of the thread's current execution state." - ], - "type": { - "option": { - "defined": "ExecContext" - } - } - }, - { - "name": "fee", - "docs": [ - "The number of lamports to payout to workers per execution." - ], - "type": "u64" - }, - { - "name": "id", - "docs": [ - "The id of the thread, given by the authority." - ], - "type": "string" - }, - { - "name": "kickoffInstruction", - "docs": [ - "The instruction to kick-off the thread." - ], - "type": { - "defined": "InstructionData" - } - }, - { - "name": "nextInstruction", - "docs": [ - "The next instruction in the thread." - ], - "type": { - "option": { - "defined": "InstructionData" - } - } - }, - { - "name": "paused", - "docs": [ - "Whether or not the thread is currently paused." - ], - "type": "bool" - }, - { - "name": "rateLimit", - "docs": [ - "The maximum number of execs allowed per slot." - ], - "type": "u64" - }, - { - "name": "trigger", - "docs": [ - "The triggering event to kickoff a thread." - ], - "type": { - "defined": "Trigger" - } - } - ] - } - } - ], - "types": [ - { - "name": "ThreadSettings", - "docs": [ - "The properties of threads which are updatable." - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "fee", - "type": { - "option": "u64" - } - }, - { - "name": "kickoffInstruction", - "type": { - "option": { - "defined": "InstructionData" - } - } - }, - { - "name": "rateLimit", - "type": { - "option": "u64" - } - }, - { - "name": "trigger", - "type": { - "option": { - "defined": "Trigger" - } - } - } - ] - } - }, - { - "name": "ExecContext", - "docs": [ - "The execution context of a particular transaction thread." - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "execsSinceReimbursement", - "docs": [ - "Number of execs since the last tx reimbursement." - ], - "type": "u64" - }, - { - "name": "execsSinceSlot", - "docs": [ - "Number of execs in this slot." - ], - "type": "u64" - }, - { - "name": "lastExecAt", - "docs": [ - "Slot of the last exec" - ], - "type": "u64" - }, - { - "name": "triggerContext", - "docs": [ - "Context for the triggering condition" - ], - "type": { - "defined": "TriggerContext" - } - } - ] - } - }, - { - "name": "ClockData", - "docs": [ - "The clock object, representing a specific moment in time recorded by a Solana cluster." - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "slot", - "docs": [ - "The current slot." - ], - "type": "u64" - }, - { - "name": "epochStartTimestamp", - "docs": [ - "The timestamp of the first slot in this Solana epoch." - ], - "type": "i64" - }, - { - "name": "epoch", - "docs": [ - "The bank epoch." - ], - "type": "u64" - }, - { - "name": "leaderScheduleEpoch", - "docs": [ - "The future epoch for which the leader schedule has most recently been calculated." - ], - "type": "u64" - }, - { - "name": "unixTimestamp", - "docs": [ - "Originally computed from genesis creation time and network time", - "in slots (drifty); corrected using validator timestamp oracle as of", - "timestamp_correction and timestamp_bounding features." - ], - "type": "i64" - } - ] - } - }, - { - "name": "ThreadResponse", - "docs": [ - "A response value target programs can return to update the thread." - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "kickoffInstruction", - "docs": [ - "The kickoff instruction to use on the next triggering of the thread.", - "If none, the kickoff instruction remains unchanged." - ], - "type": { - "option": { - "defined": "InstructionData" - } - } - }, - { - "name": "nextInstruction", - "docs": [ - "The next instruction to use on the next execution of the thread." - ], - "type": { - "option": { - "defined": "InstructionData" - } - } - } - ] - } - }, - { - "name": "InstructionData", - "docs": [ - "The data needed execute an instruction on Solana." - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "programId", - "docs": [ - "Pubkey of the instruction processor that executes this instruction" - ], - "type": "publicKey" - }, - { - "name": "accounts", - "docs": [ - "Metadata for what accounts should be passed to the instruction processor" - ], - "type": { - "vec": { - "defined": "AccountMetaData" - } - } - }, - { - "name": "data", - "docs": [ - "Opaque data passed to the instruction processor" - ], - "type": "bytes" - } - ] - } - }, - { - "name": "AccountMetaData", - "docs": [ - "Account metadata needed to execute an instruction on Solana." - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "pubkey", - "docs": [ - "An account's public key" - ], - "type": "publicKey" - }, - { - "name": "isSigner", - "docs": [ - "True if an Instruction requires a Transaction signature matching `pubkey`." - ], - "type": "bool" - }, - { - "name": "isWritable", - "docs": [ - "True if the `pubkey` can be loaded as a read-write account." - ], - "type": "bool" - } - ] - } - }, - { - "name": "Trigger", - "docs": [ - "The triggering conditions of a thread." - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "Account", - "fields": [ - { - "name": "address", - "docs": [ - "The address of the account to monitor." - ], - "type": "publicKey" - }, - { - "name": "offset", - "docs": [ - "The byte offset of the account data to monitor." - ], - "type": "u64" - }, - { - "name": "size", - "docs": [ - "The size of the byte slice to monitor (must be less than 1kb)" - ], - "type": "u64" - } - ] - }, - { - "name": "Cron", - "fields": [ - { - "name": "schedule", - "docs": [ - "The schedule in cron syntax. Value must be parsable by the `clockwork_cron` package." - ], - "type": "string" - }, - { - "name": "skippable", - "docs": [ - "Boolean value indicating whether triggering moments may be skipped if they are missed (e.g. due to network downtime).", - "If false, any \"missed\" triggering moments will simply be executed as soon as the network comes back online." - ], - "type": "bool" - } - ] - }, - { - "name": "Immediate" - } - ] - } - }, - { - "name": "TriggerContext", - "docs": [ - "The event which allowed a particular transaction thread to be triggered." - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "Account", - "fields": [ - { - "name": "data_hash", - "docs": [ - "The account's data hash." - ], - "type": "u64" - } - ] - }, - { - "name": "Cron", - "fields": [ - { - "name": "started_at", - "docs": [ - "The threshold moment the schedule was waiting for." - ], - "type": "i64" - } - ] - }, - { - "name": "Immediate" - } - ] - } - } - ], - "errors": [ - { - "code": 6000, - "name": "InvalidThreadResponse", - "msg": "The exec response could not be parsed" - }, - { - "code": 6001, - "name": "InvalidThreadState", - "msg": "The thread is in an invalid state" - }, - { - "code": 6002, - "name": "TriggerNotActive", - "msg": "The trigger condition has not been activated" - }, - { - "code": 6003, - "name": "ThreadBusy", - "msg": "This operation cannot be processes because the thread is currently busy" - }, - { - "code": 6004, - "name": "ThreadPaused", - "msg": "The thread is currently paused" - }, - { - "code": 6005, - "name": "RateLimitExeceeded", - "msg": "The thread's rate limit has been reached" - }, - { - "code": 6006, - "name": "MaxRateLimitExceeded", - "msg": "Thread rate limits cannot exceed the maximum allowed value" - }, - { - "code": 6007, - "name": "UnauthorizedWrite", - "msg": "Inner instruction attempted to write to an unauthorized address" - }, - { - "code": 6008, - "name": "WithdrawalTooLarge", - "msg": "Withdrawing this amount would leave the thread with less than the minimum required SOL for rent exemption" - } - ] -} \ No newline at end of file diff --git a/programs/thread/v1/src/lib.rs b/programs/thread/v1/src/lib.rs deleted file mode 100644 index 17e9dd63..00000000 --- a/programs/thread/v1/src/lib.rs +++ /dev/null @@ -1,24 +0,0 @@ -use anchor_lang::solana_program::entrypoint::ProgramResult; - -clockwork_anchor_gen::generate_cpi_interface!(idl_path = "idl.json"); - -anchor_lang::prelude::declare_id!("3XXuUFfweXBwFgFfYaejLvZE4cGZiHgKiGfMtdxNzYmv"); - -pub const SEED_THREAD: &[u8] = b"thread"; - -impl Thread { - /// Derive the pubkey of a thread account. - pub fn pubkey(authority: Pubkey, id: String) -> Pubkey { - Pubkey::find_program_address( - &[SEED_THREAD, authority.as_ref(), id.as_bytes()], - &crate::ID, - ) - .0 - } -} - -impl PartialEq for Thread { - fn eq(&self, other: &Self) -> bool { - self.authority.eq(&other.authority) && self.id.eq(&other.id) - } -} diff --git a/programs/webhook/Cargo.toml b/programs/webhook/Cargo.toml index 3c1c7735..859536c6 100644 --- a/programs/webhook/Cargo.toml +++ b/programs/webhook/Cargo.toml @@ -23,8 +23,4 @@ default = [] [dependencies] anchor-lang = { features = ["init-if-needed"], version = "0.29.0" } -clockwork-network-program = { path = "../network", features = [ - "cpi", -], version = "=2.0.18" } -clockwork-utils = { path = "../../utils", version = "=2.0.18" } serde = "1.0.152" diff --git a/programs/webhook/src/constants.rs b/programs/webhook/src/constants.rs new file mode 100644 index 00000000..210b9c28 --- /dev/null +++ b/programs/webhook/src/constants.rs @@ -0,0 +1,10 @@ +use anchor_lang::prelude::*; + +#[constant] +pub const SEED_WEBHOOK: &[u8] = b"webhook"; + +#[constant] +pub const WEBHOOK_FEE: u64 = 1_000_000; + +#[constant] +pub const TIMEOUT_THRESHOLD: u64 = 100; // 100 slots diff --git a/programs/webhook/src/instructions/webhook_create.rs b/programs/webhook/src/instructions/webhook_create.rs index c9c68a20..d3fe714f 100644 --- a/programs/webhook/src/instructions/webhook_create.rs +++ b/programs/webhook/src/instructions/webhook_create.rs @@ -2,24 +2,23 @@ use std::{collections::HashMap, mem::size_of}; use anchor_lang::{ prelude::*, - solana_program::system_program, system_program::{transfer, Transfer}, }; -use crate::state::{Relayer, HttpMethod, Webhook, SEED_WEBHOOK}; - -static WEBHOOK_FEE: u64 = 1_000_000; +use crate::{ + constants::{SEED_WEBHOOK, WEBHOOK_FEE}, + state::{HttpMethod, Relayer, Webhook}, +}; #[derive(Accounts)] #[instruction( body: Vec, headers: HashMap, - id: Vec, - method: HttpMethod, + id: Vec, + method: HttpMethod, url: String )] pub struct WebhookCreate<'info> { - #[account()] pub authority: Signer<'info>, #[account(mut)] @@ -38,11 +37,10 @@ pub struct WebhookCreate<'info> { )] pub webhook: Account<'info, Webhook>, - #[account(address = system_program::ID)] pub system_program: Program<'info, System>, } -pub fn handler<'info>( +pub fn handler( ctx: Context, body: Vec, headers: HashMap, @@ -57,7 +55,7 @@ pub fn handler<'info>( let system_program = &ctx.accounts.system_program; // Initialize the webhook account - let current_slot = Clock::get().unwrap().slot; + let current_slot = Clock::get()?.slot; webhook.authority = authority.key(); webhook.body = body; webhook.created_at = current_slot; diff --git a/programs/webhook/src/instructions/webhook_respond.rs b/programs/webhook/src/instructions/webhook_respond.rs index 59525148..5bfb96b7 100644 --- a/programs/webhook/src/instructions/webhook_respond.rs +++ b/programs/webhook/src/instructions/webhook_respond.rs @@ -1,10 +1,10 @@ +use crate::constants::{SEED_WEBHOOK, TIMEOUT_THRESHOLD}; + use { - crate::state::{Webhook, SEED_WEBHOOK}, + crate::state::Webhook, anchor_lang::{prelude::*, system_program}, }; -static TIMEOUT_THRESHOLD: u64 = 100; // 100 slots - #[derive(Accounts)] #[instruction()] pub struct WebhookRespond<'info> { @@ -30,7 +30,7 @@ pub struct WebhookRespond<'info> { pub worker: SystemAccount<'info>, } -pub fn handler<'info>(ctx: Context) -> Result<()> { +pub fn handler(ctx: Context) -> Result<()> { // Get accounts // let fee = &mut ctx.accounts.fee; let webhook = &mut ctx.accounts.webhook; @@ -38,18 +38,17 @@ pub fn handler<'info>(ctx: Context) -> Result<()> { // Payout webhook fee let current_slot = Clock::get().unwrap().slot; - let is_authorized_worker = webhook.workers.contains(&worker.key()); - let is_within_execution_window = - current_slot < webhook.created_at.checked_add(TIMEOUT_THRESHOLD).unwrap(); - if is_authorized_worker && is_within_execution_window { - // Pay worker for executing webhook - // fee.pay_to_worker(webhook)?; - } else { - // Either someone is spamming or this webhook has timed out. Do not pay worker. - // TODO Perhaps rather than being paid to the admin, this could be put in an escrow account where all workers could claim equal rewards. - // TODO If not claimed within X slots, the admin can claim their rewards and close the account. - // fee.pay_to_admin(webhook)?; - } + let _is_authorized_worker = webhook.workers.contains(&worker.key()); + let _is_within_execution_window = current_slot < webhook.created_at + TIMEOUT_THRESHOLD; + // if is_authorized_worker && is_within_execution_window { + // // Pay worker for executing webhook + // // fee.pay_to_worker(webhook)?; + // } else { + // // Either someone is spamming or this webhook has timed out. Do not pay worker. + // // TODO Perhaps rather than being paid to the admin, this could be put in an escrow account where all workers could claim equal rewards. + // // TODO If not claimed within X slots, the admin can claim their rewards and close the account. + // // fee.pay_to_admin(webhook)?; + // } Ok(()) } diff --git a/programs/webhook/src/lib.rs b/programs/webhook/src/lib.rs index 3f7e9766..9af26a69 100644 --- a/programs/webhook/src/lib.rs +++ b/programs/webhook/src/lib.rs @@ -1,3 +1,4 @@ +pub mod constants; pub mod errors; pub mod state; @@ -13,7 +14,7 @@ declare_id!("E7p5KFo8kKCDm6BUnWtnVFkQSYh6ZA6xaGAuvpv8NXTa"); pub mod webhook_program { pub use super::*; - pub fn webhook_create<'info>( + pub fn webhook_create( ctx: Context, body: Vec, headers: std::collections::HashMap, @@ -24,7 +25,7 @@ pub mod webhook_program { webhook_create::handler(ctx, body, headers, id, method, url) } - pub fn webhook_respond<'info>(ctx: Context) -> Result<()> { + pub fn webhook_respond(ctx: Context) -> Result<()> { webhook_respond::handler(ctx) } } diff --git a/programs/webhook/src/state/webhook.rs b/programs/webhook/src/state/webhook.rs index 532b196b..cea8b966 100644 --- a/programs/webhook/src/state/webhook.rs +++ b/programs/webhook/src/state/webhook.rs @@ -7,9 +7,7 @@ use std::{ use anchor_lang::{prelude::*, AnchorDeserialize}; use serde::{Deserialize, Serialize}; -use crate::errors::ClockworkError; - -pub const SEED_WEBHOOK: &[u8] = b"webhook"; +use crate::{constants::SEED_WEBHOOK, errors::ClockworkError}; #[account] #[derive(Debug, Deserialize, Serialize)] @@ -47,7 +45,9 @@ impl WebhookAccount for Account<'_, Webhook> { } /// HttpMethod -#[derive(AnchorDeserialize, AnchorSerialize, Deserialize, Serialize, Clone, Debug, PartialEq)] +#[derive( + AnchorDeserialize, AnchorSerialize, Deserialize, Serialize, Clone, Debug, PartialEq, InitSpace, +)] pub enum HttpMethod { Get, Post, diff --git a/relayer/Cargo.toml b/relayer/Cargo.toml index ef36187f..5c82f210 100644 --- a/relayer/Cargo.toml +++ b/relayer/Cargo.toml @@ -17,18 +17,13 @@ publish = false actix-cors = "0.6.4" actix-web = "4.3.1" anchor-lang = "0.29.0" -byte-unit = "4.0.18" clockwork-webhook-program = { path = "../programs/webhook", version = "=2.0.18" } clockwork-relayer-api = { path = "api", version = "=2.0.18" } -curve25519-dalek = "3.2.1" -lazy_static = "1.4.0" reqwest = "0.11.14" serde = "1.0.152" serde_json = "1.0.94" solana-client = "=1.17.14" solana-zk-token-sdk = "=1.17.14" solana-sdk = "=1.17.14" -tokio = "1.26.0" -bincode = "1.3.3" rayon = "1.7.0" regex = "1.7.1" diff --git a/relayer/src/main.rs b/relayer/src/main.rs index 68729bdf..9dd1ebcd 100644 --- a/relayer/src/main.rs +++ b/relayer/src/main.rs @@ -24,7 +24,7 @@ static RPC_URL: &str = "http://127.0.0.1:8899"; #[actix_web::main] async fn main() -> std::io::Result<()> { // Generate a keypair for encryption. - let encryption_keypair_path = Path::new(ENCRYPTION_KEYPAIR_PATH.into()); + let encryption_keypair_path = Path::new(ENCRYPTION_KEYPAIR_PATH); if !encryption_keypair_path.exists() { let encryption_keypair = ElGamalKeypair::new_rand(); encryption_keypair @@ -33,7 +33,7 @@ async fn main() -> std::io::Result<()> { } // Verify the secrets directory exists. - let secrets_path = Path::new(SECRETS_PATH.into()); + let secrets_path = Path::new(SECRETS_PATH); assert!(secrets_path.is_dir()); // Start the webserver. @@ -117,7 +117,7 @@ async fn secret_create(req: web::Json>) -> impl Resp let ciphertext = encrypt(keypair, plaintext); // Save the ciphertext to the filesystem. - let secrets_path = Path::new(SECRETS_PATH.into()); + let secrets_path = Path::new(SECRETS_PATH); assert!(secrets_path.is_dir()); let user_secrets_path = secrets_path.join(req.signer.to_string()); if !user_secrets_path.exists() { @@ -162,7 +162,7 @@ async fn secret_list(req: web::Json>) -> impl Responde assert!(req.0.authenticate()); // Read the filepaths from the user's secrets directory. - let secrets_path = Path::new(SECRETS_PATH.into()); + let secrets_path = Path::new(SECRETS_PATH); assert!(secrets_path.is_dir()); let user_secrets_path = secrets_path.join(req.signer.to_string()); if user_secrets_path.exists() && user_secrets_path.is_dir() { @@ -183,7 +183,7 @@ async fn secret_approve(req: web::Json>) -> impl Re assert!(req.0.authenticate()); // Create and validate filepaths. - let secrets_path = Path::new(SECRETS_PATH.into()); + let secrets_path = Path::new(SECRETS_PATH); assert!(secrets_path.is_dir()); let user_secrets_path = secrets_path.join(req.signer.to_string()); let secret_path = user_secrets_path.join(format!("{}.txt", req.msg.name)); @@ -212,7 +212,7 @@ async fn secret_revoke(req: web::Json>) -> impl Resp assert!(req.0.authenticate()); // Create and validate filepaths. - let secrets_path = Path::new(SECRETS_PATH.into()); + let secrets_path = Path::new(SECRETS_PATH); assert!(secrets_path.is_dir()); let user_secrets_path = secrets_path.join(req.signer.to_string()); let secret_path = user_secrets_path.join(format!("{}.txt", req.msg.name)); @@ -238,7 +238,7 @@ fn decrypt(keypair: &ElGamalKeypair, ciphertext: Vec) -> String { let plaintext_bytes: Vec = ciphertext .par_chunks(CIPHERTEXT_CHUNK_SIZE) .map(|i| { - let cx = ElGamalCiphertext::from_bytes(&i).unwrap(); + let cx = ElGamalCiphertext::from_bytes(i).unwrap(); let dx = keypair.secret().decrypt_u32(&cx).unwrap(); dx.to_le_bytes()[0..PLAINTEXT_CHUNK_SIZE].to_vec() }) @@ -266,20 +266,19 @@ fn encrypt(keypair: &ElGamalKeypair, plaintext: String) -> Vec { bytes .chunks(PLAINTEXT_CHUNK_SIZE) .map(|i| i.try_into().unwrap()) - .map(|s: [u8; PLAINTEXT_CHUNK_SIZE]| { + .flat_map(|s: [u8; PLAINTEXT_CHUNK_SIZE]| { keypair .pubkey() .encrypt(unsafe { std::mem::transmute::<[u8; PLAINTEXT_CHUNK_SIZE], u32>(s) }) .to_bytes() .to_vec() }) - .flatten() .collect() } async fn fetch_decrypted_secret(user: Pubkey, name: String) -> Option { let keypair = &ElGamalKeypair::read_json_file(ENCRYPTION_KEYPAIR_PATH).unwrap(); - let secret_filepath = Path::new(SECRETS_PATH.into()) + let secret_filepath = Path::new(SECRETS_PATH) .join(user.to_string()) .join(format!("{}.txt", name)); if let Ok(filetext) = fs::read(secret_filepath) { @@ -292,7 +291,7 @@ async fn fetch_decrypted_secret(user: Pubkey, name: String) -> Option { } async fn fetch_secret(user: Pubkey, name: String) -> Option { - let secret_filepath = Path::new(SECRETS_PATH.into()) + let secret_filepath = Path::new(SECRETS_PATH) .join(user.to_string()) .join(format!("{}.txt", name)); if let Ok(filetext) = fs::read(secret_filepath) { @@ -305,7 +304,7 @@ async fn fetch_secret(user: Pubkey, name: String) -> Option { fn is_approved(delegate: Pubkey, user: Pubkey, secret_name: String) -> bool { // Read the list of current delegates. - let secret_delegates_path = Path::new(SECRETS_PATH.into()) + let secret_delegates_path = Path::new(SECRETS_PATH) .join(user.to_string()) .join(format!("{}.delegates", secret_name)); let delegates = if secret_delegates_path.exists() { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index e6a72c35..34f16f70 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] channel = "1.73.0" -components = ["rustfmt", "rust-analyzer"] +components = ["rustfmt", "rust-analyzer", "clippy"] profile = "minimal" targets = [ "x86_64-apple-darwin", diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 84e8389c..a5e33e25 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -15,12 +15,9 @@ name = "clockwork_sdk" [dependencies] anchor-lang = "0.29.0" -chrono = { version = "0.4.19", default-features = false, features = ["alloc"] } clockwork-thread-program = { path = "../programs/thread", features = [ "cpi", ], version = "=2.0.18" } -nom = "~7" -once_cell = "1.5.2" [features] default = [] diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index 74e0ae8d..73b9d0df 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -10,8 +10,8 @@ pub mod state { } pub mod utils { - pub use clockwork_thread_program::state::PAYER_PUBKEY; pub use clockwork_thread_program::state::Equality; + pub use clockwork_thread_program::state::PAYER_PUBKEY; } pub mod cpi { diff --git a/utils/Cargo.toml b/utils/Cargo.toml index e715ee74..33c13b29 100644 --- a/utils/Cargo.toml +++ b/utils/Cargo.toml @@ -17,5 +17,4 @@ name = "clockwork_utils" anchor-lang = "0.29.0" base64 = "~0.13" serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" static-pubkey = "1.0.3" diff --git a/utils/src/account.rs b/utils/src/account.rs new file mode 100644 index 00000000..00dd419e --- /dev/null +++ b/utils/src/account.rs @@ -0,0 +1,14 @@ +use anchor_lang::prelude::*; + +pub trait AccountInfoExt<'info>: AsRef> { + fn realloc(&self, new_len: usize, zero_init: bool) -> Result<()> { + self.as_ref().realloc(new_len, zero_init)?; + Ok(()) + } + + fn data_len(&self) -> usize { + self.as_ref().data_len() + } +} + +impl<'info, T: AsRef>> AccountInfoExt<'info> for T {} diff --git a/utils/src/explorer.rs b/utils/src/explorer.rs index 8cb1e690..6c25f155 100644 --- a/utils/src/explorer.rs +++ b/utils/src/explorer.rs @@ -1,7 +1,6 @@ const EXPLORER_URL: &str = "https://explorer.solana.com"; const CK_EXPLORER_URL: &str = "https://explorer.clockwork.xyz"; - #[derive(Default)] pub struct Explorer { cluster: String, @@ -14,9 +13,7 @@ impl From for Explorer { url if url.contains("devnet") => Explorer::devnet(), url if url.contains("testnet") => Explorer::testnet(), url if url.contains("mainnet") => Explorer::mainnet(), - _ => { - Explorer::custom(json_rpc_url) - } + _ => Explorer::custom(json_rpc_url), } } } @@ -65,10 +62,15 @@ impl Explorer { /// Ex: https://explorer.clockwork.xyz/thread/{thread} /// ?network=custom /// &customRPC=http://localhost:8899 - pub fn thread_url(&self, thread: T, program_id: U) -> String { - let url = format!("{}/address/{}?programID={}&network={}", CK_EXPLORER_URL, - thread, program_id, self - .cluster); + pub fn thread_url( + &self, + thread: T, + program_id: U, + ) -> String { + let url = format!( + "{}/address/{}?programID={}&network={}", + CK_EXPLORER_URL, thread, program_id, self.cluster + ); if self.cluster == "custom" { url + "&customRPC=" + self.custom_rpc.as_ref().unwrap() } else { diff --git a/utils/src/lib.rs b/utils/src/lib.rs index d5f36d03..1a02c909 100644 --- a/utils/src/lib.rs +++ b/utils/src/lib.rs @@ -1,3 +1,4 @@ +pub mod account; pub mod explorer; pub mod pubkey; pub mod thread; @@ -5,7 +6,6 @@ pub mod thread; use std::fmt::{Debug, Display, Formatter}; use anchor_lang::{prelude::Pubkey, prelude::*, AnchorDeserialize}; -use base64; /// Crate build information #[derive(AnchorDeserialize, AnchorSerialize, Clone, Debug)] @@ -43,7 +43,7 @@ where // A Program's return data appears in the log in this format: // "Program return: " // https://github.com/solana-labs/solana/blob/b8837c04ec3976c9c16d028fbee86f87823fb97f/program-runtime/src/stable_log.rs#L68 - let preimage = format!("Program return: {} ", program_id.to_string()); + let preimage = format!("Program return: {} ", program_id); // Extract the return data after Program return: let get_return_data_base64 = program_logs diff --git a/utils/src/thread.rs b/utils/src/thread.rs index 5fe237b8..0726228a 100644 --- a/utils/src/thread.rs +++ b/utils/src/thread.rs @@ -14,7 +14,7 @@ use static_pubkey::static_pubkey; pub static PAYER_PUBKEY: Pubkey = static_pubkey!("C1ockworkPayer11111111111111111111111111111"); /// The clock object, representing a specific moment in time recorded by a Solana cluster. -#[derive(AnchorDeserialize, AnchorSerialize, BorshSchema, Clone, Debug, PartialEq)] +#[derive(AnchorDeserialize, AnchorSerialize, InitSpace, BorshSchema, Clone, Debug, PartialEq)] pub struct ClockData { /// The current slot. pub slot: u64, @@ -83,9 +83,9 @@ pub enum Trigger { Pyth { /// The address of the price feed to monitor. price_feed: Pubkey, - /// The equality operator (gte or lte) used to compare prices. + /// The equality operator (gte or lte) used to compare prices. equality: Equality, - /// The limit price to compare the Pyth feed to. + /// The limit price to compare the Pyth feed to. limit: i64, }, } @@ -99,7 +99,7 @@ pub enum Equality { } /// A response value target programs can return to update the thread. -#[derive(AnchorDeserialize, AnchorSerialize, Clone, Debug)] +#[derive(AnchorDeserialize, AnchorSerialize, Clone, Debug, Default)] pub struct ThreadResponse { /// If set, the thread will automatically close and return lamports to the provided address. /// If dynamic_instruction is also set, close_to will take precedence and the dynamic instruction will not be executed. @@ -111,16 +111,6 @@ pub struct ThreadResponse { pub trigger: Option, } -impl Default for ThreadResponse { - fn default() -> Self { - return Self { - close_to: None, - dynamic_instruction: None, - trigger: None, - }; - } -} - /// The data needed execute an instruction on Solana. #[derive( AnchorDeserialize,